From 31259d530499b2ff6e07fd24a5ec3b8583a41ac0 Mon Sep 17 00:00:00 2001 From: Skorpionm <85568270+Skorpionm@users.noreply.github.com> Date: Wed, 8 Feb 2023 20:59:49 +0400 Subject: [PATCH] [FL-3091] SubGhz: add protocol Alutech at-4n (#2352) * GubGhz: add protocol Alutech at-4n * SubGhz: fix syntax * SubGhz: fix subghz_protocol_decoder_alutech_at_4n_get_hash_data * SubGhz: add unit test alutech at-4n * SubGhz: add name key Co-authored-by: Aleksandr Kutuzov --- .../debug/unit_tests/subghz/subghz_test.c | 14 +- applications/main/subghz/subghz.c | 2 + applications/main/subghz/subghz_cli.c | 4 + assets/resources/subghz/assets/alutech_at_4n | 6 + .../unit_tests/subghz/alutech_at_4n_raw.sub | 10 + assets/unit_tests/subghz/test_random_raw.sub | 5 + firmware/targets/f7/api_symbols.csv | 2 + lib/subghz/environment.c | 16 + lib/subghz/environment.h | 17 + lib/subghz/protocols/alutech_at_4n.c | 455 ++++++++++++++++++ lib/subghz/protocols/alutech_at_4n.h | 74 +++ lib/subghz/protocols/came_atomo.c | 2 +- lib/subghz/protocols/keeloq.c | 13 +- lib/subghz/protocols/protocol_items.c | 1 + lib/subghz/protocols/protocol_items.h | 1 + 15 files changed, 617 insertions(+), 5 deletions(-) create mode 100644 assets/resources/subghz/assets/alutech_at_4n create mode 100644 assets/unit_tests/subghz/alutech_at_4n_raw.sub create mode 100644 lib/subghz/protocols/alutech_at_4n.c create mode 100644 lib/subghz/protocols/alutech_at_4n.h diff --git a/applications/debug/unit_tests/subghz/subghz_test.c b/applications/debug/unit_tests/subghz/subghz_test.c index 0dba19d9..705d6f2f 100644 --- a/applications/debug/unit_tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/subghz/subghz_test.c @@ -12,8 +12,9 @@ #define KEYSTORE_DIR_NAME EXT_PATH("subghz/assets/keeloq_mfcodes") #define CAME_ATOMO_DIR_NAME EXT_PATH("subghz/assets/came_atomo") #define NICE_FLOR_S_DIR_NAME EXT_PATH("subghz/assets/nice_flor_s") +#define ALUTECH_AT_4N_DIR_NAME EXT_PATH("subghz/assets/alutech_at_4n") #define TEST_RANDOM_DIR_NAME EXT_PATH("unit_tests/subghz/test_random_raw.sub") -#define TEST_RANDOM_COUNT_PARSE 300 +#define TEST_RANDOM_COUNT_PARSE 304 #define TEST_TIMEOUT 10000 static SubGhzEnvironment* environment_handler; @@ -43,6 +44,8 @@ static void subghz_test_init(void) { environment_handler, CAME_ATOMO_DIR_NAME); subghz_environment_set_nice_flor_s_rainbow_table_file_name( environment_handler, NICE_FLOR_S_DIR_NAME); + subghz_environment_set_alutech_at_4n_rainbow_table_file_name( + environment_handler, ALUTECH_AT_4N_DIR_NAME); subghz_environment_set_protocol_registry( environment_handler, (void*)&subghz_protocol_registry); @@ -619,6 +622,14 @@ MU_TEST(subghz_decoder_dooya_test) { "Test decoder " SUBGHZ_PROTOCOL_DOOYA_NAME " error\r\n"); } +MU_TEST(subghz_decoder_alutech_at_4n_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/alutech_at_4n_raw.sub"), + SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME), + "Test decoder " SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME " error\r\n"); +} + //test encoders MU_TEST(subghz_encoder_princeton_test) { mu_assert( @@ -817,6 +828,7 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_decoder_smc5326_test); MU_RUN_TEST(subghz_decoder_holtek_ht12x_test); MU_RUN_TEST(subghz_decoder_dooya_test); + MU_RUN_TEST(subghz_decoder_alutech_at_4n_test); MU_RUN_TEST(subghz_encoder_princeton_test); MU_RUN_TEST(subghz_encoder_came_test); diff --git a/applications/main/subghz/subghz.c b/applications/main/subghz/subghz.c index b7564ab5..200be626 100644 --- a/applications/main/subghz/subghz.c +++ b/applications/main/subghz/subghz.c @@ -187,6 +187,8 @@ SubGhz* subghz_alloc() { subghz->txrx->environment = subghz_environment_alloc(); subghz_environment_set_came_atomo_rainbow_table_file_name( subghz->txrx->environment, EXT_PATH("subghz/assets/came_atomo")); + subghz_environment_set_alutech_at_4n_rainbow_table_file_name( + subghz->txrx->environment, EXT_PATH("subghz/assets/alutech_at_4n")); subghz_environment_set_nice_flor_s_rainbow_table_file_name( subghz->txrx->environment, EXT_PATH("subghz/assets/nice_flor_s")); subghz_environment_set_protocol_registry( diff --git a/applications/main/subghz/subghz_cli.c b/applications/main/subghz/subghz_cli.c index 9271443a..ac19d65b 100644 --- a/applications/main/subghz/subghz_cli.c +++ b/applications/main/subghz/subghz_cli.c @@ -257,6 +257,8 @@ void subghz_cli_command_rx(Cli* cli, FuriString* args, void* context) { subghz_environment_load_keystore(environment, EXT_PATH("subghz/assets/keeloq_mfcodes_user")); subghz_environment_set_came_atomo_rainbow_table_file_name( environment, EXT_PATH("subghz/assets/came_atomo")); + subghz_environment_set_alutech_at_4n_rainbow_table_file_name( + environment, EXT_PATH("subghz/assets/alutech_at_4n")); subghz_environment_set_nice_flor_s_rainbow_table_file_name( environment, EXT_PATH("subghz/assets/nice_flor_s")); subghz_environment_set_protocol_registry(environment, (void*)&subghz_protocol_registry); @@ -452,6 +454,8 @@ void subghz_cli_command_decode_raw(Cli* cli, FuriString* args, void* context) { } subghz_environment_set_came_atomo_rainbow_table_file_name( environment, EXT_PATH("subghz/assets/came_atomo")); + subghz_environment_set_alutech_at_4n_rainbow_table_file_name( + environment, EXT_PATH("subghz/assets/alutech_at_4n")); subghz_environment_set_nice_flor_s_rainbow_table_file_name( environment, EXT_PATH("subghz/assets/nice_flor_s")); subghz_environment_set_protocol_registry(environment, (void*)&subghz_protocol_registry); diff --git a/assets/resources/subghz/assets/alutech_at_4n b/assets/resources/subghz/assets/alutech_at_4n new file mode 100644 index 00000000..5d7beace --- /dev/null +++ b/assets/resources/subghz/assets/alutech_at_4n @@ -0,0 +1,6 @@ +Filetype: Flipper SubGhz Keystore RAW File +Version: 0 +Encryption: 1 +IV: 88 64 A6 A6 44 47 67 8A D6 32 36 F6 B9 06 57 31 +Encrypt_data: RAW +E811BD4F0955D217AE6677906E799D45D8DAAFD1F7923E1660B5E24574631B60 \ No newline at end of file diff --git a/assets/unit_tests/subghz/alutech_at_4n_raw.sub b/assets/unit_tests/subghz/alutech_at_4n_raw.sub new file mode 100644 index 00000000..ae5db971 --- /dev/null +++ b/assets/unit_tests/subghz/alutech_at_4n_raw.sub @@ -0,0 +1,10 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: -854 811 -454 811 -444 409 -838 811 -454 823 -432 385 -842 811 -454 389 -854 821 -418 837 -444 401 -850 417 -854 395 -830 417 -846 819 -432 811 -448 789 -444 839 -454 401 -856 381 -850 825 -410 841 -418 417 -834 411 -840 827 -442 417 -844 799 -472 809 -420 411 -842 419 -848 397 -822 413 -850 799 -486 381 -848 415 -854 423 -16394 449 -358 437 -386 411 -384 449 -382 417 -384 419 -386 417 -386 419 -388 419 -388 419 -388 419 -390 437 -4036 421 -810 425 -820 393 -866 813 -422 415 -856 397 -858 811 -456 427 -820 815 -416 419 -850 401 -854 805 -420 835 -444 409 -842 809 -454 433 -820 421 -838 813 -420 417 -822 435 -820 419 -834 431 -852 411 -866 805 -420 815 -444 805 -454 403 -824 809 -448 819 -448 413 -844 811 -446 811 -456 409 -816 809 -456 389 -866 387 -842 809 -454 827 -432 413 -850 829 -428 809 -452 381 -852 799 -452 413 -852 807 -450 801 -444 409 -872 411 -840 413 -812 413 -832 807 -450 815 -442 801 -454 809 -454 429 -820 419 -838 811 -456 785 -428 409 -842 439 -824 813 -448 415 -858 819 -418 831 -426 449 -808 427 -820 393 -866 421 -808 825 -436 413 -852 403 -884 421 -16394 407 -478 257 -574 229 -576 229 -564 231 -592 267 -490 305 -520 307 -486 309 -522 307 -458 341 -486 337 -4096 343 -882 389 -880 341 -874 807 -476 351 -882 397 -860 807 -450 431 -824 811 -450 399 -824 417 -844 817 -432 807 -448 411 -872 801 -460 417 -810 425 -836 809 -420 411 -838 409 -852 417 -844 425 -852 385 -872 801 -426 841 -420 811 -422 409 -844 809 -454 823 -432 415 -842 835 -450 805 -454 403 -822 809 -450 399 -826 417 -844 821 -434 807 -448 411 -876 801 -440 807 -450 383 -850 833 -416 415 -852 807 -456 811 -444 411 -838 419 -848 401 -852 377 -850 819 -454 795 -436 809 -448 821 -448 411 -846 417 -842 817 -432 811 -412 411 -864 417 -844 791 -438 415 -876 793 -458 809 -450 383 -832 413 -840 407 -866 387 -844 821 -434 413 -874 377 -868 419 -16408 411 -392 421 -390 421 -388 421 -376 427 -394 433 -388 409 -386 411 -384 449 -382 419 -384 419 -384 419 -4018 343 -89684 97 -430 65 -166 163 -66 231 -100 161 -392 161 -64 229 -1056 97 -198 97 -198 259 -166 691 -66 395 -98 131 -100 99 -66 199 -198 1657 -406 365 -462 361 -436 357 -438 387 -444 353 -444 385 -414 387 -448 355 -448 355 -444 395 -394 399 -4050 819 -434 811 -414 819 -450 409 -852 809 -450 805 -448 805 -446 831 -428 409 -846 389 -854 395 -862 811 +RAW_Data: -452 783 -462 811 -446 411 -874 383 -852 403 -852 777 -450 411 -838 805 -452 397 -858 805 -484 387 -872 803 -442 805 -448 383 -846 797 -484 777 -474 381 -846 831 -430 807 -482 387 -852 817 -418 805 -452 823 -430 385 -878 377 -876 411 -846 391 -884 811 -444 805 -420 415 -846 399 -852 807 -452 805 -444 803 -450 803 -454 807 -452 397 -850 395 -862 385 -844 427 -840 809 -456 379 -876 407 -880 383 -846 819 -432 387 -872 375 -854 413 -846 387 -886 779 -476 803 -450 801 -444 415 -846 793 -438 415 -846 417 -822 407 -852 417 -852 817 -444 409 -16426 443 -358 431 -388 409 -386 447 -350 449 -382 419 -386 419 -386 417 -386 419 -388 453 -354 453 -356 445 -4018 813 -416 839 -420 817 -418 451 -816 835 -444 809 -450 811 -440 803 -444 407 -830 419 -844 419 -836 805 -420 835 -444 803 -446 409 -868 421 -814 431 -822 807 -452 397 -828 819 -452 415 -856 787 -454 419 -848 837 -410 839 -416 395 -866 787 -450 811 -454 407 -850 805 -454 805 -470 381 -850 833 -418 805 -438 809 -448 397 -860 421 -810 431 -856 381 -888 791 -424 841 -422 415 -820 437 -818 813 -450 813 -454 803 -446 817 -448 829 -410 451 -816 403 -818 413 -850 409 -846 811 -448 415 -834 413 -884 399 -822 815 -452 381 -852 407 -846 415 -846 385 -866 807 -456 809 -446 835 -412 407 -834 815 -450 415 -822 405 -848 419 -844 427 -852 809 -442 407 -16420 425 -422 335 -486 309 -486 309 -522 307 -492 337 -454 351 -466 329 -498 327 -468 323 -472 355 -442 355 -4120 757 -456 773 -478 781 -458 381 -874 771 -482 801 -470 777 -482 805 -450 399 -826 415 -846 387 -866 805 -420 813 -446 831 -458 417 -846 401 -852 381 -840 835 -420 415 -846 795 -440 413 -842 835 -450 407 -860 811 -418 815 -424 413 -842 807 -454 823 -428 411 -842 801 -454 807 -488 401 -822 805 -448 803 -446 803 -426 447 -844 397 -856 381 -870 411 -870 777 -452 829 -432 385 -840 419 -848 797 -438 809 -450 815 -448 833 -440 803 -452 411 -820 415 -848 409 -844 411 -846 779 -462 409 -848 409 -864 421 -844 793 -438 385 -846 419 -850 399 -838 415 -872 777 -478 803 -448 799 -442 417 -848 799 -438 415 -842 409 -826 417 -844 427 -854 807 -452 409 -16402 461 -352 421 -386 421 -386 419 -388 453 -354 453 -354 447 -378 409 -386 439 -376 421 -410 385 -414 415 -4024 831 -418 809 -438 807 -444 409 -838 809 -456 821 -432 841 -414 255 -87638 131 -66 97 -296 97 -264 131 -196 65 -132 231 -632 197 -664 131 +RAW_Data: -500 395 -132 461 -132 689 -98 2685 -100 997 -1508 99 -2186 231 -166 231 -134 133 -932 65 -268 99 -132 65 -200 97 -68 163 -234 65 -68 99 -930 331 -98 763 -100 2025 -418 353 -446 385 -414 385 -416 387 -448 355 -442 383 -412 397 -424 405 -388 409 -418 379 -418 415 -4014 443 -814 413 -822 817 -454 801 -436 409 -842 409 -866 415 -838 441 -836 811 -432 387 -842 419 -846 793 -440 807 -448 837 -446 803 -448 835 -420 807 -448 383 -868 379 -850 409 -866 387 -844 825 -468 381 -884 793 -426 415 -842 427 -818 817 -440 407 -830 419 -844 429 -852 387 -872 409 -826 811 -450 813 -418 837 -412 409 -864 417 -844 397 -852 809 -454 805 -448 409 -840 809 -420 813 -458 409 -844 407 -860 385 -878 793 -470 809 -420 817 -416 417 -850 403 -852 381 -852 827 -428 447 -844 401 -854 813 -424 421 -840 419 -812 823 -438 415 -846 409 -844 415 -846 389 -868 809 -458 803 -416 409 -866 813 -418 417 -854 397 -862 419 -842 401 -854 415 -16404 435 -376 409 -410 407 -384 439 -384 409 -410 417 -368 421 -410 407 -378 447 -376 415 -378 447 -380 407 -4022 421 -844 423 -822 821 -418 807 -454 429 -820 421 -836 439 -854 421 -810 821 -436 385 -840 441 -822 813 -448 811 -452 803 -444 835 -444 801 -446 801 -426 447 -808 423 -834 413 -852 407 -840 819 -452 389 -856 813 -444 409 -848 415 -812 809 -458 409 -848 411 -842 415 -844 421 -834 415 -834 835 -418 819 -418 807 -456 393 -856 393 -866 421 -846 799 -474 809 -420 421 -836 811 -420 813 -458 407 -850 413 -842 415 -846 819 -428 835 -416 835 -412 407 -832 421 -842 423 -822 813 -446 407 -864 419 -846 799 -440 413 -850 419 -816 797 -442 413 -850 409 -844 417 -846 423 -834 841 -428 805 -414 435 -822 813 -450 413 -822 437 -818 421 -844 429 -854 411 -16406 427 -418 309 -522 307 -488 303 -520 289 -530 295 -500 323 -470 325 -504 321 -476 321 -476 355 -444 357 -4080 355 -906 339 -882 771 -476 777 -486 381 -874 383 -884 375 -884 387 -852 819 -418 417 -846 399 -854 809 -418 815 -446 837 -420 839 -454 801 -436 807 -452 399 -826 417 -844 391 -852 423 -838 809 -452 431 -852 811 -414 409 -836 417 -844 821 -432 385 -876 385 -850 409 -848 415 -854 421 -840 817 -420 815 -424 817 -448 409 -848 413 -844 389 -854 815 -446 829 -426 413 -842 819 -434 809 -446 409 -838 419 -846 401 -852 811 -456 811 -444 803 -418 417 -848 403 -850 381 -864 805 -450 395 -866 419 -848 801 -474 381 -848 411 +RAW_Data: -842 807 -446 381 -872 377 -866 421 -846 401 -854 813 -458 779 -446 407 -832 811 -450 415 -856 399 -856 385 -876 399 -854 411 -16398 435 -392 395 -400 421 -412 385 -412 417 -384 415 -386 415 -418 385 -420 385 -420 417 -390 417 -388 419 -4020 421 -838 421 -812 819 -434 809 -448 397 -864 421 -844 401 -850 413 -858 789 -426 413 -844 419 -836 807 -424 843 -410 829 -442 835 -446 801 -454 809 -420 417 -832 411 -848 249 -88020 133 -896 231 -466 67 -1062 131 -728 163 -98 621 -98 1051 -100 680933 -452 269 -522 273 -554 273 -558 239 -558 271 -490 337 -488 321 -498 295 -500 325 -470 323 -474 353 -4082 757 -492 375 -880 357 -872 777 -486 773 -480 807 -450 805 -444 805 -476 407 -812 413 -834 411 -848 407 -828 813 -450 811 -458 803 -448 835 -446 791 -424 447 -808 427 -818 423 -840 419 -848 401 -854 811 -458 809 -446 801 -416 439 -826 415 -848 813 -430 809 -450 395 -866 419 -846 403 -850 413 -820 407 -848 415 -846 781 -460 805 -446 803 -474 803 -448 835 -420 805 -454 389 -836 409 -842 407 -866 419 -842 399 -854 809 -456 809 -446 409 -840 385 -844 819 -434 809 -450 395 -860 811 -452 393 -886 779 -446 409 -830 419 -842 423 -818 423 -838 419 -844 799 -472 809 -454 385 -844 807 -454 391 -854 395 -860 385 -844 429 -852 809 -454 385 -874 409 -16402 427 -368 455 -358 433 -380 443 -378 415 -378 447 -380 411 -384 409 -406 421 -408 387 -412 415 -386 415 -4026 831 -398 441 -810 417 -832 837 -418 833 -444 803 -446 833 -448 801 -424 449 -810 427 -820 423 -838 419 -812 825 -438 841 -416 845 -446 825 -418 809 -422 419 -822 433 -822 419 -844 425 -820 421 -840 841 -458 797 -436 809 -414 435 -822 419 -844 819 -432 809 -448 395 -864 421 -846 407 -850 411 -808 433 -824 419 -844 819 -432 809 -446 823 -416 837 -454 807 -440 809 -414 435 -828 417 -844 425 -828 415 -848 419 -818 839 -446 807 -422 411 -844 419 -846 795 -438 807 -450 395 -866 811 -454 391 -854 845 -412 407 -832 421 -842 419 -832 411 -824 435 -820 815 -450 811 -460 409 -850 799 -454 407 -824 413 -848 411 -842 415 -844 815 -432 415 -848 405 -16400 441 -432 327 -492 301 -516 307 -484 309 -520 307 -492 339 -454 337 -490 331 -464 327 -500 325 -472 325 -4110 763 -480 373 -852 385 -878 759 -482 775 -474 813 -458 781 -482 789 -454 415 -846 397 -820 411 -840 405 -852 809 -450 811 -458 809 -450 817 -448 803 -426 411 -844 391 -854 393 -866 419 -848 399 -854 811 +RAW_Data: -454 811 -444 803 -418 417 -846 403 -850 809 -452 805 -444 411 -840 419 -846 407 -850 415 -836 385 -842 419 -850 797 -438 807 -452 817 -446 801 -486 813 -444 775 -450 409 -838 419 -810 431 -854 379 -848 405 -884 809 -450 817 -430 385 -874 375 -856 811 -446 809 -422 421 -836 835 -452 419 -848 783 -460 409 -814 407 -856 415 -846 383 -870 381 -848 819 -450 811 -472 383 -850 803 -454 415 -838 399 -854 379 -850 407 -848 811 -448 415 -872 387 -16400 451 -374 445 -374 415 -378 415 -412 411 -384 405 -422 409 -410 387 -410 417 -382 417 -384 415 -420 383 -4030 827 -428 411 -842 425 -820 817 -418 833 -426 845 -452 815 -428 837 -416 409 -842 421 -810 431 -820 421 -89106 265 -662 99 -532 131 -598 97 -668 65 -300 761 -198 231 -132 265 -100 233 -100 197 diff --git a/assets/unit_tests/subghz/test_random_raw.sub b/assets/unit_tests/subghz/test_random_raw.sub index aee15a16..44e1613c 100644 --- a/assets/unit_tests/subghz/test_random_raw.sub +++ b/assets/unit_tests/subghz/test_random_raw.sub @@ -178,3 +178,8 @@ RAW_Data: -2072 1971 -2056 1971 -2074 1973 -34714 455 -3634 373 -3634 1901 -2110 RAW_Data: 4046 -17306 65 -298 97 -100 133 -268 265 -330 133 -132 1723 -16806 165 -132 99 -920 65 -622 789 -130 99 -66 361 -98 295 -166 73573 -17510 97 -492 129 -728 529 -100 1063 -164 295 -66 1119 -14962 627 -166 363 -264 427 -132 593 -100 633 -132 39555 -16938 99 -2024 65 -100 97 -164 99 -66 399 -100 123891 -16736 163 -200 97 -200 165 -264 65 -828 427 -132 871 -5132 591 -490 595 -486 605 -454 275 -822 241 -824 273 -784 321 -782 649 -444 653 -408 657 -428 321 -744 693 -388 699 -388 707 -392 313 -752 345 -750 317 -744 351 -730 355 -738 323 -774 327 -748 329 -750 695 -386 701 -354 381 -722 351 -720 385 -718 351 -718 345 -738 705 -382 329 -736 713 -360 387 -718 369 -718 367 -706 735 -352 375 -726 351 -722 351 -720 719 -7808 4845 -1474 743 -332 741 -370 705 -370 349 -718 383 -716 345 -712 381 -704 747 -326 747 -350 737 -352 351 -718 719 -360 741 -366 687 -362 375 -704 381 -724 351 -740 353 -712 357 -718 359 -744 363 -688 365 -722 727 -354 727 -354 379 -724 351 -722 353 -720 387 -718 353 -718 703 -374 351 -716 735 -354 365 -708 353 -734 351 -746 717 -356 359 -720 371 -704 371 -720 731 -7786 4847 -1482 711 -386 711 -358 743 -330 373 -708 359 -748 349 -740 351 -716 719 -356 727 -354 739 -354 351 -718 719 -362 743 -364 721 -330 373 -706 381 -722 351 -740 353 -712 359 -720 361 -722 361 -720 361 -720 725 -354 731 -354 381 -720 353 -722 385 -720 351 -720 349 -716 735 -354 361 -748 711 -364 347 -740 365 -722 365 -720 695 -384 371 -704 381 -702 377 -710 709 -7804 4853 -1468 743 -336 735 -358 719 -352 379 -724 353 -722 353 -720 387 -686 721 -360 721 -362 743 -332 387 -718 721 -366 701 -382 701 -350 377 -720 351 -740 353 -714 357 -710 397 -710 365 -702 385 -688 377 -724 731 -352 703 -354 379 -736 343 -740 357 -720 349 -706 385 -718 719 -354 365 -724 735 -352 377 -724 355 -720 353 -720 721 -358 387 -686 387 -718 353 -718 733 -7796 4821 -1492 739 -350 719 -334 737 -350 365 -722 373 -722 367 -708 371 -702 747 -352 711 -358 743 -364 343 -706 749 -352 717 -350 717 -384 327 -736 351 -746 355 -716 357 -720 359 -710 365 -742 365 -708 367 -704 711 -354 743 -356 387 -684 373 -706 381 -722 351 -740 353 -714 721 -356 361 -720 733 -352 375 -694 385 -724 353 -722 719 -356 385 -686 385 -718 351 -716 731 -7792 4843 -1480 717 -354 719 -386 717 -354 359 -720 351 -708 387 -712 355 -718 721 -356 727 -354 739 -356 351 -718 741 -364 RAW_Data: 705 -370 703 -372 351 -718 383 -720 347 -720 347 -714 381 -704 353 -744 357 -718 355 -720 723 -356 725 -354 379 -722 351 -722 353 -722 385 -718 351 -718 721 -372 351 -716 719 -372 351 -718 383 -716 345 -714 743 -346 361 -740 353 -712 357 -710 725 -7818 4837 -1498 713 -356 709 -360 741 -332 375 -706 359 -750 351 -706 353 -748 719 -356 723 -352 739 -354 351 -718 709 -364 719 -362 721 -364 385 -718 353 -718 383 -682 377 -712 349 -734 353 -742 355 -712 359 -722 723 -354 729 -352 381 -722 353 -722 351 -720 387 -718 353 -716 701 -388 345 -722 737 -354 357 -722 351 -708 387 -712 717 -350 731 -354 741 -356 743 -330 375 -8180 4829 -1468 739 -364 707 -354 729 -352 379 -722 353 -720 387 -686 387 -718 707 -368 721 -366 707 -368 351 -718 735 -354 719 -354 719 -388 329 -746 349 -738 351 -712 359 -718 361 -742 365 -708 371 -706 373 -720 733 -320 733 -354 383 -720 353 -720 387 -718 351 -716 385 -714 703 -388 327 -746 705 -348 387 -702 385 -690 385 -724 713 -358 709 -362 743 -364 709 -370 351 -8162 4837 -1482 715 -388 715 -352 715 -384 325 -730 353 -744 353 -712 359 -720 723 -354 733 -354 745 -356 351 -720 719 -362 741 -330 737 -382 349 -722 345 -724 361 -744 349 -704 383 -716 357 -718 357 -720 361 -720 723 -354 733 -354 383 -720 387 -686 387 -718 353 -718 349 -716 731 -384 347 -724 721 -352 365 -706 353 -732 353 -746 717 -356 723 -352 739 -354 711 -360 385 -8146 4841 -1470 737 -344 739 -326 751 -352 377 -690 387 -724 353 -724 353 -722 711 -360 743 -364 721 -330 387 -716 703 -386 721 -356 721 -354 363 -706 349 -734 351 -746 355 -718 355 -712 363 -744 365 -708 369 -722 695 -352 731 -354 381 -722 353 -722 351 -734 351 -716 383 -720 723 -354 333 -736 739 -348 361 -708 351 -748 355 -712 725 -354 727 -352 741 -352 713 -358 385 -8134 4855 -1474 719 -358 709 -362 721 -364 387 -716 351 -718 385 -712 347 -712 739 -334 739 -354 729 -352 379 -722 717 -354 711 -360 743 -332 387 -718 351 -716 377 -708 349 -730 353 -742 355 -710 359 -720 359 -720 723 -354 729 -352 381 -720 353 -722 351 -722 387 -684 387 -716 703 -384 349 -722 737 -354 329 -750 349 -738 353 -712 719 -356 725 -354 741 -354 717 -358 385 -8126 4861 -1470 735 -344 731 -346 729 -348 383 -718 347 -712 353 -734 353 -746 715 -356 725 -350 741 -352 351 -718 741 -366 721 -366 705 -370 353 -718 385 -682 377 -710 349 -734 353 -744 355 -710 359 -710 397 -688 RAW_Data: 727 -354 729 -352 379 -724 353 -722 353 -718 387 -716 353 -716 735 -348 383 -682 727 -386 347 -722 347 -712 381 -706 747 -326 747 -350 737 -352 711 -358 +RAW_Data: -854 811 -454 811 -444 409 -838 811 -454 823 -432 385 -842 811 -454 389 -854 821 -418 837 -444 401 -850 417 -854 395 -830 417 -846 819 -432 811 -448 789 -444 839 -454 401 -856 381 -850 825 -410 841 -418 417 -834 411 -840 827 -442 417 -844 799 -472 809 -420 411 -842 419 -848 397 -822 413 -850 799 -486 381 -848 415 -854 423 -16394 449 -358 437 -386 411 -384 449 -382 417 -384 419 -386 417 -386 419 -388 419 -388 419 -388 419 -390 437 -4036 421 -810 425 -820 393 -866 813 -422 415 -856 397 -858 811 -456 427 -820 815 -416 419 -850 401 -854 805 -420 835 -444 409 -842 809 -454 433 -820 421 -838 813 -420 417 -822 435 -820 419 -834 431 -852 411 -866 805 -420 815 -444 805 -454 403 -824 809 -448 819 -448 413 -844 811 -446 811 -456 409 -816 809 -456 389 -866 387 -842 809 -454 827 -432 413 -850 829 -428 809 -452 381 -852 799 -452 413 -852 807 -450 801 -444 409 -872 411 -840 413 -812 413 -832 807 -450 815 -442 801 -454 809 -454 429 -820 419 -838 811 -456 785 -428 409 -842 439 -824 813 -448 415 -858 819 -418 831 -426 449 -808 427 -820 393 -866 421 -808 825 -436 413 -852 403 -884 421 -16394 407 -478 257 -574 229 -576 229 -564 231 -592 267 -490 305 -520 307 -486 309 -522 307 -458 341 -486 337 -4096 343 -882 389 -880 341 -874 807 -476 351 -882 397 -860 807 -450 431 -824 811 -450 399 -824 417 -844 817 -432 807 -448 411 -872 801 -460 417 -810 425 -836 809 -420 411 -838 409 -852 417 -844 425 -852 385 -872 801 -426 841 -420 811 -422 409 -844 809 -454 823 -432 415 -842 835 -450 805 -454 403 -822 809 -450 399 -826 417 -844 821 -434 807 -448 411 -876 801 -440 807 -450 383 -850 833 -416 415 -852 807 -456 811 -444 411 -838 419 -848 401 -852 377 -850 819 -454 795 -436 809 -448 821 -448 411 -846 417 -842 817 -432 811 -412 411 -864 417 -844 791 -438 415 -876 793 -458 809 -450 383 -832 413 -840 407 -866 387 -844 821 -434 413 -874 377 -868 419 -16408 411 -392 421 -390 421 -388 421 -376 427 -394 433 -388 409 -386 411 -384 449 -382 419 -384 419 -384 419 -4018 343 -89684 97 -430 65 -166 163 -66 231 -100 161 -392 161 -64 229 -1056 97 -198 97 -198 259 -166 691 -66 395 -98 131 -100 99 -66 199 -198 1657 -406 365 -462 361 -436 357 -438 387 -444 353 -444 385 -414 387 -448 355 -448 355 -444 395 -394 399 -4050 819 -434 811 -414 819 -450 409 -852 809 -450 805 -448 805 -446 831 -428 409 -846 389 -854 395 -862 811 +RAW_Data: -452 783 -462 811 -446 411 -874 383 -852 403 -852 777 -450 411 -838 805 -452 397 -858 805 -484 387 -872 803 -442 805 -448 383 -846 797 -484 777 -474 381 -846 831 -430 807 -482 387 -852 817 -418 805 -452 823 -430 385 -878 377 -876 411 -846 391 -884 811 -444 805 -420 415 -846 399 -852 807 -452 805 -444 803 -450 803 -454 807 -452 397 -850 395 -862 385 -844 427 -840 809 -456 379 -876 407 -880 383 -846 819 -432 387 -872 375 -854 413 -846 387 -886 779 -476 803 -450 801 -444 415 -846 793 -438 415 -846 417 -822 407 -852 417 -852 817 -444 409 -16426 443 -358 431 -388 409 -386 447 -350 449 -382 419 -386 419 -386 417 -386 419 -388 453 -354 453 -356 445 -4018 813 -416 839 -420 817 -418 451 -816 835 -444 809 -450 811 -440 803 -444 407 -830 419 -844 419 -836 805 -420 835 -444 803 -446 409 -868 421 -814 431 -822 807 -452 397 -828 819 -452 415 -856 787 -454 419 -848 837 -410 839 -416 395 -866 787 -450 811 -454 407 -850 805 -454 805 -470 381 -850 833 -418 805 -438 809 -448 397 -860 421 -810 431 -856 381 -888 791 -424 841 -422 415 -820 437 -818 813 -450 813 -454 803 -446 817 -448 829 -410 451 -816 403 -818 413 -850 409 -846 811 -448 415 -834 413 -884 399 -822 815 -452 381 -852 407 -846 415 -846 385 -866 807 -456 809 -446 835 -412 407 -834 815 -450 415 -822 405 -848 419 -844 427 -852 809 -442 407 -16420 425 -422 335 -486 309 -486 309 -522 307 -492 337 -454 351 -466 329 -498 327 -468 323 -472 355 -442 355 -4120 757 -456 773 -478 781 -458 381 -874 771 -482 801 -470 777 -482 805 -450 399 -826 415 -846 387 -866 805 -420 813 -446 831 -458 417 -846 401 -852 381 -840 835 -420 415 -846 795 -440 413 -842 835 -450 407 -860 811 -418 815 -424 413 -842 807 -454 823 -428 411 -842 801 -454 807 -488 401 -822 805 -448 803 -446 803 -426 447 -844 397 -856 381 -870 411 -870 777 -452 829 -432 385 -840 419 -848 797 -438 809 -450 815 -448 833 -440 803 -452 411 -820 415 -848 409 -844 411 -846 779 -462 409 -848 409 -864 421 -844 793 -438 385 -846 419 -850 399 -838 415 -872 777 -478 803 -448 799 -442 417 -848 799 -438 415 -842 409 -826 417 -844 427 -854 807 -452 409 -16402 461 -352 421 -386 421 -386 419 -388 453 -354 453 -354 447 -378 409 -386 439 -376 421 -410 385 -414 415 -4024 831 -418 809 -438 807 -444 409 -838 809 -456 821 -432 841 -414 255 -87638 131 -66 97 -296 97 -264 131 -196 65 -132 231 -632 197 -664 131 +RAW_Data: -500 395 -132 461 -132 689 -98 2685 -100 997 -1508 99 -2186 231 -166 231 -134 133 -932 65 -268 99 -132 65 -200 97 -68 163 -234 65 -68 99 -930 331 -98 763 -100 2025 -418 353 -446 385 -414 385 -416 387 -448 355 -442 383 -412 397 -424 405 -388 409 -418 379 -418 415 -4014 443 -814 413 -822 817 -454 801 -436 409 -842 409 -866 415 -838 441 -836 811 -432 387 -842 419 -846 793 -440 807 -448 837 -446 803 -448 835 -420 807 -448 383 -868 379 -850 409 -866 387 -844 825 -468 381 -884 793 -426 415 -842 427 -818 817 -440 407 -830 419 -844 429 -852 387 -872 409 -826 811 -450 813 -418 837 -412 409 -864 417 -844 397 -852 809 -454 805 -448 409 -840 809 -420 813 -458 409 -844 407 -860 385 -878 793 -470 809 -420 817 -416 417 -850 403 -852 381 -852 827 -428 447 -844 401 -854 813 -424 421 -840 419 -812 823 -438 415 -846 409 -844 415 -846 389 -868 809 -458 803 -416 409 -866 813 -418 417 -854 397 -862 419 -842 401 -854 415 -16404 435 -376 409 -410 407 -384 439 -384 409 -410 417 -368 421 -410 407 -378 447 -376 415 -378 447 -380 407 -4022 421 -844 423 -822 821 -418 807 -454 429 -820 421 -836 439 -854 421 -810 821 -436 385 -840 441 -822 813 -448 811 -452 803 -444 835 -444 801 -446 801 -426 447 -808 423 -834 413 -852 407 -840 819 -452 389 -856 813 -444 409 -848 415 -812 809 -458 409 -848 411 -842 415 -844 421 -834 415 -834 835 -418 819 -418 807 -456 393 -856 393 -866 421 -846 799 -474 809 -420 421 -836 811 -420 813 -458 407 -850 413 -842 415 -846 819 -428 835 -416 835 -412 407 -832 421 -842 423 -822 813 -446 407 -864 419 -846 799 -440 413 -850 419 -816 797 -442 413 -850 409 -844 417 -846 423 -834 841 -428 805 -414 435 -822 813 -450 413 -822 437 -818 421 -844 429 -854 411 -16406 427 -418 309 -522 307 -488 303 -520 289 -530 295 -500 323 -470 325 -504 321 -476 321 -476 355 -444 357 -4080 355 -906 339 -882 771 -476 777 -486 381 -874 383 -884 375 -884 387 -852 819 -418 417 -846 399 -854 809 -418 815 -446 837 -420 839 -454 801 -436 807 -452 399 -826 417 -844 391 -852 423 -838 809 -452 431 -852 811 -414 409 -836 417 -844 821 -432 385 -876 385 -850 409 -848 415 -854 421 -840 817 -420 815 -424 817 -448 409 -848 413 -844 389 -854 815 -446 829 -426 413 -842 819 -434 809 -446 409 -838 419 -846 401 -852 811 -456 811 -444 803 -418 417 -848 403 -850 381 -864 805 -450 395 -866 419 -848 801 -474 381 -848 411 +RAW_Data: -842 807 -446 381 -872 377 -866 421 -846 401 -854 813 -458 779 -446 407 -832 811 -450 415 -856 399 -856 385 -876 399 -854 411 -16398 435 -392 395 -400 421 -412 385 -412 417 -384 415 -386 415 -418 385 -420 385 -420 417 -390 417 -388 419 -4020 421 -838 421 -812 819 -434 809 -448 397 -864 421 -844 401 -850 413 -858 789 -426 413 -844 419 -836 807 -424 843 -410 829 -442 835 -446 801 -454 809 -420 417 -832 411 -848 249 -88020 133 -896 231 -466 67 -1062 131 -728 163 -98 621 -98 1051 -100 680933 -452 269 -522 273 -554 273 -558 239 -558 271 -490 337 -488 321 -498 295 -500 325 -470 323 -474 353 -4082 757 -492 375 -880 357 -872 777 -486 773 -480 807 -450 805 -444 805 -476 407 -812 413 -834 411 -848 407 -828 813 -450 811 -458 803 -448 835 -446 791 -424 447 -808 427 -818 423 -840 419 -848 401 -854 811 -458 809 -446 801 -416 439 -826 415 -848 813 -430 809 -450 395 -866 419 -846 403 -850 413 -820 407 -848 415 -846 781 -460 805 -446 803 -474 803 -448 835 -420 805 -454 389 -836 409 -842 407 -866 419 -842 399 -854 809 -456 809 -446 409 -840 385 -844 819 -434 809 -450 395 -860 811 -452 393 -886 779 -446 409 -830 419 -842 423 -818 423 -838 419 -844 799 -472 809 -454 385 -844 807 -454 391 -854 395 -860 385 -844 429 -852 809 -454 385 -874 409 -16402 427 -368 455 -358 433 -380 443 -378 415 -378 447 -380 411 -384 409 -406 421 -408 387 -412 415 -386 415 -4026 831 -398 441 -810 417 -832 837 -418 833 -444 803 -446 833 -448 801 -424 449 -810 427 -820 423 -838 419 -812 825 -438 841 -416 845 -446 825 -418 809 -422 419 -822 433 -822 419 -844 425 -820 421 -840 841 -458 797 -436 809 -414 435 -822 419 -844 819 -432 809 -448 395 -864 421 -846 407 -850 411 -808 433 -824 419 -844 819 -432 809 -446 823 -416 837 -454 807 -440 809 -414 435 -828 417 -844 425 -828 415 -848 419 -818 839 -446 807 -422 411 -844 419 -846 795 -438 807 -450 395 -866 811 -454 391 -854 845 -412 407 -832 421 -842 419 -832 411 -824 435 -820 815 -450 811 -460 409 -850 799 -454 407 -824 413 -848 411 -842 415 -844 815 -432 415 -848 405 -16400 441 -432 327 -492 301 -516 307 -484 309 -520 307 -492 339 -454 337 -490 331 -464 327 -500 325 -472 325 -4110 763 -480 373 -852 385 -878 759 -482 775 -474 813 -458 781 -482 789 -454 415 -846 397 -820 411 -840 405 -852 809 -450 811 -458 809 -450 817 -448 803 -426 411 -844 391 -854 393 -866 419 -848 399 -854 811 +RAW_Data: -454 811 -444 803 -418 417 -846 403 -850 809 -452 805 -444 411 -840 419 -846 407 -850 415 -836 385 -842 419 -850 797 -438 807 -452 817 -446 801 -486 813 -444 775 -450 409 -838 419 -810 431 -854 379 -848 405 -884 809 -450 817 -430 385 -874 375 -856 811 -446 809 -422 421 -836 835 -452 419 -848 783 -460 409 -814 407 -856 415 -846 383 -870 381 -848 819 -450 811 -472 383 -850 803 -454 415 -838 399 -854 379 -850 407 -848 811 -448 415 -872 387 -16400 451 -374 445 -374 415 -378 415 -412 411 -384 405 -422 409 -410 387 -410 417 -382 417 -384 415 -420 383 -4030 827 -428 411 -842 425 -820 817 -418 833 -426 845 -452 815 -428 837 -416 409 -842 421 -810 431 -820 421 -89106 265 -662 99 -532 131 -598 97 -668 65 -300 761 -198 231 -132 265 -100 233 -100 197 diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 65ab375e..846041c3 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -2569,12 +2569,14 @@ Function,+,subghz_block_generic_get_preset_name,void,"const char*, FuriString*" Function,+,subghz_block_generic_serialize,_Bool,"SubGhzBlockGeneric*, FlipperFormat*, SubGhzRadioPreset*" Function,+,subghz_environment_alloc,SubGhzEnvironment*, Function,+,subghz_environment_free,void,SubGhzEnvironment* +Function,+,subghz_environment_get_alutech_at_4n_rainbow_table_file_name,const char*,SubGhzEnvironment* Function,+,subghz_environment_get_came_atomo_rainbow_table_file_name,const char*,SubGhzEnvironment* Function,+,subghz_environment_get_keystore,SubGhzKeystore*,SubGhzEnvironment* Function,+,subghz_environment_get_nice_flor_s_rainbow_table_file_name,const char*,SubGhzEnvironment* Function,+,subghz_environment_get_protocol_name_registry,const char*,"SubGhzEnvironment*, size_t" Function,+,subghz_environment_get_protocol_registry,void*,SubGhzEnvironment* Function,+,subghz_environment_load_keystore,_Bool,"SubGhzEnvironment*, const char*" +Function,+,subghz_environment_set_alutech_at_4n_rainbow_table_file_name,void,"SubGhzEnvironment*, const char*" Function,+,subghz_environment_set_came_atomo_rainbow_table_file_name,void,"SubGhzEnvironment*, const char*" Function,+,subghz_environment_set_nice_flor_s_rainbow_table_file_name,void,"SubGhzEnvironment*, const char*" Function,+,subghz_environment_set_protocol_registry,void,"SubGhzEnvironment*, void*" diff --git a/lib/subghz/environment.c b/lib/subghz/environment.c index 0a4b7b60..b39b259d 100644 --- a/lib/subghz/environment.c +++ b/lib/subghz/environment.c @@ -6,6 +6,7 @@ struct SubGhzEnvironment { const SubGhzProtocolRegistry* protocol_registry; const char* came_atomo_rainbow_table_file_name; const char* nice_flor_s_rainbow_table_file_name; + const char* alutech_at_4n_rainbow_table_file_name; }; SubGhzEnvironment* subghz_environment_alloc() { @@ -57,6 +58,21 @@ const char* return instance->came_atomo_rainbow_table_file_name; } +void subghz_environment_set_alutech_at_4n_rainbow_table_file_name( + SubGhzEnvironment* instance, + const char* filename) { + furi_assert(instance); + + instance->alutech_at_4n_rainbow_table_file_name = filename; +} + +const char* + subghz_environment_get_alutech_at_4n_rainbow_table_file_name(SubGhzEnvironment* instance) { + furi_assert(instance); + + return instance->alutech_at_4n_rainbow_table_file_name; +} + void subghz_environment_set_nice_flor_s_rainbow_table_file_name( SubGhzEnvironment* instance, const char* filename) { diff --git a/lib/subghz/environment.h b/lib/subghz/environment.h index e994f7c9..7bd38ba2 100644 --- a/lib/subghz/environment.h +++ b/lib/subghz/environment.h @@ -52,6 +52,23 @@ void subghz_environment_set_came_atomo_rainbow_table_file_name( */ const char* subghz_environment_get_came_atomo_rainbow_table_file_name(SubGhzEnvironment* instance); +/** + * Set filename to work with Alutech at-4n. + * @param instance Pointer to a SubGhzEnvironment instance + * @param filename Full path to the file + */ +void subghz_environment_set_alutech_at_4n_rainbow_table_file_name( + SubGhzEnvironment* instance, + const char* filename); + +/** + * Get filename to work with Alutech at-4n. + * @param instance Pointer to a SubGhzEnvironment instance + * @return Full path to the file + */ +const char* + subghz_environment_get_alutech_at_4n_rainbow_table_file_name(SubGhzEnvironment* instance); + /** * Set filename to work with Nice Flor-S. * @param instance Pointer to a SubGhzEnvironment instance diff --git a/lib/subghz/protocols/alutech_at_4n.c b/lib/subghz/protocols/alutech_at_4n.c new file mode 100644 index 00000000..6bcf9f25 --- /dev/null +++ b/lib/subghz/protocols/alutech_at_4n.c @@ -0,0 +1,455 @@ +#include "alutech_at_4n.h" +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocoAlutech_at_4n" + +#define SUBGHZ_NO_ALUTECH_AT_4N_RAINBOW_TABLE 0xFFFFFFFF + +static const SubGhzBlockConst subghz_protocol_alutech_at_4n_const = { + .te_short = 400, + .te_long = 800, + .te_delta = 140, + .min_count_bit_for_found = 72, +}; + +struct SubGhzProtocolDecoderAlutech_at_4n { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; + + uint64_t data; + uint32_t crc; + uint16_t header_count; + + const char* alutech_at_4n_rainbow_table_file_name; +}; + +struct SubGhzProtocolEncoderAlutech_at_4n { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + Alutech_at_4nDecoderStepReset = 0, + Alutech_at_4nDecoderStepCheckPreambula, + Alutech_at_4nDecoderStepSaveDuration, + Alutech_at_4nDecoderStepCheckDuration, +} Alutech_at_4nDecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_alutech_at_4n_decoder = { + .alloc = subghz_protocol_decoder_alutech_at_4n_alloc, + .free = subghz_protocol_decoder_alutech_at_4n_free, + + .feed = subghz_protocol_decoder_alutech_at_4n_feed, + .reset = subghz_protocol_decoder_alutech_at_4n_reset, + + .get_hash_data = subghz_protocol_decoder_alutech_at_4n_get_hash_data, + .serialize = subghz_protocol_decoder_alutech_at_4n_serialize, + .deserialize = subghz_protocol_decoder_alutech_at_4n_deserialize, + .get_string = subghz_protocol_decoder_alutech_at_4n_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_alutech_at_4n_encoder = { + .alloc = NULL, + .free = NULL, + + .deserialize = NULL, + .stop = NULL, + .yield = NULL, +}; + +const SubGhzProtocol subghz_protocol_alutech_at_4n = { + .name = SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME, + .type = SubGhzProtocolTypeDynamic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + + .decoder = &subghz_protocol_alutech_at_4n_decoder, + .encoder = &subghz_protocol_alutech_at_4n_encoder, +}; + +/** + * Read bytes from rainbow table + * @param file_name Full path to rainbow table the file + * @param number_alutech_at_4n_magic_data number in the array + * @return alutech_at_4n_magic_data + */ +static uint32_t subghz_protocol_alutech_at_4n_get_magic_data_in_file( + const char* file_name, + 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 alutech_at_4n_magic_data = 0; + + if(subghz_keystore_raw_get_data(file_name, address, buffer, sizeof(uint32_t))) { + for(size_t i = 0; i < sizeof(uint32_t); 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; +} + +static uint8_t subghz_protocol_alutech_at_4n_crc(uint64_t data) { + uint8_t* p = (uint8_t*)&data; + uint8_t crc = 0xff; + for(uint8_t y = 0; y < 8; y++) { + crc = crc ^ p[y]; + for(uint8_t i = 0; i < 8; i++) { + if((crc & 0x80) != 0) { + crc <<= 1; + crc ^= 0x31; + } else { + crc <<= 1; + } + } + } + return crc; +} + +static uint8_t subghz_protocol_alutech_at_4n_decrypt_data_crc(uint8_t data) { + uint8_t crc = data; + for(uint8_t i = 0; i < 8; i++) { + if((crc & 0x80) != 0) { + crc <<= 1; + crc ^= 0x31; + } else { + crc <<= 1; + } + } + return ~crc; +} + +static uint64_t subghz_protocol_alutech_at_4n_decrypt(uint64_t data, const char* file_name) { + uint8_t* p = (uint8_t*)&data; + 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 data3 = 0; + 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_in_file(file_name, 1), + subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 2), + subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 3), + subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 4), + subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 5)}; + + uint32_t i = magic_data[0]; + do { + data2 = data2 - + ((magic_data[1] + (data1 << 4)) ^ ((magic_data[2] + (data1 >> 5)) ^ (data1 + i))); + data3 = data2 + i; + i += magic_data[3]; + data1 = + data1 - ((magic_data[4] + (data2 << 4)) ^ ((magic_data[5] + (data2 >> 5)) ^ data3)); + } while(i != 0); + + p[0] = (uint8_t)(data1 >> 24); + p[1] = (uint8_t)(data1 >> 16); + p[3] = (uint8_t)data1; + p[4] = (uint8_t)(data2 >> 24); + p[5] = (uint8_t)(data2 >> 16); + p[2] = (uint8_t)(data1 >> 8); + p[6] = (uint8_t)(data2 >> 8); + p[7] = (uint8_t)data2; + + return data; +} + +// static uint64_t subghz_protocol_alutech_at_4n_encrypt(uint64_t data, const char* file_name) { +// uint8_t* p = (uint8_t*)&data; +// uint32_t data1 = 0; +// 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 magic_data[] = { +// subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 6), +// subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 4), +// subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 5), +// subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 1), +// subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 2), +// subghz_protocol_alutech_at_4n_get_magic_data_in_file(file_name, 0)}; + +// do { +// data1 = data1 + magic_data[0]; +// data2 = data2 + ((magic_data[1] + (data3 << 4)) ^ +// ((magic_data[2] + (data3 >> 5)) ^ (data1 + data3))); +// data3 = data3 + ((magic_data[3] + (data2 << 4)) ^ +// ((magic_data[4] + (data2 >> 5)) ^ (data1 + data2))); +// } while(data1 != magic_data[5]); +// p[0] = (uint8_t)(data2 >> 24); +// p[1] = (uint8_t)(data2 >> 16); +// p[3] = (uint8_t)data2; +// p[4] = (uint8_t)(data3 >> 24); +// p[5] = (uint8_t)(data3 >> 16); +// p[2] = (uint8_t)(data2 >> 8); +// p[6] = (uint8_t)(data3 >> 8); +// p[7] = (uint8_t)data3; + +// return data; +// } + +void* subghz_protocol_decoder_alutech_at_4n_alloc(SubGhzEnvironment* environment) { + SubGhzProtocolDecoderAlutech_at_4n* instance = + malloc(sizeof(SubGhzProtocolDecoderAlutech_at_4n)); + instance->base.protocol = &subghz_protocol_alutech_at_4n; + instance->generic.protocol_name = instance->base.protocol->name; + instance->alutech_at_4n_rainbow_table_file_name = + subghz_environment_get_alutech_at_4n_rainbow_table_file_name(environment); + if(instance->alutech_at_4n_rainbow_table_file_name) { + FURI_LOG_I( + TAG, "Loading rainbow table from %s", instance->alutech_at_4n_rainbow_table_file_name); + } + return instance; +} + +void subghz_protocol_decoder_alutech_at_4n_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderAlutech_at_4n* instance = context; + instance->alutech_at_4n_rainbow_table_file_name = NULL; + free(instance); +} + +void subghz_protocol_decoder_alutech_at_4n_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderAlutech_at_4n* instance = context; + instance->decoder.parser_step = Alutech_at_4nDecoderStepReset; +} + +void subghz_protocol_decoder_alutech_at_4n_feed(void* context, bool level, uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderAlutech_at_4n* instance = context; + + switch(instance->decoder.parser_step) { + case Alutech_at_4nDecoderStepReset: + if((level) && DURATION_DIFF(duration, subghz_protocol_alutech_at_4n_const.te_short) < + subghz_protocol_alutech_at_4n_const.te_delta) { + instance->decoder.parser_step = Alutech_at_4nDecoderStepCheckPreambula; + instance->header_count++; + } + break; + case Alutech_at_4nDecoderStepCheckPreambula: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_alutech_at_4n_const.te_short) < + subghz_protocol_alutech_at_4n_const.te_delta)) { + instance->decoder.parser_step = Alutech_at_4nDecoderStepReset; + break; + } + if((instance->header_count > 2) && + (DURATION_DIFF(duration, subghz_protocol_alutech_at_4n_const.te_short * 10) < + subghz_protocol_alutech_at_4n_const.te_delta * 10)) { + // Found header + instance->decoder.parser_step = Alutech_at_4nDecoderStepSaveDuration; + instance->decoder.decode_data = 0; + instance->data = 0; + instance->decoder.decode_count_bit = 0; + } else { + instance->decoder.parser_step = Alutech_at_4nDecoderStepReset; + instance->header_count = 0; + } + break; + case Alutech_at_4nDecoderStepSaveDuration: + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = Alutech_at_4nDecoderStepCheckDuration; + } + break; + case Alutech_at_4nDecoderStepCheckDuration: + if(!level) { + if(duration >= ((uint32_t)subghz_protocol_alutech_at_4n_const.te_short * 2 + + subghz_protocol_alutech_at_4n_const.te_delta)) { + //add last bit + if(DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_alutech_at_4n_const.te_short) < + subghz_protocol_alutech_at_4n_const.te_delta) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + } else if( + DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_alutech_at_4n_const.te_long) < + subghz_protocol_alutech_at_4n_const.te_delta * 2) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + } + + // Found end TX + instance->decoder.parser_step = Alutech_at_4nDecoderStepReset; + if(instance->decoder.decode_count_bit == + subghz_protocol_alutech_at_4n_const.min_count_bit_for_found) { + if(instance->generic.data != instance->data) { + instance->generic.data = instance->data; + + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + instance->crc = instance->decoder.decode_data; + + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + } + instance->decoder.decode_data = 0; + instance->data = 0; + instance->decoder.decode_count_bit = 0; + instance->header_count = 0; + } + break; + } else if( + (DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_alutech_at_4n_const.te_short) < + subghz_protocol_alutech_at_4n_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_alutech_at_4n_const.te_long) < + subghz_protocol_alutech_at_4n_const.te_delta * 2)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + if(instance->decoder.decode_count_bit == 64) { + instance->data = instance->decoder.decode_data; + instance->decoder.decode_data = 0; + } + instance->decoder.parser_step = Alutech_at_4nDecoderStepSaveDuration; + } else if( + (DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_alutech_at_4n_const.te_long) < + subghz_protocol_alutech_at_4n_const.te_delta * 2) && + (DURATION_DIFF(duration, subghz_protocol_alutech_at_4n_const.te_short) < + subghz_protocol_alutech_at_4n_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + if(instance->decoder.decode_count_bit == 64) { + instance->data = instance->decoder.decode_data; + instance->decoder.decode_data = 0; + } + instance->decoder.parser_step = Alutech_at_4nDecoderStepSaveDuration; + } else { + instance->decoder.parser_step = Alutech_at_4nDecoderStepReset; + instance->header_count = 0; + } + } else { + instance->decoder.parser_step = Alutech_at_4nDecoderStepReset; + instance->header_count = 0; + } + break; + } +} + +/** + * Analysis of received data + * @param instance Pointer to a SubGhzBlockGeneric* instance + * @param file_name Full path to rainbow table the file + */ +static void subghz_protocol_alutech_at_4n_remote_controller( + SubGhzBlockGeneric* instance, + uint8_t crc, + const char* file_name) { + /** + * Message format 72bit LSB first + * data crc + * XXXXXXXXXXXXXXXX CC + * + * For analysis, you need to turn the package MSB + * in decoded messages format + * + * crc1 serial cnt key + * cc SSSSSSSS XXxx BB + * + * crc1 is calculated from the lower part of cnt + * key 1=0xff, 2=0x11, 3=0x22, 4=0x33, 5=0x44 + * + */ + + bool status = false; + uint64_t data = subghz_protocol_blocks_reverse_key(instance->data, 64); + crc = subghz_protocol_blocks_reverse_key(crc, 8); + + if(crc == subghz_protocol_alutech_at_4n_crc(data)) { + data = subghz_protocol_alutech_at_4n_decrypt(data, file_name); + status = true; + } + + if(status && ((uint8_t)(data >> 56) == + subghz_protocol_alutech_at_4n_decrypt_data_crc((uint8_t)((data >> 8) & 0xFF)))) { + instance->btn = (uint8_t)data & 0xFF; + instance->cnt = (uint16_t)(data >> 8) & 0xFFFF; + instance->serial = (uint32_t)(data >> 24) & 0xFFFFFFFF; + } + + if(!status) { + instance->btn = 0; + instance->cnt = 0; + instance->serial = 0; + } +} + +uint8_t subghz_protocol_decoder_alutech_at_4n_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderAlutech_at_4n* instance = context; + return (uint8_t)instance->crc; +} + +bool subghz_protocol_decoder_alutech_at_4n_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderAlutech_at_4n* instance = context; + bool res = subghz_block_generic_serialize(&instance->generic, flipper_format, preset); + if(res && !flipper_format_write_uint32(flipper_format, "CRC", &instance->crc, 1)) { + FURI_LOG_E(TAG, "Unable to add CRC"); + res = false; + } + return res; + + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +bool subghz_protocol_decoder_alutech_at_4n_deserialize( + void* context, + FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderAlutech_at_4n* instance = context; + bool ret = false; + do { + if(!subghz_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + subghz_protocol_alutech_at_4n_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + if(!flipper_format_rewind(flipper_format)) { + FURI_LOG_E(TAG, "Rewind error"); + break; + } + if(!flipper_format_read_uint32(flipper_format, "CRC", (uint32_t*)&instance->crc, 1)) { + FURI_LOG_E(TAG, "Missing CRC"); + break; + } + ret = true; + } while(false); + return ret; +} + +void subghz_protocol_decoder_alutech_at_4n_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderAlutech_at_4n* instance = context; + subghz_protocol_alutech_at_4n_remote_controller( + &instance->generic, instance->crc, instance->alutech_at_4n_rainbow_table_file_name); + uint32_t code_found_hi = instance->generic.data >> 32; + uint32_t code_found_lo = instance->generic.data & 0x00000000ffffffff; + + furi_string_cat_printf( + output, + "%s %d\r\n" + "Key:0x%08lX%08lX%02X\r\n" + "Sn:0x%08lX Btn:0x%01X\r\n" + "Cnt:0x%03lX\r\n", + + instance->generic.protocol_name, + instance->generic.data_count_bit, + code_found_hi, + code_found_lo, + (uint8_t)instance->crc, + instance->generic.serial, + instance->generic.btn, + instance->generic.cnt); +} diff --git a/lib/subghz/protocols/alutech_at_4n.h b/lib/subghz/protocols/alutech_at_4n.h new file mode 100644 index 00000000..38bac3ea --- /dev/null +++ b/lib/subghz/protocols/alutech_at_4n.h @@ -0,0 +1,74 @@ +#pragma once +#include "base.h" + +#define SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME "Alutech at-4n" + +typedef struct SubGhzProtocolDecoderAlutech_at_4n SubGhzProtocolDecoderAlutech_at_4n; +typedef struct SubGhzProtocolEncoderAlutech_at_4n SubGhzProtocolEncoderAlutech_at_4n; + +extern const SubGhzProtocolDecoder subghz_protocol_alutech_at_4n_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_alutech_at_4n_encoder; +extern const SubGhzProtocol subghz_protocol_alutech_at_4n; + +/** + * Allocate SubGhzProtocolDecoderAlutech_at_4n. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderAlutech_at_4n* pointer to a SubGhzProtocolDecoderAlutech_at_4n instance + */ +void* subghz_protocol_decoder_alutech_at_4n_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderAlutech_at_4n. + * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance + */ +void subghz_protocol_decoder_alutech_at_4n_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderAlutech_at_4n. + * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance + */ +void subghz_protocol_decoder_alutech_at_4n_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_alutech_at_4n_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_alutech_at_4n_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderAlutech_at_4n. + * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param preset The modulation on which the signal was received, SubGhzRadioPreset + * @return true On success + */ +bool subghz_protocol_decoder_alutech_at_4n_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderAlutech_at_4n. + * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return true On success + */ +bool subghz_protocol_decoder_alutech_at_4n_deserialize( + void* context, + FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderAlutech_at_4n instance + * @param output Resulting text + */ +void subghz_protocol_decoder_alutech_at_4n_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/came_atomo.c b/lib/subghz/protocols/came_atomo.c index 3f6045be..2e271848 100644 --- a/lib/subghz/protocols/came_atomo.c +++ b/lib/subghz/protocols/came_atomo.c @@ -189,7 +189,7 @@ void subghz_protocol_decoder_came_atomo_feed(void* context, bool level, uint32_t /** * Read bytes from rainbow table * @param file_name Full path to rainbow table the file - * @param number_atomo_magic_xor Сell number in the array + * @param number_atomo_magic_xor number in the array * @return atomo_magic_xor */ static uint64_t subghz_protocol_came_atomo_get_magic_xor_in_file( diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 6a9c3468..4a3602fb 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -390,11 +390,14 @@ void subghz_protocol_decoder_keeloq_feed(void* context, bool level, uint32_t dur subghz_protocol_keeloq_const.te_delta)) { // Found end TX instance->decoder.parser_step = KeeloqDecoderStepReset; - if(instance->decoder.decode_count_bit >= - subghz_protocol_keeloq_const.min_count_bit_for_found) { + if((instance->decoder.decode_count_bit >= + subghz_protocol_keeloq_const.min_count_bit_for_found) && + (instance->decoder.decode_count_bit <= + subghz_protocol_keeloq_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 = instance->decoder.decode_count_bit; + instance->generic.data_count_bit = + subghz_protocol_keeloq_const.min_count_bit_for_found; if(instance->base.callback) instance->base.callback(&instance->base, instance->base.context); } @@ -411,6 +414,8 @@ void subghz_protocol_decoder_keeloq_feed(void* context, bool level, uint32_t dur if(instance->decoder.decode_count_bit < subghz_protocol_keeloq_const.min_count_bit_for_found) { subghz_protocol_blocks_add_bit(&instance->decoder, 1); + } else { + instance->decoder.decode_count_bit++; } instance->decoder.parser_step = KeeloqDecoderStepSaveDuration; } else if( @@ -421,6 +426,8 @@ void subghz_protocol_decoder_keeloq_feed(void* context, bool level, uint32_t dur if(instance->decoder.decode_count_bit < subghz_protocol_keeloq_const.min_count_bit_for_found) { subghz_protocol_blocks_add_bit(&instance->decoder, 0); + } else { + instance->decoder.decode_count_bit++; } instance->decoder.parser_step = KeeloqDecoderStepSaveDuration; } else { diff --git a/lib/subghz/protocols/protocol_items.c b/lib/subghz/protocols/protocol_items.c index 99de18c9..3904c181 100644 --- a/lib/subghz/protocols/protocol_items.c +++ b/lib/subghz/protocols/protocol_items.c @@ -40,6 +40,7 @@ const SubGhzProtocol* subghz_protocol_registry_items[] = { &subghz_protocol_holtek_th12x, &subghz_protocol_linear_delta3, &subghz_protocol_dooya, + &subghz_protocol_alutech_at_4n, }; const SubGhzProtocolRegistry subghz_protocol_registry = { diff --git a/lib/subghz/protocols/protocol_items.h b/lib/subghz/protocols/protocol_items.h index 4d1551bb..cd9b7c6e 100644 --- a/lib/subghz/protocols/protocol_items.h +++ b/lib/subghz/protocols/protocol_items.h @@ -40,5 +40,6 @@ #include "smc5326.h" #include "holtek_ht12x.h" #include "dooya.h" +#include "alutech_at_4n.h" extern const SubGhzProtocolRegistry subghz_protocol_registry;