Merge remote-tracking branch 'ul/dev' into mntm-dev --nobuild

This commit is contained in:
WillyJL
2026-01-21 21:42:50 +01:00
105 changed files with 2816 additions and 2413 deletions

View File

@@ -1,203 +1,29 @@
### Breaking Changes:
- OFW: JS: SDK 1.0:
- Scripts using these modules will need to be updated
- Module `gui/submenu`:
- The API now takes submenu items as view children, instead of as a view prop
- Effort required to update scripts using `gui/submenu`: very minimal
- Module `gui/widget`:
- The `button` event now returns an object with `key` and `type`, instead of just the key name
- Effort required to update scripts using `gui/widget`: very minimal
### Added: ### Added:
- Apps: - Sub-GHz:
- Games: Geometry Flip (by @goosedev72-projects) - UL: Cardin S449 protocol full support (64bit keeloq) (with Add manually, and all button codes) (use FSK12K modulation to read the remote) (by @xMasterX & @zero-mega)
- GPIO: - UL: Beninca ARC AES128 protocol full support (128bit dynamic) (with Add manually, and 2 button codes) (by @xMasterX & @zero-mega)
- [GPIO] Explorer (by @EvgeniGenchev07) - UL: Treadmill37 protocol support (37bit static) (by @xMasterX)
- [KT0803] FM Transmitter (by @goosedev72-projects) - UL: New modulation FSK with 12KHz deviation (by @xMasterX)
- [SPI] Terminal (by @janwiesemann) - UL: KingGates Stylo 4k Add manually and button switch support and refactoring of encoder (by @xMasterX)
- GPIO/Debug: - UL: Stilmatic button 9 support (two buttons hold simulation) (mapped on arrow keys) (by @xMasterX)
- [FTDI232H] FlipTDI (by @Skorpionm) - UL: Sommer last button code 0x6 support (mapped on arrow keys) (by @xMasterX)
- [INA2xx] INA Meter (by @cepetr) - UL: Add 390MHz and 430.5MHz to default hopper list (6 elements like in OFW) (works well with Hopper RSSI level set for your enviroment) (by @xMasterX)
- GPIO/ESP: [ESP32] Ghost ESP (by @jaylikesbunda) - UL: Docs: Add [full list of supported SubGHz protocols](https://github.com/Next-Flip/Momentum-Firmware/blob/dev/documentation/SubGHzSupportedSystems.md) and their frequencies/modulations that can be used for reading remotes (by @xMasterX)
- GPIO/FlipBoard:
- FlipBoard Blinky (by @jamisonderek)
- FlipBoard Keyboard (by @jamisonderek)
- FlipBoard Signal (by @jamisonderek)
- FlipBoard Simon (by @jamisonderek)
- GPIO/FlipperHTTP:
- FlipMap (by @jblanked)
- FlipTelegram (by @jblanked)
- Free Roam (by @jblanked)
- GPIO/GPS: [NMEA] Nearby Files (by @Stichoza)
- GPIO/Sensors: [MH-Z19] CO2 Logger (by @harryob2)
- iButton: iButton Converter (by @Leptopt1los)
- Infrared:
- Hitachi AC Remote (by @dogtopus)
- LIDAR Emulator (by @regaly)
- Midea AC Remote (by @xakep666)
- Mitsubishi AC Remote (by @achistyakov)
- Xbox Controller (by @gebeto)
- Media:
- Fmatrix (by @misterwaztaken)
- Image Viewer (by @polioan)
- Space Playground (by @alanfortlink)
- Video Player (by @LTVA1)
- NFC:
- Amiibo Toolkit (by @Firefox2100)
- NFC-Eink (by @RebornedBrain)
- NFC Login (by @Play2BReal)
- SaFlip (by @aaronjamt)
- RFID: Simultaneous UHF RFID Reader (by @haffnerriley)
- Sub-GHz:
- Chief Cooker (by @denr01)
- Flipper Share (by @lomalkin)
- HC-11 Modem (by @Giraut)
- Sub Analyzer (by @RocketGod-git)
- Sub-GHz Scheduler (by @shalebridge, fixes by @xMasterX)
- Tools:
- CAN Tools (by @MatthewKuKanich)
- FlipCrypt (by @Tyl3rA)
- IconEdit (by @rdefeo)
- Programmer Calculator (by @armixz)
- Resistance Calculator (by @instantiator)
- Tasks (by @MadLadSquad)
- Voltage Calculator (by @HappyAmos)
- USB:
- LEGO Dimensions Toy Pad (by @SegerEnd)
- USB-MIDI (by @kribesk, original by @DrZlo13)
- NFC:
- XERO: MIFARE Ultralight C feature parity with MIFARE Classic in native NFC app (by @noproto)
- Dictionary attack: Uses system and user dictionaries stored under /nfc/assets/ to unlock Ultralight C tags
- Key management: Extra Actions → MIFARE Ultralight C Keys in the NFC app allows you to add, list, and remove Ultralight C keys from your Flipper
- UI: Dictionary attack scene and menu options
- XERO: Support for MFKey 4.0, MIFARE Classic Static Encrypted Nested attacks run 10x faster (by @noproto)
- OFW: FeliCa Service Directory Traverse + Dump All Unencrypted-Readable Services' Blocks (by @zinongli)
- OFW: FeliCa Emulation Handle certain Polling commands in firmware (by @dogtopus)
- OFW: FeliCa Dump All Systems (by @zinongli)
- OFW: Amusement IC Card Parser for FeliCa Lite & Lite-S (by @zinongli)
- OFW: MFC 1k Banapass Parser (by @zinongli)
- UL: Returning fix for reading PWD locked MFUL (by @mishamyte)
- UL: Added UL-C keys to the dictionary (by @mishamyte)
- Add Saflok MFUL Parser Support (#474 by @aaronjamt)
- Add MIFARE Classic "Show Keys" UI (#473 by @aaronjamt)
- Add MFUL counters to Info page (#472 by @aaronjamt)
- SubGHz:
- UL: Roger (static 28 bit) with add manually support (by @xMasterX & @mishamyte)
- UL: V2 Phoenix full support (button switch, add manually, counter decrypt/encrypt) (by @xMasterX & @RocketGod-git, original code by @Skorpionm)
- UL: Add Keeloq support for - Motorline (with add manually support), Rosh, Pecinin, Rossi, Merlin, Steelmate (by @xMasterX & @RocketGod-git)
- UL: Nero Radio static parse and display more data (by @xMasterX)
- 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)
- UL: Add Elplast 18bit static code protocol (hello Hackcat ^_^)
- UL: Try to decode BFT (2 buttons remotes only) on the fly in regular Read mode (by @xMasterX)
- UL: Add support for Came Atomo TOP44RBN remotes (by @xMasterX & @mishamyte)
- UL: Add IL-100 Smart support for Add manually (by @xMasterX)
- UL: Add experimental counter overflow mode (OFEX), replicates how some key duplicators work, DO NOT USE if you don't know what you are doing, it will reset your counter value! (by @xMasterX)
- UL: Counter modes settings per-file for Keeloq, CAME Atomo, Nice Flor S, AlutechAT4N and option to edit counter value (by @xMasterX & @Dmitry422)
- UL: Add AN-Motors AT4 button on arrow keys (0xC) (by @xMasterX)
- UL: OFEX support for SecPlus v1 and v2, various fixes (by @Dmitry422 & xMasterX)
- RFID:
- Support writing Securakey, Jablotron and FDX-B to EM4305 cards (#434 by @jamisonderek)
- OFW: Show ISO-3166 Country Names For Pet Chips (by @zinongli)
- BT Remote:
- Add Rename Option for BT Remote, simplify Bad KB BLE profile (#439 by @aaronjamt & @WillyJL)
- OFW: Make mouse clicker button selectable (by @LordMZTE)
- MNTM Settings:
- Add Main Menu support for directories and generic files (including JS files) (#331 by @956MB & @WillyJL)
- Add Skip Sliding Animations option for Lockscreen (#436 by @aaronjamt)
- CLI:
- OFW: NFC CLI commands (by @RebornedBrain)
- OFW: Buzzer command (by @ivanbarsukov)
- OFW: JS: Added all missing GUI views for JS (by @portasynthinca3):
- Added `gui/button_menu`
- Added `gui/button_panel`
- Added `gui/menu`
- Added `gui/number_input`
- Added `gui/popup`
- Added `gui/vi_list`
- Changed API for `gui/submenu`, see breaking changes above
- Desktop:
- Add Keybinds support for directories (#331 by @956MB & @WillyJL)
- UL: Enable winter animations (by @xMasterX)
- Input Settings: Add Vibro Trigger option (#429 by @956MB)
- Archive: Support opening and favoriting Picopass files (by @WillyJL)
- Bad KB: Colemak keyboard layout (#466 by @Ashe-Sterling)
- GUI:
- Add Screen Settings shortcut to Control Center brightness click (#487 by @tototo31)
- OFW: Add date/time input module (by @aaronjamt)
### Updated: ### Updated:
- Apps:
- XERO: MFKey: Key recovery is 20% faster, new write buffering of Static Encrypted Nested key candidates performs recovery 70x faster, 4.0 update, Static Encrypted Nested attacks run 10x faster in NFC app (by @noproto)
- UL: Sub-GHz Remote: Add possibility to use custom buttons (by @MrLego8-9), add default remote and clear slot features (by @jknlsn)
- UL: BT/USB Remote: PTT global zoom and google meet shortcuts for MacOS (by @hryamzik)
- Asteroids: Bugfixes, title screen, Drone Buddy power-up (by @SimplyMinimal)
- Combo Cracker: Allow press and hold to change values, add tutorial (by @TAxelAnderson), support alphabetic combination locks (by @henrygab)
- ESP Flasher: Bump Marauder 1.9.0 (by @justcallmekoko), bump FlipperHTTP 2.1.4 (by @jblanked), add C5 support (by @Play2BReal), more reliable bootloader mode on SWCLK (by @WillyJL)
- FlipDownloader: Added a new option to download GitHub repositories with dedicated keyboard, add auto updating, new keyboard, better saving system, various keyboard improvements, support downloading FlipperHTTP for more devices (by @jblanked)
- FlipSocial: C++ rewrite, comments on feed posts, simpler logic and registration, fixed auto-updating, better saving system, show comment count, improved error handling, bugfixes (by @jblanked)
- FlipWiFi: Minor bugfixes (by @jblanked)
- Flipp Pomodoro: Added hints, added configuration page (by @thevan4), new notification modes (by @evilsquid888)
- Flipper Blackhat: Add Deauth Broadcast command, updated for latest firmware (by @o7-machinehum)
- INA Meter: Added new averaging settings allowing faster sampling (by @cepetr)
- KeyCopier: Added Weiser WR3 key format (by @lightos), added Suzuki SUZ18 key format (by @RIcePatrol)
- Mass Storage: Add ability to spoof USB identity values (by @xtruan)
- 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, support for TRT cards and Intertic disposable ST25TB cards, T-Mobilitat can parse card number (by @luu176)
- NFC Maker: Support making empty/blank NDEF payloads (by @WillyJL)
- NFC Playlist: Refactor playlist worker, new settings layout and management, loop setting, controls to move between items, time controls setting (by @acegoal07)
- NMEA GPS: Moved to GPIO/GPS subfolder (by @WillyJL)
- Passy: Misc memory management bugfixes, misc UI improvements, save DG2 and DG7 to document specific file, code cleanup (by @qistoph)
- Picopass: Removed wiegand plugin, support for changing CN during emulation for some formats (by @bettse)
- RFID/iButton Fuzzer: Fix prev navigation for custom UIDs (by @ahnilica)
- Seader: Fix ATS handling (by @NVX), reset SAM on error, support config card, code optimizations, use same commands as Proxmark3, distinguish SIO SE/SR (by @bettse)
- Sentry Safe: New interface, settings & help page (by @H4ckd4ddy)
- Seos Compatible: Add keys v2 support with per-device encryption, improve logging (by @bettse), BLE fixes, code cleanup (by @aaronjamt), compatibility with NFC Type 4 PR 4242 (by @WillyJL)
- Sub-GHz Playlist: Fix crash on disallowed frequencies (by @WillyJL)
- Weather Station: Added support for solight TE44 (by @fersingb)
- Weebo: Prevent 0x88 in UID[3], add more figures to the database (by @bettse)
- WiFi Marauder: Support for ESP32Marauder 1.8.6 (by @justcallmekoko)
- Sub-GHz: - Sub-GHz:
- UL: Add 868.46 MHz to default subghz freqs list (by @xMasterX) - UL: Counter editor refactoring (by @Dmitry422)
- UL: Reduce less popular freqs in default hopper preset, make it faster (by @xMasterX) - UL: Alutech AT-4N & Nice Flor S turbo speedup (by @Dmitry422)
- UL: Tune Linear (add better EZCode support), Dickert MAHS decoders (by @xMasterX) - UL: Sommer fm2 in Add manually now uses FM12K modulation (Sommer without fm2 tag uses FM476) (try this if regular option doesn't work for you) (by @xMasterX)
- UL: Some fixes and improvements to Honeywell Sec protocol (by @xMasterX) - UL: Replaced Cars ignore option with Revers RB2 protocol ignore option (by @xMasterX)
- Infrared:
- Update universal remotes from IRDB (#465 by @jaylikesbunda)
- OFW: Add an old JVC model to universal remotes (by @zgracem)
- OFW: Add Daikin FTXN25LV1B9 and Toyotomi KTN22-12R32 to universal remotes (by @minchogaydarov)
- OFW: Infrared Universal remote DBs unit test & move infrared_signal / infrared_brute_force into lib (by @xMasterX)
- OFW: BLE: Improved pairing security (by @hedger)
- JS: Expose button event type in `gui/widget` button callback, see breaking changes above (by @WillyJL)
- NFC:
- OFW: Synchronise mf_classic_dict.nfc with mfc_default_keys.dic from Proxmark3 Iceman fork, 164 new MFC keys (by @ry4000)
- OFW: Expose nfc_common.h (by @zinongli)
- OFW: GUI: Store View by value in ViewStack to save memory (by @CookiePLMonster)
- Docs:
- UL: Update Sub-GHz DoorHan programming instructions (by @li0ard)
- OFW: Update devboard docs (by @alexeyzakh)
### Fixed: ### Fixed:
- CLI: Fix long delay with quick connect/disconnect, qFlipper should connect faster as expected again (by @WillyJL) - Sub-GHz:
- Storage: Dont send mount event if SD mounted at boot, fix SD card icon showing late on boot (by @WillyJL) - UL: Fixed button mapping for FAAC RC/XT (by @xMasterX)
- Bad KB: - UL: Possible Sommer timings fix (by @xMasterX)
- Fix modifier keys with HOLD/RELEASE commands (by @WillyJL) - UL: Various fixes (by @xMasterX)
- OFW: Fix demo_windows.txt for newer version of ai enabled Windows Notepad not able to keep up with default fast input text (by @ase1590) - UL: Nice Flor S remove extra uint64 variable (by @xMasterX)
- Desktop: Fix lock screen hang (#438 by @aaronjamt) - UL: NFC: Fix LED not blinking at SLIX unlock (by @xMasterX)
- NFC:
- XERO: Keys found in key cache are now used in Nested attacks, deleting key cache is no longer required (by @noproto)
- 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)
- Fix slashes in prefilled filename (by @WillyJL)
- Handle PPS request in ISO14443-4 layer (by @WillyJL)
- FBT: Fix redundant decl for apps using an icon disabled in API (by @WillyJL)
- CLI: Fix missing cleanup for subghz chat on region restricted frequencies (by @WillyJL)
- UL: Sub-GHz: Fix crash in add manually menu (by @xMasterX)
- Clangd: Add clangd parameters in IDE agnostic config file (by @WillyJL)
- OFW: GUI: Fix Number Input Save Icon (by @zinongli)
- OFW: JS: Stop PWM on exit (by @portasynthinca3)
- OFW: Sub-GHz: Fix TIM17 config not applied immediately (by @Aerosnail)
### Removed: ### Removed:
- Disabled FURI_TRACE due to flash space constraints, `furi_check failed` crashes will no longer show the file path of the error for now - SUb-GHz: Removed Starline, ScherKhan and Kia protocols from main Sub-GHz app, they can be decoded with `Apps > Sub-GHz > ProtoPirate` external app

View File

@@ -24,7 +24,6 @@ F:0156915c656d8c038c6d555d34349a36:6877:subghz/came_atomo_raw.sub
F:111a8b796661f3cbd6f49f756cf91107:8614:subghz/came_raw.sub F:111a8b796661f3cbd6f49f756cf91107:8614:subghz/came_raw.sub
F:2101b0a5a72c87f9dce77223b2885aa7:162:subghz/came_twee.sub F:2101b0a5a72c87f9dce77223b2885aa7:162:subghz/came_twee.sub
F:c608b78b8e4646eeb94db37644623254:10924:subghz/came_twee_raw.sub F:c608b78b8e4646eeb94db37644623254:10924:subghz/came_twee_raw.sub
F:c4a55acddb68fc3111d592c9292022a8:21703:subghz/cenmax_raw.sub
F:51d6bd600345954b9c84a5bc6e999313:159:subghz/clemsa.sub F:51d6bd600345954b9c84a5bc6e999313:159:subghz/clemsa.sub
F:14fa0d5931a32674bfb2ddf288f3842b:21499:subghz/clemsa_raw.sub F:14fa0d5931a32674bfb2ddf288f3842b:21499:subghz/clemsa_raw.sub
F:f38b6dfa0920199200887b2cd5c0a385:161:subghz/doitrand.sub F:f38b6dfa0920199200887b2cd5c0a385:161:subghz/doitrand.sub
@@ -44,7 +43,6 @@ F:20bba4b0aec006ced7e82513f9459e31:15532:subghz/hormann_hsm_raw.sub
F:3392f2db6aa7777e937db619b86203bb:10637:subghz/ido_117_111_raw.sub F:3392f2db6aa7777e937db619b86203bb:10637:subghz/ido_117_111_raw.sub
F:cc5c7968527cc233ef11a08986e31bf2:167:subghz/intertechno_v3.sub F:cc5c7968527cc233ef11a08986e31bf2:167:subghz/intertechno_v3.sub
F:70bceb941739260ab9f6162cfdeb0347:18211:subghz/intertechno_v3_raw.sub F:70bceb941739260ab9f6162cfdeb0347:18211:subghz/intertechno_v3_raw.sub
F:bc9a4622f3e22fd7f82eb3f26e61f59b:44952:subghz/kia_seed_raw.sub
F:6b6e95fc70ea481dc6184d291466d16a:159:subghz/linear.sub F:6b6e95fc70ea481dc6184d291466d16a:159:subghz/linear.sub
F:77aaa9005db54c0357451ced081857b2:14619:subghz/linear_raw.sub F:77aaa9005db54c0357451ced081857b2:14619:subghz/linear_raw.sub
F:1a618e21e6ffa9984d465012e704c450:161:subghz/magellan.sub F:1a618e21e6ffa9984d465012e704c450:161:subghz/magellan.sub
@@ -64,7 +62,6 @@ F:2b1192e4898aaf274caebbb493b9f96e:164:subghz/power_smart.sub
F:8b8195cab1d9022fe38e802383fb923a:3648:subghz/power_smart_raw.sub F:8b8195cab1d9022fe38e802383fb923a:3648:subghz/power_smart_raw.sub
F:1ccf1289533e0486a1d010d934ad7b06:170:subghz/princeton.sub F:1ccf1289533e0486a1d010d934ad7b06:170:subghz/princeton.sub
F:8bccc506a61705ec429aecb879e5d7ce:7344:subghz/princeton_raw.sub F:8bccc506a61705ec429aecb879e5d7ce:7344:subghz/princeton_raw.sub
F:0bda91d783e464165190c3b3d16666a7:38724:subghz/scher_khan_magic_code.sub
F:116d7e1a532a0c9e00ffeee105f7138b:166:subghz/security_pls_1_0.sub F:116d7e1a532a0c9e00ffeee105f7138b:166:subghz/security_pls_1_0.sub
F:441fc7fc6fa11ce0068fde3f6145177b:69413:subghz/security_pls_1_0_raw.sub F:441fc7fc6fa11ce0068fde3f6145177b:69413:subghz/security_pls_1_0_raw.sub
F:e5e33c24c5e55f592ca892b5aa8fa31f:208:subghz/security_pls_2_0.sub F:e5e33c24c5e55f592ca892b5aa8fa31f:208:subghz/security_pls_2_0.sub

View File

@@ -1,15 +0,0 @@
Filetype: Flipper SubGhz RAW File
Version: 1
Frequency: 433920000
Preset: FuriHalSubGhzPresetOok650Async
Protocol: RAW
RAW_Data: 32700 -1024 977 -1010 971 -1046 967 -1012 1007 -1014 1001 -1008 503 -528 523 -518 485 -550 259 -288 491 -556 231 -296 501 -560 265 -268 267 -270 497 -522 489 -550 259 -290 227 -298 267 -306 239 -308 241 -274 507 -524 261 -256 259 -296 265 -268 503 -558 495 -554 229 -296 503 -560 493 -522 259 -256 257 -296 497 -526 525 -520 261 -292 499 -560 497 -524 263 -260 525 -520 261 -290 227 -298 267 -270 505 -558 231 -332 237 -274 507 -524 521 -518 487 -548 259 -286 227 -298 269 -306 239 -308 239 -276 507 -522 261 -258 261 -296 263 -268 269 -268 271 -306 239 -306 241 -274 273 -270 499 -522 489 -550 259 -288 227 -298 503 -558 233 -332 237 -274 999 -1012 977 -1016 1007 -1018 977 -1014 985 -1008 1013 -1014 521 -524 493 -552 477 -546 239 -314 477 -558 231 -298 501 -562 265 -268 267 -270 497 -520 521 -518 259 -290 227 -300 269 -306 239 -306 241 -276 507 -522 261 -258 259 -296 265 -266 501 -558 497 -556 229 -296 503 -558 493 -522 259 -256 257 -294 497 -556 493 -522 263 -292 499 -560 499 -522 263 -260 523 -522 259 -292 227 -298 267 -270 505 -560 229 -300 269 -274 505 -524 489 -550 487 -550 259 -286 227 -298 269 -306 239 -306 241 -276 507 -522 261 -256 259 -296 267 -268 267 -270 271 -304 239 -306 241 -276 273 -270 497 -522 489 -550 259 -290 225 -298 505 -558 231 -300 269 -272 1001 -1008 979 -1014 1009 -1020 977 -1014 997 -1010 983 -1040 507 -508 511 -546 477 -546 257 -280 513 -520 261 -296 499 -558 265 -268 269 -268 497 -522 489 -552 261 -288 227 -296 271 -304 241 -306 241 -276 507 -522 259 -258 259 -296 267 -266 503 -558 495 -556 229 -296 501 -562 495 -518 259 -256 257 -296 497 -524 525 -520 261 -294 499 -558 499 -524 263 -260 523 -522 259 -290 227 -298 267 -270 505 -558 231 -300 271 -272 505 -526 489 -552 485 -550 227 -318 225 -298 269 -306 239 -306 241 -276 507 -522 261 -258 259 -296 265 -266 269 -270 271 -304 239 -308 239 -276 273 -270 497 -522 489 -550 261 -288 227 -296 505 -558 231 -300 271 -272 999 -1012 981 -1024 1007 -992 1007 -1010 1003 -982 1001 -1048 479 -548 477 -548 479 -546 257 -282 511 -554 231 -294 499 -560 265 -268 269 -268 497 -522 521 -520 259 -290 225 -298 269 -306 239 -308 239 -276 507 -522 261 -258 259 -296 265 -266 503 -556 495 -556 229 -296 503 -560 493 -520 261 -256 257 -294 499 -524 525 -520 261 -294 499 -560 497 -524 261 -262 523 -522 259 -292 227 -296 267 -270 505 -558 231 -332 237 -274
RAW_Data: 505 -526 491 -550 485 -550 227 -318 225 -298 269 -306 239 -306 241 -276 507 -522 261 -258 259 -296 265 -266 269 -270 271 -304 239 -306 241 -276 271 -270 499 -522 489 -550 259 -288 227 -298 505 -560 231 -298 271 -272 999 -1012 977 -1018 1003 -1020 977 -1016 1001 -1008 979 -1040 515 -518 483 -552 485 -552 225 -306 501 -548 227 -318 493 -556 267 -266 267 -270 497 -522 489 -552 259 -288 227 -300 267 -304 239 -308 241 -276 505 -524 261 -258 259 -296 265 -268 501 -558 495 -554 229 -296 503 -528 527 -520 259 -256 257 -296 497 -524 525 -520 261 -294 501 -558 499 -524 261 -260 523 -522 259 -290 227 -298 269 -268 505 -560 231 -300 269 -274 505 -524 489 -552 487 -550 227 -286 257 -296 269 -306 239 -308 239 -276 507 -522 261 -258 259 -296 265 -266 269 -270 269 -306 239 -308 241 -274 273 -270 497 -522 487 -552 261 -288 225 -298 503 -558 233 -332 237 -274 999 -1010 977 -1016 1007 -1020 977 -1014 999 -1014 993 -1012 513 -514 513 -548 479 -548 225 -310 509 -520 261 -294 499 -558 267 -268 269 -268 497 -524 487 -552 259 -288 227 -298 269 -306 239 -308 241 -274 507 -524 259 -258 259 -296 265 -268 501 -558 497 -552 231 -296 501 -560 493 -520 261 -256 257 -294 497 -558 493 -554 129 -32700 261 -332 131 -534 329 -98 32700 -1002 979 -1048 989 -1006 989 -1012 977 -1024 1007 -1034 225 -284 255 -292 263 -264 267 -268 501 -558 231 -298 267 -306 477 -560 231 -296 229 -296 495 -522 523 -520 521 -518 261 -294 265 -304 239 -276 273 -272 497 -522 259 -258 521 -524 261 -296 497 -558 231 -300 505 -528 525 -522 485 -550 483 -550 485 -548 487 -550 261 -294 495 -560 265 -268 267 -270 497 -522 261 -260 259 -296 267 -268 505 -560 231 -298 271 -274 507 -522 521 -520 485 -548 259 -288 227 -296 271 -306 239 -308 239 -276 507 -522 261 -258 259 -296 265 -266 269 -270 271 -272 273 -306 241 -274 273 -270 497 -522 489 -550 259 -288 261 -264 503 -560 231 -300 269 -274 999 -1012 977 -1024 1007 -992 1009 -1000 1005 -982 1033 -1016 257 -248 279 -252 259 -296 265 -268 503 -560 231 -296 267 -304 477 -560 231 -296 229 -296 495 -522 523 -518 523 -520 261 -292 265 -304 239 -276 273 -270 497 -522 259 -290 491 -522 263 -294 497 -558 231 -300 505 -528 527 -522 485 -548 483 -550 485 -550 487 -552 259 -292 495 -560 265 -268 267 -268 497 -522 261 -292 227 -296 267 -270 505 -558 231 -300 269 -274 507 -524 487 -550 487 -550 257 -288 227 -296 271 -304 239 -308
RAW_Data: 241 -276 505 -524 259 -258 259 -296 265 -268 269 -270 271 -270 273 -308 239 -276 273 -270 497 -522 489 -550 259 -288 227 -298 505 -558 231 -300 269 -274 997 -1008 1009 -988 1009 -996 1013 -1014 991 -1014 991 -1012 271 -288 251 -256 253 -292 251 -288 485 -558 231 -300 269 -306 475 -560 229 -296 229 -298 495 -524 523 -518 521 -518 261 -294 263 -304 241 -274 273 -270 499 -520 261 -290 491 -524 261 -294 499 -558 231 -298 503 -562 493 -520 487 -548 485 -548 487 -550 485 -550 261 -290 497 -558 267 -266 269 -268 497 -522 263 -290 227 -296 267 -268 505 -560 231 -300 271 -272 505 -524 489 -552 487 -550 225 -318 227 -296 271 -304 241 -306 241 -276 505 -522 261 -258 259 -296 265 -266 269 -270 271 -304 239 -308 241 -274 273 -270 497 -522 489 -550 259 -288 227 -298 501 -560 231 -334 237 -274 1001 -1012 979 -1014 1005 -986 1007 -1014 1001 -1006 983 -1040 271 -254 253 -292 253 -292 253 -284 481 -558 231 -296 267 -304 477 -562 231 -294 229 -296 497 -524 489 -550 489 -552 261 -292 265 -302 239 -276 273 -270 499 -522 259 -290 491 -522 263 -294 499 -558 231 -296 503 -560 495 -520 487 -550 485 -548 487 -548 489 -548 261 -290 497 -558 265 -268 269 -268 497 -522 261 -292 227 -296 267 -268 507 -558 231 -298 271 -272 507 -522 489 -552 487 -550 227 -286 257 -298 269 -306 239 -308 241 -274 507 -524 259 -258 257 -296 265 -268 269 -268 271 -306 239 -306 241 -276 273 -270 497 -522 489 -550 259 -288 227 -296 505 -558 231 -300 271 -272 997 -1014 975 -1016 1009 -1020 977 -1016 1001 -1012 989 -1044 237 -288 253 -290 217 -292 253 -290 485 -562 231 -298 269 -306 475 -562 229 -296 229 -296 495 -524 523 -518 523 -518 261 -292 265 -304 239 -274 273 -270 499 -520 261 -292 491 -524 261 -294 495 -558 231 -300 503 -562 493 -522 485 -550 485 -548 485 -550 487 -552 261 -290 497 -560 231 -300 267 -270 497 -522 261 -290 227 -296 267 -268 507 -558 231 -300 269 -274 505 -524 519 -518 487 -550 259 -288 227 -296 271 -304 239 -308 241 -274 507 -524 259 -260 259 -294 233 -300 267 -270 271 -306 239 -308 239 -276 271 -270 497 -522 489 -550 259 -288 227 -298 501 -560 231 -334 237 -274 1001 -1010 979 -1014 1007 -1020 977 -1016 1001 -1008 979 -1044 237 -288 255 -290 255 -290 251 -282 479 -556 231 -296 269 -304 475 -562 231 -296 229 -296 495 -524 521 -518 523 -518 261 -292 265 -304 239 -276 273 -270 497 -522 261 -290 491 -524 263 -292 497 -558 231 -298
RAW_Data: 505 -560 495 -520 485 -550 485 -548 485 -552 487 -550 261 -290 497 -558 267 -266 267 -268 497 -522 263 -290 227 -296 267 -270 505 -560 231 -298 271 -272 507 -524 487 -552 485 -550 227 -318 227 -298 269 -306 239 -306 241 -276 505 -522 261 -258 259 -296 265 -268 267 -270 271 -306 237 -308 241 -274 273 -270 497 -522 489 -550 259 -288 227 -300 503 -558 231 -300 269 -272 999 -1008 1007 -988 1005 -996 1013 -1012 987 -1004 997 -1044 225 -278 247 -284 255 -296 267 -268 503 -558 231 -296 269 -304 475 -562 229 -296 229 -296 497 -524 521 -518 523 -518 261 -292 265 -302 241 -276 273 -270 497 -522 259 -290 491 -524 263 -292 499 -556 231 -300 505 -558 495 -522 485 -548 485 -550 485 -550 485 -550 261 -292 497 -558 265 -268 267 -270 497 -520 261 -290 229 -296 267 -270 505 -558 231 -300 271 -272 507 -524 489 -550 485 -548 259 -288 225 -298 269 -306 239 -308 241 -274 507 -524 261 -258 259 -294 265 -266 269 -270 269 -306 239 -306 241 -274 273 -270 497 -524 487 -550 259 -290 227 -296 503 -558 231 -334 237 -274 997 -1014 977 -1016 1007 -1018 977 -1016 1001 -1008 981 -1038 257 -274 245 -280 251 -290 263 -266 503 -560 231 -294 267 -306 475 -562 229 -296 229 -296 495 -522 523 -520 521 -518 261 -294 265 -302 239 -276 273 -270 499 -522 259 -290 491 -524 261 -294 497 -556 233 -298 505 -560 493 -520 487 -550 485 -550 485 -550 487 -550 259 -292 495 -558 267 -266 269 -268 497 -522 261 -288 227 -298 269 -270 505 -556 231 -298 271 -274 505 -524 489 -550 485 -548 261 -288 225 -298 269 -306 239 -306 241 -274 507 -524 261 -258 259 -294 265 -268 269 -268 271 -306 237 -308 241 -274 273 -270 497 -522 489 -548 261 -288 227 -296 503 -560 231 -300 271 -272 997 -1010 1003 -1004 999 -1008 991 -1010 1011 -982 1009 -1020 257 -282 251 -286 227 -296 265 -268 503 -558 231 -298 267 -304 477 -560 231 -296 227 -296 495 -524 523 -520 489 -550 261 -292 265 -304 239 -276 273 -270 499 -520 259 -290 491 -522 263 -294 499 -558 231 -296 505 -560 493 -522 485 -550 485 -550 485 -548 489 -548 261 -290 497 -558 267 -266 269 -268 497 -522 261 -290 227 -296 267 -270 505 -560 231 -298 269 -272 507 -524 491 -550 485 -548 259 -288 225 -298 269 -306 239 -308 241 -274 507 -524 259 -258 257 -296 265 -266 269 -270 271 -304 239 -308 241 -274 273 -270 497 -522 489 -550 259 -288 227 -298 505 -558 231 -300 269 -274 997 -1012 979 -1024 1007 -992 1007 -1016 991 -1008
RAW_Data: 989 -1042 237 -288 253 -290 255 -254 255 -288 487 -560 231 -300 269 -306 475 -562 229 -296 229 -296 495 -524 523 -518 489 -550 261 -292 265 -304 239 -276 273 -270 497 -522 259 -290 493 -524 263 -292 497 -556 231 -300 505 -560 493 -520 485 -550 485 -548 487 -548 487 -550 259 -292 497 -560 265 -268 267 -268 497 -522 259 -292 227 -296 267 -270 505 -558 233 -300 269 -272 507 -524 489 -550 487 -550 227 -286 257 -296 269 -306 239 -308 241 -274 507 -524 259 -258 257 -296 267 -266 269 -270 269 -306 239 -306 241 -274 273 -270 497 -522 489 -550 259 -288 227 -298 503 -560 231 -332 237 -274 999 -1012 981 -1016 1003 -986 1009 -1018 1003 -1006 983 -1044 237 -292 253 -292 217 -292 249 -280 509 -556 229 -296 267 -306 477 -560 229 -298 229 -296 495 -522 523 -518 523 -518 261 -292 265 -304 239 -274 273 -272 497 -522 259 -290 491 -524 261 -294 497 -558 231 -300 503 -560 493 -520 487 -548 487 -548 485 -548 487 -550 261 -292 495 -560 265 -268 267 -268 497 -522 263 -290 227 -296 267 -270 503 -560 231 -300 269 -274 505 -526 489 -552 485 -550 227 -286 257 -296 269 -306 239 -306 241 -276 507 -522 259 -258 259 -296 265 -268 267 -270 271 -306 239 -306 241 -276 273 -270 495 -522 487 -552 261 -288 225 -298 503 -558 231 -332 239 -274 999 -1012 979 -1016 1007 -986 1009 -1016 999 -1012 987 -1012 271 -288 253 -290 219 -290 255 -288 485 -558 231 -300 269 -306 475 -560 231 -296 229 -296 495 -524 523 -518 521 -518 261 -292 265 -302 241 -276 273 -270 497 -522 259 -290 491 -524 261 -294 497 -558 231 -298 507 -560 493 -522 485 -548 485 -548 487 -550 489 -548 261 -290 497 -560 233 -300 267 -266 497 -522 261 -290 227 -298 267 -268 505 -558 231 -300 269 -274 505 -524 491 -550 485 -548 259 -286 227 -298 269 -306 239 -308 241 -274 507 -522 261 -256 259 -296 267 -266 269 -270 271 -304 239 -306 241 -276 271 -270 499 -522 487 -550 261 -288 225 -298 505 -558 231 -300 269 -274 997 -1010 981 -1016 1003 -1020 971 -1006 1025 -1008 987 -1042 225 -276 247 -282 255 -294 265 -268 503 -558 229 -296 267 -304 477 -562 229 -296 229 -296 495 -524 523 -518 523 -518 261 -292 265 -304 239 -274 273 -272 497 -522 259 -292 491 -524 263 -294 497 -558 231 -298 503 -560 493 -520 487 -550 485 -548 485 -548 487 -550 261 -292 497 -560 231 -300 269 -268 497 -522 259 -290 227 -298 267 -268 505 -560 231 -332 237 -274 505 -524 489 -550 485 -548 259 -288 227 -300
RAW_Data: 267 -304 239 -308 241 -274 509 -524 259 -258 257 -296 265 -268 269 -268 271 -306 239 -306 241 -274 273 -270 497 -522 487 -550 261 -288 227 -298 503 -558 233 -298 271 -274 999 -1012 979 -1016 1007 -1016 975 -1002 999 -1018 995 -1046 237 -288 251 -292 253 -256 253 -290 485 -562 233 -298 269 -306 475 -562 229 -296 229 -298 497 -522 491 -550 491 -548 261 -292 265 -304 239 -274 273 -270 499 -520 261 -290 491 -522 263 -294 497 -558 231 -298 505 -558 495 -520 487 -548 485 -550 485 -548 487 -550 261 -292 495 -558 267 -268 267 -268 499 -522 261 -290 227 -296 267 -270 505 -558 233 -298 269 -272 507 -522 489 -552 487 -550 227 -286 257 -296 271 -304 239 -308 239 -32700 165 -164 97 -1950 465 -232 393 -198 557 -7530 865 -1122 915 -1114 159 -346 187 -348 187 -348 445 -618 419 -584 455 -618 195 -354 429 -596 459 -554 227 -320 225 -294 229 -332 467 -560 229 -330 467 -560 497 -558 229 -296 229 -296 229 -300 497 -558 229 -294 265 -302 237 -308 243 -274 273 -270 233 -298 263 -266 265 -268 501 -558 231 -296 267 -306 241 -276 273 -270 497 -522 261 -258 257 -296 267 -270 507 -556 265 -266 271 -274 507 -524 519 -518 487 -548 259 -256 291 -264 269 -274 273 -310 241 -274 505 -524 259 -258 257 -296 265 -268 269 -270 271 -272 273 -306 241 -276 273 -270 495 -522 521 -516 259 -290 259 -264 505 -558 265 -266 271 -274 1001 -1010 1005 -990 1005 -996 1007 -1014 987 -1016 993 -1010 257 -276 247 -282 255 -294 499 -522 527 -520 523 -520 263 -296 503 -526 527 -520 259 -256 257 -294 265 -268 503 -558 231 -296 501 -560 497 -524 261 -262 259 -296 265 -266 497 -524 261 -296 265 -270 271 -308 241 -274 273 -270 233 -298 231 -298 265 -268 503 -556 231 -296 267 -306 239 -276 273 -270 497 -522 259 -258 291 -266 267 -270 505 -558 265 -266 271 -272 507 -522 521 -516 485 -550 257 -288 261 -266 269 -272 275 -306 241 -276 505 -522 261 -256 259 -296 265 -268 269 -270 271 -270 273 -308 241 -274 273 -270 497 -520 521 -518 261 -256 291 -264 503 -560 265 -266 269 -274 999 -1008 1003 -986 1007 -1004 1013 -980 1023 -1008 991 -1042 225 -276 247 -282 255 -294 501 -524 527 -518 527 -520 261 -296 503 -526 525 -520 259 -256 257 -294 265 -268 503 -526 263 -296 501 -560 497 -524 261 -262 261 -296 263 -266 499 -522 263 -294 265 -270 271 -308 241 -276 273 -270 233 -298 229 -298 265 -268 501 -558 231 -298 267 -304 241 -276 273 -270 495 -522 259 -290 261 -264
RAW_Data: 269 -270 505 -558 231 -300 271 -272 507 -522 521 -518 485 -550 259 -254 291 -264 271 -272 273 -308 241 -274 507 -524 259 -258 257 -296 265 -268 269 -270 271 -272 271 -308 241 -276 271 -270 497 -520 521 -520 259 -256 291 -266 503 -558 265 -266 271 -274 999 -1014 977 -1016 1007 -984 1007 -1014 999 -1016 991 -1010 271 -290 253 -254 291 -254 495 -542 499 -558 493 -522 263 -296 503 -526 525 -522 259 -256 257 -294 267 -268 503 -554 231 -298 501 -558 499 -524 261 -260 261 -298 231 -298 499 -524 261 -294 265 -268 273 -308 241 -276 271 -270 233 -298 231 -298 265 -266 503 -558 231 -298 267 -304 241 -274 273 -270 499 -520 259 -258 291 -266 267 -270 507 -558 233 -296 269 -274 505 -524 521 -520 485 -548 259 -256 291 -264 269 -272 275 -308 239 -276 507 -522 261 -256 259 -296 265 -268 267 -270 271 -272 273 -306 241 -276 271 -270 497 -520 523 -518 259 -290 259 -264 503 -560 265 -266 269 -274 999 -1008 1005 -986 1017 -994 1007 -1012 991 -1014 991 -1012 259 -276 245 -282 253 -294 499 -522 527 -520 525 -518 263 -296 501 -526 527 -520 259 -256 257 -294 265 -268 503 -558 231 -296 503 -558 501 -522 263 -260 259 -294 263 -266 499 -524 261 -296 265 -270 273 -308 241 -274 273 -270 233 -296 231 -296 267 -268 503 -556 231 -296 267 -304 241 -276 273 -270 499 -522 259 -256 259 -296 267 -272 505 -558 233 -298 271 -272 507 -522 521 -516 485 -550 259 -288 259 -264 271 -272 273 -308 241 -276 507 -522 261 -256 259 -296 265 -266 269 -270 271 -272 273 -308 241 -274 273 -270 497 -520 521 -518 259 -288 261 -266 503 -558 265 -266 271 -274 999 -1010 981 -1026 981 -1026 1007 -978 997 -1012 1019 -1006 255 -276 245 -280 255 -294 497 -524 525 -520 525 -520 261 -296 503 -526 527 -520 259 -256 257 -294 267 -268 503 -558 231 -296 499 -560 497 -524 261 -262 261 -296 263 -266 499 -524 261 -294 267 -268 273 -308 239 -276 273 -270 233 -296 231 -298 265 -268 503 -558 231 -296 267 -304 241 -274 273 -270 499 -520 259 -258 259 -298 267 -270 505 -558 265 -266 271 -274 507 -522 521 -516 485 -548 259 -288 259 -266 269 -272 275 -306 243 -274 507 -524 259 -258 257 -296 265 -268 269 -270 269 -272 273 -308 241 -276 271 -270 497 -520 521 -518 259 -290 259 -264 505 -560 263 -266 271 -274 999 -1008 1003 -986 1009 -1000 1011 -1006 1001 -1000 1003 -1018 259 -280 249 -286 261 -264 501 -522 527 -520 525 -518 263 -296 503 -526 525 -522 259 -256 257 -294 267 -266
RAW_Data: 505 -556 231 -296 501 -558 499 -522 263 -260 261 -296 265 -264 501 -524 261 -294 265 -270 271 -308 241 -274 273 -270 233 -298 231 -298 265 -266 503 -558 231 -296 267 -306 239 -276 273 -270 499 -522 259 -258 257 -296 269 -270 505 -560 231 -298 269 -272 507 -522 521 -518 487 -548 259 -288 259 -264 271 -272 273 -308 241 -276 507 -522 259 -258 257 -296 267 -268 269 -268 271 -272 273 -306 241 -276 271 -270 497 -522 519 -516 261 -288 261 -266 503 -558 265 -266 271 -274 997 -1014 979 -1014 1007 -984 1009 -1016 987 -1006 1013 -1014 273 -290 255 -254 253 -290 485 -526 527 -522 523 -520 263 -294 505 -526 525 -520 259 -256 257 -294 265 -268 501 -558 231 -298 501 -558 499 -522 263 -260 261 -296 263 -266 499 -522 263 -294 267 -268 273 -308 241 -274 273 -270 233 -298 231 -298 265 -266 503 -556 231 -296 269 -306 241 -274 273 -270 497 -520 261 -288 227 -298 269 -270 505 -556 265 -266 271 -274 507 -522 521 -516 487 -548 259 -288 259 -264 269 -272 275 -308 241 -274 507 -522 261 -256 259 -296 265 -268 267 -270 271 -272 275 -306 241 -276 271 -270 497 -520 521 -518 259 -288 259 -266 503 -558 267 -266 269 -274 999 -1006 1005 -986 1007 -1004 1011 -1014 987 -1014 993 -1012 271 -290 253 -254 255 -290 491 -536 503 -558 495 -554 231 -298 503 -524 527 -520 259 -256 257 -296 265 -268 501 -558 231 -298 501 -558 499 -524 261 -260 261 -296 263 -266 499 -522 263 -294 265 -270 273 -306 243 -274 273 -270 233 -298 231 -296 267 -268 501 -558 231 -296 267 -306 239 -276 271 -270 497 -522 261 -258 259 -296 267 -270 507 -560 231 -298 269 -274 505 -524 521 -518 487 -550 259 -254 257 -298 269 -272 275 -308 241 -274 507 -522 261 -256 257 -296 267 -266 269 -270 271 -272 273 -306 241 -276 273 -270 495 -522 519 -518 259 -290 261 -264 505 -558 231 -300 271 -272 999 -1008 1015 -980 1009 -988 1007 -1016 1001 -1010 983 -1044 237 -292 253 -292 253 -254 491 -560 497 -522 527 -520 263 -294 503 -528 527 -518 259 -256 257 -296 265 -268 503 -526 263 -296 501 -558 497 -524 261 -262 261 -296 231 -298 499 -524 261 -294 267 -268 273 -308 241 -274 273 -270 233 -298 229 -298 265 -268 503 -558 231 -298 267 -304 241 -274 273 -270 497 -522 259 -290 259 -266 267 -270 505 -558 265 -266 271 -272 507 -522 521 -520 487 -550 259 -254 257 -298 269 -272 273 -306 243 -274 507 -524 259 -258 257 -296 265 -268 269 -270 271 -270 273 -308 241 -274 273 -270 497 -522
RAW_Data: 519 -518 259 -288 261 -266 505 -558 231 -300 271 -272 997 -1012 1009 -982 1009 -986 1009 -1014 999 -1016 989 -1012 271 -288 253 -290 253 -256 495 -540 501 -558 495 -522 263 -296 501 -528 527 -520 259 -256 257 -294 265 -268 503 -556 233 -296 501 -558 499 -522 263 -260 261 -296 263 -266 499 -524 261 -294 267 -268 273 -308 241 -276 271 -270 233 -298 229 -300 265 -268 501 -556 231 -298 267 -306 241 -276 271 -270 499 -520 259 -258 259 -296 267 -272 505 -558 233 -298 271 -272 507 -522 521 -520 485 -552 259 -252 291 -264 271 -272 273 -308 241 -276 505 -522 259 -258 259 -296 265 -268 269 -270 271 -270 273 -308 241 -274 273 -270 497 -520 521 -518 259 -288 261 -266 503 -558 265 -266 269 -274 1001 -1006 1005 -984 1019 -998 1005 -1004 987 -1004 997 -1044 257 -248 279 -252 259 -296 501 -522 525 -520 525 -520 261 -296 503 -528 525 -520 259 -256 257 -294 267 -268 501 -558 231 -296 501 -560 497 -524 261 -262 259 -296 265 -264 501 -522 263 -294 265 -270 271 -308 241 -276 271 -270 233 -298 229 -298 267 -266 503 -558 231 -296 267 -306 239 -276 273 -270 497 -520 259 -290 227 -298 269 -270 505 -558 231 -298 271 -274 507 -522 521 -518 485 -550 257 -256 291 -264 269 -272 273 -308 241 -276 507 -522 259 -258 257 -296 265 -268 269 -270 271 -270 273 -308 241 -274 273 -270 497 -520 521 -518 259 -288 259 -264 503 -560 265 -266 271 -274 997 -1012 1011 -984 1005 -988 1007 -1014 1001 -1010 979 -1040 255 -274 245 -278 253 -292 495 -524 527 -520 525 -520 261 -296 499 -528 527 -520 259 -256 257 -294 265 -268 503 -556 231 -298 501 -560 499 -522 261 -260 261 -296 263 -266 501 -522 263 -294 265 -268 273 -308 241 -276 271 -270 231 -298 231 -298 267 -266 501 -558 231 -298 267 -304 241 -274 273 -270 499 -520 259 -258 259 -296 267 -270 507 -558 231 -300 271 -272 507 -522 521 -516 487 -550 259 -254 291 -266 269 -304 241 -308 241 -274 507 -524 259 -258 257 -296 265 -268 269 -270 271 -270 273 -308 241 -274 273 -270 497 -520 489 -548 261 -288 261 -264 503 -558 265 -266 271 -274 1001 -1010 977 -1028 981 -1024 1011 -978 997 -1014 1017 -1008 273 -252 255 -290 255 -290 491 -534 499 -522 527 -522 263 -294 503 -528 525 -520 259 -256 257 -294 267 -266 505 -558 231 -294 501 -558 499 -522 263 -260 261 -296 231 -298 499 -524 261 -296 265 -268 273 -306 241 -276 273 -270 231 -298 231 -296 267 -266 503 -558 231 -296 269 -304 239 -276 273 -270 497 -522
RAW_Data: 259 -258 259 -296 269 -270 505 -558 231 -300 271 -272 505 -524 521 -520 485 -552 227 -286 255 -298 269 -272 273 -308 241 -276 505 -524 259 -258 257 -296 265 -268 269 -270 271 -270 273 -308 241 -274 273 -270 497 -520 521 -518 259 -288 259 -266 503 -558 265 -266 271 -276 997 -1014 975 -1018 1009 -986 1009 -1018 985 -1002 1009 -1006 257 -274 275 -276 249 -286 493 -526 525 -520 523 -520 263 -296 501 -526 529 -520 259 -256 255 -296 265 -268 267 -32700 99 -100 529 -100 397 -134 231

View File

@@ -1,25 +0,0 @@
Filetype: Flipper SubGhz RAW File
Version: 1
Frequency: 433920000
Preset: FuriHalSubGhzPresetOok650Async
Protocol: RAW
RAW_Data: 51 -5136 1113 -104 127 -606 179 -126 325 -102 147 -200 205 -80 107 -190 81 -54 135 -378 181 -204 199 -104 121 -146 51 -230 75 -76 227 -102 415 -236 159 -54 159 -212 77 -312 73 -74 75 -128 155 -102 125 -358 125 -198 173 -608 75 -248 203 -558 53 -186 367 -180 151 -132 133 -138 135 -424 51 -240 53 -132 703 -80 79 -80 129 -294 77 -102 193 -270 77 -52 131 -180 51 -76 77 -76 51 -666 77 -104 101 -54 77 -164 107 -622 615 -294 133 -138 217 -180 75 -104 185 -80 107 -134 159 -398 181 -74 97 -198 73 -76 99 -102 127 -248 71 -128 211 -106 109 -104 101 -384 311 -398 51 -240 111 -84 81 -110 81 -668 105 -54 77 -158 79 -342 493 -78 153 -152 179 -122 223 -696 139 -590 81 -212 83 -322 129 -132 307 -346 129 -78 77 -232 77 -104 503 -52 187 -290 159 -108 159 -108 51 -136 53 -132 103 -566 177 -326 129 -176 177 -52 355 -308 129 -176 73 -104 151 -262 193 -168 111 -162 247 -52 131 -54 107 -84 83 -218 135 -402 107 -300 105 -220 81 -82 137 -82 163 -238 51 -192 293 -184 319 -454 81 -132 131 -132 79 -866 131 -212 163 -112 133 -106 211 -110 189 -214 51 -410 107 -454 131 -562 157 -52 367 -378 165 -110 81 -134 81 -82 75 -104 217 -638 81 -84 109 -160 81 -160 135 -54 53 -478 239 -78 209 -54 107 -52 155 -238 53 -184 105 -318 105 -370 233 -54 109 -246 217 -110 245 -110 209 -80 129 -514 79 -54 79 -314 155 -156 109 -292 79 -504 51 -644 157 -132 53 -208 53 -76 103 -76 77 -260 105 -82 133 -212 163 -136 53 -380 313 -178 193 -172 207 -82 79 -186 107 -136 53 -136 159 -156 97 -98 99 -254 179 -106 135 -214 307 -310 77 -76 123 -242 129 -52 103 -584 103 -178 203 -324 101 -572 253 -78 125 -126 129 -408 131 -52 129 -76 51 -132 79 -248 79 -414 51 -338 717 -322 79 -180 105 -294 109 -254 241 -76 251 -52 101 -152 125 -260 155 -80 77 -292 51 -226 209 -338 147 -100 51 -366 53 -348 133 -268 79 -366 55 -224 111 -248 81 -218 137 -168 79 -288 291 -132 51 -238 79 -78 103 -102 329 -102 123 -178 53 -202 51 -130 79 -138 51 -126 151 -180 99 -388 75 -126 51 -636 329 -150 99 -152 73 -122 177 -124 151 -386 297 -72 103 -130 51 -256 207 -354 75 -124 71 -148 351 -262 51 -540 77 -200 101 -132 77 -362 77 -254 103 -106 79 -296 51 -130 361 -240 51 -358 51 -284 201 -158 185 -288 183 -424 77 -130
RAW_Data: 121 -146 99 -124 327 -74 99 -148 99 -252 183 -112 161 -216 263 -232 77 -102 103 -416 77 -382 345 -160 131 -110 167 -138 79 -158 133 -54 163 -84 107 -80 107 -108 107 -136 225 -82 321 -108 79 -106 107 -106 55 -162 103 -160 133 -192 53 -84 269 -106 77 -162 53 -136 161 -82 135 -346 77 -864 107 -140 55 -250 189 -128 201 -502 157 -564 105 -52 107 -1150 53 -218 237 -76 159 -1010 129 -196 139 -244 101 -270 77 -106 133 -110 109 -254 501 -496 237 -692 107 -54 159 -134 347 -210 51 -190 55 -276 103 -184 229 -98 149 -252 123 -156 75 -150 537 -236 103 -204 101 -100 73 -368 283 -102 77 -652 229 -206 99 -150 197 -206 53 -80 131 -274 101 -186 159 -396 51 -188 81 -188 83 -350 105 -428 129 -128 79 -78 53 -104 351 -284 235 -130 79 -242 51 -186 77 -134 135 -434 131 -552 53 -136 107 -140 141 -252 53 -54 53 -82 51 -770 79 -130 103 -432 127 -208 153 -226 131 -248 101 -902 125 -206 129 -102 77 -154 77 -188 105 -322 105 -166 133 -474 77 -728 161 -190 107 -54 133 -80 79 -190 53 -162 53 -404 77 -334 105 -52 153 -728 423 -700 133 -476 53 -162 53 -542 159 -168 189 -134 163 -134 81 -106 133 -54 267 -108 163 -242 165 -56 167 -294 81 -136 185 -660 51 -304 157 -54 109 -378 133 -272 159 -304 135 -110 53 -402 105 -630 185 -78 257 -422 173 -252 247 -100 123 -330 107 -166 109 -502 127 -156 219 -76 101 -348 71 -586 149 -154 73 -74 77 -358 131 -270 81 -108 159 -516 295 -346 53 -240 157 -240 55 -562 133 -110 213 -320 103 -560 79 -286 51 -134 55 -452 79 -136 79 -80 77 -52 185 -504 79 -216 79 -242 135 -262 75 -206 125 -472 111 -564 79 -322 79 -432 217 -456 167 -272 103 -664 53 -302 127 -138 241 -184 53 -80 81 -192 395 -604 133 -136 53 -1044 105 -166 215 -426 133 -1222 101 -348 127 -124 123 -248 153 -492 177 -102 103 -180 77 -204 151 -282 101 -74 103 -76 101 -170 73 -506 101 -368 51 -124 193 -236 53 -310 77 -130 155 -366 229 -526 129 -428 83 -922 51 -106 131 -82 219 -706 79 -80 81 -162 133 -276 195 -220 51 -266 81 -54 51 -238 53 -686 77 -354 229 -164 195 -164 81 -294 81 -132 197 -238 73 -202 181 -180 149 -128 207 -192 111 -56 187 -808 77 -608 79 -898 77 -208 97 -200 73 -184 75 -78 203 -664 105 -384 103 -102 129 -238 131 -1346 137 -526 105 -390 129 -138 81 -484 103 -222 109 -268 51 -240
RAW_Data: 81 -658 53 -626 79 -562 79 -52 77 -266 107 -54 109 -410 105 -514 107 -110 53 -334 79 -928 121 -498 105 -184 149 -174 73 -908 129 -388 199 -450 153 -862 51 -896 101 -776 51 -990 129 -154 177 -412 169 -254 77 -902 105 -474 77 -2390 103 -1000 107 -2112 151 -402 51 -428 337 -440 129 -590 197 -538 53 -138 81 -584 81 -1958 107 -4714 57 -786 53 -684 137 -442 105 -654 53 -696 51 -2382 105 -376 83 -822 155 -6282 103 -560 77 -252 79 -1518 103 -3648 51 -6150 75 -4986 75 -2042 53 -2798 171 -804 2247 -130 357 -168 309 -168 307 -170 293 -172 305 -192 279 -224 253 -224 279 -196 265 -224 261 -222 253 -224 253 -224 279 -214 245 -232 243 -252 253 -224 251 -226 241 -222 253 -246 251 -224 253 -224 251 -252 213 -248 261 -222 251 -226 251 -254 223 -242 245 -232 245 -250 225 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 213 -248 233 -248 253 -224 253 -252 223 -242 247 -230 245 -252 223 -252 253 -224 241 -222 255 -244 251 -226 251 -224 253 -252 213 -248 233 -250 251 -226 251 -252 225 -242 245 -230 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 251 -254 213 -246 235 -248 251 -226 251 -254 223 -242 245 -232 245 -252 225 -252 251 -224 253 -214 245 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -226 251 -224 253 -252 213 -248 233 -250 251 -226 253 -252 223 -242 245 -232 243 -254 223 -254 251 -224 253 -214 245 -236 247 -254 251 -224 253 -224 241 -246 231 -246 251 -226 251 -252 225 -252 213 -248 261 -224 251 -226 251 -252 225 -252 213 -250 261 -222 253 -224 253 -252 225 -242 245 -230 245 -252 225 -252 251 -226 241 -220 255 -246 249 -226 251 -226 251 -254 213 -248 233 -248 251 -226 251 -254 223 -242 245 -232 245 -252 223 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 213 -248 233 -248 253 -224 253 -252 223 -242 245 -232 245 -252 223 -252 253 -224 241 -222 255 -244 251 -226 251 -224 253 -252 213 -246 235 -248 251 -254 223 -252 225 -242 245 -232 245 -252 223 -254 251 -226 241 -222 253 -246 251 -224 253 -224 251 -254 213 -248 233 -248 251 -226 251 -254 223 -242 245 -230 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 251 -254 213 -248 233 -248 253 -224 253 -252 225 -252 213 -248 261 -224 251 -226 251 -252 225 -242 245 -230 245 -254 223 -252 253 -224 241 -222 253 -246 251 -226 251 -224 251 -254 213 -248 259 -224 251 -226
RAW_Data: 251 -254 223 -242 245 -230 245 -252 225 -252 251 -226 251 -214 247 -234 249 -252 251 -226 251 -224 241 -248 229 -248 251 -224 253 -224 251 -254 213 -246 261 -224 251 -226 251 -252 225 -242 245 -230 247 -252 223 -252 253 -224 243 -220 255 -244 251 -226 251 -226 251 -252 213 -248 233 -248 251 -252 225 -252 225 -242 245 -232 245 -252 223 -254 251 -224 253 -214 247 -236 247 -252 251 -226 251 -226 241 -246 231 -246 251 -224 253 -224 251 -254 213 -248 233 -248 253 -252 223 -254 223 -242 245 -232 245 -252 223 -254 251 -226 241 -220 255 -244 251 -226 251 -226 251 -252 213 -248 233 -250 251 -226 251 -252 225 -242 245 -230 245 -254 223 -252 253 -224 241 -222 253 -246 251 -224 253 -224 253 -252 213 -246 235 -248 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -226 251 -214 247 -234 247 -254 251 -224 253 -224 241 -246 231 -246 251 -226 251 -226 251 -252 213 -248 261 -222 253 -224 253 -252 225 -242 245 -230 245 -254 223 -252 253 -224 253 -214 245 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -226 251 -252 225 -252 213 -248 235 -248 251 -254 223 -252 225 -242 245 -230 247 -252 223 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 215 -246 235 -248 251 -224 479 -484 501 -482 461 -492 483 -466 255 -234 245 -252 223 -254 251 -226 241 -222 487 -480 253 -222 489 -480 251 -246 465 -482 251 -246 231 -246 483 -468 255 -234 481 -488 233 -246 233 -248 483 -466 255 -234 245 -252 225 -252 251 -226 469 -494 483 -488 483 -482 221 -250 473 -488 479 -490 231 -248 231 -246 251 -226 251 -226 251 -252 467 -476 249 -252 223 -252 469 -494 481 -470 485 -484 247 -252 469 -462 481 -498 229 -252 243 -252 225 -252 223 -254 251 -214 477 -484 247 -250 251 -214 247 -234 247 -252 481 -460 261 -244 251 -226 479 -486 1435 -1456 231 -236 247 -252 225 -252 253 -224 241 -222 253 -246 251 -224 253 -224 253 -252 213 -246 261 -222 251 -226 251 -252 225 -242 245 -230 247 -252 481 -462 493 -480 481 -492 481 -462 255 -224 263 -222 253 -252 223 -254 223 -242 475 -484 249 -222 505 -488 245 -222 469 -496 247 -252 223 -254 469 -490 249 -224 477 -482 237 -250 249 -226 479 -484 239 -246 251 -226 251 -226 251 -252 467 -474 481 -490 491 -456 271 -224 469 -494 481 -492 229 -236 245 -252 225 -252 251 -226 241 -222 487 -482 251 -246 231 -246 483 -468 487 -482 473 -486 265 -222 485 -492 461 -484 247 -250
RAW_Data: 253 -214 245 -234 247 -252 225 -252 473 -486 243 -252 225 -254 223 -254 251 -214 477 -486 245 -252 223 -242 477 -484 1463 -1444 249 -222 253 -224 241 -246 233 -248 251 -226 251 -254 223 -252 213 -248 261 -224 251 -226 251 -254 223 -242 245 -232 245 -252 223 -252 253 -224 469 -496 483 -488 457 -506 479 -462 259 -244 223 -252 253 -224 251 -226 241 -246 467 -478 253 -246 467 -480 251 -248 465 -480 251 -248 229 -248 483 -468 255 -232 483 -474 255 -224 265 -224 483 -492 229 -236 249 -252 223 -252 253 -224 469 -496 479 -482 491 -480 225 -246 485 -482 491 -462 245 -252 253 -224 253 -224 241 -246 231 -246 483 -488 229 -250 241 -252 457 -490 489 -460 497 -484 243 -224 483 -490 489 -458 249 -248 249 -240 249 -226 251 -226 251 -226 493 -472 249 -252 223 -252 223 -242 245 -234 483 -488 233 -246 233 -248 483 -468 1451 -1448 229 -492 247 -248 79 -400 157 -566 133 -108 379 -218 109 -54 163 -164 51 -102 315 -260 263 -80 463 -234 151 -76 149 -154 249 -126 99 -130 125 -270 127 -188 427 -210 131 -222 593 -106 241 -562 239 -84 305 -262 183 -80 53 -524 125 -480 227 -328 51 -350 211 -82 181 -108 215 -106 147 -200 183 -104 397 -52 131 -102 147 -172 335 -618 177 -206 131 -220 129 -158 213 -52 187 -164 135 -334 157 -410 73 -120 225 -234 133 -108 81 -138 599 -238 131 -262 77 -368 209 -130 103 -76 335 -78 101 -232 253 -280 97 -74 73 -74 97 -52 383 -272 125 -104 81 -82 455 -106 159 -78 127 -52 183 -358 55 -170 139 -86 53 -108 299 -52 129 -282 385 -104 101 -514 75 -232 153 -510 75 -174 97 -128 151 -152 101 -206 103 -76 227 -308 77 -302 129 -76 77 -592 175 -202 75 -314 157 -400 343 -52 185 -104 135 -136 129 -108 111 -112 271 -266 161 -108 107 -240 343 -342 213 -128 99 -124 181 -54 103 -200 101 -274 157 -104 131 -154 123 -588 105 -108 107 -54 161 -52 349 -184 83 -84 53 -54 133 -540 105 -52 53 -160 105 -334 481 -180 101 -304 257 -176 77 -286 79 -106 179 -102 73 -554 285 -184 77 -396 103 -264 185 -106 233 -732 235 -108 53 -82 185 -140 137 -188 285 -294 281 -338 127 -378 77 -242 239 -112 327 -106 219 -240 55 -54 109 -584 51 -134 79 -80 215 -80 109 -54 81 -264 157 -310 51 -130 161 -140 375 -290 129 -886 263 -78 51 -342 55 -104 207 -288 271 -108 179 -74 75 -460 257 -280 77 -106 51 -104 53 -150 125 -174 155 -80 221 -108 161 -310
RAW_Data: 77 -104 51 -208 79 -452 379 -130 51 -318 237 -214 257 -180 77 -298 79 -604 103 -398 187 -346 181 -154 97 -174 285 -156 51 -102 583 -78 75 -74 151 -102 255 -158 339 -80 77 -234 155 -102 101 -250 75 -76 147 -150 123 -100 75 -78 259 -180 251 -80 51 -104 77 -130 77 -52 159 -236 103 -622 173 -1016 131 -184 153 -156 73 -274 331 -292 105 -204 199 -516 103 -210 157 -104 287 -304 153 -78 129 -78 385 -332 179 -286 181 -178 145 -176 121 -76 169 -146 123 -102 181 -180 51 -176 147 -230 103 -172 75 -208 199 -52 153 -52 75 -134 265 -80 51 -182 157 -110 237 -104 183 -198 213 -168 219 -132 75 -78 101 -76 101 -306 231 -130 99 -152 125 -130 105 -132 135 -110 133 -476 213 -54 325 -322 209 -404 303 -106 81 -166 403 -134 105 -242 403 -104 129 -182 55 -174 165 -168 83 -304 185 -130 133 -108 135 -134 103 -52 181 -362 207 -54 179 -228 231 -236 105 -214 53 -158 77 -452 319 -106 79 -348 349 -406 133 -84 195 -104 239 -158 197 -164 79 -80 79 -54 79 -156 201 -374 941 -492 77 -174 73 -230 75 -278 177 -52 477 -306 129 -106 79 -108 113 -196 127 -328 51 -102 125 -76 75 -102 153 -76 99 -146 373 -134 185 -134 105 -352 105 -436 127 -246 51 -106 79 -238 131 -82 165 -270 109 -108 79 -634 157 -242 105 -78 129 -52 131 -266 215 -270 329 -162 51 -478 209 -52 157 -372 79 -82 367 -560 129 -210 53 -54 133 -106 133 -292 77 -106 159 -84 185 -80 509 -54 473 -80 103 -108 105 -158 51 -180 123 -122 71 -208 129 -210 371 -212 75 -110 341 -164 425 -130 181 -54 313 -278 51 -52 129 -386 263 -78 245 -344 287 -134 133 -130 81 -276 105 -114 129 -106 487 -78 127 -182 179 -146 127 -148 125 -186 133 -182 127 -76 195 -96 103 -76 75 -52 101 -204 77 -102 405 -102 75 -224 125 -276 153 -100 147 -350 259 -156 77 -128 463 -76 77 -234 103 -252 51 -286 75 -232 201 -102 75 -176 175 -124 151 -100 51 -254 97 -74 123 -122 123 -174 201 -154 129 -190 53 -136 81 -78 79 -216 133 -106 111 -84 137 -136 163 -324 103 -78 51 -56 109 -106 177 -168 75 -492 131 -52 131 -180 73 -74 359 -104 101 -102 101 -492 159 -290 215 -80 187 -214 103 -160 135 -130 175 -126 107 -54 75 -78 77 -152 199 -604 97 -74 101 -284 127 -52 177 -434 153 -122 781 -208 79 -80 105 -292 135 -84 247 -318 51 -430 79 -162 109 -56 135 -190 185 -78 159 -130
RAW_Data: 185 -188 137 -108 331 -56 79 -132 167 -188 107 -320 393 -310 99 -154 51 -180 153 -74 101 -76 229 -128 183 -184 249 -108 299 -82 191 -532 295 -400 103 -80 79 -272 53 -276 213 -84 55 -110 291 -106 123 -204 101 -102 77 -104 157 -102 51 -126 51 -126 183 -140 83 -264 53 -134 261 -128 81 -82 81 -298 81 -266 77 -52 51 -474 265 -366 103 -226 239 -166 677 -232 175 -150 205 -76 123 -76 97 -176 127 -284 77 -76 357 -182 73 -326 171 -104 675 -236 301 -216 53 -84 107 -52 157 -78 237 -136 289 -130 215 -350 77 -320 187 -110 347 -240 159 -134 79 -486 207 -272 129 -82 293 -188 105 -212 77 -216 445 -836 151 -150 73 -262 75 -102 253 -52 101 -102 281 -386 149 -230 355 -212 51 -130 329 -224 149 -52 75 -204 77 -108 85 -194 341 -134 269 -132 161 -56 81 -556 187 -448 395 -130 177 -136 107 -184 239 -136 53 -214 135 -266 79 -368 109 -372 315 -78 79 -78 103 -132 53 -82 81 -104 129 -182 125 -74 103 -236 211 -294 205 -216 131 -108 211 -236 79 -54 103 -104 161 -54 265 -54 187 -162 107 -134 183 -190 237 -104 51 -186 107 -164 137 -102 77 -206 197 -238 107 -52 53 -78 155 -126 201 -78 125 -204 103 -102 75 -104 253 -76 105 -238 159 -366 209 -216 165 -56 55 -322 585 -80 183 -108 81 -136 109 -168 211 -236 295 -674 337 -78 211 -312 77 -242 297 -378 215 -190 79 -298 161 -108 183 -122 121 -252 103 -516 105 -54 123 -226 291 -78 77 -104 53 -484 197 -452 51 -306 77 -106 127 -178 51 -256 209 -264 101 -76 101 -126 151 -126 251 -1152 359 -126 325 -254 551 -156 83 -666 161 -236 105 -186 103 -108 161 -80 157 -54 51 -344 159 -82 349 -160 141 -270 131 -578 189 -162 287 -134 161 -712 127 -106 51 -108 345 -704 431 -362 51 -52 415 -208 233 -342 257 -288 131 -80 77 -252 53 -330 105 -160 83 -280 393 -358 103 -480 161 -134 51 -54 259 -104 129 -130 105 -80 217 -350 269 -192 57 -302 79 -264 81 -326 157 -80 79 -214 51 -370 129 -236 53 -136 105 -82 57 -140 137 -52 79 -236 103 -80 55 -192 293 -188 53 -348 185 -236 207 -56 135 -54 215 -216 587 -132 103 -160 133 -158 365 -52 103 -54 107 -80 185 -298 267 -136 159 -110 109 -82 241 -78 77 -78 101 -82 141 -226 55 -462 79 -188 81 -216 511 -210 79 -162 161 -160 101 -388 157 -180 101 -100 197 -336 581 -130 211 -264 155 -52 297 -180 75 -100 73 -100 247 -130
RAW_Data: 133 -346 505 -108 105 -80 243 -292 79 -104 339 -78 75 -128 287 -398 99 -300 479 -104 257 -130 153 -78 359 -152 79 -300 77 -348 109 -82 217 -108 243 -80 185 -430 133 -460 211 -234 207 -52 291 -80 77 -54 81 -82 265 -78 101 -132 255 -122 73 -512 129 -126 77 -158 213 -168 81 -82 479 -160 159 -108 157 -158 133 -236 129 -128 485 -126 153 -412 99 -250 255 -274 173 -358 231 -76 53 -78 131 -54 135 -290 77 -102 305 -128 77 -310 183 -80 239 -80 135 -166 189 -104 81 -140 111 -164 477 -488 51 -134 53 -80 429 -240 529 -476 287 -80 189 -136 327 -84 79 -160 293 -348 133 -148 179 -52 231 -102 175 -76 125 -100 425 -228 77 -200 183 -154 231 -212 253 -78 299 -132 145 -124 337 -150 101 -132 99 -274 153 -182 53 -158 51 -160 453 -134 427 -182 77 -134 275 -528 77 -108 79 -110 109 -110 245 -136 171 -164 473 -106 265 -80 267 -184 179 -330 287 -212 185 -350 129 -630 467 -350 489 -166 107 -56 79 -270 53 -84 757 -624 207 -102 51 -416 287 -288 103 -406 73 -132 51 -214 135 -644 103 -146 73 -358 629 -736 309 -150 275 -254 51 -106 53 -54 105 -80 53 -180 77 -110 297 -106 79 -418 261 -80 161 -80 77 -480 79 -156 215 -190 601 -130 353 -76 73 -76 127 -198 125 -100 531 -78 77 -438 103 -134 191 -312 291 -108 53 -134 53 -214 317 -80 277 -182 279 -302 329 -104 479 -182 203 -98 273 -222 247 -250 241 -252 219 -248 221 -254 243 -252 225 -254 223 -252 253 -214 245 -236 247 -252 251 -226 251 -224 241 -222 255 -246 251 -226 251 -226 251 -252 213 -248 235 -248 253 -224 253 -252 225 -242 245 -230 245 -252 223 -254 251 -224 253 -214 247 -236 247 -252 251 -226 251 -226 241 -222 255 -246 251 -224 253 -224 251 -254 213 -248 233 -248 253 -224 253 -252 223 -242 247 -230 245 -252 225 -252 253 -224 251 -214 247 -236 247 -254 251 -224 253 -224 241 -246 231 -246 251 -226 251 -224 253 -252 213 -248 235 -248 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 241 -222 253 -246 251 -224 253 -224 253 -252 213 -248 233 -248 251 -226 253 -252 223 -242 245 -232 245 -252 225 -252 253 -224 251 -214 247 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -224 253 -252 225 -252 213 -248 233 -248 253 -252 225 -252 223 -244 245 -230 245 -254 223 -252 253 -224 253 -214 245 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -224 253 -252 223 -252
RAW_Data: 213 -248 263 -222 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 253 -214 247 -234 249 -252 251 -226 251 -224 241 -246 231 -246 251 -226 251 -254 223 -252 213 -248 261 -222 253 -252 223 -254 223 -242 245 -232 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 253 -252 213 -246 261 -222 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 241 -222 253 -246 251 -224 253 -224 253 -252 213 -248 235 -248 251 -224 251 -254 223 -242 245 -232 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 253 -252 213 -246 261 -222 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 243 -220 253 -246 251 -226 251 -224 251 -254 213 -248 233 -248 251 -254 223 -254 223 -242 245 -232 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 253 -252 213 -248 233 -248 251 -226 251 -252 225 -242 245 -230 247 -252 223 -254 251 -224 253 -214 245 -236 247 -254 251 -224 253 -224 241 -246 231 -246 251 -224 253 -224 253 -242 219 -256 243 -254 223 -254 251 -224 253 -214 245 -236 247 -252 251 -226 251 -224 243 -246 229 -248 251 -224 253 -252 223 -254 213 -246 261 -224 251 -226 251 -254 223 -242 245 -232 245 -252 223 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 213 -248 233 -248 253 -224 253 -252 223 -254 213 -248 263 -222 253 -224 253 -252 223 -242 245 -232 245 -252 223 -254 251 -226 241 -220 253 -246 251 -226 251 -224 253 -252 213 -248 261 -222 251 -226 251 -254 223 -242 245 -232 243 -252 225 -252 253 -224 241 -222 253 -246 251 -226 251 -224 251 -254 213 -246 261 -222 253 -224 253 -252 223 -242 247 -230 245 -252 223 -254 251 -224 243 -220 255 -246 249 -226 251 -226 251 -254 213 -246 235 -248 251 -226 251 -252 225 -242 245 -230 245 -252 225 -252 253 -224 251 -214 247 -236 247 -254 251 -224 253 -224 241 -246 231 -246 251 -226 251 -224 253 -252 213 -248 261 -222 251 -226 253 -252 223 -242 245 -232 245 -252 225 -252 253 -224 251 -214 247 -234 249 -252 251 -226 251 -224 241 -246 231 -246 251 -226 251 -226 251 -254 213 -248 261 -220 253 -252 225 -252 223 -242 247 -230 245 -254 479 -462 495 -482 479 -490 481 -470 229 -254 245 -250 225 -252 223 -254 251 -214 503 -458 249 -248 481 -484 243 -224 495 -472 249 -252 223 -252 471 -490 249 -224 479 -486 473 -482 241 -242 477 -482 247 -250 253 -214 245 -234 247 -252 481 -462 495 -482
RAW_Data: 465 -488 245 -252 479 -480 473 -488 243 -252 213 -246 261 -224 251 -224 253 -252 469 -466 245 -254 251 -224 473 -486 481 -480 485 -482 247 -224 505 -458 499 -484 243 -252 223 -252 225 -252 223 -242 247 -232 483 -490 485 -472 249 -252 473 -484 243 -224 483 -492 231 -234 485 -488 487 -472 1445 -1448 237 -248 251 -226 251 -224 253 -252 213 -246 261 -222 251 -254 223 -252 225 -242 245 -230 247 -252 223 -254 251 -224 243 -220 255 -244 251 -226 477 -482 501 -454 507 -480 479 -462 259 -244 251 -224 253 -224 251 -226 241 -246 493 -464 241 -242 475 -484 249 -222 505 -484 225 -246 251 -242 485 -470 229 -254 477 -480 485 -482 247 -224 495 -464 273 -224 253 -224 251 -226 241 -246 493 -480 479 -470 481 -480 233 -266 459 -488 485 -476 247 -252 223 -254 251 -214 245 -234 247 -252 481 -462 259 -244 251 -226 479 -486 469 -482 481 -492 247 -224 477 -482 503 -464 241 -242 245 -232 245 -254 223 -252 253 -224 469 -496 483 -486 229 -252 477 -476 227 -248 497 -480 227 -254 477 -480 483 -482 1439 -1452 245 -252 223 -254 223 -252 253 -214 245 -234 247 -252 225 -252 251 -226 241 -222 253 -246 251 -226 251 -226 251 -252 213 -248 261 -222 253 -224 479 -484 501 -482 461 -492 483 -466 255 -234 245 -252 225 -252 253 -224 241 -222 487 -480 253 -222 489 -480 251 -248 463 -482 251 -246 231 -246 483 -488 229 -252 477 -478 485 -480 223 -248 479 -484 247 -250 251 -214 247 -234 247 -252 481 -460 493 -482 479 -492 249 -224 477 -480 477 -488 243 -240 245 -234 245 -252 223 -254 251 -226 469 -494 247 -224 253 -252 469 -488 483 -470 485 -482 247 -224 497 -462 483 -490 231 -248 233 -248 251 -226 251 -252 225 -242 475 -484 475 -484 239 -250 483 -468 255 -232 483 -490 231 -246 493 -480 481 -470 1445 -1448 239 -772 105 -194 247 -314 105 -176 125 -126 151 -382 51 -266 51 -104 55 -400 129 -114 243 -210 343 -78 161 -108 107 -110 53 -214 83 -242 209 -80 155 -82 53 -268 391 -80 79 -214 211 -132 131 -320 77 -320 157 -138 191 -136 103 -202 99 -446 213 -406 131 -286 101 -258 51 -188 55 -82 81 -162 237 -130 183 -512 291 -80 193 -342 77 -106 159 -272 77 -52 53 -78 183 -544 79 -106 277 -338 185 -132 153 -108 107 -108 163 -54 107 -134 235 -356 523 -108 137 -134 291 -80 79 -214 213 -266 137 -54 53 -162 165 -84 191 -78 53 -132 213 -318 79 -264 215 -320 159 -82 53 -246 131 -132 175 -102 227 -228
RAW_Data: 315 -106 53 -872 139 -136 209 -332 177 -272 417 -180 51 -52 181 -338 77 -130 51 -104 151 -52 127 -152 99 -76 155 -126 203 -180 151 -126 101 -200 179 -384 123 -592 153 -80 127 -466 75 -100 121 -98 123 -126 97 -336 359 -104 107 -192 55 -80 103 -190 81 -132 79 -78 207 -128 109 -216 183 -270 105 -80 129 -52 51 -354 85 -194 135 -238 243 -82 81 -370 295 -130 135 -136 137 -190 211 -188 81 -184 53 -80 159 -82 55 -350 319 -160 355 -210 99 -462 53 -130 277 -204 619 -184 471 -78 131 -378 453 -162 171 -86 165 -222 81 -82 315 -210 101 -78 383 -102 101 -180 207 -416 183 -310 259 -200 225 -146 333 -460 185 -78 211 -192 85 -84 353 -82 79 -80 213 -158 75 -156 131 -226 133 -54 107 -134 105 -106 131 -80 267 -132 187 -192 271 -110 105 -82 79 -270 135 -102 185 -134 185 -54 191 -134 249 -368 53 -238 79 -54 185 -526 51 -376 243 -586 109 -346 81 -82 179 -78 267 -206 177 -100 125 -104 173 -74 77 -152 155 -186 83 -190 351 -164 135 -106 109 -142 337 -214 81 -188 79 -78 103 -228 101 -226 175 -214 315 -52 79 -184 77 -240 291 -54 79 -80 51 -624 135 -134 203 -146 223 -74 135 -238 133 -134 129 -380 133 -190 79 -108 241 -186 181 -416 155 -134 157 -128 305 -134 425 -508 283 -128 181 -826 127 -268 77 -368 261 -54 189 -374 415 -156 201 -178 177 -206 127 -234 79 -380 133 -54 161 -236 53 -184 79 -298 53 -294 77 -312 177 -154 77 -208 369 -78 53 -160 215 -106 557 -320 473 -274 343 -78 99 -100 119 -72 155 -98 123 -76 257 -280 51 -260 157 -78 127 -52 99 -74 569 -302 131 -428 77 -336 101 -102 177 -230 97 -124 51 -102 75 -156 251 -126 173 -326 79 -428 123 -380 281 -238 161 -158 157 -230 395 -202 123 -220 255 -104 97 -198 77 -100 551 -76 101 -256 231 -410 77 -102 75 -230 105 -158 51 -132 105 -340 215 -108 241 -134 129 -160 191 -292 51 -852 155 -186 77 -52 103 -578 77 -106 209 -132 107 -130 53 -164 455 -78 155 -244 185 -160 217 -216 381 -130 127 -514 209 -82 55 -136 103 -104 173 -226 231 -176 73 -130 205 -102 319 -244 53 -160 107 -162 57 -350 97 -230 203 -252 127 -360 79 -316 103 -180 101 -178 185 -216 101 -302 257 -182 103 -126 75 -152 103 -102 77 -284 413 -612 177 -432 73 -460 79 -78 53 -556 155 -664 75 -214 327 -134 79 -134 133 -136 51 -82 103 -130 145 -74 199 -128 51 -102 103 -482
RAW_Data: 179 -100 177 -52 103 -158 191 -110 81 -190 217 -326 51 -280 147 -602 209 -76 99 -124 293 -108 193 -192 241 -184 131 -106 159 -52 77 -132 53 -104 101 -188 79 -538 105 -80 107 -52 213 -428 243 -84 81 -132 265 -140 77 -80 51 -214 189 -140 301 -162 75 -102 231 -178 123 -264 123 -98 125 -76 103 -238 77 -228 183 -140 165 -552 297 -54 291 -186 185 -234 155 -78 79 -180 53 -82 505 -182 103 -128 123 -280 133 -158 103 -644 213 -330 77 -106 79 -424 155 -212 163 -192 189 -508 369 -80 79 -220 111 -166 79 -304 133 -108 139 -140 189 -78 51 -348 289 -104 187 -54 109 -508 131 -108 283 -516 99 -100 299 -380 199 -152 325 -304 229 -476 75 -148 101 -102 75 -208 77 -74 125 -74 73 -76 181 -176 179 -186 235 -130 79 -184 77 -152 121 -304 127 -484 103 -152 173 -100 157 -176 185 -82 177 -156 309 -106 79 -132 51 -236 179 -154 73 -236 77 -74 71 -160 235 -130 105 -108 247 -56 53 -208 75 -74 75 -128 505 -154 179 -76 51 -278 103 -178 99 -126 183 -54 161 -526 133 -80 79 -298 105 -236 77 -264 139 -54 243 -164 459 -208 51 -236 105 -370 79 -374 77 -182 129 -202 77 -158 107 -108 107 -82 245 -244 109 -82 81 -292 179 -52 129 -164 423 -52 153 -102 151 -100 125 -76 259 -78 365 -240 107 -162 105 -244 163 -56 163 -108 159 -52 79 -260 79 -502 133 -82 323 -552 105 -210 699 -78 189 -192 105 -128 165 -188 105 -158 77 -158 79 -54 131 -498 131 -130 101 -176 125 -170 213 -52 77 -106 53 -292 389 -104 133 -402 133 -80 109 -54 53 -104 79 -182 505 -54 161 -264 181 -212 107 -164 83 -244 315 -234 127 -130 147 -150 231 -456 101 -124 73 -104 287 -320 81 -134 107 -244 267 -78 157 -108 137 -84 133 -54 79 -186 107 -262 77 -80 81 -240 53 -82 107 -136 245 -110 185 -294 259 -134 135 -80 159 -566 107 -190 187 -190 79 -54 107 -80 107 -54 135 -164 165 -56 79 -54 349 -78 75 -104 157 -320 53 -82 421 -180 97 -172 105 -106 111 -280 163 -132 193 -250 107 -318 155 -266 109 -162 183 -242 105 -484 79 -106 125 -246 99 -492 75 -180 127 -100 95 -196 75 -152 537 -214 53 -186 103 -134 81 -108 109 -560 51 -382 153 -104 51 -188 373 -240 53 -266 129 -622 51 -132 81 -58 137 -364 263 -78 235 -82 177 -486 105 -276 157 -108 237 -80 105 -132 131 -258 289 -102 51 -104 103 -104 73 -508 283 -102 51 -230 99 -178 105 -106
RAW_Data: 53 -190 105 -160 157 -158 129 -80 241 -162 277 -260 77 -312 157 -320 193 -108 77 -184 77 -102 125 -286 107 -82 371 -266 447 -218 271 -106 51 -162 107 -194 333 -264 99 -76 75 -150 345 -444 105 -696 75 -154 185 -348 105 -108 159 -296 161 -80 107 -222 81 -106 239 -80 75 -78 105 -52 323 -246 51 -162 79 -130 157 -618 241 -82 107 -106 133 -294 137 -108 53 -104 107 -80 51 -80 267 -106 77 -212 105 -84 81 -56 131 -132 211 -78 187 -138 131 -104 53 -78 311 -210 77 -80 109 -160 239 -208 51 -292 443 -158 167 -138 185 -232 293 -78 181 -136 53 -186 107 -108 53 -80 395 -130 299 -160 53 -162 109 -56 135 -468 75 -102 229 -396 105 -98 277 -386 339 -356 125 -226 291 -270 165 -80 79 -106 77 -244 189 -162 215 -672 343 -184 75 -450 131 -208 57 -114 107 -420 53 -106 81 -188 103 -136 501 -110 211 -76 161 -294 107 -54 55 -206 75 -100 75 -432 77 -248 51 -78 419 -52 535 -106 207 -230 99 -124 179 -100 71 -76 77 -400 53 -340 185 -188 235 -106 105 -220 55 -134 53 -346 53 -192 291 -346 209 -242 185 -158 51 -128 75 -176 153 -282 159 -158 73 -330 105 -634 323 -242 79 -210 181 -52 103 -54 107 -108 105 -330 105 -272 51 -206 227 -154 129 -194 285 -80 79 -266 127 -492 131 -432 181 -108 213 -242 107 -346 207 -78 157 -160 53 -108 53 -322 83 -674 317 -188 243 -186 81 -166 111 -84 535 -78 181 -134 327 -240 103 -206 77 -78 177 -152 121 -70 75 -100 535 -152 75 -78 101 -368 267 -168 217 -688 383 -222 247 -234 275 -224 251 -226 251 -224 241 -222 255 -246 251 -224 253 -224 251 -252 215 -246 261 -222 253 -224 253 -252 223 -242 245 -232 245 -252 225 -252 253 -224 253 -214 245 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -224 251 -254 223 -242 221 -254 245 -252 225 -252 251 -226 251 -214 247 -236 247 -252 253 -224 251 -226 241 -246 229 -246 251 -226 251 -254 223 -252 213 -248 261 -224 251 -226 251 -252 225 -242 245 -230 245 -254 223 -252 253 -224 253 -214 245 -236 247 -252 251 -226 251 -224 243 -246 229 -248 251 -224 253 -252 223 -254 213 -248 261 -222 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 243 -220 255 -244 251 -226 251 -226 251 -252 213 -248 261 -220 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 243 -220 255 -246 249 -226 251 -226 251 -252 213 -248 235 -248 251 -226 251 -252
RAW_Data: 225 -242 245 -230 247 -252 223 -252 253 -224 243 -220 255 -244 251 -226 251 -226 251 -252 213 -248 233 -248 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 253 -214 247 -234 249 -252 251 -226 251 -224 241 -246 231 -246 251 -226 251 -226 251 -252 213 -248 261 -224 251 -226 251 -252 225 -242 245 -230 245 -252 225 -252 253 -224 253 -212 247 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -224 253 -252 225 -252 213 -248 261 -222 253 -224 253 -252 223 -242 247 -230 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 251 -252 213 -248 233 -250 251 -224 253 -252 225 -242 245 -230 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 253 -252 213 -248 233 -250 251 -224 253 -252 223 -242 245 -232 245 -252 223 -254 251 -224 253 -214 247 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -224 253 -252 223 -252 213 -248 261 -224 251 -252 223 -254 223 -242 245 -232 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 251 -254 213 -246 261 -224 251 -226 251 -252 225 -242 245 -230 245 -252 223 -254 251 -224 243 -220 255 -244 251 -226 251 -226 251 -252 213 -248 261 -222 251 -226 251 -254 223 -242 245 -232 243 -252 225 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 213 -248 233 -248 251 -254 223 -252 225 -242 245 -232 245 -252 223 -254 251 -224 241 -222 255 -244 251 -226 251 -226 251 -254 213 -246 235 -248 251 -226 251 -254 223 -242 245 -230 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 251 -254 213 -248 233 -248 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -226 241 -220 255 -246 249 -226 253 -224 251 -254 213 -246 235 -248 251 -226 251 -252 225 -242 245 -230 245 -252 225 -252 253 -224 241 -220 255 -246 249 -226 251 -226 251 -252 213 -248 261 -222 253 -224 253 -252 223 -242 247 -230 245 -252 225 -252 251 -226 251 -214 247 -234 249 -252 251 -226 251 -224 241 -248 229 -248 249 -226 253 -252 223 -252 213 -248 263 -222 251 -226 251 -254 223 -242 245 -230 245 -254 223 -252 253 -224 241 -222 255 -244 251 -226 251 -226 251 -252 213 -248 233 -250 251 -226 251 -252 225 -252 213 -248 263 -222 251 -226 251 -254 223 -242 245 -232 245 -252 225 -252 251 -226 241 -222 253 -246 485 -488 457 -504 481 -462 493 -480 227 -246 251 -244 251 -226 251 -224 253 -224 493 -474 247 -252 475 -486 243 -222 485 -492
RAW_Data: 231 -234 247 -252 481 -462 493 -480 225 -248 251 -244 251 -224 479 -486 237 -246 251 -226 251 -224 253 -252 467 -474 481 -492 489 -458 245 -250 469 -494 481 -480 231 -238 247 -252 253 -224 253 -224 241 -246 465 -488 243 -240 245 -234 481 -488 487 -472 481 -492 229 -236 485 -474 485 -478 249 -250 251 -226 241 -246 231 -246 251 -224 479 -486 237 -248 485 -470 253 -232 245 -252 223 -254 473 -486 243 -224 251 -254 1439 -1448 249 -224 251 -226 251 -224 241 -246 233 -248 251 -226 251 -254 223 -242 245 -230 245 -252 225 -252 251 -226 241 -222 253 -246 249 -226 253 -224 497 -462 483 -490 485 -472 479 -480 259 -244 223 -254 251 -224 253 -224 241 -246 467 -488 243 -240 477 -484 247 -250 469 -494 247 -224 253 -224 499 -462 481 -488 233 -248 233 -248 251 -224 477 -486 239 -248 253 -224 253 -252 223 -254 467 -476 479 -490 491 -458 271 -224 469 -496 479 -480 233 -238 249 -254 251 -224 253 -224 241 -222 489 -482 269 -212 247 -234 483 -500 483 -480 481 -460 261 -244 485 -460 485 -478 247 -246 223 -248 261 -222 249 -222 247 -252 479 -488 243 -238 479 -482 225 -248 249 -242 251 -226 479 -486 237 -246 251 -226 1443 -1446 243 -252 225 -252 225 -252 253 -212 247 -234 247 -252 253 -224 251 -226 241 -246 231 -246 251 -226 251 -224 253 -252 213 -248 261 -222 251 -226 477 -484 503 -462 489 -490 479 -482 229 -238 247 -252 223 -254 251 -224 243 -220 489 -480 251 -246 467 -480 251 -248 465 -488 243 -240 247 -232 481 -488 487 -472 249 -252 223 -254 223 -242 475 -486 245 -252 223 -242 247 -234 247 -252 481 -460 493 -482 481 -490 249 -224 477 -482 475 -480 243 -240 247 -234 247 -252 251 -226 251 -224 469 -496 247 -254 223 -252 469 -490 483 -462 483 -478 247 -252 473 -486 479 -478 231 -246 261 -224 251 -254 223 -252 225 -242 475 -482 249 -222 505 -486 245 -224 241 -222 255 -246 483 -468 255 -232 245 -252 1445 -1446 243 -460 421 -100 233 -78 103 -126 73 -364 133 -274 163 -238 509 -132 51 -238 211 -812 77 -208 245 -276 261 -184 309 -1392 587 -182 209 -182 101 -122 121 -128 99 -300 175 -154 283 -210 51 -136 163 -506 655 -132 77 -76 157 -242 265 -214 243 -242 163 -574 605 -336 101 -102 331 -78 741 -52 255 -128 51 -178 127 -200 129 -462 179 -132 165 -108 53 -78 159 -728 157 -134 109 -162 129 -108 239 -344 199 -328 99 -102 209 -384 101 -154 229 -78 157 -52 103 -976 259 -102 123 -76 123 -102
RAW_Data: 73 -200 79 -52 131 -212 55 -402 285 -212 315 -56 573 -110 81 -54 161 -214 53 -390 351 -106 53 -316 129 -230 131 -162 163 -136 55 -140 263 -54 137 -192 313 -184 211 -322 53 -108 139 -56 719 -104 323 -236 263 -138 355 -162 135 -266 155 -156 103 -76 251 -284 335 -102 123 -252 185 -190 237 -394 75 -78 79 -132 81 -328 109 -82 179 -530 163 -160 85 -56 375 -52 351 -416 79 -160 107 -492 53 -108 109 -280 53 -52 235 -216 303 -84 131 -160 79 -80 243 -54 215 -82 165 -82 77 -182 207 -330 107 -264 451 -402 131 -134 53 -464 103 -354 51 -188 163 -154 133 -266 105 -52 209 -430 51 -108 107 -186 131 -426 51 -108 55 -82 179 -164 135 -104 399 -52 105 -214 105 -312 135 -188 51 -242 107 -134 79 -314 77 -54 133 -54 105 -164 135 -318 81 -232 151 -180 127 -102 99 -102 453 -130 299 -126 99 -798 235 -206 149 -100 79 -108 955 -80 79 -210 107 -132 131 -196 291 -134 159 -80 377 -312 159 -242 107 -52 53 -156 51 -132 79 -54 133 -274 157 -54 105 -134 387 -104 129 -234 77 -254 361 -52 77 -104 101 -52 53 -54 561 -80 163 -54 109 -216 51 -498 535 -82 163 -210 51 -182 259 -102 75 -76 305 -102 253 -172 215 -268 77 -52 81 -186 133 -106 333 -162 111 -220 569 -102 215 -54 131 -196 433 -80 51 -158 129 -108 53 -188 261 -52 101 -100 227 -402 201 -182 77 -78 175 -126 75 -306 231 -100 149 -178 489 -228 221 -154 77 -220 81 -52 51 -308 233 -104 77 -156 73 -286 181 -132 133 -144 165 -160 109 -54 105 -236 153 -76 211 -372 133 -140 105 -104 77 -320 653 -54 159 -54 181 -162 133 -406 213 -80 79 -132 211 -154 233 -138 189 -84 165 -200 217 -298 107 -272 161 -110 135 -172 103 -102 291 -56 109 -56 317 -52 105 -54 587 -1018 53 -132 109 -56 187 -80 109 -160 81 -80 107 -188 53 -56 237 -158 79 -154 127 -76 51 -204 103 -106 83 -54 313 -52 187 -186 183 -82 189 -474 133 -82 189 -110 155 -136 55 -192 133 -80 183 -106 233 -52 79 -188 187 -158 77 -106 133 -242 111 -106 81 -108 53 -130 245 -290 131 -54 163 -356 287 -156 51 -80 155 -86 687 -104 53 -290 341 -108 217 -160 51 -188 215 -52 133 -210 161 -186 185 -244 51 -210 51 -184 187 -84 133 -108 101 -126 123 -52 77 -150 255 -132 79 -820 183 -108 263 -340 79 -110 137 -82 243 -80 81 -162 51 -132 131 -136 83 -78 181 -126 299 -80 571 -134 105 -80
RAW_Data: 187 -216 109 -112 359 -316 79 -108 189 -82 133 -266 319 -544 311 -314 51 -162 165 -136 107 -162 193 -194 427 -104 269 -136 107 -80 343 -106 207 -266 53 -80 75 -178 99 -74 169 -506 51 -150 149 -620 207 -266 325 -106 183 -184 161 -106 141 -86 137 -134 239 -214 289 -104 51 -52 77 -106 129 -344 51 -372 75 -302 361 -214 393 -290 103 -106 135 -82 81 -82 185 -136 55 -194 81 -164 81 -78 101 -168 83 -186 81 -222 105 -52 105 -186 79 -418 129 -324 125 -128 75 -256 407 -414 131 -108 107 -80 135 -54 693 -52 369 -80 159 -162 53 -370 79 -162 55 -164 463 -236 77 -230 99 -178 153 -230 129 -80 161 -82 241 -322 79 -216 105 -216 81 -244 105 -326 289 -210 105 -82 299 -52 473 -496 159 -52 79 -108 249 -80 179 -132 107 -84 303 -370 239 -162 239 -126 149 -430 75 -52 123 -304 637 -238 109 -160 379 -190 647 -370 157 -294 235 -292 133 -108 135 -900 183 -56 241 -414 77 -210 161 -190 53 -184 185 -54 103 -394 131 -196 135 -546 151 -76 73 -100 201 -102 125 -316 259 -208 351 -160 81 -456 107 -232 129 -126 75 -228 101 -78 75 -230 431 -102 101 -172 201 -132 107 -108 303 -166 55 -458 203 -76 51 -232 131 -168 85 -198 137 -80 79 -84 81 -80 131 -194 585 -292 155 -722 221 -588 371 -132 101 -246 107 -270 81 -136 81 -262 289 -108 217 -218 77 -104 219 -342 259 -106 187 -78 133 -594 51 -132 267 -80 107 -54 53 -134 131 -192 243 -52 77 -102 155 -78 79 -104 79 -286 353 -192 53 -84 133 -184 75 -198 127 -132 123 -464 407 -130 103 -102 335 -202 103 -104 129 -176 289 -188 357 -754 255 -386 53 -138 255 -140 135 -426 53 -134 237 -52 187 -196 401 -54 157 -344 159 -192 55 -82 219 -202 215 -164 55 -166 81 -350 105 -158 101 -52 51 -284 129 -366 103 -392 53 -52 367 -312 133 -248 111 -272 211 -242 51 -158 165 -136 163 -54 133 -132 125 -374 229 -230 173 -304 103 -480 75 -78 175 -128 77 -362 127 -246 275 -76 313 -156 105 -158 247 -436 235 -132 71 -222 177 -236 345 -78 343 -78 341 -190 297 -188 77 -78 101 -76 99 -152 333 -154 101 -74 147 -122 75 -152 175 -452 453 -182 261 -284 149 -156 103 -170 109 -236 155 -110 295 -206 77 -132 81 -110 141 -1406 365 -214 79 -110 105 -484 87 -198 53 -106 185 -140 111 -322 77 -444 131 -78 239 -80 103 -182 131 -184 51 -106 107 -270 239 -134 213 -132 53 -316 513 -236 77 -80
RAW_Data: 163 -664 131 -188 269 -110 135 -200 73 -126 95 -380 53 -128 195 -98 271 -158 147 -224 103 -132 125 -360 231 -336 229 -374 643 -180 247 -104 75 -434 79 -322 107 -138 107 -322 51 -776 157 -78 105 -184 51 -264 433 -82 53 -344 79 -82 161 -110 253 -106 77 -52 101 -78 127 -804 157 -148 73 -74 75 -256 301 -126 99 -76 235 -52 155 -460 77 -130 73 -222 283 -134 53 -110 55 -162 53 -106 263 -78 105 -214 133 -192 107 -208 133 -164 243 -346 105 -276 73 -52 77 -226 131 -408 189 -138 217 -508 77 -214 53 -78 235 -52 213 -372 219 -108 53 -210 207 -52 207 -184 99 -200 103 -54 129 -76 101 -104 101 -74 73 -406 181 -174 509 -300 143 -378 177 -254 101 -216 243 -616 239 -154 99 -312 335 -52 75 -180 127 -202 75 -108 189 -214 101 -384 267 -528 153 -260 367 -214 161 -108 183 -136 107 -130 77 -296 211 -132 189 -134 133 -54 107 -326 51 -266 103 -76 263 -242 313 -284 129 -132 185 -54 275 -138 239 -136 165 -316 129 -212 319 -214 55 -110 237 -312 77 -54 79 -210 227 -76 101 -102 125 -76 251 -104 187 -192 105 -162 79 -404 557 -486 159 -272 157 -84 141 -650 187 -130 205 -596 257 -102 135 -160 101 -270 355 -162 109 -196 187 -104 75 -52 159 -52 107 -266 129 -128 565 -52 133 -54 241 -160 187 -598 51 -184 797 -164 81 -132 161 -160 179 -54 111 -108 159 -164 53 -82 107 -158 161 -162 153 -458 329 -312 79 -218 77 -238 241 -270 307 -110 135 -314 131 -106 53 -354 157 -186 291 -260 563 -80 133 -80 77 -234 219 -84 215 -292 81 -82 135 -54 79 -270 55 -186 77 -78 215 -192 211 -220 109 -158 71 -104 51 -186 263 -230 99 -152 227 -52 75 -102 127 -104 157 -318 107 -112 111 -116 159 -82 105 -218 239 -160 305 -188 99 -52 279 -102 149 -148 259 -180 51 -52 131 -466 135 -460 183 -580 77 -130 51 -106 77 -80 135 -304 107 -160 709 -372 79 -164 53 -158 53 -184 233 -180 107 -466 187 -78 79 -134 291 -78 51 -52 101 -78 75 -78 77 -416 283 -278 131 -106 137 -108 311 -236 247 -252 251 -226 251 -224 243 -220 255 -244 251 -226 251 -226 251 -252 215 -246 235 -248 251 -224 253 -252 223 -244 245 -230 245 -252 225 -252 251 -226 241 -220 255 -246 249 -226 251 -226 251 -252 213 -248 261 -222 251 -254 223 -252 225 -242 245 -230 247 -252 223 -252 253 -224 243 -220 255 -244 251 -226 251 -226 251 -252 213 -248 235 -248 251 -226 251 -252
RAW_Data: 225 -242 245 -230 245 -252 223 -254 251 -224 243 -220 255 -244 251 -226 251 -226 251 -254 213 -246 235 -248 251 -226 251 -252 225 -242 245 -230 245 -254 223 -252 253 -224 253 -212 247 -236 247 -252 253 -224 251 -226 241 -246 231 -246 251 -224 253 -252 223 -254 213 -246 263 -222 251 -254 223 -254 223 -242 245 -232 245 -252 225 -252 251 -226 241 -222 253 -246 251 -224 253 -224 253 -252 213 -246 235 -248 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 253 -214 247 -236 247 -252 251 -226 251 -224 243 -246 229 -246 251 -226 251 -226 251 -252 213 -248 261 -222 253 -224 253 -252 223 -242 245 -232 245 -252 225 -252 251 -224 241 -222 253 -246 251 -226 251 -224 251 -254 213 -248 233 -250 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 243 -220 255 -244 251 -226 251 -226 251 -252 213 -248 259 -222 253 -224 253 -252 223 -242 247 -230 245 -252 225 -252 251 -226 241 -220 255 -244 251 -226 251 -226 251 -252 215 -246 235 -248 253 -224 253 -252 223 -254 213 -248 261 -224 251 -224 253 -252 225 -242 245 -230 245 -252 225 -252 253 -224 241 -222 253 -246 251 -226 251 -224 251 -254 213 -248 233 -250 251 -226 251 -254 223 -242 245 -230 245 -252 223 -254 251 -226 241 -220 255 -246 251 -224 253 -224 251 -254 213 -248 233 -248 251 -226 251 -254 223 -242 245 -232 245 -252 223 -254 251 -224 243 -220 255 -244 251 -226 251 -226 251 -254 213 -246 235 -248 251 -226 251 -254 223 -252 215 -248 261 -222 253 -224 253 -252 223 -242 247 -230 245 -252 225 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 213 -248 259 -222 251 -226 251 -254 223 -242 245 -232 245 -252 225 -252 251 -226 251 -214 247 -234 249 -252 251 -226 251 -224 241 -248 229 -248 249 -226 253 -252 223 -254 213 -246 261 -224 251 -254 223 -252 225 -242 245 -230 247 -252 223 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 213 -248 259 -224 251 -226 251 -252 225 -242 245 -230 245 -252 225 -252 253 -224 251 -214 247 -236 247 -254 251 -224 253 -224 241 -246 231 -246 251 -226 251 -252 225 -252 213 -248 261 -222 251 -226 251 -254 223 -242 245 -230 247 -252 223 -254 251 -224 243 -220 255 -244 251 -226 251 -226 251 -254 213 -248 233 -248 251 -226 251 -252 225 -242 245 -230 245 -254 223 -252 253 -224 241 -222 255 -244 251 -226 251 -226 251 -252 213 -248 233 -248 251 -254 223 -254 223 -242 245 -232
RAW_Data: 245 -252 223 -254 251 -226 241 -220 255 -244 251 -226 251 -226 251 -252 213 -248 261 -222 251 -254 223 -252 225 -242 245 -230 245 -254 223 -252 253 -224 241 -222 253 -246 251 -224 253 -224 251 -254 213 -248 233 -250 251 -224 253 -252 225 -242 243 -232 245 -252 225 -252 253 -224 241 -222 253 -246 251 -226 251 -224 253 -252 213 -248 233 -248 251 -226 477 -486 501 -456 487 -494 483 -466 255 -232 247 -252 223 -254 251 -226 251 -214 503 -458 243 -252 469 -496 247 -224 477 -486 239 -250 251 -226 477 -486 473 -480 253 -246 467 -488 241 -242 475 -484 247 -224 247 -264 221 -252 251 -226 471 -488 479 -476 485 -502 221 -252 473 -486 479 -490 231 -248 229 -248 249 -226 251 -254 223 -242 477 -482 247 -252 223 -242 475 -482 479 -486 481 -480 253 -232 481 -488 487 -472 247 -252 223 -254 223 -242 245 -232 247 -252 483 -460 493 -488 467 -488 479 -490 231 -248 231 -248 483 -466 487 -484 247 -250 1433 -1456 225 -246 251 -240 251 -224 253 -224 251 -226 241 -246 231 -248 251 -226 251 -254 223 -242 245 -230 245 -252 223 -254 251 -224 253 -214 247 -234 483 -498 483 -482 477 -486 471 -488 243 -250 213 -248 235 -248 251 -254 223 -254 467 -490 249 -224 477 -482 237 -248 485 -468 255 -232 245 -252 481 -462 493 -482 225 -248 483 -480 225 -248 485 -480 251 -222 255 -244 251 -226 251 -252 469 -464 483 -498 483 -482 247 -224 471 -488 481 -480 253 -234 245 -252 223 -252 253 -224 251 -214 505 -460 245 -252 251 -214 503 -458 505 -462 483 -498 229 -250 477 -480 485 -482 247 -224 251 -252 213 -248 233 -250 251 -226 477 -486 475 -488 489 -492 483 -462 231 -248 261 -224 483 -492 463 -484 249 -248 1445 -1430 255 -234 245 -252 223 -254 251 -224 253 -214 245 -236 247 -252 251 -226 251 -226 241 -246 231 -246 251 -224 253 -252 223 -254 213 -248 235 -248 485 -492 459 -484 479 -486 483 -500 227 -250 241 -252 223 -254 223 -252 225 -242 477 -484 247 -250 469 -494 247 -224 479 -488 237 -246 251 -226 479 -486 471 -480 251 -222 489 -480 253 -246 465 -480 243 -240 245 -236 247 -252 253 -224 473 -486 481 -478 485 -482 247 -224 503 -460 497 -484 243 -224 251 -254 225 -252 223 -242 247 -232 481 -474 255 -226 265 -222 485 -490 489 -456 505 -462 247 -252 477 -482 471 -482 243 -240 247 -232 247 -252 225 -252 251 -226 467 -496 481 -468 487 -482 497 -458 267 -224 251 -254 449 -484 503 -464 241 -240 1447 -1454 229 -804 209 -238

View File

@@ -1,22 +0,0 @@
Filetype: Flipper SubGhz RAW File
Version: 1
Frequency: 433920000
Preset: FuriHalSubGhzPresetOok650Async
Protocol: RAW
RAW_Data: 95 -240 191 -412 187 -152 95 -120 263 -220 373 -116 199 -88 239 -334 503 -142 167 -174 85 -172 143 -86 85 -96 119 -196 259 -96 167 -148 201 -96 481 -120 237 -264 143 -144 105 -790 257 -88 243 -144 143 -86 553 -216 103 -174 143 -142 119 -144 119 -224 307 -144 239 -120 127 -390 189 -168 119 -312 191 -142 215 -96 103 -86 307 -274 191 -104 143 -96 167 -120 357 -390 651 -218 197 -170 143 -164 85 -210 143 -116 143 -86 255 -160 95 -114 199 -88 545 -288 173 -114 115 -202 85 -316 145 -144 113 -562 105 -254 85 -144 287 -116 115 -202 87 -346 287 -244 103 -370 143 -230 143 -144 85 -88 113 -230 231 -984 119 -144 171 -144 201 -174 115 -288 113 -192 277 -114 345 -202 249 -316 83 -228 119 -146 151 -116 85 -202 85 -144 437 -272 115 -144 85 -86 173 -142 163 -260 205 -280 339 -88 229 -194 363 -144 585 -394 599 -144 85 -100 151 -574 171 -174 85 -114 239 -288 211 -410 115 -144 489 -116 115 -116 201 -336 95 -96 93 -120 95 -128 115 -116 257 -174 141 -292 113 -162 165 -192 287 -192 161 -192 1125 -202 85 -222 461 -144 113 -116 115 -114 201 -288 259 -288 401 -174 85 -106 119 -96 431 -130 85 -114 375 -494 95 -96 167 -288 281 -104 411 -214 335 -144 119 -534 85 -144 143 -144 229 -246 97 -82 85 -260 201 -304 403 -116 391 -172 229 -448 81 -82 95 -116 201 -86 521 -144 119 -336 119 -142 95 -144 119 -96 267 -170 283 -288 95 -190 167 -288 199 -116 247 -144 87 -144 85 -114 215 -260 115 -116 113 -338 103 -240 167 -96 119 -120 95 -96 405 -188 85 -116 191 -334 143 -164 85 -230 115 -154 119 -166 143 -288 195 -144 87 -86 343 -232 113 -202 115 -86 201 -278 201 -86 85 -86 303 -286 95 -120 95 -168 167 -118 129 -94 95 -432 151 -218 119 -186 235 -230 167 -632 143 -144 231 -156 153 -282 147 -96 143 -592 261 -120 191 -96 167 -576 333 -342 171 -462 173 -514 157 -432 87 -312 397 -378 287 -374 403 -230 117 -264 257 -170 189 -346 137 -528 117 -240 805 -454 539 -288 171 -86 173 -286 153 -288 115 -172 173 -158 399 -114 85 -116 201 -116 85 -216 215 -432 113 -100 113 -338 123 -146 289 -86 143 -114 343 -94 95 -96 311 -110 171 -86 143 -88 969 -312 119 -316 401 -134 255 -202 323 -86 87 -114 253 -228 95 -172 85 -170 165 -86 343 -192 119 -144 213 -112 191 -334 287 -96 359 -500 137 -120 261 -242 119 -118 283 -210 167 -178 287 -174 343 -268
RAW_Data: 185 -96 119 -978 215 -120 213 -96 265 -172 261 -168 225 -462 307 -312 87 -172 115 -288 423 -84 87 -230 143 -404 109 -114 233 -216 165 -240 95 -288 95 -192 215 -238 335 -116 199 -170 135 -144 109 -408 285 -130 97 -98 115 -86 85 -86 87 -120 167 -144 119 -264 171 -316 231 -202 257 -274 115 -114 421 -86 85 -202 143 -144 201 -86 229 -86 143 -116 115 -86 115 -114 85 -202 143 -288 163 -186 483 -202 167 -212 373 -288 115 -86 171 -116 113 -230 231 -230 201 -172 171 -318 113 -390 101 -200 317 -404 287 -220 171 -232 199 -490 171 -144 173 -168 223 -202 173 -200 115 -172 119 -288 209 -220 85 -86 85 -480 423 -450 201 -364 411 -216 143 -120 219 -538 513 -330 199 -120 119 -96 127 -138 141 -140 117 -312 429 -182 259 -422 1027 -280 303 -210 131 -168 85 -86 201 -230 547 -174 113 -88 259 -202 109 -96 215 -144 291 -168 151 -316 85 -258 287 -260 279 -302 171 -284 189 -168 95 -96 309 -240 167 -384 165 -96 169 -226 95 -216 271 -122 195 -102 113 -116 339 -168 85 -192 583 -114 297 -406 167 -326 209 -212 119 -262 143 -86 87 -114 125 -172 115 -172 173 -576 219 -192 335 -120 85 -116 171 -202 711 -116 85 -172 373 -232 381 -144 95 -244 173 -210 119 -198 85 -86 143 -312 211 -96 115 -86 113 -528 103 -150 191 -144 119 -98 333 -172 215 -114 87 -86 529 -490 85 -356 239 -374 143 -260 457 -312 157 -394 131 -116 353 -172 229 -490 171 -144 189 -166 305 -144 85 -288 201 -356 147 -106 167 -740 143 -312 95 -242 137 -88 465 -126 239 -358 167 -120 1385 -130 385 -192 95 -120 817 -218 805 -140 171 -394 143 -86 371 -430 143 -216 187 -84 143 -316 173 -86 115 -202 85 -114 215 -96 167 -316 107 -368 313 -120 95 -382 197 -216 289 -388 119 -264 109 -86 113 -202 963 -172 111 -104 113 -346 115 -266 255 -88 229 -202 109 -288 357 -348 365 -226 381 -144 455 -144 901 -532 531 -108 103 -142 225 -144 143 -230 85 -144 141 -142 645 -82 167 -116 143 -172 403 -230 85 -144 87 -288 229 -144 115 -144 371 -82 107 -306 333 -116 113 -88 143 -86 229 -174 617 -96 677 -286 95 -240 95 -168 141 -216 95 -212 209 -120 95 -144 95 -240 165 -116 765 -230 229 -88 141 -192 97 -86 111 -114 231 -172 143 -144 365 -96 291 -144 129 -144 87 -168 141 -120 215 -144 143 -238 215 -192 95 -96 95 -144 403 -216 163 -102 155 -120 95 -120 263 -120 403 -374 431 -230 303 -134 791 -288
RAW_Data: 201 -138 251 -262 95 -376 287 -230 143 -114 143 -144 259 -214 231 -238 167 -288 95 -166 119 -120 411 -144 143 -546 243 -260 143 -404 113 -450 137 -184 143 -230 375 -144 85 -230 129 -104 133 -112 171 -258 115 -316 259 -86 163 -96 95 -88 113 -350 167 -780 847 -174 143 -404 85 -314 109 -278 287 -86 101 -172 201 -258 115 -86 143 -144 115 -114 547 -86 423 -116 85 -144 507 -144 133 -518 85 -424 167 -246 143 -96 261 -192 109 -240 167 -240 117 -168 239 -192 85 -116 137 -264 143 -304 119 -96 191 -144 141 -264 95 -96 119 -144 95 -96 121 -478 229 -88 575 -230 85 -312 81 -102 103 -390 93 -96 119 -144 143 -238 215 -288 277 -96 115 -114 87 -288 113 -120 143 -114 261 -146 153 -116 335 -144 259 -136 85 -258 87 -144 85 -86 661 -86 161 -120 95 -110 191 -86 135 -408 103 -144 125 -192 119 -336 113 -86 173 -114 173 -216 335 -116 321 -186 559 -116 229 -316 115 -512 141 -168 191 -130 113 -120 143 -288 127 -174 215 -96 85 -318 1169 -174 85 -86 563 -146 315 -162 163 -96 339 -222 215 -230 229 -88 109 -218 493 -120 189 -264 253 -466 239 -240 157 -288 219 -268 309 -192 121 -156 241 -192 215 -144 95 -168 261 -86 397 -428 569 -88 411 -268 251 -168 167 -268 143 -288 453 -144 163 -86 115 -144 113 -296 81 -224 163 -458 171 -310 161 -88 85 -316 461 -508 201 -162 229 -114 145 -144 143 -86 143 -114 259 -144 345 -346 85 -124 143 -302 83 -116 113 -96 261 -84 297 -116 201 -240 143 -120 861 -144 117 -158 167 -96 215 -454 273 -304 239 -96 95 -204 189 -346 345 -286 545 -88 339 -104 171 -284 95 -360 239 -144 289 -96 95 -120 225 -106 197 -144 219 -208 145 -144 187 -282 95 -408 95 -338 187 -250 229 -86 115 -402 87 -86 143 -202 283 -98 329 -134 167 -88 229 -172 221 -138 169 -202 171 -196 111 -108 85 -144 479 -100 623 -212 133 -116 113 -144 403 -88 257 -462 287 -144 373 -210 239 -144 115 -172 289 -168 143 -98 119 -96 95 -96 357 -96 119 -216 143 -144 311 -192 95 -166 175 -416 351 -100 145 -94 119 -360 427 -94 95 -144 263 -144 115 -366 97 -98 95 -190 95 -264 541 -288 131 -140 85 -202 409 -226 229 -518 143 -202 363 -260 85 -86 269 -142 95 -120 215 -168 189 -208 239 -96 285 -456 129 -144 517 -114 589 -344 115 -288 235 -98 105 -282 109 -278 85 -312 171 -116 287 -316 87 -172 335 -430 119 -274 143 -164 229 -216 167 -232 343 -260
RAW_Data: 143 -86 565 -144 87 -460 115 -508 363 -86 143 -276 671 -144 115 -86 515 -116 199 -236 185 -140 143 -82 113 -116 85 -116 85 -408 95 -284 199 -88 315 -116 143 -114 717 -202 85 -86 173 -86 201 -144 333 -200 115 -86 85 -174 401 -174 263 -244 229 -86 143 -434 229 -202 231 -164 143 -86 165 -182 167 -172 85 -346 771 -252 81 -106 217 -96 119 -96 287 -140 85 -86 143 -374 143 -116 85 -114 83 -118 119 -164 201 -86 153 -166 359 -116 283 -86 187 -120 459 -280 201 -144 229 -258 143 -408 427 -144 373 -294 197 -120 287 -96 119 -264 143 -120 119 -528 95 -168 119 -192 117 -558 97 -148 143 -120 185 -188 167 -264 95 -176 215 -254 201 -258 263 -158 215 -168 119 -312 873 -388 95 -192 359 -278 341 -96 171 -116 143 -432 173 -316 403 -84 85 -144 113 -174 287 -346 243 -216 95 -394 161 -144 317 -200 199 -140 95 -86 143 -278 139 -86 143 -144 201 -114 191 -264 119 -238 163 -114 143 -766 143 -144 167 -604 349 -390 459 -86 201 -172 633 -114 549 -432 339 -114 201 -174 325 -220 287 -116 123 -264 137 -86 173 -336 171 -422 133 -144 661 -86 163 -96 93 -96 215 -168 105 -114 259 -238 115 -86 315 -86 229 -298 167 -168 319 -432 189 -336 167 -120 123 -250 95 -144 167 -346 97 -96 429 -86 517 -120 95 -480 85 -86 307 -84 109 -112 121 -136 227 -112 115 -114 85 -202 201 -230 201 -88 143 -144 229 -96 347 -172 143 -656 201 -508 199 -174 139 -192 171 -172 257 -86 223 -216 143 -144 215 -120 85 -264 185 -212 271 -112 85 -374 85 -116 113 -88 113 -174 431 -202 315 -264 87 -116 373 -336 201 -172 173 -374 201 -172 115 -114 115 -86 115 -86 489 -280 119 -86 115 -144 137 -144 253 -480 1225 -1598 631 -828 709 -782 689 -792 1063 -1152 1105 -1066 1141 -1076 761 -734 1125 -1090 761 -696 765 -698 817 -672 1183 -1012 1197 -1022 819 -686 775 -710 775 -680 835 -646 839 -646 1181 -1018 801 -710 1139 -1078 1151 -1066 813 -646 843 -644 843 -622 841 -650 1187 -1014 1205 -1018 825 -656 829 -652 1197 -1024 1197 -1016 1209 -990 1167 -1074 789 -676 1179 -1032 831 -644 839 -644 843 -650 813 -678 795 -684 769 -712 775 -708 777 -728 783 -676 817 -646 1205 -1006 1219 -998 845 -632 1189 -1044 1177 -980 1527 -1456 1483 -1440 1537 -1388 839 -672 817 -648 843 -676 1127 -1088 1177 -1022 1199 -1020 817 -648 1213 -1010 831 -624 833 -648 839 -646 1213 -1018 1191 -1022 815 -678 783 -710 779 -710 769 -684 773 -734 1115 -1078 785 -710 1147 -1068
RAW_Data: 1183 -992 855 -630 827 -664 839 -646 815 -644 1209 -1014 1191 -1050 765 -708 771 -738 1113 -1080 1181 -1006 1199 -1020 1185 -1042 815 -646 1181 -1032 827 -668 811 -670 815 -648 839 -676 769 -714 779 -710 773 -712 775 -708 777 -676 835 -644 1213 -1018 1143 -1078 763 -702 1177 -1008 1199 -994 1575 -1376 1525 -1428 1503 -1438 779 -718 817 -646 843 -650 1209 -1012 1179 -1024 1201 -1016 843 -644 1181 -1032 831 -622 831 -668 839 -644 1181 -1034 1197 -1024 811 -684 781 -712 771 -712 775 -680 775 -706 1177 -1024 807 -710 1137 -1076 1159 -1014 831 -652 835 -646 841 -646 839 -644 1183 -1040 1193 -996 837 -656 833 -686 1143 -1074 1161 -1016 1195 -1026 1185 -1012 831 -648 1207 -996 831 -684 771 -710 775 -702 809 -676 817 -646 817 -672 817 -672 817 -674 767 -734 771 -710 1137 -1076 1131 -1066 803 -642 1209 -1020 1197 -1018 1521 -1392 1549 -1416 1519 -1392 815 -670 841 -678 761 -736 1119 -1092 1155 -1018 1217 -1022 789 -702 1183 -1016 815 -648 815 -674 819 -648 1211 -1012 1199 -1022 833 -684 749 -712 769 -736 751 -678 829 -668 1179 -1016 797 -710 1139 -1078 1133 -1090 817 -644 819 -674 815 -676 789 -676 1153 -1064 1179 -1020 801 -712 773 -708 1141 -1076 1133 -1068 1187 -992 1197 -1046 793 -648 1209 -1012 829 -668 815 -674 819 -648 841 -674 761 -706 761 -732 767 -712 769 -712 777 -678 833 -648 1205 -1016 1161 -1074 817 -624 1207 -1006 1197 -996 1575 -1358 1573 -1386 1547 -1380 835 -686 775 -710 773 -704 1203 -996 1195 -1042 1187 -1018 831 -656 1195 -1026 811 -654 765 -736 771 -712 1139 -1078 1153 -1034 835 -646 817 -670 817 -650 841 -676 761 -704 1149 -1062 809 -646 1211 -1016 1191 -1024 839 -678 771 -710 775 -686 779 -712 1137 -1080 1129 -1040 835 -646 841 -646 1211 -1016 1193 -1022 1179 -1014 1197 -1022 835 -658 1143 -1068 817 -648 843 -674 765 -712 777 -712 769 -710 773 -704 781 -674 839 -648 845 -646 815 -674 1179 -1034 1201 -994 793 -714 1141 -1074 1159 -988 1557 -1404 1559 -1386 1509 -1438 809 -668 843 -674 813 -676 1135 -1070 1159 -1020 1169 -1072 817 -648 1207 -1012 839 -622 841 -646 843 -646 1179 -1034 1197 -1024 821 -686 749 -714 775 -710 775 -702 779 -694 1181 -1018 801 -708 1139 -1076 1127 -1088 811 -646 845 -646 841 -624 843 -650 1181 -1036 1203 -994 835 -658 829 -656 1191 -1050 1177 -1012 1179 -1000 1203 -1016 841 -646 1211 -1018 775 -710 777 -730 759 -702 815 -644 843 -646 817 -674 815 -678 785 -712 753 -734 773 -712 1115 -1076 1155 -1038 833 -648 1203 -994 1211 -1018 1519 -1388 1573 -1362 2045 -2332 103 -86 691 -116 229 -144 239 -120 135 -216 93 -202 315 -202
RAW_Data: 231 -432 229 -114 403 -116 569 -86 575 -404 133 -120 239 -96 95 -96 93 -240 95 -144 95 -96 95 -168 141 -250 431 -174 113 -116 401 -116 173 -144 143 -172 85 -230 115 -260 137 -96 129 -86 605 -172 257 -168 229 -314 113 -88 257 -466 197 -96 81 -330 139 -86 85 -260 277 -200 87 -202 229 -88 219 -168 109 -86 119 -96 143 -216 143 -364 523 -118 95 -120 225 -330 83 -170 115 -86 81 -302 125 -256 95 -144 117 -96 95 -96 119 -168 167 -386 173 -132 515 -232 277 -144 229 -376 229 -202 455 -262 175 -88 171 -174 85 -86 85 -508 143 -174 315 -130 105 -202 115 -114 173 -432 111 -144 221 -162 273 -118 143 -380 257 -356 315 -236 119 -124 325 -214 115 -530 193 -168 105 -86 109 -144 119 -352 93 -96 119 -216 387 -224 197 -120 463 -144 93 -1134 85 -86 259 -86 201 -192 173 -198 185 -144 307 -200 85 -116 115 -192 95 -104 143 -202 229 -120 285 -120 239 -144 143 -392 519 -296 95 -144 229 -202 85 -202 85 -116 95 -120 101 -200 119 -96 95 -96 95 -172 119 -142 143 -216 81 -316 119 -144 269 -286 167 -130 231 -324 221 -96 167 -240 119 -102 113 -116 143 -192 191 -288 143 -144 309 -114 187 -378 231 -172 171 -458 413 -430 201 -120 469 -94 143 -504 261 -96 95 -144 237 -120 455 -334 163 -116 191 -280 169 -288 99 -492 85 -458 141 -260 171 -244 713 -168 359 -96 195 -154 733 -168 119 -364 143 -88 171 -86 85 -116 339 -86 173 -334 359 -144 95 -540 95 -120 185 -144 317 -114 87 -86 113 -254 373 -86 345 -288 85 -96 151 -122 429 -202 113 -342 247 -202 139 -86 229 -172 143 -88 87 -296 755 -220 447 -330 259 -330 241 -118 95 -340 245 -194 239 -112 201 -200 367 -1020 431 -408 279 -120 95 -96 95 -166 95 -216 281 -116 549 -140 257 -166 157 -192 263 -186 95 -286 119 -170 287 -230 173 -258 343 -366 171 -144 143 -116 85 -86 115 -86 243 -422 319 -120 243 -86 115 -172 143 -116 259 -86 201 -202 257 -664 763 -356 289 -114 85 -86 113 -486 271 -144 229 -116 115 -122 423 -314 969 -144 171 -116 201 -230 101 -202 143 -200 317 -86 85 -116 85 -462 181 -172 115 -202 309 -114 287 -316 139 -430 157 -192 191 -84 137 -168 113 -116 259 -114 373 -86 201 -116 199 -88 85 -172 173 -86 169 -240 119 -174 85 -286 137 -200 143 -172 259 -244 147 -144 115 -116 201 -140 423 -172 85 -144 87 -200 87 -202 85 -86 345 -174 143 -202 315 -404 229 -144 141 -212
RAW_Data: 119 -114 231 -114 201 -318 431 -404 201 -82 167 -88 85 -114 81 -144 85 -202 85 -134 109 -144 461 -114 189 -354 171 -226 311 -152 115 -178 117 -360 239 -240 143 -286 143 -288 119 -268 315 -82 163 -196 173 -288 173 -192 215 -118 489 -88 143 -230 477 -110 459 -172 115 -172 403 -282 113 -116 143 -288 143 -172 139 -144 95 -214 167 -484 191 -444 95 -96 95 -202 117 -168 167 -120 325 -172 239 -202 229 -144 85 -404 115 -86 85 -528 143 -166 83 -172 403 -144 115 -144 507 -258 403 -156 171 -192 95 -120 293 -166 115 -86 547 -230 143 -192 315 -340 129 -84 229 -86 221 -202 143 -86 215 -178 85 -288 143 -164 141 -96 95 -144 287 -120 189 -216 143 -144 533 -192 85 -260 85 -86 115 -244 129 -134 229 -86 287 -174 171 -346 373 -86 229 -260 469 -100 83 -84 143 -118 95 -100 143 -116 431 -124 115 -114 345 -114 81 -314 199 -144 173 -192 95 -114 85 -88 171 -278 239 -288 171 -86 287 -202 201 -114 219 -336 199 -382 145 -144 121 -288 167 -240 299 -188 161 -96 117 -96 239 -120 213 -96 119 -336 127 -88 171 -390 163 -202 201 -216 119 -144 95 -144 157 -86 655 -206 699 -410 111 -126 135 -88 85 -172 115 -576 85 -116 85 -518 143 -86 87 -266 149 -120 129 -168 215 -110 167 -96 119 -168 95 -118 269 -306 201 -202 513 -96 99 -346 229 -288 115 -216 147 -172 173 -230 211 -124 87 -364 85 -172 259 -230 87 -114 143 -140 237 -88 85 -120 215 -238 95 -718 129 -214 167 -168 95 -262 665 -204 215 -418 97 -142 143 -288 95 -144 191 -168 301 -86 115 -202 113 -144 257 -116 173 -288 285 -198 85 -374 539 -244 119 -432 259 -400 175 -302 87 -402 259 -134 171 -88 113 -144 479 -202 85 -260 335 -266 131 -144 147 -144 143 -230 287 -144 231 -518 113 -144 143 -174 167 -172 201 -86 201 -230 171 -194 135 -86 345 -220 259 -144 85 -316 135 -406 191 -262 119 -96 113 -116 143 -144 143 -86 229 -260 115 -142 223 -318 85 -172 201 -86 373 -88 287 -490 105 -144 573 -116 695 -86 113 -82 209 -190 231 -172 605 -86 85 -646 143 -168 209 -168 153 -86 205 -144 143 -238 701 -262 163 -186 191 -96 197 -432 87 -114 341 -202 227 -120 335 -118 95 -240 191 -118 147 -144 87 -144 143 -172 115 -148 119 -130 345 -172 115 -358 493 -250 85 -172 167 -144 81 -548 143 -96 309 -282 159 -130 119 -96 95 -146 311 -86 191 -144 189 -120 155 -84 103 -96 165 -384 287 -120 527 -454
RAW_Data: 115 -138 349 -212 143 -116 143 -748 143 -148 95 -168 535 -164 403 -316 201 -144 85 -86 105 -120 95 -144 453 -106 167 -144 213 -192 365 -110 143 -96 119 -120 191 -88 229 -114 173 -144 95 -120 107 -462 173 -200 335 -266 377 -118 167 -568 85 -144 85 -318 247 -174 223 -288 123 -128 143 -336 399 -220 263 -192 161 -144 85 -116 257 -260 229 -174 143 -230 115 -172 115 -258 285 -172 143 -142 153 -432 143 -142 145 -96 267 -202 143 -120 95 -142 167 -116 143 -172 287 -116 171 -116 115 -230 315 -86 423 -360 95 -352 253 -96 407 -96 143 -478 311 -168 167 -164 85 -202 85 -202 85 -114 459 -202 421 -230 85 -174 85 -116 85 -86 85 -374 311 -302 171 -116 201 -172 575 -190 373 -116 403 -432 143 -202 115 -86 113 -290 167 -84 243 -172 345 -88 201 -200 113 -312 99 -112 155 -294 171 -430 239 -220 85 -336 95 -96 117 -144 215 -120 95 -144 287 -310 311 -374 85 -174 171 -86 133 -116 153 -102 143 -144 215 -250 85 -512 201 -116 267 -120 279 -356 213 -120 191 -110 335 -144 95 -216 191 -142 95 -216 119 -190 191 -96 95 -240 191 -164 333 -170 267 -120 95 -192 165 -158 229 -202 85 -144 259 -174 191 -116 113 -86 113 -258 173 -144 113 -174 257 -88 417 -110 169 -144 87 -114 173 -114 221 -94 105 -288 85 -88 85 -144 259 -214 149 -258 115 -86 85 -86 403 -192 95 -306 231 -144 113 -86 115 -200 115 -260 171 -236 95 -240 113 -312 197 -166 191 -168 95 -96 165 -96 167 -120 287 -138 339 -216 117 -98 105 -110 597 -144 359 -186 283 -96 261 -312 127 -140 113 -318 171 -174 143 -318 143 -200 345 -576 143 -116 143 -144 229 -316 143 -346 229 -786 85 -316 229 -244 339 -96 603 -304 173 -432 543 -84 111 -116 113 -466 103 -150 141 -88 381 -104 273 -98 215 -318 143 -100 87 -114 85 -174 201 -86 345 -144 521 -172 113 -86 85 -164 199 -174 85 -202 575 -114 87 -144 257 -146 199 -246 237 -274 329 -184 147 -96 311 -130 195 -312 93 -240 163 -140 141 -168 119 -168 455 -144 259 -202 85 -288 143 -174 113 -260 171 -174 633 -440 243 -250 391 -88 287 -144 143 -144 191 -86 239 -142 263 -246 105 -120 143 -142 263 -96 215 -168 85 -260 87 -480 277 -86 143 -144 403 -114 85 -462 767 -200 85 -174 315 -94 147 -408 85 -260 171 -112 143 -114 903 -116 201 -116 115 -86 173 -344 87 -114 115 -288 143 -288 85 -86 365 -230 143 -316 201 -86 569 -202 171 -202 143 -442
RAW_Data: 375 -172 211 -96 85 -264 429 -168 119 -116 163 -148 239 -168 95 -192 215 -230 95 -216 119 -144 167 -364 115 -316 115 -346 85 -116 229 -288 103 -480 305 -116 143 -86 85 -304 261 -168 167 -96 141 -144 95 -144 455 -106 113 -144 87 -86 229 -202 143 -316 143 -232 199 -174 233 -216 547 -278 143 -116 345 -288 369 -290 153 -316 305 -230 143 -116 545 -230 287 -168 237 -120 95 -370 201 -288 143 -258 173 -138 361 -82 345 -288 197 -168 165 -240 143 -186 263 -216 195 -202 171 -144 465 -194 501 -192 159 -172 143 -144 85 -192 253 -96 219 -300 205 -86 143 -86 311 -120 269 -634 185 -116 113 -456 97 -96 85 -174 85 -288 115 -144 173 -114 245 -144 119 -120 119 -96 93 -138 199 -144 173 -88 315 -202 157 -120 143 -96 167 -120 271 -268 287 -86 231 -144 143 -144 113 -346 259 -104 441 -204 249 -272 231 -114 345 -116 85 -86 85 -142 127 -100 169 -156 119 -96 167 -238 141 -86 143 -230 115 -114 115 -202 137 -168 143 -312 167 -110 193 -338 281 -230 721 -124 95 -120 309 -110 143 -144 563 -460 171 -88 143 -490 201 -144 85 -232 171 -144 201 -144 171 -144 95 -124 109 -572 633 -316 215 -264 161 -236 215 -202 115 -86 229 -260 257 -144 173 -172 259 -86 171 -264 129 -202 503 -350 161 -112 195 -144 401 -116 201 -230 287 -144 191 -96 167 -284 161 -164 119 -224 143 -376 209 -82 85 -144 201 -116 403 -114 231 -238 107 -174 85 -86 387 -200 173 -86 85 -116 87 -200 201 -174 287 -114 623 -86 143 -260 567 -108 113 -246 99 -396 115 -168 137 -396 85 -116 171 -86 87 -114 231 -144 235 -196 85 -144 305 -126 95 -218 417 -330 133 -116 85 -346 371 -134 345 -114 173 -372 111 -144 345 -402 115 -144 85 -86 87 -144 517 -86 413 -86 403 -120 431 -214 119 -264 191 -374 195 -86 287 -86 143 -608 143 -120 95 -216 263 -96 167 -120 113 -336 157 -192 285 -136 287 -200 87 -292 119 -216 109 -168 253 -118 167 -96 309 -96 191 -264 117 -170 119 -96 95 -406 167 -96 95 -120 167 -188 185 -96 417 -120 759 -144 85 -144 115 -86 173 -202 411 -188 263 -306 259 -288 229 -116 113 -88 171 -116 201 -114 365 -220 119 -398 181 -124 143 -202 85 -288 143 -288 229 -86 87 -114 229 -86 287 -88 143 -114 115 -258 287 -260 143 -86 335 -86 267 -240 119 -144 95 -238 119 -96 119 -246 405 -144 105 -144 147 -222 117 -110 129 -202 171 -86 229 -174 85 -96 109 -108 81 -86 95 -216
RAW_Data: 247 -86 113 -144 459 -140 115 -86 143 -144 229 -652 273 -96 81 -114 115 -172 87 -594 115 -230 85 -462 85 -86 85 -86 287 -240 263 -96 85 -458 363 -480 95 -192 119 -120 167 -288 105 -288 201 -172 201 -172 345 -144 115 -312 255 -144 167 -112 155 -96 167 -134 173 -114 201 -86 105 -114 347 -86 201 -144 173 -258 143 -260 215 -234 173 -114 229 -174 117 -168 335 -114 231 -114 191 -216 589 -120 141 -96 95 -168 335 -150 201 -230 259 -268 125 -100 287 -114 85 -174 201 -288 161 -166 125 -144 345 -116 575 -336 237 -120 421 -96 95 -96 119 -96 543 -258 115 -86 85 -116 85 -202 257 -202 409 -84 169 -114 115 -374 173 -374 85 -144 215 -168 195 -116 345 -230 173 -114 85 -398 81 -86 143 -144 345 -114 115 -86 173 -222 93 -116 113 -86 375 -114 153 -326 401 -116 87 -288 143 -460 143 -168 95 -168 253 -216 469 -96 167 -96 265 -244 111 -114 1439 -114 115 -140 119 -134 201 -144 199 -346 229 -202 489 -288 459 -222 81 -172 229 -288 335 -198 201 -200 143 -140 119 -134 383 -216 579 -86 85 -288 167 -116 143 -312 287 -192 113 -174 403 -460 287 -308 545 -284 333 -114 119 -190 145 -114 115 -96 153 -220 539 -192 829 -162 201 -216 143 -258 143 -116 171 -86 115 -86 115 -638 213 -120 431 -192 287 -144 239 -94 167 -192 95 -120 417 -162 95 -96 119 -142 167 -120 357 -168 431 -214 81 -516 197 -114 361 -86 257 -136 141 -288 87 -86 143 -288 143 -86 115 -172 143 -174 113 -174 85 -144 171 -144 143 -144 85 -116 257 -116 219 -176 949 -342 107 -140 115 -144 359 -142 95 -120 119 -240 95 -96 167 -96 95 -164 185 -172 197 -112 101 -116 171 -144 229 -202 85 -202 115 -114 263 -168 143 -122 213 -216 95 -96 381 -168 319 -202 171 -230 271 -278 259 -278 95 -220 489 -144 259 -132 315 -202 113 -86 143 -144 287 -174 393 -116 173 -346 143 -262 129 -142 119 -86 115 -138 399 -230 257 -422 315 -306 147 -96 285 -192 455 -130 263 -144 113 -144 461 -278 369 -120 97 -136 81 -144 113 -232 85 -258 317 -144 633 -86 173 -316 119 -192 163 -96 115 -86 173 -518 85 -174 285 -108 107 -488 201 -264 93 -232 85 -240 215 -124 215 -344 169 -94 143 -120 119 -120 179 -140 255 -146 119 -280 141 -316 143 -418 147 -442 127 -174 201 -172 115 -172 85 -346 115 -144 85 -144 259 -172 201 -316 87 -86 127 -96 263 -192 173 -114 367 -120 133 -552 313 -144 143 -96 85 -260 109 -614
RAW_Data: 333 -140 141 -114 287 -394 257 -88 145 -314 113 -86 113 -178 367 -198 199 -136 229 -662 489 -174 181 -134 171 -82 201 -288 367 -196 85 -88 171 -172 259 -116 85 -144 505 -260 85 -318 489 -114 143 -116 143 -172 115 -116 401 -278 167 -96 335 -120 143 -168 249 -184 95 -86 229 -144 187 -114 87 -86 171 -398 461 -326 95 -96 287 -112 181 -124 115 -178 95 -106 85 -192 109 -120 311 -470 95 -190 825 -114 317 -86 113 -146 113 -174 199 -88 85 -192 261 -332 85 -86 115 -116 661 -86 115 -114 287 -144 259 -202 143 -174 113 -322 297 -202 673 -106 111 -202 171 -232 305 -518 173 -346 113 -404 229 -86 253 -226 113 -144 487 -106 249 -302 195 -120 95 -120 311 -216 209 -192 95 -96 171 -96 95 -168 215 -214 167 -140 311 -140 83 -82 191 -336 95 -216 167 -354 107 -234 315 -88 85 -172 113 -86 315 -236 115 -172 201 -316 115 -374 141 -82 185 -190 325 -274 115 -86 143 -164 191 -86 201 -114 215 -170 95 -264 143 -96 119 -196 229 -82 289 -234 143 -264 201 -86 115 -346 229 -172 143 -202 143 -86 345 -86 173 -138 95 -102 575 -144 143 -230 221 -158 251 -168 103 -96 133 -172 173 -336 143 -188 309 -86 143 -116 85 -144 85 -306 201 -116 215 -286 283 -396 305 -148 317 -216 115 -490 115 -186 111 -144 201 -86 143 -192 285 -128 137 -86 85 -116 173 -216 119 -118 215 -96 95 -216 107 -82 173 -258 115 -168 263 -182 459 -288 143 -86 115 -490 143 -230 115 -144 229 -764 93 -112 81 -118 249 -144 229 -174 201 -374 201 -230 171 -88 223 -304 115 -200 143 -86 87 -174 85 -116 169 -172 429 -168 165 -216 603 -188 119 -120 269 -86 249 -120 141 -216 229 -174 85 -202 251 -186 87 -114 121 -254 649 -144 399 -86 201 -104 169 -162 103 -122 165 -168 119 -120 213 -84 143 -86 143 -168 173 -258 85 -232 315 -86 229 -116 95 -288 217 -124 335 -144 191 -120 333 -120 191 -216 143 -574 375 -86 311 -110 143 -202 287 -86 113 -174 345 -96 511 -88 109 -96 143 -638 133 -120 167 -360 95 -96 95 -144 143 -116 403 -480 341 -88 85 -114 115 -230 111 -226 115 -86 171 -404 259 -144 215 -288 405 -240 105 -402 255 -572 115 -168 113 -216 115 -144 143 -116 143 -374 85 -116 113 -116 287 -162 87 -86 219 -240 113 -116 863 -86 305 -126 113 -202 143 -378 143 -376 391 -88 229 -144 171 -200 259 -86 87 -144 109 -140 85 -116 327 -140 363 -114 143 -244 85 -116 335 -96 309 -352
RAW_Data: 95 -168 219 -96 95 -168 95 -312 333 -144 117 -290 119 -94 373 -240 215 -96 229 -338 135 -202 257 -490 201 -116 85 -202 257 -144 113 -346 85 -86 289 -230 143 -144 109 -168 167 -96 189 -144 239 -114 143 -144 199 -116 85 -202 85 -174 165 -88 113 -112 315 -116 229 -164 119 -110 113 -116 115 -144 85 -202 113 -116 115 -200 115 -86 231 -114 85 -86 287 -168 93 -168 85 -88 257 -144 201 -230 715 -86 115 -144 373 -202 85 -116 85 -194 217 -144 201 -202 143 -172 143 -86 163 -202 115 -402 187 -244 251 -152 191 -336 117 -216 95 -144 253 -114 201 -456 95 -646 85 -288 85 -84 443 -576 115 -116 143 -432 115 -346 257 -334 621 -96 95 -264 171 -198 147 -452 229 -144 215 -288 93 -96 287 -96 165 -96 287 -138 777 -202 363 -190 191 -240 81 -114 119 -118 283 -138 95 -166 229 -194 119 -198 189 -192 167 -168 215 -94 119 -124 81 -196 351 -286 183 -140 969 -346 171 -586 87 -172 201 -164 267 -130 113 -144 191 -98 191 -96 243 -202 201 -174 199 -202 713 -454 95 -144 107 -144 451 -110 201 -174 143 -116 143 -144 285 -84 83 -328 117 -424 119 -144 95 -214 135 -402 115 -114 115 -174 257 -406 215 -336 193 -288 113 -116 229 -86 345 -260 113 -232 101 -264 167 -94 95 -216 401 -202 373 -114 173 -232 279 -690 259 -172 143 -404 229 -220 115 -114 173 -230 171 -318 309 -156 113 -170 223 -172 287 -174 315 -116 229 -332 111 -116 85 -258 431 -404 201 -86 171 -106 115 -96 369 -124 239 -206 115 -230 389 -200 115 -86 565 -488 83 -82 585 -172 459 -198 87 -86 85 -116 143 -202 371 -96 287 -392 221 -174 85 -230 461 -474 93 -120 95 -274 171 -144 339 -226 143 -184 81 -230 141 -216 143 -216 117 -120 167 -216 167 -96 265 -108 165 -86 315 -260 229 -172 87 -312 587 -150 341 -200 187 -432 171 -84 85 -202 85 -116 85 -116 431 -114 201 -84 169 -86 85 -114 313 -346 85 -86 85 -142 159 -646 143 -88 119 -120 521 -134 173 -128 315 -462 99 -362 227 -144 167 -120 165 -246 215 -86 825 -168 443 -536 835 -316 85 -174 113 -144 85 -144 173 -458 143 -288 81 -170 143 -268 215 -192 285 -360 113 -258 225 -168 163 -334 113 -116 257 -296 287 -312 277 -116 603 -82 255 -96 95 -336 301 -82 95 -552 141 -332 281 -110 201 -172 145 -200 115 -144 95 -344 201 -116 171 -96 119 -120 143 -144 421 -96 199 -394 107 -110 115 -114 145 -316 315 -288 115 -200 87 -114 115 -288
RAW_Data: 85 -374 259 -260 113 -174 287 -144 507 -202 229 -144 221 -142 115 -124 143 -216 95 -96 117 -216 143 -144 85 -144 143 -144 201 -144 85 -284 469 -190 149 -86 143 -316 283 -290 95 -216 119 -180 167 -200 375 -86 111 -192 143 -144 213 -404 85 -144 719 -202 85 -434 143 -144 143 -172 287 -264 111 -114 315 -96 115 -576 85 -230 85 -144 143 -174 281 -198 201 -86 201 -144 575 -116 85 -174 143 -164 315 -168 171 -268 85 -536 111 -172 153 -462 239 -158 333 -174 361 -258 343 -96 453 -240 119 -256 113 -88 171 -172 259 -230 173 -110 113 -202 113 -88 113 -232 315 -100 165 -422 99 -316 311 -262 191 -120 555 -280 85 -174 431 -86 259 -210 119 -168 885 -462 433 -106 107 -116 113 -644 127 -278 115 -86 87 -226 159 -346 115 -144 85 -144 85 -768 541 -168 113 -86 87 -374 113 -144 747 -230 187 -268 521 -346 311 -1194 383 -478 313 -110 229 -202 171 -144 287 -722 285 -138 225 -188 133 -346 85 -174 199 -374 229 -112 135 -194 95 -216 143 -120 377 -86 245 -120 93 -96 95 -178 217 -86 277 -312 517 -530 505 -192 259 -106 119 -94 143 -336 293 -348 219 -316 87 -258 85 -174 143 -86 85 -116 171 -398 167 -88 85 -116 85 -202 459 -314 143 -202 459 -222 253 -202 171 -462 143 -490 143 -264 249 -340 147 -88 143 -144 113 -144 461 -258 85 -86 115 -202 171 -86 317 -86 115 -114 283 -86 287 -116 373 -86 287 -156 659 -158 87 -114 201 -124 95 -86 287 -172 87 -172 113 -144 663 -230 143 -162 95 -116 143 -116 113 -86 173 -356 99 -198 391 -140 191 -144 219 -172 171 -318 191 -374 201 -328 87 -230 85 -86 143 -116 195 -96 99 -226 383 -382 119 -264 431 -120 167 -120 95 -312 191 -106 85 -172 143 -520 95 -238 299 -288 359 -108 375 -172 185 -150 213 -168 119 -120 127 -146 171 -86 143 -202 115 -144 113 -202 201 -116 113 -144 365 -142 143 -22490 523 -858 969 -1190 1065 -1160 1067 -1146 683 -754 1133 -1100 747 -712 775 -708 779 -702 1125 -1102 1119 -1094 767 -698 763 -728 759 -734 755 -710 757 -738 1117 -1070 815 -648 1207 -1010 1197 -1024 835 -658 779 -710 771 -710 779 -706 1115 -1102 1133 -1066 815 -644 843 -650 1203 -1010 1207 -998 1197 -1042 1153 -1020 803 -710 1141 -1076 791 -678 785 -708 767 -712 773 -710 775 -704 779 -704 815 -646 839 -646 843 -648 813 -656 1205 -1012 1205 -1020 1193 -1020 815 -644 843 -624 1551 -1394 1553 -1364 1575 -1390 819 -672 841 -680 755 -712 1141 -1076 1185 -1016 1191 -1050 763 -704
RAW_Data: 1183 -1014 813 -646 841 -644 843 -648 1203 -1010 1207 -996 805 -714 775 -710 775 -678 835 -648 813 -672 1181 -1016 799 -710 1139 -1076 1151 -1064 811 -646 845 -646 843 -622 843 -650 1205 -1012 1177 -1022 805 -712 775 -714 1139 -1076 1149 -1034 1205 -998 1177 -1040 811 -670 1183 -1012 855 -626 835 -674 817 -644 843 -648 843 -624 845 -674 761 -732 755 -712 779 -714 773 -710 1139 -1080 1127 -1092 1149 -1024 811 -658 831 -658 1499 -1406 1555 -1404 1557 -1408 805 -668 815 -676 817 -678 1131 -1092 1159 -1018 1213 -1022 815 -676 1131 -1092 789 -642 843 -646 841 -648 1185 -1036 1181 -1018 801 -710 775 -678 829 -668 815 -644 845 -646 1181 -1038 831 -650 1207 -992 1211 -1048 791 -650 843 -676 763 -706 763 -734 1119 -1094 1153 -1018 823 -656 829 -676 1179 -1022 1159 -1070 1179 -1006 1191 -1022 815 -706 1125 -1066 813 -648 845 -646 841 -650 815 -678 783 -710 755 -712 779 -710 769 -710 775 -706 835 -646 1181 -1020 1193 -1022 1185 -1016 833 -654 833 -624 1559 -1410 1515 -1384 1569 -1414 789 -674 843 -674 761 -730 1133 -1068 1177 -1010 1195 -1026 817 -678 1151 -1066 813 -646 817 -672 819 -646 1209 -1012 1197 -1024 835 -658 769 -710 799 -710 749 -690 835 -640 1211 -1018 777 -736 1115 -1078 1151 -1064 809 -644 841 -646 841 -624 841 -650 1201 -1010 1205 -1018 803 -712 773 -704 1145 -1076 1121 -1092 1157 -1016 1185 -1048 791 -674 1179 -1012 835 -648 841 -646 843 -646 843 -674 767 -708 769 -714 777 -714 747 -734 777 -668 843 -644 1205 -1006 1193 -1048 1177 -1012 805 -668 843 -620 1545 -1418 1521 -1388 1575 -1360 841 -672 819 -682 769 -712 1139 -1076 1157 -1040 1197 -1026 835 -658 1143 -1072 817 -620 845 -646 843 -674 1185 -988 1205 -1018 801 -712 777 -706 781 -674 841 -646 817 -648 1207 -1008 831 -652 1199 -1024 1199 -1042 817 -644 817 -648 841 -676 765 -706 1149 -1064 1179 -1020 829 -658 825 -654 1197 -1024 1179 -1012 1205 -992 1183 -1072 789 -674 1183 -1010 837 -650 841 -644 843 -646 843 -678 789 -676 763 -706 793 -710 769 -712 775 -706 781 -674 1205 -1022 1139 -1098 1157 -1014 827 -652 829 -640 1537 -1388 1567 -1388 1541 -1392 813 -698 815 -676 767 -734 1133 -1076 1131 -1040 1195 -1052 811 -678 1133 -1070 819 -620 843 -646 843 -676 1125 -1090 1179 -994 859 -632 797 -710 775 -702 839 -622 841 -644 1211 -992 801 -710 1139 -1078 1151 -1062 813 -646 843 -646 843 -622 841 -650 1205 -1010 1203 -1020 823 -658 825 -654 1195 -1022 1201 -1040 1155 -1016 1185 -1046 815 -650 1177 -1034 833 -644 843 -646 819 -674 815 -676 767 -710 769 -712 775 -710 775 -678 861 -620 841 -646 1205 -1008
RAW_Data: 1221 -1022 1185 -1016 813 -646 841 -618 1573 -1364 1577 -1362 1811 -2658 227 -138 191 -120 333 -488 345 -86 403 -86 115 -604 283 -82 343 -202 143 -316 87 -128 311 -230 119 -264 165 -168 247 -216 199 -166 283 -230 81 -132 487 -114 115 -142 921 -260 345 -114 373 -116 115 -114 115 -166 191 -192 171 -116 417 -242 167 -240 285 -120 283 -86 257 -230 335 -244 167 -96 167 -188 161 -96 85 -232 173 -114 201 -144 363 -144 87 -86 507 -88 143 -490 103 -124 143 -460 517 -144 219 -202 173 -144 113 -318 229 -174 401 -442 143 -88 603 -144 259 -86 115 -116 113 -144 113 -142 297 -202 171 -86 201 -86 115 -374 163 -364 471 -104 169 -88 201 -144 237 -234 203 -160 113 -86 269 -96 95 -240 431 -94 295 -328 191 -144 239 -240 165 -96 119 -168 421 -238 191 -144 119 -168 143 -120 143 -96 209 -164 239 -240 335 -116 201 -316 115 -172 201 -114 115 -172 173 -86 431 -202 143 -86 229 -116 171 -86 317 -162 143 -174 113 -174 85 -228 85 -142 139 -196 305 -106 85 -232 171 -168 531 -86 85 -86 173 -172 143 -260 137 -342 257 -174 85 -100 115 -170 139 -174 829 -96 191 -192 311 -240 311 -82 211 -144 475 -114 201 -86 85 -286 239 -144 95 -264 227 -120 387 -202 251 -142 143 -316 345 -450 85 -174 315 -372 251 -258 143 -230 221 -156 431 -170 85 -114 431 -364 633 -174 421 -114 259 -86 201 -116 115 -86 229 -174 103 -96 115 -244 307 -86 345 -356 259 -450 693 -98 263 -456 191 -96 357 -116 85 -86 115 -230 201 -88 161 -518 259 -340 173 -116 315 -140 107 -218 517 -96 285 -124 95 -382 119 -144 167 -168 357 -168 119 -144 287 -142 95 -200 143 -260 201 -306 173 -604 479 -224 285 -106 507 -116 165 -408 359 -288 97 -116 225 -430 85 -144 449 -374 113 -120 95 -96 241 -106 101 -86 123 -120 117 -214 107 -144 263 -268 119 -120 141 -96 119 -216 229 -306 287 -150 135 -172 287 -114 215 -168 143 -172 115 -462 113 -144 143 -490 199 -116 403 -116 171 -590 637 -304 113 -86 143 -100 111 -534 149 -312 237 -236 143 -202 85 -202 171 -488 109 -572 201 -238 95 -174 397 -202 283 -164 87 -662 201 -244 315 -562 143 -86 325 -96 575 -190 191 -144 85 -202 189 -358 287 -618 835 -160 163 -142 85 -172 139 -144 215 -82 287 -114 87 -144 541 -438 143 -240 167 -144 359 -190 95 -120 263 -108 109 -184 215 -100 113 -288 119 -144 95 -406 81 -114 87 -256 315 -316 171 -100 105 -144 263 -302 229 -174
RAW_Data: 113 -232 197 -176 143 -200 187 -240 537 -96 95 -118 263 -432 141 -96 119 -216 761 -282 119 -526 119 -120 185 -116 171 -168 81 -86 143 -172 173 -86 113 -144 489 -202 143 -174 287 -186 373 -168 373 -174 85 -168 119 -330 325 -174 113 -144 373 -202 143 -138 195 -174 185 -192 119 -412 115 -114 283 -120 143 -360 525 -120 119 -120 367 -116 115 -144 345 -114 87 -120 287 -240 239 -96 503 -168 459 -144 317 -242 95 -104 255 -82 227 -172 307 -314 119 -264 901 -282 171 -202 171 -346 201 -576 167 -196 201 -288 315 -116 85 -144 85 -290 143 -264 303 -532 173 -120 215 -272 603 -86 143 -86 85 -190 167 -144 431 -238 119 -96 119 -96 455 -96 285 -144 287 -618 85 -288 253 -592 105 -104 139 -188 335 -120 511 -166 431 -202 373 -86 87 -114 231 -206 83 -190 199 -288 201 -86 171 -88 195 -120 201 -116 257 -202 161 -156 229 -144 143 -298 263 -166 119 -158 115 -326 455 -166 95 -144 119 -168 141 -216 455 -334 95 -144 95 -214 143 -96 143 -196 143 -190 479 -364 287 -114 163 -86 287 -130 297 -96 167 -96 431 -144 95 -190 119 -144 141 -120 335 -144 285 -188 497 -112 429 -258 143 -140 111 -232 87 -116 143 -96 285 -204 273 -632 371 -144 85 -202 115 -172 499 -144 143 -120 119 -120 95 -360 143 -258 173 -930 315 -134 431 -144 115 -114 257 -740 373 -174 95 -144 297 -268 167 -96 143 -834 171 -168 95 -172 119 -96 85 -88 199 -88 315 -172 259 -216 311 -202 85 -260 257 -144 657 -120 119 -116 223 -286 233 -130 115 -202 85 -144 143 -172 115 -88 85 -114 95 -114 345 -288 85 -116 471 -124 173 -114 335 -260 115 -658 339 -260 113 -86 201 -480 217 -470 105 -114 259 -134 137 -86 171 -326 191 -120 263 -144 95 -148 289 -124 121 -384 95 -322 171 -142 193 -288 143 -172 211 -266 109 -144 325 -168 213 -96 685 -310 239 -262 143 -216 143 -316 393 -126 215 -216 387 -202 201 -230 143 -116 85 -144 201 -268 143 -262 311 -86 115 -316 167 -86 229 -116 335 -144 117 -302 113 -116 241 -86 143 -202 201 -116 453 -288 293 -272 367 -120 651 -170 565 -116 143 -882 557 -116 181 -588 119 -168 287 -168 119 -118 191 -168 143 -282 115 -88 171 -404 719 -202 115 -172 253 -144 143 -532 121 -144 239 -96 167 -120 119 -456 199 -114 311 -86 201 -352 111 -144 115 -114 173 -86 85 -538 113 -88 257 -116 143 -96 95 -144 121 -198 127 -172 173 -114 229 -116 143 -144 173 -368 111 -200 163 -116
RAW_Data: 113 -292 169 -200 145 -86 85 -230 259 -86 85 -86 439 -96 85 -116 115 -86 113 -86 85 -192 191 -214 263 -264 119 -96 345 -116 85 -86 173 -288 85 -104 145 -130 85 -662 243 -390 263 -96 129 -422 223 -288 219 -172 655 -108 361 -96 271 -432 167 -120 421 -278 217 -248 143 -96 165 -240 109 -628 99 -96 95 -168 95 -216 119 -144 171 -172 115 -86 85 -174 387 -190 239 -384 143 -344 115 -114 143 -86 233 -140 85 -724 119 -82 85 -144 115 -144 115 -144 143 -114 201 -174 215 -96 109 -144 85 -144 599 -144 115 -258 249 -206 171 -86 143 -110 255 -86 85 -86 287 -208 225 -100 193 -200 143 -288 139 -460 113 -498 85 -144 143 -88 85 -144 229 -144 85 -144 171 -288 261 -202 113 -88 87 -114 143 -288 373 -366 229 -202 201 -172 173 -172 421 -280 153 -120 81 -160 137 -116 201 -250 141 -230 115 -318 863 -206 119 -462 143 -144 85 -86 201 -230 407 -96 223 -112 143 -94 95 -106 479 -86 113 -174 171 -284 119 -158 239 -190 167 -204 185 -408 215 -168 259 -202 201 -86 85 -202 87 -448 249 -332 363 -490 85 -172 115 -114 145 -114 259 -144 101 -142 119 -240 143 -188 387 -384 425 -144 173 -506 137 -162 139 -174 253 -116 131 -106 115 -130 117 -144 95 -86 239 -192 407 -120 237 -144 143 -82 487 -102 439 -112 199 -88 201 -262 269 -230 229 -192 219 -252 133 -96 191 -346 135 -288 621 -232 661 -202 327 -164 143 -144 139 -536 115 -114 143 -174 85 -100 99 -86 85 -174 85 -144 345 -172 243 -408 115 -86 115 -202 229 -114 87 -114 229 -740 801 -158 143 -168 479 -124 103 -264 119 -240 171 -88 219 -278 431 -402 513 -264 465 -256 141 -168 115 -358 251 -316 387 -172 101 -96 683 -192 95 -120 191 -120 95 -462 261 -96 121 -180 167 -878 287 -86 143 -86 311 -118 287 -168 191 -96 167 -158 85 -86 315 -434 165 -822 171 -316 231 -84 415 -174 87 -296 229 -222 93 -192 167 -190 143 -96 95 -96 237 -168 259 -86 115 -346 171 -116 115 -114 317 -114 95 -140 373 -116 143 -286 207 -260 171 -202 171 -134 119 -320 453 -96 293 -168 143 -144 119 -172 143 -202 237 -360 225 -86 287 -86 201 -202 109 -120 133 -214 215 -116 85 -260 267 -122 335 -316 111 -604 87 -172 259 -258 235 -96 173 -230 339 -140 115 -86 287 -288 143 -186 95 -96 95 -96 339 -256 147 -158 143 -246 223 -264 213 -202 85 -110 95 -168 95 -118 119 -168 95 -264 191 -316 119 -144 119 -382 167 -120

View File

@@ -425,13 +425,6 @@ MU_TEST(subghz_decoder_keeloq_test) {
"Test decoder " SUBGHZ_PROTOCOL_KEELOQ_NAME " error\r\n"); "Test decoder " SUBGHZ_PROTOCOL_KEELOQ_NAME " error\r\n");
} }
MU_TEST(subghz_decoder_kia_seed_test) {
mu_assert(
subghz_decoder_test(
EXT_PATH("unit_tests/subghz/kia_seed_raw.sub"), SUBGHZ_PROTOCOL_KIA_NAME),
"Test decoder " SUBGHZ_PROTOCOL_KIA_NAME " error\r\n");
}
MU_TEST(subghz_decoder_nero_radio_test) { MU_TEST(subghz_decoder_nero_radio_test) {
mu_assert( mu_assert(
subghz_decoder_test( subghz_decoder_test(
@@ -467,14 +460,6 @@ MU_TEST(subghz_decoder_princeton_test) {
"Test decoder " SUBGHZ_PROTOCOL_PRINCETON_NAME " error\r\n"); "Test decoder " SUBGHZ_PROTOCOL_PRINCETON_NAME " error\r\n");
} }
MU_TEST(subghz_decoder_scher_khan_magic_code_test) {
mu_assert(
subghz_decoder_test(
EXT_PATH("unit_tests/subghz/scher_khan_magic_code.sub"),
SUBGHZ_PROTOCOL_SCHER_KHAN_NAME),
"Test decoder " SUBGHZ_PROTOCOL_SCHER_KHAN_NAME " error\r\n");
}
MU_TEST(subghz_decoder_somfy_keytis_test) { MU_TEST(subghz_decoder_somfy_keytis_test) {
mu_assert( mu_assert(
subghz_decoder_test( subghz_decoder_test(
@@ -489,13 +474,6 @@ MU_TEST(subghz_decoder_somfy_telis_test) {
"Test decoder " SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME " error\r\n"); "Test decoder " SUBGHZ_PROTOCOL_SOMFY_TELIS_NAME " error\r\n");
} }
MU_TEST(subghz_decoder_star_line_test) {
mu_assert(
subghz_decoder_test(
EXT_PATH("unit_tests/subghz/cenmax_raw.sub"), SUBGHZ_PROTOCOL_STAR_LINE_NAME),
"Test decoder " SUBGHZ_PROTOCOL_STAR_LINE_NAME " error\r\n");
}
MU_TEST(subghz_decoder_linear_test) { MU_TEST(subghz_decoder_linear_test) {
mu_assert( mu_assert(
subghz_decoder_test( subghz_decoder_test(
@@ -984,16 +962,13 @@ MU_TEST_SUITE(subghz) {
MU_RUN_TEST(subghz_decoder_hormann_hsm_test); MU_RUN_TEST(subghz_decoder_hormann_hsm_test);
MU_RUN_TEST(subghz_decoder_ido_test); MU_RUN_TEST(subghz_decoder_ido_test);
MU_RUN_TEST(subghz_decoder_keeloq_test); MU_RUN_TEST(subghz_decoder_keeloq_test);
MU_RUN_TEST(subghz_decoder_kia_seed_test);
MU_RUN_TEST(subghz_decoder_nero_radio_test); MU_RUN_TEST(subghz_decoder_nero_radio_test);
MU_RUN_TEST(subghz_decoder_nero_sketch_test); MU_RUN_TEST(subghz_decoder_nero_sketch_test);
MU_RUN_TEST(subghz_decoder_nice_flo_test); MU_RUN_TEST(subghz_decoder_nice_flo_test);
MU_RUN_TEST(subghz_decoder_nice_flor_s_test); MU_RUN_TEST(subghz_decoder_nice_flor_s_test);
MU_RUN_TEST(subghz_decoder_princeton_test); MU_RUN_TEST(subghz_decoder_princeton_test);
MU_RUN_TEST(subghz_decoder_scher_khan_magic_code_test);
MU_RUN_TEST(subghz_decoder_somfy_keytis_test); MU_RUN_TEST(subghz_decoder_somfy_keytis_test);
MU_RUN_TEST(subghz_decoder_somfy_telis_test); MU_RUN_TEST(subghz_decoder_somfy_telis_test);
MU_RUN_TEST(subghz_decoder_star_line_test);
MU_RUN_TEST(subghz_decoder_linear_test); MU_RUN_TEST(subghz_decoder_linear_test);
MU_RUN_TEST(subghz_decoder_linear_delta3_test); MU_RUN_TEST(subghz_decoder_linear_delta3_test);
MU_RUN_TEST(subghz_decoder_megacode_test); MU_RUN_TEST(subghz_decoder_megacode_test);

View File

@@ -43,6 +43,10 @@ static void subghz_device_cc1101_ext_interconnect_load_preset(
subghz_device_cc1101_ext_load_custom_preset( subghz_device_cc1101_ext_load_custom_preset(
subghz_device_cc1101_preset_2fsk_dev2_38khz_async_regs); subghz_device_cc1101_preset_2fsk_dev2_38khz_async_regs);
break; break;
case FuriHalSubGhzPreset2FSKDev12KAsync:
subghz_device_cc1101_ext_load_custom_preset(
subghz_device_cc1101_preset_2fsk_dev12khz_async_regs);
break;
case FuriHalSubGhzPreset2FSKDev476Async: case FuriHalSubGhzPreset2FSKDev476Async:
subghz_device_cc1101_ext_load_custom_preset( subghz_device_cc1101_ext_load_custom_preset(
subghz_device_cc1101_preset_2fsk_dev47_6khz_async_regs); subghz_device_cc1101_preset_2fsk_dev47_6khz_async_regs);

View File

@@ -26,7 +26,7 @@ typedef struct {
uint8_t worker_result; uint8_t worker_result;
} EventLoopMutexApp; } EventLoopMutexApp;
// This funciton is being run in a separate thread to simulate lenghty blocking operations // This funciton is being run in a separate thread to simulate lengthy blocking operations
static int32_t event_loop_mutex_app_worker_thread(void* context) { static int32_t event_loop_mutex_app_worker_thread(void* context) {
furi_assert(context); furi_assert(context);
EventLoopMutexApp* app = context; EventLoopMutexApp* app = context;

View File

@@ -35,6 +35,8 @@ void nfc_scene_slix_unlock_on_enter(void* context) {
instance->popup, "Hold card next\nto Flipper's back", 94, 27, AlignCenter, AlignTop); instance->popup, "Hold card next\nto Flipper's back", 94, 27, AlignCenter, AlignTop);
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup); view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);
notification_message(instance->notifications, &sequence_blink_start_cyan);
instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolSlix); instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolSlix);
nfc_poller_start(instance->poller, nfc_scene_slix_unlock_worker_callback, instance); nfc_poller_start(instance->poller, nfc_scene_slix_unlock_worker_callback, instance);
} }
@@ -67,4 +69,7 @@ void nfc_scene_slix_unlock_on_exit(void* context) {
nfc_poller_free(instance->poller); nfc_poller_free(instance->poller);
popup_reset(instance->popup); popup_reset(instance->popup);
// Stop notifications
nfc_blink_stop(instance);
} }

View File

@@ -78,6 +78,8 @@ typedef enum {
SetTypeFaacSLH_433, SetTypeFaacSLH_433,
SetTypeBFTMitto, SetTypeBFTMitto,
SetTypeSomfyTelis, SetTypeSomfyTelis,
SetTypeKingGatesStylo4k,
SetTypeBenincaARC,
SetTypeANMotorsAT4, SetTypeANMotorsAT4,
SetTypeAlutechAT4N, SetTypeAlutechAT4N,
SetTypePhoenix_V2_433, SetTypePhoenix_V2_433,
@@ -96,8 +98,8 @@ typedef enum {
SetTypeMotorline433, SetTypeMotorline433,
SetTypeSommer_FM_434, SetTypeSommer_FM_434,
SetTypeSommer_FM_868, SetTypeSommer_FM_868,
SetTypeSommer_FM238_434, SetTypeSommer_FM12K_434,
SetTypeSommer_FM238_868, SetTypeSommer_FM12K_868,
SetTypeStilmatic, SetTypeStilmatic,
SetTypeIronLogic, SetTypeIronLogic,
SetTypeIronLogicSmart, SetTypeIronLogicSmart,
@@ -111,6 +113,7 @@ typedef enum {
SetTypeJCM_433_92, SetTypeJCM_433_92,
SetTypeNovoferm_433_92, SetTypeNovoferm_433_92,
SetTypeHormannEcoStar_433_92, SetTypeHormannEcoStar_433_92,
SetTypeCardinS449_433FM,
SetTypeFAACRCXT_433_92, SetTypeFAACRCXT_433_92,
SetTypeFAACRCXT_868, SetTypeFAACRCXT_868,
SetTypeGeniusBravo433, SetTypeGeniusBravo433,

View File

@@ -426,7 +426,7 @@ void subghz_scene_set_type_fill_generation_infos(GenInfo* infos_dest, SetType ty
.keeloq.serial = (key & 0x0000FFFF) | 0x01700000, .keeloq.serial = (key & 0x0000FFFF) | 0x01700000,
.keeloq.btn = 0x02, .keeloq.btn = 0x02,
.keeloq.cnt = 0x03, .keeloq.cnt = 0x03,
.keeloq.manuf = "Sommer(fsk476)"}; .keeloq.manuf = "Sommer"};
break; break;
case SetTypeSommer_FM_868: case SetTypeSommer_FM_868:
gen_info = (GenInfo){ gen_info = (GenInfo){
@@ -436,27 +436,27 @@ void subghz_scene_set_type_fill_generation_infos(GenInfo* infos_dest, SetType ty
.keeloq.serial = (key & 0x0000FFFF) | 0x01700000, .keeloq.serial = (key & 0x0000FFFF) | 0x01700000,
.keeloq.btn = 0x02, .keeloq.btn = 0x02,
.keeloq.cnt = 0x03, .keeloq.cnt = 0x03,
.keeloq.manuf = "Sommer(fsk476)"}; .keeloq.manuf = "Sommer"};
break; break;
case SetTypeSommer_FM238_434: case SetTypeSommer_FM12K_434:
gen_info = (GenInfo){ gen_info = (GenInfo){
.type = GenKeeloq, .type = GenKeeloq,
.mod = "FM238", .mod = "FM12K",
.freq = 434420000, .freq = 434420000,
.keeloq.serial = key & 0x0000FFFF, .keeloq.serial = key & 0x0000FFFF,
.keeloq.btn = 0x02, .keeloq.btn = 0x02,
.keeloq.cnt = 0x03, .keeloq.cnt = 0x03,
.keeloq.manuf = "Sommer(fsk476)"}; .keeloq.manuf = "Sommer"};
break; break;
case SetTypeSommer_FM238_868: case SetTypeSommer_FM12K_868:
gen_info = (GenInfo){ gen_info = (GenInfo){
.type = GenKeeloq, .type = GenKeeloq,
.mod = "FM238", .mod = "FM12K",
.freq = 868800000, .freq = 868800000,
.keeloq.serial = key & 0x0000FFFF, .keeloq.serial = key & 0x0000FFFF,
.keeloq.btn = 0x02, .keeloq.btn = 0x02,
.keeloq.cnt = 0x03, .keeloq.cnt = 0x03,
.keeloq.manuf = "Sommer(fsk476)"}; .keeloq.manuf = "Sommer"};
break; break;
case SetTypeDTMNeo433: case SetTypeDTMNeo433:
gen_info = (GenInfo){ gen_info = (GenInfo){
@@ -523,6 +523,24 @@ void subghz_scene_set_type_fill_generation_infos(GenInfo* infos_dest, SetType ty
.somfy_telis.btn = 0x02, .somfy_telis.btn = 0x02,
.somfy_telis.cnt = 0x03}; .somfy_telis.cnt = 0x03};
break; break;
case SetTypeKingGatesStylo4k:
gen_info = (GenInfo){
.type = GenKingGatesStylo4k,
.mod = "AM650",
.freq = 433920000,
.kinggates_stylo_4k.serial = key & 0xFFFFFFFF,
.kinggates_stylo_4k.btn = 0x0E,
.kinggates_stylo_4k.cnt = 0x03};
break;
case SetTypeBenincaARC:
gen_info = (GenInfo){
.type = GenBenincaARC,
.mod = "AM650",
.freq = 433920000,
.beninca_arc.serial = key & 0x00FFFFFF,
.beninca_arc.btn = 0x02,
.beninca_arc.cnt = 0x03};
break;
case SetTypeMotorline433: case SetTypeMotorline433:
gen_info = (GenInfo){ gen_info = (GenInfo){
.type = GenKeeloq, .type = GenKeeloq,
@@ -643,6 +661,16 @@ void subghz_scene_set_type_fill_generation_infos(GenInfo* infos_dest, SetType ty
.keeloq.cnt = 0x03, .keeloq.cnt = 0x03,
.keeloq.manuf = "EcoStar"}; .keeloq.manuf = "EcoStar"};
break; break;
case SetTypeCardinS449_433FM:
gen_info = (GenInfo){
.type = GenKeeloq,
.mod = "FM12K",
.freq = 433920000,
.keeloq.serial = (key & 0x000FFFFF),
.keeloq.btn = 0x02,
.keeloq.cnt = 0x03,
.keeloq.manuf = "Cardin_S449"};
break;
case SetTypeFAACRCXT_433_92: case SetTypeFAACRCXT_433_92:
gen_info = (GenInfo){ gen_info = (GenInfo){
.type = GenKeeloq, .type = GenKeeloq,

View File

@@ -10,6 +10,8 @@ typedef enum {
GenKeeloqBFT, GenKeeloqBFT,
GenAlutechAt4n, GenAlutechAt4n,
GenSomfyTelis, GenSomfyTelis,
GenKingGatesStylo4k,
GenBenincaARC,
GenNiceFlorS, GenNiceFlorS,
GenSecPlus1, GenSecPlus1,
GenSecPlus2, GenSecPlus2,
@@ -61,6 +63,16 @@ typedef struct {
uint8_t btn; uint8_t btn;
uint16_t cnt; uint16_t cnt;
} somfy_telis; } somfy_telis;
struct {
uint32_t serial;
uint8_t btn;
uint16_t cnt;
} kinggates_stylo_4k;
struct {
uint32_t serial;
uint8_t btn;
uint32_t cnt;
} beninca_arc;
struct { struct {
uint32_t serial; uint32_t serial;
uint8_t btn; uint8_t btn;

View File

@@ -121,6 +121,8 @@ const char* subghz_txrx_get_preset_name(SubGhzTxRx* instance, const char* preset
preset_name = "AM650"; preset_name = "AM650";
} else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev238Async")) { } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev238Async")) {
preset_name = "FM238"; preset_name = "FM238";
} else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev12KAsync")) {
preset_name = "FM12K";
} else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev476Async")) { } else if(!strcmp(preset, "FuriHalSubGhzPreset2FSKDev476Async")) {
preset_name = "FM476"; preset_name = "FM476";
} else if(!strcmp(preset, "FuriHalSubGhzPresetCustom")) { } else if(!strcmp(preset, "FuriHalSubGhzPresetCustom")) {

View File

@@ -335,6 +335,66 @@ bool subghz_txrx_gen_somfy_telis_protocol(
return res; return res;
} }
bool subghz_txrx_gen_kinggates_stylo_4k_protocol(
void* context,
const char* preset_name,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint16_t cnt) {
SubGhzTxRx* txrx = context;
bool res = false;
txrx->transmitter =
subghz_transmitter_alloc_init(txrx->environment, SUBGHZ_PROTOCOL_KINGGATES_STYLO_4K_NAME);
subghz_txrx_set_preset(txrx, preset_name, frequency, NAN, NAN, NULL, 0);
if(txrx->transmitter && subghz_protocol_kinggates_stylo_4k_create_data(
subghz_transmitter_get_protocol_instance(txrx->transmitter),
txrx->fff_data,
serial,
btn,
cnt,
txrx->preset)) {
res = true;
}
subghz_transmitter_free(txrx->transmitter);
return res;
}
bool subghz_txrx_gen_beninca_arc_protocol(
void* context,
const char* preset_name,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint32_t cnt) {
SubGhzTxRx* txrx = context;
bool res = false;
txrx->transmitter =
subghz_transmitter_alloc_init(txrx->environment, SUBGHZ_PROTOCOL_BENINCA_ARC_NAME);
subghz_txrx_set_preset(txrx, preset_name, frequency, NAN, NAN, NULL, 0);
if(txrx->transmitter && subghz_protocol_beninca_arc_create_data(
subghz_transmitter_get_protocol_instance(txrx->transmitter),
txrx->fff_data,
serial,
btn,
cnt,
txrx->preset)) {
res = true;
}
subghz_transmitter_free(txrx->transmitter);
return res;
}
bool subghz_txrx_gen_secplus_v2_protocol( bool subghz_txrx_gen_secplus_v2_protocol(
SubGhzTxRx* instance, SubGhzTxRx* instance,
const char* name_preset, const char* name_preset,

View File

@@ -108,6 +108,22 @@ bool subghz_txrx_gen_somfy_telis_protocol(
uint8_t btn, uint8_t btn,
uint16_t cnt); uint16_t cnt);
bool subghz_txrx_gen_kinggates_stylo_4k_protocol(
void* context,
const char* preset_name,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint16_t cnt);
bool subghz_txrx_gen_beninca_arc_protocol(
void* context,
const char* preset_name,
uint32_t frequency,
uint32_t serial,
uint8_t btn,
uint32_t cnt);
bool subghz_txrx_gen_came_atomo_protocol( bool subghz_txrx_gen_came_atomo_protocol(
void* context, void* context,
const char* preset_name, const char* preset_name,

View File

@@ -1,69 +1,71 @@
Filetype: Flipper SubGhz Keystore File Filetype: Flipper SubGhz Keystore File
Version: 0 Version: 0
Encryption: 1 Encryption: 1
IV: 46 75 72 72 79 20 52 6F 63 6B 65 74 21 21 21 30 IV: 4F 77 4F 20 66 75 72 72 79 20 49 56 20 55 77 55
05176EEFAC177FE261FE3EB5C8E103BE7CF9F2FEB32BDD6BB63D22EE9C17B9D2 1D0560740B25F58EE0E85BF949139971E5AA08C5499CC74B11992D124C281012
B645E3CAC0D5E26891249D326BCEB09850E4FB8F8E86A466E97E83437A9E0041 C05E2D2C715D8E24C518EF2841DA02173C05DD5BA5310EE85D09709500DB1726
AA4255FFA1ADE8FB840F80A93F8F1A2D1E39051131D24DE7258D66A8CF2066CF 9EA5721836369FF918859077F50E33100F7AC53E8E8F31E25296579F875359DF
13ACA390FD5254B024084D5D1F41B8DDF5304FF00C3C85A9C26CD13A7A268654 D2A8AD1B65BC66B459525124CDC5011C79D98F542702FC69EABD64F908C0D80D
4CFBF498D5E2C85496985E83D91B0F4229A925E16A90C6712750032C3699EE0AA5D04123E579B6121573FC61766E89AD 2FA5F078BEB59851D42BC7E4E331AE3A8C384892DF003238CDA82450A6CD02AC
93DADC2AE4235470E171E0E85D24D04A84C37187284C38D1CBB48666FDA8CD6C E54ED5F49A093BC938521195C86FECF35FB6EC463C54C6E1609592DC5FA03CCB5E1EDA362FC9AB008C85E66B60147EBA
DB13D8CCC0CB07685F29F33AE07DA2FD14C2AE4F4D001DB88465D5CFE8CFDAA9 048F4A28B18496487D65A924F4E37766C3563F41090D442DE61D7A5DD82F5FF1
E51CD1B5074B63D26E274218A0AB3B2E435454EE094DCA5679F35477658A72F9 DA876A11401727E5102B578F87CCF9596AB9D9925FC90CDF99C9DEC7261B2C8C
10AFD5FD9C296E67EDD9504A60BA9EF84556F40213DEC4DE44F99B088BCC6A57 03D3842335D69A3AA42452274130B3FAAEE6087CB8D783B0E770062C034BB302
EF7AA55F6A473DE093D648240D5FCEB05F8B3295DC37B3E83239A4AF320CD688 7F50401E9FFAF10D1F61067C2E830EBBEC7C8B3B20F5C0AC2E10E68912BF2C82
A22892E71B9D0D7FAF92B27C724E76C4A6824DBE5F083F1006D11E42D153C4AC98D0A11C6A8D62F5921A24ECC7437485 160BC0CA2FF01E076830F29846C1F6CCBAC7857F2043E8163449048BA8C99AA8
7A25416E390D81DA68A59C3BA30D4B7FC8269B5E0DAF77CA3A857B6F478A050585918485AEE72D375F02D177CB296E31 09357F089CB148DDC578E0F11EC10659EF68A57440700F584922CB9842E2BF08AC977CCAA11355E89FA5C18113349F5E
94004BA0BB1E47965E60025949EF4CC2738C463F57C97FD2A89C76CCCDEA5397 910D166F40F264225BD4C8EB16C5CC6374F8F8E1202D5BF28FA2E8BA38E420A36E67611E6D151051F7C74843E4A72BBC
111CB1C19863A0165521D974F838CE718DA07948A8D9A8A7490E75032A62ECA2 D9ACEBC528D7CA74B894A0378095E03C9BDBBE13DDA3FCD6D60CD3CAC49746B8
17B6E27C69FA002F6CF23D719DFE595140BEFA5083D12E774CF89E2CED53D68D 90F94FD262E1859B7E5C08E7ED5B16CDB56D0E930034E315CD011DE3759150DA
73311E0FF8ABB3E9461AD14A4F52791647A50E2102D3B74188A73C35BC14EB55 6620E176FC61DF250EF2BBC2AB27E0DA45A6E1E27F4E94405EE01C36E892EFBF
54E15840A6A6DCA85275E38E4218EE2B539E9E468E24C49428DA363C955C5FC81ACEE79EEB941B83EE4147A0817043BD 7D6A062453236E4C353F19B875D079157D016B223B7D429C8F5BEA9D0F703EED
7D0FBB417B99B3C6AB18C7B2DC82582D2DCD1E10515028874E73254188F7FEE9 20631589CB541B32C23CA7EA93B12E2016B5A90A2C9CAA6F5849C0B67158EA635858F26A86282C124AEA3FD31B7FD365
3F6E89BBCC133B85945234A8201539ECD8796909CC81FE67673F8DE1ECA63045 E6CF167CEA0639D1504E0BFC8BAAA7FC7FA36A2286CBBE1312803422018A9F00
39554C0DC1C3694FAAFF65537FF710D9593B7B461E011FC39D014F253F0432533A40276D8259AFD8C957A378237D574F 0EB81E23FF37366BA4890CBD46BC8AF5A2CD56E9802B8DF5CDDD5114F677CDF6
E60F6CD7063B85F0F20ACB7E7A42B03DE4A9F6CCA54CB7F036AFA23A27D3E9E006BD523E5356260AA78206D9276E6E57 62195292F6F920DAF91F812FC3B94E8539C157D35D3BC94F2FB7A8481406C655AC0F112C4E10AC36892D43D95827BC1D
9EB252EDA9352B966EC4F053D5B013772361D2AD4B217EF33F46A5CEC97A00F3 65FB9BEBDB9BE975168D47B02CA8A2E0ADE2CD1949E90B06689B0475395663BD5AF3C8FEC42C4138CBBB8956AC55B475
AA6773E79BC6D76314BB523FDF203358E01ECB2BBCF3B5DD1EBD043663C74B05 EF0A6961C754FCDBAE0222099DD8AA38DD6A92BCD53A576E105BC5BBD23400B7
29B29A50F3F27F4D8C7B0FADA98CC004A7871078DAD1CBAC4846862C3DF82E02 A608752C8602A5BD538441DE046DD7AE011FBA87210B57372BCBB471ECC2B720
6E3A479D4334FF05606899B0383116125056A316621B279F904A02B842918C59 222C83DDC445F72152E563CD068851389364C1D83C9F7D6353325EFD553560B1
3991732015F4A213E9912E34AC92515D88010C07DA0B118AD6F64A05DC38D2C5 96977544F2F821408C1A88FADB9B1E12D9CA97638A622190F83BC640508B6029
550B1866F7493C75812DF85DDADC38AF21D9B58189E4EE99A021328523881A9D B596A98BDDA5BD2FF1F812BE67FD00456D4D313E9497147E2439B51972B6B752
77960CA031D28362586100F17DF94FF4E7D6EFAFAF23952887F9DF0507825A99 FC276CAC90756F397C3BC616631CE8B9257E6C25D0DC15C5ED1CEB439ACF04D9
01E6FC89E97B7729BF4D1ED8041F69005181BF3639F939C5833B009E96B9F2F7 383DD624B98E650E5B4BA28990B4D1912B785C689E6B6A05D77B47B6501CD98F
D1CC7C536706ECFC5826C8933135D2B110996F1CB13388A702B8453DA40E40AD 410814DC8B38DD6EF781B55CA02730092F252082A77400AD90F22BF45A41C849
B64D2F1E1A80E6DAB92283A512B40DB7FFC519F394AA94CC86C8532F69949723 8DA240E13E8B512B50FF4504A61037D0A3920B00523D51EEF9996CC3907C175E
6399409A0AC0298DEDA76037C83042FC0870132CFF7F82E54AD0966BE16AC882 E655B7C31E346154C5EF7C59E3A710A2A2F145E7403E4ADB388B3A27D6FF59DE
D310536FA78F95BB0B408676990AA937117717BADE9D3B975C0ECE10FB586A1B E2FB7F96EA16B20589995E95D0959B4ECC1EDDF86E347EB85FD29D0D5933A2A1
A8149C0581DCC291D037E96EF321DB6214BD7CB25F1696226A9FE750AA23B334 00D910F2B050900735A8446220FF7321813252862A69C05A7A534118E50E61DB
BA3BEBD564D8F571202CD6FE89BC33F89C8E01C03AE0814F2BEF37C33CE874B4 BA1B9E7E26E04542183F085060421553CDD3FD9034AAAFCB7EE980A68B98087E
88CD81AC7605A7F6EFF85FD62C65E0C9945335CFC085B92B27B69648C6E5BF6B 216EBA33FCE4B834BF64621E557923D8AE41F5895266B7BBDFCA6EAF985F036E
8057C7CB5071DFFFAE4804FD9EC1EC1D3F54D06514906A34B17F6B6CB45A9D473992DF6BC8A9F9E146E39D6163209CC6 2E9075A45ED6D86C172C9ADAAF5E991DA8DA9CBF2F24D746D22A331E236FBA4A
9ABC8814C8FD1AB254374150177616F5C7B43049473C84329BEC855578B96002 04E4B185C150AF45A67E15D68282C7558B13BFFB05BFCB71BCFD2B92DE5D9701
8BCA39A498B00245C71D94E3160CEE8ACA5BEB18AE0AD64A385AFCC018E99744 1FDC4D759EA89681F76A8F7D336118FE6801EFD10D73925C2749775D9DFED282
5AD75C51CA5AE5FA9BBC6A41576C745F265CC28FC4DA2AD230B6692CF151FD61 FFB32167FBF860418AAABF29B0D4FEF57BB07454ECF4BD2CF175D44E84C04CED
E86092E04CD72D874A92DE838035E811E75E411049C0A7BD0FE2AA9C802BE5AB 7C6E419658872D298F2E7B02568B9ED870FDFFE5082ED0BBE689FD04EFFFE7E7
CE70ADB22E85747FDC064F0B5974385CD57D41D376CE1C7490C1BEC8A3FC5A7A ADAB0F3108398C75ECC6D2E572960B5685C336DDF3D6F5B9C12D069F27BA15A8
8F096E0A11682DB315825213D3DB5D725555C1CDF444169EB919E47E0F0FA6F7 DAC772C1A81181738CDB8C0E89C2E5B7A57E2DA65CA15232DE96A3C4A599A0E9
AD9C9A694D807BA77E5A54B248A88B55000757203D931506255BF8F4215C00D3 7F6204274D90E88B3F5D5AC86EEEE76C27C0D083E79ADA7BCF7D060FE6F05A3E
F0E804B6C6B6E91916CB73EB44FB2D1992400BC90ED8B22DF5D038317588341207D74E08C00E529DF2CF2A64F2C7C0FF 5BAB4CCB593418CD8965C09C0925EDB78BB4C8A10892F264DF12F50E532F006E
72212FCEED35E9C3A176B67DCDB84B284F4DFDCD0ECE8D3F6089C58C2B8A616C 7C67525C921ABAEC4BFAA376162A7B2B2827AE4C9840DC37F067FE3B72BE7304B6EEB5FB1AD17CFF5F079EFECC04AD56
000F9F746BFB47FC10B23E3F08C2A84BCB3870D0C5AE974472849699884BC929 94FF6DD4CE63381778E86E61423EDDDD9CC71C3462D66F1AD9A0AD5D378AECE2
7B8F9AB04E5F86D6DDCF6164A25EA927788A03F57977FC5C55E1D565279B09C4 E9CA5BA5C6D6101EA3A51F28E48D49789D60273A9F70D56020D003265517AFA3
0E9CDCD07D1D4F1429E59F81B524960A75F19A464798C7E822E52728AC83784A EBF55649D226E9FDAAB57C2E1D75E3FD3A8D216488E97D00E932B3542E731D20
F2DE2B108A1476BB6F85DD3CCB0F0527627B45179092BA7A56D5971490E3875C 2B576C3616DDAFEE23A8ECE24BBD89590C8C2D551F14D8EFA4DBB30216F89C31
7F307358D988FEA12648739F58DD249EBDF0B1C44B73BA547C50EB576C071DAE EE8D3CF3C503DE4FF368F23585F1A7017FF66A910696A6760AFD2B9822911960
2DFBA988592CEF3B62A76183DBA727E734359B89F53AFF3160441EF8709FC633 A32910F791C5EE9998DCE5371B3252427315C9D11AD506CE65760611D873C81D
57F7DC38DDC87C19CE956BC44C638DEF34D814A7BAB0AC8AD61855143FD984FD 740646D11A32C65A8549B3AEA8A499866C35D926B2BA21ED73934AA37ADCC1E6
A8AADB687251FA6AC2BBC8EF1E3FA621893293DFBD8C1D07971BF82F22A00DC3 0E66EF4CA934A5D1ACED28CBEEAA3AF7941E10918DA79379090B6339F11E267E
65AEA1EE34E316C769E551AC2309D07FC2ED92EA044674E3A99CD7B543C730EB D79D8666FD947B0D0D504FF10B048B147CB000AD8CDC1F0DEB395FB72B789963
968ECC790E5590E7EB22AFD3546C28F4EB87EA4CEE35F72DDFE7153F74611EAA 2F7BA07F18F4A91AEDC08867E9CC4B8689B0831A7CE0E0AEF3D92C0CA9BBC698
0F937930D4E1BDF0B729277CF94A47064BCB959938C70CDB3AC3C65DA68DA1FB 1AB4351CFF02CC600C972CE87F69B23F8ECCC32A90BD5F429F8017A80306F23D
A8AB66375D59E112104CD81B819D618BE43D6A6F159BAD35583653EF3547D25D ED2AD447E7DF7A34D78A313395FA1C3AF63CE02B77A5B08CE19493CFA1173232
A81D5DE2102F05D50750DC37C26E9C9502FA89EF98A2EB1EA546EE48C628E9C4 C8C8DEAF10AA3994EE7D6DC8E1EB403042627E0F3524409F40C03A7C0C106A80
EAFDE0A8936AF8EF718027937BC17CEF691E570996B403CF4762240D267EB305 5778B4A3E7BE82C07BA6A311A87649F3C7AE5107A89571E14AEF05B9E285C87A
C48686348F0A94B07BC60AB825C1A0791C20DBBDD7DAE0ED47E8A7FBD9334EACF8E33DCEC36963E87929260DF769520B 30080347DB3B580B18E8EAC66E1B7227F791773F0342EE0DF8267EC993EC3F24
493D53BD7BB2B3E081AE793A3BADB3AB0F33C95B83677715D6DE2922F2BEC892 2DB3B2A17C165B5C6A1D4944A5B595016588F028DD4F763C4ED6B7FE7849E918
63FFD3D8CAB980E45D49253A69C99A6813CBE6013992EFBC862173BAD0E26373 C1F0CF343B77F31D9A2E810821393EE9D1E0D4B54A87B2DD8CCFBB16FBD77A75B50A0E78D1E8A86310572443731B9DB5
2EF88F43C5A76EC87E02B780585B10957F4EA386F96710FAB98BC2C1E214DBFA 88EF373C37AADAE1155E7DBDBB7E0B048E3BFEFB412DC49EA8A48E1544B6DC87
A021CFA0E72AADFD75BC67FBE9345082B0A8B31782E933E81196F84B1797D83E8B2F81E1CF5C3F026D11B9DFC95222E2 98694781F3EE698ABA8D2CDFFB1CA0425AA17BFE904FC7812E65A78DF1CA06C2
6BBBCA6672311E1A3BF7001B3222890C8A68A8B7D87DE91624BB9D1FEC0E2728
4550A44B654085C3A3620B5D4D2C6A7F962275BC5926B9B7E3A706F128BF6D6C967E2BF2ACD4DD000BDC8BDE69684F6F

View File

@@ -174,8 +174,16 @@ bool subghz_scene_decode_raw_next(SubGhz* subghz) {
level_duration = level_duration =
subghz_file_encoder_worker_get_level_duration(subghz->decode_raw_file_worker_encoder); subghz_file_encoder_worker_get_level_duration(subghz->decode_raw_file_worker_encoder);
if(!level_duration_is_reset(level_duration)) { if(!level_duration_is_reset(level_duration)) {
if(level_duration_is_wait(level_duration)) {
FURI_LOG_W(TAG, "LD tells wait!");
return true;
}
bool level = level_duration_get_level(level_duration); bool level = level_duration_get_level(level_duration);
uint32_t duration = level_duration_get_duration(level_duration); uint32_t duration = level_duration_get_duration(level_duration);
if(duration > 1000000) {
FURI_LOG_E(TAG, "LD came with overflow: %ld", duration);
return true;
}
subghz_receiver_decode(receiver, level, duration); subghz_receiver_decode(receiver, level, duration);
} else { } else {
scene_manager_set_scene_state( scene_manager_set_scene_state(

View File

@@ -14,7 +14,7 @@ enum SubGhzSettingIndex {
SubGhzSettingIndexRemoveDuplicates, SubGhzSettingIndexRemoveDuplicates,
SubGhzSettingIndexDeleteOldSignals, SubGhzSettingIndexDeleteOldSignals,
SubGhzSettingIndexAutosave, SubGhzSettingIndexAutosave,
SubGhzSettingIndexIgnoreCars, SubGhzSettingIndexIgnoreReversRB2,
SubGhzSettingIndexIgnoreAlarms, SubGhzSettingIndexIgnoreAlarms,
SubGhzSettingIndexIgnoreSensors, SubGhzSettingIndexIgnoreSensors,
SubGhzSettingIndexIgnorePrinceton, SubGhzSettingIndexIgnorePrinceton,
@@ -411,8 +411,8 @@ static inline bool subghz_scene_receiver_config_ignore_filter_get_index(
return READ_BIT(filter, flag) > 0; return READ_BIT(filter, flag) > 0;
} }
static void subghz_scene_receiver_config_set_cars(VariableItem* item) { static void subghz_scene_receiver_config_set_reversrb2(VariableItem* item) {
subghz_scene_receiver_config_set_ignore_filter(item, SubGhzProtocolFilter_Cars); subghz_scene_receiver_config_set_ignore_filter(item, SubGhzProtocolFilter_ReversRB2);
} }
static void subghz_scene_receiver_config_set_alarms(VariableItem* item) { static void subghz_scene_receiver_config_set_alarms(VariableItem* item) {
@@ -607,13 +607,13 @@ void subghz_scene_receiver_config_on_enter(void* context) {
item = variable_item_list_add( item = variable_item_list_add(
subghz->variable_item_list, subghz->variable_item_list,
"Ignore Cars", "Ignore ReversRB2",
COMBO_BOX_COUNT, COMBO_BOX_COUNT,
subghz_scene_receiver_config_set_cars, subghz_scene_receiver_config_set_reversrb2,
subghz); subghz);
value_index = subghz_scene_receiver_config_ignore_filter_get_index( value_index = subghz_scene_receiver_config_ignore_filter_get_index(
subghz->ignore_filter, SubGhzProtocolFilter_Cars); subghz->ignore_filter, SubGhzProtocolFilter_ReversRB2);
variable_item_set_current_value_index(item, value_index); variable_item_set_current_value_index(item, value_index);
variable_item_set_current_value_text(item, combobox_text[value_index]); variable_item_set_current_value_text(item, combobox_text[value_index]);

View File

@@ -36,6 +36,14 @@ void subghz_scene_set_button_on_enter(void* context) {
byte_ptr = &subghz->gen_info->somfy_telis.btn; byte_ptr = &subghz->gen_info->somfy_telis.btn;
byte_count = sizeof(subghz->gen_info->somfy_telis.btn); byte_count = sizeof(subghz->gen_info->somfy_telis.btn);
break; break;
case GenKingGatesStylo4k:
byte_ptr = &subghz->gen_info->kinggates_stylo_4k.btn;
byte_count = sizeof(subghz->gen_info->kinggates_stylo_4k.btn);
break;
case GenBenincaARC:
byte_ptr = &subghz->gen_info->beninca_arc.btn;
byte_count = sizeof(subghz->gen_info->beninca_arc.btn);
break;
case GenNiceFlorS: case GenNiceFlorS:
byte_ptr = &subghz->gen_info->nice_flor_s.btn; byte_ptr = &subghz->gen_info->nice_flor_s.btn;
byte_count = sizeof(subghz->gen_info->nice_flor_s.btn); byte_count = sizeof(subghz->gen_info->nice_flor_s.btn);
@@ -82,6 +90,8 @@ bool subghz_scene_set_button_on_event(void* context, SceneManagerEvent event) {
case GenKeeloqBFT: case GenKeeloqBFT:
case GenAlutechAt4n: case GenAlutechAt4n:
case GenSomfyTelis: case GenSomfyTelis:
case GenKingGatesStylo4k:
case GenBenincaARC:
case GenNiceFlorS: case GenNiceFlorS:
case GenSecPlus2: case GenSecPlus2:
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetCounter); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetCounter);

View File

@@ -42,6 +42,14 @@ void subghz_scene_set_counter_on_enter(void* context) {
byte_ptr = (uint8_t*)&subghz->gen_info->somfy_telis.cnt; byte_ptr = (uint8_t*)&subghz->gen_info->somfy_telis.cnt;
byte_count = sizeof(subghz->gen_info->somfy_telis.cnt); byte_count = sizeof(subghz->gen_info->somfy_telis.cnt);
break; break;
case GenKingGatesStylo4k:
byte_ptr = (uint8_t*)&subghz->gen_info->kinggates_stylo_4k.cnt;
byte_count = sizeof(subghz->gen_info->kinggates_stylo_4k.cnt);
break;
case GenBenincaARC:
byte_ptr = (uint8_t*)&subghz->gen_info->beninca_arc.cnt;
byte_count = sizeof(subghz->gen_info->beninca_arc.cnt);
break;
case GenNiceFlorS: case GenNiceFlorS:
byte_ptr = (uint8_t*)&subghz->gen_info->nice_flor_s.cnt; byte_ptr = (uint8_t*)&subghz->gen_info->nice_flor_s.cnt;
byte_count = sizeof(subghz->gen_info->nice_flor_s.cnt); byte_count = sizeof(subghz->gen_info->nice_flor_s.cnt);
@@ -113,6 +121,13 @@ bool subghz_scene_set_counter_on_event(void* context, SceneManagerEvent event) {
case GenSomfyTelis: case GenSomfyTelis:
subghz->gen_info->somfy_telis.cnt = __bswap16(subghz->gen_info->somfy_telis.cnt); subghz->gen_info->somfy_telis.cnt = __bswap16(subghz->gen_info->somfy_telis.cnt);
break; break;
case GenKingGatesStylo4k:
subghz->gen_info->kinggates_stylo_4k.cnt =
__bswap16(subghz->gen_info->kinggates_stylo_4k.cnt);
break;
case GenBenincaARC:
subghz->gen_info->beninca_arc.cnt = __bswap32(subghz->gen_info->beninca_arc.cnt);
break;
case GenNiceFlorS: case GenNiceFlorS:
subghz->gen_info->nice_flor_s.cnt = __bswap16(subghz->gen_info->nice_flor_s.cnt); subghz->gen_info->nice_flor_s.cnt = __bswap16(subghz->gen_info->nice_flor_s.cnt);
break; break;
@@ -171,6 +186,24 @@ bool subghz_scene_set_counter_on_event(void* context, SceneManagerEvent event) {
subghz->gen_info->somfy_telis.btn, subghz->gen_info->somfy_telis.btn,
subghz->gen_info->somfy_telis.cnt); subghz->gen_info->somfy_telis.cnt);
break; break;
case GenKingGatesStylo4k:
generated_protocol = subghz_txrx_gen_kinggates_stylo_4k_protocol(
subghz->txrx,
subghz->gen_info->mod,
subghz->gen_info->freq,
subghz->gen_info->kinggates_stylo_4k.serial,
subghz->gen_info->kinggates_stylo_4k.btn,
subghz->gen_info->kinggates_stylo_4k.cnt);
break;
case GenBenincaARC:
generated_protocol = subghz_txrx_gen_beninca_arc_protocol(
subghz->txrx,
subghz->gen_info->mod,
subghz->gen_info->freq,
subghz->gen_info->beninca_arc.serial,
subghz->gen_info->beninca_arc.btn,
subghz->gen_info->beninca_arc.cnt);
break;
case GenNiceFlorS: case GenNiceFlorS:
generated_protocol = subghz_txrx_gen_nice_flor_s_protocol( generated_protocol = subghz_txrx_gen_nice_flor_s_protocol(
subghz->txrx, subghz->txrx,

View File

@@ -30,6 +30,8 @@ void subghz_scene_set_seed_on_enter(void* context) {
case GenKeeloq: case GenKeeloq:
case GenAlutechAt4n: case GenAlutechAt4n:
case GenSomfyTelis: case GenSomfyTelis:
case GenKingGatesStylo4k:
case GenBenincaARC:
case GenNiceFlorS: case GenNiceFlorS:
case GenSecPlus2: case GenSecPlus2:
case GenPhoenixV2: case GenPhoenixV2:
@@ -89,6 +91,8 @@ bool subghz_scene_set_seed_on_event(void* context, SceneManagerEvent event) {
case GenKeeloq: case GenKeeloq:
case GenAlutechAt4n: case GenAlutechAt4n:
case GenSomfyTelis: case GenSomfyTelis:
case GenKingGatesStylo4k:
case GenBenincaARC:
case GenNiceFlorS: case GenNiceFlorS:
case GenSecPlus2: case GenSecPlus2:
case GenPhoenixV2: case GenPhoenixV2:

View File

@@ -42,6 +42,14 @@ void subghz_scene_set_serial_on_enter(void* context) {
byte_ptr = (uint8_t*)&subghz->gen_info->somfy_telis.serial; byte_ptr = (uint8_t*)&subghz->gen_info->somfy_telis.serial;
byte_count = sizeof(subghz->gen_info->somfy_telis.serial); byte_count = sizeof(subghz->gen_info->somfy_telis.serial);
break; break;
case GenKingGatesStylo4k:
byte_ptr = (uint8_t*)&subghz->gen_info->kinggates_stylo_4k.serial;
byte_count = sizeof(subghz->gen_info->kinggates_stylo_4k.serial);
break;
case GenBenincaARC:
byte_ptr = (uint8_t*)&subghz->gen_info->beninca_arc.serial;
byte_count = sizeof(subghz->gen_info->beninca_arc.serial);
break;
case GenNiceFlorS: case GenNiceFlorS:
byte_ptr = (uint8_t*)&subghz->gen_info->nice_flor_s.serial; byte_ptr = (uint8_t*)&subghz->gen_info->nice_flor_s.serial;
byte_count = sizeof(subghz->gen_info->nice_flor_s.serial); byte_count = sizeof(subghz->gen_info->nice_flor_s.serial);
@@ -110,6 +118,14 @@ bool subghz_scene_set_serial_on_event(void* context, SceneManagerEvent event) {
subghz->gen_info->somfy_telis.serial = subghz->gen_info->somfy_telis.serial =
__bswap32(subghz->gen_info->somfy_telis.serial); __bswap32(subghz->gen_info->somfy_telis.serial);
break; break;
case GenKingGatesStylo4k:
subghz->gen_info->kinggates_stylo_4k.serial =
__bswap32(subghz->gen_info->kinggates_stylo_4k.serial);
break;
case GenBenincaARC:
subghz->gen_info->beninca_arc.serial =
__bswap32(subghz->gen_info->beninca_arc.serial);
break;
case GenNiceFlorS: case GenNiceFlorS:
subghz->gen_info->nice_flor_s.serial = subghz->gen_info->nice_flor_s.serial =
__bswap32(subghz->gen_info->nice_flor_s.serial); __bswap32(subghz->gen_info->nice_flor_s.serial);
@@ -136,6 +152,8 @@ bool subghz_scene_set_serial_on_event(void* context, SceneManagerEvent event) {
case GenKeeloqBFT: case GenKeeloqBFT:
case GenAlutechAt4n: case GenAlutechAt4n:
case GenSomfyTelis: case GenSomfyTelis:
case GenKingGatesStylo4k:
case GenBenincaARC:
case GenNiceFlorS: case GenNiceFlorS:
case GenSecPlus2: case GenSecPlus2:
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetButton); scene_manager_next_scene(subghz->scene_manager, SubGhzSceneSetButton);

View File

@@ -20,6 +20,8 @@ static const char* submenu_names[SetTypeMAX] = {
[SetTypeAlutechAT4N] = "Alutech AT4N 433MHz", [SetTypeAlutechAT4N] = "Alutech AT4N 433MHz",
[SetTypeRoger_433] = "Roger 433MHz", [SetTypeRoger_433] = "Roger 433MHz",
[SetTypePhoenix_V2_433] = "V2 Phoenix 433MHz", [SetTypePhoenix_V2_433] = "V2 Phoenix 433MHz",
[SetTypeKingGatesStylo4k] = "KingGates Stylo4k 433M.",
[SetTypeBenincaARC] = "Beninca ARC 433MHz",
[SetTypeHCS101_433_92] = "KL: HCS101 433MHz", [SetTypeHCS101_433_92] = "KL: HCS101 433MHz",
[SetTypeDoorHan_315_00] = "KL: DoorHan 315MHz", [SetTypeDoorHan_315_00] = "KL: DoorHan 315MHz",
[SetTypeDoorHan_433_92] = "KL: DoorHan 433MHz", [SetTypeDoorHan_433_92] = "KL: DoorHan 433MHz",
@@ -35,8 +37,8 @@ static const char* submenu_names[SetTypeMAX] = {
[SetTypeJollyMotors433] = "KL: Jolly Mot. 433MHz", [SetTypeJollyMotors433] = "KL: Jolly Mot. 433MHz",
[SetTypeSommer_FM_434] = "KL: Sommer 434MHz", [SetTypeSommer_FM_434] = "KL: Sommer 434MHz",
[SetTypeSommer_FM_868] = "KL: Sommer 868MHz", [SetTypeSommer_FM_868] = "KL: Sommer 868MHz",
[SetTypeSommer_FM238_434] = "KL: Sommer fm2 434Mhz", [SetTypeSommer_FM12K_434] = "KL: Sommer fm2 434Mhz",
[SetTypeSommer_FM238_868] = "KL: Sommer fm2 868Mhz", [SetTypeSommer_FM12K_868] = "KL: Sommer fm2 868Mhz",
[SetTypeStilmatic] = "KL: Stilmatic 433MHz", [SetTypeStilmatic] = "KL: Stilmatic 433MHz",
[SetTypeIronLogic] = "KL: IronLogic 433MHz", [SetTypeIronLogic] = "KL: IronLogic 433MHz",
[SetTypeIronLogicSmart] = "KL: IronLogic SM 433MHz", [SetTypeIronLogicSmart] = "KL: IronLogic SM 433MHz",
@@ -50,6 +52,7 @@ static const char* submenu_names[SetTypeMAX] = {
[SetTypeJCM_433_92] = "KL: JCM Tech 433MHz", [SetTypeJCM_433_92] = "KL: JCM Tech 433MHz",
[SetTypeNovoferm_433_92] = "KL: Novoferm 433MHz", [SetTypeNovoferm_433_92] = "KL: Novoferm 433MHz",
[SetTypeHormannEcoStar_433_92] = "KL: Hor. EcoStar 433MHz", [SetTypeHormannEcoStar_433_92] = "KL: Hor. EcoStar 433MHz",
[SetTypeCardinS449_433FM] = "KL: Cardin S449 433MHz",
[SetTypeFAACRCXT_433_92] = "KL: FAAC RC,XT 433MHz", [SetTypeFAACRCXT_433_92] = "KL: FAAC RC,XT 433MHz",
[SetTypeFAACRCXT_868] = "KL: FAAC RC,XT 868MHz", [SetTypeFAACRCXT_868] = "KL: FAAC RC,XT 868MHz",
[SetTypeGeniusBravo433] = "KL: Genius Bravo 433MHz", [SetTypeGeniusBravo433] = "KL: Genius Bravo 433MHz",
@@ -186,6 +189,24 @@ bool subghz_scene_set_type_generate_protocol_from_infos(SubGhz* subghz) {
gen_info.somfy_telis.btn, gen_info.somfy_telis.btn,
gen_info.somfy_telis.cnt); gen_info.somfy_telis.cnt);
break; break;
case GenKingGatesStylo4k:
generated_protocol = subghz_txrx_gen_kinggates_stylo_4k_protocol(
subghz->txrx,
gen_info.mod,
gen_info.freq,
gen_info.kinggates_stylo_4k.serial,
gen_info.kinggates_stylo_4k.btn,
gen_info.kinggates_stylo_4k.cnt);
break;
case GenBenincaARC:
generated_protocol = subghz_txrx_gen_beninca_arc_protocol(
subghz->txrx,
gen_info.mod,
gen_info.freq,
gen_info.beninca_arc.serial,
gen_info.beninca_arc.btn,
gen_info.beninca_arc.cnt);
break;
case GenNiceFlorS: case GenNiceFlorS:
generated_protocol = subghz_txrx_gen_nice_flor_s_protocol( generated_protocol = subghz_txrx_gen_nice_flor_s_protocol(
subghz->txrx, subghz->txrx,
@@ -265,6 +286,8 @@ bool subghz_scene_set_type_on_event(void* context, SceneManagerEvent event) {
case GenKeeloqBFT: // Serial (u32), Button (u8), Counter (u16), Seed (u32) case GenKeeloqBFT: // Serial (u32), Button (u8), Counter (u16), Seed (u32)
case GenAlutechAt4n: // Serial (u32), Button (u8), Counter (u16) case GenAlutechAt4n: // Serial (u32), Button (u8), Counter (u16)
case GenSomfyTelis: // Serial (u32), Button (u8), Counter (u16) case GenSomfyTelis: // Serial (u32), Button (u8), Counter (u16)
case GenKingGatesStylo4k: // Serial (u32), Button (u8), Counter (u16)
case GenBenincaARC: // Serial (u32), Button (u8), Counter (u32)
case GenNiceFlorS: // Serial (u32), Button (u8), Counter (u16) case GenNiceFlorS: // Serial (u32), Button (u8), Counter (u16)
case GenSecPlus2: // Serial (u32), Button (u8), Counter (u32) case GenSecPlus2: // Serial (u32), Button (u8), Counter (u32)
case GenPhoenixV2: // Serial (u32), Counter (u16) case GenPhoenixV2: // Serial (u32), Counter (u16)

View File

@@ -4,16 +4,15 @@
#include <lib/toolbox/value_index.h> #include <lib/toolbox/value_index.h>
#include <machine/endian.h> #include <machine/endian.h>
#include <toolbox/strint.h> #include <toolbox/strint.h>
#include <lib/subghz/blocks/generic.h>
#define TAG "SubGhzSceneSignalSettings" #define TAG "SubGhzSceneSignalSettings"
static uint32_t counter_mode = 0xff; static uint32_t counter_mode = 0xff;
static uint32_t loaded_counter32 = 0x0;
static uint32_t counter32 = 0x0; static uint32_t counter32 = 0x0;
static uint16_t counter16 = 0x0; static uint16_t counter16 = 0x0;
static uint8_t byte_count = 0; static uint8_t byte_count = 0;
static uint8_t* byte_ptr = NULL; static uint8_t* byte_ptr = NULL;
static uint8_t hex_char_lenght = 0;
static FuriString* byte_input_text; static FuriString* byte_input_text;
#define COUNTER_MODE_COUNT 7 #define COUNTER_MODE_COUNT 7
@@ -52,55 +51,6 @@ static Protocols protocols[] = {
#define PROTOCOLS_COUNT (sizeof(protocols) / sizeof(Protocols)); #define PROTOCOLS_COUNT (sizeof(protocols) / sizeof(Protocols));
// our special case function based on strint_to_uint32 from strint.c
StrintParseError strint_to_uint32_base16(const char* str, uint32_t* out, uint8_t* lenght) {
// skip whitespace
while(((*str >= '\t') && (*str <= '\r')) || *str == ' ') {
str++;
}
// read digits
uint32_t limit = UINT32_MAX;
uint32_t mul_limit = limit / 16;
uint32_t result = 0;
int read_total = 0;
while(*str != 0) {
int digit_value;
if(*str >= '0' && *str <= '9') {
digit_value = *str - '0';
} else if(*str >= 'A' && *str <= 'Z') {
digit_value = *str - 'A' + 10;
} else if(*str >= 'a' && *str <= 'z') {
digit_value = *str - 'a' + 10;
} else {
break;
}
if(digit_value >= 16) {
break;
}
if(result > mul_limit) return StrintParseOverflowError;
result *= 16;
if(result > limit - digit_value) return StrintParseOverflowError; //-V658
result += digit_value;
read_total++;
str++;
}
if(read_total == 0) {
result = 0;
*lenght = 0;
return StrintParseAbsentError;
}
if(out) *out = result;
if(lenght) *lenght = read_total;
return StrintParseNoError;
}
void subghz_scene_signal_settings_counter_mode_changed(VariableItem* item) { void subghz_scene_signal_settings_counter_mode_changed(VariableItem* item) {
uint8_t index = variable_item_get_current_value_index(item); uint8_t index = variable_item_get_current_value_index(item);
variable_item_set_current_value_text(item, counter_mode_text[index]); variable_item_set_current_value_text(item, counter_mode_text[index]);
@@ -117,8 +67,8 @@ void subghz_scene_signal_settings_variable_item_list_enter_callback(void* contex
// when we click OK on "Edit counter" item // when we click OK on "Edit counter" item
if(index == 1) { if(index == 1) {
furi_string_cat_printf(byte_input_text, "%i", hex_char_lenght * 4); furi_string_cat_printf(byte_input_text, "%i", subghz_block_generic_global.cnt_length_bit);
furi_string_cat_str(byte_input_text, "-bit counter in HEX"); furi_string_cat_str(byte_input_text, "-bits counter in HEX");
// Setup byte_input view // Setup byte_input view
ByteInput* byte_input = subghz->byte_input; ByteInput* byte_input = subghz->byte_input;
@@ -174,21 +124,18 @@ void subghz_scene_signal_settings_on_enter(void* context) {
} }
} }
} }
FURI_LOG_D(TAG, "Current CounterMode value %li", counter_mode); FURI_LOG_D(TAG, "Loaded CounterMode value %li", counter_mode);
flipper_format_file_close(fff_data_file); flipper_format_file_close(fff_data_file);
flipper_format_free(fff_data_file); flipper_format_free(fff_data_file);
furi_record_close(RECORD_STORAGE); furi_record_close(RECORD_STORAGE);
// ### Counter edit section ### // ### Counter edit section ###
FuriString* textCnt = furi_string_alloc_set_str("");
byte_input_text = furi_string_alloc_set_str("Enter "); byte_input_text = furi_string_alloc_set_str("Enter ");
furi_string_reset(tmp_text);
bool counter_not_available = true; bool counter_not_available = true;
SubGhzProtocolDecoderBase* decoder = subghz_txrx_get_decoder(subghz->txrx); SubGhzProtocolDecoderBase* decoder = subghz_txrx_get_decoder(subghz->txrx);
// deserialaze and decode loaded sugbhz file and take information string from decoder // deserialaze and decode loaded sugbhz file and push data to subghz_block_generic_global variable
if(subghz_protocol_decoder_base_deserialize(decoder, subghz_txrx_get_fff_data(subghz->txrx)) == if(subghz_protocol_decoder_base_deserialize(decoder, subghz_txrx_get_fff_data(subghz->txrx)) ==
SubGhzProtocolStatusOk) { SubGhzProtocolStatusOk) {
subghz_protocol_decoder_base_get_string(decoder, tmp_text); subghz_protocol_decoder_base_get_string(decoder, tmp_text);
@@ -196,86 +143,37 @@ void subghz_scene_signal_settings_on_enter(void* context) {
FURI_LOG_E(TAG, "Cant deserialize this subghz file"); FURI_LOG_E(TAG, "Cant deserialize this subghz file");
} }
// In protocols output we allways have HEX format for "Cnt:" output (text formating like ...Cnt:%05lX\r\n") if(!subghz_block_generic_global.cnt_is_available) {
// we take 8 simbols starting from "Cnt:........"
// at first we search "Cnt:????" that mean for this protocol counter cannot be decoded
int8_t place = furi_string_search_str(tmp_text, "Cnt:??", 0);
if(place > 0) {
counter_mode = 0xff; counter_mode = 0xff;
FURI_LOG_D( FURI_LOG_D(TAG, "Counter mode and edit not available for this protocol");
TAG, "Founded Cnt:???? - Counter mode and edit not available for this protocol");
} else { } else {
place = furi_string_search_str(tmp_text, "Cnt:", 0); counter_not_available = false;
if(place > 0) {
// defence from memory leaks. Check can we take 8 symbols after 'Cnt:' ?
// if from current place to end of stirngs more than 8 symbols - ok, if not - just take symbols from current place to end of string.
// +4 - its 'Cnt:' lenght
uint8_t n_symbols_taken = 8;
if(sizeof(tmp_text) - (place + 4) < 8) {
n_symbols_taken = sizeof(tmp_text) - (place + 4);
}
furi_string_set_n(textCnt, tmp_text, place + 4, n_symbols_taken);
furi_string_trim(textCnt);
FURI_LOG_D(
TAG,
"Taked 8 bytes hex value starting after 'Cnt:' - %s",
furi_string_get_cstr(textCnt));
// trim and convert 8 simbols string to uint32 by base 16 (hex);
// later we use loaded_counter in subghz_scene_signal_settings_on_event to check is there 0 or not - special case
if(strint_to_uint32_base16(
furi_string_get_cstr(textCnt), &loaded_counter32, &hex_char_lenght) ==
StrintParseNoError) {
counter_not_available = false;
// calculate and roundup number of hex bytes do display counter in byte_input (every 2 hex simbols = 1 byte for view)
// later must be used in byte_input to restrict number of available byte to edit
// cnt_byte_count = (hex_char_lenght + 1) / 2;
FURI_LOG_D(
TAG,
"Result of conversion from String to uint_32 DEC %li, HEX %lX, HEX lenght %i symbols",
loaded_counter32,
loaded_counter32,
hex_char_lenght);
// Check is there byte_count more than 2 hex bytes long (16 bit) or not (32bit)
// To show hex value we must correct revert bytes for ByteInput view
if(hex_char_lenght > 4) {
counter32 = loaded_counter32;
furi_string_printf(tmp_text, "%lX", counter32);
counter32 = __bswap32(counter32);
byte_ptr = (uint8_t*)&counter32;
byte_count = 4;
} else {
counter16 = loaded_counter32;
furi_string_printf(tmp_text, "%X", counter16);
counter16 = __bswap16(counter16);
byte_ptr = (uint8_t*)&counter16;
byte_count = 2;
}
} else {
FURI_LOG_E(TAG, "Cant convert text counter value");
};
// Check is there byte_count more than 2 hex bytes long or not
// To show hex value we must correct revert bytes for ByteInput view with __bswapХХ
if(subghz_block_generic_global.cnt_length_bit > 16) {
counter32 = subghz_block_generic_global.current_cnt;
furi_string_printf(tmp_text, "%lX", counter32);
counter32 = __bswap32(counter32);
byte_ptr = (uint8_t*)&counter32;
byte_count = 4;
} else { } else {
FURI_LOG_D(TAG, "Counter editor not available for this protocol"); counter16 = subghz_block_generic_global.current_cnt;
furi_string_printf(tmp_text, "%X", counter16);
counter16 = __bswap16(counter16);
byte_ptr = (uint8_t*)&counter16;
byte_count = 2;
} }
} }
furi_assert(byte_ptr); furi_assert(byte_ptr);
furi_assert(byte_count > 0); furi_assert(byte_count > 0);
//Create and Enable/Disable variable_item_list depent from current values //Create and Enable/Disable variable_item_list depending on current values
VariableItemList* variable_item_list = subghz->variable_item_list; VariableItemList* variable_item_list = subghz->variable_item_list;
int32_t value_index; int32_t value_index;
VariableItem* item; VariableItem* item;
// variable_item_list_set_selected_item(subghz->variable_item_list, 0);
// variable_item_list_reset(subghz->variable_item_list);
variable_item_list_set_enter_callback( variable_item_list_set_enter_callback(
variable_item_list, variable_item_list,
subghz_scene_signal_settings_variable_item_list_enter_callback, subghz_scene_signal_settings_variable_item_list_enter_callback,
@@ -299,71 +197,29 @@ void subghz_scene_signal_settings_on_enter(void* context) {
variable_item_set_locked(item, (counter_not_available), "Not available\nfor this\nprotocol !"); variable_item_set_locked(item, (counter_not_available), "Not available\nfor this\nprotocol !");
furi_string_free(tmp_text); furi_string_free(tmp_text);
furi_string_free(textCnt);
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdVariableItemList); view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdVariableItemList);
} }
bool subghz_scene_signal_settings_on_event(void* context, SceneManagerEvent event) { bool subghz_scene_signal_settings_on_event(void* context, SceneManagerEvent event) {
SubGhz* subghz = context; SubGhz* subghz = context;
int32_t tmp_counter = 0;
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubGhzCustomEventByteInputDone) { if(event.event == SubGhzCustomEventByteInputDone) {
switch(byte_count) { switch(byte_count) {
case 2: case 2:
// when signal has Cnt:00 we can step only to 0000+FFFF = FFFF, but we need 0000 for next step // set new cnt value and override_flag to global variable and call transmit to generate and save subghz signal
// for this case we must use +1 additional step to increace Cnt from FFFF to 0000.
// save current user definded counter increase value (mult)
tmp_counter = furi_hal_subghz_get_rolling_counter_mult();
// increase signal counter to max value - at result it must be 0000 in most cases
// but can be FFFF in case Cnt:0000 (for this we have +1 additional step below)
furi_hal_subghz_set_rolling_counter_mult(0xFFFF);
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
subghz_txrx_stop(subghz->txrx);
// if file Cnt:00 then do +1 additional step
if(loaded_counter32 == 0) {
furi_hal_subghz_set_rolling_counter_mult(1);
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
subghz_txrx_stop(subghz->txrx);
}
// at this point we must have signal Cnt:00
// convert back after byte_input and do one send with our new mult (counter16) - at end we must have signal Cnt = counter16
counter16 = __bswap16(counter16); counter16 = __bswap16(counter16);
subghz_block_generic_global_counter_override_set(counter16);
furi_hal_subghz_set_rolling_counter_mult(counter16);
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx)); subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
subghz_txrx_stop(subghz->txrx); subghz_txrx_stop(subghz->txrx);
// restore user definded counter increase value (mult)
furi_hal_subghz_set_rolling_counter_mult(tmp_counter);
break; break;
case 4: case 4:
// the same for 32 bit Counter // the same for 32 bit Counter
tmp_counter = furi_hal_subghz_get_rolling_counter_mult();
furi_hal_subghz_set_rolling_counter_mult(0xFFFFFFF);
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
subghz_txrx_stop(subghz->txrx);
if(loaded_counter32 == 0) {
furi_hal_subghz_set_rolling_counter_mult(1);
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
subghz_txrx_stop(subghz->txrx);
}
counter32 = __bswap32(counter32); counter32 = __bswap32(counter32);
subghz_block_generic_global_counter_override_set(counter32);
furi_hal_subghz_set_rolling_counter_mult((counter32 & 0xFFFFFFF));
subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx)); subghz_tx_start(subghz, subghz_txrx_get_fff_data(subghz->txrx));
subghz_txrx_stop(subghz->txrx); subghz_txrx_stop(subghz->txrx);
furi_hal_subghz_set_rolling_counter_mult(tmp_counter);
break; break;
default: default:
break; break;
@@ -411,7 +267,7 @@ void subghz_scene_signal_settings_on_exit(void* context) {
flipper_format_free(fff_data_file); flipper_format_free(fff_data_file);
furi_record_close(RECORD_STORAGE); furi_record_close(RECORD_STORAGE);
// we need reload file after editing when we exit from Signal Settings menu. // we need to reload file after editing when we exit from Signal Settings menu.
if(subghz_key_load(subghz, file_path, false)) { if(subghz_key_load(subghz, file_path, false)) {
FURI_LOG_D(TAG, "Subghz file was successfully reloaded"); FURI_LOG_D(TAG, "Subghz file was successfully reloaded");
} else { } else {

View File

@@ -567,6 +567,8 @@ static FuriHalSubGhzPreset subghz_cli_get_preset_name(const char* preset_name) {
preset = FuriHalSubGhzPresetOok650Async; preset = FuriHalSubGhzPresetOok650Async;
} else if(!strcmp(preset_name, "FuriHalSubGhzPreset2FSKDev238Async")) { } else if(!strcmp(preset_name, "FuriHalSubGhzPreset2FSKDev238Async")) {
preset = FuriHalSubGhzPreset2FSKDev238Async; preset = FuriHalSubGhzPreset2FSKDev238Async;
} else if(!strcmp(preset_name, "FuriHalSubGhzPreset2FSKDev12KAsync")) {
preset = FuriHalSubGhzPreset2FSKDev12KAsync;
} else if(!strcmp(preset_name, "FuriHalSubGhzPreset2FSKDev476Async")) { } else if(!strcmp(preset_name, "FuriHalSubGhzPreset2FSKDev476Async")) {
preset = FuriHalSubGhzPreset2FSKDev476Async; preset = FuriHalSubGhzPreset2FSKDev476Async;
} else if(!strcmp(preset_name, "FuriHalSubGhzPresetCustom")) { } else if(!strcmp(preset_name, "FuriHalSubGhzPresetCustom")) {

View File

@@ -8,7 +8,7 @@
#define SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER (-93.0f) #define SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_TRIGGER (-93.0f)
// 1 = "AM650" // 1 = "AM650"
// "AM270", "AM650", "FM238", "FM476", // "AM270", "AM650", "FM238", "FM12K", "FM476",
#define SUBGHZ_LAST_SETTING_DEFAULT_PRESET 1 #define SUBGHZ_LAST_SETTING_DEFAULT_PRESET 1
#define SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY 433920000 #define SUBGHZ_LAST_SETTING_DEFAULT_FREQUENCY 433920000
#define SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL 2 #define SUBGHZ_LAST_SETTING_FREQUENCY_ANALYZER_FEEDBACK_LEVEL 2

View File

@@ -30,6 +30,8 @@ static FuriHalSubGhzPreset js_subghz_get_preset_name(const char* preset_name) {
preset = FuriHalSubGhzPresetOok650Async; preset = FuriHalSubGhzPresetOok650Async;
} else if(!strcmp(preset_name, "FuriHalSubGhzPreset2FSKDev238Async")) { } else if(!strcmp(preset_name, "FuriHalSubGhzPreset2FSKDev238Async")) {
preset = FuriHalSubGhzPreset2FSKDev238Async; preset = FuriHalSubGhzPreset2FSKDev238Async;
} else if(!strcmp(preset_name, "FuriHalSubGhzPreset2FSKDev12KAsync")) {
preset = FuriHalSubGhzPreset2FSKDev12KAsync;
} else if(!strcmp(preset_name, "FuriHalSubGhzPreset2FSKDev476Async")) { } else if(!strcmp(preset_name, "FuriHalSubGhzPreset2FSKDev476Async")) {
preset = FuriHalSubGhzPreset2FSKDev476Async; preset = FuriHalSubGhzPreset2FSKDev476Async;
} else if(!strcmp(preset_name, "FuriHalSubGhzPresetCustom")) { } else if(!strcmp(preset_name, "FuriHalSubGhzPresetCustom")) {

View File

@@ -114,6 +114,8 @@ Your frequencies will be added after default ones
### Default hopper list ### Default hopper list
``` ```
315000000, 315000000,
390000000,
430500000,
433920000, 433920000,
434420000, 434420000,
868350000, 868350000,

View File

@@ -0,0 +1,183 @@
# Sub-GHz Supported Protocols
This file lists all supported Sub-GHz protocols available in Momentum Firmware, both tested and untested.
Many protocols support, and this documentation page, comes from [Unleashed Firmware](https://github.com/DarkFlippers/unleashed-firmware).
Currently Momentum has the same Sub-GHz protocol list as Unleashed, and most Sub-GHz innovation is driven by the Unleashed team.
Go show them some love and maybe donate to them too!
That list is only for default SubGHz app, apps like *Weather Station* have their own protocols list
## Static & Dynamic protocols list
*433 MHz usually means `433.92MHz` and 868 MHz = `868.35MHz`*
*If you see no frequency after protocol name, that means we don't know it, let us know in issues tab!*
*`AM650`, `FM`, `FSK476` - means modulation to use when reading the remote*
*`FM` means you should try any existing FM modulations, `FSK???` means `FM???` in SubGHz - Read - Config*
### Garage Door Openers & Gate Openers (Boom barriers, roller shutters, etc.)
- Alutech AT-4N `433.92MHz` `AM650` (72 bits, Dynamic)
- AN-Motors (Alutech) AT4 `433.92MHz` `AM650` (64 bits, Pseudo-Dynamic, KeeLoq based)
- Ansonic `433MHz` `FM` (12 bits, Static)
- BETT `433.92MHz` `AM650` (18 bits, Static)
- Beninca ARC (TOGO2VA) `433.92MHz` `AM650` (128 bits, Dynamic AES)
- BFT Mitto `433.92MHz` `AM650` (64 bits, Dynamic, KeeLoq based with Seed)
- CAME Atomo `433.92MHz, 868MHz` `AM650` (62 bits, Dynamic)
- CAME TWEE `433.92MHz` `AM650` (54 bits, Static)
- CAME `433.92MHz, 868MHz` `AM650` (12, 24 bits, Static)
- Prastel `433.92MHz, 868MHz` `AM650` (25, 42 bits, Static)
- Airforce `433.92MHz, 868MHz` `AM650` (18 bits, Static)
- Chamberlain Code `AM650` (10 bits, Static)
- Clemsa `AM650` (18 bits, Static)
- Dickert MAHS `AM650` (36 bits, Static)
- Doitrand `AM650` (37 bits, Dynamic)
- Elplast/P-11B/3BK/E.C.A `433MHz` `AM650` (18 bits, Static)
- FAAC SLH `433.92MHz, 868MHz` `AM650` (64 bits, Dynamic)
- Gate TX `433.92MHz` `AM650` (64 bits, Static)
- Hormann `868MHz` `AM650` (44 bits, Static)
- HCS101 `AM650` (64 bits, Simple Dynamic, KeeLoq-like)
- IDO `433MHz` `AM650` (48 bits, Dynamic)
- KingGates Stylo 4k `433.92MHz` `AM650` (89 bits, Dynamic, KeeLoq based)
- Mastercode `AM650` (36 bits, Static)
- Megacode `AM650` (24 bits, Static)
- Nero Sketch `AM650` (40 bits, Static)
- Nice Flo `433.92MHz` `AM650` (12, 24 bits, Static)
- Nice FloR-S `433.92MHz` `AM650` (52 bits, Dynamic)
- Nice One `433.92MHz` `AM650` (72 bits, Dynamic)
- Revers RB2 (Реверс РБ-2 (М)) `433.92MHz` `AM650` (64 bits, Static)
- Roger `433.92MHz` `AM650` (28 bits, Static)
- V2 Phoenix (Phox) `433.92MHz` `AM650` (52 bits, Dynamic)
- Marantec `433.92MHz, 868MHz` `AM650` (49 bits, Static)
- Marantec24 `868MHz` `AM650` (24 bits, Static)
- Somfy Keytis `433.92MHz, 868MHz` `AM650` (80 bits, Dynamic)
- ZKTeco `430.5MHz` `AM650` (24 bits, Static - Princeton based) - (Button codes (already mapped to arrow keys): `0x30 (UP)`, `0x03 (STOP)`, `0x0C (DOWN)`)
- Linear `300MHz` `AM650` (10 bits, Static)
- Linear Delta3 `AM650` (8 bits, Static)
- Nero Radio `434.42MHz` `AM650` (56 bits, Static mode only, Dynamic is unsupported)
- Security+1.0 `315MHz, 433.92MHz, 390MHz` `AM650` (42 bits, Dynamic)
- Security+2.0 `310MHz, 390MHz, 868MHz` `AM650` (62 bits, Dynamic)
### Sensors & Smart home
- Intertechno V3 `AM650` (32 bits, Static) - Lights, sockets, other.
- Dooya `AM650` (40 bits, Static) - Electric blinds
- Power Smart `AM650` (64 bits, Static) - Blinds, shutters
- Legrand `AM650` (18 bits, Static) - Doorbells
- Somfy Telis `433.92MHz` `AM650` (56 bits, Dynamic)
- Feron `433.92MHz` `AM650` (32 bits, Static) - RGB LED remotes, other.
- Honeywell `AM650` (64 bits, Dynamic) - Alarm, Sensor
- Honeywell WDB `AM650` (48 bits, Dynamic) - Doorbell
- Magellan `433.92MHz` `AM650` (32 bits, Static) - Sensor, alarm
### Alarms
- Hollarm `433.92MHz` `AM650` (42 bits, Static) - Bike alarms
- GangQi `433.92MHz` `AM650` (34 bits, Static) - Bike alarms
### Generic any branded remotes
- Holtek `AM650` (40 bits, Static)
- Holtek HT12X `AM650` (12 bits, Static)
- Princeton (PT2262, PT****) `315MHz, 433.92MHz, Any other frequency` `AM650` (24 bits, Static)
- SMC5326 `315MHz, 433.92MHz, Any other frequency` `AM650` (25 bits, Static)
- Hay21 `433.92MHz` `AM650` (21 bits, Dynamic)
- Treadmill37 (QH-433) `433.92MHz` `AM650` (37 bits, Static)
---
## KeeLoq Rolling Code Supported Manufacturers list
KeeLoq is a rolling code encryption system used by many garage door openers and gate systems.
The following manufacturers have KeeLoq support in Unleashed firmware:
*Default value for encryption type "learning" is `simple` and `10bits` for serial part in Hop*
*In case if remote uses other serial bits or different encryption type and it was verified - it will be stated in the end*
### Garage Door Openers & Gate Openers (Boom barriers, roller shutters, etc.)
- Allmatic - `868MHz` `AM650` (KeeLoq, 64 bits) (no serial part in Hop - magic XOR)
- Aprimatic - `433.92MHz` `AM650` (KeeLoq, 64 bits) (12bit serial number art in Hop + 2bit "parity" in front of it replacing first 2 bits of serial)
- Beninca - `433.92MHz, 868MHz` `AM650` (KeeLoq, 64 bits) (no serial part in Hop - magic XOR)
- CAME Space - `433.92MHz` `AM650` (KeeLoq, 64 bits) (12bit serial part in Hop - simple learning)
- Cardin S449 - `433.92MHz` `FSK12K` (KeeLoq, 64 bits) (12bit (original remotes) or 10bit (chinese remotes) serial part in Hop - normal learning)
- Centurion - `433.92MHz` `AM650` (KeeLoq, 64 bits) (no serial in Hop, uses fixed value 0x1CE - normal learning)
- Comunello - `433.92MHz, 868MHz` `AM650` (KeeLoq, 64 bits) (normal learning)
- DEA Mio - `433.92MHz` `AM650` (KeeLoq, 64 bits) (modified serial in Hop, uses last 3 digits modifying first one (example - 419 -> C19) - simple learning)
- DoorHan - 315MHz, `433.92MHz` `AM650` (KeeLoq, 64 bits)
- DTM Neo - `433.92MHz` `AM650` (KeeLoq, 64 bits) (12bit serial part in Hop - simple learning)
- Elmes Poland - `433.92MHz` `AM650` (KeeLoq, 64 bits) (normal learning)
- FAAC RC,XT - `433.92MHz, 868MHz` `AM650` (KeeLoq, 64 bits) (12bit serial part in Hop - normal learning)
- Genius Bravo - `433.92MHz` `AM650` (KeeLoq, 64 bits) (12bit serial part in Hop - normal learning)
- Gibidi - `433.92MHz` `AM650` (KeeLoq, 64 bits)
- GSN - `433.92MHz` `AM650` (KeeLoq, 64 bits) (12bit serial part in Hop - normal learning)
- Hormann EcoStar - `433.92MHz` `AM650` (KeeLoq, 64 bits) (normal learning)
- IronLogic IL-100 - `433.92MHz` `AM650` (KeeLoq, 64 bits)
- IronLogic IL-100 Smart PPult - `433.92MHz` `AM650` (KeeLoq, 64 bits)
- JCM Tech - `433.92MHz` `AM650` (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning)
- Jolly Motors - `433.92MHz` `AM650` (KeeLoq, 64 bits)
- KEY (KeeLoq, 64 bits)
- Monarch - `433.92MHz` `AM650` (KeeLoq, 64 bits) (no serial in Hop, uses fixed value 0x100 - normal learning)
- Motorline - `433.92MHz` `AM650` (KeeLoq, 64 bits) (normal learning)
- Mutanco/Mutancode (KeeLoq, 64 bits) (12bit serial part in Hop - normal learning)
- Mhouse - `433.92MHz` `AM650` (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning)
- Nice Smilo - `433.92MHz` `AM650` (KeeLoq, 64 bits) (8bit serial part in Hop - simple learning)
- Normstahl - `433.92MHz` `AM650` (KeeLoq, 64 bits)
- Novoferm - `433.92MHz` `AM650` (KeeLoq, 64 bits)
- Sommer `434.42MHz, 868.80MHz` `FSK12K (or FSK476)` (KeeLoq, 64 bits) (normal learning) (TX03-868-4, Pearl, and maybe other models are supported (SOMloq2))
- Steelmate - `433.92MHz` `AM650` (KeeLoq, 64 bits) (12bit serial part in Hop - normal learning)
- Stilmatic - `433.92MHz` `AM650` (KeeLoq, 64 bits) (normal learning)
### Alarms, unknown origin, etc.
- APS-1100/APS-2550 (KeeLoq, 64 bits)
- Alligator (KeeLoq, 64 bits)
- Alligator S-275 (KeeLoq, 64 bits)
- Cenmax (KeeLoq, 64 bits)
- Cenmax St-5 (KeeLoq, 64 bits)
- Cenmax St-7 (KeeLoq, 64 bits)
- Faraon (KeeLoq, 64 bits)
- Guard RF-311A (KeeLoq, 64 bits) (normal learning)
- Harpoon (KeeLoq, 64 bits)
- KGB/Subaru (KeeLoq, 64 bits) (magic serial type 1)
- Leopard (KeeLoq, 64 bits)
- Magic 1 (KeeLoq, 64 bits) (magic serial type 2)
- Magic 2 (KeeLoq, 64 bits) (magic serial type 2)
- Magic 3 (KeeLoq, 64 bits) (magic serial type 3)
- Magic 4 (KeeLoq, 64 bits) (magic serial type 3)
- Merlin (KeeLoq, 64 bits) (no serial part in Hop - simple XOR)
- Mongoose (KeeLoq, 64 bits) (normal learning)
- Pantera (KeeLoq, 64 bits)
- Pantera CLK (KeeLoq, 64 bits)
- Pantera XS/Jaguar (KeeLoq, 64 bits)
- Partisan RX (KeeLoq, 64 bits)
- Pecinin (KeeLoq, 64 bits) (12bit serial part in Hop - simple learning)
- Reff (KeeLoq, 64 bits)
- Rossi (KeeLoq, 64 bits) (12bit serial part in Hop - simple learning)
- Rosh (KeeLoq, 64 bits) (12bit serial part in Hop - simple learning)
- Sheriff (KeeLoq, 64 bits)
- SL A2-A4 (KeeLoq, 64 bits)
- SL A6-A9/Tomahawk 9010 (KeeLoq, 64 bits)
- SL B6,B9 dop (KeeLoq, 64 bits)
- Teco (KeeLoq, 64 bits)
- Tomahawk TZ-9030 (KeeLoq, 64 bits)
- Tomahawk Z,X 3-5 (KeeLoq, 64 bits)
- ZX-730-750-1055 (KeeLoq, 64 bits)
*Note: Most KeeLoq manufacturers operate in the 433 MHz and 868 MHz frequency bands with AM650 modulation. Some operate at other frequencies or modulations. Not all KeeLoq systems are supported for full decoding or emulation.*
---
## Protocol Type Reference
Unleashed firmware supports various protocol types:
- **Static Code**: Fixed transmission codes (e.g., Roger, Princeton, Marantec, Revers RB2)
- **Rolling Code (Dynamic) (KeeLoq)**: Dynamic codes with rolling counter using KeeLoq encryption (60+ manufacturer systems supported)
- **Rolling Code (Dynamic)**: Other dynamic systems with custom encoding (e.g., CAME Atomo, Nice Flor S, Somfy Telis, FAAC SLH, Alutech AT-4N, Security+)
For more information on how to use some of these protocols, see also [SubGHzRemoteProg.md](/documentation/SubGHzRemoteProg.md) and the main [ReadMe.md](/ReadMe.md).
---
*Docs made for Unleashed FW, please mention source when copying*

View File

@@ -39,6 +39,7 @@ Built-in presets:
- `FuriHalSubGhzPresetOok270Async` — On/Off Keying, 270kHz bandwidth, async(IO throw GP0) - `FuriHalSubGhzPresetOok270Async` — On/Off Keying, 270kHz bandwidth, async(IO throw GP0)
- `FuriHalSubGhzPresetOok650Async` — On/Off Keying, 650kHz bandwidth, async(IO throw GP0) - `FuriHalSubGhzPresetOok650Async` — On/Off Keying, 650kHz bandwidth, async(IO throw GP0)
- `FuriHalSubGhzPreset2FSKDev238Async` — 2 Frequency Shift Keying, deviation 2kHz, 270kHz bandwidth, async(IO throw GP0) - `FuriHalSubGhzPreset2FSKDev238Async` — 2 Frequency Shift Keying, deviation 2kHz, 270kHz bandwidth, async(IO throw GP0)
- `FuriHalSubGhzPreset2FSKDev12KAsync` — 2 Frequency Shift Keying, deviation 12kHz, 270kHz bandwidth, async(IO throw GP0)
- `FuriHalSubGhzPreset2FSKDev476Async` — 2 Frequency Shift Keying, deviation 47kHz, 270kHz bandwidth, async(IO throw GP0) - `FuriHalSubGhzPreset2FSKDev476Async` — 2 Frequency Shift Keying, deviation 47kHz, 270kHz bandwidth, async(IO throw GP0)
### Transceiver Configuration Data {#transceiver-configuration-data} ### Transceiver Configuration Data {#transceiver-configuration-data}

View File

@@ -1063,7 +1063,7 @@ MJS_PRIVATE mjs_err_t mjs_execute(struct mjs* mjs, size_t off, mjs_val_t* res) {
mjs_gen_stack_trace(mjs, bp.start_idx + i - 1 /* undo the i++ */); mjs_gen_stack_trace(mjs, bp.start_idx + i - 1 /* undo the i++ */);
/* restore stack lenghts */ /* restore stack lengths */
mjs->stack.len = stack_len; mjs->stack.len = stack_len;
mjs->call_stack.len = call_stack_len; mjs->call_stack.len = call_stack_len;
mjs->arg_stack.len = arg_stack_len; mjs->arg_stack.len = arg_stack_len;

View File

@@ -4,6 +4,35 @@
#define TAG "SubGhzBlockGeneric" #define TAG "SubGhzBlockGeneric"
// Main things: subghz protocols working (serialize, deserialize, decode and encode)
// with flipper_format data isolated from upper level subghz functions and structures.
// So if we need change something inside of protocol data - we need use this API from protocols to get and set data
SubGhzBlockGenericGlobal subghz_block_generic_global; //global structure for subghz
void subghz_block_generic_global_counter_override_set(uint32_t counter) {
subghz_block_generic_global.new_cnt = counter; // set global variable
subghz_block_generic_global.cnt_need_override = true; // set flag for protocols
}
bool subghz_block_generic_global_counter_override_get(uint32_t* counter) {
// if override flag was enabled then return succes TRUE and return overrided counter, else return success = FALSE
// we cut counter bit length to available protocol bits length by the logical AND function
if(subghz_block_generic_global.cnt_need_override) {
*counter = subghz_block_generic_global.new_cnt &
((0xFFFFFFFF >> (32 - subghz_block_generic_global.cnt_length_bit)));
subghz_block_generic_global.cnt_need_override = false;
return true;
} else {
return false;
}
}
void subghz_block_generic_global_reset(void* p) {
UNUSED(p);
memset(&subghz_block_generic_global, 0, sizeof(subghz_block_generic_global));
}
void subghz_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str) { void subghz_block_generic_get_preset_name(const char* preset_name, FuriString* preset_str) {
const char* preset_name_temp; const char* preset_name_temp;
if(!strcmp(preset_name, "AM270")) { if(!strcmp(preset_name, "AM270")) {
@@ -12,6 +41,8 @@ void subghz_block_generic_get_preset_name(const char* preset_name, FuriString* p
preset_name_temp = "FuriHalSubGhzPresetOok650Async"; preset_name_temp = "FuriHalSubGhzPresetOok650Async";
} else if(!strcmp(preset_name, "FM238")) { } else if(!strcmp(preset_name, "FM238")) {
preset_name_temp = "FuriHalSubGhzPreset2FSKDev238Async"; preset_name_temp = "FuriHalSubGhzPreset2FSKDev238Async";
} else if(!strcmp(preset_name, "FM12K")) {
preset_name_temp = "FuriHalSubGhzPreset2FSKDev12KAsync";
} else if(!strcmp(preset_name, "FM476")) { } else if(!strcmp(preset_name, "FM476")) {
preset_name_temp = "FuriHalSubGhzPreset2FSKDev476Async"; preset_name_temp = "FuriHalSubGhzPreset2FSKDev476Async";
} else { } else {

View File

@@ -27,6 +27,36 @@ struct SubGhzBlockGeneric {
uint32_t seed; uint32_t seed;
}; };
typedef struct SubGhzBlockGenericGlobal SubGhzBlockGenericGlobal;
struct SubGhzBlockGenericGlobal {
uint32_t current_cnt; // global counter value;
uint32_t new_cnt; // global counter value;
bool cnt_need_override; // flag for protocols to override signals counter inside of protocols
uint8_t cnt_length_bit; // counter length in bytes (used in counter editor giu)
bool cnt_is_available; // is there counter available for protocol (used in counter editor giu)
};
extern SubGhzBlockGenericGlobal subghz_block_generic_global; //global structure for subghz
/**
* Setup SubGhzBlockGenericGlobal.cnt and cnt_need_override flag to be used in protocols;
* @param counter new counter value;
*/
void subghz_block_generic_global_counter_override_set(uint32_t counter);
/**
* Return true if incomming variable was overrided by SubGhzBlockGenericGlobal.cnt
* else return false and not change incomming variable
* @param counter pointer to counter variable that must be changed
*/
bool subghz_block_generic_global_counter_override_get(uint32_t* counter);
/**
* Reset subghz_block_generic global structure;
*/
void subghz_block_generic_global_reset(void* p);
/** /**
* Get name preset. * Get name preset.
* @param preset_name name preset * @param preset_name name preset

View File

@@ -220,6 +220,77 @@ const uint8_t subghz_device_cc1101_preset_2fsk_dev2_38khz_async_regs[] = {
0x00, 0x00,
}; };
const uint8_t subghz_device_cc1101_preset_2fsk_dev12khz_async_regs[] = {
/* GPIO GD0 */
CC1101_IOCFG0,
0x0D, // GD0 as async serial data output/input
/* Frequency Synthesizer Control */
CC1101_FSCTRL1,
0x06, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz
/* Packet engine */
CC1101_PKTCTRL0,
0x32, // Async, continious, no whitening
CC1101_PKTCTRL1,
0x04,
// // Modem Configuration
CC1101_MDMCFG0,
0x00,
CC1101_MDMCFG1,
0x02,
CC1101_MDMCFG2,
0x04, // Format 2-FSK/FM, No preamble/sync, Disable (current optimized)
CC1101_MDMCFG3,
0x83, // Data rate is 4.79794 kBaud
CC1101_MDMCFG4,
0x67, //Rx BW filter is 270.833333 kHz
CC1101_DEVIATN,
0x30, //Deviation 12.695312 kHz
/* Main Radio Control State Machine */
CC1101_MCSM0,
0x18, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us)
/* Frequency Offset Compensation Configuration */
CC1101_FOCCFG,
0x16, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off
/* Automatic Gain Control */
CC1101_AGCCTRL0,
0x91, //10 - Medium hysteresis, medium asymmetric dead zone, medium gain ; 01 - 16 samples agc; 00 - Normal AGC, 01 - 8dB boundary
CC1101_AGCCTRL1,
0x00, // 0; 0 - LNA 2 gain is decreased to minimum before decreasing LNA gain; 00 - Relative carrier sense threshold disabled; 0000 - RSSI to MAIN_TARGET
CC1101_AGCCTRL2,
0x07, // 00 - DVGA all; 000 - MAX LNA+LNA2; 111 - MAIN_TARGET 42 dB
/* Wake on radio and timeouts control */
CC1101_WORCTRL,
0xFB, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours
/* Frontend configuration */
CC1101_FREND0,
0x10, // Adjusts current TX LO buffer
CC1101_FREND1,
0x56,
/* End load reg */
0,
0,
// 2fsk_async_patable[8]
0xC0, // 10dBm 0xC0, 7dBm 0xC8, 5dBm 0x84, 0dBm 0x60, -10dBm 0x34, -15dBm 0x1D, -20dBm 0x0E, -30dBm 0x12
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
};
const uint8_t subghz_device_cc1101_preset_2fsk_dev47_6khz_async_regs[] = { const uint8_t subghz_device_cc1101_preset_2fsk_dev47_6khz_async_regs[] = {
/* GPIO GD0 */ /* GPIO GD0 */

View File

@@ -8,6 +8,7 @@ extern "C" {
extern const uint8_t subghz_device_cc1101_preset_ook_270khz_async_regs[]; extern const uint8_t subghz_device_cc1101_preset_ook_270khz_async_regs[];
extern const uint8_t subghz_device_cc1101_preset_ook_650khz_async_regs[]; extern const uint8_t subghz_device_cc1101_preset_ook_650khz_async_regs[];
extern const uint8_t subghz_device_cc1101_preset_2fsk_dev2_38khz_async_regs[]; extern const uint8_t subghz_device_cc1101_preset_2fsk_dev2_38khz_async_regs[];
extern const uint8_t subghz_device_cc1101_preset_2fsk_dev12khz_async_regs[];
extern const uint8_t subghz_device_cc1101_preset_2fsk_dev47_6khz_async_regs[]; extern const uint8_t subghz_device_cc1101_preset_2fsk_dev47_6khz_async_regs[];
extern const uint8_t subghz_device_cc1101_preset_msk_99_97kb_async_regs[]; extern const uint8_t subghz_device_cc1101_preset_msk_99_97kb_async_regs[];
extern const uint8_t subghz_device_cc1101_preset_gfsk_9_99kb_async_regs[]; extern const uint8_t subghz_device_cc1101_preset_gfsk_9_99kb_async_regs[];

View File

@@ -38,6 +38,9 @@ static void subghz_device_cc1101_int_interconnect_load_preset(
case FuriHalSubGhzPreset2FSKDev238Async: case FuriHalSubGhzPreset2FSKDev238Async:
furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_2fsk_dev2_38khz_async_regs); furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_2fsk_dev2_38khz_async_regs);
break; break;
case FuriHalSubGhzPreset2FSKDev12KAsync:
furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_2fsk_dev12khz_async_regs);
break;
case FuriHalSubGhzPreset2FSKDev476Async: case FuriHalSubGhzPreset2FSKDev476Async:
furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_2fsk_dev47_6khz_async_regs); furi_hal_subghz_load_custom_preset(subghz_device_cc1101_preset_2fsk_dev47_6khz_async_regs);
break; break;

View File

@@ -6,6 +6,7 @@ typedef enum {
FuriHalSubGhzPresetOok270Async, /**< OOK, bandwidth 270kHz, asynchronous */ FuriHalSubGhzPresetOok270Async, /**< OOK, bandwidth 270kHz, asynchronous */
FuriHalSubGhzPresetOok650Async, /**< OOK, bandwidth 650kHz, asynchronous */ FuriHalSubGhzPresetOok650Async, /**< OOK, bandwidth 650kHz, asynchronous */
FuriHalSubGhzPreset2FSKDev238Async, /**< FM, deviation 2.380371 kHz, asynchronous */ FuriHalSubGhzPreset2FSKDev238Async, /**< FM, deviation 2.380371 kHz, asynchronous */
FuriHalSubGhzPreset2FSKDev12KAsync, /**< FM, deviation 12.695312 kHz, asynchronous */
FuriHalSubGhzPreset2FSKDev476Async, /**< FM, deviation 47.60742 kHz, asynchronous */ FuriHalSubGhzPreset2FSKDev476Async, /**< FM, deviation 47.60742 kHz, asynchronous */
FuriHalSubGhzPresetMSK99_97KbAsync, /**< MSK, deviation 47.60742 kHz, 99.97Kb/s, asynchronous */ FuriHalSubGhzPresetMSK99_97KbAsync, /**< MSK, deviation 47.60742 kHz, 99.97Kb/s, asynchronous */
FuriHalSubGhzPresetGFSK9_99KbAsync, /**< GFSK, deviation 19.042969 kHz, 9.996Kb/s, asynchronous */ FuriHalSubGhzPresetGFSK9_99KbAsync, /**< GFSK, deviation 19.042969 kHz, 9.996Kb/s, asynchronous */

View File

@@ -0,0 +1,252 @@
#include "aes_common.h"
static const uint8_t aes_sbox[256] = {
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab,
0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4,
0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71,
0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2,
0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6,
0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb,
0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45,
0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44,
0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a,
0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49,
0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d,
0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25,
0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e,
0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1,
0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb,
0x16};
static const uint8_t aes_sbox_inv[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7,
0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde,
0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42,
0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49,
0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c,
0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15,
0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7,
0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc,
0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad,
0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d,
0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b,
0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8,
0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51,
0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0,
0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c,
0x7d};
static const uint8_t aes_rcon[10] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
static uint8_t gf_mul2(uint8_t x) {
return ((x >> 7) * 0x1b) ^ (x << 1);
}
static void aes_subbytes(uint8_t* state) {
for(uint8_t row = 0; row < 4; row++) {
for(uint8_t col = 0; col < 4; col++) {
state[row + col * 4] = aes_sbox[state[row + col * 4]];
}
}
}
static void aes_subbytes_inv(uint8_t* state) {
for(uint8_t row = 0; row < 4; row++) {
for(uint8_t col = 0; col < 4; col++) {
state[row + col * 4] = aes_sbox_inv[state[row + col * 4]];
}
}
}
static void aes_shiftrows(uint8_t* state) {
uint8_t temp;
temp = state[1];
state[1] = state[5];
state[5] = state[9];
state[9] = state[13];
state[13] = temp;
temp = state[2];
state[2] = state[10];
state[10] = temp;
temp = state[6];
state[6] = state[14];
state[14] = temp;
temp = state[15];
state[15] = state[11];
state[11] = state[7];
state[7] = state[3];
state[3] = temp;
}
static void aes_shiftrows_inv(uint8_t* state) {
uint8_t temp;
temp = state[13];
state[13] = state[9];
state[9] = state[5];
state[5] = state[1];
state[1] = temp;
temp = state[2];
state[2] = state[10];
state[10] = temp;
temp = state[6];
state[6] = state[14];
state[14] = temp;
temp = state[3];
state[3] = state[7];
state[7] = state[11];
state[11] = state[15];
state[15] = temp;
}
static void aes_mixcolumns(uint8_t* state) {
uint8_t a, b, c, d;
for(uint8_t i = 0; i < 4; i++) {
a = state[i * 4];
b = state[i * 4 + 1];
c = state[i * 4 + 2];
d = state[i * 4 + 3];
uint8_t a2 = gf_mul2(a);
uint8_t b2 = gf_mul2(b);
uint8_t c2 = gf_mul2(c);
uint8_t d2 = gf_mul2(d);
state[i * 4] = a2 ^ b2 ^ b ^ c ^ d;
state[i * 4 + 1] = a ^ b2 ^ c2 ^ c ^ d;
state[i * 4 + 2] = a ^ b ^ c2 ^ d2 ^ d;
state[i * 4 + 3] = a2 ^ a ^ b ^ c ^ d2;
}
}
static void aes_mixcolumns_inv(uint8_t* state) {
uint8_t a, b, c, d;
for(uint8_t i = 0; i < 4; i++) {
a = state[i * 4];
b = state[i * 4 + 1];
c = state[i * 4 + 2];
d = state[i * 4 + 3];
uint8_t a2 = gf_mul2(a);
uint8_t a4 = gf_mul2(a2);
uint8_t a8 = gf_mul2(a4);
uint8_t b2 = gf_mul2(b);
uint8_t b4 = gf_mul2(b2);
uint8_t b8 = gf_mul2(b4);
uint8_t c2 = gf_mul2(c);
uint8_t c4 = gf_mul2(c2);
uint8_t c8 = gf_mul2(c4);
uint8_t d2 = gf_mul2(d);
uint8_t d4 = gf_mul2(d2);
uint8_t d8 = gf_mul2(d4);
state[i * 4] = (a8 ^ a4 ^ a2) ^ (b8 ^ b2 ^ b) ^ (c8 ^ c4 ^ c) ^ (d8 ^ d);
state[i * 4 + 1] = (a8 ^ a) ^ (b8 ^ b4 ^ b2) ^ (c8 ^ c2 ^ c) ^ (d8 ^ d4 ^ d);
state[i * 4 + 2] = (a8 ^ a4 ^ a) ^ (b8 ^ b) ^ (c8 ^ c4 ^ c2) ^ (d8 ^ d2 ^ d);
state[i * 4 + 3] = (a8 ^ a2 ^ a) ^ (b8 ^ b4 ^ b) ^ (c8 ^ c) ^ (d8 ^ d4 ^ d2);
}
}
static void aes_addroundkey(uint8_t* state, const uint8_t* round_key) {
for(uint8_t col = 0; col < 4; col++) {
state[col * 4] ^= round_key[col * 4];
state[col * 4 + 1] ^= round_key[col * 4 + 1];
state[col * 4 + 2] ^= round_key[col * 4 + 2];
state[col * 4 + 3] ^= round_key[col * 4 + 3];
}
}
void aes_key_expansion(const uint8_t* key, uint8_t* round_keys) {
for(uint8_t i = 0; i < 16; i++) {
round_keys[i] = key[i];
}
for(uint8_t i = 4; i < 44; i++) {
uint8_t prev_word_idx = (i - 1) * 4;
uint8_t b0 = round_keys[prev_word_idx];
uint8_t b1 = round_keys[prev_word_idx + 1];
uint8_t b2 = round_keys[prev_word_idx + 2];
uint8_t b3 = round_keys[prev_word_idx + 3];
if((i % 4) == 0) {
uint8_t new_b0 = aes_sbox[b1] ^ aes_rcon[(i / 4) - 1];
uint8_t new_b1 = aes_sbox[b2];
uint8_t new_b2 = aes_sbox[b3];
uint8_t new_b3 = aes_sbox[b0];
b0 = new_b0;
b1 = new_b1;
b2 = new_b2;
b3 = new_b3;
}
uint8_t back_word_idx = (i - 4) * 4;
b0 ^= round_keys[back_word_idx];
b1 ^= round_keys[back_word_idx + 1];
b2 ^= round_keys[back_word_idx + 2];
b3 ^= round_keys[back_word_idx + 3];
uint8_t curr_word_idx = i * 4;
round_keys[curr_word_idx] = b0;
round_keys[curr_word_idx + 1] = b1;
round_keys[curr_word_idx + 2] = b2;
round_keys[curr_word_idx + 3] = b3;
}
}
void aes128_encrypt(const uint8_t* expanded_key, uint8_t* data) {
uint8_t state[16];
memcpy(state, data, 16);
aes_addroundkey(state, &expanded_key[0]);
for(uint8_t round = 1; round < 10; round++) {
aes_subbytes(state);
aes_shiftrows(state);
aes_mixcolumns(state);
aes_addroundkey(state, &expanded_key[round * 16]);
}
aes_subbytes(state);
aes_shiftrows(state);
aes_addroundkey(state, &expanded_key[160]);
memcpy(data, state, 16);
}
void aes128_decrypt(const uint8_t* expanded_key, uint8_t* data) {
uint8_t state[16];
memcpy(state, data, 16);
aes_addroundkey(state, &expanded_key[160]);
for(uint8_t round = 9; round > 0; round--) {
aes_shiftrows_inv(state);
aes_subbytes_inv(state);
aes_addroundkey(state, &expanded_key[round * 16]);
aes_mixcolumns_inv(state);
}
aes_shiftrows_inv(state);
aes_subbytes_inv(state);
aes_addroundkey(state, &expanded_key[0]);
memcpy(data, state, 16);
}
void reverse_bits_in_bytes(uint8_t* data, uint8_t len) {
for(uint8_t i = 0; i < len; i++) {
uint8_t byte = data[i];
uint8_t step1 = ((byte & 0x55) << 1) | ((byte >> 1) & 0x55);
uint8_t step2 = ((step1 & 0x33) << 2) | ((step1 >> 2) & 0x33);
data[i] = ((step2 & 0x0F) << 4) | (step2 >> 4);
}
}

View File

@@ -0,0 +1,10 @@
#pragma once
#include "base.h"
#include <furi.h>
void reverse_bits_in_bytes(uint8_t* data, uint8_t len);
void aes128_decrypt(const uint8_t* expanded_key, uint8_t* data);
void aes128_encrypt(const uint8_t* expanded_key, uint8_t* data);
void aes_key_expansion(const uint8_t* key, uint8_t* round_keys);

View File

@@ -9,7 +9,8 @@
#define TAG "SubGhzProtocoAlutech_at_4n" #define TAG "SubGhzProtocoAlutech_at_4n"
#define SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE 0xFFFFFFFF #define SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE 0xFFFFFFFFFFFFFFFF
#define SUBGHZ_ALUTECH_AT_4N_RAINBOW_TABLE_SIZE_BYTES 32
static const SubGhzBlockConst subghz_protocol_alutech_at_4n_const = { static const SubGhzBlockConst subghz_protocol_alutech_at_4n_const = {
.te_short = 400, .te_short = 400,
@@ -142,27 +143,21 @@ LevelDuration subghz_protocol_encoder_alutech_at_4n_yield(void* context) {
} }
/** /**
* Read bytes from rainbow table * Read bytes from buffer array with rainbow table
* @param file_name Full path to rainbow table the file * @param buffer Pointer to decrypted magic data buffer
* @param number_alutech_at_4n_magic_data number in the array * @param number_alutech_at_4n_magic_data number in the array
* @return alutech_at_4n_magic_data * @return alutech_at_4n_magic_data
*/ */
static uint32_t subghz_protocol_alutech_at_4n_get_magic_data_in_file( static uint32_t subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(
const char* file_name, uint8_t* buffer,
uint8_t number_alutech_at_4n_magic_data) { uint8_t number_alutech_at_4n_magic_data) {
if(!strcmp(file_name, "")) return SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE;
uint8_t buffer[sizeof(uint32_t)] = {0};
uint32_t address = number_alutech_at_4n_magic_data * sizeof(uint32_t); uint32_t address = number_alutech_at_4n_magic_data * sizeof(uint32_t);
uint32_t alutech_at_4n_magic_data = 0; uint32_t alutech_at_4n_magic_data = 0;
if(subghz_keystore_raw_get_data(file_name, address, buffer, sizeof(uint32_t))) { for(size_t i = address; i < (address + sizeof(uint32_t)); i++) {
for(size_t i = 0; i < sizeof(uint32_t); i++) { alutech_at_4n_magic_data = (alutech_at_4n_magic_data << 8) | buffer[i];
alutech_at_4n_magic_data = (alutech_at_4n_magic_data << 8) | buffer[i];
}
} else {
alutech_at_4n_magic_data = SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE;
} }
return alutech_at_4n_magic_data; return alutech_at_4n_magic_data;
} }
@@ -197,17 +192,29 @@ static uint8_t subghz_protocol_alutech_at_4n_decrypt_data_crc(uint8_t data) {
} }
static uint64_t subghz_protocol_alutech_at_4n_decrypt(uint64_t data, const char* file_name) { static uint64_t subghz_protocol_alutech_at_4n_decrypt(uint64_t data, const char* file_name) {
// load and decrypt rainbow table from file to buffer array in RAM
if(!file_name) return SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE;
uint8_t buffer[SUBGHZ_ALUTECH_AT_4N_RAINBOW_TABLE_SIZE_BYTES] = {0};
uint8_t* buffer_ptr = (uint8_t*)&buffer;
if(subghz_keystore_raw_get_data(
file_name, 0, buffer, SUBGHZ_ALUTECH_AT_4N_RAINBOW_TABLE_SIZE_BYTES)) {
} else {
return SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE;
}
uint8_t* p = (uint8_t*)&data; uint8_t* p = (uint8_t*)&data;
uint32_t data1 = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; uint32_t data1 = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
uint32_t data2 = p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7]; uint32_t data2 = p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7];
uint32_t data3 = 0; uint32_t data3 = 0;
uint32_t magic_data[] = { uint32_t magic_data[] = {
subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 0), subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 0),
subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 1), subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 1),
subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 2), subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 2),
subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 3), subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 3),
subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 4), subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 4),
subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 5)}; subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 5)};
uint32_t i = magic_data[0]; uint32_t i = magic_data[0];
do { do {
@@ -232,17 +239,29 @@ static uint64_t subghz_protocol_alutech_at_4n_decrypt(uint64_t data, const char*
} }
static uint64_t subghz_protocol_alutech_at_4n_encrypt(uint64_t data, const char* file_name) { static uint64_t subghz_protocol_alutech_at_4n_encrypt(uint64_t data, const char* file_name) {
// load and decrypt rainbow table from file to buffer array in RAM
if(!file_name) return SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE;
uint8_t buffer[SUBGHZ_ALUTECH_AT_4N_RAINBOW_TABLE_SIZE_BYTES] = {0};
uint8_t* buffer_ptr = (uint8_t*)&buffer;
if(subghz_keystore_raw_get_data(
file_name, 0, buffer, SUBGHZ_ALUTECH_AT_4N_RAINBOW_TABLE_SIZE_BYTES)) {
} else {
return SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE;
}
uint8_t* p = (uint8_t*)&data; uint8_t* p = (uint8_t*)&data;
uint32_t data1 = 0; uint32_t data1 = 0;
uint32_t data2 = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; uint32_t data2 = p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
uint32_t data3 = p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7]; uint32_t data3 = p[4] << 24 | p[5] << 16 | p[6] << 8 | p[7];
uint32_t magic_data[] = { uint32_t magic_data[] = {
subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 6), subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 6),
subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 4), subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 4),
subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 5), subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 5),
subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 1), subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 1),
subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 2), subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 2),
subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 0)}; subghz_protocol_alutech_at_4n_get_magic_data_from_buffer(buffer_ptr, 0)};
do { do {
data1 = data1 + magic_data[0]; data1 = data1 + magic_data[0];
@@ -280,12 +299,17 @@ static bool subghz_protocol_alutech_at_4n_gen_data(
if(alutech_at4n_counter_mode == 0) { if(alutech_at4n_counter_mode == 0) {
// Check for OFEX (overflow experimental) mode // Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { // standart counter mode. PULL data from subghz_block_generic_global variables
instance->generic.cnt = 0; if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
} else { // if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
} }
} else { } else {
//OFFEX mode
if((instance->generic.cnt + 0x1) > 0xFFFF) { if((instance->generic.cnt + 0x1) > 0xFFFF) {
instance->generic.cnt = 0; instance->generic.cnt = 0;
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) { } else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
@@ -461,7 +485,7 @@ SubGhzProtocolStatus subghz_protocol_encoder_alutech_at_4n_deserialize(
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
@@ -872,6 +896,12 @@ void subghz_protocol_decoder_alutech_at_4n_get_string(void* context, FuriString*
uint32_t code_found_hi = instance->generic.data >> 32; uint32_t code_found_hi = instance->generic.data >> 32;
uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff;
// push protocol data to global variable
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
//
furi_string_cat_printf( furi_string_cat_printf(
output, output,
"%s\r\n" "%s\r\n"

View File

@@ -152,7 +152,7 @@ SubGhzProtocolStatus
FURI_LOG_E(TAG, "Deserialize error"); FURI_LOG_E(TAG, "Deserialize error");
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -1,5 +1,6 @@
#include "base.h" #include "base.h"
#include "registry.h" #include "registry.h"
#include "../blocks/generic.h"
void subghz_protocol_decoder_base_set_decoder_callback( void subghz_protocol_decoder_base_set_decoder_callback(
SubGhzProtocolDecoderBase* decoder_base, SubGhzProtocolDecoderBase* decoder_base,
@@ -17,6 +18,8 @@ bool subghz_protocol_decoder_base_get_string(
furi_check(decoder_base); furi_check(decoder_base);
furi_check(output); furi_check(output);
subghz_block_generic_global_reset(0);
bool status = false; bool status = false;
if(decoder_base->protocol && decoder_base->protocol->decoder && if(decoder_base->protocol && decoder_base->protocol->decoder &&

View File

@@ -0,0 +1,681 @@
#include "beninca_arc.h"
#include "../blocks/const.h"
#include "../blocks/decoder.h"
#include "../blocks/encoder.h"
#include "../blocks/generic.h"
#include "../blocks/math.h"
#include "core/log.h"
#include <stddef.h>
#include <stdint.h>
#include "aes_common.h"
#include "../blocks/custom_btn_i.h"
#define TAG "BenincaARC"
#define BENINCA_ARC_KEY_TYPE 9u
static const SubGhzBlockConst subghz_protocol_beninca_arc_const = {
.te_short = 300,
.te_long = 600,
.te_delta = 155,
.min_count_bit_for_found = 128,
};
typedef enum {
BenincaARCDecoderStart = 0,
BenincaARCDecoderHighLevel,
BenincaARCDecoderLowLevel,
} BenincaARCDecoderState;
struct SubGhzProtocolDecoderBenincaARC {
SubGhzProtocolDecoderBase base;
SubGhzBlockDecoder decoder;
SubGhzBlockGeneric generic;
SubGhzKeystore* keystore;
};
struct SubGhzProtocolEncoderBenincaARC {
SubGhzProtocolEncoderBase base;
SubGhzProtocolBlockEncoder encoder;
SubGhzBlockGeneric generic;
SubGhzKeystore* keystore;
};
const SubGhzProtocolDecoder subghz_protocol_beninca_arc_decoder = {
.alloc = subghz_protocol_decoder_beninca_arc_alloc,
.free = subghz_protocol_decoder_beninca_arc_free,
.feed = subghz_protocol_decoder_beninca_arc_feed,
.reset = subghz_protocol_decoder_beninca_arc_reset,
.get_hash_data = NULL,
.get_hash_data_long = subghz_protocol_decoder_beninca_arc_get_hash_data,
.serialize = subghz_protocol_decoder_beninca_arc_serialize,
.deserialize = subghz_protocol_decoder_beninca_arc_deserialize,
.get_string = subghz_protocol_decoder_beninca_arc_get_string,
.get_string_brief = NULL,
};
const SubGhzProtocolEncoder subghz_protocol_beninca_arc_encoder = {
.alloc = subghz_protocol_encoder_beninca_arc_alloc,
.free = subghz_protocol_encoder_beninca_arc_free,
.deserialize = subghz_protocol_encoder_beninca_arc_deserialize,
.stop = subghz_protocol_encoder_beninca_arc_stop,
.yield = subghz_protocol_encoder_beninca_arc_yield,
};
const SubGhzProtocol subghz_protocol_beninca_arc = {
.name = SUBGHZ_PROTOCOL_BENINCA_ARC_NAME,
.type = SubGhzProtocolTypeDynamic,
.flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable |
SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send,
.decoder = &subghz_protocol_beninca_arc_decoder,
.encoder = &subghz_protocol_beninca_arc_encoder,
};
// Get custom button code
static uint8_t subghz_protocol_beninca_arc_get_btn_code(void) {
uint8_t custom_btn_id = subghz_custom_btn_get();
uint8_t original_btn_code = subghz_custom_btn_get_original();
uint8_t btn = original_btn_code;
// Set custom button
if((custom_btn_id == SUBGHZ_CUSTOM_BTN_OK) && (original_btn_code != 0)) {
// Restore original button code
btn = original_btn_code;
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_UP) {
switch(original_btn_code) {
case 0x02:
btn = 0x04;
break;
case 0x04:
btn = 0x02;
break;
case 0xFF:
btn = 0x04;
break;
default:
break;
}
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_DOWN) {
switch(original_btn_code) {
case 0x02:
btn = 0xFF;
break;
case 0x04:
btn = 0xFF;
break;
case 0xFF:
btn = 0x02;
break;
default:
break;
}
}
return btn;
}
static void get_subghz_protocol_beninca_arc_aes_key(SubGhzKeystore* keystore, uint8_t* aes_key) {
uint64_t mfkey = 0;
for
M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) {
if(manufacture_code->type == BENINCA_ARC_KEY_TYPE) {
mfkey = manufacture_code->key;
break;
}
}
uint32_t derived_lo = (uint32_t)(mfkey & 0xFFFFFFFF);
uint32_t derived_hi = (uint32_t)((mfkey >> 32) & 0xFFFFFFFF);
uint64_t val64_a = ((uint64_t)derived_hi << 32) | derived_lo;
for(uint8_t i = 0; i < 8; i++) {
aes_key[i] = (val64_a >> (56 - i * 8)) & 0xFF;
}
uint32_t new_lo = ((derived_hi >> 24) & 0xFF) | ((derived_hi >> 8) & 0xFF00) |
((derived_hi << 8) & 0xFF0000) | ((derived_hi << 24) & 0xFF000000);
uint32_t new_hi = ((derived_lo >> 24) & 0xFF) | ((derived_lo >> 8) & 0xFF00) |
((derived_lo << 8) & 0xFF0000) | ((derived_lo << 24) & 0xFF000000);
uint64_t val64_b = ((uint64_t)new_hi << 32) | new_lo;
for(uint8_t i = 0; i < 8; i++) {
aes_key[i + 8] = (val64_b >> (56 - i * 8)) & 0xFF;
}
}
static uint64_t
subghz_protocol_beninca_arc_decrypt(SubGhzBlockGeneric* generic, SubGhzKeystore* keystore) {
// Beninca ARC Decoder
// 01.2026 - @xMasterX (MMX) & @zero-mega
// Decrypt data
uint8_t encrypted_data[16];
for(uint8_t i = 0; i < 8; i++) {
encrypted_data[i] = (generic->data >> (56 - i * 8)) & 0xFF;
encrypted_data[i + 8] = (generic->data_2 >> (56 - i * 8)) & 0xFF;
}
reverse_bits_in_bytes(encrypted_data, 16);
uint8_t aes_key[16];
get_subghz_protocol_beninca_arc_aes_key(keystore, aes_key);
uint8_t expanded_key[176];
aes_key_expansion(aes_key, expanded_key);
aes128_decrypt(expanded_key, encrypted_data);
// Serial number of remote
generic->serial = ((uint32_t)encrypted_data[0] << 24) | ((uint32_t)encrypted_data[1] << 16) |
((uint32_t)encrypted_data[2] << 8) | encrypted_data[3];
// Button code
generic->btn = encrypted_data[4];
// Middle bytes contains mini counter that is increased while button is held
// its value mostly stored in encrypted_data[9] but might be in other bytes as well
// In order to support all variants we read all middle bytes as uint64_t
// In case you have the remote with ARC rolling code please share RAW recording where you hold button for 15+ sec with us to improve this part!
uint64_t middle_bytes = 0;
middle_bytes = ((uint64_t)encrypted_data[5] << 32) | ((uint64_t)encrypted_data[6] << 24) |
((uint64_t)encrypted_data[7] << 16) | ((uint64_t)encrypted_data[8] << 8) |
encrypted_data[9];
// 32-bit counter
generic->cnt = ((uint32_t)encrypted_data[10] << 24) | ((uint32_t)encrypted_data[11] << 16) |
((uint32_t)encrypted_data[12] << 8) | encrypted_data[13];
// Fixed constant value AA 55
generic->seed = ((uint16_t)encrypted_data[14] << 8) | encrypted_data[15];
// Save original button for later use
if(subghz_custom_btn_get_original() == 0) {
subghz_custom_btn_set_original(generic->btn);
}
subghz_custom_btn_set_max(2);
return middle_bytes;
}
static void subghz_protocol_beninca_arc_encrypt(
SubGhzBlockGeneric* generic,
SubGhzKeystore* keystore,
uint64_t middle_bytes) {
// Beninca ARC Encoder
// 01.2026 - @xMasterX (MMX) & @zero-mega
// Encrypt data
uint8_t plaintext[16];
plaintext[0] = (generic->serial >> 24) & 0xFF;
plaintext[1] = (generic->serial >> 16) & 0xFF;
plaintext[2] = (generic->serial >> 8) & 0xFF;
plaintext[3] = generic->serial & 0xFF;
plaintext[4] = generic->btn;
plaintext[5] = (middle_bytes >> 32) & 0xFF;
plaintext[6] = (middle_bytes >> 24) & 0xFF;
plaintext[7] = (middle_bytes >> 16) & 0xFF;
plaintext[8] = (middle_bytes >> 8) & 0xFF;
plaintext[9] = middle_bytes & 0xFF;
plaintext[10] = (generic->cnt >> 24) & 0xFF;
plaintext[11] = (generic->cnt >> 16) & 0xFF;
plaintext[12] = (generic->cnt >> 8) & 0xFF;
plaintext[13] = generic->cnt & 0xFF;
plaintext[14] = (generic->seed >> 8) & 0xFF;
plaintext[15] = generic->seed & 0xFF;
uint8_t aes_key[16];
get_subghz_protocol_beninca_arc_aes_key(keystore, aes_key);
uint8_t expanded_key[176];
aes_key_expansion(aes_key, expanded_key);
aes128_encrypt(expanded_key, plaintext);
reverse_bits_in_bytes(plaintext, 16);
for(uint8_t i = 0; i < 8; i++) {
generic->data = (generic->data << 8) | plaintext[i];
generic->data_2 = (generic->data_2 << 8) | plaintext[i + 8];
}
return;
}
void* subghz_protocol_encoder_beninca_arc_alloc(SubGhzEnvironment* environment) {
SubGhzProtocolEncoderBenincaARC* instance = malloc(sizeof(SubGhzProtocolEncoderBenincaARC));
instance->base.protocol = &subghz_protocol_beninca_arc;
instance->generic.protocol_name = instance->base.protocol->name;
instance->keystore = subghz_environment_get_keystore(environment);
instance->encoder.repeat = 10;
instance->encoder.size_upload = 800;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
return instance;
}
void subghz_protocol_encoder_beninca_arc_free(void* context) {
furi_assert(context);
SubGhzProtocolEncoderBenincaARC* instance = context;
free(instance->encoder.upload);
free(instance);
}
void subghz_protocol_encoder_beninca_arc_stop(void* context) {
furi_assert(context);
SubGhzProtocolEncoderBenincaARC* instance = context;
instance->encoder.is_running = false;
}
static void subghz_protocol_beninca_arc_encoder_get_upload(
SubGhzProtocolEncoderBenincaARC* instance,
size_t* index) {
furi_assert(instance);
size_t index_local = *index;
// First part of data 64 bits
for(uint8_t i = 64; i > 0; i--) {
if(bit_read(instance->generic.data, i - 1)) {
// Send bit 1
instance->encoder.upload[index_local++] =
level_duration_make(true, (uint32_t)subghz_protocol_beninca_arc_const.te_short);
instance->encoder.upload[index_local++] =
level_duration_make(false, (uint32_t)subghz_protocol_beninca_arc_const.te_long);
} else {
// Send bit 0
instance->encoder.upload[index_local++] =
level_duration_make(true, (uint32_t)subghz_protocol_beninca_arc_const.te_long);
instance->encoder.upload[index_local++] =
level_duration_make(false, (uint32_t)subghz_protocol_beninca_arc_const.te_short);
}
}
// Second part of data 64 bits - total 128bits data
for(uint8_t i = 64; i > 0; i--) {
if(bit_read(instance->generic.data_2, i - 1)) {
// Send bit 1
instance->encoder.upload[index_local++] =
level_duration_make(true, (uint32_t)subghz_protocol_beninca_arc_const.te_short);
instance->encoder.upload[index_local++] =
level_duration_make(false, (uint32_t)subghz_protocol_beninca_arc_const.te_long);
} else {
// Send bit 0
instance->encoder.upload[index_local++] =
level_duration_make(true, (uint32_t)subghz_protocol_beninca_arc_const.te_long);
instance->encoder.upload[index_local++] =
level_duration_make(false, (uint32_t)subghz_protocol_beninca_arc_const.te_short);
}
}
// Add stop bit
instance->encoder.upload[index_local++] =
level_duration_make(true, (uint32_t)subghz_protocol_beninca_arc_const.te_short);
// Add gap between packets
instance->encoder.upload[index_local++] =
level_duration_make(false, (uint32_t)subghz_protocol_beninca_arc_const.te_long * 15);
*index = index_local;
}
static void subghz_protocol_beninca_arc_encoder_prepare_packets(
SubGhzProtocolEncoderBenincaARC* instance) {
furi_assert(instance);
// Counter increment
// check OFEX mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
// standart counter mode. PULL data from subghz_block_generic_global variables
if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
// if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFFFFFF) {
instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
}
} else {
// TODO: OFEX mode
instance->generic.cnt += 1;
}
// Index for upload array
size_t index = 0;
// Generate new key using custom or default button
instance->generic.btn = subghz_protocol_beninca_arc_get_btn_code();
// Make 3 packets with different mini counter values - 2, 4, 6
for(uint8_t i = 0; i < 3; i++) {
subghz_protocol_beninca_arc_encrypt(
&instance->generic, instance->keystore, (uint64_t)((i + 1) * 2));
subghz_protocol_beninca_arc_encoder_get_upload(instance, &index);
}
// Set final size of upload array
instance->encoder.size_upload = index;
}
bool subghz_protocol_beninca_arc_create_data(
void* context,
FlipperFormat* flipper_format,
uint32_t serial,
uint8_t btn,
uint32_t cnt,
SubGhzRadioPreset* preset) {
furi_assert(context);
// UwU
SubGhzProtocolEncoderBenincaARC* instance = context;
instance->generic.serial = serial;
instance->generic.btn = btn; // 02 / 04
instance->generic.cnt = cnt;
instance->generic.seed = 0xAA55; // Fixed value constant
instance->generic.data_count_bit = 128;
subghz_protocol_beninca_arc_encrypt(&instance->generic, instance->keystore, 0x1);
SubGhzProtocolStatus res =
subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
uint8_t key_data[sizeof(uint64_t)] = {0};
for(size_t i = 0; i < sizeof(uint64_t); i++) {
key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data_2 >> (i * 8)) & 0xFF;
}
if(!flipper_format_rewind(flipper_format)) {
FURI_LOG_E(TAG, "Rewind error");
res = SubGhzProtocolStatusErrorParserOthers;
}
if((res == SubGhzProtocolStatusOk) &&
!flipper_format_insert_or_update_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
FURI_LOG_E(TAG, "Unable to add Data2");
res = SubGhzProtocolStatusErrorParserOthers;
}
return res == SubGhzProtocolStatusOk;
}
SubGhzProtocolStatus
subghz_protocol_encoder_beninca_arc_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderBenincaARC* instance = context;
SubGhzProtocolStatus res = SubGhzProtocolStatusError;
do {
if(SubGhzProtocolStatusOk !=
subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
FURI_LOG_E(TAG, "Deserialize error");
break;
}
// Optional value
flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
if(!flipper_format_rewind(flipper_format)) {
FURI_LOG_E(TAG, "Rewind error");
break;
}
uint8_t key_data[sizeof(uint64_t)] = {0};
if(!flipper_format_read_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
FURI_LOG_E(TAG, "Missing Data");
break;
}
for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
instance->generic.data_2 = instance->generic.data_2 << 8 | key_data[i];
}
// TODO: if minicounter having larger value use it instead of fixed values
subghz_protocol_beninca_arc_decrypt(&instance->generic, instance->keystore);
subghz_protocol_beninca_arc_encoder_prepare_packets(instance);
if(!flipper_format_rewind(flipper_format)) {
FURI_LOG_E(TAG, "Rewind error");
break;
}
for(size_t i = 0; i < sizeof(uint64_t); i++) {
key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> i * 8) & 0xFF;
}
if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) {
FURI_LOG_E(TAG, "Unable to update Key");
break;
}
for(size_t i = 0; i < sizeof(uint64_t); i++) {
key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data_2 >> i * 8) & 0xFF;
}
if(!flipper_format_update_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
FURI_LOG_E(TAG, "Unable to update Data");
break;
}
instance->encoder.is_running = true;
res = SubGhzProtocolStatusOk;
} while(false);
return res;
}
LevelDuration subghz_protocol_encoder_beninca_arc_yield(void* context) {
furi_assert(context);
SubGhzProtocolEncoderBenincaARC* instance = context;
if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
instance->encoder.is_running = false;
return level_duration_reset();
}
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
instance->encoder.front = 0;
}
return ret;
}
void* subghz_protocol_decoder_beninca_arc_alloc(SubGhzEnvironment* environment) {
SubGhzProtocolDecoderBenincaARC* instance = malloc(sizeof(SubGhzProtocolDecoderBenincaARC));
instance->base.protocol = &subghz_protocol_beninca_arc;
instance->generic.protocol_name = instance->base.protocol->name;
instance->keystore = subghz_environment_get_keystore(environment);
instance->decoder.parser_step = BenincaARCDecoderStart;
return instance;
}
void subghz_protocol_decoder_beninca_arc_free(void* context) {
furi_assert(context);
SubGhzProtocolDecoderBenincaARC* instance = context;
free(instance);
}
void subghz_protocol_decoder_beninca_arc_reset(void* context) {
furi_assert(context);
SubGhzProtocolDecoderBenincaARC* instance = context;
instance->decoder.parser_step = BenincaARCDecoderStart;
}
void subghz_protocol_decoder_beninca_arc_feed(void* context, bool level, uint32_t duration) {
furi_assert(context);
SubGhzProtocolDecoderBenincaARC* instance = context;
switch(instance->decoder.parser_step) {
case BenincaARCDecoderStart:
if((!level) && (DURATION_DIFF(duration, subghz_protocol_beninca_arc_const.te_long * 16) <
subghz_protocol_beninca_arc_const.te_delta * 15)) {
// GAP (9300 +- 2325 us) found switch to next state
instance->decoder.decode_data = 0;
instance->decoder.decode_count_bit = 0;
instance->decoder.parser_step = BenincaARCDecoderHighLevel;
break;
}
// No GAP so stay in current state
break;
case BenincaARCDecoderHighLevel:
if(level) {
instance->decoder.te_last = duration;
instance->decoder.parser_step = BenincaARCDecoderLowLevel;
// Check if we have collected enough bits
if((instance->decoder.decode_count_bit ==
(subghz_protocol_beninca_arc_const.min_count_bit_for_found / 2)) &&
(instance->decoder.decode_data != 0)) {
// Half data captured 64 bits
instance->generic.data = instance->decoder.decode_data;
instance->decoder.decode_data = 0;
} else if(
instance->decoder.decode_count_bit ==
subghz_protocol_beninca_arc_const.min_count_bit_for_found) {
// Full data captured 128 bits
instance->generic.data_2 = instance->decoder.decode_data;
instance->generic.data_count_bit = instance->decoder.decode_count_bit;
instance->decoder.parser_step = BenincaARCDecoderStart;
if(instance->base.callback) {
instance->base.callback(&instance->base, instance->base.context);
}
break;
}
} else {
instance->decoder.parser_step = BenincaARCDecoderStart;
}
break;
case BenincaARCDecoderLowLevel:
if(!level) {
// Bit 1 is short and long timing = 300us HIGH (te_last) and 600us LOW
if((DURATION_DIFF(
instance->decoder.te_last, subghz_protocol_beninca_arc_const.te_short) <
subghz_protocol_beninca_arc_const.te_delta) &&
(DURATION_DIFF(duration, subghz_protocol_beninca_arc_const.te_long) <
subghz_protocol_beninca_arc_const.te_delta)) {
subghz_protocol_blocks_add_bit(&instance->decoder, 1);
instance->decoder.parser_step = BenincaARCDecoderHighLevel;
// Bit 0 is long and short timing = 600us HIGH (te_last) and 300us LOW
} else if(
(DURATION_DIFF(
instance->decoder.te_last, subghz_protocol_beninca_arc_const.te_long) <
subghz_protocol_beninca_arc_const.te_delta) &&
(DURATION_DIFF(duration, subghz_protocol_beninca_arc_const.te_short) <
subghz_protocol_beninca_arc_const.te_delta)) {
subghz_protocol_blocks_add_bit(&instance->decoder, 0);
instance->decoder.parser_step = BenincaARCDecoderHighLevel;
} else {
instance->decoder.parser_step = BenincaARCDecoderStart;
}
break;
} else {
instance->decoder.parser_step = BenincaARCDecoderStart;
break;
}
}
}
uint32_t subghz_protocol_decoder_beninca_arc_get_hash_data(void* context) {
furi_assert(context);
SubGhzProtocolDecoderBenincaARC* instance = context;
return subghz_protocol_blocks_get_hash_data_long(
&instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
}
SubGhzProtocolStatus subghz_protocol_decoder_beninca_arc_serialize(
void* context,
FlipperFormat* flipper_format,
SubGhzRadioPreset* preset) {
furi_assert(context);
SubGhzProtocolDecoderBenincaARC* instance = context;
SubGhzProtocolStatus ret =
subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
uint8_t key_data[sizeof(uint64_t)] = {0};
for(size_t i = 0; i < sizeof(uint64_t); i++) {
key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data_2 >> (i * 8)) & 0xFF;
}
if(!flipper_format_rewind(flipper_format)) {
FURI_LOG_E(TAG, "Rewind error");
ret = SubGhzProtocolStatusErrorParserOthers;
}
if((ret == SubGhzProtocolStatusOk) &&
!flipper_format_insert_or_update_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
FURI_LOG_E(TAG, "Unable to add Data");
ret = SubGhzProtocolStatusErrorParserOthers;
}
return ret;
}
SubGhzProtocolStatus
subghz_protocol_decoder_beninca_arc_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolDecoderBenincaARC* instance = context;
SubGhzProtocolStatus ret = SubGhzProtocolStatusError;
do {
ret = subghz_block_generic_deserialize_check_count_bit(
&instance->generic,
flipper_format,
subghz_protocol_beninca_arc_const.min_count_bit_for_found);
if(ret != SubGhzProtocolStatusOk) {
break;
}
if(!flipper_format_rewind(flipper_format)) {
FURI_LOG_E(TAG, "Rewind error");
ret = SubGhzProtocolStatusErrorParserOthers;
break;
}
uint8_t key_data[sizeof(uint64_t)] = {0};
if(!flipper_format_read_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
FURI_LOG_E(TAG, "Missing Data");
ret = SubGhzProtocolStatusErrorParserOthers;
break;
}
for(uint8_t i = 0; i < sizeof(uint64_t); i++) {
instance->generic.data_2 = instance->generic.data_2 << 8 | key_data[i];
}
} while(false);
return ret;
}
void subghz_protocol_decoder_beninca_arc_get_string(void* context, FuriString* output) {
furi_assert(context);
SubGhzProtocolDecoderBenincaARC* instance = context;
uint64_t middle_bytes_dec =
subghz_protocol_beninca_arc_decrypt(&instance->generic, instance->keystore);
// push protocol data to global variable
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 32;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
furi_string_printf(
output,
"%s %db\r\n"
"Key1:%08llX\r\n"
"Key2:%08llX\r\n"
"Sn:%08lX Btn:%02X\r\n"
"Mc:%0lX Cnt:%0lX\r\n"
"Fx:%04lX",
instance->base.protocol->name,
instance->generic.data_count_bit,
instance->generic.data,
instance->generic.data_2,
instance->generic.serial,
instance->generic.btn,
(uint32_t)(middle_bytes_dec & 0xFFFFFFFF),
instance->generic.cnt,
instance->generic.seed & 0xFFFF);
}

View File

@@ -0,0 +1,108 @@
#pragma once
#include "base.h"
#define SUBGHZ_PROTOCOL_BENINCA_ARC_NAME "Beninca ARC"
typedef struct SubGhzProtocolDecoderBenincaARC SubGhzProtocolDecoderBenincaARC;
typedef struct SubGhzProtocolEncoderBenincaARC SubGhzProtocolEncoderBenincaARC;
extern const SubGhzProtocolDecoder subghz_protocol_beninca_arc_decoder;
extern const SubGhzProtocolEncoder subghz_protocol_beninca_arc_encoder;
extern const SubGhzProtocol subghz_protocol_beninca_arc;
/**
* Allocate SubGhzProtocolEncoderBenincaARC.
* @param environment Pointer to a SubGhzEnvironment instance
* @return SubGhzProtocolEncoderBenincaARC* pointer to a SubGhzProtocolEncoderBenincaARC instance
*/
void* subghz_protocol_encoder_beninca_arc_alloc(SubGhzEnvironment* environment);
/**
* Free SubGhzProtocolEncoderBenincaARC.
* @param context Pointer to a SubGhzProtocolEncoderBenincaARC instance
*/
void subghz_protocol_encoder_beninca_arc_free(void* context);
/**
* Deserialize and generating an upload to send.
* @param context Pointer to a SubGhzProtocolEncoderBenincaARC instance
* @param flipper_format Pointer to a FlipperFormat instance
* @return true On success
*/
SubGhzProtocolStatus
subghz_protocol_encoder_beninca_arc_deserialize(void* context, FlipperFormat* flipper_format);
/**
* Forced transmission stop.
* @param context Pointer to a SubGhzProtocolEncoderBenincaARC instance
*/
void subghz_protocol_encoder_beninca_arc_stop(void* context);
/**
* Getting the level and duration of the upload to be loaded into DMA.
* @param context Pointer to a SubGhzProtocolEncoderBenincaARC instance
* @return LevelDuration
*/
LevelDuration subghz_protocol_encoder_beninca_arc_yield(void* context);
/**
* Allocate SubGhzProtocolDecoderBenincaARC.
* @param environment Pointer to a SubGhzEnvironment instance
* @return SubGhzProtocolDecoderBenincaARC* pointer to a SubGhzProtocolDecoderBenincaARC instance
*/
void* subghz_protocol_decoder_beninca_arc_alloc(SubGhzEnvironment* environment);
/**
* Free SubGhzProtocolDecoderBenincaARC.
* @param context Pointer to a SubGhzProtocolDecoderBenincaARC instance
*/
void subghz_protocol_decoder_beninca_arc_free(void* context);
/**
* Reset decoder SubGhzProtocolDecoderBenincaARC.
* @param context Pointer to a SubGhzProtocolDecoderBenincaARC instance
*/
void subghz_protocol_decoder_beninca_arc_reset(void* context);
/**
* Parse a raw sequence of levels and durations received from the air.
* @param context Pointer to a SubGhzProtocolDecoderBenincaARC instance
* @param level Signal level true-high false-low
* @param duration Duration of this level in, us
*/
void subghz_protocol_decoder_beninca_arc_feed(void* context, bool level, uint32_t duration);
/**
* Getting the hash sum of the last randomly received parcel.
* @param context Pointer to a SubGhzProtocolDecoderBenincaARC instance
* @return hash Hash sum
*/
uint32_t subghz_protocol_decoder_beninca_arc_get_hash_data(void* context);
/**
* Serialize data SubGhzProtocolDecoderBenincaARC.
* @param context Pointer to a SubGhzProtocolDecoderBenincaARC instance
* @param flipper_format Pointer to a FlipperFormat instance
* @param preset The modulation on which the signal was received, SubGhzRadioPreset
* @return status
*/
SubGhzProtocolStatus subghz_protocol_decoder_beninca_arc_serialize(
void* context,
FlipperFormat* flipper_format,
SubGhzRadioPreset* preset);
/**
* Deserialize data SubGhzProtocolDecoderBenincaARC.
* @param context Pointer to a SubGhzProtocolDecoderBenincaARC instance
* @param flipper_format Pointer to a FlipperFormat instance
* @return status
*/
SubGhzProtocolStatus
subghz_protocol_decoder_beninca_arc_deserialize(void* context, FlipperFormat* flipper_format);
/**
* Getting a textual representation of the received data.
* @param context Pointer to a SubGhzProtocolDecoderBenincaARC instance
* @param output Resulting text
*/
void subghz_protocol_decoder_beninca_arc_get_string(void* context, FuriString* output);

View File

@@ -171,7 +171,7 @@ SubGhzProtocolStatus
FURI_LOG_E(TAG, "Deserialize error"); FURI_LOG_E(TAG, "Deserialize error");
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -311,7 +311,7 @@ SubGhzProtocolStatus
res = SubGhzProtocolStatusErrorParserOthers; res = SubGhzProtocolStatusErrorParserOthers;
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -183,7 +183,7 @@ SubGhzProtocolStatus
ret = SubGhzProtocolStatusErrorValueBitCount; ret = SubGhzProtocolStatusErrorValueBitCount;
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -192,12 +192,17 @@ static void subghz_protocol_encoder_came_atomo_get_upload(
if(came_atomo_counter_mode == 0) { if(came_atomo_counter_mode == 0) {
// Check for OFEX (overflow experimental) mode // Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { // standart counter mode. PULL data from subghz_block_generic_global variables
instance->generic.cnt = 0; if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
} else { // if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
} }
} else { } else {
//OFFEX mode
if((instance->generic.cnt + 0x1) > 0xFFFF) { if((instance->generic.cnt + 0x1) > 0xFFFF) {
instance->generic.cnt = 0; instance->generic.cnt = 0;
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) { } else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
@@ -371,7 +376,7 @@ SubGhzProtocolStatus
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
@@ -822,6 +827,12 @@ void subghz_protocol_decoder_came_atomo_get_string(void* context, FuriString* ou
uint32_t code_found_hi = instance->generic.data >> 32; uint32_t code_found_hi = instance->generic.data >> 32;
uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff;
// push protocol data to global variable
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
//
furi_string_cat_printf( furi_string_cat_printf(
output, output,
"%s %db\r\n" "%s %db\r\n"

View File

@@ -256,7 +256,7 @@ SubGhzProtocolStatus
if(res != SubGhzProtocolStatusOk) { if(res != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -225,7 +225,7 @@ SubGhzProtocolStatus
ret = SubGhzProtocolStatusErrorValueBitCount; ret = SubGhzProtocolStatusErrorValueBitCount;
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -170,7 +170,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -209,7 +209,7 @@ SubGhzProtocolStatus
ret = SubGhzProtocolStatusErrorValueBitCount; ret = SubGhzProtocolStatusErrorValueBitCount;
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -151,7 +151,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -161,7 +161,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -143,7 +143,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -140,32 +140,37 @@ static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* inst
uint8_t data_prg[8]; uint8_t data_prg[8];
data_prg[0] = 0x00; data_prg[0] = 0x00;
// faac slh protocol have 20-bit counter so we take only 20 bits from mult (by AND 0xFFFFF)
if(allow_zero_seed || (instance->generic.seed != 0x0)) { if(allow_zero_seed || (instance->generic.seed != 0x0)) {
// check OFEX mode // check OFEX mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
if((instance->generic.cnt + // standart counter mode. PULL data from subghz_block_generic_global variables
(furi_hal_subghz_get_rolling_counter_mult() & 0xFFFFF)) > 0xFFFFF) { if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
instance->generic.cnt = 0; // if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
} else { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >
instance->generic.cnt += 0xFFFFF) {
(furi_hal_subghz_get_rolling_counter_mult() & 0xFFFFF); instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
} }
} else { } else {
// to do OFEX mode // TODO: OFEX mode
instance->generic.cnt += 1; instance->generic.cnt += 1;
} }
if(temp_counter_backup != 0x0) { if(temp_counter_backup != 0x0) {
// check OFEX mode // check OFEX mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
if((temp_counter_backup + // standart counter mode. PULL data from subghz_block_generic_global variables
(furi_hal_subghz_get_rolling_counter_mult() & 0xFFFFF)) > 0xFFFFF) { if(!subghz_block_generic_global_counter_override_get(&temp_counter_backup)) {
temp_counter_backup = 0; // if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
} else { if((temp_counter_backup + furi_hal_subghz_get_rolling_counter_mult()) >
temp_counter_backup += 0xFFFFF) {
(furi_hal_subghz_get_rolling_counter_mult() & 0xFFFFF); temp_counter_backup = 0;
} else {
temp_counter_backup += furi_hal_subghz_get_rolling_counter_mult();
}
} }
} else { } else {
// todo OFEX mode // todo OFEX mode
@@ -236,17 +241,19 @@ static bool subghz_protocol_faac_slh_gen_data(SubGhzProtocolEncoderFaacSLH* inst
fixx[i] = (fix >> (shiftby -= 4)) & 0xF; fixx[i] = (fix >> (shiftby -= 4)) & 0xF;
} }
// faac slh protocol have 20-bit counter so we take only 20 bits from mult (by AND 0xFFFFF)
if(allow_zero_seed || (instance->generic.seed != 0x0)) { if(allow_zero_seed || (instance->generic.seed != 0x0)) {
// check OFEX mode // check OFEX mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
if((instance->generic.cnt + (furi_hal_subghz_get_rolling_counter_mult() & 0xFFFFF)) > // standart counter mode. PULL data from subghz_block_generic_global variables
0xFFFFF) { if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
instance->generic.cnt = 0; // if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
} else { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >
instance->generic.cnt += (furi_hal_subghz_get_rolling_counter_mult() & 0xFFFFF); 0xFFFFF) {
instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
} }
} else { } else {
// OFEX mode // OFEX mode
if(instance->generic.cnt < 0xFFFFF) { if(instance->generic.cnt < 0xFFFFF) {
@@ -393,7 +400,7 @@ SubGhzProtocolStatus
subghz_protocol_faac_slh_check_remote_controller( subghz_protocol_faac_slh_check_remote_controller(
&instance->generic, instance->keystore, &instance->manufacture_name); &instance->generic, instance->keystore, &instance->manufacture_name);
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
@@ -747,6 +754,12 @@ void subghz_protocol_decoder_faac_slh_get_string(void* context, FuriString* outp
instance->generic.btn, instance->generic.btn,
instance->generic.serial); instance->generic.serial);
} else { } else {
// push protocol data to global variable
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 20;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
//
furi_string_cat_printf( furi_string_cat_printf(
output, output,
"%s %dbit\r\n" "%s %dbit\r\n"

View File

@@ -163,7 +163,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -261,7 +261,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -144,7 +144,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -149,11 +149,14 @@ static void subghz_protocol_encoder_hay21_get_upload(SubGhzProtocolEncoderHay21*
// Counter increment // Counter increment
// Check for OFEX (overflow experimental) mode // Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
//not matter how big and long mult - we take only 4 bits ( AND 0xF) beacose hay21 counter have only 4 bits long (0..F) // standart counter mode. PULL data from subghz_block_generic_global variables
if((instance->generic.cnt + (furi_hal_subghz_get_rolling_counter_mult() & 0xF)) > 0xF) { if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
instance->generic.cnt = 0; // if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
} else { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xF) {
instance->generic.cnt += (furi_hal_subghz_get_rolling_counter_mult() & 0xF); instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
} }
} else { } else {
// OFEX mode // OFEX mode
@@ -266,7 +269,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
@@ -462,6 +465,11 @@ void subghz_protocol_decoder_hay21_get_string(void* context, FuriString* output)
// Parse serial, button, counter // Parse serial, button, counter
subghz_protocol_hay21_remote_controller(&instance->generic); subghz_protocol_hay21_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 8;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
furi_string_cat_printf( furi_string_cat_printf(
output, output,
"%s - %dbit\r\n" "%s - %dbit\r\n"

View File

@@ -257,7 +257,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -157,7 +157,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -172,7 +172,7 @@ SubGhzProtocolStatus
ret = SubGhzProtocolStatusErrorParserTe; ret = SubGhzProtocolStatusErrorParserTe;
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -213,7 +213,7 @@ SubGhzProtocolStatus
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -160,7 +160,7 @@ SubGhzProtocolStatus subghz_protocol_encoder_honeywell_wdb_deserialize(
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -155,7 +155,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -178,7 +178,7 @@ SubGhzProtocolStatus subghz_protocol_encoder_intertechno_v3_deserialize(
ret = SubGhzProtocolStatusErrorValueBitCount; ret = SubGhzProtocolStatusErrorValueBitCount;
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -189,10 +189,15 @@ static bool subghz_protocol_keeloq_gen_data(
if(keeloq_counter_mode == 0) { if(keeloq_counter_mode == 0) {
// Check for OFEX (overflow experimental) mode // Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { // standart counter mode. PULL data from subghz_block_generic_global variables
instance->generic.cnt = 0; if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
} else { // if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) >
0xFFFF) {
instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
} }
} else { } else {
if((instance->generic.cnt + 0x1) > 0xFFFF) { if((instance->generic.cnt + 0x1) > 0xFFFF) {
@@ -301,11 +306,13 @@ static bool subghz_protocol_keeloq_gen_data(
(strcmp(instance->manufacture_name, "Rosh") == 0) || (strcmp(instance->manufacture_name, "Rosh") == 0) ||
(strcmp(instance->manufacture_name, "Rossi") == 0) || (strcmp(instance->manufacture_name, "Rossi") == 0) ||
(strcmp(instance->manufacture_name, "Pecinin") == 0) || (strcmp(instance->manufacture_name, "Pecinin") == 0) ||
(strcmp(instance->manufacture_name, "Steelmate") == 0)) { (strcmp(instance->manufacture_name, "Steelmate") == 0) ||
(strcmp(instance->manufacture_name, "Cardin_S449") == 0)) {
// DTM Neo, Came_Space uses 12bit serial -> simple learning // DTM Neo, Came_Space uses 12bit serial -> simple learning
// FAAC_RC,XT , Mutanco_Mutancode, Genius_Bravo, GSN 12bit serial -> normal learning // FAAC_RC,XT , Mutanco_Mutancode, Genius_Bravo, GSN 12bit serial -> normal learning
// Rosh, Rossi, Pecinin -> 12bit serial - simple learning // Rosh, Rossi, Pecinin -> 12bit serial - simple learning
// Steelmate -> 12bit serial - normal learning // Steelmate -> 12bit serial - normal learning
// Cardin_S449 -> 12bit serial - normal learning
decrypt = btn << 28 | (instance->generic.serial & 0xFFF) << 16 | decrypt = btn << 28 | (instance->generic.serial & 0xFFF) << 16 |
instance->generic.cnt; instance->generic.cnt;
} else if( } else if(
@@ -507,12 +514,23 @@ static bool
(strcmp(instance->manufacture_name, "Monarch") == 0) || (strcmp(instance->manufacture_name, "Monarch") == 0) ||
(strcmp(instance->manufacture_name, "NICE_Smilo") == 0)) { (strcmp(instance->manufacture_name, "NICE_Smilo") == 0)) {
klq_last_custom_btn = 0xB; klq_last_custom_btn = 0xB;
} else if((strcmp(instance->manufacture_name, "Novoferm") == 0)) { } else if(
(strcmp(instance->manufacture_name, "Novoferm") == 0) ||
(strcmp(instance->manufacture_name, "Stilmatic") == 0)) {
klq_last_custom_btn = 0x9; klq_last_custom_btn = 0x9;
} else if((strcmp(instance->manufacture_name, "EcoStar") == 0)) { } else if(
(strcmp(instance->manufacture_name, "EcoStar") == 0) ||
(strcmp(instance->manufacture_name, "Sommer") == 0)) {
klq_last_custom_btn = 0x6; klq_last_custom_btn = 0x6;
} else if((strcmp(instance->manufacture_name, "AN-Motors") == 0)) { } else if((strcmp(instance->manufacture_name, "AN-Motors") == 0)) {
klq_last_custom_btn = 0xC; klq_last_custom_btn = 0xC;
} else if((strcmp(instance->manufacture_name, "Cardin_S449") == 0)) {
klq_last_custom_btn = 0xD;
}
uint32_t gap_duration = subghz_protocol_keeloq_const.te_short * 40;
if((strcmp(instance->manufacture_name, "Sommer") == 0)) {
gap_duration = subghz_protocol_keeloq_const.te_short * 29;
} }
btn = subghz_protocol_keeloq_get_btn_code(klq_last_custom_btn); btn = subghz_protocol_keeloq_get_btn_code(klq_last_custom_btn);
@@ -569,8 +587,7 @@ static bool
// send end // send end
instance->encoder.upload[index++] = instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_keeloq_const.te_short); level_duration_make(true, (uint32_t)subghz_protocol_keeloq_const.te_short);
instance->encoder.upload[index++] = instance->encoder.upload[index++] = level_duration_make(false, gap_duration);
level_duration_make(false, (uint32_t)subghz_protocol_keeloq_const.te_short * 40);
return true; return true;
} }
@@ -613,6 +630,21 @@ SubGhzProtocolStatus
flipper_format, "Manufacture", instance->manufacture_from_file)) { flipper_format, "Manufacture", instance->manufacture_from_file)) {
instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file);
instance->keystore->mfname = instance->manufacture_name; instance->keystore->mfname = instance->manufacture_name;
// Compatibility fixes for old names in user files
if(strcmp(instance->manufacture_name, "Sommer(fsk476)") == 0) {
instance->manufacture_name = "Sommer";
instance->keystore->mfname = instance->manufacture_name;
if(!flipper_format_rewind(flipper_format)) {
FURI_LOG_E(TAG, "Rewind error");
break;
}
if(!flipper_format_update_string_cstr(
flipper_format, "Manufacture", instance->manufacture_name)) {
FURI_LOG_E(TAG, "DECODER: Unable to fix Sommer manufacture name");
ret = SubGhzProtocolStatusError;
break;
}
}
} else { } else {
FURI_LOG_D(TAG, "ENCODER: Missing Manufacture"); FURI_LOG_D(TAG, "ENCODER: Missing Manufacture");
} }
@@ -637,7 +669,7 @@ SubGhzProtocolStatus
subghz_protocol_keeloq_check_remote_controller( subghz_protocol_keeloq_check_remote_controller(
&instance->generic, instance->keystore, &instance->manufacture_name); &instance->generic, instance->keystore, &instance->manufacture_name);
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
@@ -1264,6 +1296,21 @@ SubGhzProtocolStatus
flipper_format, "Manufacture", instance->manufacture_from_file)) { flipper_format, "Manufacture", instance->manufacture_from_file)) {
instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file);
instance->keystore->mfname = instance->manufacture_name; instance->keystore->mfname = instance->manufacture_name;
// Compatibility fixes for old names in user files
if(strcmp(instance->manufacture_name, "Sommer(fsk476)") == 0) {
instance->manufacture_name = "Sommer";
instance->keystore->mfname = instance->manufacture_name;
if(!flipper_format_rewind(flipper_format)) {
FURI_LOG_E(TAG, "Rewind error");
break;
}
if(!flipper_format_update_string_cstr(
flipper_format, "Manufacture", instance->manufacture_name)) {
FURI_LOG_E(TAG, "DECODER: Unable to fix Sommer manufacture name");
res = SubGhzProtocolStatusError;
break;
}
}
} else { } else {
FURI_LOG_D(TAG, "DECODER: Missing Manufacture"); FURI_LOG_D(TAG, "DECODER: Missing Manufacture");
} }
@@ -1325,6 +1372,12 @@ static uint8_t subghz_protocol_keeloq_get_btn_code(uint8_t last_btn_code) {
case 0xF: case 0xF:
btn = 0x1; btn = 0x1;
break; break;
case 0x9:
btn = 0x2;
break;
case 0x6:
btn = 0x2;
break;
default: default:
btn = 0x1; btn = 0x1;
@@ -1350,6 +1403,12 @@ static uint8_t subghz_protocol_keeloq_get_btn_code(uint8_t last_btn_code) {
case 0xF: case 0xF:
btn = 0x4; btn = 0x4;
break; break;
case 0x9:
btn = 0x4;
break;
case 0x6:
btn = 0x4;
break;
default: default:
btn = 0x4; btn = 0x4;
@@ -1375,6 +1434,12 @@ static uint8_t subghz_protocol_keeloq_get_btn_code(uint8_t last_btn_code) {
case 0xF: case 0xF:
btn = 0x8; btn = 0x8;
break; break;
case 0x9:
btn = 0x6;
break;
case 0x6:
btn = 0x9;
break;
default: default:
btn = 0x8; btn = 0x8;
@@ -1400,9 +1465,15 @@ static uint8_t subghz_protocol_keeloq_get_btn_code(uint8_t last_btn_code) {
case 0xF: case 0xF:
btn = 0x2; btn = 0x2;
break; break;
case 0x9:
btn = last_btn_code;
break;
case 0x6:
btn = last_btn_code;
break;
default: default:
btn = 0x2; btn = last_btn_code;
break; break;
} }
} }
@@ -1426,6 +1497,9 @@ void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff; uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
if(strcmp(instance->manufacture_name, "BFT") == 0) { if(strcmp(instance->manufacture_name, "BFT") == 0) {
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
furi_string_cat_printf( furi_string_cat_printf(
output, output,
"%s %dbit\r\n" "%s %dbit\r\n"
@@ -1461,6 +1535,9 @@ void subghz_protocol_decoder_keeloq_get_string(void* context, FuriString* output
instance->generic.btn, instance->generic.btn,
instance->manufacture_name); instance->manufacture_name);
} else { } else {
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
furi_string_cat_printf( furi_string_cat_printf(
output, output,
"%s %dbit\r\n" "%s %dbit\r\n"

View File

@@ -25,6 +25,7 @@
#define KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_1 6u #define KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_1 6u
#define KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_2 7u #define KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_2 7u
#define KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_3 8u #define KEELOQ_LEARNING_MAGIC_SERIAL_TYPE_3 8u
// #define BENINCA_ARC_KEY_TYPE 9u -- RESERVED
/** /**
* Simple Learning Encrypt * Simple Learning Encrypt

View File

@@ -1,276 +0,0 @@
#include "kia.h"
#include "../blocks/const.h"
#include "../blocks/decoder.h"
#include "../blocks/encoder.h"
#include "../blocks/generic.h"
#include "../blocks/math.h"
#define TAG "SubGhzProtocoKia"
static const SubGhzBlockConst subghz_protocol_kia_const = {
.te_short = 250,
.te_long = 500,
.te_delta = 100,
.min_count_bit_for_found = 61,
};
struct SubGhzProtocolDecoderKIA {
SubGhzProtocolDecoderBase base;
SubGhzBlockDecoder decoder;
SubGhzBlockGeneric generic;
uint16_t header_count;
};
struct SubGhzProtocolEncoderKIA {
SubGhzProtocolEncoderBase base;
SubGhzProtocolBlockEncoder encoder;
SubGhzBlockGeneric generic;
};
typedef enum {
KIADecoderStepReset = 0,
KIADecoderStepCheckPreambula,
KIADecoderStepSaveDuration,
KIADecoderStepCheckDuration,
} KIADecoderStep;
const SubGhzProtocolDecoder subghz_protocol_kia_decoder = {
.alloc = subghz_protocol_decoder_kia_alloc,
.free = subghz_protocol_decoder_kia_free,
.feed = subghz_protocol_decoder_kia_feed,
.reset = subghz_protocol_decoder_kia_reset,
.get_hash_data = NULL,
.get_hash_data_long = subghz_protocol_decoder_kia_get_hash_data,
.serialize = subghz_protocol_decoder_kia_serialize,
.deserialize = subghz_protocol_decoder_kia_deserialize,
.get_string = subghz_protocol_decoder_kia_get_string,
.get_string_brief = NULL,
};
const SubGhzProtocolEncoder subghz_protocol_kia_encoder = {
.alloc = NULL,
.free = NULL,
.deserialize = NULL,
.stop = NULL,
.yield = NULL,
};
const SubGhzProtocol subghz_protocol_kia = {
.name = SUBGHZ_PROTOCOL_KIA_NAME,
.type = SubGhzProtocolTypeDynamic,
.flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_FM | SubGhzProtocolFlag_Decodable,
.decoder = &subghz_protocol_kia_decoder,
.encoder = &subghz_protocol_kia_encoder,
.filter = SubGhzProtocolFilter_Cars,
};
void* subghz_protocol_decoder_kia_alloc(SubGhzEnvironment* environment) {
UNUSED(environment);
SubGhzProtocolDecoderKIA* instance = malloc(sizeof(SubGhzProtocolDecoderKIA));
instance->base.protocol = &subghz_protocol_kia;
instance->generic.protocol_name = instance->base.protocol->name;
return instance;
}
void subghz_protocol_decoder_kia_free(void* context) {
furi_assert(context);
SubGhzProtocolDecoderKIA* instance = context;
free(instance);
}
void subghz_protocol_decoder_kia_reset(void* context) {
furi_assert(context);
SubGhzProtocolDecoderKIA* instance = context;
instance->decoder.parser_step = KIADecoderStepReset;
}
void subghz_protocol_decoder_kia_feed(void* context, bool level, uint32_t duration) {
furi_assert(context);
SubGhzProtocolDecoderKIA* instance = context;
switch(instance->decoder.parser_step) {
case KIADecoderStepReset:
if((level) && (DURATION_DIFF(duration, subghz_protocol_kia_const.te_short) <
subghz_protocol_kia_const.te_delta)) {
instance->decoder.parser_step = KIADecoderStepCheckPreambula;
instance->decoder.te_last = duration;
instance->header_count = 0;
}
break;
case KIADecoderStepCheckPreambula:
if(level) {
if((DURATION_DIFF(duration, subghz_protocol_kia_const.te_short) <
subghz_protocol_kia_const.te_delta) ||
(DURATION_DIFF(duration, subghz_protocol_kia_const.te_long) <
subghz_protocol_kia_const.te_delta)) {
instance->decoder.te_last = duration;
} else {
instance->decoder.parser_step = KIADecoderStepReset;
}
} else if(
(DURATION_DIFF(duration, subghz_protocol_kia_const.te_short) <
subghz_protocol_kia_const.te_delta) &&
(DURATION_DIFF(instance->decoder.te_last, subghz_protocol_kia_const.te_short) <
subghz_protocol_kia_const.te_delta)) {
// Found header
instance->header_count++;
break;
} else if(
(DURATION_DIFF(duration, subghz_protocol_kia_const.te_long) <
subghz_protocol_kia_const.te_delta) &&
(DURATION_DIFF(instance->decoder.te_last, subghz_protocol_kia_const.te_long) <
subghz_protocol_kia_const.te_delta)) {
// Found start bit
if(instance->header_count > 15) {
instance->decoder.parser_step = KIADecoderStepSaveDuration;
instance->decoder.decode_data = 0;
instance->decoder.decode_count_bit = 1;
subghz_protocol_blocks_add_bit(&instance->decoder, 1);
} else {
instance->decoder.parser_step = KIADecoderStepReset;
}
} else {
instance->decoder.parser_step = KIADecoderStepReset;
}
break;
case KIADecoderStepSaveDuration:
if(level) {
if(duration >=
(subghz_protocol_kia_const.te_long + subghz_protocol_kia_const.te_delta * 2UL)) {
//Found stop bit
instance->decoder.parser_step = KIADecoderStepReset;
if(instance->decoder.decode_count_bit ==
subghz_protocol_kia_const.min_count_bit_for_found) {
instance->generic.data = instance->decoder.decode_data;
instance->generic.data_count_bit = instance->decoder.decode_count_bit;
if(instance->base.callback)
instance->base.callback(&instance->base, instance->base.context);
}
instance->decoder.decode_data = 0;
instance->decoder.decode_count_bit = 0;
break;
} else {
instance->decoder.te_last = duration;
instance->decoder.parser_step = KIADecoderStepCheckDuration;
}
} else {
instance->decoder.parser_step = KIADecoderStepReset;
}
break;
case KIADecoderStepCheckDuration:
if(!level) {
if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_kia_const.te_short) <
subghz_protocol_kia_const.te_delta) &&
(DURATION_DIFF(duration, subghz_protocol_kia_const.te_short) <
subghz_protocol_kia_const.te_delta)) {
subghz_protocol_blocks_add_bit(&instance->decoder, 0);
instance->decoder.parser_step = KIADecoderStepSaveDuration;
} else if(
(DURATION_DIFF(instance->decoder.te_last, subghz_protocol_kia_const.te_long) <
subghz_protocol_kia_const.te_delta) &&
(DURATION_DIFF(duration, subghz_protocol_kia_const.te_long) <
subghz_protocol_kia_const.te_delta)) {
subghz_protocol_blocks_add_bit(&instance->decoder, 1);
instance->decoder.parser_step = KIADecoderStepSaveDuration;
} else {
instance->decoder.parser_step = KIADecoderStepReset;
}
} else {
instance->decoder.parser_step = KIADecoderStepReset;
}
break;
}
}
uint8_t subghz_protocol_kia_crc8(uint8_t* data, size_t len) {
uint8_t crc = 0x08;
size_t i, j;
for(i = 0; i < len; i++) {
crc ^= data[i];
for(j = 0; j < 8; j++) {
if((crc & 0x80) != 0)
crc = (uint8_t)((crc << 1) ^ 0x7F);
else
crc <<= 1;
}
}
return crc;
}
/**
* Analysis of received data
* @param instance Pointer to a SubGhzBlockGeneric* instance
*/
static void subghz_protocol_kia_check_remote_controller(SubGhzBlockGeneric* instance) {
/*
* 0x0F 0112 43B04EC 1 7D
* 0x0F 0113 43B04EC 1 DF
* 0x0F 0114 43B04EC 1 30
* 0x0F 0115 43B04EC 2 13
* 0x0F 0116 43B04EC 3 F5
* CNT Serial K CRC8 Kia (CRC8, poly 0x7f, start_crc 0x08)
*/
instance->serial = (uint32_t)((instance->data >> 12) & 0x0FFFFFFF);
instance->btn = (instance->data >> 8) & 0x0F;
instance->cnt = (instance->data >> 40) & 0xFFFF;
}
uint32_t subghz_protocol_decoder_kia_get_hash_data(void* context) {
furi_assert(context);
SubGhzProtocolDecoderKIA* instance = context;
return subghz_protocol_blocks_get_hash_data_long(
&instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
}
SubGhzProtocolStatus subghz_protocol_decoder_kia_serialize(
void* context,
FlipperFormat* flipper_format,
SubGhzRadioPreset* preset) {
furi_assert(context);
SubGhzProtocolDecoderKIA* instance = context;
return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
}
SubGhzProtocolStatus
subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolDecoderKIA* instance = context;
return subghz_block_generic_deserialize_check_count_bit(
&instance->generic, flipper_format, subghz_protocol_kia_const.min_count_bit_for_found);
}
void subghz_protocol_decoder_kia_get_string(void* context, FuriString* output) {
furi_assert(context);
SubGhzProtocolDecoderKIA* instance = context;
subghz_protocol_kia_check_remote_controller(&instance->generic);
uint32_t code_found_hi = instance->generic.data >> 32;
uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff;
// use 'Cntr:' instead of 'Cnt:' to exclude this protocol counter from Counter edit
furi_string_cat_printf(
output,
"%s %dbit\r\n"
"Key:%08lX%08lX\r\n"
"Sn:%07lX Btn:%X\r\n"
"Cntr:%04lX\r\n",
instance->generic.protocol_name,
instance->generic.data_count_bit,
code_found_hi,
code_found_lo,
instance->generic.serial,
instance->generic.btn,
instance->generic.cnt);
}

View File

@@ -1,74 +0,0 @@
#pragma once
#include "base.h"
#define SUBGHZ_PROTOCOL_KIA_NAME "KIA Seed"
typedef struct SubGhzProtocolDecoderKIA SubGhzProtocolDecoderKIA;
typedef struct SubGhzProtocolEncoderKIA SubGhzProtocolEncoderKIA;
extern const SubGhzProtocolDecoder subghz_protocol_kia_decoder;
extern const SubGhzProtocolEncoder subghz_protocol_kia_encoder;
extern const SubGhzProtocol subghz_protocol_kia;
/**
* Allocate SubGhzProtocolDecoderKIA.
* @param environment Pointer to a SubGhzEnvironment instance
* @return SubGhzProtocolDecoderKIA* pointer to a SubGhzProtocolDecoderKIA instance
*/
void* subghz_protocol_decoder_kia_alloc(SubGhzEnvironment* environment);
/**
* Free SubGhzProtocolDecoderKIA.
* @param context Pointer to a SubGhzProtocolDecoderKIA instance
*/
void subghz_protocol_decoder_kia_free(void* context);
/**
* Reset decoder SubGhzProtocolDecoderKIA.
* @param context Pointer to a SubGhzProtocolDecoderKIA instance
*/
void subghz_protocol_decoder_kia_reset(void* context);
/**
* Parse a raw sequence of levels and durations received from the air.
* @param context Pointer to a SubGhzProtocolDecoderKIA instance
* @param level Signal level true-high false-low
* @param duration Duration of this level in, us
*/
void subghz_protocol_decoder_kia_feed(void* context, bool level, uint32_t duration);
/**
* Getting the hash sum of the last randomly received parcel.
* @param context Pointer to a SubGhzProtocolDecoderKIA instance
* @return hash Hash sum
*/
uint32_t subghz_protocol_decoder_kia_get_hash_data(void* context);
/**
* Serialize data SubGhzProtocolDecoderKIA.
* @param context Pointer to a SubGhzProtocolDecoderKIA instance
* @param flipper_format Pointer to a FlipperFormat instance
* @param preset The modulation on which the signal was received, SubGhzRadioPreset
* @return status
*/
SubGhzProtocolStatus subghz_protocol_decoder_kia_serialize(
void* context,
FlipperFormat* flipper_format,
SubGhzRadioPreset* preset);
/**
* Deserialize data SubGhzProtocolDecoderKIA.
* @param context Pointer to a SubGhzProtocolDecoderKIA instance
* @param flipper_format Pointer to a FlipperFormat instance
* @return status
*/
SubGhzProtocolStatus
subghz_protocol_decoder_kia_deserialize(void* context, FlipperFormat* flipper_format);
/**
* Getting a textual representation of the received data.
* @param context Pointer to a SubGhzProtocolDecoderKIA instance
* @param output Resulting text
*/
void subghz_protocol_decoder_kia_get_string(void* context, FuriString* output);

View File

@@ -8,6 +8,8 @@
#include "../blocks/generic.h" #include "../blocks/generic.h"
#include "../blocks/math.h" #include "../blocks/math.h"
#include "../blocks/custom_btn_i.h"
#define TAG "SubGhzProtocoKingGatesStylo4k" #define TAG "SubGhzProtocoKingGatesStylo4k"
static const SubGhzBlockConst subghz_protocol_kinggates_stylo_4k_const = { static const SubGhzBlockConst subghz_protocol_kinggates_stylo_4k_const = {
@@ -86,6 +88,13 @@ static void subghz_protocol_kinggates_stylo_4k_remote_controller(
SubGhzBlockGeneric* instance, SubGhzBlockGeneric* instance,
SubGhzKeystore* keystore); SubGhzKeystore* keystore);
/**
* Defines the button value for the current btn_id
* Basic set | 0xE | 0xD | 0xB | 0x7 |
* @return Button code
*/
static uint8_t subghz_protocol_kinggates_stylo_4k_get_btn_code(void);
void* subghz_protocol_encoder_kinggates_stylo_4k_alloc(SubGhzEnvironment* environment) { void* subghz_protocol_encoder_kinggates_stylo_4k_alloc(SubGhzEnvironment* environment) {
SubGhzProtocolEncoderKingGates_stylo_4k* instance = SubGhzProtocolEncoderKingGates_stylo_4k* instance =
malloc(sizeof(SubGhzProtocolEncoderKingGates_stylo_4k)); malloc(sizeof(SubGhzProtocolEncoderKingGates_stylo_4k));
@@ -140,29 +149,23 @@ LevelDuration subghz_protocol_encoder_kinggates_stylo_4k_yield(void* context) {
static bool subghz_protocol_kinggates_stylo_4k_gen_data( static bool subghz_protocol_kinggates_stylo_4k_gen_data(
SubGhzProtocolEncoderKingGates_stylo_4k* instance, SubGhzProtocolEncoderKingGates_stylo_4k* instance,
uint8_t btn) { uint8_t btn) {
UNUSED(btn); // Save original button for later use
uint32_t hop = subghz_protocol_blocks_reverse_key(instance->generic.data_2 >> 4, 32); if(subghz_custom_btn_get_original() == 0) {
uint64_t fix = subghz_protocol_blocks_reverse_key(instance->generic.data, 53); subghz_custom_btn_set_original(btn);
int res = 0; }
uint32_t decrypt = 0;
for btn = subghz_protocol_kinggates_stylo_4k_get_btn_code();
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
res = strcmp(furi_string_get_cstr(manufacture_code->name), "Kingates_Stylo4k");
if(res == 0) {
//Simple Learning
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
break;
}
}
instance->generic.cnt = decrypt & 0xFFFF;
// Check for OFEX (overflow experimental) mode // Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { // standart counter mode. PULL data from subghz_block_generic_global variables
instance->generic.cnt = 0; if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
} else { // if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
} }
} else { } else {
if((instance->generic.cnt + 0x1) > 0xFFFF) { if((instance->generic.cnt + 0x1) > 0xFFFF) {
@@ -174,18 +177,21 @@ static bool subghz_protocol_kinggates_stylo_4k_gen_data(
} }
} }
instance->generic.btn = (fix >> 17) & 0x0F; // hop is encrypted part
instance->generic.serial = ((fix >> 5) & 0xFFFF0000) | (fix & 0xFFFF); uint32_t hop = (uint64_t)btn << 28 | (((uint32_t)0x0C) << 24) |
((instance->generic.serial & 0xFF) << 16) | (instance->generic.cnt & 0xFFFF);
uint32_t data = (decrypt & 0xFFFF0000) | instance->generic.cnt; uint64_t fix = ((uint64_t)((instance->generic.serial >> 16) & 0xFFFF) << 21) |
(uint64_t)btn << 17 | 0b1 << 16 | (instance->generic.serial & 0xFFFF);
instance->generic.data = subghz_protocol_blocks_reverse_key(fix, 53);
uint64_t encrypt = 0; uint64_t encrypt = 0;
for for
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) { M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
res = strcmp(furi_string_get_cstr(manufacture_code->name), "Kingates_Stylo4k"); if(strcmp(furi_string_get_cstr(manufacture_code->name), "Kingates_Stylo4k") == 0) {
if(res == 0) { // Simple Learning
//Simple Learning encrypt = subghz_protocol_keeloq_common_encrypt(hop, manufacture_code->key);
encrypt = subghz_protocol_keeloq_common_encrypt(data, manufacture_code->key);
encrypt = subghz_protocol_blocks_reverse_key(encrypt, 32); encrypt = subghz_protocol_blocks_reverse_key(encrypt, 32);
instance->generic.data_2 = encrypt << 4; instance->generic.data_2 = encrypt << 4;
return true; return true;
@@ -195,6 +201,63 @@ static bool subghz_protocol_kinggates_stylo_4k_gen_data(
return false; return false;
} }
bool subghz_protocol_kinggates_stylo_4k_create_data(
void* context,
FlipperFormat* flipper_format,
uint32_t serial,
uint8_t btn,
uint16_t cnt,
SubGhzRadioPreset* preset) {
furi_assert(context);
SubGhzProtocolEncoderKingGates_stylo_4k* instance = context;
instance->generic.serial = serial;
instance->generic.cnt = cnt;
instance->generic.btn = btn;
instance->generic.data_count_bit = 89;
uint32_t decrypt = instance->generic.btn << 28 | (((uint32_t)0x0C) << 24) |
((instance->generic.serial & 0xFF) << 16) |
(instance->generic.cnt & 0xFFFF);
uint64_t encrypt = 0;
for
M_EACH(manufacture_code, *subghz_keystore_get_data(instance->keystore), SubGhzKeyArray_t) {
if(strcmp(furi_string_get_cstr(manufacture_code->name), "Kingates_Stylo4k") == 0) {
// Simple Learning
encrypt = subghz_protocol_keeloq_common_encrypt(decrypt, manufacture_code->key);
encrypt = subghz_protocol_blocks_reverse_key(encrypt, 32);
instance->generic.data_2 = encrypt << 4;
break;
}
}
uint64_t fix = ((uint64_t)((instance->generic.serial >> 16) & 0xFFFF) << 21) |
instance->generic.btn << 17 | 0b1 << 16 | (instance->generic.serial & 0xFFFF);
instance->generic.data = subghz_protocol_blocks_reverse_key(fix, 53);
SubGhzProtocolStatus res =
subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
uint8_t key_data[sizeof(uint64_t)] = {0};
for(size_t i = 0; i < sizeof(uint64_t); i++) {
key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data_2 >> (i * 8)) & 0xFF;
}
if(!flipper_format_rewind(flipper_format)) {
FURI_LOG_E(TAG, "Rewind error");
res = SubGhzProtocolStatusErrorParserOthers;
}
if((res == SubGhzProtocolStatusOk) &&
!flipper_format_insert_or_update_hex(flipper_format, "Data", key_data, sizeof(uint64_t))) {
FURI_LOG_E(TAG, "Unable to add Data2");
res = SubGhzProtocolStatusErrorParserOthers;
}
return res == SubGhzProtocolStatusOk;
}
/** /**
* Generating an upload from data. * Generating an upload from data.
* @param instance Pointer to a SubGhzProtocolEncoderKingGates_stylo_4k instance * @param instance Pointer to a SubGhzProtocolEncoderKingGates_stylo_4k instance
@@ -283,10 +346,7 @@ SubGhzProtocolStatus subghz_protocol_encoder_kinggates_stylo_4k_deserialize(
break; break;
} }
subghz_protocol_kinggates_stylo_4k_remote_controller( // Optional value
&instance->generic, instance->keystore);
//optional parameter parameter
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
@@ -305,6 +365,9 @@ SubGhzProtocolStatus subghz_protocol_encoder_kinggates_stylo_4k_deserialize(
instance->generic.data_2 = instance->generic.data_2 << 8 | key_data[i]; instance->generic.data_2 = instance->generic.data_2 << 8 | key_data[i];
} }
subghz_protocol_kinggates_stylo_4k_remote_controller(
&instance->generic, instance->keystore);
subghz_protocol_encoder_kinggates_stylo_4k_get_upload(instance, instance->generic.btn); subghz_protocol_encoder_kinggates_stylo_4k_get_upload(instance, instance->generic.btn);
if(!flipper_format_rewind(flipper_format)) { if(!flipper_format_rewind(flipper_format)) {
@@ -312,6 +375,14 @@ SubGhzProtocolStatus subghz_protocol_encoder_kinggates_stylo_4k_deserialize(
break; break;
} }
for(size_t i = 0; i < sizeof(uint64_t); i++) {
key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> i * 8) & 0xFF;
}
if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) {
FURI_LOG_E(TAG, "Unable to update Key");
break;
}
for(size_t i = 0; i < sizeof(uint64_t); i++) { for(size_t i = 0; i < sizeof(uint64_t); i++) {
key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data_2 >> i * 8) & 0xFF; key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data_2 >> i * 8) & 0xFF;
} }
@@ -503,6 +574,11 @@ static void subghz_protocol_kinggates_stylo_4k_remote_controller(
} }
if(ret) { if(ret) {
instance->cnt = decrypt & 0xFFFF; instance->cnt = decrypt & 0xFFFF;
// Save original button for later use
if(subghz_custom_btn_get_original() == 0) {
subghz_custom_btn_set_original(instance->btn);
}
subghz_custom_btn_set_max(3);
} else { } else {
instance->btn = 0; instance->btn = 0;
instance->serial = 0; instance->serial = 0;
@@ -577,11 +653,84 @@ SubGhzProtocolStatus subghz_protocol_decoder_kinggates_stylo_4k_deserialize(
return ret; return ret;
} }
static uint8_t subghz_protocol_kinggates_stylo_4k_get_btn_code(void) {
uint8_t custom_btn_id = subghz_custom_btn_get();
uint8_t original_btn_code = subghz_custom_btn_get_original();
uint8_t btn = original_btn_code;
// Set custom button
if((custom_btn_id == SUBGHZ_CUSTOM_BTN_OK) && (original_btn_code != 0)) {
// Restore original button code
btn = original_btn_code;
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_UP) {
switch(original_btn_code) {
case 0xE:
btn = 0xD;
break;
case 0xD:
btn = 0xE;
break;
case 0xB:
btn = 0xE;
break;
case 0x7:
btn = 0xE;
break;
default:
break;
}
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_DOWN) {
switch(original_btn_code) {
case 0xE:
btn = 0xB;
break;
case 0xD:
btn = 0xB;
break;
case 0xB:
btn = 0xD;
break;
case 0x7:
btn = 0xD;
break;
default:
break;
}
} else if(custom_btn_id == SUBGHZ_CUSTOM_BTN_LEFT) {
switch(original_btn_code) {
case 0xE:
btn = 0x7;
break;
case 0xD:
btn = 0x7;
break;
case 0xB:
btn = 0x7;
break;
case 0x7:
btn = 0xB;
break;
default:
break;
}
}
return btn;
}
void subghz_protocol_decoder_kinggates_stylo_4k_get_string(void* context, FuriString* output) { void subghz_protocol_decoder_kinggates_stylo_4k_get_string(void* context, FuriString* output) {
furi_assert(context); furi_assert(context);
SubGhzProtocolDecoderKingGates_stylo_4k* instance = context; SubGhzProtocolDecoderKingGates_stylo_4k* instance = context;
subghz_protocol_kinggates_stylo_4k_remote_controller(&instance->generic, instance->keystore); subghz_protocol_kinggates_stylo_4k_remote_controller(&instance->generic, instance->keystore);
// push protocol data to global variable
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
furi_string_cat_printf( furi_string_cat_printf(
output, output,
"%s\r\n" "%s\r\n"

View File

@@ -162,7 +162,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -166,7 +166,7 @@ SubGhzProtocolStatus subghz_protocol_encoder_linear_delta3_deserialize(
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -167,7 +167,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -215,7 +215,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -161,7 +161,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -170,7 +170,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -190,7 +190,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -182,7 +182,7 @@ SubGhzProtocolStatus
break; break;
} }
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -163,7 +163,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -149,7 +149,7 @@ SubGhzProtocolStatus
ret = SubGhzProtocolStatusErrorValueBitCount; ret = SubGhzProtocolStatusErrorValueBitCount;
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -16,8 +16,10 @@
#define TAG "SubGhzProtocolNiceFlorS" #define TAG "SubGhzProtocolNiceFlorS"
#define NICE_ONE_COUNT_BIT 72 #define NICE_ONE_COUNT_BIT 72
#define NICE_ONE_NAME "Nice One" #define NICE_ONE_NAME "Nice One"
#define SUBGHZ_NICE_FLOR_S_RAINBOW_TABLE_SIZE_BYTES 32
#define SUBGHZ_NO_NICE_FLOR_S_RAINBOW_TABLE 0
static const SubGhzBlockConst subghz_protocol_nice_flor_s_const = { static const SubGhzBlockConst subghz_protocol_nice_flor_s_const = {
.te_short = 500, .te_short = 500,
@@ -33,7 +35,6 @@ struct SubGhzProtocolDecoderNiceFlorS {
SubGhzBlockGeneric generic; SubGhzBlockGeneric generic;
const char* nice_flor_s_rainbow_table_file_name; const char* nice_flor_s_rainbow_table_file_name;
uint64_t data;
}; };
struct SubGhzProtocolEncoderNiceFlorS { struct SubGhzProtocolEncoderNiceFlorS {
@@ -159,10 +160,14 @@ static void subghz_protocol_encoder_nice_flor_s_get_upload(
if(nice_flors_counter_mode == 0) { if(nice_flors_counter_mode == 0) {
// Check for OFEX (overflow experimental) mode // Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { // standart counter mode. PULL data from subghz_block_generic_global variables
instance->generic.cnt = 0; if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
} else { // if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
} }
} else { } else {
if((instance->generic.cnt + 0x1) > 0xFFFF) { if((instance->generic.cnt + 0x1) > 0xFFFF) {
@@ -278,7 +283,7 @@ SubGhzProtocolStatus
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
// flipper_format_read_uint32( // flipper_format_read_uint32(
@@ -414,21 +419,13 @@ static void subghz_protocol_nice_one_get_data(uint8_t* p, uint8_t num_parcel, ui
} }
/** /**
* Read bytes from rainbow table * Read bytes from buffer array with rainbow table
* @param file_name Full path to rainbow table the file * @param buffer pointer to decrypted rainbow table
* @param address Byte address in file * @param address Byte address in file
* @return data * @return data
*/ */
static uint8_t static uint8_t subghz_protocol_nice_flor_s_get_byte_from_buffer(uint8_t* buffer, uint8_t address) {
subghz_protocol_nice_flor_s_get_byte_in_file(const char* file_name, uint32_t address) { return buffer[address];
if(!file_name) return 0;
uint8_t buffer[1] = {0};
if(subghz_keystore_raw_get_data(file_name, address, buffer, sizeof(uint8_t))) {
return buffer[0];
} else {
return 0;
}
} }
static inline void subghz_protocol_decoder_nice_flor_s_magic_xor(uint8_t* p, uint8_t k) { static inline void subghz_protocol_decoder_nice_flor_s_magic_xor(uint8_t* p, uint8_t k) {
@@ -438,16 +435,28 @@ static inline void subghz_protocol_decoder_nice_flor_s_magic_xor(uint8_t* p, uin
} }
uint64_t subghz_protocol_nice_flor_s_encrypt(uint64_t data, const char* file_name) { uint64_t subghz_protocol_nice_flor_s_encrypt(uint64_t data, const char* file_name) {
// load and decrypt rainbow table from file to buffer array in RAM
if(!file_name) return SUBGHZ_NO_NICE_FLOR_S_RAINBOW_TABLE;
uint8_t buffer[SUBGHZ_NICE_FLOR_S_RAINBOW_TABLE_SIZE_BYTES] = {0};
uint8_t* buffer_ptr = (uint8_t*)&buffer;
if(subghz_keystore_raw_get_data(
file_name, 0, buffer, SUBGHZ_NICE_FLOR_S_RAINBOW_TABLE_SIZE_BYTES)) {
} else {
return SUBGHZ_NO_NICE_FLOR_S_RAINBOW_TABLE;
}
uint8_t* p = (uint8_t*)&data; uint8_t* p = (uint8_t*)&data;
uint8_t k = 0; uint8_t k = 0;
for(uint8_t y = 0; y < 2; y++) { for(uint8_t y = 0; y < 2; y++) {
k = subghz_protocol_nice_flor_s_get_byte_in_file(file_name, p[0] & 0x1f); k = subghz_protocol_nice_flor_s_get_byte_from_buffer(buffer_ptr, p[0] & 0x1f);
subghz_protocol_decoder_nice_flor_s_magic_xor(p, k); subghz_protocol_decoder_nice_flor_s_magic_xor(p, k);
p[5] &= 0x0f; p[5] &= 0x0f;
p[0] ^= k & 0xe0; p[0] ^= k & 0xe0;
k = subghz_protocol_nice_flor_s_get_byte_in_file(file_name, p[0] >> 3) + 0x25; k = subghz_protocol_nice_flor_s_get_byte_from_buffer(buffer_ptr, p[0] >> 3) + 0x25;
subghz_protocol_decoder_nice_flor_s_magic_xor(p, k); subghz_protocol_decoder_nice_flor_s_magic_xor(p, k);
p[5] &= 0x0f; p[5] &= 0x0f;
@@ -475,6 +484,19 @@ static uint64_t
subghz_protocol_nice_flor_s_decrypt(SubGhzBlockGeneric* instance, const char* file_name) { subghz_protocol_nice_flor_s_decrypt(SubGhzBlockGeneric* instance, const char* file_name) {
furi_assert(instance); furi_assert(instance);
uint64_t data = instance->data; uint64_t data = instance->data;
// load and decrypt rainbow table from file to buffer array in RAM
if(!file_name) return SUBGHZ_NO_NICE_FLOR_S_RAINBOW_TABLE;
uint8_t buffer[SUBGHZ_NICE_FLOR_S_RAINBOW_TABLE_SIZE_BYTES] = {0};
uint8_t* buffer_ptr = (uint8_t*)&buffer;
if(subghz_keystore_raw_get_data(
file_name, 0, buffer, SUBGHZ_NICE_FLOR_S_RAINBOW_TABLE_SIZE_BYTES)) {
} else {
return SUBGHZ_NO_NICE_FLOR_S_RAINBOW_TABLE;
}
uint8_t* p = (uint8_t*)&data; uint8_t* p = (uint8_t*)&data;
uint8_t k = 0; uint8_t k = 0;
@@ -489,12 +511,12 @@ static uint64_t
p[1] = k; p[1] = k;
for(uint8_t y = 0; y < 2; y++) { for(uint8_t y = 0; y < 2; y++) {
k = subghz_protocol_nice_flor_s_get_byte_in_file(file_name, p[0] >> 3) + 0x25; k = subghz_protocol_nice_flor_s_get_byte_from_buffer(buffer_ptr, p[0] >> 3) + 0x25;
subghz_protocol_decoder_nice_flor_s_magic_xor(p, k); subghz_protocol_decoder_nice_flor_s_magic_xor(p, k);
p[5] &= 0x0f; p[5] &= 0x0f;
p[0] ^= k & 0x7; p[0] ^= k & 0x7;
k = subghz_protocol_nice_flor_s_get_byte_in_file(file_name, p[0] & 0x1f); k = subghz_protocol_nice_flor_s_get_byte_from_buffer(buffer_ptr, p[0] & 0x1f);
subghz_protocol_decoder_nice_flor_s_magic_xor(p, k); subghz_protocol_decoder_nice_flor_s_magic_xor(p, k);
p[5] &= 0x0f; p[5] &= 0x0f;
@@ -619,8 +641,8 @@ void subghz_protocol_decoder_nice_flor_s_feed(void* context, bool level, uint32_
if((instance->decoder.decode_count_bit == if((instance->decoder.decode_count_bit ==
subghz_protocol_nice_flor_s_const.min_count_bit_for_found) || subghz_protocol_nice_flor_s_const.min_count_bit_for_found) ||
(instance->decoder.decode_count_bit == NICE_ONE_COUNT_BIT)) { (instance->decoder.decode_count_bit == NICE_ONE_COUNT_BIT)) {
instance->generic.data = instance->data; instance->generic.data = instance->generic.data_2;
instance->data = instance->decoder.decode_data; instance->generic.data_2 = instance->decoder.decode_data;
instance->decoder.decode_data = instance->generic.data; instance->decoder.decode_data = instance->generic.data;
instance->generic.data_count_bit = instance->decoder.decode_count_bit; instance->generic.data_count_bit = instance->decoder.decode_count_bit;
@@ -659,7 +681,7 @@ void subghz_protocol_decoder_nice_flor_s_feed(void* context, bool level, uint32_
} }
if(instance->decoder.decode_count_bit == if(instance->decoder.decode_count_bit ==
subghz_protocol_nice_flor_s_const.min_count_bit_for_found) { subghz_protocol_nice_flor_s_const.min_count_bit_for_found) {
instance->data = instance->decoder.decode_data; instance->generic.data_2 = instance->decoder.decode_data;
instance->decoder.decode_data = 0; instance->decoder.decode_data = 0;
} }
break; break;
@@ -755,7 +777,7 @@ SubGhzProtocolStatus subghz_protocol_decoder_nice_flor_s_serialize(
} }
if((ret == SubGhzProtocolStatusOk) && if((ret == SubGhzProtocolStatusOk) &&
!flipper_format_insert_or_update_uint32( !flipper_format_insert_or_update_uint32(
flipper_format, "Data", (uint32_t*)&instance->data, 1)) { flipper_format, "Data", (uint32_t*)&instance->generic.data_2, 1)) {
FURI_LOG_E(TAG, "Unable to add Data"); FURI_LOG_E(TAG, "Unable to add Data");
ret = SubGhzProtocolStatusErrorParserOthers; ret = SubGhzProtocolStatusErrorParserOthers;
} }
@@ -792,7 +814,7 @@ SubGhzProtocolStatus
ret = SubGhzProtocolStatusErrorParserOthers; ret = SubGhzProtocolStatusErrorParserOthers;
break; break;
} }
instance->data = (uint64_t)temp; instance->generic.data_2 = (uint64_t)temp;
} }
if(!flipper_format_rewind(flipper_format)) { if(!flipper_format_rewind(flipper_format)) {
FURI_LOG_E(TAG, "Rewind error"); FURI_LOG_E(TAG, "Rewind error");
@@ -914,6 +936,11 @@ void subghz_protocol_decoder_nice_flor_s_get_string(void* context, FuriString* o
subghz_protocol_nice_flor_s_remote_controller( subghz_protocol_nice_flor_s_remote_controller(
&instance->generic, instance->nice_flor_s_rainbow_table_file_name); &instance->generic, instance->nice_flor_s_rainbow_table_file_name);
// push protocol data to global variable
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
if(instance->generic.data_count_bit == NICE_ONE_COUNT_BIT) { if(instance->generic.data_count_bit == NICE_ONE_COUNT_BIT) {
furi_string_cat_printf( furi_string_cat_printf(
output, output,
@@ -924,7 +951,7 @@ void subghz_protocol_decoder_nice_flor_s_get_string(void* context, FuriString* o
NICE_ONE_NAME, NICE_ONE_NAME,
instance->generic.data_count_bit, instance->generic.data_count_bit,
instance->generic.data, instance->generic.data,
instance->data, instance->generic.data_2,
instance->generic.serial, instance->generic.serial,
instance->generic.cnt, instance->generic.cnt,
instance->generic.btn); instance->generic.btn);

View File

@@ -256,10 +256,14 @@ static bool
// Reconstruction of the data // Reconstruction of the data
// Check for OFEX (overflow experimental) mode // Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { // standart counter mode. PULL data from subghz_block_generic_global variables
instance->generic.cnt = 0; if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
} else { // if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
} }
} else { } else {
if((instance->generic.cnt + 0x1) > 0xFFFF) { if((instance->generic.cnt + 0x1) > 0xFFFF) {
@@ -320,7 +324,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
@@ -590,6 +594,12 @@ void subghz_protocol_decoder_phoenix_v2_get_string(void* context, FuriString* ou
furi_assert(context); furi_assert(context);
SubGhzProtocolDecoderPhoenix_V2* instance = context; SubGhzProtocolDecoderPhoenix_V2* instance = context;
subghz_protocol_phoenix_v2_check_remote_controller(&instance->generic); subghz_protocol_phoenix_v2_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
furi_string_cat_printf( furi_string_cat_printf(
output, output,
"V2 Phoenix %dbit\r\n" "V2 Phoenix %dbit\r\n"

View File

@@ -208,7 +208,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -358,7 +358,7 @@ SubGhzProtocolStatus
ret = SubGhzProtocolStatusErrorParserTe; ret = SubGhzProtocolStatusErrorParserTe;
break; break;
} }
//optional parameter parameter // Optional value
if(!flipper_format_read_uint32( if(!flipper_format_read_uint32(
flipper_format, "Guard_time", (uint32_t*)&instance->guard_time, 1)) { flipper_format, "Guard_time", (uint32_t*)&instance->guard_time, 1)) {
instance->guard_time = PRINCETON_GUARD_TIME_DEFALUT; instance->guard_time = PRINCETON_GUARD_TIME_DEFALUT;

View File

@@ -3,7 +3,6 @@
const SubGhzProtocol* const subghz_protocol_registry_items[] = { const SubGhzProtocol* const subghz_protocol_registry_items[] = {
&subghz_protocol_gate_tx, &subghz_protocol_gate_tx,
&subghz_protocol_keeloq, &subghz_protocol_keeloq,
&subghz_protocol_star_line,
&subghz_protocol_nice_flo, &subghz_protocol_nice_flo,
&subghz_protocol_came, &subghz_protocol_came,
&subghz_protocol_faac_slh, &subghz_protocol_faac_slh,
@@ -12,12 +11,10 @@ const SubGhzProtocol* const subghz_protocol_registry_items[] = {
&subghz_protocol_came_atomo, &subghz_protocol_came_atomo,
&subghz_protocol_nero_sketch, &subghz_protocol_nero_sketch,
&subghz_protocol_ido, &subghz_protocol_ido,
&subghz_protocol_kia,
&subghz_protocol_hormann, &subghz_protocol_hormann,
&subghz_protocol_nero_radio, &subghz_protocol_nero_radio,
&subghz_protocol_somfy_telis, &subghz_protocol_somfy_telis,
&subghz_protocol_somfy_keytis, &subghz_protocol_somfy_keytis,
&subghz_protocol_scher_khan,
&subghz_protocol_princeton, &subghz_protocol_princeton,
&subghz_protocol_raw, &subghz_protocol_raw,
&subghz_protocol_linear, &subghz_protocol_linear,
@@ -84,6 +81,8 @@ const SubGhzProtocol* const subghz_protocol_registry_items[] = {
&subghz_protocol_feron, &subghz_protocol_feron,
&subghz_protocol_roger, &subghz_protocol_roger,
&subghz_protocol_elplast, &subghz_protocol_elplast,
&subghz_protocol_treadmill37,
&subghz_protocol_beninca_arc,
}; };
const SubGhzProtocolRegistry subghz_protocol_registry = { const SubGhzProtocolRegistry subghz_protocol_registry = {

View File

@@ -4,7 +4,6 @@
#include "princeton.h" #include "princeton.h"
#include "keeloq.h" #include "keeloq.h"
#include "star_line.h"
#include "nice_flo.h" #include "nice_flo.h"
#include "came.h" #include "came.h"
#include "faac_slh.h" #include "faac_slh.h"
@@ -13,12 +12,10 @@
#include "came_atomo.h" #include "came_atomo.h"
#include "nero_sketch.h" #include "nero_sketch.h"
#include "ido.h" #include "ido.h"
#include "kia.h"
#include "hormann.h" #include "hormann.h"
#include "nero_radio.h" #include "nero_radio.h"
#include "somfy_telis.h" #include "somfy_telis.h"
#include "somfy_keytis.h" #include "somfy_keytis.h"
#include "scher_khan.h"
#include "gate_tx.h" #include "gate_tx.h"
#include "raw.h" #include "raw.h"
#include "linear.h" #include "linear.h"
@@ -85,3 +82,5 @@
#include "feron.h" #include "feron.h"
#include "roger.h" #include "roger.h"
#include "elplast.h" #include "elplast.h"
#include "treadmill37.h"
#include "beninca_arc.h"

View File

@@ -159,26 +159,6 @@ bool subghz_protocol_nice_flor_s_create_data(
SubGhzRadioPreset* preset, SubGhzRadioPreset* preset,
bool nice_one); bool nice_one);
/**
* Key generation from simple data.
* @param context Pointer to a SubGhzProtocolEncoderStarLine instance
* @param flipper_format Pointer to a FlipperFormat instance
* @param serial Serial number, 24 bit
* @param btn Button number, 8 bit
* @param cnt Counter value, 16 bit
* @param manufacture_name Name of manufacturer's key
* @param preset Modulation, SubGhzRadioPreset
* @return true On success
*/
bool subghz_protocol_star_line_create_data(
void* context,
FlipperFormat* flipper_format,
uint32_t serial,
uint8_t btn,
uint16_t cnt,
const char* manufacture_name,
SubGhzRadioPreset* preset);
/** /**
* Key generation from simple data. * Key generation from simple data.
* @param context Pointer to a SubGhzProtocolEncoderSomfyTelis instance * @param context Pointer to a SubGhzProtocolEncoderSomfyTelis instance
@@ -215,6 +195,42 @@ bool subghz_protocol_somfy_keytis_create_data(
uint16_t cnt, uint16_t cnt,
SubGhzRadioPreset* preset); SubGhzRadioPreset* preset);
/**
* Key generation from simple data.
* @param context Pointer to a SubGhzProtocolEncoderKingGates_stylo_4k instance
* @param flipper_format Pointer to a FlipperFormat instance
* @param serial Serial number, 24 bit
* @param btn Button number, 8 bit
* @param cnt Counter value, 16 bit
* @param preset Modulation, SubGhzRadioPreset
* @return true On success
*/
bool subghz_protocol_kinggates_stylo_4k_create_data(
void* context,
FlipperFormat* flipper_format,
uint32_t serial,
uint8_t btn,
uint16_t cnt,
SubGhzRadioPreset* preset);
/**
* Key generation from simple data.
* @param context Pointer to a SubGhzProtocolEncoderBenincaARC instance
* @param flipper_format Pointer to a FlipperFormat instance
* @param serial Serial number, 32 bit
* @param btn Button number, 8 bit
* @param cnt Counter value, 32 bit
* @param preset Modulation, SubGhzRadioPreset
* @return true On success
*/
bool subghz_protocol_beninca_arc_create_data(
void* context,
FlipperFormat* flipper_format,
uint32_t serial,
uint8_t btn,
uint32_t cnt,
SubGhzRadioPreset* preset);
typedef struct SubGhzProtocolDecoderBinRAW SubGhzProtocolDecoderBinRAW; typedef struct SubGhzProtocolDecoderBinRAW SubGhzProtocolDecoderBinRAW;
void subghz_protocol_decoder_bin_raw_data_input_rssi( void subghz_protocol_decoder_bin_raw_data_input_rssi(

View File

@@ -68,6 +68,8 @@ const SubGhzProtocol subghz_protocol_revers_rb2 = {
.decoder = &subghz_protocol_revers_rb2_decoder, .decoder = &subghz_protocol_revers_rb2_decoder,
.encoder = &subghz_protocol_revers_rb2_encoder, .encoder = &subghz_protocol_revers_rb2_encoder,
.filter = SubGhzProtocolFilter_ReversRB2,
}; };
void* subghz_protocol_encoder_revers_rb2_alloc(SubGhzEnvironment* environment) { void* subghz_protocol_encoder_revers_rb2_alloc(SubGhzEnvironment* environment) {
@@ -178,7 +180,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -265,7 +265,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -1,320 +0,0 @@
#include "scher_khan.h"
#include "../blocks/const.h"
#include "../blocks/decoder.h"
#include "../blocks/encoder.h"
#include "../blocks/generic.h"
#include "../blocks/math.h"
//https://phreakerclub.com/72
//https://phreakerclub.com/forum/showthread.php?t=7&page=2
//https://phreakerclub.com/forum/showthread.php?t=274&highlight=magicar
//!!! https://phreakerclub.com/forum/showthread.php?t=489&highlight=magicar&page=5
#define TAG "SubGhzProtocolScherKhan"
static const SubGhzBlockConst subghz_protocol_scher_khan_const = {
.te_short = 750,
.te_long = 1100,
.te_delta = 150,
.min_count_bit_for_found = 35,
};
struct SubGhzProtocolDecoderScherKhan {
SubGhzProtocolDecoderBase base;
SubGhzBlockDecoder decoder;
SubGhzBlockGeneric generic;
uint16_t header_count;
const char* protocol_name;
};
struct SubGhzProtocolEncoderScherKhan {
SubGhzProtocolEncoderBase base;
SubGhzProtocolBlockEncoder encoder;
SubGhzBlockGeneric generic;
};
typedef enum {
ScherKhanDecoderStepReset = 0,
ScherKhanDecoderStepCheckPreambula,
ScherKhanDecoderStepSaveDuration,
ScherKhanDecoderStepCheckDuration,
} ScherKhanDecoderStep;
const SubGhzProtocolDecoder subghz_protocol_scher_khan_decoder = {
.alloc = subghz_protocol_decoder_scher_khan_alloc,
.free = subghz_protocol_decoder_scher_khan_free,
.feed = subghz_protocol_decoder_scher_khan_feed,
.reset = subghz_protocol_decoder_scher_khan_reset,
.get_hash_data = NULL,
.get_hash_data_long = subghz_protocol_decoder_scher_khan_get_hash_data,
.serialize = subghz_protocol_decoder_scher_khan_serialize,
.deserialize = subghz_protocol_decoder_scher_khan_deserialize,
.get_string = subghz_protocol_decoder_scher_khan_get_string,
.get_string_brief = NULL,
};
const SubGhzProtocolEncoder subghz_protocol_scher_khan_encoder = {
.alloc = NULL,
.free = NULL,
.deserialize = NULL,
.stop = NULL,
.yield = NULL,
};
const SubGhzProtocol subghz_protocol_scher_khan = {
.name = SUBGHZ_PROTOCOL_SCHER_KHAN_NAME,
.type = SubGhzProtocolTypeDynamic,
.flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_FM | SubGhzProtocolFlag_Decodable |
SubGhzProtocolFlag_Save,
.decoder = &subghz_protocol_scher_khan_decoder,
.encoder = &subghz_protocol_scher_khan_encoder,
.filter = SubGhzProtocolFilter_Cars,
};
void* subghz_protocol_decoder_scher_khan_alloc(SubGhzEnvironment* environment) {
UNUSED(environment);
SubGhzProtocolDecoderScherKhan* instance = malloc(sizeof(SubGhzProtocolDecoderScherKhan));
instance->base.protocol = &subghz_protocol_scher_khan;
instance->generic.protocol_name = instance->base.protocol->name;
return instance;
}
void subghz_protocol_decoder_scher_khan_free(void* context) {
furi_assert(context);
SubGhzProtocolDecoderScherKhan* instance = context;
free(instance);
}
void subghz_protocol_decoder_scher_khan_reset(void* context) {
furi_assert(context);
SubGhzProtocolDecoderScherKhan* instance = context;
instance->decoder.parser_step = ScherKhanDecoderStepReset;
}
void subghz_protocol_decoder_scher_khan_feed(void* context, bool level, uint32_t duration) {
furi_assert(context);
SubGhzProtocolDecoderScherKhan* instance = context;
switch(instance->decoder.parser_step) {
case ScherKhanDecoderStepReset:
if((level) && (DURATION_DIFF(duration, subghz_protocol_scher_khan_const.te_short * 2) <
subghz_protocol_scher_khan_const.te_delta)) {
instance->decoder.parser_step = ScherKhanDecoderStepCheckPreambula;
instance->decoder.te_last = duration;
instance->header_count = 0;
}
break;
case ScherKhanDecoderStepCheckPreambula:
if(level) {
if((DURATION_DIFF(duration, subghz_protocol_scher_khan_const.te_short * 2) <
subghz_protocol_scher_khan_const.te_delta) ||
(DURATION_DIFF(duration, subghz_protocol_scher_khan_const.te_short) <
subghz_protocol_scher_khan_const.te_delta)) {
instance->decoder.te_last = duration;
} else {
instance->decoder.parser_step = ScherKhanDecoderStepReset;
}
} else if(
(DURATION_DIFF(duration, subghz_protocol_scher_khan_const.te_short * 2) <
subghz_protocol_scher_khan_const.te_delta) ||
(DURATION_DIFF(duration, subghz_protocol_scher_khan_const.te_short) <
subghz_protocol_scher_khan_const.te_delta)) {
if(DURATION_DIFF(
instance->decoder.te_last, subghz_protocol_scher_khan_const.te_short * 2) <
subghz_protocol_scher_khan_const.te_delta) {
// Found header
instance->header_count++;
break;
} else if(
DURATION_DIFF(
instance->decoder.te_last, subghz_protocol_scher_khan_const.te_short) <
subghz_protocol_scher_khan_const.te_delta) {
// Found start bit
if(instance->header_count >= 2) {
instance->decoder.parser_step = ScherKhanDecoderStepSaveDuration;
instance->decoder.decode_data = 0;
instance->decoder.decode_count_bit = 1;
} else {
instance->decoder.parser_step = ScherKhanDecoderStepReset;
}
} else {
instance->decoder.parser_step = ScherKhanDecoderStepReset;
}
} else {
instance->decoder.parser_step = ScherKhanDecoderStepReset;
}
break;
case ScherKhanDecoderStepSaveDuration:
if(level) {
if(duration >= (subghz_protocol_scher_khan_const.te_delta * 2UL +
subghz_protocol_scher_khan_const.te_long)) {
//Found stop bit
instance->decoder.parser_step = ScherKhanDecoderStepReset;
if(instance->decoder.decode_count_bit >=
subghz_protocol_scher_khan_const.min_count_bit_for_found) {
instance->generic.data = instance->decoder.decode_data;
instance->generic.data_count_bit = instance->decoder.decode_count_bit;
if(instance->base.callback)
instance->base.callback(&instance->base, instance->base.context);
}
instance->decoder.decode_data = 0;
instance->decoder.decode_count_bit = 0;
break;
} else {
instance->decoder.te_last = duration;
instance->decoder.parser_step = ScherKhanDecoderStepCheckDuration;
}
} else {
instance->decoder.parser_step = ScherKhanDecoderStepReset;
}
break;
case ScherKhanDecoderStepCheckDuration:
if(!level) {
if((DURATION_DIFF(
instance->decoder.te_last, subghz_protocol_scher_khan_const.te_short) <
subghz_protocol_scher_khan_const.te_delta) &&
(DURATION_DIFF(duration, subghz_protocol_scher_khan_const.te_short) <
subghz_protocol_scher_khan_const.te_delta)) {
subghz_protocol_blocks_add_bit(&instance->decoder, 0);
instance->decoder.parser_step = ScherKhanDecoderStepSaveDuration;
} else if(
(DURATION_DIFF(
instance->decoder.te_last, subghz_protocol_scher_khan_const.te_long) <
subghz_protocol_scher_khan_const.te_delta) &&
(DURATION_DIFF(duration, subghz_protocol_scher_khan_const.te_long) <
subghz_protocol_scher_khan_const.te_delta)) {
subghz_protocol_blocks_add_bit(&instance->decoder, 1);
instance->decoder.parser_step = ScherKhanDecoderStepSaveDuration;
} else {
instance->decoder.parser_step = ScherKhanDecoderStepReset;
}
} else {
instance->decoder.parser_step = ScherKhanDecoderStepReset;
}
break;
}
}
/**
* Analysis of received data
* @param instance Pointer to a SubGhzBlockGeneric* instance
* @param protocol_name
*/
static void subghz_protocol_scher_khan_check_remote_controller(
SubGhzBlockGeneric* instance,
const char** protocol_name) {
/*
* MAGICAR 51 bit 00000001A99121DE83C3 MAGIC CODE, Dynamic
* 0E8C1619E830C -> 000011101000110000010110 0001 1001 1110 1000001100001100
* 0E8C1629D830D -> 000011101000110000010110 0010 1001 1101 1000001100001101
* 0E8C1649B830E -> 000011101000110000010110 0100 1001 1011 1000001100001110
* 0E8C16897830F -> 000011101000110000010110 1000 1001 0111 1000001100001111
* Serial Key Ser ~Key CNT
*/
switch(instance->data_count_bit) {
case 35: //MAGIC CODE, Static
*protocol_name = "MAGIC CODE, Static";
instance->serial = 0;
instance->btn = 0;
instance->cnt = 0;
break;
case 51: //MAGIC CODE, Dynamic
*protocol_name = "MAGIC CODE, Dynamic";
instance->serial = ((instance->data >> 24) & 0xFFFFFF0) | ((instance->data >> 20) & 0x0F);
instance->btn = (instance->data >> 24) & 0x0F;
instance->cnt = instance->data & 0xFFFF;
break;
case 57: //MAGIC CODE PRO / PRO2
*protocol_name = "MAGIC CODE PRO/PRO2";
instance->serial = 0;
instance->btn = 0;
instance->cnt = 0;
break;
case 63: //MAGIC CODE, Dynamic Response
*protocol_name = "MAGIC CODE, Response";
instance->serial = 0;
instance->btn = 0;
instance->cnt = 0;
break;
case 64: //MAGICAR, Response ???
*protocol_name = "MAGICAR, Response";
instance->serial = 0;
instance->btn = 0;
instance->cnt = 0;
break;
case 81: // MAGIC CODE PRO / PRO2 Response ???
case 82: // MAGIC CODE PRO / PRO2 Response ???
*protocol_name = "MAGIC CODE PRO,\n Response";
instance->serial = 0;
instance->btn = 0;
instance->cnt = 0;
break;
default:
*protocol_name = "Unknown";
instance->serial = 0;
instance->btn = 0;
instance->cnt = 0;
break;
}
}
uint32_t subghz_protocol_decoder_scher_khan_get_hash_data(void* context) {
furi_assert(context);
SubGhzProtocolDecoderScherKhan* instance = context;
return subghz_protocol_blocks_get_hash_data_long(
&instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
}
SubGhzProtocolStatus subghz_protocol_decoder_scher_khan_serialize(
void* context,
FlipperFormat* flipper_format,
SubGhzRadioPreset* preset) {
furi_assert(context);
SubGhzProtocolDecoderScherKhan* instance = context;
return subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
}
SubGhzProtocolStatus
subghz_protocol_decoder_scher_khan_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolDecoderScherKhan* instance = context;
return subghz_block_generic_deserialize(&instance->generic, flipper_format);
}
void subghz_protocol_decoder_scher_khan_get_string(void* context, FuriString* output) {
furi_assert(context);
SubGhzProtocolDecoderScherKhan* instance = context;
subghz_protocol_scher_khan_check_remote_controller(
&instance->generic, &instance->protocol_name);
// use 'Cntr:' instead of 'Cnt:' to exclude this protocol counter from Counter edit
furi_string_cat_printf(
output,
"%s %dbit\r\n"
"Key:0x%lX%08lX\r\n"
"Sn:%07lX Btn:%X\r\n"
"Cntr:%04lX\r\n"
"Pt: %s\r\n",
instance->generic.protocol_name,
instance->generic.data_count_bit,
(uint32_t)(instance->generic.data >> 32),
(uint32_t)instance->generic.data,
instance->generic.serial,
instance->generic.btn,
instance->generic.cnt,
instance->protocol_name);
}

View File

@@ -1,74 +0,0 @@
#pragma once
#include "base.h"
#define SUBGHZ_PROTOCOL_SCHER_KHAN_NAME "Scher-Khan"
typedef struct SubGhzProtocolDecoderScherKhan SubGhzProtocolDecoderScherKhan;
typedef struct SubGhzProtocolEncoderScherKhan SubGhzProtocolEncoderScherKhan;
extern const SubGhzProtocolDecoder subghz_protocol_scher_khan_decoder;
extern const SubGhzProtocolEncoder subghz_protocol_scher_khan_encoder;
extern const SubGhzProtocol subghz_protocol_scher_khan;
/**
* Allocate SubGhzProtocolDecoderScherKhan.
* @param environment Pointer to a SubGhzEnvironment instance
* @return SubGhzProtocolDecoderScherKhan* pointer to a SubGhzProtocolDecoderScherKhan instance
*/
void* subghz_protocol_decoder_scher_khan_alloc(SubGhzEnvironment* environment);
/**
* Free SubGhzProtocolDecoderScherKhan.
* @param context Pointer to a SubGhzProtocolDecoderScherKhan instance
*/
void subghz_protocol_decoder_scher_khan_free(void* context);
/**
* Reset decoder SubGhzProtocolDecoderScherKhan.
* @param context Pointer to a SubGhzProtocolDecoderScherKhan instance
*/
void subghz_protocol_decoder_scher_khan_reset(void* context);
/**
* Parse a raw sequence of levels and durations received from the air.
* @param context Pointer to a SubGhzProtocolDecoderScherKhan instance
* @param level Signal level true-high false-low
* @param duration Duration of this level in, us
*/
void subghz_protocol_decoder_scher_khan_feed(void* context, bool level, uint32_t duration);
/**
* Getting the hash sum of the last randomly received parcel.
* @param context Pointer to a SubGhzProtocolDecoderScherKhan instance
* @return hash Hash sum
*/
uint32_t subghz_protocol_decoder_scher_khan_get_hash_data(void* context);
/**
* Serialize data SubGhzProtocolDecoderScherKhan.
* @param context Pointer to a SubGhzProtocolDecoderScherKhan instance
* @param flipper_format Pointer to a FlipperFormat instance
* @param preset The modulation on which the signal was received, SubGhzRadioPreset
* @return status
*/
SubGhzProtocolStatus subghz_protocol_decoder_scher_khan_serialize(
void* context,
FlipperFormat* flipper_format,
SubGhzRadioPreset* preset);
/**
* Deserialize data SubGhzProtocolDecoderScherKhan.
* @param context Pointer to a SubGhzProtocolDecoderScherKhan instance
* @param flipper_format Pointer to a FlipperFormat instance
* @return status
*/
SubGhzProtocolStatus
subghz_protocol_decoder_scher_khan_deserialize(void* context, FlipperFormat* flipper_format);
/**
* Getting a textual representation of the received data.
* @param context Pointer to a SubGhzProtocolDecoderScherKhan instance
* @param output Resulting text
*/
void subghz_protocol_decoder_scher_khan_get_string(void* context, FuriString* output);

View File

@@ -222,43 +222,19 @@ static bool subghz_protocol_secplus_v1_encode(SubGhzProtocolEncoderSecPlus_v1* i
//increment the counter //increment the counter
//rolling += 2; - old way //rolling += 2; - old way
// Experemental case - we dont know counter size exactly, so just will be think that it is in range of 0xE6000000 - 0xFFFFFFFF // Experemental case - we dont know counter size exactly, so just will be think that it is in range of 0xE6000000 - 0xFFFFFFFF
// one case when we have mult = 0xFFFFFFFF - its when we reset counter before applying new cnt value
// so at first step we reset cnt to 0 and now we sure here will be second step (set new cnt value);
// at second step check what user set for new Cnt (and correct it if cnt less than 0xE6000000 or more than 0xFFFFFFFF)
int32_t multicntr = (furi_hal_subghz_get_rolling_counter_mult() & 0xFFFFFFF);
// Adjust for negative multiplier
if(furi_hal_subghz_get_rolling_counter_mult() < 0) {
multicntr = furi_hal_subghz_get_rolling_counter_mult();
}
if(multicntr == 1) {
multicntr = 2; // to keep old behaviour when mult = 1
}
// Check for OFEX (overflow experimental) mode // Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
if((furi_hal_subghz_get_rolling_counter_mult() == (int32_t)0xFFFFFFF) & (rolling != 0)) { // standart counter mode. PULL data from subghz_block_generic_global variables
rolling = 0; if(!subghz_block_generic_global_counter_override_get(&rolling)) {
} else { // if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
// if cnt was reset to 0 on previous step and user want new Cnt then set it to 0xE6000000 or 0xFFFFFFFF or new user value if((rolling + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFFFFFF) {
if(rolling == 0) { rolling = 0xE6000000;
if((furi_hal_subghz_get_rolling_counter_mult()) < (int32_t)0x6000000) {
rolling = 0xE6000000;
} else {
if((furi_hal_subghz_get_rolling_counter_mult()) >= (int32_t)0xFFFFFFF) {
rolling = 0xFFFFFFFF;
} else {
rolling = 0xE0000000;
rolling += multicntr;
}
}
} else { } else {
// if we have not special cases - so work as standart mode rolling += furi_hal_subghz_get_rolling_counter_mult();
if((rolling + multicntr) > 0xFFFFFFFF) {
rolling = 0xE6000000;
} else {
rolling += multicntr;
}
} }
} }
if(rolling < 0xE6000000) rolling = 0xE6000000;
} else { } else {
// OFEX (overflow experimental) mode // OFEX (overflow experimental) mode
if((rolling + 0x1) > 0xFFFFFFFF) { if((rolling + 0x1) > 0xFFFFFFFF) {
@@ -324,7 +300,7 @@ SubGhzProtocolStatus
if(ret != SubGhzProtocolStatusOk) { if(ret != SubGhzProtocolStatusOk) {
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
@@ -607,6 +583,11 @@ void subghz_protocol_decoder_secplus_v1_get_string(void* context, FuriString* ou
uint8_t id1 = (fixed / 9) % 3; uint8_t id1 = (fixed / 9) % 3;
uint16_t pin = 0; uint16_t pin = 0;
// push protocol data to global variable
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 32;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
furi_string_cat_printf( furi_string_cat_printf(
output, output,
"%s %db\r\n" "%s %db\r\n"

View File

@@ -404,40 +404,19 @@ static void subghz_protocol_secplus_v2_encode(SubGhzProtocolEncoderSecPlus_v2* i
uint8_t roll_2[9] = {0}; uint8_t roll_2[9] = {0};
// Experemental case - we dont know counter size exactly, so just will be think that it is in range of 0xE500000 - 0xFFFFFFF // Experemental case - we dont know counter size exactly, so just will be think that it is in range of 0xE500000 - 0xFFFFFFF
// one case when we have mult = 0xFFFFFFFF - its when we reset counter before applying new cnt value
// so at first step we reset cnt to 0 and now we sure here will be second step (set new cnt value);
// at second step check what user set for new Cnt (and correct it if cnt less than 0xE500000 or more than 0xFFFFFFF)
int32_t multicntr = (furi_hal_subghz_get_rolling_counter_mult() & 0xFFFFFFF);
// Adjust for negative multiplier
if(furi_hal_subghz_get_rolling_counter_mult() < 0) {
multicntr = furi_hal_subghz_get_rolling_counter_mult();
}
// Check for OFEX (overflow experimental) mode // Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
if((furi_hal_subghz_get_rolling_counter_mult() == (int32_t)0xFFFFFFF) & // standart counter mode. PULL data from subghz_block_generic_global variables
(instance->generic.cnt != 0)) { if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
instance->generic.cnt = 0; // if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
} else { if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFFFFF) {
// if cnt was reset to 0 on previous step and user want new Cnt then set it to 0xE500000 or 0xFFFFFFF or new user value instance->generic.cnt = 0xE500000;
if(instance->generic.cnt == 0) {
if(furi_hal_subghz_get_rolling_counter_mult() < (int32_t)0xE500000) {
instance->generic.cnt = 0xE500000;
} else {
if(furi_hal_subghz_get_rolling_counter_mult() >= (int32_t)0xFFFFFFF) {
instance->generic.cnt = 0xFFFFFFF;
} else {
instance->generic.cnt += multicntr;
}
}
} else { } else {
// if we have not special cases - so work as standart mode instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
if((instance->generic.cnt + multicntr) > 0xFFFFFFF) {
instance->generic.cnt = 0xE500000;
} else {
instance->generic.cnt += multicntr;
}
} }
} }
if(instance->generic.cnt < 0xE500000) instance->generic.cnt = 0xE500000;
} else { } else {
// OFEX (overflow experimental) mode // OFEX (overflow experimental) mode
if((instance->generic.cnt + 0x1) > 0xFFFFFFF) { if((instance->generic.cnt + 0x1) > 0xFFFFFFF) {
@@ -597,7 +576,7 @@ SubGhzProtocolStatus
subghz_protocol_secplus_v2_remote_controller( subghz_protocol_secplus_v2_remote_controller(
&instance->generic, instance->secplus_packet_1); &instance->generic, instance->secplus_packet_1);
subghz_protocol_secplus_v2_encode(instance); subghz_protocol_secplus_v2_encode(instance);
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_secplus_v2_get_upload(instance); subghz_protocol_encoder_secplus_v2_get_upload(instance);
@@ -984,6 +963,11 @@ void subghz_protocol_decoder_secplus_v2_get_string(void* context, FuriString* ou
subghz_protocol_secplus_v2_remote_controller(&instance->generic, instance->secplus_packet_1); subghz_protocol_secplus_v2_remote_controller(&instance->generic, instance->secplus_packet_1);
// need to research or practice check how much bits in counter // need to research or practice check how much bits in counter
// push protocol data to global variable
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 28;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
furi_string_cat_printf( furi_string_cat_printf(
output, output,
"%s %db\r\n" "%s %db\r\n"

View File

@@ -180,7 +180,7 @@ SubGhzProtocolStatus
ret = SubGhzProtocolStatusErrorParserTe; ret = SubGhzProtocolStatusErrorParserTe;
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);

View File

@@ -134,10 +134,14 @@ static bool
// Check for OFEX (overflow experimental) mode // Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { // standart counter mode. PULL data from subghz_block_generic_global variables
instance->generic.cnt = 0; if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
} else { // if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
} }
} else { } else {
if((instance->generic.cnt + 0x1) > 0xFFFF) { if((instance->generic.cnt + 0x1) > 0xFFFF) {
@@ -410,7 +414,7 @@ SubGhzProtocolStatus
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
@@ -794,6 +798,11 @@ void subghz_protocol_decoder_somfy_keytis_get_string(void* context, FuriString*
subghz_protocol_somfy_keytis_check_remote_controller(&instance->generic); subghz_protocol_somfy_keytis_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
furi_string_cat_printf( furi_string_cat_printf(
output, output,
"%s %db\r\n" "%s %db\r\n"

View File

@@ -128,10 +128,14 @@ static bool subghz_protocol_somfy_telis_gen_data(
// Check for OFEX (overflow experimental) mode // Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) { if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) { // standart counter mode. PULL data from subghz_block_generic_global variables
instance->generic.cnt = 0; if(!subghz_block_generic_global_counter_override_get(&instance->generic.cnt)) {
} else { // if counter_override_get return FALSE then counter was not changed and we increase counter by standart mult value
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult(); if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
} }
} else { } else {
if((instance->generic.cnt + 0x1) > 0xFFFF) { if((instance->generic.cnt + 0x1) > 0xFFFF) {
@@ -339,7 +343,7 @@ SubGhzProtocolStatus
break; break;
} }
//optional parameter parameter // Optional value
flipper_format_read_uint32( flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
@@ -750,6 +754,12 @@ void subghz_protocol_decoder_somfy_telis_get_string(void* context, FuriString* o
SubGhzProtocolDecoderSomfyTelis* instance = context; SubGhzProtocolDecoderSomfyTelis* instance = context;
subghz_protocol_somfy_telis_check_remote_controller(&instance->generic); subghz_protocol_somfy_telis_check_remote_controller(&instance->generic);
// push protocol data to global variable
subghz_block_generic_global.cnt_is_available = true;
subghz_block_generic_global.cnt_length_bit = 16;
subghz_block_generic_global.current_cnt = instance->generic.cnt;
furi_string_cat_printf( furi_string_cat_printf(
output, output,
"%s %db\r\n" "%s %db\r\n"

View File

@@ -1,741 +0,0 @@
#include "star_line.h"
#include "keeloq_common.h"
#include "../subghz_keystore.h"
#include <m-array.h>
#include "../blocks/const.h"
#include "../blocks/decoder.h"
#include "../blocks/encoder.h"
#include "../blocks/generic.h"
#include "../blocks/math.h"
#include "../subghz_keystore_i.h"
#define TAG "SubGhzProtocolStarLine"
static const SubGhzBlockConst subghz_protocol_star_line_const = {
.te_short = 250,
.te_long = 500,
.te_delta = 120,
.min_count_bit_for_found = 64,
};
struct SubGhzProtocolDecoderStarLine {
SubGhzProtocolDecoderBase base;
SubGhzBlockDecoder decoder;
SubGhzBlockGeneric generic;
uint16_t header_count;
SubGhzKeystore* keystore;
const char* manufacture_name;
FuriString* manufacture_from_file;
};
struct SubGhzProtocolEncoderStarLine {
SubGhzProtocolEncoderBase base;
SubGhzProtocolBlockEncoder encoder;
SubGhzBlockGeneric generic;
SubGhzKeystore* keystore;
const char* manufacture_name;
FuriString* manufacture_from_file;
};
typedef enum {
StarLineDecoderStepReset = 0,
StarLineDecoderStepCheckPreambula,
StarLineDecoderStepSaveDuration,
StarLineDecoderStepCheckDuration,
} StarLineDecoderStep;
const SubGhzProtocolDecoder subghz_protocol_star_line_decoder = {
.alloc = subghz_protocol_decoder_star_line_alloc,
.free = subghz_protocol_decoder_star_line_free,
.feed = subghz_protocol_decoder_star_line_feed,
.reset = subghz_protocol_decoder_star_line_reset,
.get_hash_data = NULL,
.get_hash_data_long = subghz_protocol_decoder_star_line_get_hash_data,
.serialize = subghz_protocol_decoder_star_line_serialize,
.deserialize = subghz_protocol_decoder_star_line_deserialize,
.get_string = subghz_protocol_decoder_star_line_get_string,
.get_string_brief = NULL,
};
const SubGhzProtocolEncoder subghz_protocol_star_line_encoder = {
.alloc = subghz_protocol_encoder_star_line_alloc,
.free = subghz_protocol_encoder_star_line_free,
.deserialize = subghz_protocol_encoder_star_line_deserialize,
.stop = subghz_protocol_encoder_star_line_stop,
.yield = subghz_protocol_encoder_star_line_yield,
};
const SubGhzProtocol subghz_protocol_star_line = {
.name = SUBGHZ_PROTOCOL_STAR_LINE_NAME,
.type = SubGhzProtocolTypeDynamic,
.flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable |
SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send,
.decoder = &subghz_protocol_star_line_decoder,
.encoder = &subghz_protocol_star_line_encoder,
.filter = SubGhzProtocolFilter_Cars,
};
/**
* Analysis of received data
* @param instance Pointer to a SubGhzBlockGeneric* instance
* @param keystore Pointer to a SubGhzKeystore* instance
* @param manufacture_name
*/
static void subghz_protocol_star_line_check_remote_controller(
SubGhzBlockGeneric* instance,
SubGhzKeystore* keystore,
const char** manufacture_name);
void* subghz_protocol_encoder_star_line_alloc(SubGhzEnvironment* environment) {
SubGhzProtocolEncoderStarLine* instance = malloc(sizeof(SubGhzProtocolEncoderStarLine));
instance->base.protocol = &subghz_protocol_star_line;
instance->generic.protocol_name = instance->base.protocol->name;
instance->keystore = subghz_environment_get_keystore(environment);
instance->manufacture_from_file = furi_string_alloc();
instance->encoder.repeat = 10;
instance->encoder.size_upload = 256;
instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration));
instance->encoder.is_running = false;
return instance;
}
void subghz_protocol_encoder_star_line_free(void* context) {
furi_assert(context);
SubGhzProtocolEncoderStarLine* instance = context;
furi_string_free(instance->manufacture_from_file);
free(instance->encoder.upload);
free(instance);
}
/**
* Key generation from simple data
* @param instance Pointer to a SubGhzProtocolEncoderKeeloq* instance
* @param btn Button number, 4 bit
*/
static bool
subghz_protocol_star_line_gen_data(SubGhzProtocolEncoderStarLine* instance, uint8_t btn) {
// Check for OFEX (overflow experimental) mode
if(furi_hal_subghz_get_rolling_counter_mult() != -0x7FFFFFFF) {
if((instance->generic.cnt + furi_hal_subghz_get_rolling_counter_mult()) > 0xFFFF) {
instance->generic.cnt = 0;
} else {
instance->generic.cnt += furi_hal_subghz_get_rolling_counter_mult();
}
} else {
if((instance->generic.cnt + 0x1) > 0xFFFF) {
instance->generic.cnt = 0;
} else if(instance->generic.cnt >= 0x1 && instance->generic.cnt != 0xFFFE) {
instance->generic.cnt = 0xFFFE;
} else {
instance->generic.cnt++;
}
}
uint32_t fix = btn << 24 | instance->generic.serial;
uint32_t decrypt = btn << 24 | (instance->generic.serial & 0xFF) << 16 | instance->generic.cnt;
uint32_t hop = 0;
uint64_t man = 0;
uint64_t code_found_reverse;
int res = 0;
if(instance->manufacture_name == 0x0) {
instance->manufacture_name = "";
}
if(strcmp(instance->manufacture_name, "Unknown") == 0) {
code_found_reverse = subghz_protocol_blocks_reverse_key(
instance->generic.data, instance->generic.data_count_bit);
hop = code_found_reverse & 0x00000000ffffffff;
} else {
uint8_t kl_type_en = instance->keystore->kl_type;
for
M_EACH(
manufacture_code,
*subghz_keystore_get_data(instance->keystore),
SubGhzKeyArray_t) {
res = strcmp(
furi_string_get_cstr(manufacture_code->name), instance->manufacture_name);
if(res == 0) {
switch(manufacture_code->type) {
case KEELOQ_LEARNING_SIMPLE:
//Simple Learning
hop =
subghz_protocol_keeloq_common_encrypt(decrypt, manufacture_code->key);
break;
case KEELOQ_LEARNING_NORMAL:
//Normal Learning
man = subghz_protocol_keeloq_common_normal_learning(
fix, manufacture_code->key);
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
break;
case KEELOQ_LEARNING_UNKNOWN:
if(kl_type_en == 1) {
hop = subghz_protocol_keeloq_common_encrypt(
decrypt, manufacture_code->key);
}
if(kl_type_en == 2) {
man = subghz_protocol_keeloq_common_normal_learning(
fix, manufacture_code->key);
hop = subghz_protocol_keeloq_common_encrypt(decrypt, man);
}
break;
}
break;
}
}
}
if(hop) {
uint64_t yek = (uint64_t)fix << 32 | hop;
instance->generic.data =
subghz_protocol_blocks_reverse_key(yek, instance->generic.data_count_bit);
return true;
} else {
instance->manufacture_name = "Unknown";
return false;
}
}
bool subghz_protocol_star_line_create_data(
void* context,
FlipperFormat* flipper_format,
uint32_t serial,
uint8_t btn,
uint16_t cnt,
const char* manufacture_name,
SubGhzRadioPreset* preset) {
furi_assert(context);
SubGhzProtocolEncoderStarLine* instance = context;
instance->generic.serial = serial;
instance->generic.cnt = cnt;
instance->manufacture_name = manufacture_name;
instance->generic.data_count_bit = 64;
bool res = subghz_protocol_star_line_gen_data(instance, btn);
if(res) {
return SubGhzProtocolStatusOk ==
subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
}
return res;
}
/**
* Generating an upload from data.
* @param instance Pointer to a SubGhzProtocolEncoderKeeloq instance
* @return true On success
*/
static bool subghz_protocol_encoder_star_line_get_upload(
SubGhzProtocolEncoderStarLine* instance,
uint8_t btn) {
furi_assert(instance);
// Gen new key
if(!subghz_protocol_star_line_gen_data(instance, btn)) {
return false;
}
size_t index = 0;
size_t size_upload = 6 * 2 + (instance->generic.data_count_bit * 2);
if(size_upload > instance->encoder.size_upload) {
FURI_LOG_E(TAG, "Size upload exceeds allocated encoder buffer.");
return false;
} else {
instance->encoder.size_upload = size_upload;
}
//Send header
for(uint8_t i = 6; i > 0; i--) {
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_star_line_const.te_long * 2);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_star_line_const.te_long * 2);
}
//Send key data
for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) {
if(bit_read(instance->generic.data, i - 1)) {
//send bit 1
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_star_line_const.te_long);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_star_line_const.te_long);
} else {
//send bit 0
instance->encoder.upload[index++] =
level_duration_make(true, (uint32_t)subghz_protocol_star_line_const.te_short);
instance->encoder.upload[index++] =
level_duration_make(false, (uint32_t)subghz_protocol_star_line_const.te_short);
}
}
return true;
}
SubGhzProtocolStatus
subghz_protocol_encoder_star_line_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolEncoderStarLine* instance = context;
SubGhzProtocolStatus res = SubGhzProtocolStatusError;
do {
if(SubGhzProtocolStatusOk !=
subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
FURI_LOG_E(TAG, "Deserialize error");
break;
}
// Read manufacturer from file
if(flipper_format_read_string(
flipper_format, "Manufacture", instance->manufacture_from_file)) {
instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file);
instance->keystore->mfname = instance->manufacture_name;
} else {
FURI_LOG_D(TAG, "ENCODER: Missing Manufacture");
}
subghz_protocol_star_line_check_remote_controller(
&instance->generic, instance->keystore, &instance->manufacture_name);
//optional parameter parameter
flipper_format_read_uint32(
flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1);
subghz_protocol_encoder_star_line_get_upload(instance, instance->generic.btn);
if(!flipper_format_rewind(flipper_format)) {
FURI_LOG_E(TAG, "Rewind error");
break;
}
uint8_t key_data[sizeof(uint64_t)] = {0};
for(size_t i = 0; i < sizeof(uint64_t); i++) {
key_data[sizeof(uint64_t) - i - 1] = (instance->generic.data >> i * 8) & 0xFF;
}
if(!flipper_format_update_hex(flipper_format, "Key", key_data, sizeof(uint64_t))) {
FURI_LOG_E(TAG, "Unable to add Key");
break;
}
instance->encoder.is_running = true;
res = SubGhzProtocolStatusOk;
} while(false);
return res;
}
void subghz_protocol_encoder_star_line_stop(void* context) {
SubGhzProtocolEncoderStarLine* instance = context;
instance->encoder.is_running = false;
}
LevelDuration subghz_protocol_encoder_star_line_yield(void* context) {
SubGhzProtocolEncoderStarLine* instance = context;
if(instance->encoder.repeat == 0 || !instance->encoder.is_running) {
instance->encoder.is_running = false;
return level_duration_reset();
}
LevelDuration ret = instance->encoder.upload[instance->encoder.front];
if(++instance->encoder.front == instance->encoder.size_upload) {
instance->encoder.repeat--;
instance->encoder.front = 0;
}
return ret;
}
void* subghz_protocol_decoder_star_line_alloc(SubGhzEnvironment* environment) {
SubGhzProtocolDecoderStarLine* instance = malloc(sizeof(SubGhzProtocolDecoderStarLine));
instance->base.protocol = &subghz_protocol_star_line;
instance->generic.protocol_name = instance->base.protocol->name;
instance->manufacture_from_file = furi_string_alloc();
instance->keystore = subghz_environment_get_keystore(environment);
return instance;
}
void subghz_protocol_decoder_star_line_free(void* context) {
furi_assert(context);
SubGhzProtocolDecoderStarLine* instance = context;
furi_string_free(instance->manufacture_from_file);
free(instance);
}
void subghz_protocol_decoder_star_line_reset(void* context) {
furi_assert(context);
SubGhzProtocolDecoderStarLine* instance = context;
instance->decoder.parser_step = StarLineDecoderStepReset;
// TODO
instance->keystore->mfname = "";
instance->keystore->kl_type = 0;
}
void subghz_protocol_decoder_star_line_feed(void* context, bool level, uint32_t duration) {
furi_assert(context);
SubGhzProtocolDecoderStarLine* instance = context;
switch(instance->decoder.parser_step) {
case StarLineDecoderStepReset:
if(level) {
if(DURATION_DIFF(duration, subghz_protocol_star_line_const.te_long * 2) <
subghz_protocol_star_line_const.te_delta * 2) {
instance->decoder.parser_step = StarLineDecoderStepCheckPreambula;
instance->header_count++;
} else if(instance->header_count > 4) {
instance->decoder.decode_data = 0;
instance->decoder.decode_count_bit = 0;
instance->decoder.te_last = duration;
instance->decoder.parser_step = StarLineDecoderStepCheckDuration;
}
} else {
instance->header_count = 0;
}
break;
case StarLineDecoderStepCheckPreambula:
if((!level) && (DURATION_DIFF(duration, subghz_protocol_star_line_const.te_long * 2) <
subghz_protocol_star_line_const.te_delta * 2)) {
//Found Preambula
instance->decoder.parser_step = StarLineDecoderStepReset;
} else {
instance->header_count = 0;
instance->decoder.parser_step = StarLineDecoderStepReset;
}
break;
case StarLineDecoderStepSaveDuration:
if(level) {
if(duration >= (subghz_protocol_star_line_const.te_long +
subghz_protocol_star_line_const.te_delta)) {
instance->decoder.parser_step = StarLineDecoderStepReset;
if((instance->decoder.decode_count_bit >=
subghz_protocol_star_line_const.min_count_bit_for_found) &&
(instance->decoder.decode_count_bit <=
subghz_protocol_star_line_const.min_count_bit_for_found + 2)) {
if(instance->generic.data != instance->decoder.decode_data) {
instance->generic.data = instance->decoder.decode_data;
instance->generic.data_count_bit =
subghz_protocol_star_line_const.min_count_bit_for_found;
if(instance->base.callback)
instance->base.callback(&instance->base, instance->base.context);
}
}
instance->decoder.decode_data = 0;
instance->decoder.decode_count_bit = 0;
instance->header_count = 0;
break;
} else {
instance->decoder.te_last = duration;
instance->decoder.parser_step = StarLineDecoderStepCheckDuration;
}
} else {
instance->decoder.parser_step = StarLineDecoderStepReset;
}
break;
case StarLineDecoderStepCheckDuration:
if(!level) {
if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_star_line_const.te_short) <
subghz_protocol_star_line_const.te_delta) &&
(DURATION_DIFF(duration, subghz_protocol_star_line_const.te_short) <
subghz_protocol_star_line_const.te_delta)) {
if(instance->decoder.decode_count_bit <
subghz_protocol_star_line_const.min_count_bit_for_found) {
subghz_protocol_blocks_add_bit(&instance->decoder, 0);
} else {
instance->decoder.decode_count_bit++;
}
instance->decoder.parser_step = StarLineDecoderStepSaveDuration;
} else if(
(DURATION_DIFF(instance->decoder.te_last, subghz_protocol_star_line_const.te_long) <
subghz_protocol_star_line_const.te_delta) &&
(DURATION_DIFF(duration, subghz_protocol_star_line_const.te_long) <
subghz_protocol_star_line_const.te_delta)) {
if(instance->decoder.decode_count_bit <
subghz_protocol_star_line_const.min_count_bit_for_found) {
subghz_protocol_blocks_add_bit(&instance->decoder, 1);
} else {
instance->decoder.decode_count_bit++;
}
instance->decoder.parser_step = StarLineDecoderStepSaveDuration;
} else {
instance->decoder.parser_step = StarLineDecoderStepReset;
}
} else {
instance->decoder.parser_step = StarLineDecoderStepReset;
}
break;
}
}
/**
* Validation of decrypt data.
* @param instance Pointer to a SubGhzBlockGeneric instance
* @param decrypt Decrypd data
* @param btn Button number, 4 bit
* @param end_serial decrement the last 10 bits of the serial number
* @return true On success
*/
static inline bool subghz_protocol_star_line_check_decrypt(
SubGhzBlockGeneric* instance,
uint32_t decrypt,
uint8_t btn,
uint32_t end_serial) {
furi_assert(instance);
if((decrypt >> 24 == btn) && ((((uint16_t)(decrypt >> 16)) & 0x00FF) == end_serial)) {
instance->cnt = decrypt & 0x0000FFFF;
return true;
}
return false;
}
/**
* Checking the accepted code against the database manafacture key
* @param instance Pointer to a SubGhzBlockGeneric* instance
* @param fix Fix part of the parcel
* @param hop Hop encrypted part of the parcel
* @param keystore Pointer to a SubGhzKeystore* instance
* @param manufacture_name
* @return true on successful search
*/
static uint8_t subghz_protocol_star_line_check_remote_controller_selector(
SubGhzBlockGeneric* instance,
uint32_t fix,
uint32_t hop,
SubGhzKeystore* keystore,
const char** manufacture_name) {
uint16_t end_serial = (uint16_t)(fix & 0xFF);
uint8_t btn = (uint8_t)(fix >> 24);
uint32_t decrypt = 0;
uint64_t man_normal_learning;
bool mf_not_set = false;
// TODO:
// if(mfname == 0x0) {
// mfname = "";
// }
const char* mfname = keystore->mfname;
if(strcmp(mfname, "Unknown") == 0) {
return 1;
} else if(strcmp(mfname, "") == 0) {
mf_not_set = true;
}
for
M_EACH(manufacture_code, *subghz_keystore_get_data(keystore), SubGhzKeyArray_t) {
if(mf_not_set || (strcmp(furi_string_get_cstr(manufacture_code->name), mfname) == 0)) {
switch(manufacture_code->type) {
case KEELOQ_LEARNING_SIMPLE:
// Simple Learning
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
if(subghz_protocol_star_line_check_decrypt(
instance, decrypt, btn, end_serial)) {
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
keystore->mfname = *manufacture_name;
return 1;
}
break;
case KEELOQ_LEARNING_NORMAL:
// Normal Learning
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
man_normal_learning =
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
if(subghz_protocol_star_line_check_decrypt(
instance, decrypt, btn, end_serial)) {
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
keystore->mfname = *manufacture_name;
return 1;
}
break;
case KEELOQ_LEARNING_UNKNOWN:
// Simple Learning
decrypt = subghz_protocol_keeloq_common_decrypt(hop, manufacture_code->key);
if(subghz_protocol_star_line_check_decrypt(
instance, decrypt, btn, end_serial)) {
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
keystore->mfname = *manufacture_name;
keystore->kl_type = 1;
return 1;
}
// Check for mirrored man
uint64_t man_rev = 0;
uint64_t man_rev_byte = 0;
for(uint8_t i = 0; i < 64; i += 8) {
man_rev_byte = (uint8_t)(manufacture_code->key >> i);
man_rev = man_rev | man_rev_byte << (56 - i);
}
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_rev);
if(subghz_protocol_star_line_check_decrypt(
instance, decrypt, btn, end_serial)) {
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
keystore->mfname = *manufacture_name;
keystore->kl_type = 1;
return 1;
}
//###########################
// Normal Learning
// https://phreakerclub.com/forum/showpost.php?p=43557&postcount=37
man_normal_learning =
subghz_protocol_keeloq_common_normal_learning(fix, manufacture_code->key);
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
if(subghz_protocol_star_line_check_decrypt(
instance, decrypt, btn, end_serial)) {
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
keystore->mfname = *manufacture_name;
keystore->kl_type = 2;
return 1;
}
// Check for mirrored man
man_normal_learning =
subghz_protocol_keeloq_common_normal_learning(fix, man_rev);
decrypt = subghz_protocol_keeloq_common_decrypt(hop, man_normal_learning);
if(subghz_protocol_star_line_check_decrypt(
instance, decrypt, btn, end_serial)) {
*manufacture_name = furi_string_get_cstr(manufacture_code->name);
keystore->mfname = *manufacture_name;
keystore->kl_type = 2;
return 1;
}
break;
}
}
}
*manufacture_name = "Unknown";
keystore->mfname = "Unknown";
instance->cnt = 0;
return 0;
}
/**
* Analysis of received data
* @param instance Pointer to a SubGhzBlockGeneric* instance
* @param keystore Pointer to a SubGhzKeystore* instance
* @param manufacture_name
*/
static void subghz_protocol_star_line_check_remote_controller(
SubGhzBlockGeneric* instance,
SubGhzKeystore* keystore,
const char** manufacture_name) {
uint64_t key = subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit);
uint32_t key_fix = key >> 32;
uint32_t key_hop = key & 0x00000000ffffffff;
subghz_protocol_star_line_check_remote_controller_selector(
instance, key_fix, key_hop, keystore, manufacture_name);
instance->serial = key_fix & 0x00FFFFFF;
instance->btn = key_fix >> 24;
}
uint32_t subghz_protocol_decoder_star_line_get_hash_data(void* context) {
furi_assert(context);
SubGhzProtocolDecoderStarLine* instance = context;
return subghz_protocol_blocks_get_hash_data_long(
&instance->decoder, (instance->decoder.decode_count_bit / 8) + 1);
}
SubGhzProtocolStatus subghz_protocol_decoder_star_line_serialize(
void* context,
FlipperFormat* flipper_format,
SubGhzRadioPreset* preset) {
furi_assert(context);
SubGhzProtocolDecoderStarLine* instance = context;
subghz_protocol_star_line_check_remote_controller(
&instance->generic, instance->keystore, &instance->manufacture_name);
SubGhzProtocolStatus ret =
subghz_block_generic_serialize(&instance->generic, flipper_format, preset);
if((ret == SubGhzProtocolStatusOk) &&
!flipper_format_write_string_cstr(
flipper_format, "Manufacture", instance->manufacture_name)) {
FURI_LOG_E(TAG, "Unable to add manufacture name");
ret = SubGhzProtocolStatusErrorParserOthers;
}
if((ret == SubGhzProtocolStatusOk) &&
instance->generic.data_count_bit !=
subghz_protocol_star_line_const.min_count_bit_for_found) {
FURI_LOG_E(TAG, "Wrong number of bits in key");
ret = SubGhzProtocolStatusErrorParserOthers;
}
return ret;
}
SubGhzProtocolStatus
subghz_protocol_decoder_star_line_deserialize(void* context, FlipperFormat* flipper_format) {
furi_assert(context);
SubGhzProtocolDecoderStarLine* instance = context;
SubGhzProtocolStatus res = SubGhzProtocolStatusError;
do {
if(SubGhzProtocolStatusOk !=
subghz_block_generic_deserialize(&instance->generic, flipper_format)) {
FURI_LOG_E(TAG, "Deserialize error");
break;
}
// Read manufacturer from file
if(flipper_format_read_string(
flipper_format, "Manufacture", instance->manufacture_from_file)) {
instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file);
instance->keystore->mfname = instance->manufacture_name;
} else {
FURI_LOG_D(TAG, "DECODER: Missing Manufacture");
}
res = SubGhzProtocolStatusOk;
} while(false);
return res;
}
void subghz_protocol_decoder_star_line_get_string(void* context, FuriString* output) {
furi_assert(context);
SubGhzProtocolDecoderStarLine* instance = context;
subghz_protocol_star_line_check_remote_controller(
&instance->generic, instance->keystore, &instance->manufacture_name);
uint32_t code_found_hi = instance->generic.data >> 32;
uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff;
uint64_t code_found_reverse = subghz_protocol_blocks_reverse_key(
instance->generic.data, instance->generic.data_count_bit);
uint32_t code_found_reverse_hi = code_found_reverse >> 32;
uint32_t code_found_reverse_lo = code_found_reverse & 0x00000000ffffffff;
furi_string_cat_printf(
output,
"%s %dbit\r\n"
"Key:%08lX%08lX\r\n"
"Fix:0x%08lX Cnt:%04lX\r\n"
"Hop:0x%08lX Btn:%02X\r\n"
"MF:%s\r\n",
instance->generic.protocol_name,
instance->generic.data_count_bit,
code_found_hi,
code_found_lo,
code_found_reverse_hi,
instance->generic.cnt,
code_found_reverse_lo,
instance->generic.btn,
instance->manufacture_name);
}

View File

@@ -1,109 +0,0 @@
#pragma once
#include "base.h"
#define SUBGHZ_PROTOCOL_STAR_LINE_NAME "Star Line"
typedef struct SubGhzProtocolDecoderStarLine SubGhzProtocolDecoderStarLine;
typedef struct SubGhzProtocolEncoderStarLine SubGhzProtocolEncoderStarLine;
extern const SubGhzProtocolDecoder subghz_protocol_star_line_decoder;
extern const SubGhzProtocolEncoder subghz_protocol_star_line_encoder;
extern const SubGhzProtocol subghz_protocol_star_line;
/**
* Allocate SubGhzProtocolEncoderStarLine.
* @param environment Pointer to a SubGhzEnvironment instance
* @return SubGhzProtocolEncoderStarLine* pointer to a SubGhzProtocolEncoderStarLine instance
*/
void* subghz_protocol_encoder_star_line_alloc(SubGhzEnvironment* environment);
/**
* Free SubGhzProtocolEncoderStarLine.
* @param context Pointer to a SubGhzProtocolEncoderStarLine instance
*/
void subghz_protocol_encoder_star_line_free(void* context);
/**
* Deserialize and generating an upload to send.
* @param context Pointer to a SubGhzProtocolEncoderStarLine instance
* @param flipper_format Pointer to a FlipperFormat instance
* @return true On success
*/
SubGhzProtocolStatus
subghz_protocol_encoder_star_line_deserialize(void* context, FlipperFormat* flipper_format);
/**
* Forced transmission stop.
* @param context Pointer to a SubGhzProtocolEncoderStarLine instance
*/
void subghz_protocol_encoder_star_line_stop(void* context);
/**
* Getting the level and duration of the upload to be loaded into DMA.
* @param context Pointer to a SubGhzProtocolEncoderStarLine instance
* @return LevelDuration
*/
LevelDuration subghz_protocol_encoder_star_line_yield(void* context);
/**
* Allocate SubGhzProtocolDecoderStarLine.
* @param environment Pointer to a SubGhzEnvironment instance
* @return SubGhzProtocolDecoderStarLine* pointer to a SubGhzProtocolDecoderStarLine instance
*/
void* subghz_protocol_decoder_star_line_alloc(SubGhzEnvironment* environment);
/**
* Free SubGhzProtocolDecoderStarLine.
* @param context Pointer to a SubGhzProtocolDecoderStarLine instance
*/
void subghz_protocol_decoder_star_line_free(void* context);
/**
* Reset decoder SubGhzProtocolDecoderStarLine.
* @param context Pointer to a SubGhzProtocolDecoderStarLine instance
*/
void subghz_protocol_decoder_star_line_reset(void* context);
/**
* Parse a raw sequence of levels and durations received from the air.
* @param context Pointer to a SubGhzProtocolDecoderStarLine instance
* @param level Signal level true-high false-low
* @param duration Duration of this level in, us
*/
void subghz_protocol_decoder_star_line_feed(void* context, bool level, uint32_t duration);
/**
* Getting the hash sum of the last randomly received parcel.
* @param context Pointer to a SubGhzProtocolDecoderStarLine instance
* @return hash Hash sum
*/
uint32_t subghz_protocol_decoder_star_line_get_hash_data(void* context);
/**
* Serialize data SubGhzProtocolDecoderStarLine.
* @param context Pointer to a SubGhzProtocolDecoderStarLine instance
* @param flipper_format Pointer to a FlipperFormat instance
* @param preset The modulation on which the signal was received, SubGhzRadioPreset
* @return status
*/
SubGhzProtocolStatus subghz_protocol_decoder_star_line_serialize(
void* context,
FlipperFormat* flipper_format,
SubGhzRadioPreset* preset);
/**
* Deserialize data SubGhzProtocolDecoderStarLine.
* @param context Pointer to a SubGhzProtocolDecoderStarLine instance
* @param flipper_format Pointer to a FlipperFormat instance
* @return status
*/
SubGhzProtocolStatus
subghz_protocol_decoder_star_line_deserialize(void* context, FlipperFormat* flipper_format);
/**
* Getting a textual representation of the received data.
* @param context Pointer to a SubGhzProtocolDecoderStarLine instance
* @param output Resulting text
*/
void subghz_protocol_decoder_star_line_get_string(void* context, FuriString* output);

Some files were not shown because too many files have changed in this diff Show More