diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/feron.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/feron.sub new file mode 100644 index 00000000000..14c293ca81c --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/feron.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Feron +Bit: 32 +Key: 00 00 00 00 63 38 84 7B diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/feron_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/feron_raw.sub new file mode 100644 index 00000000000..16249dce5d9 --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/feron_raw.sub @@ -0,0 +1,31 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 329 -296 295 -66 163 -98 2441 -66 9337 -5690 131 -2574 65 -692 65 -460 165 -230 329 -266 131 -134 97 -400 197 -66 197 -66 12303 -5844 97 -200 167 -102 197 -334 297 -100 559 -166 133 -132 3425 -98 99 -13334 65 -66 129 -822 99 -598 133 -366 131 -68 163 -100 131 -66 99 -98 361 -130 63 -296 2175 -100 163 -100 1095 -100 859 -7534 165 -5584 99 -198 99 -1066 99 -232 99 -266 67 -66 99 -132 97 -564 131 -66 197 -132 231 -98 261 -560 195 -166 885 -98 1579 -198 729 -134 431 -68 5783 -5922 131 -992 65 -166 1459 -262 65 -526 97 -100 163 -230 65 -362 197 -958 99 -634 99 -132 65 -234 99 -394 527 -132 461 -130 323 -18704 231 -564 99 -600 133 -98 1359 -66 165 -166 133 -232 1657 -98 1907 -132 4497 -496 99 -66 167 -100 133 -168 233 -264 167 -66 863 -296 399 -68 2453 -134 635 -66 331 -200 395 -134 7025 -4436 165 -528 99 -298 229 -162 97 -362 197 -524 361 -428 65 -66 99 -166 199 -66 67 -198 165 -466 99 -428 263 -330 361 -132 293 -296 225 -66 3753 -66 291 -66 133 -66 6907 -4898 63 -558 65 -918 99 -100 623 -132 359 -100 457 -98 97 -98 363 -100 559 -132 297 -166 129 -296 97 -262 99 -722 297 -196 1187 -266 199 -168 133 -68 597 -66 301 -132 429 -64 6665 -5372 65 -1054 329 -200 167 -100 629 -100 293 -200 165 -100 133 -132 133 -332 197 -100 233 -496 65 -166 561 -232 165 -296 1127 -64 2753 -66 755 -164 12059 -360 65 -266 99 -66 65 -2612 99 -1780 97 -164 1083 -330 197 -100 397 -66 2095 -98 793 -102 65 -100 10223 -594 65 -232 97 -984 131 -296 99 -166 99 -664 197 -66 261 -230 97 -68 1683 -266 691 -98 335 -66 133 -8384 99 -2300 97 -1710 165 -230 229 -426 97 -134 359 -300 555 -164 193 -132 99 -132 163 -100 497 -298 823 -12964 99 -1874 97 -132 97 -262 97 -328 133 -100 231 -198 131 -132 195 -460 63 -198 131 -66 195 -66 1791 -100 97 -66 131 -64 955 -66 559 -98 233 -66 4633 -5270 263 -100 131 -198 99 -164 331 -132 303 -134 133 -430 233 -1192 67 -498 99 -302 233 -300 597 -66 99 -132 1261 -134 65 -5292 63 -756 131 -884 131 -130 231 -98 197 -198 195 -66 97 -592 261 -298 163 -922 163 -164 65 -656 131 -68 231 -66 99 -430 1295 -68 529 -100 1263 -68 1687 -14880 99 -236 65 -566 163 -758 99 -68 461 -98 559 -130 165 -162 995 -100 1787 -196 195 -524 295 -66 821 -66 5703 -3860 63 -3736 523 -166 161 -64 97 -132 163 -164 257 -164 197 -656 229 -1420 +RAW_Data: 99 -598 97 -168 297 -132 199 -232 629 -132 131 -100 97 -266 499 -66 597 -166 229 -66 429 -68 3463 -3518 97 -2346 265 -66 433 -66 503 -464 65 -68 987 -98 131 -98 557 -66 1583 -66 431 -100 1097 -134 5651 -6742 99 -830 197 -102 233 -398 67 -66 197 -168 267 -366 197 -332 363 -364 131 -2374 329 -66 331 -200 133 -100 333 -134 299 -66 4079 -5972 101 -1558 393 -230 331 -330 63 -98 65 -328 131 -426 133 -66 197 -196 65 -1352 65 -590 97 -230 161 -96 163 -230 329 -198 97 -134 1525 -66 433 -168 1455 -230 6225 -2024 99 -266 99 -268 133 -264 297 -100 167 -168 233 -168 267 -660 369 -234 337 -300 97 -132 263 -134 1133 -200 137 -136 265 -166 167 -232 99 -300 167 -66 99 -200 197 -462 131 -432 99 -300 165 -862 197 -496 531 -332 231 -132 1015 -100 427 -100 197 -1018 99 -66 97 -200 199 -168 199 -100 465 -100 197 -68 65 -132 3155 -66 12365 -328 131 -696 133 -896 265 -472 165 -132 133 -232 129 -68 165 -66 723 -564 529 -66 1491 -266 99 -132 397 -66 501 -6672 65 -1580 97 -1420 199 -166 265 -134 699 -168 133 -100 663 -66 637 -68 2119 -66 697 -66 1027 -66 3319 -7648 97 -162 293 -460 197 -230 591 -166 227 -98 65 -262 329 -198 163 -128 97 -328 131 -426 229 -368 299 -202 265 -168 331 -100 729 -68 1597 -66 133 -66 961 -68 231 -166 99 -234 5397 -5158 65 -1328 97 -502 99 -166 199 -198 131 -68 199 -264 231 -436 163 -332 199 -100 131 -166 165 -168 97 -100 133 -600 165 -1754 99 -66 195 -228 263 -164 297 -232 365 -200 499 -66 297 -66 1625 -66 399 -166 5011 -6110 97 -1482 65 -264 367 -166 65 -68 465 -892 197 -330 231 -430 133 -12408 129 -5982 295 -562 165 -132 1033 -66 997 -66 799 -66 297 -196 959 -100 729 -66 2115 -66 2639 -5752 99 -802 365 -232 97 -362 97 -2510 131 -534 99 -296 131 -268 1161 -66 131 -66 1057 -100 1325 -66 463 -4028 97 -364 65 -728 197 -234 99 -100 97 -100 65 -132 265 -428 333 -628 195 -262 99 -228 131 -1766 163 -562 297 -132 465 -302 165 -100 133 -198 365 -132 465 -66 1787 -4594 65 -2792 65 -164 131 -66 131 -98 197 -296 131 -332 165 -330 693 -298 101 -366 265 -1892 65 -134 65 -164 201 -200 65 -266 265 -232 133 -200 235 -200 1001 -68 991 -66 597 -100 963 -200 2913 -9784 65 -426 229 -954 131 -398 531 -198 97 -98 163 -130 131 -326 359 -100 2367 -168 691 -100 13125 -362 65 -394 197 -332 133 -200 299 -366 167 -264 299 -132 835 -234 2493 -132 +RAW_Data: 99 -134 565 -334 231 -134 167 -200 1425 -132 3943 -3864 563 -66 233 -2296 99 -198 165 -234 199 -298 263 -134 131 -530 299 -398 233 -1336 165 -166 65 -132 99 -232 295 -130 99 -328 97 -132 97 -66 97 -132 65 -262 2145 -132 195 -196 65 -362 231 -196 261 -98 65 -198 229 -132 229 -196 793 -66 555 -100 297 -66 493 -230 359 -100 195 -296 229 -66 99 -166 10343 -3654 165 -1392 65 -834 65 -132 495 -100 395 -232 331 -360 265 -132 1681 -5474 165 -2122 65 -200 65 -232 99 -1132 65 -200 165 -102 133 -68 199 -100 663 -234 165 -298 163 -68 1597 -98 1199 -66 197 -332 5539 -1934 65 -3354 133 -168 167 -2354 101 -930 65 -1266 131 -298 99 -1328 259 -232 563 -200 297 -100 65 -132 131 -66 1681 -100 267 -98 331 -168 299 -132 629 -66 5981 -2810 165 -3282 99 -132 227 -98 163 -430 231 -330 293 -66 65 -164 99 -958 65 -134 67 -432 99 -1426 297 -264 295 -132 363 -332 97 -366 133 -98 2869 -102 1755 -100 2911 -7466 261 -196 193 -260 259 -298 135 -66 133 -400 199 -266 195 -334 97 -268 365 -864 129 -1132 395 -300 395 -132 933 -200 367 -134 997 -66 233 -198 5415 -5556 65 -1292 65 -68 131 -268 165 -264 231 -1792 65 -764 65 -1394 299 -396 451 -854 323 -808 97 -62 227 -838 231 -868 635 -460 669 -402 275 -810 271 -838 681 -398 711 -388 691 -392 275 -832 279 -780 311 -774 741 -376 285 -776 321 -762 325 -776 297 -776 765 -324 345 -752 345 -724 341 -756 767 -326 773 -334 743 -340 771 -348 313 -770 741 -350 753 -556 497 -4666 359 -736 779 -318 759 -326 351 -758 347 -726 339 -760 767 -322 775 -334 351 -734 341 -732 769 -318 781 -326 777 -334 355 -724 349 -740 347 -724 775 -324 349 -734 353 -734 355 -756 347 -724 771 -326 347 -758 345 -732 353 -732 755 -350 771 -320 765 -322 763 -356 317 -758 755 -352 755 -524 557 -4642 323 -746 795 -320 773 -296 389 -722 347 -726 375 -724 767 -324 779 -332 355 -724 347 -724 775 -326 779 -334 747 -338 357 -730 355 -728 355 -756 743 -350 355 -722 353 -720 349 -754 345 -758 743 -346 331 -756 323 -744 361 -752 761 -322 773 -332 747 -336 779 -310 343 -764 735 -348 773 -516 561 -4620 349 -744 781 -320 763 -330 351 -756 347 -724 341 -758 769 -324 775 -332 351 -736 341 -734 771 -324 777 -322 773 -332 355 -724 349 -724 377 -724 769 -324 347 -758 345 -734 351 -732 351 -722 791 -320 351 -726 359 -736 321 -768 753 -322 801 -330 753 -334 755 -336 353 -732 765 -354 727 -548 +RAW_Data: 545 -4646 351 -738 755 -322 801 -296 389 -722 347 -740 347 -726 773 -326 777 -334 355 -730 355 -730 779 -308 777 -346 743 -348 321 -758 353 -722 351 -750 769 -314 333 -742 351 -740 361 -720 363 -754 761 -322 345 -756 347 -724 339 -756 767 -324 775 -332 745 -338 779 -310 357 -728 777 -348 739 -550 513 -4672 323 -776 749 -320 763 -328 353 -758 347 -740 347 -726 771 -326 777 -334 355 -724 349 -758 743 -326 777 -332 747 -340 351 -732 343 -736 351 -756 755 -320 371 -724 375 -724 335 -746 337 -746 771 -326 349 -756 347 -722 341 -756 767 -326 775 -332 747 -338 777 -310 343 -766 745 -346 759 -546 509 -4650 345 -770 743 -324 785 -326 347 -758 345 -734 349 -734 769 -344 763 -296 373 -744 333 -754 765 -322 777 -332 745 -340 351 -732 343 -734 351 -756 753 -322 367 -724 341 -760 335 -748 337 -756 767 -324 345 -756 345 -734 351 -732 767 -314 797 -296 769 -322 801 -296 353 -756 777 -332 747 -536 537 -4634 359 -742 777 -320 763 -328 349 -756 347 -726 339 -756 767 -322 775 -334 355 -732 355 -728 779 -310 757 -338 757 -342 351 -732 343 -734 353 -758 753 -322 367 -724 341 -760 335 -748 337 -756 765 -324 347 -736 351 -724 377 -726 769 -324 777 -334 747 -338 779 -310 343 -764 739 -330 769 -546 523 -4664 343 -758 743 -346 761 -324 347 -752 335 -754 333 -746 769 -324 775 -334 351 -734 341 -734 773 -324 775 -322 779 -332 355 -722 349 -740 347 -724 773 -324 351 -756 347 -724 339 -758 337 -748 769 -322 347 -756 347 -722 341 -756 767 -324 777 -332 747 -338 779 -310 341 -766 771 -298 767 -548 523 -4658 329 -770 777 -320 755 -328 349 -756 347 -740 347 -726 773 -324 777 -332 357 -722 349 -754 743 -326 779 -334 745 -342 351 -734 349 -752 347 -722 781 -312 333 -780 321 -742 361 -752 331 -752 763 -324 343 -756 347 -734 351 -734 767 -322 765 -352 753 -346 753 -296 373 -750 763 -322 775 -530 535 -4632 359 -736 779 -320 761 -328 351 -732 351 -758 347 -724 775 -326 781 -330 355 -724 349 -756 743 -326 779 -334 745 -340 351 -732 341 -762 317 -776 749 -320 367 -722 339 -758 337 -746 337 -746 773 -326 347 -736 351 -754 347 -726 771 -324 779 -332 747 -340 779 -310 343 -768 745 -348 753 -516 543 -4650 383 -716 769 -348 753 -326 343 -750 333 -754 335 -744 769 -324 775 -334 351 -734 343 -736 771 -324 775 -322 775 -332 351 -734 353 -722 349 -754 755 -318 337 -768 319 -766 325 -746 361 -752 763 -320 345 -756 345 -726 +RAW_Data: 337 -746 771 -324 777 -334 743 -340 769 -352 311 -768 741 -324 781 -520 561 -4636 359 -736 777 -320 757 -326 349 -756 347 -724 341 -758 769 -324 777 -332 351 -734 341 -734 773 -324 779 -320 773 -332 349 -734 353 -722 349 -756 753 -352 301 -766 319 -768 325 -746 365 -752 761 -322 345 -724 377 -734 351 -732 767 -316 761 -332 767 -322 769 -330 351 -766 745 -336 777 -512 541 -4668 325 -742 779 -320 761 -330 351 -756 347 -740 347 -724 773 -324 779 -332 355 -730 355 -726 777 -346 755 -308 777 -346 319 -760 309 -764 347 -752 751 -320 367 -724 375 -722 337 -746 337 -746 771 -326 349 -756 347 -724 339 -756 767 -324 775 -330 745 -340 769 -322 341 -766 743 -322 781 -552 529 -4628 359 -736 781 -318 759 -328 351 -734 341 -766 323 -746 779 -322 761 -328 351 -766 353 -724 777 -330 751 -336 753 -336 355 -728 355 -726 355 -756 741 -352 353 -722 351 -722 347 -752 349 -738 777 -320 361 -724 339 -756 335 -746 769 -326 775 -334 747 -338 755 -340 357 -724 783 -330 747 -538 539 -4658 347 -750 753 -320 763 -330 351 -732 353 -756 347 -724 775 -326 781 -332 355 -724 347 -756 741 -326 779 -334 747 -340 351 -734 349 -752 347 -722 779 -312 333 -780 323 -740 361 -752 331 -754 763 -320 345 -756 345 -724 339 -746 771 -324 779 -332 747 -338 769 -320 343 -766 741 -348 753 -556 531 -4624 349 -776 747 -320 765 -328 351 -758 347 -726 339 -758 767 -324 777 -332 351 -732 343 -732 771 -318 781 -324 777 -332 355 -722 349 -722 379 -734 745 -340 351 -732 345 -734 349 -760 323 -746 793 -322 341 -722 379 -722 339 -744 771 -324 775 -334 745 -340 757 -340 355 -728 779 -346 741 -548 511 -4676 323 -744 777 -318 763 -328 351 -758 347 -724 377 -722 767 -326 777 -332 355 -732 353 -724 777 -332 745 -338 777 -310 343 -734 349 -744 353 -742 759 -322 371 -734 351 -732 345 -734 353 -756 755 -322 367 -724 341 -770 349 -734 767 -318 765 -332 765 -320 761 -328 351 -756 745 -362 747 -536 537 -4662 317 -778 747 -322 797 -294 389 -724 347 -728 337 -746 771 -326 777 -334 351 -734 343 -734 777 -326 773 -322 775 -330 355 -724 349 -732 351 -732 767 -352 333 -736 351 -738 325 -780 331 -752 763 -322 345 -736 351 -758 345 -724 769 -324 777 -332 743 -340 769 -356 317 -752 769 -314 787 -514 539 -4638 345 -768 773 -320 753 -326 351 -760 347 -712 379 -724 773 -322 777 -334 351 -734 355 -718 789 -320 769 -324 759 -348 323 -758 355 -720 351 -720 +RAW_Data: 801 -314 333 -740 351 -740 361 -720 363 -754 761 -322 345 -726 377 -724 337 -746 769 -324 777 -334 743 -340 769 -320 343 -768 739 -324 783 -552 529 -4634 359 -736 779 -320 757 -326 351 -760 345 -722 341 -756 767 -322 777 -334 349 -736 353 -720 763 -354 759 -320 755 -350 331 -740 353 -740 327 -748 793 -320 341 -758 345 -722 337 -746 339 -746 773 -324 349 -756 345 -724 341 -756 767 -326 775 -334 745 -338 777 -310 343 -764 771 -296 767 -548 523 -4650 347 -742 781 -320 765 -328 351 -732 351 -758 347 -724 777 -326 779 -332 353 -724 349 -754 741 -326 779 -334 745 -342 351 -732 349 -754 347 -722 779 -348 299 -778 321 -742 363 -718 363 -754 763 -322 343 -758 345 -732 351 -732 769 -354 725 -350 755 -348 737 -350 353 -722 763 -354 757 -510 543 -4652 353 -742 791 -288 773 -330 351 -734 387 -722 347 -724 775 -326 781 -330 355 -732 355 -730 745 -342 777 -346 755 -310 357 -726 355 -724 353 -758 755 -348 355 -722 351 -722 349 -756 345 -756 747 -346 329 -752 321 -746 361 -752 763 -322 773 -332 751 -336 745 -342 341 -768 749 -346 753 -514 543 -4656 349 -756 755 -318 789 -316 333 -744 353 -742 359 -718 791 -320 773 -332 357 -724 349 -740 779 -296 785 -334 755 -336 353 -732 341 -736 353 -750 753 -320 369 -724 375 -712 375 -712 375 -736 749 -338 353 -730 343 -734 349 -754 753 -320 801 -294 779 -338 777 -310 341 -764 771 -296 799 -514 523 -4664 347 -756 745 -346 757 -318 349 -756 335 -756 335 -746 767 -324 777 -332 353 -730 343 -732 771 -326 775 -324 777 -332 357 -724 347 -726 375 -736 747 -338 353 -732 341 -734 349 -756 325 -744 793 -320 343 -726 377 -724 337 -746 769 -324 777 -334 747 -338 767 -322 341 -766 741 -322 785 -518 563 -4622 349 -744 783 -320 761 -326 353 -756 347 -724 375 -724 767 -324 777 -334 355 -724 349 -740 745 -330 779 -336 747 -342 353 -732 351 -722 383 -718 781 -314 333 -742 353 -742 361 -716 363 -754 765 -322 345 -724 379 -724 337 -746 769 -324 779 -334 745 -340 777 -312 341 -764 771 -296 769 -546 523 -4654 359 -734 779 -320 757 -328 349 -756 347 -720 377 -742 743 -326 777 -334 353 -722 349 -754 743 -360 745 -336 743 -342 343 -736 329 -768 321 -768 757 -322 369 -722 341 -770 349 -734 311 -768 777 -326 311 -778 331 -746 335 -754 767 -324 775 -332 745 -340 777 -312 355 -760 755 -346 741 -88244 133 -132 99 -232 165 -100 97 -730 99 -66 2213 -264 995 -100 631 -132 6925 -4032 +RAW_Data: 133 -66 65 -2118 165 -1032 197 -66 65 -66 197 -66 99 -132 267 -66 297 -434 133 -134 133 -68 65 -66 131 -266 299 -64 67 -362 161 -296 165 -132 229 -66 361 -498 197 -132 657 -132 1031 -98 1595 -100 965 -132 165 -7880 99 -164 99 -564 67 -928 165 -166 231 -100 65 -166 333 -66 165 -266 165 -398 953 -132 1755 -66 1541 -98 4449 -8044 99 -166 303 -368 591 -132 359 -264 227 -164 99 -1550 299 -200 435 -100 67 -66 593 -132 2943 -134 895 -198 3879 -7540 99 -938 99 -860 99 -1392 99 -1474 197 -166 199 -134 99 -264 233 -134 265 -100 397 -134 1497 -2162 99 -1496 67 -1392 99 -230 233 -66 735 -66 567 -364 197 -66 99 -232 2109 -64 429 -98 99 -98 131 -66 359 -198 195 -162 4861 -4980 131 -950 131 -228 359 -1078 297 -398 231 -262 231 -66 65 -726 295 -366 199 -232 229 -328 459 -68 231 -132 367 -132 3483 -100 597 -134 7113 -1274 99 -236 165 -4414 199 -1432 67 -298 267 -166 329 -234 529 -200 197 -296 129 -294 163 -98 65 -362 131 -100 65 -1426 959 -332 265 -66 297 -166 2683 -66 535 -66 199 -4286 99 -164 525 -1224 363 -166 199 -270 131 -1758 165 -200 557 -298 163 -132 329 -68 233 -66 965 -100 99 -166 365 -234 1391 -9070 131 -1526 97 -1546 131 -98 329 -364 363 -132 329 -164 1183 -10266 65 -6530 65 -732 131 -398 197 -230 195 -98 65 -364 63 -458 65 -198 65 -658 65 -196 163 -98 1805 -98 463 -164 99 -66 623 -98 423 -228 325 -66 233 -100 5543 -5982 97 -1486 331 -198 131 -526 133 -232 131 -132 131 -66 231 -98 131 -134 629 -2026 65 -266 163 -334 265 -66 363 -134 2383 -134 131 -68 233 -98 6503 -98 1329 -9556 65 -166 463 -66 133 -166 233 -266 203 -68 67 -168 99 -66 1161 -66 1667 -132 265 -168 197 -100 199 -200 889 -15904 99 -132 133 -300 1093 -198 201 -132 133 -366 1193 -166 101 -66 935 -134 367 -14672 195 -824 131 -788 395 -430 231 -166 99 -68 99 -17390 65 -1062 65 -498 99 -134 99 -368 65 -66 65 -464 65 -332 265 -132 231 -66 597 -266 133 -330 165 -100 2127 -234 1395 -132 10439 -1004 67 -698 97 -2784 65 -66 265 -264 133 -528 331 -100 131 -234 2027 -164 693 -100 65 -134 197 -130 97 -66 457 -100 4649 -4556 65 -3626 67 -464 65 -100 133 -100 131 -532 67 -566 133 -134 231 -564 65 -166 99 -134 165 -102 65 -1206 199 -666 1261 -66 1031 -132 869 -134 199 -66 597 -100 7409 -7344 97 -296 99 -232 99 -232 65 -662 263 -66 131 -266 397 -100 363 -66 2553 -98 531 -166 +RAW_Data: 7313 -3784 133 -168 133 -1022 99 -558 361 -68 65 -66 97 -166 229 -132 265 -198 97 -792 97 -132 97 -558 163 -264 161 -658 197 -294 231 -328 193 -130 295 -166 231 -166 65 -98 489 -66 885 -100 921 -66 461 -66 323 -304 99 -3408 65 -166 99 -66 195 -296 265 -134 133 -364 65 -296 197 -228 97 -294 231 -368 1387 -66 133 -166 1133 -100 333 -68 431 -66 165 -134 4955 -5736 97 -1088 99 -100 99 -166 199 -264 131 -68 165 -398 199 -630 99 -66 233 -68 403 -98 233 -662 133 -1126 65 -228 131 -98 65 -490 199 -132 229 -232 491 -64 429 -66 667 -100 167 -200 531 -100 263 -264 295 -100 429 -14212 97 -956 65 -930 363 -66 299 -200 331 -66 63 -100 131 -230 1215 -66 1425 -132 927 -132 8041 -732 133 -1064 97 -270 269 -298 129 -228 65 -262 65 -198 459 -100 667 -166 129 -688 67 -2106 97 -232 329 -64 1065 -66 99 -334 167 -132 969 -100 1855 -98 1189 -100 5599 -4798 99 -2932 557 -200 163 -492 295 -758 457 -1788 99 -198 131 -402 197 -134 129 -524 231 -266 1295 -68 1135 -102 701 -10576 65 -5130 63 -100 97 -464 395 -298 99 -100 365 -134 201 -100 99 -100 2515 -98 1611 -132 327 -3806 97 -2502 197 -654 131 -196 97 -196 163 -392 263 -1018 97 -826 197 -130 331 -298 367 -98 267 -68 803 -236 367 -132 851 -166 299 -100 6833 -6158 65 -1062 199 -294 163 -326 227 -724 65 -164 1215 -132 855 -198 467 -66 431 -200 393 -100 229 -98 10229 -338 197 -1756 97 -298 263 -166 97 -164 195 -228 131 -198 199 -234 533 -66 529 -134 397 -100 165 -166 199 -168 99 -100 99 -166 301 -202 529 -66 921 -98 6861 -7702 65 -400 65 -1856 201 -134 65 -100 197 -166 199 -300 165 -134 65 -20006 99 -332 561 -164 199 -630 133 -66 99 -134 131 -200 2393 -134 199 -132 1127 -6284 67 -1900 97 -494 131 -490 163 -264 231 -66 197 -130 327 -164 129 -332 133 -132 3021 -13676 97 -1056 63 -232 65 -264 295 -596 731 -66 295 -66 161 -66 589 -68 3121 -66 199 -68 299 -100 629 -68 8427 -262 405 -744 739 -362 743 -338 353 -760 317 -756 313 -768 741 -360 741 -356 339 -756 307 -786 741 -358 743 -334 743 -374 311 -772 295 -774 319 -764 753 -352 341 -756 307 -758 337 -744 339 -772 743 -338 353 -726 353 -760 313 -766 773 -312 753 -330 771 -354 737 -362 317 -754 745 -364 743 -538 539 -4668 325 -742 781 -320 761 -328 349 -756 347 -724 341 -744 775 -326 777 -334 355 -732 353 -722 779 -332 745 -338 769 -352 311 -768 317 -760 325 -776 +RAW_Data: 761 -320 345 -734 351 -732 345 -770 317 -760 753 -322 369 -724 341 -756 335 -756 765 -324 775 -332 747 -338 755 -340 343 -736 781 -346 755 -516 543 -4650 349 -756 755 -352 755 -314 333 -776 321 -740 361 -752 763 -322 773 -332 353 -722 347 -736 781 -332 745 -338 771 -318 343 -736 351 -758 325 -774 761 -322 341 -736 349 -736 349 -756 347 -724 773 -326 347 -756 345 -724 341 -768 747 -338 777 -344 741 -344 739 -348 353 -722 763 -354 757 -510 543 -4654 353 -740 757 -354 771 -296 353 -756 347 -724 341 -758 769 -326 777 -332 349 -736 341 -736 775 -326 775 -320 773 -330 355 -720 349 -736 349 -754 741 -330 351 -756 347 -722 343 -758 337 -744 771 -324 347 -756 345 -736 349 -734 767 -346 765 -296 769 -354 739 -330 353 -758 743 -364 747 -536 535 -4668 325 -740 777 -320 761 -328 349 -758 347 -722 341 -758 769 -324 777 -334 353 -732 353 -722 777 -332 745 -338 769 -354 315 -752 317 -768 319 -766 755 -322 371 -724 375 -724 337 -746 339 -754 767 -326 345 -756 345 -734 351 -732 755 -350 767 -314 765 -346 757 -324 349 -744 767 -326 775 -530 537 -4636 359 -738 777 -318 761 -328 353 -732 389 -696 389 -724 777 -330 747 -336 357 -730 355 -728 779 -310 779 -348 741 -348 321 -758 353 -722 351 -752 769 -314 333 -742 353 -740 361 -718 363 -752 763 -322 345 -734 351 -726 377 -726 771 -324 777 -332 747 -338 769 -320 343 -766 739 -324 783 -522 561 -4654 315 -778 747 -320 767 -328 351 -758 347 -726 341 -758 765 -324 779 -330 357 -724 347 -724 773 -326 779 -334 747 -340 357 -728 355 -728 355 -758 739 -352 355 -722 341 -736 353 -754 321 -744 793 -318 345 -724 379 -724 337 -746 771 -324 777 -332 755 -336 779 -310 343 -732 779 -346 757 -514 543 -4650 351 -756 753 -352 751 -348 329 -752 321 -746 361 -752 761 -322 775 -298 387 -730 355 -724 781 -296 781 -336 755 -336 353 -730 343 -736 349 -756 751 -322 369 -734 351 -732 345 -732 353 -756 751 -322 369 -726 375 -712 375 -734 747 -338 777 -310 771 -352 733 -344 341 -740 757 -322 803 -528 533 -4634 359 -736 779 -318 763 -328 349 -758 347 -724 339 -756 767 -324 777 -334 351 -734 343 -732 773 -326 775 -322 777 -332 355 -730 357 -722 347 -726 773 -326 349 -734 353 -732 387 -698 389 -724 777 -296 387 -722 347 -726 375 -714 773 -324 777 -334 745 -342 779 -310 343 -766 747 -346 757 -514 543 -4654 341 -764 779 -296 767 -320 373 -724 377 -724 335 -746 771 -324 777 -332 +RAW_Data: 353 -734 343 -732 771 -324 777 -322 779 -332 355 -732 355 -724 347 -724 777 -324 349 -756 347 -724 339 -746 375 -734 747 -338 351 -732 343 -734 349 -756 753 -320 801 -328 747 -336 757 -336 357 -724 781 -332 745 -536 539 -4642 359 -738 779 -318 761 -328 351 -736 353 -756 347 -724 771 -324 777 -334 357 -724 349 -724 775 -326 779 -334 745 -340 351 -732 345 -734 351 -756 753 -322 369 -724 377 -702 383 -734 341 -734 773 -324 345 -752 333 -748 335 -748 771 -324 775 -334 745 -338 779 -312 357 -728 777 -350 741 -548 511 -4676 325 -740 781 -320 763 -328 351 -758 347 -724 341 -746 775 -326 775 -334 355 -732 355 -724 779 -330 747 -336 779 -310 357 -728 355 -724 353 -756 767 -322 351 -722 345 -766 319 -762 325 -778 761 -320 345 -724 377 -724 337 -758 767 -322 775 -332 755 -336 745 -342 341 -732 769 -330 769 -546 523 -4664 345 -742 779 -320 759 -326 349 -736 353 -756 347 -726 771 -324 779 -334 351 -734 341 -736 779 -324 773 -320 777 -296 389 -728 357 -722 349 -724 777 -326 347 -726 379 -734 351 -734 351 -722 793 -322 351 -720 343 -762 323 -744 779 -320 763 -328 781 -334 755 -336 353 -734 767 -316 761 -536 541 -4650 349 -756 753 -352 755 -312 333 -746 353 -742 361 -752 765 -322 773 -298 389 -722 349 -724 775 -326 781 -332 747 -338 357 -728 355 -726 355 -724 799 -322 351 -718 347 -740 353 -738 359 -720 793 -320 343 -724 379 -726 337 -748 767 -324 779 -332 747 -338 757 -340 357 -728 755 -342 757 -538 539 -4660 317 -780 751 -320 767 -328 353 -756 347 -740 347 -726 771 -326 777 -334 355 -730 357 -724 781 -330 747 -336 747 -342 353 -732 349 -754 347 -720 777 -316 341 -746 361 -720 363 -754 331 -748 767 -322 347 -732 355 -758 321 -754 769 -320 765 -354 757 -322 757 -352 331 -736 777 -320 757 -556 533 -4634 359 -738 779 -320 761 -326 351 -756 347 -722 373 -726 767 -322 775 -334 355 -724 349 -724 773 -326 779 -334 747 -338 353 -732 343 -734 349 -760 751 -320 371 -740 347 -726 375 -726 335 -748 769 -322 347 -734 351 -732 345 -768 743 -322 785 -324 777 -334 753 -336 357 -728 777 -312 777 -546 509 -4670 323 -744 779 -320 763 -328 353 -732 353 -732 389 -722 777 -330 747 -338 357 -724 349 -756 741 -328 779 -336 745 -340 341 -736 347 -742 351 -740 791 -288 373 -724 379 -712 377 -724 337 -748 769 -322 347 -758 347 -724 339 -746 771 -324 777 -334 747 -340 767 -322 341 -766 739 -348 755 -558 527 -4632 +RAW_Data: 359 -736 781 -318 761 -326 351 -756 347 -726 339 -748 771 -324 783 -332 351 -736 341 -734 771 -324 775 -322 775 -332 351 -736 341 -734 347 -750 753 -322 367 -742 347 -724 339 -746 375 -734 747 -338 357 -728 353 -728 353 -724 775 -350 767 -320 757 -350 739 -352 353 -724 765 -322 761 -556 523 -4648 347 -754 753 -322 767 -328 351 -734 387 -732 355 -722 779 -330 747 -338 355 -730 355 -728 753 -340 777 -312 791 -310 357 -728 355 -728 353 -758 741 -352 355 -722 351 -720 383 -720 345 -758 745 -346 331 -756 323 -742 361 -752 763 -322 773 -332 749 -336 777 -310 343 -734 781 -346 755 -514 543 -4652 349 -752 769 -348 749 -318 347 -746 337 -754 335 -756 767 -320 775 -332 351 -734 343 -736 775 -326 775 -320 773 -332 351 -734 341 -732 349 -754 749 -322 367 -732 353 -732 343 -734 349 -756 753 -322 371 -734 349 -734 343 -734 775 -322 783 -322 777 -332 747 -338 357 -728 777 -312 791 -508 541 -4660 349 -750 751 -320 765 -330 351 -732 353 -732 389 -722 781 -296 785 -334 357 -730 355 -724 779 -330 747 -338 779 -310 357 -728 355 -726 355 -758 737 -352 341 -732 349 -752 323 -744 363 -746 763 -322 347 -756 345 -726 337 -758 767 -322 775 -332 747 -338 779 -310 343 -764 771 -296 767 -548 523 -4660 345 -756 771 -326 771 -318 345 -724 379 -722 337 -758 767 -324 777 -330 351 -734 341 -738 775 -326 773 -320 775 -300 383 -736 309 -764 347 -754 749 -322 367 -722 341 -760 337 -746 339 -746 773 -324 347 -756 345 -724 339 -746 773 -326 777 -332 747 -340 779 -310 357 -726 765 -356 757 -524 545 -4646 351 -740 791 -320 771 -328 357 -722 349 -724 377 -726 767 -322 777 -334 351 -734 341 -734 769 -316 783 -324 777 -332 353 -732 343 -734 349 -752 751 -322 367 -736 349 -732 353 -752 347 -722 781 -312 333 -744 353 -744 361 -754 763 -320 771 -332 753 -336 747 -340 353 -734 787 -318 759 -548 511 -4672 323 -778 749 -320 763 -328 353 -758 347 -740 347 -726 775 -326 777 -332 357 -722 349 -726 775 -326 777 -334 755 -338 351 -732 343 -732 353 -756 755 -320 369 -722 377 -712 375 -702 389 -724 779 -294 353 -758 347 -724 377 -722 769 -322 777 -332 747 -338 779 -310 343 -764 771 -296 767 -548 523 -4666 345 -758 745 -346 759 -324 347 -752 335 -754 333 -748 769 -322 777 -332 353 -732 343 -730 771 -326 777 -322 777 -334 351 -734 353 -720 351 -754 755 -318 335 -766 319 -764 357 -718 363 -754 765 -318 345 -724 379 -732 351 -732 +RAW_Data: 765 -316 791 -316 775 -322 775 -330 357 -730 747 -340 781 -510 543 -4670 325 -740 779 -322 761 -328 351 -764 319 -756 347 -756 741 -328 777 -336 349 -736 313 -766 771 -326 777 -322 773 -332 353 -720 349 -734 349 -764 735 -350 333 -742 351 -740 325 -780 331 -746 767 -324 343 -756 345 -724 339 -754 767 -324 775 -334 745 -338 771 -350 311 -768 741 -356 751 -91544 97 -1916 131 -560 161 -784 65 -64 495 -98 589 -296 2305 -15072 197 -1258 65 -130 97 -164 97 -98 297 -198 201 -234 261 -98 99 -66 1333 -166 759 -98 95 -196 295 -66 491 -64 163 -66 4795 -4508 131 -922 65 -166 129 -164 163 -66 131 -164 65 -164 99 -196 163 -264 229 -164 65 -164 131 -1932 231 -164 261 -130 65 -264 65 -362 727 -130 2635 -66 327 -66 2397 -4778 65 -364 67 -1134 67 -438 99 -864 163 -366 1187 -830 99 -328 165 -100 131 -134 199 -568 99 -100 99 -466 231 -560 131 -100 129 -132 329 -64 263 -296 1049 -132 333 -98 703 -364 231 -13082 99 -2554 133 -832 133 -164 395 -132 295 -164 65 -66 131 -66 131 -132 65 -134 955 -100 99 -66 961 -66 4911 -4040 65 -2524 165 -896 65 -498 65 -66 99 -232 133 -268 197 -300 265 -266 133 -400 395 -166 297 -98 131 -1020 97 -492 199 -100 563 -132 99 -66 133 -100 3051 -66 591 -196 195 -162 1921 -66 9139 -3400 129 -692 301 -1262 131 -100 265 -166 337 -134 363 -66 133 -332 233 -134 919 -64 2019 -132 295 -132 165 -200 6921 -4912 133 -336 165 -98 99 -66 261 -298 63 -100 65 -264 163 -296 297 -132 465 -100 65 -332 195 -196 165 -334 97 -100 131 -132 165 -300 629 -66 65 -66 165 -134 663 -134 233 -66 861 -66 3939 -134 567 -1310 163 -2894 229 -168 99 -234 431 -494 97 -396 133 -66 1563 -100 497 -198 265 -14052 65 -524 99 -398 923 -66 3991 -6098 99 -1626 99 -1394 99 -100 265 -200 163 -168 97 -432 99 -100 133 -200 4699 -4592 63 -1486 65 -1786 131 -66 197 -334 101 -400 99 -200 99 -168 131 -100 99 -430 231 -234 167 -2338 763 -364 263 -66 131 -200 263 -132 333 -66 3823 -198 1091 -1186 65 -756 65 -494 99 -1546 97 -1432 131 -66 131 -132 295 -132 131 -300 231 -562 99 -66 363 -100 663 -166 457 -66 3199 -6668 99 -962 65 -164 133 -132 131 -266 363 -430 363 -364 99 -66 365 -132 67 -2376 299 -166 165 -130 161 -360 97 -132 953 -198 2041 -66 855 -12212 95 -330 97 -164 97 -1388 65 -366 99 -964 165 -398 163 -232 427 -66 363 -98 133 -166 895 -98 1519 -132 101 -100 +RAW_Data: 133 -166 691 -100 8965 -4740 131 -196 99 -162 231 -226 195 -524 263 -98 391 -66 97 -98 489 -98 2167 -66 129 -198 263 -66 397 -9262 65 -164 97 -2798 197 -830 265 -232 463 -228 425 -230 2667 -132 67 -164 197 -98 2023 -14336 99 -922 65 -1262 531 -100 65 -200 97 -200 197 -102 133 -134 99 -168 395 -100 133 -68 199 -100 855 -66 9821 -5296 65 -4678 229 -166 265 -134 131 -100 65 -166 167 -132 1217 -66 1351 -98 393 -164 487 -12590 99 -2428 131 -434 131 -330 65 -98 131 -298 163 -66 229 -232 559 -66 1805 -66 3565 -100 4163 -4266 67 -3536 65 -824 229 -132 399 -166 67 -100 231 -166 497 -1526 99 -560 231 -134 133 -68 665 -230 291 -230 4463 -66 199 -100 1419 -832 65 -200 65 -464 199 -866 265 -264 231 -100 331 -100 65 -100 131 -100 2415 -132 827 -168 1991 -3852 65 -1928 67 -2620 99 -560 65 -362 65 -198 493 -132 525 -360 231 -100 1017 -132 555 -198 825 -100 10151 -296 131 -698 131 -300 99 -502 99 -966 293 -264 97 -66 395 -430 65 -164 131 -96 97 -98 1617 -132 455 -132 1017 -16428 65 -164 97 -458 131 -66 163 -132 429 -98 463 -66 397 -68 97 -100 367 -100 829 -332 231 -134 1655 -4488 165 -102 165 -830 197 -458 163 -164 65 -132 97 -694 297 -2498 99 -302 165 -764 133 -166 131 -100 763 -98 657 -66 819 -132 229 -130 97 -64 361 -66 401 -66 2079 -5522 99 -2848 297 -298 165 -332 99 -562 99 -1280 99 -594 165 -264 491 -132 99 -164 393 -132 461 -100 465 -132 799 -12900 65 -1660 133 -2006 613 -792 669 -430 671 -436 219 -842 289 -810 259 -826 689 -390 699 -396 311 -782 311 -774 739 -346 737 -348 741 -354 327 -774 307 -772 349 -734 769 -314 345 -742 353 -740 327 -748 363 -750 763 -324 343 -756 347 -722 337 -756 767 -324 775 -334 745 -338 777 -310 343 -766 739 -330 767 -548 523 -4662 345 -760 745 -346 757 -324 347 -752 333 -754 333 -746 769 -326 779 -332 319 -768 309 -766 773 -324 777 -322 773 -330 355 -730 353 -730 353 -722 779 -332 349 -736 311 -768 323 -750 353 -742 759 -352 341 -738 347 -756 345 -720 769 -326 775 -334 745 -340 779 -310 355 -728 787 -346 739 -546 511 -4674 323 -746 781 -320 763 -328 351 -756 347 -726 339 -746 771 -324 779 -334 357 -724 349 -724 777 -326 779 -332 747 -338 351 -732 345 -736 347 -758 751 -320 371 -734 351 -732 343 -736 351 -756 751 -322 369 -736 349 -734 343 -736 771 -324 779 -324 775 -334 755 -336 357 -728 777 -312 775 -548 509 -4676 323 -742 +RAW_Data: 783 -320 759 -328 351 -758 345 -726 375 -722 767 -326 777 -332 357 -722 349 -740 781 -296 781 -336 745 -342 351 -732 353 -754 347 -718 769 -344 333 -756 323 -744 361 -718 365 -752 763 -320 345 -758 345 -734 349 -732 767 -346 761 -316 775 -322 773 -332 351 -734 769 -320 757 -548 513 -4668 347 -752 751 -322 765 -328 353 -756 347 -726 375 -714 773 -326 775 -334 355 -730 353 -724 783 -330 745 -338 777 -312 355 -728 353 -726 353 -756 765 -322 351 -722 345 -770 319 -760 325 -750 791 -320 343 -724 379 -726 335 -746 771 -324 775 -334 745 -340 769 -322 341 -768 741 -322 783 -520 563 -4658 325 -738 777 -318 765 -326 351 -758 347 -724 341 -758 769 -324 775 -332 351 -734 341 -734 773 -324 777 -320 775 -332 355 -724 347 -740 349 -740 777 -296 353 -756 347 -724 375 -724 337 -748 767 -324 349 -732 351 -730 345 -770 743 -324 783 -324 779 -334 745 -340 357 -730 775 -312 791 -508 541 -4664 323 -776 747 -320 767 -328 351 -734 353 -732 353 -766 751 -336 747 -340 357 -730 355 -726 777 -348 755 -310 791 -310 357 -728 355 -726 355 -758 755 -348 319 -758 341 -736 323 -780 319 -744 791 -320 341 -724 377 -724 339 -756 765 -324 775 -332 745 -340 779 -310 343 -764 735 -350 771 -516 527 -4664 345 -760 743 -346 759 -324 349 -752 333 -754 335 -746 767 -324 777 -334 351 -734 341 -734 773 -324 777 -322 775 -332 351 -734 341 -734 347 -754 749 -322 367 -734 351 -732 351 -754 347 -720 785 -314 333 -742 351 -740 361 -752 763 -322 773 -332 751 -334 745 -342 341 -764 739 -332 769 -546 521 -4664 347 -756 745 -346 757 -324 347 -752 333 -754 335 -748 767 -322 777 -332 355 -724 347 -758 741 -328 779 -334 753 -338 351 -732 343 -732 349 -756 753 -322 369 -734 351 -732 343 -736 349 -756 751 -322 371 -734 349 -734 343 -736 775 -324 779 -322 779 -332 745 -338 351 -732 767 -344 765 -512 549 -4650 343 -756 771 -326 769 -320 345 -722 379 -724 339 -744 771 -324 779 -334 349 -736 341 -734 771 -324 779 -322 775 -330 351 -734 343 -732 349 -752 751 -320 369 -734 349 -734 349 -756 333 -732 775 -324 347 -752 333 -746 337 -746 771 -324 777 -332 755 -338 747 -340 353 -732 755 -354 765 -512 543 -4646 351 -744 789 -322 773 -296 387 -724 347 -724 375 -724 771 -324 775 -332 351 -734 341 -736 771 -324 777 -322 775 -332 355 -724 347 -724 377 -736 743 -340 351 -732 343 -734 349 -758 325 -746 795 -288 373 -724 377 -732 351 -732 769 -320 +RAW_Data: 765 -354 759 -320 753 -352 335 -736 779 -320 757 -556 533 -4636 359 -734 779 -318 761 -328 349 -756 347 -742 347 -722 773 -326 777 -332 357 -724 349 -756 743 -326 781 -334 747 -338 353 -732 351 -720 383 -718 783 -312 333 -744 353 -740 363 -720 363 -752 763 -322 343 -758 345 -734 351 -732 765 -346 765 -296 801 -320 773 -298 353 -766 745 -338 779 -510 543 -4670 325 -742 777 -320 761 -328 353 -766 355 -722 349 -738 777 -330 747 -338 357 -728 353 -728 777 -348 741 -350 739 -350 355 -722 351 -720 381 -722 781 -314 341 -740 361 -720 363 -754 331 -748 767 -322 347 -732 351 -730 345 -770 743 -324 785 -324 777 -334 747 -338 353 -732 765 -350 769 -498 565 -4652 333 -746 767 -324 777 -334 355 -724 347 -726 377 -724 767 -324 777 -334 351 -734 341 -734 771 -324 779 -322 775 -332 355 -730 355 -732 353 -724 779 -330 351 -734 341 -734 347 -754 323 -742 795 -320 341 -724 379 -724 337 -744 771 -324 777 -334 745 -340 777 -312 357 -728 787 -310 779 -546 511 -4674 325 -738 779 -320 763 -328 353 -732 353 -766 355 -722 779 -328 747 -336 357 -724 349 -758 741 -328 779 -334 747 -340 353 -732 351 -720 383 -716 767 -318 341 -776 333 -748 335 -756 333 -744 769 -324 347 -732 355 -758 355 -722 755 -350 757 -348 741 -350 737 -352 353 -722 765 -354 759 -524 521 -4650 349 -758 751 -322 799 -296 353 -758 349 -724 375 -724 767 -322 775 -334 353 -734 353 -720 765 -344 767 -320 757 -326 351 -734 351 -758 347 -726 773 -326 347 -758 345 -722 339 -758 335 -746 769 -326 347 -734 341 -766 323 -744 781 -320 763 -328 783 -334 749 -338 355 -728 755 -342 779 -512 543 -4670 325 -742 779 -320 761 -328 351 -756 347 -724 377 -726 767 -322 777 -334 355 -732 355 -730 745 -340 757 -338 779 -312 355 -730 353 -726 351 -756 767 -322 351 -724 383 -720 345 -758 325 -740 777 -320 363 -722 341 -758 335 -746 769 -324 777 -334 745 -340 769 -322 341 -766 739 -324 781 -522 563 -4652 317 -778 747 -320 763 -328 353 -732 387 -724 347 -722 775 -326 781 -332 355 -724 347 -724 775 -326 781 -332 747 -340 353 -732 343 -736 353 -754 749 -320 369 -726 375 -724 335 -748 339 -756 767 -322 345 -736 351 -756 345 -724 775 -324 777 -332 753 -336 747 -340 341 -764 739 -330 769 -546 521 -4660 329 -766 777 -320 757 -326 349 -758 347 -724 373 -724 769 -324 777 -332 353 -732 343 -734 777 -326 773 -320 775 -332 355 -722 349 -732 351 -732 765 -346 339 -754 +RAW_Data: 321 -744 363 -718 363 -748 765 -324 345 -734 349 -732 345 -768 745 -322 783 -326 779 -332 747 -340 353 -730 769 -352 753 -524 557 -4630 351 -740 755 -322 803 -296 387 -722 347 -724 377 -724 769 -322 779 -332 357 -722 349 -724 773 -326 779 -334 747 -338 353 -732 351 -754 345 -722 783 -312 333 -744 353 -744 363 -718 365 -754 761 -322 343 -736 351 -732 349 -756 751 -352 755 -346 753 -326 773 -322 345 -756 743 -326 781 -534 537 -4638 359 -738 779 -320 759 -326 351 -756 347 -726 341 -746 771 -326 777 -334 351 -734 341 -734 777 -324 777 -320 773 -332 355 -732 355 -730 355 -728 777 -310 357 -728 353 -758 341 -732 347 -752 751 -322 367 -724 375 -712 375 -724 767 -324 779 -332 753 -336 747 -342 353 -732 765 -344 763 -516 543 -4650 351 -756 753 -352 753 -314 333 -748 351 -744 361 -752 761 -320 773 -332 355 -724 347 -724 777 -326 781 -332 747 -338 351 -732 343 -734 349 -758 751 -322 371 -724 377 -722 335 -746 339 -746 773 -324 349 -734 353 -734 353 -756 743 -328 781 -336 747 -340 757 -340 355 -730 757 -340 769 -516 549 -4642 353 -758 755 -320 767 -330 353 -758 347 -726 339 -748 771 -324 779 -334 353 -732 343 -732 773 -324 777 -322 775 -332 355 -730 355 -724 349 -758 743 -324 351 -758 347 -724 339 -748 373 -736 747 -336 357 -726 357 -726 355 -726 797 -324 755 -320 783 -316 767 -320 367 -724 773 -326 781 -530 535 -4632 359 -738 781 -318 761 -328 351 -734 387 -724 347 -726 773 -326 779 -332 355 -730 355 -732 745 -342 777 -312 777 -314 357 -726 353 -758 353 -718 789 -322 353 -720 343 -734 349 -760 355 -718 791 -320 343 -724 377 -726 339 -748 771 -324 781 -330 747 -338 777 -312 343 -766 745 -348 757 -514 543 -4678 347 -716 769 -346 757 -324 347 -746 337 -760 333 -758 763 -320 775 -330 357 -730 355 -730 747 -342 777 -310 777 -348 319 -758 341 -734 347 -752 749 -320 371 -722 377 -724 337 -756 333 -748 767 -324 347 -734 349 -732 345 -766 775 -320 755 -328 783 -332 747 -338 357 -730 779 -310 779 -512 543 -4642 359 -738 779 -318 763 -328 351 -734 353 -734 353 -764 747 -336 757 -338 355 -728 355 -726 789 -310 769 -350 733 -342 339 -758 323 -744 363 -746 765 -322 345 -756 345 -742 345 -742 345 -742 743 -328 351 -764 319 -764 353 -728 751 -340 777 -346 739 -346 737 -352 351 -722 767 -350 755 -89978 97 -228 99 -392 97 -364 131 -364 261 -98 491 -198 265 -200 595 -166 2189 -134 1781 -98 131 -66 +RAW_Data: 4895 -3912 129 -1214 65 -132 99 -266 131 -232 201 -200 65 -100 199 -166 265 -100 263 -998 165 -198 97 -298 329 -198 563 -870 99 -166 299 -332 231 -98 163 -98 99 -164 591 -66 1607 -98 327 -11988 65 -134 131 -162 193 -1974 97 -1982 65 -300 265 -230 493 -66 99 -17484 65 -458 165 -362 99 -664 131 -1126 99 -100 99 -168 431 -98 133 -498 197 -66 2277 -100 133 -66 533 -8150 97 -328 97 -100 291 -98 1015 -96 3367 -168 133 -100 1163 -66 667 -66 393 -66 425 -66 5567 -7622 659 -366 199 -330 361 -66 129 -494 131 -264 367 -334 165 -1022 165 -66 133 -166 199 -432 595 -66 131 -98 1363 -6728 65 -2332 65 -7664 99 -1682 99 -196 163 -924 65 -330 65 -196 589 -132 229 -228 229 -198 1909 -100 1477 -66 701 -66 5773 -4316 163 -232 131 -194 65 -392 229 -458 165 -1216 461 -562 263 -462 131 -166 97 -528 97 -394 131 -558 367 -100 233 -68 133 -366 167 -166 267 -66 333 -132 2219 -168 431 -100 1461 -66 1433 -100 5641 -4648 65 -802 97 -794 65 -2290 133 -266 167 -100 165 -334 365 -134 263 -168 65 -266 67 -132 365 -100 599 -168 297 -98 567 -66 331 -198 65 -100 599 -100 1065 -100 5343 -4728 99 -1760 165 -1430 165 -198 99 -202 299 -294 197 -198 129 -64 131 -328 229 -100 357 -464 197 -100 565 -134 133 -102 401 -134 601 -164 129 -66 895 -168 397 -198 397 -100 197 -68 9979 -3582 65 -300 99 -400 63 -694 131 -798 133 -898 167 -200 131 -134 229 -264 197 -360 65 -264 97 -100 763 -100 295 -166 867 -68 65 -132 559 -12458 65 -2028 97 -132 163 -166 129 -100 195 -262 97 -296 263 -130 991 -66 1361 -134 661 -66 361 -66 197 -1088 167 -336 65 -366 65 -794 165 -68 133 -100 131 -266 133 -100 65 -198 135 -366 65 -198 729 -68 995 -100 397 -134 97 -132 363 -232 431 -64 1573 -4672 63 -8966 99 -464 197 -828 165 -602 131 -360 295 -164 63 -66 625 -398 197 -100 2475 -66 367 -132 133 -100 6651 -4462 99 -3092 101 -100 99 -234 99 -198 233 -66 165 -300 165 -132 65 -100 99 -264 65 -598 429 -2318 399 -200 67 -198 133 -166 199 -164 65 -132 165 -98 263 -64 2613 -166 697 -66 6631 -6580 131 -890 65 -66 165 -166 165 -300 133 -368 265 -726 65 -98 161 -164 97 -296 131 -98 131 -988 65 -232 201 -132 165 -100 165 -300 229 -100 261 -268 1459 -132 1575 -364 461 -132 297 -332 8997 -9896 229 -134 265 -164 267 -300 299 -300 763 -134 1933 -100 465 -100 431 -98 199 -134 6761 -2074 65 -3566 65 -132 195 -166 +RAW_Data: 133 -462 67 -166 99 -100 265 -100 131 -364 925 -132 763 -700 231 -856 165 -100 299 -164 631 -166 231 -132 429 -134 463 -66 4979 -4996 165 -430 165 -502 99 -132 97 -1160 457 -100 261 -296 131 -134 201 -98 99 -100 363 -200 361 -134 363 -198 131 -1496 67 -264 329 -360 327 -132 163 -264 985 -68 565 -66 429 -66 263 -130 229 -134 8225 -200 101 -136 101 -368 265 -330 65 -598 195 -304 169 -268 101 -696 99 -1484 67 -1952 99 -1386 165 -66 233 -134 101 -164 65 -364 65 -298 2491 -132 367 -100 1295 -66 6535 -5946 65 -1186 97 -298 623 -426 99 -66 99 -66 559 -134 133 -168 331 -200 133 -132 133 -462 459 -1088 65 -264 131 -164 65 -98 493 -98 97 -198 723 -134 1283 -64 819 -66 459 -66 621 -14282 65 -398 97 -396 97 -366 131 -162 99 -602 165 -66 369 -134 363 -100 561 -134 1261 -100 99 -134 831 -132 8053 -3428 65 -2474 65 -1484 265 -196 131 -98 197 -230 225 -196 97 -232 65 -234 795 -232 397 -234 335 -100 1425 -66 329 -68 527 -134 595 -100 165 -68 165 -200 329 -66 233 -68 889 -64 6761 -1518 97 -5252 133 -1660 65 -528 131 -292 97 -66 165 -66 293 -98 329 -164 97 -130 97 -260 627 -68 1533 -132 867 -132 5585 -6044 97 -1858 99 -132 65 -264 229 -198 97 -924 131 -2698 65 -362 527 -66 263 -100 963 -164 231 -132 295 -166 1093 -66 167 -100 635 -100 165 -68 133 -168 495 -100 299 -100 4855 -6142 65 -1458 97 -134 135 -66 267 -598 131 -168 201 -266 165 -66 133 -232 593 -68 131 -200 97 -198 553 -200 597 -66 1261 -132 2119 -66 199 -168 199 -230 1975 -4282 65 -8382 63 -3286 65 -460 65 -164 97 -100 97 -198 293 -198 63 -326 361 -164 297 -198 1985 -166 297 -100 431 -200 233 -66 65 -68 329 -168 8161 -5090 99 -64 97 -398 67 -2510 263 -1116 65 -230 161 -66 689 -130 129 -132 131 -426 3359 -98 3431 -8782 97 -930 67 -920 97 -786 565 -198 163 -66 461 -198 3347 -164 231 -11298 419 -750 715 -378 721 -360 317 -774 333 -774 305 -782 735 -360 745 -336 315 -768 313 -772 747 -360 741 -356 735 -362 317 -752 347 -752 345 -750 739 -328 347 -756 345 -754 345 -718 339 -772 743 -338 349 -734 349 -754 345 -756 749 -334 737 -354 753 -326 775 -336 347 -736 769 -344 733 -554 507 -4680 351 -722 761 -354 757 -352 317 -760 325 -740 351 -742 757 -354 739 -362 319 -756 347 -756 741 -326 779 -334 745 -340 355 -726 353 -758 319 -758 767 -318 353 -758 311 -754 345 -758 325 -740 777 -322 363 -722 +RAW_Data: 337 -756 337 -756 767 -322 775 -332 747 -338 777 -310 355 -760 739 -350 735 -550 547 -4640 353 -750 751 -320 767 -328 353 -758 347 -724 339 -758 767 -322 777 -332 351 -734 341 -734 773 -324 777 -322 773 -332 355 -732 355 -730 355 -728 753 -338 357 -728 355 -724 355 -758 355 -722 765 -320 351 -754 313 -768 319 -766 753 -352 769 -330 747 -336 779 -310 357 -726 779 -332 747 -540 537 -4670 323 -740 779 -320 761 -328 351 -758 347 -724 375 -724 769 -322 775 -332 351 -734 343 -732 771 -326 777 -322 775 -330 357 -722 347 -726 377 -734 745 -338 353 -732 343 -734 349 -756 325 -744 795 -320 341 -726 377 -724 339 -756 765 -322 777 -332 747 -338 777 -310 343 -764 771 -296 769 -548 521 -4660 329 -768 777 -316 759 -326 351 -758 347 -740 347 -726 771 -324 779 -334 355 -722 349 -724 775 -326 777 -334 747 -340 353 -732 343 -736 351 -756 751 -322 367 -736 351 -732 343 -736 353 -754 751 -322 367 -744 347 -724 339 -746 771 -324 777 -334 745 -340 769 -320 353 -752 769 -314 787 -518 545 -4642 351 -722 789 -310 765 -318 355 -754 337 -758 335 -746 769 -324 775 -334 353 -724 349 -724 773 -326 779 -336 755 -336 353 -732 343 -734 353 -752 753 -320 367 -722 343 -758 337 -746 337 -758 765 -322 345 -756 347 -724 339 -756 767 -324 775 -334 745 -338 777 -312 343 -764 769 -296 769 -548 523 -4650 347 -744 779 -320 763 -330 351 -758 347 -724 341 -758 767 -324 777 -330 351 -734 341 -736 777 -324 775 -320 773 -332 355 -730 357 -722 347 -726 773 -328 349 -756 347 -722 339 -746 375 -734 747 -338 357 -728 353 -728 353 -758 765 -322 757 -352 753 -314 785 -316 345 -752 765 -322 775 -530 535 -4634 359 -736 781 -320 759 -326 351 -756 347 -726 339 -758 769 -324 775 -334 351 -734 341 -734 777 -326 775 -320 773 -298 389 -730 355 -724 347 -722 775 -326 349 -758 345 -724 341 -744 375 -712 773 -324 349 -758 347 -724 339 -756 769 -322 775 -332 745 -340 769 -320 351 -752 771 -314 753 -554 513 -4672 343 -732 771 -318 783 -324 349 -756 347 -724 339 -746 771 -326 775 -336 351 -734 341 -734 777 -326 773 -324 775 -330 355 -724 347 -724 377 -722 767 -324 347 -734 353 -760 353 -722 351 -722 791 -322 351 -720 349 -740 351 -742 757 -352 773 -296 781 -334 755 -338 355 -728 777 -312 777 -544 513 -4674 325 -742 779 -320 759 -328 353 -756 347 -724 341 -758 767 -324 777 -332 357 -730 355 -730 747 -340 781 -310 757 -340 353 -732 343 -738 +RAW_Data: 351 -754 753 -320 369 -724 341 -770 351 -734 341 -732 771 -324 345 -752 333 -748 337 -746 769 -324 777 -332 747 -338 755 -340 353 -732 765 -354 761 -524 515 -4676 319 -764 755 -322 767 -330 351 -758 347 -724 341 -746 773 -324 779 -332 353 -734 343 -732 769 -318 783 -324 779 -332 351 -734 341 -734 347 -754 753 -320 365 -744 347 -724 339 -748 337 -746 773 -324 349 -758 347 -724 339 -744 771 -326 777 -332 745 -340 769 -320 343 -766 741 -322 783 -554 529 -4624 349 -744 779 -320 761 -328 353 -758 347 -724 341 -756 769 -324 775 -334 355 -722 349 -756 741 -326 779 -334 747 -338 353 -732 343 -734 353 -756 751 -322 369 -724 341 -758 337 -746 337 -748 769 -324 349 -732 341 -768 325 -742 781 -322 759 -328 783 -334 747 -338 357 -728 777 -346 755 -510 543 -4664 323 -778 747 -320 763 -330 351 -758 347 -724 339 -746 773 -324 779 -336 351 -734 341 -734 771 -324 777 -324 775 -332 355 -724 347 -724 377 -724 769 -324 347 -756 345 -734 351 -732 343 -732 773 -316 353 -754 337 -746 337 -756 767 -324 777 -334 745 -340 755 -338 353 -732 767 -342 767 -512 549 -4654 345 -754 769 -296 803 -320 341 -724 379 -724 337 -746 769 -326 777 -332 353 -734 341 -732 775 -324 779 -322 773 -332 351 -734 341 -736 323 -780 753 -320 367 -722 375 -722 337 -746 339 -768 747 -336 353 -732 343 -732 351 -754 753 -320 801 -330 745 -338 777 -310 341 -764 767 -318 775 -516 525 -4682 315 -780 749 -320 767 -328 351 -732 353 -758 347 -740 777 -330 749 -336 357 -730 355 -726 779 -310 791 -310 777 -312 357 -726 353 -756 353 -720 765 -354 333 -736 351 -738 359 -716 363 -754 765 -322 343 -724 379 -732 351 -732 767 -314 799 -296 767 -322 801 -296 383 -734 767 -316 763 -522 539 -4680 341 -734 775 -326 773 -322 345 -722 377 -726 337 -756 769 -322 775 -332 351 -736 353 -718 767 -344 765 -320 761 -326 349 -758 347 -740 347 -726 771 -326 347 -758 345 -724 339 -746 375 -734 747 -338 353 -732 341 -734 349 -758 751 -322 767 -330 779 -336 779 -308 357 -726 779 -334 747 -538 539 -4662 317 -780 749 -320 765 -328 353 -732 389 -722 347 -724 775 -326 777 -334 355 -730 355 -724 779 -330 747 -338 777 -310 343 -732 349 -746 353 -740 759 -320 373 -736 349 -734 343 -734 349 -758 755 -320 371 -734 349 -732 343 -760 773 -296 769 -322 801 -328 747 -336 357 -724 781 -332 747 -536 539 -4662 323 -744 781 -318 763 -328 353 -758 347 -726 339 -756 767 -324 +RAW_Data: 777 -334 349 -734 343 -734 777 -326 773 -320 773 -330 355 -724 347 -724 379 -722 769 -324 347 -756 345 -734 351 -732 343 -734 777 -324 347 -752 333 -746 337 -746 769 -326 777 -334 755 -336 779 -308 343 -732 783 -346 755 -514 543 -4646 349 -754 751 -350 753 -346 331 -758 323 -744 361 -754 763 -320 775 -296 389 -732 355 -722 777 -330 747 -336 755 -338 353 -732 351 -720 383 -716 771 -346 329 -756 319 -742 363 -718 365 -752 765 -322 343 -756 347 -732 351 -732 769 -310 799 -316 755 -326 777 -334 353 -732 767 -316 761 -552 545 -4640 345 -732 771 -324 781 -324 347 -758 345 -722 341 -756 767 -326 775 -334 351 -734 341 -736 775 -326 773 -322 771 -332 355 -732 355 -724 349 -724 775 -326 349 -756 345 -724 339 -746 375 -736 745 -338 357 -728 353 -726 353 -758 765 -322 755 -352 753 -348 749 -318 347 -752 765 -322 775 -530 537 -4632 359 -738 779 -320 759 -328 353 -756 347 -726 339 -758 767 -322 777 -334 351 -734 341 -734 771 -318 779 -324 777 -332 357 -730 355 -730 357 -724 777 -332 349 -734 341 -734 323 -782 321 -742 793 -290 373 -722 379 -734 355 -730 747 -340 777 -310 777 -350 739 -348 319 -760 769 -322 767 -520 553 -4646 323 -778 749 -320 767 -328 351 -758 347 -726 339 -756 769 -324 775 -332 353 -734 341 -734 773 -326 775 -322 775 -300 353 -764 309 -766 347 -752 749 -322 367 -722 341 -746 375 -736 351 -732 767 -318 341 -742 353 -738 327 -778 761 -322 773 -332 747 -338 777 -310 355 -728 779 -348 739 -550 511 -4674 323 -746 779 -320 763 -330 351 -758 347 -740 347 -742 743 -330 781 -334 357 -730 357 -728 751 -340 755 -340 769 -318 343 -766 317 -760 325 -778 759 -322 343 -734 351 -732 345 -766 317 -760 755 -322 369 -736 351 -732 353 -756 757 -322 755 -352 753 -346 755 -326 343 -750 767 -322 771 -530 537 -4664 325 -740 777 -320 761 -328 351 -758 347 -726 341 -756 767 -324 777 -332 351 -734 341 -736 775 -326 775 -320 773 -330 351 -734 341 -736 323 -780 749 -320 367 -724 375 -722 337 -744 339 -746 771 -326 347 -758 345 -722 373 -726 767 -324 775 -332 753 -338 745 -340 353 -732 765 -352 753 -526 553 -4646 355 -730 753 -340 779 -312 357 -726 353 -726 353 -758 765 -322 765 -356 317 -758 345 -722 781 -346 755 -326 771 -320 345 -724 377 -726 337 -746 769 -326 347 -732 355 -758 355 -722 351 -754 757 -310 343 -760 325 -746 363 -752 763 -322 771 -332 753 -336 747 -338 353 -732 767 -344 763 -514 +RAW_Data: 541 -4674 313 -768 779 -320 755 -324 349 -734 353 -758 347 -722 773 -326 777 -334 351 -734 341 -734 773 -324 777 -320 775 -332 355 -724 347 -724 379 -732 747 -340 353 -732 343 -732 349 -760 323 -746 795 -290 373 -724 377 -724 337 -746 769 -324 777 -332 747 -338 769 -320 341 -766 743 -322 783 -522 561 -4630 359 -736 777 -320 757 -328 351 -758 347 -724 341 -758 767 -324 779 -300 383 -734 341 -734 779 -296 803 -320 773 -298 387 -724 347 -740 347 -726 775 -322 349 -756 345 -742 347 -724 341 -756 769 -324 345 -724 377 -736 351 -732 765 -312 797 -320 753 -326 777 -334 353 -732 765 -316 761 -536 541 -4648 345 -766 775 -290 785 -324 349 -758 347 -726 339 -746 771 -324 779 -332 353 -730 343 -734 777 -324 777 -322 775 -332 355 -730 357 -724 347 -724 773 -328 349 -758 347 -734 351 -732 343 -732 777 -324 347 -754 335 -758 333 -748 765 -322 775 -332 745 -340 757 -340 355 -728 779 -312 777 -548 511 -4672 323 -742 781 -320 761 -328 387 -698 387 -698 389 -722 781 -296 781 -336 357 -726 349 -732 779 -312 767 -356 759 -322 351 -722 359 -736 351 -740 755 -320 373 -726 375 -726 337 -754 333 -748 767 -324 347 -724 379 -724 339 -758 765 -322 779 -332 745 -340 777 -310 357 -728 775 -348 757 -512 545 -4640 359 -738 779 -320 759 -328 353 -756 347 -726 375 -726 765 -324 777 -300 389 -722 347 -726 775 -324 779 -332 747 -338 353 -730 345 -734 351 -754 753 -322 369 -734 351 -732 343 -728 349 -744 781 -320 365 -726 339 -758 335 -748 769 -324 777 -332 745 -340 779 -312 357 -730 777 -310 795 -510 541 -4666 315 -746 783 -320 763 -326 355 -758 347 -726 339 -748 769 -326 777 -334 353 -730 343 -732 773 -324 779 -322 777 -298 389 -724 347 -726 375 -724 767 -324 347 -724 379 -724 339 -746 339 -760 765 -324 345 -724 377 -726 339 -758 765 -322 777 -332 747 -338 779 -310 341 -734 771 -346 757 -546 543 -4620 383 -716 769 -346 757 -324 345 -752 333 -750 335 -758 765 -320 775 -332 353 -724 349 -756 741 -328 777 -334 753 -338 351 -732 343 -732 349 -756 751 -322 369 -724 341 -746 375 -736 349 -734 769 -322 351 -720 345 -734 349 -762 755 -322 767 -328 781 -334 747 -342 357 -728 777 -346 741 -548 511 -4670 323 -744 779 -320 763 -330 351 -758 349 -724 339 -758 767 -324 775 -330 353 -732 341 -736 769 -324 779 -320 777 -330 357 -724 347 -740 347 -724 775 -324 347 -756 345 -724 341 -744 341 -770 743 -338 353 -732 343 -734 +RAW_Data: 349 -758 753 -320 767 -360 747 -336 777 -308 357 -726 789 -312 777 -79086 67 -500 65 -496 63 -458 131 -856 133 -438 131 -202 99 -398 263 -328 195 -198 363 -100 395 -100 961 -66 393 -132 365 -102 199 -66 5167 -4206 99 -640 99 -726 65 -1814 293 -98 163 -98 97 -164 327 -64 259 -132 231 -428 97 -232 197 -134 65 -398 197 -1124 99 -462 465 -68 397 -132 303 -66 665 -66 3199 -66 1825 -5202 65 -8960 231 -460 131 -396 97 -166 99 -132 133 -330 99 -328 425 -166 133 -100 199 -68 131 -168 133 -66 3381 -66 13735 -270 199 -134 99 -166 133 -302 1029 -100 165 -200 201 -198 301 -132 1467 -66 501 -68 367 -168 1925 -66 495 -98 299 -66 455 -262 5365 -6980 65 -66 129 -462 65 -130 97 -98 327 -394 65 -98 359 -232 97 -330 295 -430 365 -2796 263 -134 199 -198 291 -164 3701 -66 9467 -9052 99 -802 329 -200 197 -64 129 -294 131 -300 891 -266 133 -166 329 -102 99 -132 2173 -64 161 -98 6545 -8052 129 -562 429 -100 563 -168 335 -134 133 -98 133 -232 363 -66 299 -66 1129 -164 397 -464 561 -68 795 -100 1687 -13310 133 -1490 101 -170 231 -66 199 -66 197 -134 65 -334 365 -134 297 -66 959 -100 293 -198 795 -362 231 -100 365 -166 365 -100 4957 -7546 231 -268 397 -232 131 -398 231 -730 65 -434 199 -1492 65 -728 65 -528 97 -164 229 -66 131 -64 197 -132 391 -164 2959 -66 65 -12414 65 -1126 65 -534 67 -400 231 -366 99 -134 65 -166 67 -166 167 -166 167 -298 335 -232 299 -66 1697 -66 233 -134 67 -166 529 -100 67 -66 7763 -728 99 -932 99 -1296 197 -100 99 -630 65 -794 165 -634 165 -130 97 -198 199 -132 133 -198 99 -262 2175 -66 97 -132 1645 -164 563 -12852 131 -1032 67 -1730 99 -166 199 -236 99 -300 263 -196 293 -198 357 -66 1263 -100 1363 -98 725 -134 231 -66 627 -66 5743 -4102 263 -230 131 -262 131 -66 67 -198 99 -498 165 -364 131 -1000 263 -100 101 -464 197 -198 399 -98 1029 -166 133 -198 99 -300 131 -100 199 -432 99 -230 1829 -66 429 -134 131 -66 131 -230 133 -394 395 -196 397 -3828 63 -960 65 -458 197 -198 129 -1480 97 -1948 97 -428 195 -66 229 -426 197 -426 1185 -64 1181 -132 633 -166 363 -170 167 -66 329 -232 4851 -4466 67 -930 65 -434 165 -268 65 -166 133 -234 133 -330 261 -132 199 -68 99 -134 99 -68 65 -234 99 -2214 63 -132 361 -164 297 -98 227 -456 163 -130 127 -228 397 -13124 131 -3210 365 -722 163 -360 97 -362 427 -66 395 -66 163 -132 6621 -9772 +RAW_Data: 231 -332 265 -132 665 -66 531 -232 693 -66 363 -66 1253 -132 621 -428 599 -98 7479 -6028 99 -296 97 -654 99 -724 97 -328 97 -98 435 -166 295 -264 129 -132 589 -66 627 -66 397 -98 199 -66 199 -1528 297 -6504 63 -900 65 -1130 133 -166 663 -398 395 -298 131 -100 599 -98 67 -66 695 -166 403 -164 1807 -200 4679 -3774 131 -130 99 -98 457 -2774 231 -396 525 -262 197 -294 97 -68 163 -134 331 -298 365 -166 99 -634 99 -362 165 -1196 163 -166 231 -98 267 -132 197 -300 2521 -100 895 -100 401 -134 503 -12428 163 -362 231 -396 165 -166 199 -66 99 -232 167 -134 197 -100 99 -330 365 -168 1927 -334 231 -198 495 -66 8407 -5784 229 -1188 163 -492 65 -336 99 -602 99 -100 365 -200 431 -334 331 -100 1791 -134 397 -132 65 -166 359 -66 297 -100 465 -68 1097 -4396 67 -564 431 -298 99 -132 429 -198 1053 -66 327 -98 723 -12552 65 -1232 199 -864 131 -1890 99 -132 133 -134 99 -66 233 -100 165 -628 65 -132 2857 -66 295 -166 631 -100 197 -100 4333 -1082 131 -1476 359 -366 97 -166 99 -100 231 -166 861 -100 529 -98 863 -200 99 -102 99 -132 493 -132 325 -100 8365 -2990 65 -302 133 -964 97 -1100 65 -266 867 -166 99 -100 131 -134 565 -166 695 -100 901 -100 497 -66 401 -12558 63 -830 99 -100 131 -694 99 -498 129 -200 99 -402 99 -266 231 -66 199 -134 65 -200 99 -132 133 -68 167 -166 67 -168 599 -202 1633 -66 723 -100 1547 -64 7133 -5950 97 -522 97 -428 97 -554 65 -2048 133 -132 363 -66 297 -234 2847 -164 791 -132 301 -3286 131 -6472 99 -364 99 -1096 199 -590 65 -362 131 -66 133 -134 299 -98 369 -66 2063 -166 99 -132 599 -100 7507 -8234 199 -232 97 -168 201 -530 229 -132 163 -66 427 -68 165 -100 1981 -66 463 -100 65 -166 1017 -132 6219 -6002 131 -64 165 -428 199 -432 131 -530 133 -200 67 -11500 65 -6344 65 -1958 165 -100 97 -664 65 -334 99 -730 331 -236 367 -168 329 -200 395 -66 131 -98 527 -68 99 -132 1493 -66 197 -14856 199 -1364 197 -132 165 -366 163 -234 65 -98 131 -428 65 -98 65 -232 2273 -164 553 -392 6131 -6662 233 -832 231 -432 63 -1328 263 -300 131 -866 197 -926 65 -166 65 -232 227 -98 263 -198 131 -164 65 -166 791 -100 525 -98 361 -198 365 -132 859 -66 329 -228 529 -7030 131 -620 97 -164 163 -132 131 -66 195 -100 163 -394 229 -262 131 -66 131 -198 527 -100 133 -400 133 -166 99 -1232 65 -134 197 -66 131 -232 431 -596 131 -166 2673 -134 295 -166 +RAW_Data: 5357 -11284 99 -1290 65 -134 1501 -200 263 -100 325 -132 399 -166 1997 -15232 131 -1320 99 -168 65 -466 65 -134 65 -100 165 -98 97 -196 425 -134 331 -132 1491 -168 395 -134 299 -100 1519 -12916 99 -998 197 -794 131 -1654 165 -100 97 -362 163 -66 163 -230 231 -434 497 -100 1499 -100 1495 -166 65 -298 229 -5848 99 -134 99 -8920 133 -1126 131 -234 231 -134 265 -66 131 -134 365 -166 829 -100 1793 -134 395 -12288 97 -2094 65 -430 65 -268 65 -400 65 -232 335 -166 199 -132 231 -100 2191 -100 929 -15146 299 -230 129 -788 591 -100 231 -100 165 -66 431 -100 65 -100 65 -166 133 -264 199 -134 595 -100 397 -132 927 -68 435 -166 267 -232 65 -166 99 -68 7469 -3932 99 -360 231 -2184 131 -166 293 -200 229 -262 99 -1020 65 -656 261 -66 229 -132 163 -66 97 -760 1663 -66 233 -166 397 -100 329 -132 955 -166 491 -14812 167 -1052 163 -528 131 -132 227 -66 659 -66 367 -100 2749 -68 1595 -66 10545 -1162 67 -3130 131 -1224 131 -66 99 -230 199 -166 529 -662 299 -18024 131 -298 201 -366 131 -100 65 -166 333 -166 65 -132 297 -164 395 -392 131 -166 9295 -9924 133 -1430 133 -334 397 -134 131 -68 65 -100 331 -100 197 -200 691 -166 329 -13826 131 -1978 131 -66 531 -66 265 -268 165 -136 165 -100 263 -166 467 -66 365 -102 467 -166 631 -136 67 -696 133 -396 97 -758 165 -3180 131 -362 163 -132 63 -164 461 -164 229 -164 197 -296 2399 -194 293 -13158 131 -1494 231 -524 327 -198 97 -394 297 -68 2025 -66 227 -296 365 -13564 65 -1380 131 -954 67 -658 429 -166 195 -66 65 -98 163 -130 823 -100 99 -64 757 -66 131 -98 99 -64 165 -132 11025 -21882 65 -1816 65 -822 229 -326 163 -100 723 -264 427 -66 329 -98 985 -68 1827 -66 133 -168 401 -98 301 -132 399 -100 1725 -4022 65 -1726 67 -732 99 -1070 99 -198 65 -494 197 -298 165 -100 131 -66 823 -134 299 -166 363 -102 363 -66 823 -132 7641 -4542 65 -834 65 -1220 67 -1164 133 -562 65 -698 67 -464 197 -736 263 -134 231 -332 99 -302 131 -264 361 -164 1245 -66 65 -66 395 -130 161 -98 65 -12312 65 -1324 65 -572 67 -166 101 -202 65 -702 395 -198 401 -100 333 -68 331 -66 133 -132 1281 -68 367 -132 433 -132 99 -66 8729 -2158 65 -3984 65 -1562 265 -166 161 -194 165 -132 497 -300 1055 -166 425 -100 599 -134 991 -66 6793 -5222 99 -1602 65 -328 129 -132 291 -330 99 -228 97 -196 97 -98 297 -624 297 -1186 165 -502 165 -498 97 -1086 525 -230 261 -292 199 -298 +RAW_Data: 2443 -100 8837 -7844 99 -300 101 -3474 65 -426 131 -786 131 -66 261 -66 131 -132 623 -198 431 -98 3805 -64 163 -132 4689 -2290 65 -5964 129 -996 197 -2760 165 -230 395 -300 263 -234 301 -166 2423 -68 367 -200 197 -134 429 -66 131 -100 231 -100 1455 -100 7041 -260 63 -2606 163 -262 97 -164 261 -166 161 -130 493 -200 799 -132 525 -132 129 -1222 97 -918 919 -68 65 -264 165 -168 3119 -64 97 -98 265 -66 293 -66 9961 -3892 97 -168 461 -362 165 -438 267 -100 531 -134 1659 -168 167 -66 101 -762 99 -330 231 -8514 65 -4398 99 -1312 99 -130 163 -294 163 -822 197 -270 429 -100 461 -66 329 -130 295 -330 829 -66 1461 -66 629 -66 233 -168 593 -66 13101 -102 133 -232 1405 -198 327 -296 331 -100 197 -200 365 -66 369 -98 1419 -230 527 -66 529 -302 5013 -3942 99 -1150 165 -298 65 -296 197 -822 133 -528 97 -230 163 -762 99 -666 65 -432 265 -332 201 -66 431 -198 267 -132 2459 -132 403 -100 1359 -68 7933 -3998 67 -4454 131 -198 97 -132 131 -198 295 -162 329 -298 1189 -132 327 -366 435 -66 503 -66 983 -132 4845 -5250 131 -132 133 -98 165 -134 101 -300 233 -332 231 -66 99 -132 99 -132 335 -198 165 -366 131 -1060 197 -402 99 -132 197 -168 67 -266 629 -330 65 -134 131 -336 721 -100 1501 -132 731 -66 1127 -132 5451 -4352 131 -854 163 -296 165 -432 99 -396 493 -132 131 -294 163 -1052 131 -14776 65 -5234 65 -164 129 -852 65 -98 131 -66 165 -164 97 -330 429 -66 165 -432 329 -98 491 -100 857 -198 889 -164 329 -66 295 -806 65 -722 99 -3564 199 -864 397 -400 231 -98 367 -100 797 -164 395 -98 393 -166 6901 -1552 65 -530 165 -66 99 -1186 65 -394 131 -198 99 -366 165 -198 99 -404 99 -2092 261 -264 331 -132 231 -360 297 -234 331 -64 2139 -100 399 -13226 99 -2394 65 -502 63 -394 163 -260 65 -66 131 -198 229 -132 99 -132 297 -296 263 -196 987 -132 265 -198 163 -12344 99 -696 65 -1292 65 -198 99 -894 163 -68 431 -102 65 -102 231 -166 199 -64 263 -164 359 -66 2025 -130 327 -98 11033 -788 99 -2174 65 -722 97 -100 163 -66 263 -362 789 -100 2493 -100 299 -200 7351 -4204 65 -1286 67 -1766 67 -566 99 -266 65 -200 67 -930 97 -134 429 -100 99 -132 65 -198 229 -262 163 -460 789 -98 361 -130 259 -66 657 -134 491 -166 197 -164 163 -166 5757 -6452 65 -864 65 -368 395 -230 165 -468 99 -796 133 -166 99 -134 101 -828 131 -600 163 -560 197 -328 263 -200 295 -66 97 -294 97 -198 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi.sub new file mode 100644 index 00000000000..33f1ff79f41 --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: GangQi +Bit: 34 +Key: 00 00 00 02 9D DB 77 38 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi_raw.sub new file mode 100644 index 00000000000..fd76548dd03 --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/gangqi_raw.sub @@ -0,0 +1,12 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 1223 -572304 1675 -132 1183 -536 465 -1214 1203 -502 489 -1210 509 -1202 1171 -518 1175 -522 1189 -508 489 -1176 1229 -504 1177 -520 1205 -482 479 -1232 1203 -478 1233 -486 481 -1216 1197 -480 1221 -486 505 -1182 1241 -486 1175 -482 1245 -484 505 -1218 1185 -498 1211 -490 1185 -482 545 -1174 511 -1206 1177 -516 1189 -516 1165 -508 521 -1184 503 -1232 477 -2210 1171 -510 473 -1232 1183 -514 517 -1174 513 -1194 1209 -478 1219 -486 1191 -492 513 -1204 1199 -532 1159 -500 1237 -486 481 -1206 1209 -480 1203 -480 535 -1198 1189 -496 1187 -520 483 -1230 1175 -478 1219 -506 1199 -510 505 -1180 1231 -496 1179 -486 1211 -482 517 -1214 501 -1182 1199 -508 1179 -502 1205 -516 477 -1240 473 -1206 477 -2200 1231 -478 485 -1222 1189 -520 463 -1202 515 -1208 1199 -494 1207 -486 1209 -516 483 -1182 1217 -488 1197 -534 1159 -520 481 -1234 1179 -478 1219 -486 505 -1216 1183 -506 1201 -510 491 -1174 1229 -506 1177 -542 1185 -496 483 -1208 1195 -502 1213 -490 1169 -528 493 -1208 475 -1242 1171 -482 1235 -484 1181 -542 499 -1180 473 -1242 479 -2204 1201 -490 475 -1248 1177 -488 515 -1206 489 -1236 1153 -520 1215 -480 1175 -514 531 -1192 1167 -538 1195 -484 1215 -482 515 -1176 1207 -512 1165 -548 477 -1184 1233 -478 1187 -520 519 -1174 1185 -536 1191 -474 1231 -478 493 -1212 1203 -492 1177 -544 1179 -480 487 -1250 497 -1176 1197 -496 1211 -486 1211 -480 517 -1214 501 -1178 507 -2208 1209 -486 507 -1182 1197 -526 483 -1204 507 -1198 1187 -508 1183 -506 1217 -490 475 -1244 1175 -486 1237 -484 1181 -492 547 -1176 1167 -528 1185 -520 485 -1232 1175 -478 1223 -486 519 -1216 1169 -520 1203 -482 1197 -480 493 -1242 1167 -504 1217 -490 1201 -518 489 -1176 519 -1210 1175 -514 1191 -486 1213 -518 489 -1176 505 -1214 515 -2198 1167 -506 541 -1174 1175 -520 505 -1184 505 -1216 1183 -504 1211 -490 1199 -530 495 -1178 1199 -494 1205 -484 1207 -514 479 -1200 1203 -516 1175 -512 507 -1184 1227 -498 1181 -486 515 -1204 1185 -532 1159 -504 1231 -478 493 -1210 1215 -486 1171 -544 1173 -512 475 -1216 513 -1194 1185 -510 1181 -520 1185 -514 483 -1216 513 -1158 531 -2174 1243 -486 499 -1176 1217 -490 479 -1236 505 -1184 1203 -522 1181 -484 1213 -502 485 -1206 1197 -500 1213 -490 1197 -498 515 -1180 1197 -532 1161 -502 511 -1202 1201 -482 1225 -476 485 -1248 1191 -486 1211 -482 1207 -484 537 -1196 1179 -516 1179 -506 1199 -508 489 -1172 545 -1178 1201 -520 1179 -488 1215 -494 515 -1170 513 -1204 481 -2238 1157 -520 519 -1176 1183 -540 499 -1178 473 -1236 1179 -520 1209 -480 1175 -552 475 -1188 1225 -502 1177 -488 1207 -510 473 -1232 1207 -480 1203 -520 479 -1184 +RAW_Data: 1227 -480 1189 -554 487 -1174 1217 -502 1181 -486 1211 -514 481 -1216 1207 -484 1221 -478 1185 -520 487 -1196 483 -1218 1215 -490 1229 -478 1183 -520 483 -1228 483 -1188 531 -2150 1239 -480 481 -1246 1181 -482 489 -1218 495 -1206 1197 -506 1183 -520 1205 -480 479 -1232 1181 -514 1209 -486 1199 -526 491 -1184 1207 -520 1183 -484 485 -1208 1209 -506 1181 -518 479 -1242 1169 -482 1235 -474 1201 -480 541 -1174 1205 -512 1207 -474 1215 -516 479 -1174 547 -1176 1185 -536 1193 -462 1249 -486 481 -1206 513 -1176 485 -2240 1173 -518 517 -1158 1223 -506 487 -1174 545 -1172 1207 -514 1175 -484 1223 -510 489 -1178 1219 -516 1173 -486 1235 -484 489 -1218 1185 -520 1217 -480 481 -1214 1205 -484 1183 -540 499 -1182 1201 -494 1207 -476 1241 -478 475 -1244 1171 -512 1203 -520 1173 -490 521 -1184 479 -1246 1179 -482 1243 -486 1195 -484 515 -1210 485 -1214 499 -2204 1175 -482 519 -1224 1171 -490 503 -1210 481 -1210 1213 -482 1205 -518 1175 -486 501 -1246 1179 -486 1211 -480 1213 -512 503 -1182 1231 -498 1179 -486 513 -1202 1183 -534 1159 -498 511 -1204 1199 -482 1227 -480 1199 -514 505 -1182 1229 -478 1185 -520 1209 -482 509 -1202 513 -1174 1215 -516 1153 -520 1211 -480 511 -1204 485 -1208 489 -2210 1175 -548 475 -1186 1217 -492 515 -1174 513 -1210 1177 -510 1201 -490 1233 -496 483 -1174 1215 -516 1173 -514 1209 -484 491 -1232 1159 -520 1209 -480 513 -1210 1183 -482 1245 -486 501 -1178 1231 -496 1177 -508 1205 -482 481 -1244 1171 -510 1211 -486 1199 -494 509 -1210 479 -1212 1181 -514 1207 -486 1201 -492 507 -1216 479 -1210 519 -2198 1165 -494 513 -1210 1193 -488 511 -1208 473 -1246 1175 -474 1239 -478 1203 -486 539 -1194 1155 -528 1187 -520 1211 -480 481 -1210 1203 -512 1169 -548 477 -1186 1215 -492 1205 -486 481 -1220 1177 -510 1219 -488 1199 -522 487 -1206 1197 -504 1181 -486 1241 -478 475 -1244 485 -1202 1219 -478 1187 -486 1241 -478 475 -1244 485 -1202 461 -2214 1245 -482 499 -1178 1231 -478 491 -1240 471 -1184 1243 -486 1175 -480 1241 -482 503 -1182 1233 -478 1215 -506 1165 -510 489 -1208 1195 -506 1211 -506 473 -1214 1185 -522 1207 -478 509 -1174 1243 -480 1199 -514 1169 -506 507 -1214 1197 -486 1209 -482 1201 -520 481 -1192 519 -1208 1175 -514 1199 -510 1175 -514 507 -1186 503 -1210 479 -2234 1171 -490 503 -1208 1177 -520 511 -1198 489 -1232 1169 -490 1215 -492 1205 -488 513 -1202 1185 -534 1161 -518 1209 -482 513 -1178 1205 -516 1175 -512 507 -1184 1233 -498 1175 -474 551 -1182 1177 -546 1165 -510 1189 -510 487 -1208 1215 -486 1175 -546 1173 -480 509 -1216 479 -1190 1223 -506 1179 -520 1183 -516 479 -1234 481 -1198 491 -2210 +RAW_Data: 1211 -482 501 -1184 1227 -500 483 -1208 505 -1200 1205 -474 1213 -484 1205 -520 481 -1232 1177 -478 1219 -486 1197 -504 519 -1184 1193 -522 1181 -520 481 -1230 1177 -478 1217 -508 473 -1248 1155 -504 1231 -500 1179 -486 481 -1224 1179 -510 1217 -490 1229 -480 493 -1210 477 -1238 1169 -486 1235 -484 1181 -524 491 -1206 477 -1240 477 -2206 1199 -492 511 -1180 1205 -518 481 -1190 499 -1212 1207 -486 1213 -480 1213 -512 503 -1182 1213 -490 1205 -486 1209 -512 475 -1216 1209 -484 1211 -504 487 -1174 1237 -488 1173 -518 511 -1200 1189 -530 1155 -500 1237 -486 477 -1200 1205 -516 1169 -552 1179 -482 493 -1232 477 -1182 1233 -478 1189 -554 1169 -480 509 -1210 485 -1206 527 -2182 1203 -484 517 -1194 1179 -510 489 -1210 519 -1184 1209 -484 1203 -494 1197 -508 489 -1210 1193 -490 1243 -486 1177 -482 519 -1212 1173 -522 1181 -510 491 -1206 1197 -506 1215 -492 473 -1246 1177 -506 1217 -486 1171 -514 507 -1202 1187 -534 1155 -498 1235 -488 483 -1206 513 -1208 1173 -512 1203 -490 1201 -494 515 -1174 519 -1214 481 -2198 1187 -504 513 -1208 1175 -512 505 -1182 503 -1200 1201 -490 1229 -498 1173 -520 487 -1208 1221 -478 1185 -520 1181 -512 475 -1246 1175 -478 1235 -486 505 -1182 1229 -498 1179 -520 479 -1202 1211 -504 1179 -506 1203 -490 481 -1240 1179 -516 1209 -486 1177 -488 553 -1182 479 -1242 1183 -480 1211 -520 1173 -490 473 -1244 479 -1210 513 -2166 1239 -486 479 -1244 1167 -490 481 -1242 473 -1210 1209 -484 1205 -520 1195 -486 477 -1238 1167 -514 1207 -520 1177 -518 481 -1182 1235 -484 1181 -492 547 -1178 1197 -530 1153 -520 487 -1232 1177 -478 1217 -508 1165 -542 501 -1178 1227 -498 1177 -486 1211 -510 475 -1216 507 -1200 1183 -530 1191 -486 1211 -482 513 -1176 511 -1202 489 -2210 1173 -550 479 -1188 1225 -502 485 -1172 543 -1180 1171 -548 1171 -486 1223 -506 487 -1208 1217 -484 1171 -554 1179 -484 489 -1232 1159 -520 1211 -482 513 -1176 1209 -512 1207 -520 475 -1180 1231 -478 1183 -520 1209 -480 507 -1200 1205 -480 1237 -486 1171 -486 539 -1182 507 -1218 1179 -490 1209 -518 1177 -480 541 -1172 515 -1228 481 -2192 1187 -520 483 -1228 1169 -480 495 -1246 461 -1248 1183 -476 1237 -482 1175 -516 497 -1214 1187 -500 1215 -492 1173 -548 483 -1176 1207 -518 1171 -518 509 -1200 1157 -528 1189 -520 483 -1228 1177 -480 1219 -488 1195 -524 489 -1208 1195 -506 1181 -506 1199 -508 487 -1210 499 -1210 1203 -484 1181 -486 1229 -516 463 -1246 493 -1180 481 -2234 1173 -524 489 -1198 1211 -490 505 -1180 515 -1208 1177 -516 1175 -516 1225 -482 473 -1198 1235 -484 1183 -524 1181 -506 473 -1250 1181 -476 1241 -480 481 -1246 1177 -484 1215 -514 +RAW_Data: 495 -1180 1197 -494 1211 -506 1199 -502 485 -1210 1195 -488 1211 -520 1183 -514 477 -1214 477 -1220 1181 -506 1215 -490 1197 -498 515 -1182 503 -1218 489 -2198 1205 -482 475 -1246 1161 -520 515 -1174 485 -1246 1195 -484 1209 -482 1207 -484 537 -1196 1181 -520 1179 -504 1209 -482 513 -1174 1237 -478 1199 -518 479 -1190 1225 -504 1181 -488 481 -1224 1177 -542 1197 -492 1199 -494 515 -1172 1215 -516 1173 -486 1233 -484 489 -1216 493 -1212 1205 -488 1175 -522 1205 -482 519 -1216 485 -1176 511 -2198 1229 -498 483 -1174 1239 -486 479 -1240 477 -1202 1201 -486 1205 -490 1217 -490 481 -1238 1165 -530 1213 -462 1215 -480 475 -1244 1181 -482 1215 -516 501 -1216 1187 -498 1211 -494 473 -1202 1203 -520 1179 -516 1175 -516 499 -1214 1189 -498 1213 -492 1185 -512 481 -1208 479 -1232 1175 -514 1193 -520 1179 -522 487 -1206 473 -1214 515 -2198 1173 -486 505 -1218 1189 -554 487 -1174 489 -1232 1159 -520 1209 -482 1209 -482 533 -1196 1181 -518 1181 -488 1211 -514 483 -1182 1233 -484 1181 -538 501 -1180 1213 -488 1205 -474 545 -1180 1173 -544 1173 -490 1227 -502 485 -1176 1213 -516 1171 -552 1177 -482 473 -1250 463 -1212 1197 -508 1185 -520 1183 -514 485 -1214 479 -1192 553 -2178 1215 -496 483 -1176 1215 -516 479 -1210 509 -1172 1215 -516 1155 -520 1217 -482 479 -1244 1175 -514 1209 -486 1199 -494 519 -1176 1203 -518 1177 -486 501 -1214 1211 -476 1205 -512 475 -1246 1173 -482 1243 -482 1197 -494 505 -1216 1177 -518 1171 -510 1199 -518 479 -1184 501 -1212 1209 -520 1183 -484 1213 -516 465 -1212 477 -1240 479 -2198 1199 -492 539 -1180 1183 -520 481 -1202 489 -1216 1183 -520 1211 -480 1173 -550 479 -1186 1231 -478 1189 -520 1209 -482 479 -1246 1177 -482 1217 -516 497 -1178 1213 -490 1173 -540 503 -1164 1223 -488 1195 -506 1215 -490 505 -1180 1205 -518 1173 -522 1197 -478 493 -1238 473 -1182 1243 -492 1185 -514 1175 -520 481 -1220 489 -1182 547 -2172 1201 -508 475 -1246 1183 -484 483 -1218 515 -1172 1207 -516 1177 -518 1209 -484 493 -1216 1181 -486 1215 -514 1175 -514 495 -1192 1227 -504 1181 -486 483 -1222 1209 -476 1217 -488 505 -1232 1173 -490 1233 -476 1189 -520 517 -1168 1203 -510 1197 -474 1231 -480 495 -1210 507 -1206 1175 -518 1179 -520 1219 -478 491 -1206 503 -1184 515 -2196 1175 -554 485 -1178 1215 -506 473 -1216 483 -1208 1181 -514 1205 -486 1211 -516 483 -1182 1231 -482 1199 -478 1223 -486 519 -1212 1175 -518 1207 -482 489 -1184 1239 -474 1193 -524 491 -1210 1215 -486 1169 -520 1207 -482 485 -1248 1161 -500 1235 -486 1177 -520 509 -1196 473 -1228 1191 -474 1225 -506 1181 -486 549 -1172 489 -1216 491 -2172 1233 -484 485 -1248 +RAW_Data: 1157 -498 511 -1202 509 -1174 1237 -476 1201 -514 1205 -484 493 -1200 1187 -520 1213 -482 1173 -548 477 -1190 1215 -492 1211 -476 543 -1174 1183 -538 1163 -498 509 -1204 1205 -484 1231 -482 1169 -542 501 -1184 1215 -490 1173 -518 1207 -480 503 -1236 485 -1198 1213 -500 1175 -476 1233 -488 481 -1206 513 -1210 485 -2212 1181 -538 477 -1174 1213 -518 499 -1182 519 -1180 1205 -516 1169 -508 1215 -504 487 -1176 1241 -484 1173 -552 1181 -484 489 -1216 1183 -518 1213 -480 507 -1208 1169 -510 1203 -520 477 -1188 1215 -494 1205 -474 1215 -516 477 -1240 1165 -492 1237 -474 1195 -502 517 -1182 505 -1232 1153 -518 1215 -482 1175 -514 531 -1194 485 -1214 479 -2234 1175 -488 487 -1246 1175 -484 535 -1192 485 -1206 1205 -476 1239 -480 1175 -516 463 -1246 1187 -532 1157 -500 1237 -484 479 -1208 1211 -480 1203 -484 539 -1188 1165 -538 1191 -474 507 -1214 1187 -502 1213 -482 1207 -518 481 -1190 1217 -494 1177 -520 1209 -482 485 -1250 499 -1180 1199 -494 1205 -476 1209 -514 483 -1244 483 -1196 485 -2208 1221 -478 489 -1210 1213 -486 479 -1202 513 -1212 1177 -512 1199 -490 1201 -510 489 -1208 1199 -502 1181 -520 1203 -478 477 -1246 1181 -482 1211 -518 499 -1210 1167 -510 1217 -490 483 -1216 1209 -484 1203 -494 1199 -504 487 -1210 1189 -494 1239 -492 1165 -526 493 -1208 473 -1244 1177 -476 1235 -480 1201 -518 479 -1190 499 -1244 481 -2194 1207 -482 473 -1250 1155 -520 519 -1176 485 -1248 1161 -518 1209 -482 1203 -480 537 -1192 1167 -536 1197 -462 1229 -506 487 -1206 1201 -502 1181 -520 479 -1204 1219 -480 1187 -520 515 -1172 1181 -542 1199 -486 1205 -516 479 -1176 1243 -480 1173 -550 1173 -486 503 -1238 481 -1172 1217 -518 1171 -484 1235 -480 509 -1212 503 -1182 473 -2238 1213 -496 483 -1174 1239 -486 479 -1242 487 -1176 1215 -514 1159 -520 1213 -480 481 -1246 1177 -482 1243 -484 1165 -518 515 -1208 1179 -512 1199 -486 481 -1230 1201 -482 1227 -482 473 -1216 1211 -490 1231 -478 1185 -518 483 -1228 1175 -478 1217 -508 1183 -536 497 -1176 473 -1232 1199 -494 1197 -508 1181 -554 477 -1174 485 -1248 461 -2236 1175 -482 521 -1212 1171 -518 505 -1198 477 -1222 1181 -490 1237 -474 1199 -536 497 -1178 1219 -486 1177 -520 1205 -482 487 -1184 1239 -474 1191 -526 493 -1208 1195 -508 1181 -504 505 -1198 1201 -520 1197 -482 1203 -522 485 -1164 1249 -462 1207 -506 1197 -504 485 -1210 499 -1182 1241 -480 1205 -518 1173 -482 493 -1240 471 -1184 549 -2170 1203 -508 507 -1178 1207 -480 517 -1216 479 -1186 1229 -482 1187 -520 1213 -478 509 -1208 1185 -480 1229 -520 1173 -492 519 -1184 1207 -518 1175 -486 501 -1218 1209 -488 1205 -482 519 -1216 1193 -488 +RAW_Data: 1215 -480 1207 -484 535 -1156 1217 -516 1177 -486 1247 -476 509 -1176 511 -1204 1183 -534 1195 -486 1211 -478 509 -1172 515 -1192 517 -2210 1171 -488 541 -1196 1157 -528 493 -1208 475 -1240 1169 -488 1237 -482 1183 -538 499 -1178 1229 -480 1183 -486 1245 -480 479 -1232 1177 -480 1245 -484 501 -1184 1233 -464 1211 -520 483 -1200 1219 -478 1183 -522 1211 -480 477 -1232 1185 -480 1243 -482 1193 -474 497 -1252 483 -1174 1217 -516 1171 -514 1209 -484 485 -1220 515 -1170 513 -2204 1205 -490 511 -1202 1199 -498 481 -1210 503 -1198 1209 -490 1197 -528 1191 -486 483 -1226 1175 -482 1223 -486 1197 -538 501 -1180 1219 -488 1173 -520 479 -1218 1179 -506 1215 -490 485 -1244 1171 -486 1235 -480 1199 -478 525 -1186 1199 -534 1193 -486 1215 -480 515 -1176 511 -1204 1185 -532 1191 -486 1213 -480 513 -1180 513 -1204 489 -2212 1175 -512 507 -1182 1233 -478 493 -1176 521 -1210 1171 -548 1175 -488 1217 -492 515 -1172 1241 -484 1175 -482 1235 -482 485 -1252 1159 -522 1213 -480 479 -1214 1207 -480 1209 -512 505 -1180 1229 -478 1189 -486 1243 -478 479 -1234 1177 -514 1211 -486 1201 -490 505 -1192 493 -1242 1181 -486 1207 -520 1181 -482 525 -1184 503 -1212 503 -2156 1241 -486 483 -1232 1177 -480 495 -1240 471 -1198 1235 -484 1185 -534 1161 -500 511 -1202 1201 -486 1231 -484 1179 -524 491 -1208 1201 -490 1209 -480 545 -1170 1169 -540 1199 -486 487 -1236 1173 -480 1221 -486 1193 -524 493 -1206 1197 -508 1181 -486 1217 -514 481 -1218 515 -1160 1223 -506 1183 -474 1241 -480 513 -1210 485 -1204 485 -2196 1197 -510 507 -1184 1227 -500 483 -1178 521 -1212 1179 -512 1203 -460 1251 -486 479 -1208 1209 -482 1207 -518 1173 -486 499 -1238 1181 -488 1213 -514 483 -1220 1173 -484 1235 -514 495 -1178 1217 -488 1171 -538 1195 -500 483 -1208 1197 -502 1209 -474 1197 -506 521 -1180 505 -1218 1179 -506 1197 -506 1181 -504 505 -1184 517 -1204 505 -2212 1171 -516 495 -1214 1187 -464 549 -1180 487 -1216 1203 -486 1229 -484 1183 -502 519 -1182 1197 -532 1193 -486 1215 -480 481 -1208 1207 -478 1203 -548 477 -1182 1229 -480 1185 -504 503 -1216 1177 -486 1245 -476 1199 -516 479 -1190 1229 -502 1179 -474 1245 -480 479 -1246 481 -1198 1217 -478 1183 -522 1209 -478 507 -1210 485 -1208 489 -2210 1207 -486 509 -1182 1229 -478 491 -1208 521 -1184 1209 -482 1203 -490 1219 -490 513 -1172 1209 -482 1205 -520 1209 -480 471 -1234 1209 -486 1215 -500 485 -1208 1181 -514 1203 -506 471 -1216 1203 -506 1161 -528 1185 -522 487 -1196 1209 -478 1221 -488 1185 -548 483 -1172 505 -1204 1207 -488 1211 -514 1173 -514 509 -1180 505 -1216 487 -2204 1179 -484 529 -1216 1183 -488 515 -1202 +RAW_Data: 489 -1232 1171 -490 1233 -478 1187 -486 553 -1168 1201 -512 1197 -492 1199 -496 515 -1174 1209 -516 1167 -520 517 -1192 1187 -508 1185 -486 553 -1172 1187 -534 1187 -474 1231 -476 493 -1206 1197 -508 1181 -520 1205 -478 509 -1206 515 -1170 1217 -504 1177 -506 1205 -482 511 -1208 487 -1206 491 -2212 1209 -482 503 -1184 1227 -500 485 -1206 521 -1174 1203 -514 1167 -506 1231 -484 497 -1210 1199 -478 1221 -488 1197 -498 519 -1184 1201 -516 1177 -504 473 -1216 1207 -474 1249 -484 477 -1238 1169 -516 1201 -506 1161 -496 513 -1202 1199 -502 1211 -488 1229 -480 491 -1208 477 -1236 1167 -482 1237 -482 1183 -542 501 -1180 485 -1214 509 -2194 1197 -490 537 -1166 1197 -506 505 -1180 507 -1218 1183 -504 1211 -488 1185 -516 515 -1170 1237 -486 1201 -488 1207 -482 517 -1196 1215 -480 1229 -484 499 -1178 1235 -478 1181 -486 553 -1174 1183 -534 1191 -462 1247 -486 479 -1204 1207 -482 1205 -520 1209 -486 493 -1218 487 -1176 1217 -514 1175 -520 1213 -450 519 -1210 513 -1172 513 -2174 1249 -482 477 -1236 1197 -464 513 -1206 503 -1200 1205 -474 1195 -506 1213 -490 503 -1198 1201 -472 1229 -516 1193 -486 515 -1174 1209 -512 1201 -492 477 -1242 1173 -486 1237 -482 485 -1240 1175 -486 1241 -480 1175 -514 531 -1156 1189 -524 1185 -520 1209 -480 509 -1168 549 -1176 1183 -536 1195 -488 1211 -480 513 -1174 547 -1174 489 -2194 1201 -482 535 -1196 1187 -498 529 -1178 475 -1242 1173 -482 1235 -482 1183 -526 493 -1208 1195 -506 1179 -486 1243 -480 479 -1232 1181 -480 1229 -522 477 -1180 1231 -478 1185 -556 477 -1174 1243 -486 1195 -488 1217 -482 479 -1248 1181 -484 1215 -506 1183 -476 515 -1196 517 -1218 1169 -486 1229 -482 1191 -500 511 -1204 477 -1200 547 -2164 1209 -482 511 -1206 1185 -514 483 -1216 513 -1160 1249 -462 1209 -522 1175 -482 517 -1218 1199 -484 1211 -482 1207 -518 481 -1188 1215 -494 1207 -472 545 -1182 1175 -550 1173 -490 507 -1208 1175 -488 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/hay21_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/hay21_raw.sub new file mode 100644 index 00000000000..beab064622a --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/hay21_raw.sub @@ -0,0 +1,10 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 99 -820 65 -230 65 -802 361 -852 131 -162 131 -298 133 -306 99 -198 129 -430 99 -732 197 -742 131 -302 197 -238 233 -132 99 -532 99 -168 101 -306 65 -832 133 -304 65 -300 65 -664 131 -198 133 -232 101 -234 99 -134 133 -404 65 -262 163 -654 131 -702 133 -864 131 -194 95 -390 131 -388 99 -1078 65 -260 97 -364 65 -194 161 -258 163 -228 97 -394 131 -336 133 -198 63 -358 97 -392 199 -164 65 -390 97 -426 99 -162 163 -326 193 -326 131 -456 131 -400 99 -700 133 -198 133 -400 131 -302 99 -202 65 -200 99 -1002 133 -236 169 -406 165 -372 99 -202 99 -334 165 -304 131 -332 133 -132 65 -464 133 -400 99 -298 67 -960 163 -400 133 -402 129 -166 101 -268 133 -432 133 -374 101 -366 101 -19558 129 -454 97 -23210 133 -688 129 -196 131 -162 65 -422 65 -132 163 -228 63 -194 65 -228 131 -292 129 -552 65 -986 65 -530 131 -164 99 -294 65 -796 65 -466 133 -200 131 -136 133 -1970 99 -1594 133 -966 65 -100 99 -300 99 -534 65 -664 99 -332 65 -198 97 -1086 131 -304 133 -402 167 -166 67 -996 99 -728 133 -268 131 -1684 163 -394 129 -690 65 -558 65 -132 131 -162 95 -456 97 -362 133 -168 67 -306 133 -202 67 -168 197 -338 167 -438 101 -362 97 -470 101 -402 65 -1058 131 -336 133 -1402 133 -402 165 -236 65 -432 99 -764 133 -470 65 -200 67 -166 131 -436 99 -398 99 -168 135 -902 65 -234 135 -200 199 -166 65 -628 197 -662 165 -694 65 -166 67 -564 65 -1072 99 -334 167 -168 131 -1058 131 -336 131 -370 99 -198 133 -462 131 -302 133 -438 67 -368 133 -1036 97 -634 165 -134 135 -670 99 -370 161 -690 65 -296 131 -1000 99 -436 133 -170 101 -404 99 -170 101 -270 67 -268 131 -302 131 -672 133 -234 65 -502 99 -604 65 -1260 99 -232 99 -964 131 -338 99 -200 65 -232 99 -168 135 -168 67 -204 67 -134 133 -370 99 -428 133 -234 135 -1128 163 -454 97 -362 163 -458 65 -164 99 -596 99 -268 131 -1562 65 -398 99 -402 163 -438 67 -368 65 -988 97 -622 131 -162 97 -390 133 -368 135 -402 133 -164 65 -438 131 -686 165 -334 99 -460 99 -368 167 -22538 65 -170 65 -766 99 -1098 165 -760 99 -364 65 -722 65 -2132 163 -326 163 -402 133 -266 161 -406 97 -168 101 -404 163 -168 67 -266 65 -334 65 -402 97 -494 65 -132 97 -462 99 -336 133 -334 131 -198 133 -672 131 -200 65 -1036 67 -1028 165 -702 99 -402 97 -1234 97 -196 63 -488 131 -658 65 -498 +RAW_Data: 97 -270 131 -566 65 -168 67 -336 67 -996 133 -300 67 -166 101 -702 99 -1202 131 -264 97 -590 163 -1680 99 -228 95 -162 97 -194 65 -886 99 -3586 65 -558 131 -1486 99 -634 65 -100 133 -132 67 -1134 97 -658 65 -1446 65 -564 133 -234 133 -372 65 -166 99 -1362 99 -332 97 -202 133 -1984 97 -198 65 -394 161 -23544 65 -334 99 -298 165 -570 167 -334 99 -198 67 -836 131 -290 65 -724 99 -298 165 -130 97 -264 127 -628 165 -266 131 -200 101 -234 135 -564 165 -234 99 -202 97 -368 131 -466 131 -1770 65 -326 165 -622 131 -296 133 -496 97 -1166 65 -1512 97 -1090 99 -534 165 -498 101 -336 99 -300 167 -302 65 -302 133 -1158 65 -166 99 -666 65 -736 233 -566 99 -502 99 -596 131 -168 135 -370 99 -1758 67 -3408 129 -1212 99 -690 65 -2674 67 -696 97 -200 65 -500 97 -338 65 -298 99 -234 165 -636 97 -724 65 -1424 97 -918 131 -198 65 -366 65 -562 99 -456 163 -1142 99 -394 165 -262 325 -230 97 -424 65 -460 131 -1150 129 -394 163 -356 197 -722 131 -920 97 -424 65 -1114 65 -262 97 -394 97 -888 97 -520 97 -21882 97 -2496 97 -164 97 -848 99 -47158 99 -234 99 -600 67 -1088 65 -918 63 -230 99 -162 127 -288 131 -164 97 -756 131 -392 99 -404 65 -400 67 -132 99 -302 131 -688 65 -982 131 -970 199 -372 101 -966 97 -130 129 -980 133 -1116 99 -162 95 -390 65 -428 163 -324 131 -266 99 -266 135 -1302 131 -470 199 -472 97 -358 97 -164 65 -230 99 -402 99 -398 99 -370 133 -372 99 -398 99 -166 129 -394 99 -266 67 -668 133 -1000 133 -734 131 -898 163 -324 131 -164 97 -424 99 -336 165 -328 163 -162 63 -946 129 -620 131 -130 129 -356 63 -296 131 -194 65 -390 97 -1692 129 -360 195 -390 127 -400 133 -200 65 -1034 133 -630 97 -162 129 -422 133 -1626 97 -368 133 -202 97 -1038 133 -498 133 -630 165 -730 97 -704 65 -134 97 -434 165 -462 99 -268 99 -628 165 -672 131 -1448 165 -604 167 -366 99 -398 131 -230 67 -438 65 -134 133 -432 67 -430 97 -232 65 -404 101 -426 131 -198 97 -756 131 -290 165 -298 99 -200 65 -1330 99 -702 131 -462 229 -294 161 -656 97 -196 97 -390 165 -1510 63 -2134 131 -328 129 -164 97 -726 99 -166 67 -134 97 -66 65 -730 99 -264 133 -266 165 -298 67 -1132 99 -1000 101 -200 67 -766 101 -368 165 -404 133 -832 99 -604 133 -640 197 -234 101 -134 99 -432 99 -100 133 -792 131 -168 101 -500 99 -298 101 -764 +RAW_Data: 133 -334 97 -196 97 -266 131 -202 167 -798 97 -966 99 -802 65 -396 65 -1062 101 -794 97 -770 131 -230 133 -728 99 -398 99 -268 133 -268 101 -1004 65 -964 97 -402 101 -438 131 -1168 97 -1494 65 -1446 99 -202 65 -566 131 -306 99 -198 65 -234 131 -470 63 -1092 165 -660 99 -266 131 -1006 67 -198 99 -3394 65 -696 199 -1100 65 -228 163 -230 131 -360 65 -228 97 -230 97 -164 97 -228 197 -164 135 -332 165 -166 133 -168 131 -1696 97 -1742 99 -556 131 -1180 65 -534 67 -794 65 -360 99 -2958 99 -532 65 -234 101 -166 67 -232 99 -734 99 -528 65 -432 65 -198 133 -66 197 -334 63 -924 131 -754 131 -1064 67 -298 99 -566 65 -330 65 -202 65 -998 65 -2024 163 -834 99 -366 65 -398 167 -5114 755 -4222 691 -310 657 -348 247 -724 257 -714 257 -726 283 -698 669 -302 683 -294 703 -312 285 -694 679 -290 679 -308 691 -318 657 -290 289 -702 677 -316 659 -324 297 -678 677 -316 691 -292 693 -4228 675 -318 667 -304 281 -692 289 -700 285 -694 281 -728 669 -302 683 -294 701 -312 285 -664 683 -324 673 -312 657 -316 691 -290 283 -702 677 -318 659 -322 295 -674 707 -284 697 -274 685 -4252 677 -318 663 -304 317 -688 259 -698 309 -696 283 -684 677 -316 661 -342 653 -294 309 -692 675 -318 659 -324 655 -344 657 -318 287 -698 683 -278 695 -310 285 -694 675 -318 663 -302 683 -4250 675 -320 659 -292 303 -682 291 -700 311 -662 317 -690 677 -318 661 -292 703 -310 269 -696 669 -316 691 -290 677 -310 689 -320 287 -682 685 -314 657 -314 285 -694 677 -316 663 -294 701 -4224 677 -318 661 -322 293 -676 289 -700 297 -696 281 -694 679 -294 701 -312 657 -316 285 -688 681 -314 695 -310 649 -294 701 -302 277 -700 681 -314 681 -290 285 -704 677 -318 659 -292 721 -4218 675 -318 693 -290 295 -680 291 -702 275 -698 313 -686 677 -318 663 -304 681 -294 277 -716 671 -318 659 -324 661 -344 655 -318 285 -698 685 -278 693 -312 285 -686 677 -316 661 -306 683 -4248 679 -318 663 -304 317 -656 289 -700 311 -662 317 -692 677 -318 663 -292 705 -310 271 -696 687 -312 657 -292 701 -312 657 -316 287 -686 677 -316 693 -310 287 -694 677 -318 665 -300 679 -4246 677 -318 665 -300 279 -692 289 -700 309 -662 317 -692 677 -318 667 -300 683 -294 277 -716 677 -320 659 -290 689 -310 689 -320 287 -682 687 -314 657 -314 287 -694 677 -318 663 -304 681 -4254 677 -286 701 -300 277 -684 289 -698 285 -726 277 -704 677 -294 699 -274 +RAW_Data: 693 -320 273 -696 681 -290 681 -308 691 -320 677 -290 295 -680 677 -318 695 -290 295 -678 675 -320 695 -258 721 -4222 677 -320 673 -294 301 -682 291 -696 311 -664 317 -692 673 -320 665 -300 681 -294 275 -718 677 -318 661 -290 687 -308 691 -320 285 -698 683 -280 691 -312 287 -694 677 -318 663 -144512 67 -362 131 -164 97 -456 99 -268 167 -674 133 -404 165 -334 165 -168 67 -404 133 -440 165 -304 165 -568 163 -298 97 -1054 65 -864 165 -302 101 -370 67 -764 97 -362 65 -690 99 -2320 99 -200 65 -1630 131 -564 99 -200 67 -302 65 -762 65 -366 99 -432 131 -134 131 -166 99 -366 133 -168 103 -668 99 -166 133 -304 133 -338 65 -200 99 -768 99 -368 131 -264 101 -402 65 -1062 131 -134 65 -434 133 -234 65 -396 99 -166 133 -366 65 -432 99 -766 167 -762 165 -1320 65 -490 97 -396 131 -464 97 -1346 99 -230 63 -420 97 -324 127 -822 131 -1558 65 -472 99 -500 65 -134 131 -434 65 -664 163 -470 133 -328 131 -1228 97 -164 97 -692 129 -936 133 -1882 99 -1620 63 -1118 97 -488 129 -728 99 -466 101 -468 65 -198 131 -202 65 -266 167 -630 65 -232 99 -1590 131 -666 97 -1294 99 -728 97 -564 67 -436 97 -22018 99 -1560 101 -200 65 -1896 65 -532 133 -202 97 -2158 133 -1600 65 -1016 65 -198 65 -260 67 -1154 65 -2234 97 -1188 133 -232 101 -336 99 -2400 99 -856 133 -884 97 -1312 129 -456 129 -746 65 -988 165 -324 99 -430 129 -164 99 -362 129 -360 131 -428 131 -598 65 -464 99 -468 131 -22500 65 -758 67 -2260 99 -164 99 -658 63 -228 163 -708 65 -730 99 -370 99 -728 97 -502 67 -298 165 -968 99 -198 65 -398 129 -882 131 -358 97 -22984 65 -688 97 -196 97 -718 131 -1210 129 -654 99 -170 135 -168 67 -338 135 -266 65 -500 65 -794 99 -100 99 -406 97 -234 65 -168 99 -406 63 -100 165 -200 99 -1298 131 -772 165 -704 65 -132 65 -1660 163 -360 133 -830 97 -724 99 -732 99 -426 63 -1356 165 -1180 131 -228 129 -720 167 -832 131 -262 163 -590 131 -400 99 -234 133 -166 67 -1598 99 -1428 65 -592 163 -286 131 -816 133 -266 167 -500 131 -698 133 -468 99 -402 99 -434 167 -200 165 -162 99 -304 101 -738 133 -336 99 -1800 165 -732 133 -722 67 -556 97 -326 97 -164 163 -458 99 -434 65 -166 65 -198 161 -1148 165 -914 99 -162 65 -130 165 -992 163 -952 65 -560 99 -826 65 -664 163 -620 197 -350 161 -292 161 -388 65 -494 65 -432 67 -202 101 -234 65 -722 +RAW_Data: 163 -196 63 -460 163 -468 65 -166 99 -334 129 -666 63 -230 63 -66 97 -328 129 -232 127 -494 129 -358 131 -260 197 -322 97 -628 99 -656 163 -358 99 -2128 133 -336 99 -1070 165 -368 99 -1004 65 -332 65 -330 163 -102 99 -2830 65 -1434 65 -800 65 -530 65 -1516 131 -400 97 -554 63 -300 99 -334 99 -1130 65 -896 99 -166 65 -1724 131 -270 99 -1068 131 -1168 97 -52402 99 -2098 99 -196 65 -454 65 -1644 97 -1754 65 -332 97 -794 131 -364 165 -330 99 -2220 129 -468 197 -1090 97 -360 65 -1746 63 -164 127 -784 131 -1284 65 -396 65 -390 97 -422 65 -428 97 -592 97 -1312 65 -694 131 -266 67 -732 97 -460 195 -360 65 -982 97 -2244 133 -472 99 -1096 97 -1762 65 -1664 131 -134 131 -1192 97 -1736 131 -204 99 -668 99 -602 165 -654 163 -324 161 -328 129 -960 65 -466 101 -768 131 -1588 99 -502 67 -988 65 -952 129 -424 65 -228 161 -162 129 -452 131 -954 65 -954 99 -328 65 -1564 133 -1300 131 -164 133 -728 135 -200 165 -298 131 -1572 131 -328 65 -164 133 -336 99 -1260 133 -370 97 -466 67 -830 197 -1260 131 -330 131 -1034 65 -198 97 -1378 133 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/hollarm.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/hollarm.sub new file mode 100644 index 00000000000..0b29739ee75 --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/hollarm.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Hollarm +Bit: 42 +Key: 00 00 00 ED 24 3C 22 6F diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/hollarm_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/hollarm_raw.sub new file mode 100644 index 00000000000..8bc83019e2e --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/hollarm_raw.sub @@ -0,0 +1,10 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 211 -978 199 -1602 209 -988 193 -990 217 -1592 209 -1616 205 -958 201 -1618 211 -1574 195 -1628 193 -1590 201 -992 209 -2406 199 -1604 195 -1592 195 -1616 193 -990 185 -1628 211 -1586 201 -986 201 -1608 211 -984 199 -996 233 -1576 195 -998 203 -990 195 -1632 193 -994 189 -998 205 -990 199 -1006 205 -1586 197 -1596 225 -1584 195 -1614 195 -992 211 -1020 195 -960 207 -984 195 -1618 201 -998 247 -952 199 -998 201 -1610 197 -1002 205 -1018 197 -1566 193 -1618 201 -1000 209 -1582 195 -1632 195 -1560 197 -1638 207 -956 199 -2416 199 -1626 177 -1614 201 -1580 201 -1032 213 -1548 197 -1626 193 -994 187 -1628 207 -950 225 -992 203 -1588 207 -1026 203 -968 205 -1622 197 -970 191 -1028 209 -982 199 -1028 205 -1552 201 -1628 201 -1556 207 -1632 197 -974 239 -978 201 -982 205 -1022 199 -1572 201 -1032 177 -984 197 -1024 185 -1594 209 -1016 201 -1000 211 -1594 197 -1572 201 -1034 177 -1582 197 -1626 195 -1622 193 -1556 199 -1030 207 -2384 199 -1594 195 -1618 201 -1562 241 -982 195 -1630 195 -1590 195 -1022 189 -1590 185 -1030 205 -954 227 -1590 191 -996 207 -1030 195 -1584 195 -1026 185 -1000 197 -974 205 -1020 199 -1572 227 -1584 193 -1616 195 -1586 201 -1028 207 -956 203 -1016 203 -986 203 -1610 211 -980 199 -976 235 -992 195 -1620 193 -996 211 -974 201 -1590 211 -1610 201 -980 193 -1620 191 -1592 209 -1618 205 -1586 197 -1000 191 -2416 205 -1586 207 -1564 225 -1586 227 -958 221 -1620 189 -1590 215 -994 207 -1588 229 -968 191 -996 205 -1588 229 -972 189 -1028 211 -1574 227 -1000 193 -962 243 -1002 201 -968 201 -1612 197 -1594 203 -1592 209 -1618 207 -958 203 -992 229 -1006 201 -980 199 -1602 195 -996 189 -1028 213 -976 201 -1592 209 -980 195 -1026 187 -1590 211 -1608 201 -978 205 -1610 211 -1606 199 -1574 201 -1596 201 -994 195 -2424 193 -1588 227 -1554 235 -1592 205 -988 227 -1562 201 -1620 195 -990 211 -1608 199 -978 205 -1014 199 -1574 201 -1032 211 -958 199 -1626 211 -958 199 -1038 211 -974 201 -962 229 -1600 195 -1622 193 -1588 193 -1618 195 -988 185 -1032 205 -960 203 -1014 237 -1546 201 -1028 187 -996 201 -978 223 -1582 225 -994 211 -986 199 -1624 213 -1550 195 -1036 201 -1556 207 -1630 197 -1602 195 -1590 193 -1022 189 -2382 215 -1590 211 -1586 203 -1580 195 -1020 225 -1558 185 -1628 209 -988 225 -1580 195 -1020 191 -996 205 -1620 197 -970 191 -996 207 -1594 197 -1004 239 -980 199 -980 205 -1016 199 -1576 201 -1628 203 -1606 213 -1550 195 -1034 203 -976 199 -976 225 -990 211 -1614 199 -978 205 -992 193 -1032 203 -1574 213 -1002 201 -968 +RAW_Data: 207 -1594 231 -1598 195 -1000 207 -1576 245 -1564 193 -1618 195 -1554 257 -990 207 -2372 207 -1596 193 -1590 225 -1586 225 -958 221 -1590 219 -1592 213 -982 193 -1586 199 -1040 211 -970 201 -1588 209 -986 201 -1006 209 -1596 193 -1024 193 -994 211 -1002 201 -968 207 -1596 229 -1566 201 -1596 201 -1618 211 -982 199 -978 199 -1018 201 -996 199 -1606 197 -998 207 -988 229 -974 203 -1612 211 -974 201 -1014 207 -1554 225 -1584 225 -960 219 -1590 219 -1590 215 -1590 185 -1624 185 -998 199 -2404 195 -1626 195 -1556 235 -1594 191 -996 207 -1584 229 -1600 193 -998 205 -1584 207 -1004 201 -992 203 -1580 201 -1030 211 -960 197 -1630 211 -958 199 -1008 241 -964 201 -996 197 -1602 195 -1628 195 -1560 235 -1592 211 -958 199 -1032 207 -964 203 -996 241 -1568 195 -1032 193 -992 211 -976 201 -1606 209 -960 235 -996 207 -1558 259 -1554 195 -1020 225 -1558 209 -1620 207 -1552 201 -1626 199 -996 233 -2368 195 -1588 225 -1586 225 -1552 227 -992 207 -1584 201 -1612 195 -1000 205 -1584 207 -1004 203 -992 201 -1582 227 -994 205 -982 195 -1624 195 -994 189 -1032 211 -970 201 -994 237 -1546 201 -1624 201 -1570 247 -1550 229 -1008 201 -994 197 -976 203 -1016 199 -1574 201 -1030 185 -998 199 -1010 201 -1566 211 -1022 201 -998 213 -1596 197 -1570 201 -1030 185 -1594 247 -1544 197 -1626 195 -1588 193 -1024 205 -2378 207 -1594 195 -1588 227 -1586 225 -960 219 -1594 207 -1584 201 -1010 193 -1588 205 -1014 201 -980 191 -1620 191 -996 207 -1028 195 -1582 195 -1028 213 -956 199 -976 237 -996 201 -1606 211 -1582 197 -1602 193 -1596 201 -1000 211 -982 201 -1030 205 -954 203 -1612 211 -978 195 -1024 185 -996 201 -1610 195 -1002 205 -984 225 -1560 225 -1588 227 -958 219 -1594 219 -1558 217 -1596 211 -1610 201 -982 205 -2402 211 -1608 199 -1572 203 -1592 225 -960 245 -1598 197 -1600 195 -998 205 -1582 209 -1004 201 -960 197 -1630 195 -1000 243 -946 231 -1596 195 -994 191 -996 205 -994 199 -998 199 -1610 195 -1598 239 -1550 193 -1620 191 -996 207 -1032 201 -964 201 -984 203 -1628 207 -968 199 -1014 201 -994 199 -1604 195 -996 189 -1030 211 -1570 193 -1622 193 -990 189 -1628 207 -1586 207 -1556 227 -1588 225 -958 219 -2388 209 -1618 205 -1592 195 -1598 201 -998 207 -1600 193 -1592 201 -992 211 -1608 199 -978 203 -1016 201 -1578 201 -1030 185 -996 197 -1602 197 -996 191 -1028 211 -972 195 -992 247 -1548 229 -1596 197 -1588 195 -1616 195 -990 185 -1028 207 -960 235 -994 201 -1578 201 -1030 185 -996 199 -1008 195 -1582 193 -1028 211 -980 201 -1604 209 -1582 197 -1008 195 -1588 +RAW_Data: 203 -1610 211 -1606 199 -1574 201 -1000 215 -2388 211 -1580 195 -1626 195 -1560 271 -960 211 -1574 229 -1566 201 -1026 209 -1588 197 -1008 201 -996 197 -1602 193 -996 189 -996 241 -1570 195 -1032 203 -976 199 -976 205 -1024 199 -1570 201 -1622 195 -1622 203 -1554 207 -1000 235 -962 201 -1012 195 -992 211 -1608 201 -982 205 -984 229 -970 237 -1556 243 -974 195 -990 209 -1608 201 -1608 197 -998 207 -1578 245 -1564 193 -1588 227 -1584 225 -994 205 -2380 207 -1556 259 -1556 193 -1616 225 -958 219 -1594 209 -1580 199 -1014 195 -1582 255 -960 211 -982 201 -1602 209 -986 195 -1018 193 -1592 211 -1020 193 -992 189 -1030 211 -970 201 -1608 211 -1554 197 -1630 195 -1622 195 -990 189 -996 205 -988 201 -996 201 -1606 195 -998 189 -1030 211 -976 203 -1588 211 -986 199 -1008 209 -1596 195 -1584 227 -990 187 -1624 187 -1594 243 -1548 201 -1610 195 -998 189 -2414 189 -1620 191 -1590 185 -1622 185 -998 235 -1584 195 -1622 193 -992 189 -1626 207 -950 195 -1022 225 -1556 209 -1020 195 -998 207 -1582 245 -968 203 -1012 205 -956 203 -994 195 -1630 193 -1590 227 -1552 225 -1590 199 -998 201 -1016 199 -990 213 -1006 195 -1586 193 -1026 185 -998 199 -974 225 -1584 203 -998 241 -968 195 -1618 195 -1584 191 -1028 211 -1574 193 -1592 225 -1558 271 -1554 191 -1028 211 -2366 227 -1562 237 -1586 199 -1568 211 -1016 193 -1580 197 -1614 195 -990 211 -1612 199 -982 239 -996 197 -1600 195 -994 191 -996 205 -1586 229 -968 191 -1032 211 -976 201 -996 239 -1548 201 -1624 201 -1590 209 -1582 197 -1028 195 -992 211 -972 223 -990 211 -1552 263 -978 203 -978 199 -1012 201 -1568 211 -1018 201 -1000 213 -1596 197 -1566 227 -992 205 -1620 211 -1566 193 -1592 227 -1554 235 -1000 213 -2398 199 -1570 201 -1598 203 -1610 211 -984 199 -1606 209 -1584 197 -1010 199 -1570 211 -1018 201 -1000 211 -1594 199 -970 193 -1028 211 -1572 195 -1028 195 -992 211 -1006 201 -966 201 -1614 197 -1594 193 -1618 201 -1564 245 -982 195 -1000 205 -984 229 -970 191 -1626 203 -984 195 -1028 193 -992 211 -1604 197 -974 203 -1026 199 -1574 203 -1594 203 -990 197 -1630 193 -1560 271 -1554 189 -1628 205 -988 193 -2382 237 -1588 199 -1592 211 -1596 199 -974 191 -1622 189 -1624 205 -968 235 -1576 197 -1000 191 -996 241 -1570 193 -1028 195 -992 211 -1604 199 -976 203 -990 195 -1028 201 -978 197 -1606 195 -1628 195 -1558 235 -1588 187 -996 201 -1016 199 -1006 205 -952 255 -1584 193 -962 279 -948 199 -1006 205 -1582 229 -968 191 -1028 211 -1574 193 -1594 227 -960 243 -1590 205 -1588 197 -1600 201 -1596 203 -990 +RAW_Data: 195 -2422 193 -1584 227 -1618 191 -1558 235 -994 209 -1558 225 -1588 237 -956 211 -1612 197 -980 205 -1000 245 -1560 193 -1026 193 -994 211 -1598 197 -974 205 -1022 199 -980 203 -1022 199 -1570 201 -1598 201 -1588 207 -1620 199 -972 237 -992 211 -974 201 -1012 207 -1550 227 -992 237 -958 195 -1034 193 -1588 189 -1032 211 -974 201 -1608 211 -1556 195 -1034 199 -1558 243 -1596 197 -1602 195 -1594 195 -1026 205 -2388 185 -1592 211 -1602 199 -1574 227 -992 203 -1614 211 -1570 193 -1030 203 -1554 207 -1032 201 -970 207 -1590 229 -968 191 -1030 211 -1572 195 -1032 203 -958 195 -1004 205 -1022 197 -1568 227 -1590 201 -1600 203 -1586 207 -990 225 -958 217 -1000 239 -950 225 -1588 225 -962 209 -996 225 -990 185 -1624 209 -956 225 -962 211 -1616 199 -1608 195 -1002 205 -1608 211 -1568 195 -1588 227 -1588 237 -956 211 -2406 199 -1604 195 -1594 201 -1596 209 -990 201 -1592 209 -1584 233 -986 201 -1590 211 -984 201 -976 203 -1614 197 -1000 207 -988 229 -1566 237 -990 185 -996 197 -1012 201 -996 197 -1602 195 -1592 193 -1616 201 -1598 203 -982 195 -998 223 -990 211 -984 201 -1590 213 -984 195 -1024 187 -994 201 -1610 195 -1004 203 -1000 209 -1562 225 -1586 227 -956 243 -1582 207 -1596 229 -1566 203 -1598 201 -982 197 -2426 193 -1588 227 -1554 271 -1550 193 -1028 211 -1578 195 -1622 193 -992 187 -1622 189 -996 205 -988 225 -1556 203 -1014 237 -952 203 -1618 211 -976 201 -1010 205 -966 225 -964 245 -1564 231 -1598 195 -1590 193 -1618 193 -990 185 -1030 207 -964 201 -1016 237 -1548 201 -1028 211 -960 199 -1032 207 -1556 235 -990 187 -996 203 -1612 197 -1596 201 -998 209 -1560 227 -1590 201 -1624 201 -1572 211 -1012 201 -2360 243 -1580 207 -1586 229 -1566 203 -1002 209 -1580 227 -1596 195 -958 251 -1592 207 -988 195 -1000 191 -1624 205 -982 193 -994 189 -1626 205 -952 257 -964 235 -960 195 -1036 201 -1556 207 -1630 199 -1600 195 -1594 201 -998 207 -1002 201 -958 231 -1006 193 -1622 203 -976 199 -974 191 -1028 211 -1576 227 -968 227 -960 245 -1596 197 -1602 195 -1000 205 -1584 207 -1598 193 -1586 225 -1584 225 -986 189 -2420 207 -1550 201 -1614 195 -1624 195 -994 189 -1626 207 -1550 203 -1016 201 -1592 211 -1008 201 -966 209 -1628 197 -972 191 -1028 211 -1576 195 -1030 201 -978 199 -1006 193 -992 211 -1610 199 -1576 195 -1620 195 -1614 195 -990 211 -956 235 -996 207 -998 201 -1586 213 -978 195 -1024 187 -998 199 -1606 195 -1004 205 -1000 207 -1562 225 -1588 225 -960 219 -1592 219 -1594 207 -1586 199 -1612 195 -998 207 -2372 209 -1598 231 -1562 195 -1614 +RAW_Data: 195 -986 219 -1592 209 -1618 207 -960 203 -1624 211 -974 193 -1026 211 -1566 207 -996 235 -962 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/legrand.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/legrand.sub new file mode 100644 index 00000000000..7041324cb6d --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/legrand.sub @@ -0,0 +1,8 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Legrand +Bit: 18 +Key: 00 00 00 00 00 02 E3 7F +TE: 358 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/legrand_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/legrand_raw.sub new file mode 100644 index 00000000000..ba703925c32 --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/legrand_raw.sub @@ -0,0 +1,22 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 10133 -4946 65 -5114 65 -1750 67 -232 165 -536 165 -166 533 -694 395 -198 263 -66 395 -12664 297 -662 133 -264 99 -102 131 -200 131 -234 263 -66 265 -100 661 -168 197 -134 297 -66 431 -132 45005 -12358 131 -100 129 -66 65 -198 65 -66 197 -1018 131 -266 97 -1052 97 -228 459 -100 1517 -100 4361 -10350 165 -1264 65 -232 131 -200 65 -166 133 -232 299 -132 65 -166 299 -134 231 -198 99 -68 429 -12270 231 -628 163 -594 97 -496 227 -1220 163 -166 129 -66 655 -98 163 -66 393 -66 195 -198 293 -12130 67 -68 331 -134 99 -98 99 -332 99 -562 163 -164 65 -130 131 -920 131 -98 65 -198 133 -98 427 -130 359 -132 627 -66 2207 -16066 163 -1316 331 -832 131 -370 131 -132 661 -166 265 -134 833 -168 34477 -10228 65 -2266 261 -230 131 -198 129 -1282 65 -66 463 -100 365 -232 233 -66 297 -166 2151 -12330 99 -400 97 -436 131 -896 165 -400 363 -298 199 -166 97 -430 165 -168 365 -132 725 -130 3253 -12440 131 -796 297 -332 65 -830 65 -828 429 -198 335 -66 665 -266 29175 -12140 163 -230 131 -992 165 -1230 397 -132 199 -132 299 -66 659 -100 9675 -11036 99 -570 99 -830 165 -662 331 -266 429 -132 391 -396 431 -132 233 -166 231 -100 3435 -11728 99 -332 165 -166 63 -128 161 -326 129 -690 231 -130 265 -98 167 -232 199 -66 201 -264 165 -166 365 -66 727 -100 363 -12688 229 -228 95 -98 391 -198 129 -196 97 -364 97 -100 65 -266 99 -64 293 -98 327 -262 761 -66 7681 -5384 99 -762 195 -134 525 -992 99 -166 67 -98 329 -100 659 -100 293 -100 97 -98 163 -264 1741 -100 57331 -9834 67 -664 67 -2158 99 -862 133 -368 331 -864 65 -330 65 -794 99 -66 431 -100 3017 -66 7061 -6558 99 -6316 99 -266 131 -166 97 -198 65 -294 99 -66 661 -132 2661 -130 19413 -12380 65 -262 133 -66 67 -232 133 -798 197 -264 165 -498 97 -166 199 -134 559 -98 165 -13118 99 -562 65 -1256 231 -232 99 -132 131 -66 199 -66 429 -296 131 -200 201 -266 65 -66 895 -132 829 -66 12455 -11974 199 -334 99 -2160 165 -1232 929 -100 327 -166 295 -134 2191 -100 20415 -11032 65 -1170 131 -2326 163 -398 263 -596 99 -400 165 -68 499 -66 661 -11724 97 -1226 99 -166 233 -400 131 -662 165 -400 165 -166 299 -296 1159 -100 131 -98 427 -68 1643 -13934 101 -1294 65 -394 63 -1458 265 -166 265 -364 133 -434 101 -398 195 -264 1097 -166 265 -166 58013 -11978 131 -100 165 -666 199 -66 163 -166 65 -198 195 -592 1295 -134 597 -136 567 -100 1615 -100 17759 -12402 261 -692 +RAW_Data: 265 -730 327 -398 131 -300 199 -432 7947 -4772 233 -366 365 -166 133 -522 99 -164 65 -366 99 -100 395 -66 4423 -15068 197 -430 163 -398 65 -230 165 -228 97 -494 165 -134 197 -168 131 -168 65 -298 267 -132 1657 -98 99 -66 165 -100 7687 -12010 197 -132 163 -198 527 -130 293 -396 297 -360 163 -264 95 -164 161 -694 427 -262 129 -100 885 -100 131 -66 461 -9862 97 -5002 497 -594 197 -66 229 -596 65 -132 195 -262 99 -132 63 -166 65 -230 431 -100 165 -168 461 -164 13159 -12060 133 -64 129 -1316 131 -758 165 -430 165 -270 133 -564 995 -7536 99 -4746 165 -358 457 -132 165 -166 99 -100 397 -132 299 -66 197 -66 131 -392 129 -196 131 -328 459 -100 565 -66 165 -66 265 -100 1131 -100 9533 -12070 65 -400 163 -366 165 -530 197 -196 133 -68 233 -398 165 -66 99 -100 163 -132 791 -66 17359 -12434 131 -328 229 -558 195 -564 167 -132 133 -234 131 -100 65 -364 65 -496 65 -200 297 -66 1725 -12958 63 -68 65 -164 67 -132 63 -200 131 -166 165 -696 131 -166 67 -200 65 -168 1061 -12848 199 -166 2039 -1660 201 -5822 1017 -1126 299 -414 1015 -388 1061 -380 1055 -1086 327 -1118 339 -1084 351 -360 1051 -376 1083 -1070 343 -346 1105 -350 1069 -354 1087 -346 1063 -362 1075 -372 1067 -334 1097 -5694 1083 -1074 351 -378 1057 -332 1101 -370 1065 -1050 379 -1050 379 -1066 363 -348 1073 -388 1047 -1076 351 -380 1053 -362 1071 -372 1067 -352 1081 -352 1069 -350 1091 -346 1087 -5682 1095 -1044 381 -342 1097 -326 1111 -346 1061 -1064 379 -1066 381 -1032 379 -360 1065 -364 1067 -1066 375 -352 1081 -350 1069 -350 1089 -352 1081 -350 1069 -350 1097 -326 1081 -5698 1097 -1074 353 -354 1083 -326 1111 -344 1083 -1054 387 -1046 349 -1094 345 -350 1081 -354 1069 -1076 385 -350 1051 -354 1077 -386 1057 -334 1099 -370 1051 -354 1083 -356 1087 -5670 1107 -1072 353 -354 1081 -326 1111 -346 1085 -1054 389 -1050 353 -1056 377 -352 1083 -350 1071 -1080 381 -312 1099 -334 1107 -358 1079 -320 1091 -350 1095 -348 1081 -318 1113 -5688 1075 -1076 353 -354 1085 -324 1111 -346 1067 -1056 387 -1048 381 -1070 383 -314 1085 -352 1073 -1078 385 -348 1049 -354 1103 -356 1055 -334 1097 -372 1049 -354 1081 -354 1087 -5680 1109 -1038 383 -356 1085 -326 1107 -344 1065 -1066 361 -1076 371 -1054 389 -330 1069 -376 1069 -1054 389 -332 1073 -374 1069 -354 1079 -320 1097 -350 1093 -348 1083 -322 1111 -5680 1105 -1044 359 -356 1083 -354 1085 -348 1097 -1050 387 -1042 349 -1074 385 -350 1053 -352 1077 -1082 379 -314 1099 -336 1095 -346 1075 -374 1071 -354 1081 -320 1095 -348 1097 -5686 +RAW_Data: 1085 -1062 369 -346 1093 -322 1105 -350 1063 -1076 351 -1070 381 -1068 355 -358 1087 -354 1049 -1070 351 -384 1081 -318 1113 -344 1065 -348 1083 -352 1071 -388 1051 -352 1081 -5706 1065 -1064 361 -348 1087 -356 1079 -348 1091 -1072 381 -1020 375 -1068 361 -356 1081 -354 1085 -1042 381 -352 1079 -352 1101 -320 1093 -346 1087 -322 1117 -354 1057 -334 1099 -5702 1085 -1044 381 -340 1087 -352 1081 -352 1069 -1080 379 -1032 379 -1050 377 -346 1099 -332 1077 -1084 355 -334 1101 -334 1089 -350 1097 -320 1095 -348 1097 -326 1077 -376 1053 -5706 1073 -1088 367 -346 1063 -354 1071 -382 1067 -1076 347 -1068 381 -1064 347 -360 1085 -354 1047 -1072 385 -352 1087 -328 1073 -374 1051 -388 1045 -354 1093 -348 1085 -354 1079 -5668 1085 -1082 349 -348 1079 -374 1051 -382 1063 -1076 355 -1082 349 -1068 353 -364 1065 -362 1075 -1064 373 -346 1067 -362 1073 -382 1063 -352 1067 -380 1065 -326 1081 -376 1065 -5714 1075 -1072 345 -346 1099 -332 1097 -346 1075 -1062 373 -1066 347 -1076 373 -344 1069 -362 1073 -1072 383 -314 1113 -344 1063 -350 1079 -374 1065 -332 1099 -370 1065 -336 1099 -5694 1087 -1046 351 -368 1097 -348 1051 -354 1109 -1046 383 -1060 365 -1072 365 -352 1049 -352 1091 -1074 347 -384 1051 -352 1073 -384 1051 -350 1079 -354 1073 -380 1067 -326 1081 -5722 1065 -1078 355 -352 1081 -356 1085 -344 1083 -1050 385 -1050 353 -1092 345 -384 1051 -352 1069 -1078 381 -350 1051 -354 1069 -386 1057 -364 1073 -368 1071 -352 1049 -354 1093 -5710 1077 -1072 353 -354 1085 -326 1079 -376 1069 -1052 381 -1064 349 -1074 381 -346 1073 -368 1067 -1056 359 -350 1107 -348 1063 -352 1069 -382 1065 -326 1111 -346 1063 -364 1071 -5686 1099 -1072 355 -352 1083 -326 1111 -346 1065 -1086 353 -1050 383 -1068 383 -350 1047 -354 1071 -1076 381 -346 1069 -370 1065 -336 1095 -334 1099 -336 1099 -330 1073 -354 1081 -5710 1077 -1050 385 -348 1085 -322 1109 -356 1055 -1084 355 -1054 377 -1052 375 -346 1103 -350 1065 -1074 351 -342 1093 -346 1091 -322 1107 -356 1055 -364 1071 -372 1053 -354 1085 -5704 1077 -1050 383 -346 1073 -370 1065 -334 1097 -1060 371 -1062 347 -1080 373 -344 1069 -360 1075 -1076 351 -346 1109 -344 1063 -364 1069 -370 1065 -334 1099 -332 1097 -336 1097 -5690 1087 -1044 383 -338 1095 -348 1083 -320 1109 -1048 385 -1056 365 -1072 365 -356 1081 -320 1095 -1078 343 -346 1103 -330 1075 -352 1095 -350 1069 -350 1085 -352 1081 -350 1071 -5712 1075 -1042 385 -354 1085 -326 1079 -374 1051 -1084 351 -1064 383 -1068 347 -346 1099 -334 1103 -1054 347 -354 1099 -346 1083 -354 1081 -354 1053 -362 1071 -374 1065 -346 1067 -5726 1053 -1082 351 -360 1091 -344 1083 -350 +RAW_Data: 1081 -1074 353 -1074 351 -1088 325 -386 1051 -386 1047 -1074 353 -378 1051 -384 1047 -354 1073 -384 1049 -376 1065 -356 1073 -352 1087 -5680 1079 -1074 381 -350 1051 -354 1071 -386 1051 -1086 351 -1080 351 -1070 381 -350 1051 -352 1071 -1080 383 -348 1049 -354 1075 -384 1065 -324 1113 -346 1061 -350 1079 -374 1051 -5706 1077 -1086 333 -384 1047 -354 1093 -346 1065 -1078 353 -1094 345 -1082 351 -360 1089 -346 1063 -1074 353 -366 1065 -360 1075 -372 1067 -334 1101 -368 1051 -352 1085 -356 1051 -5734 1073 -1072 353 -354 1083 -328 1073 -376 1083 -1040 375 -1066 359 -1082 353 -334 1099 -368 1069 -1070 343 -346 1105 -354 1055 -362 1071 -370 1069 -352 1077 -352 1069 -350 1087 -5680 1079 -1086 367 -352 1049 -354 1097 -346 1063 -1078 349 -1092 345 -1098 347 -358 1065 -350 1079 -1064 373 -346 1067 -362 1081 -350 1065 -350 1095 -346 1067 -362 1075 -372 1049 -5706 1071 -1086 367 -352 1083 -320 1095 -348 1087 -1050 387 -1050 353 -1094 345 -346 1101 -332 1073 -1072 383 -346 1083 -346 1087 -352 1051 -354 1093 -346 1085 -346 1061 -354 1103 -5700 1069 -1050 393 -352 1063 -352 1069 -350 1097 -1044 383 -1068 379 -1030 379 -358 1065 -348 1073 -1068 377 -346 1099 -330 1073 -352 1093 -350 1073 -348 1087 -352 1081 -350 1069 -5710 1073 -1076 353 -354 1085 -324 1111 -344 1083 -1040 389 -1044 381 -1070 347 -350 1085 -352 1071 -1078 383 -352 1047 -352 1075 -352 1089 -350 1083 -352 1069 -350 1097 -326 1109 -5664 1113 -1040 383 -354 1085 -328 1075 -374 1051 -1084 351 -1066 351 -1096 379 -314 1099 -334 1097 -1052 379 -356 1069 -354 1079 -320 1097 -348 1093 -346 1083 -354 1077 -354 1055 -5714 1073 -1076 345 -350 1081 -354 1069 -382 1065 -1074 349 -1068 379 -1064 347 -360 1065 -364 1071 -1066 371 -344 1067 -360 1077 -354 1083 -354 1087 -346 1065 -364 1071 -368 1071 -5682 1075 -1084 367 -342 1067 -360 1075 -352 1097 -1040 353 -1074 385 -1058 363 -346 1075 -354 1081 -1076 351 -378 1057 -334 1101 -334 1103 -356 1079 -320 1091 -348 1093 -348 1085 -5678 1095 -1050 379 -356 1065 -334 1097 -370 1049 -1086 353 -1086 325 -1080 375 -352 1081 -350 1067 -1078 383 -350 1051 -352 1071 -386 1053 -334 1103 -336 1085 -354 1087 -324 1111 -5676 1079 -1078 351 -380 1055 -364 1073 -368 1051 -1082 349 -1064 351 -1092 347 -378 1073 -334 1099 -1050 381 -328 1095 -346 1083 -350 1081 -352 1069 -382 1049 -344 1095 -354 1077 -5682 1071 -1078 359 -352 1081 -356 1085 -346 1065 -1082 353 -1080 351 -1070 385 -348 1051 -354 1077 -1076 381 -314 1103 -334 1105 -354 1081 -318 1095 -348 1087 -354 1081 -320 1097 -5712 1077 -1074 319 -380 1067 -356 1087 -346 1065 -1080 349 -1092 345 -1082 351 -360 +RAW_Data: 1053 -378 1083 -1050 381 -346 1053 -376 1067 -364 1069 -370 1047 -386 1047 -356 1093 -344 1083 -5690 1079 -1060 371 -344 1067 -362 1073 -348 1095 -1076 353 -1074 353 -1054 359 -352 1101 -348 1085 -1046 361 -388 1043 -350 1093 -346 1081 -352 1081 -352 1067 -384 1055 -346 1085 -5678 1083 -1084 347 -344 1093 -348 1097 -326 1075 -1070 375 -1062 347 -1080 373 -344 1067 -362 1073 -1074 381 -314 1115 -344 1085 -356 1047 -354 1091 -348 1085 -354 1081 -320 1095 -5708 1075 -1074 353 -354 1083 -326 1109 -346 1065 -1054 387 -1050 351 -1096 381 -316 1083 -352 1073 -1080 381 -312 1101 -336 1105 -350 1063 -352 1067 -384 1065 -324 1111 -346 1065 -5704 1073 -1080 347 -350 1083 -352 1073 -350 1085 -1064 375 -1064 357 -1072 383 -314 1111 -344 1087 -1042 387 -330 1071 -374 1069 -352 1081 -350 1067 -350 1097 -348 1083 -322 1113 -5682 1075 -1076 353 -354 1083 -326 1117 -342 1085 -1054 351 -1062 383 -1070 377 -314 1103 -332 1105 -1042 381 -346 1083 -346 1065 -360 1071 -374 1069 -352 1079 -352 1067 -348 1089 -5682 1077 -1088 367 -354 1047 -354 1095 -346 1083 -1068 345 -1096 351 -1074 351 -346 1077 -372 1065 -1066 349 -386 1069 -346 1085 -356 1077 -354 1057 -364 1071 -370 1071 -352 1079 -5676 1073 -1074 381 -314 1117 -344 1063 -352 1081 -1076 357 -1080 355 -1052 359 -352 1095 -334 1097 -1064 371 -352 1083 -320 1095 -348 1085 -352 1081 -350 1069 -350 1093 -348 1085 -5676 1095 -1052 379 -356 1065 -346 1087 -356 1075 -1048 387 -1058 363 -1074 367 -356 1049 -354 1091 -1072 347 -346 1101 -332 1073 -384 1063 -350 1067 -350 1101 -326 1079 -376 1065 -5680 1107 -1074 343 -346 1067 -362 1083 -352 1085 -1078 349 -1070 345 -1066 379 -360 1065 -348 1079 -1062 375 -344 1069 -362 1075 -352 1081 -356 1085 -344 1063 -384 1047 -354 1073 -5708 1073 -1074 357 -354 1083 -356 1087 -344 1087 -1052 351 -1064 379 -1068 379 -314 1103 -334 1099 -1052 347 -386 1061 -348 1073 -374 1067 -352 1083 -350 1067 -350 1095 -348 1081 -5682 1085 -1054 383 -344 1087 -346 1067 -362 1069 -1064 373 -1062 347 -1078 373 -352 1081 -350 1065 -1078 383 -350 1051 -352 1071 -386 1051 -352 1081 -352 1069 -350 1095 -346 1087 -5678 1089 -1052 387 -330 1073 -374 1083 -354 1045 -1072 353 -1074 385 -1056 361 -350 1081 -352 1083 -1080 349 -376 1059 -346 1087 -356 1075 -354 1055 -362 1075 -370 1067 -352 1081 -5676 1075 -1076 387 -330 1071 -374 1065 -352 1079 -1072 355 -1082 353 -1054 361 -350 1095 -348 1073 -1068 373 -352 1081 -322 1097 -348 1085 -354 1079 -352 1069 -348 1093 -348 1083 -5676 1097 -1056 361 -348 1071 -354 1081 -354 1089 -1074 345 -1062 383 -1050 353 -380 1057 -364 1071 -1066 371 -354 1081 -318 +RAW_Data: 1099 -348 1085 -352 1079 -352 1071 -348 1087 -346 1095 -5678 1095 -1050 383 -328 1091 -348 1061 -386 1047 -1078 357 -1084 351 -1066 351 -366 1087 -348 1061 -1076 357 -354 1081 -354 1089 -346 1065 -352 1079 -354 1069 -386 1055 -334 1099 -5694 1085 -1044 383 -340 1087 -352 1081 -350 1065 -1080 383 -1052 351 -1082 349 -376 1059 -348 1083 -1046 395 -356 1049 -352 1091 -348 1085 -354 1083 -320 1093 -348 1087 -354 1081 -5670 1107 -1070 343 -348 1067 -384 1067 -354 1083 -1068 345 -1064 349 -1080 373 -350 1081 -352 1067 -1076 383 -348 1049 -354 1071 -386 1053 -364 1071 -368 1069 -352 1079 -350 1069 -5708 1075 -1074 351 -354 1083 -326 1111 -344 1067 -1052 385 -1050 381 -1070 347 -346 1101 -332 1073 -1072 383 -344 1085 -346 1067 -362 1069 -370 1053 -352 1085 -356 1085 -346 1067 -5682 1111 -1060 369 -344 1071 -360 1081 -354 1053 -1080 353 -1092 345 -1084 351 -360 1053 -376 1067 -1086 351 -330 1081 -376 1051 -382 1067 -352 1067 -380 1067 -326 1081 -374 1051 -5696 1109 -1058 369 -354 1079 -320 1097 -350 1085 -1054 387 -1048 353 -1060 377 -352 1085 -350 1069 -1078 383 -350 1049 -352 1071 -384 1065 -326 1081 -376 1067 -334 1101 -334 1101 -5692 1063 -1064 375 -346 1067 -362 1073 -380 1065 -1074 355 -1072 349 -1066 349 -366 1085 -350 1081 -1076 355 -350 1085 -326 1077 -376 1083 -352 1049 -354 1095 -346 1065 -380 1051 -5712 1083 -1052 389 -330 1073 -374 1053 -354 1083 -1074 351 -1074 385 -1052 343 -346 1107 -352 1065 -1072 351 -376 1065 -356 1081 -346 1065 -362 1069 -372 1067 -336 1097 -332 1099 -5678 1101 -1068 343 -350 1081 -352 1069 -384 1055 -1082 349 -1056 377 -1082 353 -330 1081 -374 1067 -1082 351 -330 1081 -376 1081 -352 1047 -354 1097 -348 1081 -352 1081 -352 1069 -5712 1077 -1038 383 -354 1083 -326 1079 -374 1055 -1074 383 -1064 347 -1066 381 -316 1099 -370 1051 -1082 353 -336 1097 -368 1053 -352 1081 -354 1089 -346 1063 -350 1081 -352 1071 -5714 1075 -1074 355 -350 1083 -358 1053 -376 1065 -1084 347 -1064 353 -1070 385 -346 1085 -352 1077 -1042 387 -346 1053 -354 1077 -386 1055 -364 1069 -370 1051 -388 1051 -354 1087 -5672 1081 -1074 351 -378 1065 -356 1083 -346 1065 -1078 347 -1092 345 -1066 359 -350 1107 -356 1045 -1068 383 -354 1083 -328 1075 -372 1053 -388 1051 -356 1087 -346 1065 -362 1071 -5702 1083 -1076 349 -376 1055 -346 1083 -356 1073 -1078 353 -1054 361 -1078 369 -352 1083 -352 1065 -1072 347 -346 1103 -332 1101 -346 1081 -354 1045 -386 1051 -362 1073 -370 1049 -5718 1075 -1048 365 -388 1047 -354 1091 -346 1085 -1040 387 -1050 351 -1096 349 -348 1083 -352 1073 -1076 379 -316 1101 -334 1097 -336 1099 -330 1071 -388 1047 -354 +RAW_Data: 1087 -348 1085 -5684 1075 -1084 367 -344 1067 -358 1073 -350 1063 -1074 353 -1108 349 -1068 353 -362 1067 -344 1097 -1050 363 -386 1047 -356 1087 -346 1085 -352 1079 -320 1097 -346 1083 -352 1081 -5676 1103 -1054 387 -330 1071 -372 1053 -354 1085 -1074 351 -1070 385 -1058 347 -362 1069 -350 1087 -1054 381 -346 1085 -346 1065 -364 1069 -370 1071 -354 1081 -320 1097 -348 1083 -5676 1079 -1090 367 -344 1067 -360 1073 -350 1095 -1074 351 -1076 349 -1068 353 -364 1081 -352 1081 -1074 321 -382 1051 -360 1075 -374 1051 -386 1049 -354 1091 -346 1085 -346 1067 -5706 1065 -1084 351 -360 1087 -346 1085 -356 1047 -1074 353 -1072 383 -1064 347 -362 1067 -364 1069 -1068 371 -352 1083 -320 1095 -350 1097 -346 1083 -322 1077 -388 1051 -350 1081 -5706 1051 -1084 387 -328 1073 -372 1049 -386 1049 -1076 353 -1072 383 -1056 363 -348 1071 -354 1085 -1076 351 -376 1057 -344 1087 -356 1073 -352 1081 -350 1053 -376 1051 -384 1049 -5710 1083 -1076 351 -348 1073 -372 1063 -334 1099 -1062 371 -1052 389 -1050 353 -364 1087 -354 1049 -1072 353 -382 1055 -362 1075 -370 1051 -352 1095 -350 1067 -348 1099 -326 1077 -5702 1077 -1076 353 -378 1053 -362 1071 -370 1051 -1084 349 -1066 353 -1096 345 -382 1049 -354 1069 -1080 379 -346 1069 -368 1041 -386 1047 -354 1093 -346 1085 -350 1083 -350 1067 -5708 1075 -1074 353 -352 1083 -326 1109 -344 1083 -1050 387 -1052 355 -1054 377 -352 1085 -350 1069 -1076 377 -314 1103 -332 1101 -336 1097 -330 1073 -354 1085 -354 1089 -346 1083 -5688 1073 -1084 331 -386 1047 -356 1087 -346 1061 -1082 383 -1050 353 -1070 385 -346 1051 -354 1105 -1046 385 -346 1085 -322 1073 -386 1049 -382 1047 -354 1069 -386 1053 -362 1071 -5692 1079 -1076 351 -378 1055 -364 1071 -370 1073 -1040 373 -1070 357 -1084 353 -334 1097 -334 1105 -1056 387 -330 1071 -372 1069 -354 1081 -318 1095 -348 1085 -352 1077 -352 1069 -5708 1075 -1076 353 -352 1087 -326 1081 -372 1067 -1084 351 -1050 353 -1098 345 -344 1101 -332 1101 -1054 365 -348 1079 -354 1087 -326 1081 -374 1049 -382 1063 -352 1067 -384 1055 -5708 1071 -1076 345 -350 1081 -352 1069 -386 1059 -1054 361 -1076 371 -1054 387 -330 1073 -372 1069 -1054 383 -344 1085 -346 1065 -364 1073 -368 1065 -334 1099 -334 1073 -382 1061 -5700 1067 -1064 383 -328 1093 -348 1083 -354 1083 -1040 383 -1046 387 -1056 361 -348 1073 -354 1085 -1074 351 -378 1055 -332 1099 -338 1089 -354 1085 -324 1115 -344 1085 -350 1063 -5704 1069 -1068 349 -360 1091 -346 1067 -362 1075 -1062 373 -1068 333 -1102 365 -354 1049 -356 1087 -1074 345 -384 1047 -352 1069 -386 1053 -364 1071 -370 1051 -352 1085 -354 1085 -5678 1081 -1072 351 -378 +RAW_Data: 1055 -362 1069 -372 1069 -1054 387 -1048 353 -1092 345 -346 1101 -332 1073 -1074 383 -312 1113 -346 1063 -364 1071 -370 1073 -354 1081 -320 1091 -348 1085 -5680 1075 -1088 367 -344 1069 -360 1075 -350 1063 -1074 353 -1076 385 -1054 365 -348 1071 -354 1083 -1074 351 -374 1067 -326 1077 -376 1085 -352 1049 -354 1091 -346 1063 -380 1051 -5714 1085 -1038 387 -328 1081 -376 1053 -382 1063 -1072 355 -1076 349 -1064 349 -368 1097 -326 1073 -1070 377 -344 1099 -330 1085 -354 1087 -326 1079 -374 1069 -350 1081 -352 1071 -5700 1067 -1076 357 -350 1095 -320 1095 -348 1065 -1078 349 -1092 347 -1066 379 -358 1069 -332 1101 -1062 371 -350 1085 -320 1095 -348 1097 -346 1049 -356 1075 -386 1057 -364 1069 -5692 1077 -1070 351 -380 1051 -350 1075 -376 1065 -1052 385 -1048 383 -1068 381 -316 1083 -352 1073 -1080 377 -314 1103 -334 1099 -336 1099 -328 1075 -350 1095 -352 1065 -350 1095 -5674 1079 -1076 379 -346 1071 -368 1067 -336 1065 -1088 369 -1050 387 -1048 353 -366 1063 -382 1045 -1078 361 -386 1047 -354 1089 -346 1063 -384 1045 -354 1071 -386 1057 -332 1101 -5698 1081 -1044 383 -340 1085 -352 1079 -352 1067 -1080 379 -1030 379 -1050 377 -344 1099 -330 1073 -1074 381 -346 1085 -346 1085 -356 1047 -354 1091 -348 1063 -362 1075 -374 1063 -5678 1103 -1042 377 -352 1081 -352 1073 -348 1095 -1056 347 -1080 373 -1054 383 -314 1113 -346 1065 -1082 355 -358 1067 -352 1079 -352 1067 -350 1093 -346 1083 -354 1075 -354 1087 -5678 1079 -1074 345 -348 1099 -332 1101 -336 1067 -1090 365 -1052 387 -1048 355 -362 1067 -364 1073 -1066 371 -350 1081 -352 1065 -348 1069 -362 1075 -372 1067 -334 1099 -332 1099 -848 153 -153886 131 -896 231 -464 231 -428 97 -166 99 -966 233 -200 101 -66 199 -102 265 -266 299 -98 131 -100 65 -232 131 -100 44699 -12320 65 -132 131 -300 231 -100 167 -266 197 -68 297 -330 131 -496 131 -400 131 -166 633 -66 431 -230 589 -166 10885 -11354 329 -792 99 -296 129 -166 97 -98 65 -132 229 -294 297 -98 561 -166 231 -98 825 -166 57693 -12116 131 -98 295 -424 163 -398 131 -232 97 -130 65 -66 97 -66 165 -460 529 -66 197 -132 393 -198 267 -168 43035 -10678 99 -1716 97 -498 65 -298 67 -2020 331 -166 957 -66 199 -100 529 -12206 199 -796 67 -66 131 -132 129 -398 197 -230 131 -66 227 -196 65 -526 197 -132 589 -132 597 -100 327 -66 8489 -11212 133 -630 131 -100 133 -166 99 -994 99 -198 333 -1626 329 -130 6045 -13890 65 -434 463 -264 295 -266 1385 -132 461 -134 163951 -12284 131 -858 233 -532 199 -402 97 -266 133 -496 431 -66 1161 -66 493 -68 21495 -5856 +RAW_Data: 95 -560 65 -2896 199 -762 97 -100 65 -430 131 -896 199 -234 101 -800 231 -332 99 -334 133 -132 265 -268 1425 -66 33043 -12400 99 -666 131 -234 67 -232 65 -498 65 -266 65 -498 165 -102 165 -200 2189 -11534 133 -266 197 -232 97 -166 165 -100 99 -98 99 -500 97 -332 99 -200 12547 -12014 65 -232 99 -600 131 -330 299 -332 625 -66 1243 -134 7929 -12344 97 -762 131 -860 165 -298 295 -298 231 -266 97 -134 397 -132 2891 -68 299 -16210 67 -266 133 -234 101 -268 163 -466 97 -232 65 -198 67 -132 67 -100 263 -98 437 -302 133 -66 165 -168 24439 -10722 131 -1534 229 -1318 99 -98 195 -2100 597 -100 733 -134 28455 -10484 231 -2030 67 -100 101 -132 163 -166 265 -854 361 -166 531 -134 233 -100 495 -164 25733 -12966 65 -1880 65 -132 163 -1086 799 -68 16865 -12956 295 -330 163 -232 233 -166 97 -1860 99 -68 333 -66 1613 -98 55627 -12998 97 -266 263 -1594 131 -894 167 -134 231 -332 131 -66 399 -98 99 -66 697 -4972 65 -3944 65 -132 459 -328 197 -100 1557 -98 23673 -12982 333 -928 133 -232 433 -198 131 -360 99 -64 497 -100 463 -98 397 -132 197 -68 765 -13710 65 -166 99 -1684 131 -632 691 -230 263 -66 359 -132 2073 -64 6059 -12430 97 -462 65 -328 65 -792 229 -824 97 -892 529 -166 163 -168 165 -698 165 -166 431 -130 20385 -12774 97 -98 65 -1384 131 -198 131 -622 131 -598 99 -164 129 -98 193 -98 195 -98 263 -98 459 -132 131 -66 73855 -13048 65 -2554 97 -166 761 -68 761 -366 15305 -12094 165 -764 963 -68 65 -66 163 -66 233 -102 333 -100 965 -66 40087 -10292 165 -1724 65 -1754 165 -266 463 -396 267 -432 795 -132 297 -66 267 -68 261 -134 36583 -10588 65 -2738 97 -1184 259 -298 131 -294 395 -98 819 -132 689 -166 7999 -11970 65 -468 63 -1892 429 -262 263 -200 199 -632 265 -66 229 -66 1149 -68 2355 -15782 233 -198 67 -166 295 -818 229 -164 1059 -68 265 -68 1789 -10374 131 -1904 65 -196 229 -230 197 -360 229 -164 129 -1120 963 -166 231 -200 199 -230 333 -10180 67 -966 133 -1264 65 -798 99 -432 65 -898 65 -134 7681 -12052 131 -928 129 -624 99 -526 65 -432 65 -532 65 -596 199 -100 265 -296 895 -100 229 -98 589 -15506 97 -266 65 -434 65 -1520 199 -98 265 -894 293 -198 427 -198 97 -132 459 -64 2145 -66 9075 -7224 99 -66 65 -1060 65 -200 99 -932 167 -894 65 -528 165 -102 927 -100 597 -232 99 -66 97 -98 461 -196 261 -98 197 -264 2909 -134 11635 -804 99 -240 143 -244 369 -5700 1077 -1074 353 -354 1083 -324 +RAW_Data: 1117 -346 1063 -1086 353 -1050 381 -1070 383 -348 1049 -354 1073 -1082 383 -350 1047 -354 1077 -386 1057 -334 1101 -336 1105 -354 1081 -320 1093 -5710 1073 -1076 351 -354 1085 -324 1111 -344 1065 -1084 351 -1082 349 -1068 385 -348 1053 -354 1075 -1078 385 -348 1051 -354 1075 -382 1065 -354 1085 -346 1065 -364 1069 -370 1069 -5686 1077 -1086 367 -354 1047 -354 1095 -346 1095 -1054 363 -1072 369 -1050 387 -328 1077 -374 1051 -1084 349 -348 1081 -376 1081 -348 1063 -352 1073 -380 1067 -356 1053 -376 1083 -5684 1073 -1086 365 -356 1049 -354 1089 -348 1085 -1066 385 -1046 351 -1074 385 -348 1083 -320 1109 -1048 381 -346 1071 -336 1097 -336 1097 -334 1085 -352 1093 -320 1097 -348 1095 -5680 1089 -1064 371 -352 1081 -352 1067 -348 1067 -1078 349 -1094 347 -1096 349 -358 1067 -350 1081 -1076 355 -352 1081 -356 1055 -378 1065 -350 1079 -352 1069 -384 1053 -348 1079 -5702 1099 -1072 353 -350 1065 -354 1087 -348 1097 -1046 347 -1096 377 -1034 377 -360 1085 -356 1049 -1074 351 -382 1051 -362 1071 -374 1051 -388 1049 -352 1093 -346 1061 -384 1049 -5708 1087 -1068 349 -362 1089 -344 1061 -382 1051 -1076 359 -1080 351 -1088 355 -358 1069 -352 1081 -1078 353 -350 1087 -326 1079 -376 1065 -350 1079 -354 1069 -384 1059 -332 1101 -5700 1087 -1044 353 -368 1095 -348 1085 -320 1111 -1044 381 -1064 347 -1090 345 -344 1101 -332 1073 -1074 383 -344 1087 -344 1067 -352 1083 -352 1071 -384 1051 -352 1083 -352 1071 -5712 1077 -1076 355 -350 1087 -326 1079 -374 1053 -1070 375 -1072 357 -1080 353 -334 1103 -334 1073 -1084 349 -378 1051 -376 1067 -364 1073 -368 1065 -336 1101 -332 1083 -352 1083 -5712 1075 -1044 383 -348 1069 -372 1051 -354 1083 -1076 351 -1074 383 -1052 385 -326 1089 -346 1065 -1066 381 -340 1099 -326 1077 -374 1067 -352 1083 -350 1069 -350 1087 -352 1081 -5676 1085 -1074 387 -330 1071 -372 1069 -352 1079 -1076 355 -1078 351 -1084 347 -360 1067 -348 1081 -1074 357 -352 1081 -356 1085 -344 1065 -384 1049 -354 1071 -384 1059 -346 1085 -5680 1087 -1084 343 -348 1103 -352 1065 -354 1087 -1070 345 -1086 351 -1082 351 -340 1097 -346 1087 -1046 361 -352 1083 -354 1089 -346 1067 -350 1081 -354 1071 -386 1053 -346 1097 -5676 1085 -1084 349 -360 1085 -344 1081 -348 1065 -1076 357 -1080 351 -1086 325 -388 1065 -366 1067 -1064 371 -352 1081 -352 1065 -382 1049 -348 1083 -352 1071 -382 1049 -384 1047 -5708 1065 -1062 377 -350 1083 -354 1085 -326 1077 -1070 377 -1052 381 -1066 351 -378 1057 -332 1103 -1060 373 -344 1069 -362 1073 -350 1095 -350 1065 -348 1095 -350 1085 -344 1065 -5704 1079 -1072 347 -382 1049 -354 1075 -382 1051 -1082 351 -1082 351 -1072 +RAW_Data: 381 -348 1053 -354 1071 -1074 381 -348 1071 -370 1049 -386 1047 -356 1091 -346 1083 -346 1067 -354 1071 -5700 1103 -1046 361 -386 1047 -354 1087 -346 1085 -1050 387 -1050 351 -1098 345 -350 1083 -352 1073 -1078 379 -316 1103 -332 1101 -336 1097 -330 1073 -380 1065 -352 1069 -384 1061 -5684 1089 -1064 369 -346 1093 -320 1109 -352 1067 -1076 349 -1070 381 -1032 379 -360 1065 -362 1071 -1064 373 -342 1099 -330 1073 -350 1093 -352 1067 -350 1087 -350 1081 -352 1071 -5710 1077 -1074 355 -354 1081 -326 1113 -346 1083 -1054 381 -1034 383 -1066 379 -316 1099 -334 1097 -1052 379 -358 1067 -350 1081 -352 1067 -386 1055 -334 1101 -334 1107 -322 1085 -5708 1077 -1050 387 -348 1087 -320 1111 -356 1055 -1086 355 -1050 375 -1054 387 -330 1075 -376 1067 -1068 385 -326 1087 -346 1063 -382 1047 -354 1105 -354 1057 -332 1097 -372 1049 -5716 1071 -1080 365 -356 1047 -354 1095 -348 1085 -1070 353 -1050 383 -1070 379 -314 1101 -334 1099 -1052 377 -356 1071 -354 1081 -320 1097 -348 1087 -346 1095 -322 1105 -352 1063 -5702 1075 -1076 351 -346 1109 -342 1087 -322 1081 -1074 351 -1076 383 -1062 347 -362 1065 -364 1071 -1064 373 -344 1099 -330 1077 -350 1097 -320 1097 -348 1095 -326 1079 -376 1063 -5712 1071 -1074 347 -346 1101 -332 1083 -350 1097 -1040 385 -1044 387 -1054 363 -348 1085 -354 1087 -1046 351 -370 1085 -346 1097 -320 1107 -350 1063 -350 1087 -346 1065 -360 1075 -5704 1077 -1076 351 -378 1055 -362 1071 -370 1049 -1084 351 -1084 355 -1054 375 -350 1083 -352 1067 -1076 379 -346 1075 -332 1101 -336 1065 -362 1073 -382 1065 -352 1069 -384 1049 -5682 1077 -1090 369 -354 1049 -354 1093 -348 1087 -1070 347 -1062 383 -1042 385 -346 1073 -372 1051 -1084 351 -346 1079 -374 1083 -354 1051 -354 1091 -348 1089 -354 1047 -354 1097 -5702 1075 -1076 353 -352 1085 -326 1077 -374 1053 -1082 385 -1050 353 -1092 345 -348 1083 -352 1069 -1076 383 -346 1051 -354 1073 -384 1051 -374 1067 -358 1073 -350 1069 -354 1087 -5706 1075 -1042 385 -352 1085 -326 1077 -378 1067 -1050 387 -1048 383 -1064 381 -350 1049 -354 1069 -1080 383 -350 1049 -354 1073 -388 1055 -334 1101 -336 1107 -354 1047 -354 1093 -5674 1109 -1072 353 -350 1083 -348 1051 -376 1065 -1082 351 -1082 351 -1072 379 -348 1073 -332 1073 -1072 381 -346 1085 -344 1065 -362 1073 -372 1047 -386 1047 -354 1089 -346 1083 -5686 1075 -1092 367 -354 1049 -354 1093 -348 1065 -1066 383 -1070 347 -1062 379 -358 1063 -348 1079 -1066 375 -344 1067 -362 1073 -350 1097 -350 1071 -348 1095 -346 1083 -320 1107 -5668 1107 -1078 329 -388 1047 -354 1093 -344 1065 -1082 343 -1098 353 -1080 349 -346 1077 -370 1067 -1052 347 -390 +RAW_Data: 1067 -364 1069 -366 1051 -386 1051 -356 1053 -378 1085 -346 1067 -5712 1053 -1074 381 -346 1083 -344 1063 -350 1077 -1068 377 -1066 383 -1050 351 -378 1057 -364 1073 -1066 371 -346 1063 -354 1071 -386 1053 -346 1103 -332 1071 -382 1063 -352 1065 -5716 1077 -1074 353 -352 1083 -326 1077 -376 1051 -1084 381 -1066 351 -1066 379 -348 1069 -368 1067 -1066 349 -362 1067 -362 1071 -370 1067 -334 1099 -366 1065 -336 1067 -364 1073 -5714 1075 -1050 361 -388 1045 -350 1091 -348 1085 -1054 381 -1066 349 -1070 381 -346 1071 -368 1065 -1052 379 -358 1067 -334 1097 -334 1085 -352 1085 -354 1087 -346 1083 -354 1051 -5706 1087 -1078 349 -348 1075 -372 1051 -382 1067 -1072 353 -1076 353 -1056 361 -350 1083 -352 1083 -1076 351 -376 1055 -364 1071 -370 1049 -352 1083 -356 1087 -346 1083 -352 1049 -5702 1087 -1052 389 -346 1087 -322 1111 -354 1057 -1082 355 -1054 375 -1064 347 -354 1105 -354 1081 -1040 383 -352 1085 -326 1075 -374 1051 -354 1083 -354 1089 -346 1085 -348 1065 -5710 1087 -1062 345 -352 1071 -382 1061 -352 1069 -1078 383 -1052 351 -1082 349 -380 1055 -334 1099 -1062 371 -354 1083 -318 1097 -348 1083 -352 1081 -352 1065 -350 1087 -352 1077 -5710 1069 -1054 389 -328 1075 -376 1049 -356 1079 -1076 351 -1074 385 -1058 365 -344 1073 -352 1097 -1036 383 -350 1063 -354 1087 -348 1097 -328 1071 -376 1063 -332 1101 -336 1101 -5676 1103 -1038 379 -344 1099 -332 1077 -354 1085 -1076 349 -1070 385 -1052 353 -360 1087 -344 1085 -1040 387 -328 1081 -374 1051 -386 1047 -354 1089 -346 1065 -362 1077 -372 1065 -5710 1075 -1042 377 -350 1083 -352 1069 -350 1095 -1050 373 -1064 357 -1074 353 -364 1073 -372 1053 -1074 351 -346 1081 -376 1069 -332 1099 -334 1087 -352 1085 -354 1085 -346 1085 -5682 1075 -1088 329 -388 1049 -354 1089 -346 1065 -1070 353 -1096 345 -1084 351 -362 1085 -344 1067 -1082 355 -358 1083 -354 1047 -354 1093 -346 1065 -360 1073 -372 1081 -354 1045 -5708 1073 -1086 353 -346 1075 -374 1055 -352 1095 -1074 353 -1074 351 -1062 379 -340 1095 -326 1079 -1070 373 -344 1099 -330 1083 -356 1083 -324 1113 -344 1067 -352 1081 -352 1073 -5706 1073 -1076 355 -354 1085 -326 1081 -374 1067 -1054 389 -1048 353 -1096 345 -350 1081 -352 1071 -1080 383 -348 1047 -354 1073 -386 1057 -334 1099 -334 1077 -384 1063 -350 1067 -5704 1071 -1076 357 -354 1081 -356 1083 -346 1067 -1086 353 -1048 383 -1070 383 -314 1081 -354 1071 -1078 385 -348 1047 -354 1107 -354 1057 -334 1099 -334 1085 -354 1083 -354 1085 -5670 1111 -1038 383 -354 1085 -328 1071 -376 1053 -1088 353 -1086 355 -1048 375 -352 1081 -350 1069 -1078 381 -350 1049 -352 1071 -386 1055 -334 1097 -336 +RAW_Data: 1087 -356 1081 -356 1085 -5672 1077 -1074 353 -382 1053 -364 1073 -372 1073 -1054 389 -1050 355 -1054 377 -344 1099 -330 1073 -1076 387 -330 1069 -372 1067 -344 1099 -330 1073 -354 1081 -354 1087 -348 1063 -5718 1081 -1060 369 -342 1067 -360 1073 -354 1083 -1076 349 -1068 385 -1052 353 -360 1085 -346 1087 -1052 389 -330 1069 -372 1051 -356 1083 -354 1087 -346 1089 -348 1065 -352 1069 -5700 1101 -1046 359 -354 1083 -354 1087 -348 1063 -1082 353 -1054 377 -1062 379 -356 1067 -334 1101 -1060 369 -344 1067 -360 1083 -356 1087 -328 1075 -374 1067 -352 1081 -350 1071 -5706 1075 -1076 351 -354 1085 -324 1111 -344 1085 -1040 389 -1048 353 -1094 345 -350 1081 -352 1071 -1076 379 -316 1097 -336 1097 -336 1097 -334 1095 -346 1073 -372 1051 -354 1079 -5692 1085 -1084 351 -346 1075 -374 1051 -354 1083 -1074 351 -1072 385 -1058 381 -328 1073 -348 1085 -1054 389 -328 1075 -376 1067 -350 1081 -352 1069 -350 1085 -352 1083 -350 1071 -5710 1077 -1042 383 -352 1089 -326 1073 -376 1065 -1064 375 -1072 365 -1038 373 -348 1071 -386 1059 -1050 379 -358 1087 -354 1047 -354 1089 -348 1085 -354 1081 -320 1095 -348 1087 -5686 1079 -1084 365 -356 1049 -354 1093 -346 1085 -1052 387 -1048 355 -1090 347 -350 1083 -352 1071 -1076 379 -314 1099 -334 1097 -336 1097 -332 1099 -336 1095 -332 1075 -354 1083 -5708 1051 -1080 383 -348 1049 -354 1105 -354 1055 -1084 355 -1052 375 -1084 351 -330 1079 -376 1051 -1074 387 -328 1075 -376 1067 -350 1079 -352 1069 -380 1067 -326 1081 -374 1051 -5714 1075 -1050 395 -356 1047 -354 1091 -348 1095 -1052 375 -1064 353 -1076 351 -346 1077 -372 1065 -1050 379 -360 1065 -362 1069 -370 1065 -334 1099 -332 1097 -336 1097 -332 1083 -5682 1101 -1046 395 -356 1047 -354 1089 -346 1097 -1050 385 -1046 351 -1074 385 -348 1051 -354 1105 -1042 385 -350 1051 -354 1073 -384 1067 -326 1113 -344 1063 -364 1069 -370 1065 -5690 1077 -1074 383 -348 1047 -354 1075 -386 1057 -1054 361 -1076 373 -1052 387 -330 1073 -374 1069 -1054 387 -330 1075 -374 1067 -352 1081 -352 1067 -350 1085 -352 1079 -352 1069 -5712 1075 -1076 351 -354 1085 -326 1109 -344 1083 -1054 387 -1052 355 -1054 375 -352 1085 -318 1097 -1076 379 -314 1099 -334 1103 -356 1079 -320 1091 -348 1085 -352 1081 -350 1067 -5708 1075 -1076 355 -350 1085 -326 1079 -374 1053 -1084 351 -1084 353 -1090 343 -350 1079 -354 1069 -1080 379 -346 1073 -332 1073 -382 1065 -352 1067 -380 1067 -326 1081 -374 1069 -5680 1103 -1070 345 -346 1099 -330 1073 -388 1047 -1070 351 -1078 385 -1058 363 -346 1081 -354 1087 -1046 351 -368 1095 -348 1051 -354 1077 -384 1065 -326 1113 -344 1085 -350 1061 -5708 1053 -1084 +RAW_Data: 351 -364 1073 -372 1069 -352 1083 -1040 353 -1110 353 -1056 361 -348 1081 -354 1083 -1078 351 -376 1059 -346 1055 -354 1079 -386 1057 -364 1071 -368 1037 -386 1047 -5706 1073 -1084 355 -334 1101 -336 1083 -354 1083 -1074 351 -1072 383 -1050 351 -360 1087 -346 1087 -1038 383 -344 1087 -346 1063 -362 1077 -370 1051 -354 1085 -356 1087 -344 1065 -5704 1081 -1074 345 -384 1047 -354 1069 -384 1057 -1086 325 -1078 373 -1052 385 -330 1079 -374 1049 -1072 381 -346 1085 -344 1067 -362 1073 -370 1067 -334 1101 -332 1071 -386 1049 -5712 1077 -1044 383 -346 1075 -370 1065 -348 1085 -1048 361 -1072 389 -1048 353 -364 1085 -354 1079 -1042 385 -354 1087 -328 1073 -374 1071 -352 1081 -320 1099 -348 1085 -352 1083 -5668 1087 -1084 353 -364 1069 -368 1053 -380 1067 -1072 353 -1078 349 -1068 355 -362 1067 -348 1083 -1074 357 -350 1085 -356 1081 -344 1083 -354 1047 -354 1093 -348 1083 -352 1079 -5704 1073 -1052 387 -330 1077 -372 1051 -352 1085 -1076 349 -1072 379 -1070 323 -388 1063 -348 1077 -1064 375 -352 1079 -352 1065 -384 1049 -352 1083 -352 1069 -350 1085 -352 1083 -5676 1085 -1080 351 -366 1071 -366 1053 -352 1085 -1076 351 -1070 379 -1064 349 -360 1065 -364 1073 -1064 369 -346 1071 -358 1073 -350 1065 -354 1091 -380 1051 -348 1083 -352 1069 -5712 1077 -1074 353 -352 1085 -326 1075 -374 1065 -1066 361 -1074 371 -1056 387 -330 1071 -372 1051 -1086 353 -336 1095 -370 1069 -354 1079 -320 1095 -348 1097 -350 1051 -354 1077 -5708 1075 -1078 355 -352 1085 -326 1081 -374 1051 -1082 349 -1100 321 -1098 345 -348 1101 -332 1099 -1072 325 -388 1065 -334 1099 -368 1051 -352 1083 -356 1053 -378 1083 -352 1047 -5710 1073 -1072 383 -314 1113 -344 1067 -364 1067 -1068 371 -1054 389 -1050 355 -362 1087 -354 1049 -1074 351 -382 1053 -362 1077 -370 1051 -352 1095 -352 1065 -348 1097 -324 1079 -5690 1101 -1074 355 -350 1081 -350 1085 -346 1081 -1050 387 -1048 355 -1094 345 -350 1083 -352 1069 -1074 379 -346 1073 -366 1067 -346 1085 -354 1073 -352 1055 -360 1075 -374 1051 -5718 1071 -1048 395 -356 1047 -354 1091 -346 1085 -1052 383 -1066 349 -1070 381 -314 1101 -334 1085 -1074 351 -346 1081 -376 1067 -332 1099 -334 1099 -336 1101 -330 1085 -350 1065 -5702 1075 -1072 381 -348 1051 -374 1069 -366 1067 -1064 371 -1070 351 -1080 351 -376 1047 -382 1047 -1078 357 -352 1083 -358 1053 -374 1051 -386 1049 -354 1093 -344 1065 -350 1079 -5720 1067 -1076 355 -352 1085 -326 1077 -376 1053 -1086 353 -1084 355 -1056 375 -344 1093 -322 1105 -1074 351 -348 1073 -372 1065 -334 1099 -332 1101 -346 1083 -352 1079 -354 1057 -5706 1077 -1074 347 -348 1081 -354 1071 -384 1057 -1052 +RAW_Data: 361 -1076 373 -1050 387 -330 1075 -374 1049 -1086 387 -330 1073 -370 1053 -352 1083 -354 1085 -346 1065 -362 1071 -370 1065 -5682 1105 -1036 377 -346 1099 -330 1085 -354 1085 -1046 353 -1096 347 -1086 351 -360 1085 -344 1085 -1052 381 -314 1113 -344 1083 -354 1047 -354 1093 -348 1067 -362 1073 -374 1049 -5716 1071 -1052 363 -388 1047 -354 1091 -346 1065 -1080 347 -1090 345 -1064 379 -358 1069 -334 1097 -1062 369 -352 1083 -320 1099 -348 1065 -362 1075 -374 1067 -334 1099 -332 1073 -5720 1073 -1048 395 -356 1049 -356 1089 -346 1065 -1084 343 -1072 361 -1084 355 -334 1101 -336 1099 -1058 363 -344 1085 -354 1089 -326 1075 -376 1051 -356 1081 -356 1085 -346 1065 -5688 1111 -1058 367 -348 1065 -352 1069 -384 1067 -1042 379 -1070 383 -1052 351 -330 1115 -346 1087 -1056 351 -346 1077 -376 1083 -352 1061 -352 1067 -350 1097 -326 1109 -346 1083 -5686 1075 -1048 397 -356 1047 -354 1091 -346 1085 -1054 389 -1048 353 -1058 377 -352 1085 -352 1069 -1074 381 -350 1051 -352 1069 -386 1055 -366 1069 -368 1051 -354 1083 -356 1083 -5672 1081 -1074 351 -382 1055 -364 1069 -372 1053 -1086 355 -1054 359 -1076 373 -352 1079 -350 1065 -1078 383 -316 1083 -354 1073 -352 1085 -352 1083 -350 1071 -348 1099 -328 1075 -5694 1099 -1072 351 -354 1083 -326 1111 -342 1085 -1054 353 -1062 381 -1064 379 -314 1101 -334 1099 -1058 361 -348 1081 -354 1081 -348 1087 -346 1085 -356 1049 -354 1091 -348 1065 -5710 1073 -1078 347 -346 1101 -332 1073 -350 1093 -1074 355 -1050 385 -1062 347 -366 1099 -326 1077 -1066 373 -352 1083 -320 1097 -350 1097 -326 1075 -376 1065 -332 1097 -370 1065 -5684 1101 -1036 377 -344 1101 -330 1073 -356 1079 -1074 349 -1074 385 -1056 365 -344 1081 -354 1085 -1042 379 -340 1095 -348 1085 -320 1109 -356 1055 -332 1101 -334 1107 -354 1049 -5704 1087 -1048 389 -350 1081 -320 1111 -356 1055 -1052 389 -1048 377 -1056 391 -328 1073 -374 1057 -1084 353 -344 1077 -372 1053 -356 1083 -356 1085 -346 1063 -352 1081 -352 1073 -5712 1073 -1074 353 -356 1079 -318 1117 -346 1065 -1056 389 -1048 381 -1066 383 -314 1081 -352 1073 -1080 385 -316 1085 -352 1071 -352 1097 -326 1109 -344 1071 -354 1081 -320 1099 -5696 1069 -1076 355 -356 1083 -324 1113 -346 1063 -1078 347 -1090 379 -1032 377 -356 1069 -354 1081 -1040 387 -354 1087 -326 1075 -376 1069 -342 1097 -330 1077 -356 1083 -324 1115 -5678 1081 -1076 349 -346 1089 -334 1095 -336 1107 -1058 355 -1054 389 -1046 377 -354 1081 -320 1097 -1078 379 -314 1097 -332 1099 -338 1093 -332 1073 -354 1091 -350 1069 -350 1095 -5674 1111 -1044 381 -314 1099 -336 1097 -336 1095 -1064 369 -1038 389 -1050 381 -338 1093 -350 +RAW_Data: 1081 -1044 395 -322 1081 -354 1087 -348 1085 -356 1083 -320 1093 -348 1089 -356 1049 -5706 1077 -1052 387 -350 1087 -320 1113 -318 1097 -1042 379 -1066 381 -1030 379 -362 1063 -364 1069 -1068 373 -356 1081 -320 1095 -350 1087 -352 1063 -352 1071 -350 1099 -326 1111 -5670 1081 -1076 349 -380 1057 -334 1097 -334 1089 -1054 389 -1056 361 -1072 373 -354 1083 -320 1091 -1074 381 -318 1079 -352 1071 -352 1091 -348 1083 -322 1113 -358 1053 -332 1133 -810 65 -262 181 -142572 65 -98 199 -100 133 -300 99 -166 99 -232 99 -134 333 -166 231 -330 99 -230 493 -100 361 -66 525 -12248 131 -268 133 -268 131 -400 229 -726 97 -494 265 -402 65 -664 363 -134 365 -166 131 -262 395 -98 795 -98 68827 -6766 99 -1626 99 -66 65 -700 97 -864 565 -464 99 -98 133 -230 197 -166 591 -98 5135 -12244 97 -2452 65 -734 165 -198 233 -266 631 -198 12423 -12322 165 -796 67 -100 99 -98 67 -862 133 -728 263 -66 361 -166 129 -100 395 -166 625 -232 131 -66 8113 -12068 229 -132 65 -1394 99 -134 65 -300 165 -134 65 -102 99 -166 133 -766 297 -98 199 -102 1067 -166 859 -98 25307 -13210 65 -1764 97 -264 163 -496 133 -132 65 -66 427 -98 721 -68 531 -134 1591 -100 54955 -11122 65 -726 65 -368 65 -492 99 -428 233 -164 99 -266 131 -498 197 -430 295 -66 2793 -130 11307 -12324 97 -132 193 -1216 65 -1286 131 -594 399 -100 431 -266 495 -100 165 -132 63531 -12252 99 -166 165 -596 99 -496 99 -298 97 -368 65 -134 131 -198 165 -434 99 -266 301 -364 37153 -11928 65 -332 195 -528 131 -230 97 -1126 131 -530 99 -790 361 -100 895 -98 597 -66 699 -100 15803 -10136 99 -2044 65 -400 165 -534 165 -134 99 -434 65 -966 97 -100 133 -134 1125 -66 589 -100 26555 -12218 165 -334 65 -100 99 -2586 65 -732 531 -100 461 -132 3347 -10206 97 -2084 63 -296 99 -164 65 -1052 97 -66 231 -330 65 -232 331 -596 1119 -424 361 -66 28413 -12166 67 -264 161 -228 97 -390 65 -856 131 -66 763 -132 201 -132 9717 -13508 129 -990 65 -100 97 -296 165 -724 65 -368 231 -98 401 -66 527 -66 767 -100 637 -66 109351 -13036 165 -796 65 -200 133 -100 199 -600 133 -134 99 -932 461 -132 399 -264 47323 -12184 97 -566 231 -400 67 -1456 229 -132 97 -394 163 -230 1579 -66 231 -164 10685 -12812 99 -132 67 -464 133 -1162 331 -132 99 -266 167 -200 99 -268 791 -164 823 -132 329 -134 63603 -10646 65 -662 165 -234 163 -630 463 -98 233 -100 195 -262 131 -132 491 -12204 65 -1156 131 -954 295 -132 99 -332 65 -664 789 -328 +RAW_Data: 1351 -8346 67 -4708 133 -400 99 -298 65 -556 65 -396 295 -66 263 -64 163 -100 131 -100 97 -68 131 -166 65 -166 497 -132 999 -132 5609 -4806 131 -4842 131 -298 133 -332 67 -596 131 -1186 263 -268 495 -100 461 -462 165 -66 525 -100 1579 -100 4557 -10356 165 -1614 165 -98 97 -630 65 -164 461 -164 65 -558 231 -130 131 -164 591 -66 557 -9122 65 -166 101 -6060 295 -68 65 -594 163 -368 263 -98 65 -98 99 -294 99 -66 363 -432 329 -66 1987 -100 25465 -9810 197 -100 131 -262 97 -530 99 -168 65 -166 431 -530 99 -232 167 -266 97 -234 1065 -66 131 -198 17549 -9930 899 -100 367 -994 67 -132 167 -794 231 -98 99 -464 299 -134 131 -100 199 -732 97 -296 131 -66 1157 -132 359 -130 47799 -12132 99 -630 197 -132 165 -502 195 -164 261 -98 261 -98 263 -66 195 -296 195 -198 65 -66 393 -66 955 -100 12501 -12452 97 -2942 165 -262 97 -228 65 -98 359 -130 625 -100 723 -66 365 -13612 99 -832 233 -66 99 -298 65 -464 233 -164 65 -164 1053 -362 10409 -11212 197 -794 131 -970 67 -132 99 -366 167 -366 165 -134 167 -664 99 -302 1253 -200 131 -15330 97 -132 259 -100 63 -558 165 -398 65 -860 231 -66 163 -98 263 -364 559 -100 1313 -66 89369 -10410 65 -1788 233 -132 133 -1062 165 -532 65 -632 63 -794 65 -166 97 -132 133 -66 431 -100 467 -132 199 -364 15615 -12276 99 -662 165 -66 133 -564 197 -1460 65 -66 65 -364 231 -396 165 -134 5835 -12662 165 -436 163 -468 65 -100 299 -728 99 -534 265 -166 263 -100 627 -100 197 -66 43301 -12090 163 -96 197 -692 97 -862 129 -368 165 -232 65 -998 197 -66 393 -196 683 -98 6471 -12036 165 -662 133 -302 99 -566 727 -66 2289 -66 7119 -12372 99 -662 97 -300 99 -66 131 -962 165 -362 131 -168 65 -428 133 -134 1797 -66 63965 -10524 263 -1458 265 -298 99 -166 199 -130 789 -68 23871 -12668 65 -990 99 -196 331 -990 755 -100 233 -132 267 -13192 65 -932 233 -134 199 -164 133 -568 99 -898 331 -134 99 -66 961 -66 7013 -10302 65 -664 131 -432 99 -532 199 -466 329 -364 65 -134 429 -198 759 -132 617 -198 38455 -12426 199 -134 99 -1252 99 -396 229 -660 99 -362 197 -164 197 -132 689 -66 161 -98 357 -330 265 -100 15001 -11544 133 -636 131 -132 99 -232 65 -1488 165 -636 131 -266 133 -134 367 -66 197 -100 267 -6574 131 -260 165 -166 65 -132 65 -828 295 -66 589 -100 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24.sub new file mode 100644 index 00000000000..b15d1cdb37b --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Marantec24 +Bit: 24 +Key: 00 00 00 00 00 AC 05 C4 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24_raw.sub new file mode 100644 index 00000000000..4a8c34b212f --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/marantec24_raw.sub @@ -0,0 +1,14 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 868350000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 1224 -1300 1801 -3200 1615 -2374 821 -3198 1603 -2410 785 -3196 815 -3188 1605 -2398 1605 -2398 1607 -2400 1605 -2398 1605 -2396 1601 -2400 1605 -2398 809 -3184 1603 -2396 815 -3194 811 -3190 811 -3194 1603 -2398 1603 -2398 1601 -2392 811 -3194 1605 -2394 1607 -16170 131 -196 217 -493440 135 -1296 1807 -3210 1591 -2396 811 -3198 1591 -2394 807 -3218 807 -3188 1607 -2400 1605 -2394 1599 -2402 1601 -2392 1609 -2400 1605 -2392 1603 -2392 815 -3190 1609 -2402 809 -3188 813 -3192 813 -3190 1605 -2400 1603 -2396 1605 -2396 813 -3194 1601 -2402 1601 -16170 133 -200 219 -382462 101 -1314 1813 -3194 1581 -2414 801 -3214 1605 -2398 807 -3190 811 -3190 1601 -2394 1603 -2398 1607 -2398 1605 -2396 1605 -2394 1601 -2394 1609 -2396 815 -3194 1603 -2400 809 -3194 811 -3190 811 -3190 1603 -2396 1603 -2396 1607 -2398 811 -3192 1607 -2396 1601 -16176 131 -198 217 -348436 303 -1106 1817 -3194 1609 -2386 803 -3214 1597 -2392 811 -3186 815 -3192 1611 -2396 1601 -2394 1609 -2404 1605 -2396 1605 -2396 1607 -2392 1601 -2396 813 -3192 1603 -2394 813 -3190 815 -3188 811 -3194 1601 -2396 1607 -2394 1601 -2396 815 -3186 1611 -2396 1609 -16168 131 -198 217 -349492 347 -1080 1799 -3192 1617 -2388 801 -3218 1601 -2396 809 -3190 809 -3192 1605 -2394 1599 -2394 1605 -2398 1607 -2398 1599 -2398 1607 -2396 1601 -2396 811 -3192 1605 -2400 811 -3184 813 -3192 811 -3192 1607 -2398 1601 -2398 1607 -2400 811 -3190 1603 -2394 1607 -16176 131 -204 213 -447994 135 -1330 977 -1036 65 -230 181 -514880 135 -66 67 -1140 1815 -3192 1615 -2388 803 -3214 1603 -2396 813 -3190 811 -3190 1609 -2398 1601 -2392 1603 -2396 1607 -2398 1607 -2398 1607 -2398 1605 -2394 813 -3186 1611 -2404 809 -3186 811 -3192 813 -3188 1605 -2394 1607 -2400 1607 -2398 807 -3190 1605 -2398 1603 -16172 131 -200 217 -395118 99 -1304 1841 -3160 1621 -2388 805 -3186 1631 -2392 809 -3182 811 -3188 1605 -2402 1601 -2398 1601 -2402 1607 -2398 1605 -2398 1601 -2392 1605 -2404 809 -3188 1599 -2396 817 -3192 811 -3192 811 -3190 1599 -2392 1603 -2398 1607 -2404 809 -3192 1603 -2402 1605 -16164 133 -198 187 -382202 137 -1302 1803 -3192 1601 -2404 803 -3184 1633 -2392 807 -3190 811 -3188 1601 -2400 1607 -2402 1601 -2392 1601 -2396 1607 -2400 1603 -2398 1605 -2398 811 -3184 1601 -2400 813 -3188 809 -3190 811 -3192 1605 -2400 1605 -2396 1599 -2402 809 -3192 1607 -2400 1607 -16174 99 -232 181 -361858 65 -1368 1785 -3228 1567 -2426 777 -3222 1601 -2402 785 -3198 815 -3186 1609 -2402 1601 -2396 1605 -2402 1603 -2396 1605 -2398 1601 -2400 1603 -2398 813 -3194 1605 -2400 809 -3186 813 -3190 813 -3188 1607 -2396 1605 -2400 1605 -2394 809 -3182 1607 -2400 1607 -16210 65 -236 177 -379100 1819 -3192 1611 -2384 799 -3220 1601 -2396 811 -3186 809 -3188 1605 -2394 1607 -2398 +RAW_Data: 1599 -2394 1603 -2396 1609 -2402 1603 -2396 1607 -2398 809 -3196 1603 -2394 809 -3188 813 -3194 809 -3188 1605 -2394 1599 -2396 1609 -2404 811 -3184 1605 -2400 1601 -16162 133 -234 191 -393094 97 -1316 1021 -1010 67 -246 173 -677840 131 -64 59 -1178 1773 -3210 1593 -2430 773 -3222 1601 -2396 811 -3186 813 -3190 1603 -2398 1603 -2396 1607 -2398 1605 -2400 1601 -2396 1605 -2396 1601 -2396 815 -3190 1607 -2402 811 -3190 811 -3186 811 -3192 1607 -2396 1603 -2396 1601 -2400 813 -3188 1607 -2404 1607 -15160 827 -3204 1577 -2404 813 -3200 1591 -2390 807 -3220 807 -3186 1599 -2400 1605 -2398 1603 -2400 1603 -2396 1605 -2398 1605 -2398 1599 -2394 809 -3190 1611 -2394 809 -3186 815 -3192 809 -3192 1603 -2398 1601 -2396 1599 -2396 815 -3188 1609 -2400 1605 -15178 801 -3222 1575 -2392 805 -3190 1615 -2396 809 -3190 819 -3198 1601 -2402 1577 -2402 1609 -2400 1605 -2398 1605 -2396 1605 -2398 1601 -2400 809 -3184 1605 -2396 809 -3190 811 -3192 813 -3190 1601 -2404 1605 -2394 1599 -2396 811 -3190 1605 -2400 1601 -15174 831 -3166 1615 -2396 783 -3200 1611 -2398 813 -3192 811 -3188 1601 -2396 1603 -2398 1607 -2396 1605 -2396 1603 -2398 1601 -2394 1601 -2398 811 -3192 1601 -2394 813 -3192 809 -3194 807 -3190 1605 -2394 1599 -2394 1601 -2394 813 -3194 1601 -2398 1603 -15178 793 -3228 1577 -2404 809 -3186 1611 -2396 815 -3192 811 -3188 1605 -2400 1577 -2404 1603 -2396 1607 -2400 1601 -2398 1603 -2394 1605 -2396 811 -3192 1605 -2394 811 -3190 811 -3188 807 -3186 1601 -2396 1605 -2398 1601 -2398 813 -3186 1601 -2394 1605 -15178 797 -3204 1581 -2400 813 -3188 1603 -2400 813 -3192 811 -3192 1607 -2398 1605 -2398 1607 -2394 1601 -2400 1605 -2398 1601 -2396 1601 -2394 809 -3190 1605 -2400 811 -3186 813 -3192 811 -3184 1601 -2396 1605 -2396 1605 -2400 809 -3184 1599 -2400 1605 -15146 827 -3188 1613 -2402 785 -3200 1605 -2396 815 -3192 811 -3190 1605 -2396 1605 -2396 1607 -2398 1601 -2398 1601 -2392 1599 -2398 1603 -2398 811 -3186 1605 -2396 811 -3190 811 -3192 809 -3190 1597 -2394 1599 -2398 1605 -2398 813 -3186 1599 -2396 1605 -15176 793 -3226 1577 -2398 817 -3198 1605 -2370 817 -3192 813 -3192 1609 -2396 1601 -2396 1605 -2396 1603 -2394 1605 -2394 1607 -2398 1607 -2394 809 -3188 1605 -2400 811 -3194 809 -3188 811 -3192 1605 -2400 1603 -2388 1605 -2394 811 -3186 1605 -2396 1605 -15180 797 -3202 1605 -2398 781 -3196 1605 -2396 815 -3184 817 -3196 1603 -2398 1605 -2398 1605 -2400 1603 -2394 1601 -2396 1607 -2398 1605 -2396 811 -3188 1605 -2396 809 -3186 807 -3194 811 -3194 1603 -2396 1597 -2396 1605 -2396 811 -3192 1603 -2396 1601 -15146 831 -3190 1603 -2404 777 -3224 1605 -2398 785 -3196 813 -3192 1607 -2396 1601 -2398 1607 -2394 1605 -2398 1603 -2394 1601 -2400 1599 -2396 807 -3192 1603 -2396 809 -3186 +RAW_Data: 813 -3190 809 -3190 1603 -2400 1603 -2398 1599 -2390 813 -3192 1603 -2394 1603 -15146 823 -3204 1603 -2398 787 -3204 1595 -2388 805 -3216 807 -3192 1605 -2400 1601 -2398 1597 -2394 1605 -2396 1603 -2398 1605 -2392 1601 -2396 809 -3192 1605 -2398 807 -3190 809 -3186 811 -3194 1603 -2394 1605 -2394 1599 -2398 813 -3192 1609 -2394 1603 -15174 795 -3206 1605 -2398 783 -3196 1607 -2400 809 -3188 813 -3188 1609 -2402 1601 -2394 1609 -2396 1603 -2396 1603 -2400 1599 -2388 1599 -2400 811 -3192 1607 -2394 811 -3186 811 -3190 809 -3194 1603 -2400 1599 -2394 1601 -2392 813 -3192 1603 -2396 1605 -15162 799 -3218 1581 -2404 807 -3202 1603 -2396 787 -3196 819 -3192 1611 -2394 1603 -2396 1607 -2402 1601 -2392 1599 -2392 1601 -2400 1607 -2398 811 -3192 1603 -2396 811 -3190 813 -3188 813 -3186 1603 -2394 1601 -2392 1605 -2400 809 -3188 1609 -2394 1601 -15156 829 -3188 1601 -2414 797 -3182 1629 -2394 807 -3192 811 -3188 1603 -2398 1599 -2392 1603 -2398 1603 -2396 1603 -2396 1607 -2400 1607 -2392 809 -3186 1603 -2400 813 -3194 811 -3192 809 -3188 1599 -2400 1603 -2404 1609 -2394 809 -3194 1599 -2394 1607 -15176 829 -3158 1623 -2404 773 -3224 1605 -2386 799 -3210 811 -3190 1607 -2392 1605 -2398 1607 -2400 1601 -2388 1605 -2398 1603 -2402 1599 -2392 809 -3188 1605 -2400 811 -3186 813 -3190 809 -3190 1603 -2396 1599 -2404 1603 -2400 809 -3188 1605 -2396 1607 -15146 829 -3216 1561 -2414 817 -3196 1599 -2404 797 -3180 809 -3212 1607 -2400 1601 -2394 1603 -2400 1603 -2396 1599 -2400 1605 -2396 1605 -2394 813 -3186 1607 -2394 811 -3186 809 -3190 813 -3192 1607 -2398 1603 -2398 1601 -2396 813 -3192 1603 -2392 1605 -15144 827 -3188 1613 -2404 809 -3192 1615 -2370 811 -3188 811 -3188 1611 -2398 1603 -2400 1601 -2394 1601 -2402 1605 -2396 1601 -2394 1609 -2398 811 -3186 1603 -2392 813 -3196 811 -3182 809 -3188 1603 -2402 1605 -2400 1599 -2394 809 -3194 1607 -2398 1601 -15148 831 -3186 1587 -2424 811 -3192 1575 -2408 803 -3188 805 -3222 1599 -2392 1601 -2400 1609 -2398 1601 -2392 1597 -2394 1601 -2400 1601 -2400 807 -3190 1601 -2400 813 -3190 809 -3190 809 -3188 1607 -2398 1601 -2396 1605 -2398 809 -3184 1603 -2400 1605 -15176 795 -3200 1613 -2400 783 -3198 1603 -2398 813 -3192 809 -3186 1607 -2398 1605 -2398 1605 -2398 1599 -2394 1605 -2398 1603 -2392 1599 -2396 809 -3194 1609 -2390 811 -3194 813 -3188 811 -3188 1599 -2394 1603 -2398 1601 -2394 815 -3192 1605 -2402 1601 -15150 831 -3186 1605 -2412 799 -3206 1601 -2392 809 -3186 813 -3192 1603 -2402 1601 -2392 1605 -2398 1607 -2396 1601 -2392 1609 -2402 1599 -2396 811 -3186 1601 -2398 815 -3196 809 -3188 809 -3188 1607 -2394 1605 -2394 1603 -2394 811 -3194 1603 -2398 1607 -15174 797 -3218 1563 -2424 785 -3194 1633 -2396 795 -3178 805 -3214 1607 -2394 1603 -2400 +RAW_Data: 1603 -2392 1603 -2398 1605 -2400 1597 -2392 1603 -2396 811 -3198 1603 -2390 809 -3192 811 -3188 813 -3192 1599 -2394 1607 -2398 1607 -2394 811 -3192 1601 -2394 1605 -15152 861 -3154 1603 -2410 799 -3186 1601 -2422 809 -3190 809 -3186 1601 -2392 1603 -2394 1611 -2398 1605 -2400 1601 -2392 1609 -2396 1603 -2398 809 -3186 1605 -2400 811 -3188 811 -3188 807 -3192 1605 -2402 1597 -2392 1603 -2396 813 -3194 1601 -2398 1605 -15174 795 -3200 1597 -2428 785 -3196 1613 -2398 785 -3192 815 -3192 1611 -2400 1603 -2394 1603 -2400 1601 -2398 1607 -2394 1603 -2398 1603 -2396 811 -3190 1605 -2394 811 -3194 811 -3182 811 -3192 1607 -2392 1599 -2394 1601 -2398 811 -3192 1607 -2392 1603 -15156 827 -3190 1607 -2408 797 -3210 1599 -2398 777 -3218 811 -3192 1601 -2400 1599 -2398 1601 -2396 1597 -2396 1601 -2392 1607 -2392 1605 -2400 813 -3190 1601 -2396 811 -3194 809 -3190 813 -3190 1603 -2394 1599 -2390 1603 -2400 811 -3190 1607 -2398 1605 -15150 825 -3192 1603 -2404 793 -3178 1605 -2422 777 -3222 775 -3218 1603 -2398 1605 -2398 1597 -2392 1603 -2398 1605 -2400 1601 -2394 1601 -2392 811 -3192 1609 -2398 813 -3190 809 -3182 809 -3184 1607 -2398 1603 -2396 1607 -2398 813 -3190 1607 -2396 1601 -15172 797 -3230 1563 -2424 805 -3190 1599 -2404 795 -3182 807 -3214 1601 -2402 1603 -2396 1601 -2396 1603 -2398 1605 -2398 1599 -2392 1601 -2402 813 -3192 1601 -2396 809 -3188 811 -3188 809 -3192 1605 -2400 1607 -2398 1599 -2394 809 -3190 1607 -2400 1605 -15180 827 -3190 1577 -2394 819 -3196 1613 -2366 815 -3196 813 -3190 1607 -2396 1607 -2402 1599 -2398 1605 -2400 1603 -2398 1601 -2392 1605 -2400 811 -3186 1603 -2400 813 -3190 809 -3196 807 -3182 1601 -2396 1609 -2398 1601 -2398 813 -3192 1601 -2394 1607 -15174 793 -3202 1599 -2424 787 -3196 1607 -2404 785 -3192 815 -3188 1609 -2404 1603 -2398 1607 -2396 1601 -2400 1603 -2394 1601 -2394 1603 -2400 811 -3190 1605 -2400 811 -3188 809 -3190 813 -3194 1597 -2398 1607 -2394 1603 -2394 809 -3190 1603 -2392 1607 -15180 795 -3230 1581 -2392 807 -3218 1593 -2408 777 -3220 781 -3204 1597 -2424 1605 -2394 1595 -2392 1605 -2394 1599 -2396 1605 -2402 1603 -2394 809 -3188 1601 -2396 813 -3194 811 -3188 813 -3190 1605 -2398 1607 -2392 1601 -2398 811 -3192 1599 -2400 1605 -15178 797 -3218 1595 -2400 803 -3198 1605 -2370 825 -3182 803 -3214 1603 -2396 1601 -2398 1601 -2394 1599 -2398 1603 -2396 1607 -2394 1605 -2394 809 -3190 1607 -2398 809 -3194 811 -3188 809 -3194 1605 -2394 1599 -2396 1605 -2396 809 -3196 1603 -2402 1599 -15160 829 -3192 1579 -2400 817 -3198 1605 -2398 783 -3194 813 -3190 1609 -2400 1607 -2400 1599 -2394 1601 -2394 1609 -2398 1601 -2396 1605 -2394 809 -3186 1609 -2400 811 -3186 809 -3196 811 -3190 1605 -2396 1601 -2398 1607 -2396 809 -3186 1605 -2398 1607 -15170 +RAW_Data: 827 -3192 1595 -2376 813 -3192 1601 -2414 797 -3186 807 -3220 1601 -2398 1603 -2394 1599 -2396 1607 -2400 1605 -2394 1597 -2398 1603 -2398 813 -3192 1603 -2394 809 -3188 809 -3188 811 -3192 1607 -2396 1601 -2398 1605 -2398 811 -3188 1603 -2400 1603 -15174 829 -3162 1627 -2374 803 -3224 1571 -2412 801 -3186 807 -3222 1605 -2392 1605 -2392 1599 -2394 1605 -2404 1601 -2396 1607 -2396 1601 -2394 809 -3188 1601 -2398 811 -3190 815 -3194 811 -3184 1603 -2400 1605 -2400 1605 -2394 809 -3188 1609 -2394 1605 -15154 829 -3188 1603 -2412 801 -3210 1603 -2398 807 -3182 809 -3196 1605 -2400 1605 -2396 1599 -2402 1607 -2390 1599 -2396 1599 -2400 1607 -2396 811 -3192 1605 -2396 813 -3196 809 -3190 811 -3192 1609 -2394 1597 -2396 1607 -2398 809 -3186 1605 -2394 1605 -15178 795 -3216 1577 -2408 819 -3190 1607 -2394 817 -3194 779 -3194 1607 -2404 1605 -2398 1607 -2394 1601 -2398 1605 -2400 1603 -2402 1607 -2394 811 -3192 1601 -2396 809 -3186 813 -3194 811 -3188 1599 -2394 1601 -2402 1601 -2398 811 -3186 1603 -2396 1611 -15176 799 -3224 1567 -2424 785 -3202 1599 -2396 809 -3204 783 -3198 1605 -2398 1607 -2402 1605 -2398 1607 -2400 1599 -2398 1605 -2392 1603 -2400 811 -3186 1601 -2400 811 -3194 809 -3184 811 -3186 1603 -2396 1603 -2398 1607 -2398 811 -3188 1605 -2396 1605 -15174 829 -3166 1605 -2402 809 -3190 1615 -2368 815 -3194 815 -3192 1605 -2396 1603 -2400 1603 -2400 1605 -2392 1601 -2400 1607 -2400 1601 -2402 811 -3194 1599 -2392 809 -3188 813 -3184 813 -3192 1605 -2400 1605 -2400 1607 -2390 809 -3188 1607 -2398 1603 -15174 829 -3158 1617 -2400 787 -3192 1607 -2404 811 -3184 815 -3190 1607 -2402 1601 -2396 1605 -2400 1601 -2396 1603 -2396 1607 -2400 1603 -2394 809 -3188 1609 -2398 809 -3190 811 -3188 809 -3188 1607 -2396 1599 -2396 1607 -2400 809 -3188 1607 -2398 1603 -15172 797 -3228 1575 -2424 771 -3202 1615 -2386 801 -3198 807 -3218 1587 -2390 1603 -2394 1603 -2424 1603 -2396 1603 -2398 1599 -2394 1605 -2396 809 -3192 1605 -2400 807 -3184 809 -3190 813 -3190 1603 -2390 1601 -2394 1601 -2396 813 -3196 1607 -2402 1599 -15152 829 -3194 1605 -2408 793 -3182 1597 -2426 807 -3184 811 -3192 1607 -2392 1603 -2396 1605 -2400 1601 -2394 1603 -2394 1605 -2400 1605 -2394 809 -3190 1605 -2396 811 -3192 809 -3186 811 -3190 1601 -2394 1605 -2400 1607 -2398 809 -3186 1601 -2394 1603 -15174 829 -3160 1635 -2382 811 -3194 1609 -2400 779 -3220 781 -3222 1575 -2406 1603 -2398 1607 -2402 1601 -2394 1603 -2396 1601 -2402 1605 -2398 805 -3190 1605 -2394 813 -3194 809 -3188 811 -3192 1603 -2396 1599 -2394 1607 -2394 811 -3194 1603 -2394 1601 -15174 799 -3216 1599 -2402 785 -3198 1615 -2376 819 -3194 811 -3190 1599 -2394 1623 -2392 1599 -2396 1611 -2382 1599 -2390 1633 -2392 1599 -2396 811 -3194 1599 -2394 811 -3188 +RAW_Data: 811 -3190 809 -3192 1603 -2398 1607 -2392 1599 -2398 811 -3190 1603 -2402 1601 -15172 795 -3194 1603 -2404 807 -3186 1599 -2394 821 -3196 785 -3196 1609 -2396 1609 -2398 1603 -2396 1605 -2400 1599 -2394 1605 -2396 1605 -2398 809 -3190 1601 -2396 811 -3190 809 -3194 809 -3188 1601 -2398 1603 -2398 1607 -2392 807 -3190 1603 -2402 1601 -15178 803 -3198 1579 -2410 807 -3188 1625 -2406 793 -3204 779 -3192 1609 -2408 1597 -2392 1595 -2424 1605 -2394 1601 -2394 1601 -2392 1601 -2396 809 -3194 1607 -2398 811 -3194 811 -3186 809 -3182 1607 -2398 1605 -2392 1605 -2392 809 -3190 1611 -2400 1605 -15154 799 -3228 1567 -2434 795 -3180 1627 -2392 809 -3190 809 -3186 1603 -2396 1599 -2394 1603 -2398 1603 -2398 1603 -2392 1607 -2400 1601 -2390 809 -3186 1601 -2404 811 -3188 811 -3190 813 -3186 1605 -2398 1605 -2392 1599 -2400 813 -3190 1599 -2396 1603 -15184 799 -3194 1607 -2410 795 -3176 1603 -2428 807 -3188 811 -3188 1603 -2394 1607 -2398 1599 -2396 1603 -2400 1605 -2394 1601 -2394 1607 -2400 809 -3186 1607 -2400 809 -3184 811 -3188 809 -3196 1605 -2396 1603 -2394 1607 -2392 809 -3188 1607 -2396 1609 -15176 795 -3226 1567 -2406 819 -3198 1579 -2406 809 -3190 821 -3198 1575 -2400 1603 -2398 1611 -2400 1603 -2398 1607 -2396 1601 -2394 1607 -2402 809 -3190 1603 -2396 811 -3186 809 -3192 811 -3192 1607 -2394 1603 -2398 1601 -2396 809 -3196 1605 -2398 1603 -15148 827 -3196 1597 -2426 775 -3200 1613 -2398 783 -3198 813 -3184 1613 -2400 1607 -2400 1605 -2398 1603 -2400 1601 -2394 1603 -2398 1605 -2398 809 -3192 1603 -2396 811 -3190 811 -3190 809 -3194 1605 -2394 1601 -2396 1601 -2400 811 -3192 1607 -2396 1603 -15162 797 -3244 1573 -2398 817 -3196 1603 -2404 795 -3210 775 -3220 1603 -2396 1603 -2396 1607 -2394 1607 -2368 1633 -2392 1601 -2396 1607 -2396 811 -3190 1605 -2400 807 -3186 811 -3194 809 -3186 1607 -2396 1603 -2392 1599 -2394 811 -3186 1611 -2396 1601 -15178 763 -3288 1501 -2496 741 -3254 1543 -2442 777 -3194 815 -3206 1585 -2390 1603 -2426 1601 -2392 1599 -2400 1605 -2396 1599 -2398 1603 -2398 809 -3190 1601 -2396 811 -3188 811 -3188 811 -3194 1607 -2396 1599 -2396 1605 -2398 813 -3190 1605 -2400 1603 -16206 65 -230 181 -579692 165 -1118 1797 -3196 1591 -2420 773 -3224 1603 -2394 809 -3188 809 -3188 1609 -2402 1603 -2398 1599 -2400 1605 -2400 1605 -2396 1605 -2396 1603 -2394 813 -3194 1607 -2398 809 -3188 809 -3192 809 -3196 1603 -2394 1599 -2396 1605 -2402 811 -3190 1605 -2400 1605 -15178 793 -3222 1577 -2402 809 -3192 1601 -2394 807 -3202 819 -3196 1609 -2396 1603 -2396 1601 -2392 1613 -2400 1579 -2398 1613 -2396 1603 -2396 813 -3192 1607 -2394 813 -3198 809 -3188 809 -3188 1599 -2398 1607 -2400 1607 -2398 807 -3186 1603 -2400 1607 -15178 823 -3168 1615 -2398 809 -3192 1615 -2398 783 -3228 +RAW_Data: 779 -3200 1607 -2394 1605 -2402 1607 -2394 1601 -2396 1603 -2400 1607 -2398 1603 -2396 809 -3182 1607 -2402 813 -3194 811 -3188 811 -3186 1603 -2402 1605 -2398 1607 -2396 809 -3188 1603 -2398 1609 -15162 829 -3204 1575 -2428 783 -3202 1597 -2422 775 -3214 809 -3192 1605 -2400 1603 -2402 1601 -2392 1603 -2394 1605 -2392 1611 -2398 1603 -2398 811 -3182 1609 -2400 813 -3196 811 -3186 811 -3186 1609 -2400 1605 -2394 1601 -2402 807 -3190 1607 -2398 1607 -15178 829 -3182 1595 -2424 773 -3224 1589 -2384 805 -3222 809 -3188 1603 -2398 1605 -2400 1599 -2396 1601 -2392 1601 -2400 1609 -2396 1605 -2398 813 -3190 1603 -2396 813 -3186 811 -3194 811 -3196 1603 -2394 1603 -2400 1603 -2396 809 -3186 1609 -2400 1605 -15160 825 -3198 1605 -2402 785 -3208 1599 -2426 775 -3220 807 -3186 1601 -2396 1609 -2398 1607 -2392 1599 -2402 1605 -2398 1599 -2398 1603 -2402 807 -3190 1603 -2398 813 -3186 813 -3196 809 -3184 1601 -2394 1603 -2428 1571 -2400 815 -3220 1575 -2402 1609 -15178 793 -3234 1575 -2404 819 -3188 1599 -2398 807 -3204 819 -3192 1581 -2400 1607 -2396 1607 -2402 1601 -2392 1605 -2398 1605 -2400 1605 -2398 811 -3190 1609 -2396 811 -3186 811 -3194 811 -3186 1603 -2396 1609 -2396 1601 -2400 811 -3192 1603 -2394 1603 -15188 831 -3184 1609 -2382 803 -3190 1629 -2396 809 -3192 809 -3188 1607 -2396 1607 -2398 1607 -2392 1599 -2396 1607 -2398 1605 -2398 1605 -2394 811 -3188 1607 -2400 813 -3192 811 -3190 813 -3186 1603 -2400 1603 -2402 1599 -2394 811 -3190 1609 -2396 1609 -15164 823 -3196 1599 -2396 789 -3210 1595 -2424 809 -3188 811 -3186 1603 -2398 1605 -2390 1601 -2394 1609 -2400 1605 -2396 1607 -2394 1603 -2398 813 -3194 1599 -2394 815 -3194 809 -3192 809 -3190 1607 -2398 1605 -2396 1603 -2394 809 -3188 1605 -2402 1601 -15162 827 -3196 1579 -2426 805 -3206 1605 -2366 811 -3208 799 -3212 1603 -2400 1603 -2394 1601 -2398 1605 -2398 1599 -2394 1601 -2394 1609 -2394 813 -3192 1607 -2398 813 -3186 807 -3188 813 -3188 1601 -2396 1609 -2396 1603 -2392 811 -3194 1601 -2398 1611 -15174 831 -3186 1595 -2406 785 -3200 1625 -2378 813 -3190 815 -3202 1593 -2424 1603 -2400 1603 -2394 1597 -2400 1603 -2400 1605 -2396 1597 -2400 811 -3192 1601 -2400 811 -3190 811 -3190 811 -3192 1607 -2398 1603 -2392 1607 -2394 811 -3194 1603 -2396 1601 -15154 831 -3190 1605 -2404 797 -3180 1635 -2392 807 -3190 809 -3188 1605 -2400 1603 -2394 1605 -2396 1605 -2398 1601 -2394 1605 -2400 1605 -2396 811 -3192 1603 -2394 809 -3186 815 -3192 805 -3192 1601 -2396 1601 -2366 1629 -2388 807 -3192 1603 -2396 1599 -15118 825 -3198 1605 -2400 783 -3198 1589 -2392 809 -3180 809 -3186 1629 -2400 1573 -2390 1631 -2362 1633 -2360 1631 -2366 1599 -2394 1603 -2392 805 -3214 1601 -2396 809 -3184 811 -3190 807 -3160 1631 -2394 1601 -2364 1601 -2420 +RAW_Data: 807 -3192 1603 -2360 1633 -15120 827 -3200 1575 -2400 809 -3196 1605 -2394 807 -3186 809 -3160 1633 -2392 1599 -2366 1599 -2394 1631 -2358 1635 -2366 1601 -2396 1629 -2390 777 -3190 1629 -2400 775 -3218 775 -3216 809 -3188 1603 -2362 1631 -2390 1601 -2396 811 -3190 1597 -2400 1601 -15128 809 -3220 1577 -2398 809 -3196 1603 -2364 811 -3194 811 -3192 1605 -2400 1605 -2360 1601 -2396 1601 -2392 1603 -2390 1631 -2394 1571 -2394 807 -3218 1603 -2396 775 -3214 807 -3186 807 -3162 1603 -2394 1601 -2390 1603 -2396 805 -3222 1603 -2364 1635 -15142 791 -3228 1571 -2400 811 -3188 1601 -2394 809 -3194 809 -3186 1605 -2398 1601 -2390 1603 -2362 1633 -2362 1601 -2394 1635 -2362 1631 -2390 807 -3190 1605 -2394 773 -3220 775 -3186 807 -3192 1599 -2424 1597 -2366 1603 -2396 807 -3216 1601 -2398 1601 -15140 813 -3196 1571 -2398 813 -3190 1601 -2396 811 -3186 811 -3192 1603 -2402 1601 -2392 1601 -2392 1609 -2394 1603 -2394 1607 -2394 1611 -2396 811 -3190 1605 -2400 811 -3190 811 -3190 813 -3190 1601 -2400 1603 -2394 1607 -2398 809 -3188 1607 -2398 1605 -15176 793 -3226 1579 -2400 811 -3186 1613 -2400 785 -3194 815 -3194 1611 -2396 1607 -2396 1601 -2400 1607 -2396 1605 -2398 1603 -2394 1599 -2392 811 -3190 1605 -2396 815 -3192 815 -3190 813 -3188 1601 -2398 1603 -2398 1603 -2398 811 -3194 1605 -2398 1601 -15156 859 -3148 1639 -2378 803 -3214 1569 -2430 807 -3186 809 -3194 1601 -2396 1605 -2398 1607 -2400 1605 -2396 1605 -2396 1607 -2392 1599 -2394 811 -3184 1609 -2400 815 -3194 809 -3188 809 -3196 1605 -2394 1607 -2394 1599 -2396 813 -3194 1603 -2398 1603 -15170 797 -3212 1595 -2402 819 -3184 1613 -2390 831 -3174 819 -3196 1597 -2402 1589 -2388 1601 -2396 1633 -2398 1601 -2392 1599 -2400 1607 -2396 811 -3186 1609 -2402 809 -3188 813 -3192 809 -3188 1607 -2396 1601 -2398 1601 -2398 811 -3192 1599 -2396 1607 -15174 831 -3186 1579 -2402 801 -3202 1615 -2388 827 -3178 803 -3188 1617 -2392 1601 -2392 1635 -2396 1599 -2392 1603 -2398 1605 -2400 1601 -2392 813 -3194 1601 -2400 813 -3190 811 -3190 809 -3188 1603 -2396 1601 -2398 1605 -2400 809 -3184 1601 -2396 1607 -15178 831 -3166 1611 -2398 815 -3198 1577 -2398 811 -3194 815 -3192 1607 -2400 1605 -2400 1599 -2398 1603 -2396 1601 -2398 1605 -2400 1609 -2392 811 -3192 1605 -2398 811 -3188 811 -3192 813 -3190 1607 -2394 1605 -2398 1603 -2400 809 -3190 1601 -2396 1609 -15174 795 -3230 1567 -2432 781 -3204 1597 -2394 807 -3222 807 -3182 1605 -2398 1603 -2392 1603 -2396 1607 -2396 1603 -2404 1605 -2400 1599 -2396 811 -3186 1611 -2398 813 -3188 811 -3192 811 -3188 1605 -2404 1603 -2400 1605 -2398 807 -3190 1605 -2396 1605 -15164 827 -3198 1605 -2398 783 -3206 1595 -2424 807 -3192 807 -3184 1605 -2396 1605 -2400 1607 -2398 1599 -2394 1607 -2396 1605 -2400 1599 -2394 +RAW_Data: 809 -3184 1609 -2400 809 -3194 813 -3188 807 -3188 1603 -2400 1605 -2400 1599 -2398 809 -3190 1605 -2400 1603 -15170 803 -3208 1595 -2402 809 -3196 1589 -2388 807 -3216 809 -3182 1603 -2394 1607 -2398 1603 -2396 1607 -2396 1603 -2400 1605 -2396 1599 -2394 811 -3188 1605 -2396 817 -3196 811 -3182 811 -3192 1607 -2394 1603 -2394 1607 -2398 811 -3190 1603 -2398 1601 -15186 833 -3156 1605 -2412 799 -3218 1595 -2392 809 -3186 811 -3186 1609 -2404 1607 -2394 1605 -2396 1601 -2400 1607 -2396 1601 -2392 1607 -2400 809 -3192 1603 -2396 815 -3194 809 -3188 809 -3192 1603 -2400 1599 -2394 1605 -2400 811 -3188 1599 -2400 1605 -16142 167 -202 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2.sub new file mode 100644 index 00000000000..9a046fd7bee --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Revers_RB2 +Bit: 64 +Key: FF FF FF FF 39 F9 0A 00 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2_raw.sub new file mode 100644 index 00000000000..f50ad7442b0 --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/revers_rb2_raw.sub @@ -0,0 +1,17 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 215 -498 257 -246 243 -276 215 -280 215 -278 247 -250 507 -258 247 -504 479 -274 253 -254 219 -290 213 -530 485 -482 481 -308 217 -254 253 -252 241 -234 257 -250 249 -278 219 -252 247 -250 279 -544 235 -268 259 -226 255 -250 249 -280 219 -252 249 -250 215 -280 247 -252 249 -250 249 -280 219 -252 249 -250 215 -280 279 -218 251 -250 249 -280 219 -252 251 -248 281 -220 251 -250 249 -248 247 -278 219 -252 249 -250 279 -220 251 -250 247 -280 219 -254 249 -248 217 -280 277 -220 507 -258 247 -504 225 -278 245 -246 469 -292 213 -530 227 -276 215 -274 247 -248 249 -248 247 -248 501 -258 249 -502 479 -272 251 -254 255 -254 249 -476 481 -514 481 -274 253 -254 255 -250 239 -262 225 -254 249 -248 217 -278 247 -250 251 -572 267 -238 263 -224 251 -280 219 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -248 249 -248 247 -250 251 -250 249 -280 219 -252 251 -248 217 -280 247 -250 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 281 -220 251 -250 247 -280 479 -228 279 -500 255 -216 277 -214 531 -228 279 -500 257 -216 275 -214 275 -216 277 -278 217 -250 505 -260 217 -500 509 -258 243 -246 273 -216 275 -500 479 -546 479 -238 253 -256 253 -250 243 -268 221 -250 247 -250 251 -250 247 -280 219 -574 265 -268 199 -292 219 -250 279 -220 251 -250 249 -248 249 -278 219 -252 249 -250 279 -220 251 -248 249 -280 219 -252 251 -248 217 -280 247 -250 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 503 -260 217 -532 225 -276 215 -278 503 -238 251 -502 249 -244 241 -278 215 -272 215 -272 277 -214 493 -310 215 -530 483 -232 261 -258 223 -254 249 -538 483 -482 509 -274 217 -290 217 -252 241 -236 259 -250 247 -248 247 -280 217 -252 249 -602 203 -272 229 -256 281 -220 251 -250 249 -280 219 -252 249 -250 279 -222 251 -250 247 -248 249 -278 219 -252 249 -250 279 -220 251 -250 247 -280 221 -252 249 -250 215 -280 247 -250 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 507 -258 215 -530 227 -278 215 -276 501 -258 215 -530 227 -278 215 -276 215 -276 247 -250 247 -250 501 -260 249 -502 481 -272 251 -254 219 -290 247 -474 481 -514 481 -274 289 -218 253 -252 241 -230 253 -282 217 -252 249 -248 279 -220 251 -574 267 -238 263 -222 +RAW_Data: 251 -280 219 -252 249 -250 215 -280 279 -220 251 -248 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -250 277 -222 251 -250 247 -280 219 -252 249 -250 217 -280 247 -250 251 -250 247 -280 219 -252 249 -250 279 -222 251 -250 247 -250 501 -258 249 -502 257 -218 275 -216 497 -272 287 -464 219 -274 275 -216 273 -216 271 -278 213 -274 499 -238 253 -498 479 -262 261 -228 257 -252 249 -506 481 -512 507 -236 291 -218 253 -290 211 -270 223 -250 247 -250 251 -250 247 -248 249 -568 267 -272 201 -292 221 -248 217 -280 247 -250 251 -250 247 -280 221 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -222 251 -248 249 -280 219 -252 249 -250 217 -278 247 -252 251 -250 247 -280 219 -252 507 -260 217 -502 269 -252 253 -256 495 -236 265 -482 259 -250 247 -278 217 -252 249 -248 215 -280 503 -258 217 -532 515 -238 253 -254 255 -254 213 -504 513 -514 477 -274 215 -290 217 -256 247 -234 253 -252 249 -250 249 -280 219 -252 249 -602 203 -272 229 -256 281 -220 251 -250 249 -280 219 -252 249 -250 247 -248 249 -250 251 -250 249 -280 219 -250 249 -250 279 -222 251 -250 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 281 -220 249 -250 249 -280 219 -252 249 -250 215 -280 503 -260 217 -530 227 -280 213 -278 501 -258 217 -496 257 -276 215 -278 215 -278 245 -250 251 -250 501 -260 249 -502 479 -272 251 -256 217 -290 247 -474 483 -514 481 -274 251 -256 253 -252 241 -230 253 -282 217 -252 249 -248 217 -278 247 -576 269 -240 265 -222 251 -248 249 -278 219 -252 249 -250 279 -220 249 -250 249 -280 219 -252 249 -250 217 -278 279 -220 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 535 -226 251 -502 225 -246 275 -246 467 -290 245 -504 225 -276 245 -248 247 -246 247 -248 245 -280 475 -228 279 -500 479 -272 251 -256 253 -256 247 -470 483 -514 513 -238 289 -220 253 -288 209 -270 223 -250 215 -280 245 -250 251 -248 249 -570 267 -238 229 -288 221 -254 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -222 251 -250 247 -280 219 -252 249 -250 217 -278 247 -252 251 -250 247 -280 219 -252 249 -250 279 -222 251 -250 247 -248 249 -280 217 -252 +RAW_Data: 249 -250 279 -220 251 -250 249 -278 221 -252 505 -228 245 -530 257 -214 275 -246 505 -226 247 -532 257 -214 275 -216 275 -246 249 -248 217 -280 503 -258 217 -498 543 -236 251 -254 255 -254 251 -474 513 -516 477 -238 253 -292 217 -254 245 -234 253 -252 251 -248 249 -278 219 -252 251 -602 203 -272 229 -258 279 -222 251 -250 247 -250 247 -280 217 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -250 249 -280 219 -252 249 -250 247 -248 279 -220 251 -248 249 -280 219 -252 249 -250 279 -220 253 -250 247 -248 249 -278 219 -252 249 -250 503 -258 217 -564 195 -278 215 -276 503 -258 215 -500 271 -288 215 -256 253 -250 207 -262 251 -252 505 -256 247 -504 481 -306 215 -254 253 -256 213 -534 487 -480 511 -274 215 -292 253 -218 247 -236 257 -250 247 -278 219 -250 249 -250 279 -544 235 -268 259 -226 253 -250 249 -280 219 -252 249 -250 279 -220 253 -250 247 -248 249 -278 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 277 -220 251 -250 247 -280 221 -252 249 -250 279 -220 251 -250 471 -290 247 -502 225 -278 245 -246 469 -306 251 -466 251 -242 245 -272 245 -246 241 -246 241 -278 497 -238 253 -500 483 -264 229 -258 283 -220 253 -508 481 -508 477 -308 253 -218 253 -254 243 -264 225 -256 247 -250 279 -220 249 -250 249 -570 269 -236 231 -286 223 -252 251 -248 217 -278 247 -252 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -250 279 -220 251 -250 247 -280 221 -252 249 -250 215 -280 247 -250 251 -250 247 -280 219 -254 249 -250 247 -248 277 -220 251 -250 247 -280 479 -228 279 -500 257 -216 275 -214 531 -228 279 -500 257 -216 275 -216 275 -246 249 -250 247 -250 503 -260 215 -500 541 -238 249 -256 253 -256 215 -508 481 -548 479 -238 253 -292 217 -254 245 -232 221 -280 247 -250 251 -250 247 -280 219 -574 263 -268 199 -292 219 -250 279 -220 253 -250 247 -280 221 -252 249 -248 249 -248 277 -220 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -250 249 -280 219 -252 249 -250 247 -248 279 -220 251 -250 247 -280 219 -252 249 -250 505 -260 217 -498 257 -276 213 -278 503 -260 215 -498 257 -246 243 -276 215 -280 215 -278 247 -252 505 -256 247 -506 479 -274 253 -254 219 -290 213 -530 485 -482 509 -274 +RAW_Data: 215 -292 217 -252 243 -236 259 -250 249 -280 219 -250 249 -250 215 -632 205 -272 261 -226 255 -250 249 -248 247 -280 217 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 279 -220 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -250 249 -280 219 -252 249 -250 247 -248 279 -218 507 -258 247 -504 225 -278 215 -274 499 -258 215 -530 225 -280 213 -278 245 -250 249 -248 247 -248 501 -260 247 -502 479 -272 251 -256 253 -254 249 -476 481 -514 483 -274 253 -254 255 -252 239 -260 225 -254 249 -248 215 -280 247 -250 251 -572 267 -238 263 -224 249 -280 219 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 217 -280 277 -220 251 -248 249 -280 219 -252 251 -248 247 -248 279 -220 251 -250 247 -282 219 -250 249 -250 279 -222 251 -250 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 479 -228 277 -500 257 -214 275 -216 529 -228 279 -500 257 -216 275 -216 275 -216 277 -278 217 -250 507 -258 219 -500 511 -274 253 -254 255 -218 245 -500 483 -544 479 -226 273 -244 243 -276 213 -278 213 -278 245 -250 251 -248 247 -280 219 -572 265 -268 199 -292 219 -250 279 -222 251 -250 247 -248 249 -278 221 -250 249 -250 279 -220 251 -250 249 -280 219 -252 251 -248 247 -248 279 -220 251 -248 249 -280 219 -252 249 -250 247 -248 279 -220 251 -250 247 -280 219 -254 249 -248 281 -220 251 -250 247 -250 247 -280 219 -250 505 -260 217 -500 257 -276 215 -278 503 -236 249 -504 247 -246 241 -278 213 -274 243 -244 275 -214 493 -310 215 -516 477 -272 235 -262 227 -256 249 -504 509 -482 511 -274 215 -292 217 -252 279 -202 259 -250 249 -248 247 -278 219 -250 249 -604 205 -272 229 -254 281 -220 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -222 249 -250 249 -280 219 -252 249 -250 247 -248 277 -220 251 -250 249 -280 219 -252 249 -250 247 -248 279 -220 251 -250 247 -280 221 -252 249 -248 279 -220 507 -256 215 -532 225 -280 213 -276 501 -258 217 -530 227 -280 213 -276 215 -276 247 -248 249 -250 535 -226 249 -502 479 -258 243 -276 213 -276 245 -502 481 -514 483 -272 253 -254 255 -250 239 -230 253 -280 219 -250 249 -248 279 -220 253 -572 267 -238 263 -224 249 -282 219 -250 249 -250 217 -280 277 -220 251 -250 247 -280 221 -252 249 -248 281 -220 251 -250 249 -248 247 -280 219 -250 +RAW_Data: 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 247 -248 277 -220 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 501 -260 249 -502 257 -216 275 -216 497 -272 287 -464 243 -290 253 -212 271 -226 251 -280 219 -250 505 -226 247 -530 477 -274 251 -256 253 -218 283 -472 483 -514 515 -236 291 -218 253 -288 209 -268 223 -250 247 -250 251 -250 247 -248 247 -570 267 -270 201 -294 219 -250 247 -248 279 -220 249 -250 249 -280 219 -252 249 -250 247 -248 279 -220 251 -250 249 -280 219 -252 249 -250 277 -222 251 -250 247 -250 247 -278 219 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 279 -220 249 -250 247 -280 221 -252 505 -260 219 -500 271 -252 253 -256 487 -234 267 -488 257 -250 247 -248 245 -278 219 -252 249 -248 505 -258 217 -532 515 -238 253 -254 255 -254 213 -506 511 -514 477 -274 215 -290 219 -290 211 -234 285 -220 251 -250 247 -280 219 -252 249 -602 239 -238 229 -256 281 -220 251 -250 249 -280 219 -252 249 -250 215 -280 279 -220 251 -250 247 -280 219 -252 249 -250 247 -248 247 -252 251 -248 249 -280 219 -252 249 -250 279 -220 253 -250 247 -248 249 -278 219 -252 249 -250 279 -220 251 -248 249 -280 219 -252 251 -248 249 -248 503 -258 217 -532 227 -278 215 -276 501 -260 215 -498 257 -276 213 -278 215 -278 245 -252 249 -250 535 -226 249 -504 479 -272 251 -254 217 -292 247 -474 483 -514 481 -274 253 -256 253 -252 239 -230 253 -280 219 -252 247 -250 215 -280 277 -544 269 -240 265 -224 251 -248 247 -278 219 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 277 -220 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 253 -250 247 -248 249 -278 219 -252 249 -250 277 -222 251 -250 535 -228 249 -502 225 -246 275 -246 469 -306 251 -464 243 -290 253 -212 273 -226 251 -248 247 -280 475 -228 279 -500 477 -274 251 -254 255 -254 247 -472 481 -514 515 -226 273 -214 271 -246 241 -276 215 -278 215 -278 245 -252 249 -250 249 -570 267 -236 231 -288 221 -254 249 -250 277 -222 251 -248 249 -248 247 -280 219 -252 249 -248 281 -220 251 -250 249 -280 219 -252 249 -250 215 -280 247 -250 251 -250 247 -280 221 -252 249 -248 281 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 477 -228 279 -500 255 -216 275 -246 505 -228 247 -530 255 -216 275 -216 275 -246 +RAW_Data: 247 -250 249 -248 503 -260 217 -498 541 -238 249 -256 253 -256 251 -474 513 -518 477 -238 253 -292 217 -254 243 -234 283 -222 249 -250 249 -248 247 -278 219 -606 239 -238 231 -256 249 -248 279 -220 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -250 279 -220 251 -250 249 -280 219 -250 249 -250 249 -248 247 -250 251 -250 247 -280 219 -252 251 -248 281 -220 251 -250 249 -248 247 -280 219 -252 249 -248 505 -258 217 -498 257 -276 215 -278 501 -258 217 -498 257 -276 215 -278 215 -278 215 -278 247 -250 505 -260 245 -504 481 -288 215 -274 215 -276 213 -530 515 -478 511 -274 215 -256 289 -220 243 -234 255 -250 245 -280 217 -252 249 -248 279 -544 237 -268 259 -224 255 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -250 249 -248 249 -278 219 -252 249 -248 279 -222 251 -250 247 -280 219 -254 249 -248 247 -248 279 -220 251 -250 249 -278 221 -252 249 -248 279 -222 251 -250 469 -292 245 -504 235 -288 253 -218 489 -266 269 -500 195 -280 215 -276 247 -248 249 -250 247 -280 479 -228 277 -502 477 -272 253 -254 253 -256 247 -474 481 -516 481 -276 253 -256 253 -214 273 -260 223 -254 249 -248 279 -220 251 -250 249 -570 267 -236 231 -288 221 -254 249 -250 215 -280 247 -252 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -222 251 -250 247 -280 219 -252 249 -250 217 -280 247 -250 251 -250 249 -278 479 -228 279 -500 257 -214 275 -216 531 -228 279 -500 257 -214 275 -216 275 -248 247 -250 249 -248 503 -258 217 -500 545 -238 251 -256 253 -218 247 -502 481 -546 481 -238 289 -256 217 -290 213 -234 223 -280 247 -250 251 -250 247 -280 219 -574 263 -268 199 -292 219 -250 279 -220 251 -250 249 -280 219 -252 249 -250 247 -248 279 -220 251 -250 249 -280 219 -252 249 -248 281 -220 251 -250 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -222 251 -250 247 -280 219 -252 249 -250 503 -260 217 -498 257 -276 215 -278 503 -258 217 -500 269 -254 253 -254 255 -250 205 -264 281 -220 507 -256 247 -504 481 -272 253 -256 217 -290 213 -532 487 -480 511 -274 215 -292 217 -252 243 -236 257 -250 247 -280 219 -250 249 -250 215 -632 205 -272 261 -226 255 -250 249 -248 249 -278 219 -252 +RAW_Data: 249 -248 279 -222 251 -250 247 -280 219 -252 249 -250 247 -248 279 -220 249 -252 247 -280 219 -252 249 -250 279 -222 251 -250 247 -248 249 -278 221 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 247 -248 279 -220 505 -258 245 -504 227 -278 213 -274 501 -258 215 -530 227 -280 213 -276 247 -248 249 -248 247 -248 501 -258 249 -502 479 -272 253 -254 253 -256 249 -474 483 -514 483 -274 255 -254 255 -214 273 -260 223 -254 249 -248 215 -280 247 -252 249 -574 267 -238 263 -224 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 253 -250 247 -280 219 -252 249 -250 247 -248 279 -220 251 -250 247 -280 219 -252 249 -250 279 -220 253 -250 247 -248 249 -278 219 -252 249 -250 279 -220 251 -250 249 -280 477 -228 279 -500 257 -216 275 -214 531 -226 279 -500 225 -244 277 -214 277 -216 277 -278 219 -250 505 -260 217 -500 513 -274 251 -256 253 -218 247 -500 481 -546 479 -238 289 -218 255 -286 211 -270 223 -250 247 -250 249 -250 249 -280 219 -572 265 -268 199 -292 221 -248 281 -220 251 -250 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -250 249 -280 219 -252 249 -250 217 -278 279 -220 249 -250 249 -280 219 -252 249 -250 279 -220 253 -250 247 -248 247 -280 219 -252 505 -260 217 -532 225 -276 215 -278 503 -236 251 -504 247 -254 251 -280 201 -260 251 -248 247 -252 505 -258 215 -530 513 -238 253 -254 255 -254 213 -504 513 -514 477 -274 215 -290 219 -252 281 -204 259 -252 247 -248 247 -278 219 -250 249 -604 203 -272 229 -256 281 -220 251 -250 247 -280 219 -252 251 -248 281 -220 251 -250 247 -250 247 -280 217 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 277 -220 251 -250 249 -280 219 -252 249 -250 217 -278 247 -252 249 -250 249 -280 219 -252 249 -250 279 -220 507 -258 215 -530 227 -278 215 -276 499 -260 215 -530 225 -280 213 -276 215 -278 247 -248 249 -248 503 -260 249 -502 479 -258 243 -274 215 -274 247 -504 481 -512 477 -274 251 -256 253 -252 241 -230 253 -280 219 -252 249 -248 279 -220 251 -574 267 -238 263 -224 249 -282 219 -250 249 -250 217 -280 245 -252 251 -250 247 -280 219 -254 249 -248 281 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -248 217 -280 277 -220 251 -250 249 -280 219 -252 249 -250 215 -280 279 -220 +RAW_Data: 249 -250 535 -228 249 -502 257 -218 275 -216 497 -272 285 -466 243 -290 253 -212 271 -226 251 -280 219 -250 505 -228 245 -530 479 -272 253 -254 253 -220 283 -470 481 -516 515 -236 255 -254 253 -288 209 -268 223 -248 217 -278 247 -250 251 -250 247 -570 267 -238 231 -286 221 -254 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 217 -278 247 -252 251 -248 249 -280 219 -252 249 -250 279 -222 251 -250 247 -248 249 -278 219 -252 249 -248 281 -220 251 -248 249 -280 219 -252 249 -250 249 -248 247 -252 249 -250 249 -280 219 -252 505 -228 247 -530 227 -246 273 -246 505 -228 245 -530 255 -216 275 -214 275 -248 247 -250 247 -250 503 -258 217 -564 483 -238 251 -256 253 -254 215 -504 515 -514 475 -258 213 -274 243 -276 213 -276 245 -248 247 -248 247 -280 219 -250 249 -604 203 -272 229 -256 281 -220 251 -250 247 -280 221 -252 249 -250 215 -280 277 -220 251 -250 249 -280 219 -252 249 -250 215 -280 279 -218 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 253 -250 247 -280 219 -252 249 -250 217 -280 503 -258 217 -532 225 -280 213 -278 501 -258 217 -496 257 -276 215 -278 215 -278 247 -250 249 -250 469 -292 245 -504 481 -272 251 -254 217 -292 247 -474 485 -512 481 -274 253 -254 255 -252 239 -230 255 -280 219 -250 249 -248 217 -278 279 -544 269 -238 265 -224 251 -248 249 -278 219 -252 249 -250 279 -220 251 -250 247 -280 219 -252 249 -250 217 -280 247 -252 249 -250 249 -280 219 -252 249 -250 247 -248 279 -220 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 535 -228 249 -504 237 -250 291 -218 491 -264 265 -498 193 -280 247 -248 249 -248 249 -248 247 -278 477 -230 277 -500 479 -272 215 -292 253 -256 247 -472 481 -514 515 -236 291 -218 255 -252 239 -262 225 -252 249 -250 279 -220 249 -250 249 -570 267 -238 231 -286 221 -254 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 253 -250 247 -280 219 -252 249 -250 247 -248 279 -220 251 -248 249 -280 221 -252 249 -248 247 -248 279 -220 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 477 -228 277 -500 257 -216 275 -246 505 -226 247 -530 257 -214 275 -216 275 -246 249 -250 247 -250 503 -258 217 -498 541 -228 245 -244 243 -278 247 -500 511 -516 479 -238 253 -292 217 -252 209 -266 281 -222 +RAW_Data: 249 -250 249 -248 247 -278 219 -606 239 -238 231 -258 249 -248 247 -250 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 217 -278 279 -220 251 -250 249 -278 221 -250 249 -250 279 -222 251 -250 247 -248 249 -278 219 -252 249 -250 503 -260 217 -498 257 -276 215 -278 501 -258 217 -498 257 -276 215 -278 215 -278 215 -278 247 -250 505 -258 245 -506 479 -308 215 -254 219 -290 213 -534 487 -482 479 -288 213 -274 243 -246 275 -214 275 -216 277 -278 217 -250 247 -248 279 -546 235 -268 259 -226 253 -250 249 -280 219 -252 249 -250 247 -248 279 -220 251 -250 249 -280 219 -252 249 -248 281 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -250 249 -280 219 -252 249 -250 247 -248 279 -218 251 -250 249 -280 219 -252 249 -250 279 -220 251 -250 471 -292 245 -502 227 -276 245 -248 467 -308 215 -504 243 -290 217 -244 265 -228 253 -250 247 -280 477 -228 279 -500 479 -272 251 -256 253 -254 249 -472 483 -514 479 -256 275 -244 243 -246 243 -276 215 -278 215 -276 247 -250 249 -250 249 -570 267 -236 231 -286 221 -254 249 -250 217 -278 279 -220 251 -250 247 -280 221 -252 249 -248 247 -248 279 -220 251 -250 247 -280 219 -254 249 -248 279 -222 251 -250 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 279 -220 249 -250 249 -280 477 -228 277 -502 255 -216 275 -216 531 -228 279 -500 257 -216 275 -214 277 -246 249 -250 247 -250 503 -260 215 -500 541 -226 245 -246 243 -246 275 -500 477 -548 477 -236 255 -290 217 -254 245 -234 221 -282 247 -250 249 -250 249 -280 219 -572 265 -266 199 -292 221 -248 281 -220 251 -250 249 -278 221 -252 249 -250 247 -248 279 -220 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -250 279 -220 249 -250 249 -248 249 -278 219 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 503 -260 217 -498 257 -276 215 -278 503 -258 217 -498 257 -244 243 -278 215 -278 217 -278 245 -252 505 -258 247 -506 479 -272 255 -254 217 -292 211 -532 485 -480 509 -274 217 -290 219 -252 243 -236 259 -250 247 -280 219 -250 249 -250 217 -630 205 -272 261 -226 255 -252 247 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 217 -278 279 -220 251 -250 247 -280 219 -252 249 -250 279 -220 251 -250 +RAW_Data: 249 -248 247 -280 219 -252 249 -248 279 -222 251 -250 247 -250 247 -280 217 -252 249 -250 279 -220 507 -258 247 -504 225 -278 213 -274 501 -258 215 -530 225 -280 213 -276 247 -248 249 -248 249 -246 501 -260 249 -502 479 -272 251 -254 255 -254 249 -476 481 -514 483 -274 253 -256 253 -250 239 -230 251 -280 219 -252 247 -250 279 -220 251 -572 269 -236 265 -222 251 -280 219 -252 249 -250 277 -222 251 -250 247 -250 247 -280 217 -252 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 279 -220 251 -250 247 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 251 -252 247 -248 503 -258 249 -502 257 -216 277 -214 531 -228 279 -502 237 -254 253 -256 253 -216 271 -260 223 -254 505 -260 217 -500 513 -274 251 -256 253 -218 247 -498 483 -546 479 -238 289 -220 253 -288 209 -268 223 -250 247 -252 249 -250 249 -278 219 -574 265 -268 199 -292 219 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -222 251 -250 247 -248 249 -278 219 -252 249 -250 279 -220 251 -250 249 -278 221 -252 249 -250 215 -280 279 -220 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 505 -258 219 -498 257 -276 215 -278 503 -238 249 -504 245 -254 253 -280 203 -260 219 -280 215 -278 503 -260 215 -532 515 -238 253 -254 255 -254 213 -506 511 -516 477 -272 215 -292 217 -254 279 -204 261 -250 249 -246 247 -278 219 -252 249 -602 205 -272 229 -256 281 -220 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 281 -220 249 -250 249 -248 247 -280 219 -252 249 -250 279 -220 251 -250 249 -280 219 -250 249 -250 217 -280 247 -252 249 -250 249 -280 219 -252 249 -248 281 -220 507 -258 215 -530 227 -280 213 -276 499 -258 215 -532 225 -280 213 -276 215 -276 247 -250 249 -248 503 -258 251 -502 479 -272 251 -254 219 -290 247 -474 515 -482 481 -274 253 -256 253 -252 239 -230 253 -280 219 -252 247 -250 279 -220 251 -572 269 -236 263 -224 251 -280 219 -252 249 -250 215 -280 279 -220 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -248 247 -280 219 -252 249 -248 279 -220 253 -250 247 -280 219 -252 249 -250 217 -280 247 -250 251 -250 535 -226 251 -502 257 -216 277 -216 497 -272 287 -464 245 -288 253 -212 271 -224 251 -280 219 -250 507 -228 247 -528 +RAW_Data: 477 -274 251 -254 255 -218 283 -472 481 -516 515 -236 255 -254 255 -250 245 -266 223 -250 217 -278 245 -252 249 -250 249 -570 267 -238 229 -288 221 -254 249 -250 279 -220 251 -250 247 -280 221 -252 249 -248 217 -278 279 -220 251 -250 247 -282 219 -252 249 -250 277 -222 251 -250 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 217 -278 247 -252 251 -250 247 -280 219 -252 507 -228 247 -530 255 -216 275 -246 503 -228 245 -530 257 -214 275 -216 275 -246 249 -248 249 -248 503 -260 217 -532 515 -238 253 -254 253 -256 213 -506 511 -516 477 -272 215 -292 217 -254 245 -234 255 -252 249 -250 249 -278 219 -252 249 -602 205 -272 229 -256 281 -220 251 -250 249 -248 249 -278 219 -252 249 -250 279 -220 249 -250 249 -280 219 -254 249 -248 217 -280 277 -220 251 -250 247 -280 221 -252 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 247 -280 221 -252 249 -248 249 -248 503 -258 217 -532 227 -280 213 -278 499 -258 215 -500 271 -288 217 -254 255 -248 241 -234 259 -250 469 -306 249 -464 501 -280 215 -284 207 -262 251 -508 515 -480 481 -274 253 -254 253 -254 241 -230 253 -282 219 -250 249 -248 217 -278 247 -576 269 -240 265 -222 251 -248 249 -278 219 -252 249 -248 279 -220 251 -250 249 -248 249 -278 219 -252 249 -248 281 -220 249 -250 249 -280 219 -252 249 -250 217 -280 247 -250 251 -250 247 -280 219 -254 249 -248 281 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 535 -228 249 -502 225 -246 275 -248 465 -290 245 -504 225 -276 245 -246 247 -248 247 -246 247 -278 477 -228 279 -500 477 -274 251 -254 255 -254 247 -474 483 -514 515 -238 253 -256 253 -250 239 -262 223 -254 249 -250 279 -220 249 -250 249 -570 267 -238 229 -288 221 -254 249 -250 279 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 217 -278 247 -252 249 -250 249 -280 219 -252 249 -250 217 -278 279 -220 251 -248 249 -280 221 -252 249 -250 279 -220 251 -250 249 -248 247 -280 477 -228 277 -500 257 -216 275 -246 505 -228 245 -530 257 -214 275 -216 275 -246 249 -250 247 -250 503 -258 217 -498 543 -226 243 -246 243 -278 247 -500 479 -546 477 -238 255 -290 217 -252 245 -232 283 -222 249 -250 249 -248 247 -280 217 -608 239 -238 229 -256 219 -280 247 -250 251 -250 247 -280 219 -254 249 -248 281 -220 251 -250 +RAW_Data: 247 -250 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 247 -252 249 -250 249 -280 219 -252 249 -250 217 -278 279 -220 251 -250 247 -280 219 -252 249 -250 505 -258 217 -500 255 -278 215 -278 501 -260 215 -498 257 -276 215 -278 215 -278 215 -278 247 -252 505 -258 245 -504 481 -272 251 -254 217 -292 213 -532 485 -480 511 -274 215 -292 217 -252 243 -236 259 -250 249 -278 219 -252 249 -248 279 -546 235 -268 259 -226 255 -250 249 -278 221 -250 249 -250 215 -280 279 -220 251 -250 247 -280 219 -254 249 -248 281 -220 251 -250 249 -248 247 -280 219 -250 249 -250 279 -220 251 -250 249 -280 219 -252 249 -250 215 -280 247 -252 249 -250 249 -280 219 -252 249 -250 279 -220 251 -250 471 -288 247 -502 227 -276 245 -248 469 -292 213 -530 225 -278 213 -276 245 -250 247 -248 249 -278 477 -228 279 -500 477 -256 245 -242 277 -246 247 -502 479 -512 475 -274 291 -218 255 -250 241 -262 223 -254 249 -250 247 -252 249 -250 249 -570 267 -238 231 -286 221 -254 251 -248 217 -278 247 -252 251 -250 247 -280 219 -252 249 -250 217 -278 247 -252 251 -250 247 -280 221 -252 249 -248 279 -220 253 -250 247 -248 249 -278 219 -252 249 -250 279 -220 251 -250 247 -280 221 -252 249 -248 217 -280 247 -250 251 -250 249 -280 477 -228 279 -500 257 -214 275 -216 529 -228 279 -500 257 -216 275 -216 275 -216 277 -278 219 -250 505 -258 217 -500 547 -238 251 -254 255 -218 245 -502 481 -544 479 -236 291 -254 217 -292 213 -268 221 -250 247 -252 249 -250 249 -280 219 -572 265 -268 199 -292 219 -250 279 -222 251 -250 247 -282 219 -252 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/roger.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/roger.sub new file mode 100644 index 00000000000..2304b43d2ab --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/roger.sub @@ -0,0 +1,7 @@ +Filetype: Flipper SubGhz Key File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: Roger +Bit: 28 +Key: 00 00 00 00 05 AB A1 01 diff --git a/applications/debug/unit_tests/resources/unit_tests/subghz/roger_raw.sub b/applications/debug/unit_tests/resources/unit_tests/subghz/roger_raw.sub new file mode 100644 index 00000000000..0827fb0d2a7 --- /dev/null +++ b/applications/debug/unit_tests/resources/unit_tests/subghz/roger_raw.sub @@ -0,0 +1,23 @@ +Filetype: Flipper SubGhz RAW File +Version: 1 +Frequency: 433920000 +Preset: FuriHalSubGhzPresetOok650Async +Protocol: RAW +RAW_Data: 22710 -100 52363 -100 323 -66 1865 -66 32843 -66 753 -100 461 -100 19881 -66 16113 -66 20557 -66 6287 -64 25981 -100 587 -66 24707 -66 2367 -66 4681 -66 291 -98 4567 -100 1001 -100 33935 -66 20561 -100 5745 -66 2563 -66 4245 -66 22121 -66 1517 -100 2895 -66 15919 -66 20885 -100 12513 -890 839 -458 415 -914 843 -452 837 -482 387 -928 849 -446 415 -900 843 -474 415 -902 843 -470 841 -470 843 -468 383 -914 845 -460 415 -914 409 -884 423 -902 411 -902 835 -482 411 -880 423 -902 411 -908 397 -898 405 -920 411 -880 441 -896 835 -8268 411 -888 877 -430 415 -908 841 -460 869 -434 413 -920 845 -458 415 -912 845 -454 409 -884 879 -452 869 -428 873 -434 413 -904 871 -434 413 -918 415 -874 441 -882 425 -900 835 -448 443 -880 423 -904 409 -902 409 -904 409 -910 399 -896 417 -894 851 -8248 421 -912 853 -446 427 -872 863 -444 867 -446 441 -876 867 -456 415 -882 879 -452 419 -880 853 -448 881 -450 835 -460 415 -918 845 -454 409 -884 419 -906 411 -910 397 -898 865 -446 453 -860 421 -884 453 -876 415 -876 447 -878 441 -880 437 -882 861 -8216 457 -882 853 -456 405 -884 889 -420 879 -448 413 -890 873 -432 443 -892 841 -456 409 -922 843 -458 841 -460 873 -432 413 -918 843 -456 409 -918 387 -906 409 -912 427 -870 863 -446 439 -874 437 -888 409 -880 439 -898 419 -888 421 -880 453 -876 843 -8232 449 -874 891 -418 451 -878 865 -454 849 -448 413 -902 843 -474 411 -888 877 -432 413 -920 843 -454 869 -432 875 -432 413 -920 845 -458 415 -884 421 -910 395 -900 439 -888 839 -454 451 -880 419 -878 449 -876 415 -876 445 -878 439 -880 435 -870 867 -8246 423 -888 849 -454 445 -880 863 -418 879 -446 413 -896 875 -444 411 -902 873 -442 411 -904 839 -472 837 -472 837 -474 413 -874 871 -438 443 -892 415 -874 441 -878 439 -878 867 -454 417 -882 425 -908 399 -896 419 -896 419 -882 453 -876 413 -878 871 -8228 451 -876 853 -442 437 -904 841 -450 855 -450 449 -886 839 -474 411 -890 843 -460 415 -886 879 -456 843 -458 875 -428 409 -906 869 -436 413 -920 417 -884 423 -874 435 -892 857 -456 417 -880 453 -876 413 -910 413 -878 439 -870 439 -872 439 -870 871 -8248 421 -892 851 -454 445 -880 861 -452 843 -448 413 -896 877 -444 413 -898 853 -450 417 -898 877 -446 841 -474 839 -472 411 -892 843 -460 409 -918 417 -882 423 -872 435 -896 869 -418 453 -888 421 -878 451 -876 415 -876 443 -878 441 -876 437 -882 861 -8236 423 -878 883 -454 401 -884 +RAW_Data: 857 -450 881 -446 413 -888 873 -434 415 -906 875 -428 411 -904 869 -434 873 -438 875 -436 413 -906 869 -434 413 -906 411 -904 411 -906 415 -908 835 -460 411 -906 409 -904 411 -908 417 -874 411 -910 415 -914 421 -884 849 -8232 453 -870 853 -440 439 -902 841 -450 885 -452 413 -870 861 -452 447 -862 877 -446 411 -900 877 -444 839 -474 839 -472 411 -902 841 -470 409 -890 415 -882 421 -910 425 -872 863 -446 451 -866 417 -906 417 -906 419 -868 451 -870 415 -900 413 -904 841 -8244 439 -886 855 -456 415 -908 853 -444 861 -452 421 -886 851 -452 447 -860 877 -448 413 -898 875 -444 873 -442 837 -474 409 -904 839 -472 409 -870 441 -898 421 -886 413 -890 873 -434 443 -890 417 -882 423 -876 433 -896 417 -894 421 -880 453 -876 843 -8254 435 -870 865 -448 409 -904 869 -454 843 -458 415 -912 843 -456 409 -914 835 -458 409 -920 841 -456 867 -432 873 -434 443 -888 845 -460 415 -910 417 -882 425 -872 435 -892 867 -448 407 -898 409 -902 417 -898 419 -880 453 -874 415 -908 413 -878 871 -8236 417 -904 845 -454 451 -880 863 -420 881 -448 413 -902 841 -476 411 -892 873 -430 415 -918 843 -456 875 -426 869 -434 443 -890 841 -458 409 -920 415 -882 425 -870 439 -904 835 -450 421 -912 427 -872 437 -888 419 -888 421 -882 453 -876 413 -880 871 -8234 457 -848 881 -444 435 -880 867 -450 847 -448 415 -920 841 -470 411 -888 845 -460 415 -916 847 -454 835 -460 871 -466 381 -920 843 -458 409 -916 417 -878 411 -912 425 -870 887 -418 445 -878 419 -914 419 -876 415 -908 413 -876 443 -880 441 -880 863 -8232 423 -880 881 -454 401 -904 865 -450 847 -446 415 -898 875 -444 411 -902 839 -476 411 -902 839 -474 837 -472 839 -472 411 -888 875 -430 415 -908 415 -908 409 -882 421 -904 837 -450 421 -910 425 -872 451 -868 419 -882 451 -874 413 -906 413 -902 843 -8256 419 -892 851 -472 405 -906 837 -480 821 -482 417 -904 823 -482 387 -918 843 -472 413 -884 845 -462 875 -432 875 -468 381 -916 843 -460 415 -914 387 -908 395 -938 399 -892 863 -444 409 -902 405 -918 409 -898 407 -920 411 -878 417 -918 417 -880 839 -8254 439 -898 837 -448 411 -906 869 -454 845 -460 415 -882 881 -450 409 -914 845 -452 409 -914 843 -456 843 -458 843 -462 415 -914 843 -456 413 -912 387 -910 423 -908 415 -870 873 -460 413 -910 381 -906 411 -906 409 -906 411 -904 411 -904 411 -904 839 -8254 409 -882 865 -446 439 -874 889 -418 873 -458 417 -878 885 -454 +RAW_Data: 403 -884 857 -482 385 -918 843 -474 843 -468 839 -470 411 -906 837 -468 411 -904 379 -904 413 -900 415 -918 841 -474 381 -918 417 -912 385 -912 395 -900 451 -866 419 -918 417 -878 843 -8274 397 -896 865 -446 411 -904 871 -452 845 -458 417 -874 869 -458 415 -882 879 -454 417 -882 881 -448 837 -458 869 -432 413 -906 869 -434 413 -906 411 -904 411 -904 411 -904 869 -432 415 -916 387 -910 425 -908 415 -868 415 -908 415 -906 415 -876 879 -8236 409 -912 837 -454 451 -882 845 -452 875 -452 417 -890 849 -446 415 -896 877 -446 411 -900 841 -474 841 -470 839 -472 411 -904 839 -472 413 -886 415 -916 387 -904 411 -908 853 -448 409 -912 395 -900 435 -892 409 -916 407 -896 411 -912 409 -894 835 -8258 411 -890 871 -436 445 -888 841 -462 873 -430 413 -920 843 -456 409 -906 869 -430 415 -920 843 -454 869 -432 873 -434 413 -906 865 -470 411 -888 409 -884 449 -882 419 -890 845 -486 411 -870 437 -874 439 -870 439 -902 409 -902 409 -902 409 -902 839 -8252 405 -896 865 -446 441 -876 869 -454 845 -458 415 -882 879 -454 417 -882 879 -418 441 -882 881 -450 845 -456 867 -432 413 -906 869 -432 411 -906 409 -920 415 -884 425 -872 893 -412 439 -912 399 -892 409 -902 417 -900 421 -880 451 -878 413 -876 877 -8222 457 -886 845 -440 441 -880 869 -450 849 -450 415 -922 839 -472 411 -890 841 -462 413 -884 879 -452 869 -432 873 -434 413 -920 843 -458 409 -886 419 -912 417 -880 453 -882 847 -454 443 -880 399 -882 433 -884 427 -916 399 -886 429 -884 429 -886 853 -8258 423 -878 879 -454 403 -884 859 -452 877 -446 413 -888 873 -434 445 -890 843 -460 413 -884 879 -456 845 -458 867 -430 415 -920 843 -454 409 -920 385 -912 427 -872 435 -890 855 -456 419 -878 453 -876 415 -878 445 -878 439 -878 439 -880 401 -914 861 -8224 419 -906 845 -470 407 -902 841 -450 887 -418 451 -884 841 -474 413 -888 875 -432 413 -908 843 -460 867 -434 873 -436 443 -874 869 -436 443 -874 411 -920 415 -884 425 -874 893 -412 435 -894 441 -870 451 -862 419 -880 453 -876 417 -910 413 -878 869 -8234 457 -848 879 -456 403 -902 865 -452 847 -448 413 -896 877 -444 411 -900 873 -444 411 -902 841 -474 841 -472 839 -472 411 -890 845 -462 413 -884 421 -912 425 -872 437 -888 871 -418 445 -878 419 -914 419 -878 415 -910 413 -876 443 -880 439 -880 863 -8226 419 -904 841 -472 417 -872 879 -442 861 -450 423 -884 857 -450 451 -858 879 -448 411 -898 875 -444 +RAW_Data: 841 -474 837 -474 411 -902 839 -472 411 -902 411 -904 409 -872 443 -898 845 -448 415 -900 413 -898 425 -886 425 -888 425 -886 425 -886 423 -898 863 -8226 451 -872 877 -434 409 -904 873 -416 891 -420 453 -886 841 -474 411 -888 873 -430 413 -908 843 -460 869 -432 873 -436 445 -874 869 -436 443 -890 415 -884 423 -902 409 -904 867 -418 419 -912 425 -872 435 -894 409 -914 407 -898 411 -880 447 -880 851 -8230 457 -868 879 -452 417 -868 869 -452 849 -450 449 -858 877 -448 411 -896 877 -444 413 -900 875 -446 841 -438 875 -438 445 -890 845 -460 415 -882 421 -912 395 -898 439 -870 867 -450 425 -910 399 -894 405 -920 413 -878 419 -914 419 -878 415 -910 843 -8232 457 -886 845 -442 439 -876 869 -454 855 -448 415 -886 875 -438 443 -876 875 -434 413 -904 871 -432 873 -434 873 -436 445 -874 869 -436 413 -920 417 -880 423 -902 411 -904 867 -418 421 -912 427 -868 437 -890 409 -916 413 -876 419 -914 417 -876 879 -8234 423 -888 843 -456 449 -880 863 -420 881 -448 413 -902 843 -476 413 -888 877 -430 413 -886 877 -454 867 -432 873 -434 413 -918 845 -460 415 -882 423 -908 397 -898 437 -890 855 -426 447 -874 453 -876 415 -878 447 -878 441 -878 437 -880 435 -880 859 -8212 457 -884 847 -454 445 -880 863 -420 881 -448 411 -902 875 -442 411 -902 839 -474 411 -888 875 -430 875 -432 875 -432 413 -922 843 -458 417 -884 421 -910 397 -898 453 -864 879 -454 415 -878 439 -878 435 -880 435 -882 395 -902 437 -868 437 -870 871 -8244 421 -894 845 -470 409 -908 843 -456 857 -448 415 -890 871 -436 445 -890 843 -460 415 -882 881 -452 869 -428 867 -436 443 -888 841 -460 409 -918 417 -882 453 -844 447 -876 853 -454 449 -880 435 -878 403 -916 397 -914 397 -884 431 -884 429 -884 889 -8228 425 -878 879 -422 435 -886 855 -452 877 -448 413 -888 877 -432 413 -886 877 -454 409 -886 891 -446 855 -444 867 -456 415 -882 851 -448 439 -884 425 -902 409 -874 435 -892 867 -444 409 -910 427 -872 437 -888 411 -880 439 -892 419 -890 421 -878 879 -8234 421 -894 881 -434 409 -902 841 -456 859 -450 415 -900 885 -420 451 -886 839 -472 411 -900 847 -448 877 -446 841 -474 411 -890 845 -460 415 -884 421 -906 409 -912 397 -898 889 -420 447 -876 421 -880 455 -880 411 -878 443 -878 439 -880 435 -882 861 -8210 437 -896 865 -442 407 -908 867 -452 845 -458 415 -912 843 -454 409 -884 879 -452 407 -908 867 -432 873 -432 873 -432 415 -904 869 -434 +RAW_Data: 415 -904 411 -906 409 -906 409 -906 869 -430 415 -908 415 -880 439 -876 411 -906 411 -912 395 -898 437 -890 851 -8232 443 -890 845 -460 415 -884 879 -454 843 -458 415 -884 879 -454 409 -884 879 -448 409 -884 879 -454 841 -458 869 -432 413 -904 869 -434 413 -906 411 -904 409 -908 417 -882 881 -450 409 -880 441 -876 411 -910 425 -109718 133 -700 197 -334 133 -132 133 -166 131 -134 167 -200 427 -234 1129 -132 923 -100 22805 -66 22225 -66 655 -64 24395 -98 5203 -98 15817 -66 5793 -98 819 -98 4477 -66 12519 -68 64793 -66 425 -100 3651 -66 10365 -66 2361 -100 697 -66 13695 -100 15599 -66 1829 -100 21103 -66 40353 -64 1751 -98 14265 -132 54383 -66 2653 -98 13411 -66 15223 -66 8943 -892 857 -432 443 -876 843 -480 857 -452 421 -882 843 -474 413 -886 879 -432 415 -916 845 -454 837 -464 875 -432 415 -914 845 -458 411 -914 389 -908 427 -874 433 -894 867 -450 409 -898 409 -916 409 -896 417 -888 417 -880 449 -876 413 -908 839 -8254 415 -896 853 -470 407 -880 875 -450 853 -450 415 -920 843 -470 411 -872 869 -470 413 -888 843 -462 875 -430 875 -432 415 -918 847 -458 417 -880 425 -908 415 -904 407 -896 835 -456 443 -878 419 -882 449 -878 413 -908 413 -876 441 -876 439 -878 867 -8218 457 -886 845 -452 445 -876 865 -450 847 -450 417 -900 877 -444 413 -870 871 -440 441 -870 873 -438 873 -440 873 -438 443 -870 881 -446 417 -902 413 -902 417 -870 429 -886 891 -416 387 -978 355 -964 353 -930 387 -938 353 -942 385 -940 383 -912 845 -8258 421 -876 879 -422 469 -848 893 -420 843 -506 353 -944 813 -502 383 -912 849 -460 419 -904 837 -460 871 -466 843 -466 381 -900 875 -446 419 -912 383 -934 383 -914 415 -886 843 -462 411 -904 417 -916 417 -882 383 -964 343 -986 307 -982 345 -980 767 -8306 375 -934 839 -484 377 -932 837 -458 839 -466 407 -910 841 -478 395 -916 861 -446 421 -886 851 -448 877 -446 809 -536 353 -962 779 -502 385 -930 383 -936 387 -926 385 -926 815 -474 417 -914 381 -914 417 -912 419 -882 397 -900 405 -918 409 -898 861 -8248 437 -878 861 -450 419 -886 851 -448 877 -444 413 -884 873 -472 411 -886 845 -460 411 -916 847 -454 871 -430 877 -434 415 -916 845 -460 417 -880 423 -904 411 -908 399 -898 853 -454 415 -914 415 -882 415 -908 411 -910 409 -880 439 -878 435 -872 867 -8234 451 -864 875 -428 443 -876 875 -454 865 -482 355 -926 819 -504 355 -940 813 -504 385 -944 815 -488 819 -486 807 -492 387 -934 841 -458 +RAW_Data: 413 -914 389 -904 393 -932 411 -906 825 -480 381 -930 413 -908 413 -866 413 -914 415 -884 449 -876 411 -912 803 -8306 381 -934 827 -480 381 -932 709 -24288 131 -15484 407 -916 799 -514 373 -914 829 -500 793 -510 393 -910 855 -448 387 -912 881 -444 383 -948 789 -524 791 -524 825 -490 375 -936 811 -456 407 -920 411 -918 373 -946 373 -920 831 -478 399 -918 395 -916 395 -914 395 -914 427 -882 431 -880 397 -918 893 -8186 479 -826 881 -438 265 -5122 99 -604 291 -990 785 -540 321 -958 815 -504 813 -472 849 -440 411 -916 845 -450 437 -900 411 -888 415 -916 413 -884 841 -478 393 -916 431 -882 431 -878 431 -878 431 -872 437 -876 437 -876 863 -8226 451 -890 849 -488 369 -920 825 -478 819 -510 385 -912 845 -470 383 -908 845 -476 415 -884 845 -464 877 -432 875 -436 417 -914 843 -460 417 -906 411 -880 425 -908 397 -900 849 -454 417 -914 417 -878 415 -910 411 -912 407 -878 439 -878 439 -876 865 -8228 437 -894 853 -428 449 -878 881 -442 857 -454 423 -888 883 -418 415 -890 875 -438 445 -888 845 -456 869 -432 875 -436 445 -868 869 -438 445 -878 447 -870 409 -886 451 -874 865 -420 441 -886 421 -912 429 -870 441 -854 455 -852 455 -878 451 -840 907 -8212 437 -876 857 -456 415 -918 845 -454 867 -450 417 -886 853 -446 413 -920 843 -440 441 -872 871 -438 871 -472 839 -472 411 -888 843 -464 415 -904 409 -910 417 -876 409 -912 853 -446 411 -906 411 -910 427 -870 453 -866 415 -910 419 -878 449 -876 843 -8242 453 -868 873 -450 415 -880 867 -446 849 -484 383 -918 843 -474 409 -906 841 -470 411 -886 843 -464 875 -432 875 -434 415 -914 845 -458 417 -884 423 -902 411 -906 397 -898 867 -446 409 -906 407 -918 407 -898 409 -900 409 -918 407 -898 417 -888 845 -8236 453 -872 849 -486 411 -872 871 -446 853 -482 417 -890 847 -446 413 -896 875 -446 413 -900 851 -448 875 -444 875 -442 413 -898 841 -474 411 -902 411 -902 411 -904 413 -886 843 -462 417 -906 417 -882 423 -906 397 -900 407 -922 417 -890 419 -880 875 -8242 407 -904 867 -420 421 -906 869 -456 835 -462 409 -918 843 -460 409 -884 879 -452 411 -906 835 -462 869 -434 873 -438 445 -870 871 -438 413 -920 417 -878 423 -902 409 -906 857 -448 429 -872 437 -892 419 -892 419 -880 451 -874 413 -878 441 -868 873 -8250 421 -890 853 -438 439 -878 873 -452 855 -450 415 -888 873 -438 445 -888 843 -462 415 -882 883 -452 835 -462 869 -434 415 -918 843 -458 409 -908 417 -874 +RAW_Data: 439 -874 441 -876 869 -454 409 -908 415 -880 443 -880 427 -872 437 -894 409 -882 449 -878 877 -8236 415 -878 881 -452 411 -880 883 -450 837 -460 411 -916 847 -456 409 -914 845 -456 419 -880 851 -452 881 -452 837 -460 413 -914 843 -458 411 -916 387 -910 425 -906 415 -868 875 -460 415 -878 415 -908 413 -910 409 -878 439 -878 437 -880 437 -880 863 -8226 449 -878 853 -452 443 -878 861 -450 847 -450 415 -920 841 -438 445 -888 843 -462 415 -882 879 -454 867 -432 875 -432 415 -916 845 -460 417 -880 423 -904 409 -912 397 -900 867 -448 419 -890 419 -882 451 -876 415 -912 409 -880 439 -880 435 -872 867 -8242 409 -914 835 -442 451 -870 875 -460 845 -440 437 -902 839 -446 425 -904 863 -452 423 -888 851 -448 879 -444 845 -474 413 -886 843 -462 417 -916 387 -912 427 -872 451 -870 877 -432 441 -872 445 -872 411 -904 411 -904 409 -906 409 -904 411 -902 839 -8242 453 -866 877 -450 413 -874 871 -448 851 -484 383 -920 843 -472 413 -888 845 -462 415 -882 881 -452 837 -460 871 -436 413 -920 845 -460 415 -882 423 -902 411 -910 395 -902 861 -444 441 -874 437 -894 413 -882 419 -912 419 -880 415 -908 413 -880 869 -8228 457 -884 845 -442 435 -878 871 -452 853 -450 415 -896 881 -444 413 -904 841 -474 411 -884 879 -430 875 -432 875 -434 415 -904 869 -432 445 -888 417 -876 411 -906 411 -904 867 -452 411 -906 409 -882 421 -910 397 -900 451 -864 419 -882 449 -878 873 -8238 421 -890 843 -452 447 -878 865 -450 847 -450 415 -894 881 -444 413 -902 841 -474 413 -890 841 -462 869 -436 873 -436 415 -918 845 -462 409 -904 409 -916 387 -912 427 -872 863 -446 441 -872 451 -866 419 -912 419 -880 413 -908 413 -876 443 -880 867 -8224 447 -880 879 -430 445 -876 877 -422 859 -452 449 -860 875 -448 415 -898 851 -450 417 -894 875 -448 877 -446 841 -440 443 -890 877 -428 409 -904 411 -884 453 -880 425 -872 861 -446 441 -874 453 -866 415 -908 419 -880 451 -876 415 -876 443 -878 869 -8224 455 -884 843 -468 407 -906 841 -448 887 -448 417 -892 849 -448 415 -918 839 -472 413 -886 875 -432 845 -462 873 -432 411 -906 873 -434 415 -920 417 -880 425 -904 399 -898 865 -450 407 -902 415 -894 419 -912 417 -878 413 -908 413 -910 409 -878 869 -8234 449 -874 877 -450 413 -872 869 -448 883 -448 413 -872 889 -450 417 -890 847 -448 415 -920 841 -438 877 -436 875 -436 441 -874 873 -434 441 -872 441 -868 451 -884 413 -900 839 -476 413 -902 +RAW_Data: 411 -886 417 -884 421 -910 397 -900 451 -864 415 -910 843 -8248 445 -858 879 -458 417 -882 881 -418 879 -454 409 -882 881 -452 411 -882 883 -418 443 -874 867 -458 871 -434 875 -434 415 -918 845 -460 417 -878 421 -908 427 -872 451 -864 879 -450 417 -880 439 -880 437 -878 435 -880 401 -914 429 -870 435 -870 867 -8252 411 -886 877 -430 447 -876 879 -414 887 -452 419 -886 851 -448 447 -860 877 -446 413 -896 877 -444 873 -444 871 -442 409 -902 839 -474 409 -900 411 -902 409 -900 411 -900 875 -442 411 -902 409 -902 409 -904 409 -900 421 -888 423 -888 423 -890 849 -8264 421 -878 877 -454 401 -884 857 -452 879 -446 411 -900 875 -444 411 -900 839 -474 411 -900 839 -474 839 -474 839 -472 409 -906 839 -472 411 -872 445 -888 417 -874 441 -882 851 -450 423 -912 427 -868 439 -888 411 -882 453 -884 419 -876 449 -874 841 -8238 453 -888 843 -470 407 -904 839 -446 887 -450 415 -904 825 -482 417 -890 849 -448 415 -898 877 -446 845 -474 843 -470 381 -918 845 -460 417 -882 421 -908 427 -872 451 -866 873 -444 413 -908 417 -878 449 -876 413 -908 411 -876 441 -876 439 -878 865 -8234 417 -906 851 -440 437 -904 839 -448 885 -448 419 -890 847 -446 415 -900 857 -450 417 -918 843 -474 841 -472 843 -468 383 -916 869 -430 411 -904 411 -904 411 -902 411 -904 869 -430 443 -870 411 -904 411 -904 411 -902 411 -904 411 -906 409 -906 837 -8266 413 -904 873 -414 453 -870 867 -450 883 -414 447 -860 875 -448 411 -888 873 -440 441 -874 875 -436 873 -436 871 -436 443 -874 875 -436 443 -890 415 -876 423 -910 395 -902 863 -448 441 -872 439 -888 421 -888 419 -880 451 -874 413 -910 411 -874 869 -8234 447 -876 875 -432 445 -874 877 -454 829 -450 449 -890 847 -446 413 -898 877 -444 411 -904 843 -472 841 -474 843 -470 413 -868 875 -436 445 -888 417 -880 423 -910 415 -874 877 -428 447 -876 449 -874 413 -910 411 -876 441 -878 439 -880 437 -878 863 -8232 417 -910 845 -470 405 -904 839 -478 855 -448 421 -882 845 -476 415 -884 875 -432 415 -916 845 -456 839 -464 875 -434 417 -914 845 -458 409 -916 387 -912 425 -906 399 -894 853 -456 413 -916 415 -880 413 -910 411 -912 409 -880 435 -874 437 -872 865 -8248 453 -866 879 -402 475 -842 907 -422 859 -450 415 -886 873 -438 443 -866 879 -446 415 -896 877 -446 873 -444 841 -474 411 -890 843 -462 415 -882 421 -912 427 -872 437 -892 857 -428 447 -880 449 -878 411 -904 409 -872 441 -872 +RAW_Data: 441 -872 441 -872 871 -8252 413 -880 865 -446 439 -872 899 -416 867 -456 409 -904 869 -432 415 -886 877 -460 407 -904 867 -432 877 -434 875 -434 415 -916 845 -460 417 -882 423 -902 411 -902 411 -910 857 -444 411 -904 409 -904 411 -904 409 -902 411 -908 399 -894 407 -922 837 -8230 443 -902 873 -444 411 -898 871 -442 839 -442 443 -890 875 -432 415 -914 845 -456 409 -912 837 -462 845 -462 871 -432 415 -914 843 -462 409 -918 419 -878 409 -904 411 -902 869 -450 411 -880 423 -904 411 -904 409 -910 397 -896 407 -922 417 -890 851 -8226 463 -868 867 -448 415 -882 891 -420 879 -450 419 -886 851 -450 417 -920 839 -474 411 -890 877 -430 875 -432 877 -430 415 -904 869 -434 413 -906 409 -916 407 -906 409 -882 879 -418 443 -882 421 -912 397 -900 453 -862 421 -878 453 -874 449 -878 841 -8230 449 -876 879 -426 449 -876 881 -416 889 -418 447 -890 847 -450 449 -858 877 -446 413 -900 883 -418 879 -446 845 -474 409 -902 839 -474 409 -902 409 -900 411 -900 411 -888 873 -436 413 -920 417 -882 425 -870 453 -868 417 -906 415 -906 417 -874 875 -8238 425 -876 893 -418 445 -880 875 -440 877 -408 447 -874 877 -442 433 -870 871 -450 423 -882 889 -420 879 -446 877 -444 413 -900 839 -476 411 -888 415 -882 421 -912 429 -870 865 -446 453 -864 419 -882 449 -870 417 -910 411 -906 411 -904 407 -904 837 -8248 457 -864 875 -408 449 -874 881 -440 863 -454 427 -888 881 -416 417 -896 875 -446 413 -900 877 -444 841 -440 873 -440 445 -890 843 -460 415 -884 453 -880 429 -868 451 -866 875 -442 415 -874 449 -872 449 -872 447 -870 413 -902 413 -904 409 -904 873 -8206 449 -880 879 -452 415 -880 865 -450 845 -448 415 -894 875 -446 413 -902 853 -448 449 -858 877 -446 877 -444 875 -444 411 -888 877 -426 441 -874 409 -920 417 -880 425 -904 835 -448 441 -882 423 -904 407 -876 433 -900 409 -884 439 -896 411 -882 889 -8232 413 -886 867 -460 415 -884 881 -420 867 -462 415 -916 845 -454 409 -908 843 -460 409 -918 845 -454 869 -432 877 -432 413 -918 845 -460 417 -880 441 -880 451 -848 453 -888 851 -442 433 -880 439 -878 437 -880 435 -882 397 -902 435 -872 437 -874 869 -8244 441 -854 909 -420 415 -906 847 -440 877 -442 433 -870 871 -448 423 -882 891 -450 419 -886 851 -450 879 -446 843 -472 413 -872 875 -470 381 -918 417 -880 425 -906 399 -900 867 -448 409 -920 413 -880 417 -914 417 -878 415 -908 413 -880 439 -878 869 -8228 457 -852 +RAW_Data: 883 -456 405 -882 889 -420 883 -448 415 -888 875 -434 445 -872 869 -436 443 -892 843 -458 869 -432 873 -434 445 -870 871 -436 445 -874 441 -886 415 -876 441 -882 885 -418 425 -902 409 -912 397 -898 419 -894 421 -882 451 -880 413 -876 875 -8222 447 -884 855 -452 449 -878 865 -454 849 -450 413 -902 875 -444 413 -888 875 -432 415 -908 843 -462 875 -430 867 -436 445 -890 843 -458 407 -888 451 -874 411 -906 409 -912 855 -448 429 -874 437 -892 413 -880 455 -880 419 -876 449 -878 413 -876 871 -8238 449 -876 879 -420 449 -878 863 -420 875 -448 413 -894 877 -446 413 -898 875 -444 411 -898 875 -444 839 -474 839 -474 409 -888 877 -432 415 -918 417 -880 411 -884 447 -880 877 -452 417 -876 439 -878 437 -878 437 -878 435 -878 435 -880 433 -848 893 -8224 457 -848 885 -456 437 -870 865 -420 879 -450 445 -862 877 -448 413 -890 873 -432 441 -876 869 -436 869 -438 867 -440 441 -900 847 -450 415 -900 413 -890 445 -890 417 -882 851 -450 421 -910 397 -900 439 -888 409 -886 453 -880 419 -880 449 -876 841 -8234 447 -878 891 -432 443 -876 843 -456 891 -418 415 -898 885 -420 451 -854 879 -450 413 -890 873 -438 875 -436 873 -436 443 -892 843 -458 409 -886 451 -874 439 -884 427 -872 891 -420 451 -852 453 -878 449 -842 445 -878 441 -880 439 -880 431 -870 869 -8242 435 -874 857 -458 413 -910 845 -440 865 -454 431 -884 887 -418 449 -886 841 -472 413 -888 877 -430 869 -434 875 -438 413 -918 843 -460 415 -906 409 -910 387 -912 425 -870 867 -450 425 -904 409 -904 411 -904 409 -908 415 -874 419 -914 417 -880 875 -8236 437 -884 855 -444 441 -880 853 -446 869 -446 429 -872 887 -418 447 -878 877 -430 445 -876 875 -420 895 -420 879 -448 413 -902 875 -444 411 -892 415 -884 421 -912 399 -900 867 -448 455 -860 423 -876 453 -872 449 -844 443 -870 443 -870 443 -870 873 -8232 451 -874 889 -402 441 -876 877 -456 853 -452 413 -896 877 -448 413 -890 875 -434 413 -884 879 -460 875 -426 869 -434 445 -892 845 -458 415 -886 423 -908 417 -872 455 -882 845 -440 433 -904 411 -878 443 -880 437 -882 435 -882 431 -870 433 -874 867 -8242 455 -862 879 -452 415 -880 867 -452 853 -448 415 -900 873 -446 411 -900 849 -450 415 -896 875 -446 873 -444 875 -410 443 -876 873 -436 443 -892 415 -884 451 -848 449 -878 879 -434 441 -870 447 -870 413 -902 411 -902 413 -870 445 -870 443 -900 839 -8242 453 -872 881 -452 413 -872 869 -448 849 -450 +RAW_Data: 445 -870 889 -418 449 -892 847 -446 413 -896 879 -446 875 -442 843 -474 411 -888 845 -462 415 -884 423 -910 427 -870 451 -862 875 -428 443 -876 445 -872 413 -906 413 -904 411 -904 411 -904 409 -904 839 -8264 409 -884 887 -430 445 -876 843 -448 887 -450 417 -888 849 -448 449 -890 847 -446 413 -898 877 -444 871 -444 839 -474 411 -902 839 -474 409 -902 411 -900 409 -888 415 -884 881 -456 417 -882 423 -910 399 -898 419 -896 419 -880 453 -878 413 -878 875 -8236 449 -876 879 -434 441 -870 875 -414 889 -454 419 -890 845 -450 417 -886 871 -440 443 -868 879 -448 879 -444 843 -474 413 -888 845 -462 415 -882 421 -912 427 -872 437 -894 837 -454 449 -884 419 -880 415 -910 413 -878 443 -878 439 -880 437 -878 863 -8230 457 -848 879 -452 437 -872 865 -450 849 -450 415 -902 851 -450 417 -900 887 -418 451 -884 843 -474 839 -476 839 -472 411 -866 877 -448 415 -886 445 -888 417 -880 423 -910 853 -446 409 -912 395 -904 451 -866 415 -910 415 -874 449 -872 445 -874 873 -8212 455 -868 877 -428 445 -874 877 -446 863 -450 425 -882 843 -476 413 -904 839 -472 413 -888 875 -430 875 -432 875 -434 413 -904 873 -434 413 -904 411 -904 411 -916 417 -880 867 -456 409 -908 417 -876 409 -914 425 -872 451 -866 421 -882 415 -944 805 -8276 413 -900 839 -484 389 -908 855 -452 853 -450 425 -906 855 -450 395 -938 827 -448 435 -896 851 -456 841 -476 841 -468 407 -914 839 -452 429 -886 427 -884 427 -884 393 -982 757 -540 325 -992 357 -942 359 -942 355 -976 353 -944 353 -974 355 -942 813 -8292 405 -906 835 -450 431 -884 853 -480 847 -446 413 -886 875 -468 381 -920 845 -460 415 -916 845 -458 843 -458 869 -434 413 -920 843 -460 417 -878 411 -910 411 -908 427 -872 861 -446 441 -874 451 -866 419 -916 417 -878 415 -910 411 -880 443 -878 867 -8226 457 -882 851 -440 433 -904 837 -474 835 -446 427 -916 857 -450 419 -888 849 -448 415 -918 843 -472 845 -470 843 -470 383 -900 871 -468 381 -916 415 -884 423 -908 397 -902 863 -450 439 -874 437 -890 413 -882 419 -882 453 -876 449 -844 445 -876 871 -8232 451 -876 853 -450 445 -880 863 -452 853 -448 415 -886 871 -438 441 -886 871 -432 439 -890 845 -458 843 -460 871 -468 379 -898 879 -444 415 -918 381 -918 417 -880 423 -906 853 -450 427 -902 409 -908 399 -894 417 -894 419 -912 419 -876 415 -910 843 -8250 407 -902 851 -454 445 -878 841 -484 843 -452 427 -886 851 -482 385 -916 843 -472 +RAW_Data: 413 -886 843 -464 843 -466 845 -466 415 -916 847 -458 417 -880 425 -906 413 -100576 129 -4900 97 -1286 555 -132 65 -198 361 -132 98215 -96 21029 -64 5709 -66 22509 -98 23929 -66 4017 -66 687 -98 1353 -66 3641 -66 1391 -64 565 -66 40435 -102 51423 -66 10357 -66 10493 -98 5979 -66 22915 -100 1281 -100 62401 -66 26927 -66 20563 -100 4151 -100 12369 -66 45939 -858 863 -446 437 -894 853 -458 845 -452 449 -878 863 -454 421 -888 849 -448 415 -886 875 -470 841 -470 839 -472 411 -888 843 -464 415 -910 419 -880 425 -872 437 -894 871 -416 449 -882 419 -880 453 -876 415 -906 413 -876 443 -876 441 -878 865 -8230 457 -850 879 -440 449 -872 875 -438 873 -422 433 -882 887 -422 451 -854 875 -440 443 -892 845 -460 875 -428 871 -436 413 -906 869 -434 443 -868 449 -890 419 -884 413 -888 875 -434 415 -916 415 -876 411 -908 411 -910 427 -870 437 -894 409 -882 871 -8250 409 -900 875 -444 411 -888 875 -434 873 -434 445 -864 877 -446 415 -900 873 -446 411 -888 873 -434 871 -436 873 -436 445 -892 841 -458 409 -886 451 -882 453 -844 451 -874 845 -486 415 -878 439 -880 435 -880 401 -914 399 -914 399 -914 397 -904 863 -8224 457 -882 845 -452 441 -872 865 -450 847 -450 417 -918 841 -472 413 -888 841 -464 413 -910 845 -460 875 -432 877 -432 413 -908 843 -460 409 -918 417 -884 425 -874 435 -894 853 -456 417 -880 451 -876 413 -912 411 -904 411 -880 435 -872 439 -872 871 -8244 409 -916 835 -446 439 -904 837 -448 869 -456 411 -906 869 -430 415 -918 845 -458 415 -876 867 -460 875 -430 875 -432 415 -904 869 -434 413 -904 411 -904 409 -906 409 -906 867 -432 413 -906 409 -918 417 -882 425 -870 439 -872 439 -872 439 -904 865 -8220 439 -868 871 -450 423 -884 857 -450 881 -446 413 -902 843 -474 411 -888 877 -430 415 -908 843 -460 869 -434 871 -436 445 -874 869 -436 443 -876 409 -906 409 -906 409 -906 871 -432 415 -916 417 -882 425 -908 399 -896 409 -916 409 -896 411 -880 887 -8232 449 -844 867 -446 439 -872 893 -412 895 -446 429 -868 855 -456 451 -884 845 -442 435 -878 869 -454 853 -448 881 -444 413 -890 875 -432 413 -918 409 -874 441 -876 441 -878 867 -456 415 -882 423 -910 397 -900 437 -888 413 -880 455 -880 419 -876 877 -8238 421 -890 843 -488 413 -880 863 -450 847 -446 415 -892 879 -448 411 -898 875 -444 413 -900 841 -476 843 -472 841 -470 413 -888 843 -464 415 -906 409 -884 421 -908 397 -900 885 -420 445 -880 417 -914 419 -876 +RAW_Data: 415 -910 411 -880 441 -880 435 -872 867 -8254 421 -890 843 -444 445 -874 875 -442 865 -452 427 -890 849 -448 415 -918 841 -472 411 -886 841 -462 871 -434 873 -470 379 -920 843 -458 409 -900 413 -918 413 -886 415 -884 879 -452 409 -906 409 -884 421 -912 395 -900 437 -888 411 -880 441 -896 873 -8228 411 -902 843 -476 411 -888 877 -428 869 -434 415 -916 843 -460 415 -882 869 -458 409 -904 873 -432 875 -436 873 -436 413 -908 875 -430 413 -906 409 -886 419 -914 427 -872 889 -420 451 -882 419 -878 451 -876 415 -876 443 -878 439 -876 437 -878 869 -8228 421 -918 845 -452 403 -904 865 -444 853 -446 417 -924 847 -446 415 -920 839 -468 411 -904 841 -468 839 -468 839 -472 411 -902 841 -470 411 -904 411 -872 413 -902 413 -902 877 -434 411 -900 413 -906 411 -900 415 -916 379 -936 381 -916 415 -908 835 -8254 419 -910 841 -450 423 -884 855 -452 879 -448 417 -900 849 -448 415 -920 841 -472 411 -874 869 -438 871 -472 839 -470 411 -872 869 -440 445 -874 441 -866 449 -884 413 -888 875 -432 413 -906 409 -906 409 -906 409 -886 421 -908 427 -872 451 -866 875 -8236 415 -882 871 -460 417 -880 881 -454 845 -456 417 -880 879 -452 409 -884 881 -452 409 -880 881 -450 837 -462 871 -434 415 -914 845 -458 413 -916 387 -910 427 -904 401 -894 867 -450 411 -884 413 -908 419 -912 417 -876 415 -908 413 -910 409 -878 865 -8234 455 -882 843 -452 445 -880 859 -450 847 -446 415 -894 877 -444 415 -896 879 -444 413 -902 841 -472 841 -472 841 -472 411 -890 845 -462 415 -908 417 -876 411 -908 409 -912 851 -450 425 -908 399 -894 407 -904 437 -888 411 -880 447 -876 419 -880 881 -8238 439 -888 837 -456 451 -880 851 -452 871 -420 449 -892 845 -448 413 -894 879 -446 411 -900 875 -444 839 -474 837 -474 409 -904 839 -472 409 -902 411 -902 409 -904 409 -904 839 -472 409 -904 409 -872 443 -872 443 -890 417 -882 423 -910 417 -874 875 -8220 441 -904 841 -468 411 -904 841 -470 841 -470 413 -886 843 -462 417 -906 843 -458 411 -918 843 -456 869 -432 875 -434 415 -916 845 -456 411 -916 417 -876 411 -912 425 -870 889 -418 445 -882 421 -880 449 -878 415 -910 413 -878 441 -878 439 -880 865 -8230 417 -906 843 -468 407 -906 839 -478 857 -450 423 -884 843 -474 413 -886 877 -432 415 -916 845 -458 845 -460 871 -432 415 -916 845 -458 417 -916 387 -908 427 -870 437 -892 851 -458 415 -882 451 -876 413 -912 413 -878 439 -878 441 -880 435 -878 +RAW_Data: 863 -8240 423 -888 841 -486 415 -878 869 -452 849 -448 415 -920 841 -470 381 -920 845 -460 415 -910 843 -454 869 -432 873 -434 415 -904 869 -436 413 -920 417 -876 441 -880 425 -908 857 -444 409 -910 399 -898 417 -894 419 -882 451 -874 415 -908 413 -878 873 -8254 405 -898 853 -458 417 -914 847 -452 865 -452 421 -884 845 -474 413 -886 873 -430 411 -904 873 -432 871 -470 837 -470 413 -886 843 -460 413 -918 417 -874 413 -906 411 -910 851 -446 411 -914 425 -872 451 -866 417 -916 419 -878 415 -910 413 -878 871 -8228 455 -884 845 -452 445 -880 863 -450 851 -446 413 -920 841 -470 409 -874 873 -468 409 -872 873 -470 843 -470 839 -470 381 -918 843 -462 415 -912 411 -880 423 -906 397 -900 865 -446 419 -894 419 -912 419 -878 413 -910 411 -910 409 -880 441 -878 865 -8254 413 -878 877 -430 445 -880 841 -458 863 -452 415 -920 841 -438 415 -908 871 -434 413 -914 845 -458 871 -466 841 -470 413 -884 843 -460 409 -920 417 -880 425 -872 435 -894 867 -448 407 -902 409 -916 407 -896 407 -902 409 -886 439 -898 411 -880 875 -8248 411 -900 843 -476 413 -886 873 -432 875 -434 413 -918 843 -460 411 -916 845 -454 411 -918 845 -456 845 -460 841 -462 411 -916 843 -456 411 -916 417 -880 425 -908 399 -896 851 -456 415 -916 417 -880 415 -908 413 -880 439 -870 439 -904 407 -874 871 -8238 439 -868 869 -448 411 -906 869 -454 837 -460 411 -916 843 -458 411 -916 843 -456 409 -906 871 -432 873 -434 875 -434 413 -918 845 -458 411 -916 387 -910 425 -908 415 -870 875 -428 447 -880 415 -908 413 -880 439 -872 439 -872 441 -872 439 -872 871 -8246 419 -896 847 -486 413 -882 865 -448 849 -446 415 -928 845 -446 415 -886 875 -468 381 -916 843 -460 843 -464 877 -432 413 -916 843 -458 411 -916 385 -906 411 -910 425 -906 823 -478 411 -902 411 -904 411 -906 397 -898 407 -918 411 -880 417 -916 847 -8236 435 -892 867 -448 397 -898 869 -448 869 -456 417 -906 837 -460 415 -914 847 -456 387 -908 849 -482 837 -458 871 -430 415 -914 847 -458 411 -916 385 -902 411 -910 423 -904 839 -450 423 -910 395 -900 405 -922 417 -888 417 -912 417 -876 415 -910 841 -8264 421 -890 843 -452 445 -880 863 -448 849 -448 417 -918 841 -470 413 -886 871 -430 411 -904 873 -466 837 -470 841 -468 411 -904 839 -470 411 -902 411 -902 381 -918 417 -906 839 -460 415 -914 389 -908 427 -870 437 -892 409 -916 407 -896 409 -916 853 -8234 425 -906 825 -480 401 -894 +RAW_Data: 865 -450 851 -456 415 -918 845 -454 405 -902 865 -448 421 -902 829 -482 847 -446 875 -444 413 -898 845 -474 413 -902 411 -904 413 -904 383 -914 843 -462 411 -914 417 -880 423 -906 397 -900 405 -922 417 -890 417 -882 879 -8232 409 -904 871 -434 411 -904 871 -466 839 -470 381 -932 845 -446 415 -918 839 -470 381 -916 843 -460 873 -466 841 -468 381 -916 841 -460 413 -916 387 -910 423 -908 397 -896 869 -448 427 -906 399 -894 415 -894 417 -912 417 -880 415 -908 411 -882 869 -8228 455 -888 845 -452 409 -916 861 -450 847 -446 415 -896 877 -444 413 -902 853 -448 415 -894 879 -444 841 -476 843 -472 415 -902 839 -472 381 -914 417 -914 387 -910 395 -938 825 -446 437 -894 417 -892 417 -914 415 -876 413 -910 411 -910 409 -910 835 -8232 447 -878 853 -452 451 -880 863 -450 847 -448 413 -920 839 -472 411 -888 877 -430 415 -916 843 -456 843 -460 867 -436 443 -874 869 -436 443 -890 415 -884 421 -904 407 -912 855 -444 409 -906 409 -912 397 -898 439 -890 411 -880 453 -880 421 -872 879 -8246 417 -876 849 -482 411 -880 883 -450 837 -458 411 -916 847 -456 411 -916 847 -454 409 -916 845 -452 835 -462 875 -432 413 -916 843 -460 411 -912 409 -906 411 -878 421 -910 855 -446 411 -910 425 -872 435 -892 409 -918 413 -880 419 -880 451 -880 843 -8264 421 -890 843 -486 411 -872 867 -448 851 -448 417 -926 847 -444 415 -896 875 -442 415 -900 851 -448 877 -444 843 -476 415 -888 843 -462 415 -916 387 -910 425 -908 399 -894 867 -444 411 -908 395 -902 435 -894 417 -892 417 -882 451 -878 413 -878 871 -8250 405 -900 867 -448 409 -910 853 -446 869 -454 411 -914 845 -456 417 -880 881 -448 411 -880 881 -452 837 -460 873 -434 413 -916 845 -460 415 -882 421 -910 395 -902 437 -888 853 -458 415 -882 449 -878 413 -912 411 -880 439 -880 437 -878 435 -880 865 -8224 455 -884 843 -442 437 -878 869 -452 855 -448 415 -920 839 -472 413 -886 845 -462 417 -914 847 -454 869 -426 873 -434 415 -916 843 -460 409 -918 415 -882 425 -906 399 -896 865 -448 407 -902 439 -890 411 -880 417 -916 417 -878 417 -908 413 -880 873 -8230 457 -886 849 -452 407 -906 863 -450 849 -446 415 -894 877 -446 413 -898 877 -442 413 -904 839 -474 843 -472 843 -470 381 -918 843 -462 417 -914 387 -910 427 -872 435 -892 869 -450 407 -896 409 -900 407 -918 407 -896 409 -900 407 -918 407 -898 855 -8234 443 -892 845 -460 415 -916 845 -454 835 -462 417 -912 837 -460 +RAW_Data: 411 -916 843 -458 417 -914 845 -454 835 -462 871 -468 381 -914 871 -430 415 -918 387 -910 425 -906 399 -896 849 -474 407 -896 409 -902 407 -918 407 -898 409 -916 409 -894 409 -884 875 -8230 443 -874 873 -434 413 -920 841 -460 871 -432 413 -918 847 -456 411 -904 871 -430 415 -916 845 -458 845 -460 875 -432 415 -916 843 -456 411 -916 387 -910 425 -908 415 -870 851 -486 411 -872 439 -870 441 -872 439 -904 409 -878 439 -878 437 -878 865 -8230 455 -882 845 -442 437 -878 869 -452 855 -448 415 -920 843 -470 381 -918 845 -460 415 -912 845 -454 869 -432 873 -434 415 -916 845 -458 411 -914 387 -910 425 -902 411 -902 835 -450 441 -880 425 -902 411 -908 397 -894 409 -902 435 -890 419 -892 843 -8266 395 -900 865 -446 439 -890 835 -474 867 -442 409 -910 853 -446 411 -912 851 -450 425 -902 837 -448 869 -458 841 -462 411 -916 843 -456 411 -916 387 -910 425 -908 399 -896 855 -458 415 -914 419 -876 415 -912 411 -880 439 -878 437 -882 401 -912 865 -8226 419 -910 843 -452 447 -880 863 -452 849 -446 413 -898 875 -444 413 -900 875 -442 411 -904 841 -472 841 -472 839 -472 411 -890 843 -460 409 -906 409 -920 417 -880 425 -874 889 -418 445 -880 421 -880 453 -880 413 -910 413 -880 439 -878 437 -878 863 -8238 417 -904 843 -470 405 -902 841 -478 859 -448 421 -890 849 -448 415 -918 841 -472 413 -886 843 -462 869 -468 841 -470 381 -916 845 -460 411 -918 387 -910 425 -906 399 -894 851 -456 415 -916 417 -880 415 -910 411 -912 405 -904 409 -904 407 -904 839 -8246 441 -886 855 -430 449 -878 879 -416 889 -450 415 -900 861 -420 449 -868 889 -418 453 -886 841 -474 839 -472 843 -470 411 -898 845 -450 415 -898 413 -886 445 -874 441 -890 841 -458 409 -898 413 -920 411 -872 441 -890 415 -884 421 -910 397 -902 853 -8254 415 -898 879 -444 413 -904 841 -472 841 -472 413 -886 841 -462 411 -916 843 -458 409 -916 845 -458 841 -462 869 -436 413 -904 869 -470 379 -920 417 -876 421 -908 425 -872 889 -418 451 -884 419 -880 449 -874 415 -908 411 -878 443 -880 435 -872 865 -8226 455 -886 845 -450 445 -880 863 -452 853 -444 415 -918 841 -470 381 -916 845 -462 415 -914 845 -456 837 -460 871 -470 381 -916 843 -460 411 -914 417 -880 423 -902 409 -904 837 -484 389 -910 427 -904 399 -896 407 -916 409 -892 409 -918 409 -896 835 -8254 413 -896 879 -444 413 -900 843 -474 841 -472 411 -902 841 -472 409 -904 839 -472 411 -902 843 -468 +RAW_Data: 839 -472 843 -472 381 -916 843 -462 415 -918 387 -910 427 -870 435 -894 851 -456 415 -914 419 -880 413 -912 411 -880 441 -878 439 -880 401 -914 865 -8224 417 -908 843 -468 407 -904 839 -480 857 -448 421 -886 853 -448 417 -918 841 -472 413 -886 845 -462 867 -466 841 -470 381 -918 847 -460 415 -914 409 -878 413 -908 427 -906 825 -446 441 -902 409 -902 411 -908 397 -894 409 -900 417 -898 419 -914 843 -8246 425 -872 861 -480 399 -898 865 -448 867 -452 411 -880 881 -452 409 -908 845 -456 409 -914 835 -462 873 -432 877 -432 415 -904 869 -434 413 -916 417 -874 441 -880 411 -910 853 -448 411 -912 425 -872 451 -868 419 -914 419 -878 415 -908 411 -910 841 -8226 455 -886 843 -452 449 -878 863 -452 855 -446 415 -886 877 -434 415 -916 843 -462 415 -882 881 -454 845 -460 845 -460 411 -916 845 -456 411 -916 387 -910 425 -872 449 -870 875 -430 445 -880 413 -910 413 -878 441 -868 441 -872 441 -872 441 -902 841 -8246 421 -892 853 -452 443 -872 867 -448 849 -450 415 -926 847 -446 413 -898 877 -444 413 -900 845 -472 839 -470 839 -474 409 -902 843 -470 411 -872 445 -874 411 -904 411 -906 875 -432 413 -908 417 -884 423 -910 399 -898 407 -922 411 -880 445 -878 851 -8250 423 -904 857 -448 397 -902 853 -454 881 -430 443 -878 843 -478 431 -880 867 -450 423 -888 849 -448 843 -476 845 -474 413 -906 843 -470 381 -904 415 -914 417 -880 423 -902 837 -484 411 -878 425 -906 399 -896 405 -922 411 -916 381 -910 415 -910 841 -8232 453 -870 875 -430 447 -878 875 -442 841 -478 397 -912 861 -450 423 -886 845 -474 413 -906 841 -470 843 -470 839 -470 381 -916 843 -462 411 -918 387 -910 425 -902 411 -908 851 -450 411 -882 419 -914 417 -880 415 -908 415 -910 411 -878 439 -878 865 -8232 455 -882 845 -452 443 -880 861 -452 849 -448 417 -902 843 -474 413 -888 873 -430 411 -904 871 -434 869 -470 839 -472 409 -904 839 -470 413 -888 417 -906 411 -874 441 -876 869 -456 409 -886 419 -912 425 -870 451 -866 417 -908 415 -906 415 -872 877 -8248 407 -906 853 -446 411 -906 869 -452 847 -458 417 -880 883 -452 387 -912 851 -450 423 -906 853 -448 223 -124912 1217 -330 99 -132 163 -66 2031 -64 59635 -66 2765 -98 26085 -98 4367 -100 563 -66 24625 -66 1849 -66 10545 -68 21363 -66 15231 -100 42927 -100 3021 -66 55509 -100 4287 -66 2435 -98 1017 -132 3371 -66 11541 -100 1265 -100 799 -66 1859 -68 3385 -66 965 -100 2221 -100 2355 -68 6165 -66 1025 -100 +RAW_Data: 899 -66 173525 -166 2373 -68 397 -66 40101 -66 1891 -66 10969 -132 2617 -66 20187 -66 10559 -100 10491 -98 35135 -66 2287 -68 2649 -66 3393 -98 12375 -100 1265 -100 5605 -66 9997 -68 435 -132 16583 -100 3003 -66 10083 -64 13329 -66 64855 -100 13269 -132 10773 -100 4673 -17250 97 -1358 297 -164 165 -132 199 -66 199 -66 165 -664 65 -98 265 -66 201 -132 531 -132 235 -66 3355 -68 2757 -98 16517 -66 12659 -66 3773 -66 26419 -66 12433 -66 531 -100 20227 -66 1851 -66 11499 -64 10717 diff --git a/applications/debug/unit_tests/tests/subghz/subghz_test.c b/applications/debug/unit_tests/tests/subghz/subghz_test.c index a58875fe811..ae83ed562ec 100644 --- a/applications/debug/unit_tests/tests/subghz/subghz_test.c +++ b/applications/debug/unit_tests/tests/subghz/subghz_test.c @@ -17,7 +17,7 @@ #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 331 +#define TEST_RANDOM_COUNT_PARSE 328 #define TEST_TIMEOUT 10000 static SubGhzEnvironment* environment_handler; @@ -672,6 +672,62 @@ MU_TEST(subghz_decoder_dickert_test) { "Test decoder " SUBGHZ_PROTOCOL_DICKERT_MAHS_NAME " error\r\n"); } +MU_TEST(subghz_decoder_legrand_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/legrand_raw.sub"), SUBGHZ_PROTOCOL_LEGRAND_NAME), + "Test decoder " SUBGHZ_PROTOCOL_LEGRAND_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_marantec24_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/marantec24_raw.sub"), SUBGHZ_PROTOCOL_MARANTEC24_NAME), + "Test decoder " SUBGHZ_PROTOCOL_MARANTEC24_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_roger_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/roger_raw.sub"), SUBGHZ_PROTOCOL_ROGER_NAME), + "Test decoder " SUBGHZ_PROTOCOL_ROGER_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_feron_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/feron_raw.sub"), SUBGHZ_PROTOCOL_FERON_NAME), + "Test decoder " SUBGHZ_PROTOCOL_FERON_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_gangqi_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/gangqi_raw.sub"), SUBGHZ_PROTOCOL_GANGQI_NAME), + "Test decoder " SUBGHZ_PROTOCOL_GANGQI_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_hollarm_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/hollarm_raw.sub"), SUBGHZ_PROTOCOL_HOLLARM_NAME), + "Test decoder " SUBGHZ_PROTOCOL_HOLLARM_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_reversrb2_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/revers_rb2_raw.sub"), SUBGHZ_PROTOCOL_REVERSRB2_NAME), + "Test decoder " SUBGHZ_PROTOCOL_REVERSRB2_NAME " error\r\n"); +} + +MU_TEST(subghz_decoder_hay21_test) { + mu_assert( + subghz_decoder_test( + EXT_PATH("unit_tests/subghz/hay21_raw.sub"), SUBGHZ_PROTOCOL_HAY21_NAME), + "Test decoder " SUBGHZ_PROTOCOL_HAY21_NAME " error\r\n"); +} + //test encoders MU_TEST(subghz_encoder_princeton_test) { mu_assert( @@ -835,6 +891,48 @@ MU_TEST(subghz_encoder_dickert_test) { "Test encoder " SUBGHZ_PROTOCOL_DICKERT_MAHS_NAME " error\r\n"); } +MU_TEST(subghz_encoder_legrand_test) { + mu_assert( + subghz_encoder_test(EXT_PATH("unit_tests/subghz/legrand.sub")), + "Test encoder " SUBGHZ_PROTOCOL_LEGRAND_NAME " error\r\n"); +} + +MU_TEST(subghz_encoder_feron_test) { + mu_assert( + subghz_encoder_test(EXT_PATH("unit_tests/subghz/feron.sub")), + "Test encoder " SUBGHZ_PROTOCOL_FERON_NAME " error\r\n"); +} + +MU_TEST(subghz_encoder_gangqi_test) { + mu_assert( + subghz_encoder_test(EXT_PATH("unit_tests/subghz/gangqi.sub")), + "Test encoder " SUBGHZ_PROTOCOL_GANGQI_NAME " error\r\n"); +} + +MU_TEST(subghz_encoder_hollarm_test) { + mu_assert( + subghz_encoder_test(EXT_PATH("unit_tests/subghz/hollarm.sub")), + "Test encoder " SUBGHZ_PROTOCOL_HOLLARM_NAME " error\r\n"); +} + +MU_TEST(subghz_encoder_reversrb2_test) { + mu_assert( + subghz_encoder_test(EXT_PATH("unit_tests/subghz/revers_rb2.sub")), + "Test encoder " SUBGHZ_PROTOCOL_REVERSRB2_NAME " error\r\n"); +} + +MU_TEST(subghz_encoder_roger_test) { + mu_assert( + subghz_encoder_test(EXT_PATH("unit_tests/subghz/roger.sub")), + "Test encoder " SUBGHZ_PROTOCOL_ROGER_NAME " error\r\n"); +} + +MU_TEST(subghz_encoder_marantec24_test) { + mu_assert( + subghz_encoder_test(EXT_PATH("unit_tests/subghz/marantec24.sub")), + "Test encoder " SUBGHZ_PROTOCOL_MARANTEC24_NAME " error\r\n"); +} + MU_TEST(subghz_random_test) { mu_assert(subghz_decode_random_test(TEST_RANDOM_DIR_NAME), "Random test error\r\n"); } @@ -887,6 +985,14 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_decoder_kinggates_stylo4k_test); MU_RUN_TEST(subghz_decoder_mastercode_test); MU_RUN_TEST(subghz_decoder_dickert_test); + MU_RUN_TEST(subghz_decoder_roger_test); + MU_RUN_TEST(subghz_decoder_hollarm_test); + MU_RUN_TEST(subghz_decoder_reversrb2_test); + MU_RUN_TEST(subghz_decoder_gangqi_test); + MU_RUN_TEST(subghz_decoder_hay21_test); + MU_RUN_TEST(subghz_decoder_feron_test); + MU_RUN_TEST(subghz_decoder_legrand_test); + MU_RUN_TEST(subghz_decoder_marantec24_test); MU_RUN_TEST(subghz_encoder_princeton_test); MU_RUN_TEST(subghz_encoder_came_test); @@ -915,6 +1021,13 @@ MU_TEST_SUITE(subghz) { MU_RUN_TEST(subghz_encoder_dooya_test); MU_RUN_TEST(subghz_encoder_mastercode_test); MU_RUN_TEST(subghz_encoder_dickert_test); + MU_RUN_TEST(subghz_encoder_feron_test); + MU_RUN_TEST(subghz_encoder_roger_test); + MU_RUN_TEST(subghz_encoder_gangqi_test); + MU_RUN_TEST(subghz_encoder_marantec24_test); + MU_RUN_TEST(subghz_encoder_hollarm_test); + MU_RUN_TEST(subghz_encoder_reversrb2_test); + MU_RUN_TEST(subghz_encoder_legrand_test); MU_RUN_TEST(subghz_random_test); subghz_test_deinit(); diff --git a/applications/main/subghz/resources/subghz/assets/keeloq_mfcodes b/applications/main/subghz/resources/subghz/assets/keeloq_mfcodes index 39d9b3e3c95..b77080f8bbf 100644 --- a/applications/main/subghz/resources/subghz/assets/keeloq_mfcodes +++ b/applications/main/subghz/resources/subghz/assets/keeloq_mfcodes @@ -1,59 +1,66 @@ Filetype: Flipper SubGhz Keystore File Version: 0 Encryption: 1 -IV: 43 68 65 63 6B 20 70 61 73 73 65 64 20 4F 77 4F -00A92D8AE07E4998E826AF5C89AD659BD8C2BC6A40DA78B1AC05CF5B066243ED -A3C71FA36145D0EE56D78C05DDDDA97E487BCDCA6BDAC2C6F87402A0B20EE3CB -B9BDFBD18A63503580C18ABF84101B33D7F720900201510086EB3F0C1F533564 -EAB736F80371447008CC3BE3CE952CE429E7BF743A70C7CC62FF415B9E38467B -9C50D75C6E4A82F49AF285EC3545E58F8815FF4FCF5C9FFFCF0151FB693413FF13B594C8A28077450C8E561B0272C264 -A54C7E6DD1CAE0758F7A123B187C6EDA5BF3789969FE1E5F5A167E2DA7719671 -1461891D4AB3500B5BC0859166377CE098C04AAF6FD721F9C58A155F23F8E75A -BD1FD5645367BA76D8A87C271FF71E71C407B276BB0B165AF8CF6317250B77A6 -B18718EA6EB53CCDF9C26FC46E36D17234D93EF578376123B1F3F9953302CF62 -B633458C1948BC65357904F901F6DD5CD9D795887C176C6AA48E477F0EB693DB -B1352AC0DE8EBDD838F5DF7E040B062CF8FBB73180F3E712C5B2BDBFE1257A2C18694C51F242BCEA62DF317708771AA1 -842294FA0BACCD5B7710F002E40E4BB6142BC7C3125B2E56D4431FD8D6DD1CCE3397A4EB502B9E4248FA68CE8013E93D -5379E56AD483C0F870D9446C9CDE65ACA40C3A699D0653EC2F356A076D72D6C2 -8FD394F533CD2B03AE247B18F4A5214ED0AF64892F497362129FEF5837012BE4 -FA8BAB9CD11B306F9FCD924B3A66C678A0316F048A30312B5FA69B9E86EDD8C9 -35D6E447F3B8BA11331805027BCA1D972E9B29E07F1D2993C974DCAF5EE1EB76 -5FBF06E449C471D0AE2DECD141B937666C30EE72273CF58A99E19DCF5D2F69A703F17880B5FB1873480AFA82E2CE7674 -06C1463057544BDB86BD91B3BCC507FD3A5939CFF3315AFD252511FE4F6109EC -9AB5C03053AF5836E71FE27D0CD74515C967273EB240B7C37825B94D9D9F08AC -66EB1C65F32D5DBDC37B5FF7ACD7C4273B88298E8F0BED08F533F41F38DE651010686B79623804F67398B020E109B9A4 -7B1846759EDD928EF35B2E8FB7E3FFFE545C9A8B349476A9CE2BDDE55CE0E97F53002A543D0FB738CA67490501629296 -EB61CB652F414A70441ADACA46DBCC78A5AAC7A2ED4527AA2A93995482985867 -1E119E453C38C3242EFE3D9A3BBB3D257D91D15710C47811C1ADA934515DBD9E -6D8B689C37F7CFD52123BA77B6A4FABB16C3D22BF66FB78B4387BDBC975A3EE5 -997A46848917B76A1D728DA8C3A072F16F020AF50070BAD91AC2D841FA9805C1 -C51BFD0B93FECC7234D342F1DA785736A9229A21ACA8C9AA171906AA8916856F -86188B0DF2C25CA48DC0ED0B4524C17D93585873877FAFBBB55EB24A1D6FDABC -8178B7DFF235094BDCA1E5D72E48B113F2290C0FEBC95CF842013AB9CD84E0AD -25AEF7C490788DCC142CBC96FBCAB598B7EA1D15B7DE4ABBF75DE70832B519E4 -8C5FB85C16C5C833E1D8CE13A9432009D98B0D1639EB0C7C86D0AF4ACD7EB694 -AC9422E946BB8482CFD808B8E17BE01D9F5D9AB49E1192174A04BB0F032F2182 -793EEE939544D18C547E2198FA6F4A72D518C15C14146FC6CAD6AB642A3C9824 -C910617B5DC2C3137E96AC1869B7C5E90A1585181CC1B585C4CACC2624B7A72A -0AAEBC3463300A0391C2B2B14865A68EF44EAE8B1C2462B2730E28B25881B6462B3CCA631DC8A750F97EF5003E6B3060 -0861D4A3FE5970BB36BF8B525C69009212520A3B79F48ACEC6CB8F6DF96D913F -6327F56523F609D4ABC552912EF808E5919EA42104137AD206EF93AA4B34C097 -F88B71DAE547754731CD1C45ACBC355E52FE6D7B984A27B454DD7E8BFF12A023 -824025D56ED8B11BB65722F8C04168767D059BEB156B183D718CFB6AA38B9D81 -66E60820D0A6C452D9E209FB56FE3F49CAEFCBDC6116177063E0759FA11FDC8F -52D6ACA1A6928C52462BABD9A76628B25A2B913FC5BE316A9248C90B6F952529 -6FF5E9DAC956EF849FB58C11948C6F00743E157A8C2C631769EFCD80BAA3C048E10E682437EB53ED906C3060CCC7FECC -42757F22BDC1059154C41EDEE74E227E6D980F39939D3AA78FEC3F4DC303BE87 -689C2694447C4FF56C85B60E9FA66CD70A7EB9703A7C0202AD34374E9B290178 -E1A8E0ACF1E30714A7E580CA6380879C48992BA93A1637F24A66E15A03509B96 -5E1176A42E6C0DCF80E7B445372E3C054875A39D5F7A8B9C35985EDB46F65BB0 -12A6349CB3EC6D79B3C85052D6155730A036AF7F54BCD8CC9EC8F36557005D5E -B6D3D039D8B6D6F298665B16EBCB908D5F64D37C31F583C4F660AC0535DEC2DD -327BEE9B3E7A989B49787DE9D0C573C97343D79527FA6F442F8BDA0B9336E666 -1BDEDA4766FB3EFC1867836267E632B12020262B1EABA4BD31F9AB20DE49632A -8DE80C00CAD7F6E555713414DE8CE56B1C8603777F38F553F528907FA25E153EA5D3459739C66B46F6854A75F19A1511 -3A07DD2876F794FDF920F5D7B50A6D15C618FCF02F064E5AD5871C5B098EE8EC -66B7166156874006B35AF6997F61B84F016868FBAD283304B256F3DA065E65E3 -1E6D841D11C065F88B3F52EF60862E579E717E6AEFABF6A79FCF90D0810B35BB -B3B168E2532A6B659503736AA8933FB01A88DB9EA339C1C19EF7566600312B26 -974628362FD1951C207BDC3F5363F2747BAFA14ED7155772ADAA2FE8D1F7DC702F8DDB8CB4C17DBA803EC0DB6CDA43AC +IV: 48 69 69 69 2C 20 4D 69 73 68 61 21 21 30 31 21 +5914BA15A974B44BBF5886001E9CA8C05FED2B9A46D16F862484BC4760201A72 +885AB8E254F1403894740B50C6943A5F0A426C79CD8FA11D16915455E6B9ACE8 +48106C10911CC932FCAB49A793B6777DE845AA0D383E1B8D9FAE04E4F943FC60 +C1B81F527CF227F8A8D342BBB86EFBD95C99BFE3E3F55FFF19CF66C03CDB8779 +3DAB5A367DC19D412E9D71A89852E246DDEC0E97D7F7CE77DEE4043D9A99A1DEC4BDCA38B728CDC7BCB9E112044DCB8B +8E718417DD703259B6EBBB799EC8ED428C6D65115023C1421C349DDB70359929 +DB110804D813EB3D2F04F5723305CFA13778D46DD261D246B05DB257535C9520 +135BEFEEBEBF17665C27951E43639A82AD5B15EFAD7D1D776ACF1070E5E81F9C +996528B0D85E81D1AB47FECB2A5C2B63AFF35281EE41E316D26E34BB7E0E5EFE +BA220B2E219DE8045F6C5C4D8B4CABFB9944252ACB82755907C44E09071A0F90 +C4509ACDC858711F42B96AA40B0FEC58566E71D91E1D167835B97D13A9C6B4FD63F62D911E17C15081ED1FFBA00E08D0 +499D1031FDC6B5D6109D4A9046599FEC77F1DB26FCA809235803CE5F670F2BF1622042AB04F768CB4BBB8E93595B229A +43107EA4D34AC00BD05F45CF7AB077742C06A3619B3E258389EFF2D8ED057570 +A2ED253FB0CE66CDE2FF3921BE78662A97A23C344A83493D36CE6CC5ACC3A821 +963B48D299D6935B228A3BFCB86CF75F11A30850A19E014E31E6559F7A9A7DA8 +35D23E9D1D85AA0273A13B887EFBE9F55DD2E6C85B14F7E1100A66892F2A05BE +F3134F0E2545623B439D581F2A42F6F4CE0512622B6E53937DFBE353C26DF2E7E69871412C0221D8CCCBB1948715CB3C +C7E5A6E301B8E18BD3B15748A2A74AA1A939073FFE2F4A126213C49567D5BE44 +6E60F1421A27CEA2521C1EFE014EE2036F706ED734C12A794EBE3EFFACEA59C4 +9B60C596CE660E6A582AEC2C2804188EDD3C7636A3BC0E423A8D969F083319BB5AB90BE0DF3470BADB8D23E5AE0832EC +001C3E6E3A36954427626FC4F2CC9DA39983C945F745EC9F25B11814D8EDB233AFFA0FD3C0B9B4D22EAFA951E734FBFD +C03C3CC316F88E71C2A41B4B947FDF3FFCB46E103AFC420B820D757DCF7C46B6 +5430C52B29FDE8A436C745C1821BA6CDE9FB42C297C0407F1BC185B137485ABB +F9EE48BC297FE3866E2BFBFEC341CFD57150088F88A06725ADFCAD891F9FF9F1 +E0BB992BDBFA5A2369A1DAEF6316F1779C16A33FE03F1A4A42C86B7FAA80A8B1 +747863CCE4A663B2C4C7533733CCD604C271C8BF65066E219C427C7208DCA9D5 +8C05EF25D017E06ED6D2818B4EAC50E56727FA84039FFE119837C2E5933EB3CD +17C31C9451349E42F010F0E7540D71567485FC7D5E9CFCFEAB0E7AA3FEA8E3AE +76D5BF46CE39C37F09549D281C5FDB5EC12CAA73152E3B295E439091365EEEF1 +0B7B9F563A09D953BC6DD141A1313B9CCB52CE5406ED727DE965CE920F0CA5DC +78C9F207EBE8942DCF78A345A8E56B9C6C75D63C110250377D6C04DBB4DC15EA +3518584CFE8238E0AFA1E6F4CDF1E1A2A6349A7D2D641404067BA482DA4C6345 +F3CD339419BFF39EFF2F2F0E7C06BB0537B238427345011436EF4F28D2FB4D02 +96A25E27313CC92A48B515143643D235C28DDCB53AECCFCFC7792A417FC78CCC +11D553C6363F1C53B0074DF36C5256C9695CEA3006AC8737689694848C14FE93F15925BE58AB9D063D06FD87C0F7E637 +81BE95390E912466EAA1465BA7E316D662D7FDCE4DA91D79551247BCBE0FD66E +D2DA1301B149C17E4E579266D0AD810E8043AC1F16781F7743FAFB61B0A74D14 +C4921F5E174C988212CB46362FABB6B99599537C4E5B983016463ACF11AFA9F9 +F1333F4B1706326B776A6701E4457A18A0E262EDEC1758D3A696741094EAE7C8 +6F3647542899B48A53A829FF3CE82B22A75AA9AB3D3E01BF33C6B3D1F0C9BF3D +C42ACCF63F19E529E0D6A9AD9D2505F103D734248DAC0E9F2FCA35EC3F86C0A3 +1C0370E20EDBF342A76B1B65F0DB7C66F870ABB56E848159A0DB6585749F57B36EF4E18F730B5D0A2732C03ED74ECF72 +C61D01023FBDD674B09C6FFDB38A6F152F3B5C3203AFE4CA014C28600670922C +6C5507A0AF35860EA2EAD029A6ED19AEFE2AD90B15B2EEFD65B1F14747C1EA66 +1C908E924A1BE763868ADB985DE4BB157CEF7BA96E58CED46BE08816E7D92239 +A3E883AC3AE22373815F2C02F6B808B0DD36FCE27BDF22C262FDBFC5D1B03153 +7CC9A80338315C477B55B4024324F2EAA56A770675F2229D32B44E304214059D +D9CF90A9C4B60860355301A842323D8E207473D4A5631067E5DF2BFFD5A0E38E +824D256362207A507DD40C13D765B1BA172C1E2AAA09DB164028CE094BFF33A8 +8F04BFBD27084AC2FEA04D18F88E98E3F4AE979B40343E2D55C20173EB5030B6 +D28B98D9030AC29D79B974FCDF176C19EF6998DB776D5A8B067F1F6908B951F7 +B7AA60298EB22D45A182A6E8BC76C7AD04334BE7D26746455C5CA44BC7D34B38 +C79E0C38724D4ED317A0507C3981DC4E3AFA84F039FF9595FDE4C4C81F3332A3 +F30A3803C59558A0FD41B15E45B133B901E0C66D898B10A2EF5189BC36EAE904 +3F2CFFEE683A76EB9FDD84E99CE0C0FCFFC1B5ECA9C8677CACA2F6E33A773823 +EDBC9BF637AFFB3F8BC0A90A4B8F56D452F64949E865855DC51882B6F0889E64 +C4234CE6419E399A6415EBC80FEF6049A3EF345D4D0692784BB58626241291A37C080BCEEFB71B135368E4E3790C93B3 +C1231A97B5642D908BD9524B482801A63F6AF3E25EF69F51C495EABF5C967238 +651FF3C3EB76F90CD8BC02A0884E4C830A2794F8CE2467CC2FA2E74D081D6567 +65CCA76B05D06AC1346B23BFE435864B648247075385B74AAE53C4006560854F +2C19A88D52E56B9E09574F3B0B05A1AB3F417D47F78DCEDB9F6593EE01FD9540 +D46CF8835857552C4E77C8B37D79A6DE133ECEFD234CCD2278C78872EBAFFF2DAD0571FEFDA998031A235673CF6F2EA2 diff --git a/lib/subghz/protocols/alutech_at_4n.h b/lib/subghz/protocols/alutech_at_4n.h index 189f2f0d8b4..871ece0ad69 100644 --- a/lib/subghz/protocols/alutech_at_4n.h +++ b/lib/subghz/protocols/alutech_at_4n.h @@ -1,7 +1,7 @@ #pragma once #include "base.h" -#define SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME "Alutech at-4n" +#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; diff --git a/lib/subghz/protocols/came.c b/lib/subghz/protocols/came.c index bbe3e487fe0..c3d9c8662d9 100644 --- a/lib/subghz/protocols/came.c +++ b/lib/subghz/protocols/came.c @@ -244,8 +244,11 @@ void subghz_protocol_decoder_came_feed(void* context, bool level, uint32_t durat switch(instance->decoder.parser_step) { case CameDecoderStepReset: if((!level) && (DURATION_DIFF(duration, subghz_protocol_came_const.te_short * 56) < - subghz_protocol_came_const.te_delta * 47)) { + subghz_protocol_came_const.te_delta * 63)) { + // 17920 us + 7050 us = 24970 us max possible value old one + // delta = 150 us x 63 = 9450 us + 17920 us = 27370 us max possible value //Found header CAME + // 26700 us or 24000 us max possible values instance->decoder.parser_step = CameDecoderStepFoundStartBit; } break; diff --git a/lib/subghz/protocols/came_twee.c b/lib/subghz/protocols/came_twee.c index 1d79d2201e2..2369e854d03 100644 --- a/lib/subghz/protocols/came_twee.c +++ b/lib/subghz/protocols/came_twee.c @@ -260,6 +260,7 @@ SubGhzProtocolStatus subghz_protocol_came_twee_remote_controller(&instance->generic); subghz_protocol_encoder_came_twee_get_upload(instance); + instance->encoder.front = 0; // reset position before start instance->encoder.is_running = true; } while(false); @@ -269,6 +270,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_came_twee_stop(void* context) { SubGhzProtocolEncoderCameTwee* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position } LevelDuration subghz_protocol_encoder_came_twee_yield(void* context) { diff --git a/lib/subghz/protocols/dooya.c b/lib/subghz/protocols/dooya.c index 47e95209e54..816847840fc 100644 --- a/lib/subghz/protocols/dooya.c +++ b/lib/subghz/protocols/dooya.c @@ -308,7 +308,7 @@ void subghz_protocol_decoder_dooya_feed(void* context, bool level, uint32_t dura * Analysis of received data * @param instance Pointer to a SubGhzBlockGeneric* instance */ -static void subghz_protocol_somfy_telis_check_remote_controller(SubGhzBlockGeneric* instance) { +static void subghz_protocol_dooya_check_remote_controller(SubGhzBlockGeneric* instance) { /* * serial s/m ch key * long press down X * E1DC030533, 40b 111000011101110000000011 0000 0101 0011 0011 @@ -416,7 +416,7 @@ void subghz_protocol_decoder_dooya_get_string(void* context, FuriString* output) furi_assert(context); SubGhzProtocolDecoderDooya* instance = context; - subghz_protocol_somfy_telis_check_remote_controller(&instance->generic); + subghz_protocol_dooya_check_remote_controller(&instance->generic); furi_string_cat_printf( output, diff --git a/lib/subghz/protocols/feron.c b/lib/subghz/protocols/feron.c new file mode 100644 index 00000000000..855856f51b6 --- /dev/null +++ b/lib/subghz/protocols/feron.c @@ -0,0 +1,352 @@ +#include "feron.h" +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolFeron" + +static const SubGhzBlockConst subghz_protocol_feron_const = { + .te_short = 350, + .te_long = 750, + .te_delta = 150, + .min_count_bit_for_found = 32, +}; + +struct SubGhzProtocolDecoderFeron { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; +}; + +struct SubGhzProtocolEncoderFeron { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + FeronDecoderStepReset = 0, + FeronDecoderStepSaveDuration, + FeronDecoderStepCheckDuration, +} FeronDecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_feron_decoder = { + .alloc = subghz_protocol_decoder_feron_alloc, + .free = subghz_protocol_decoder_feron_free, + + .feed = subghz_protocol_decoder_feron_feed, + .reset = subghz_protocol_decoder_feron_reset, + + .get_hash_data = subghz_protocol_decoder_feron_get_hash_data, + .serialize = subghz_protocol_decoder_feron_serialize, + .deserialize = subghz_protocol_decoder_feron_deserialize, + .get_string = subghz_protocol_decoder_feron_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_feron_encoder = { + .alloc = subghz_protocol_encoder_feron_alloc, + .free = subghz_protocol_encoder_feron_free, + + .deserialize = subghz_protocol_encoder_feron_deserialize, + .stop = subghz_protocol_encoder_feron_stop, + .yield = subghz_protocol_encoder_feron_yield, +}; + +const SubGhzProtocol subghz_protocol_feron = { + .name = SUBGHZ_PROTOCOL_FERON_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | + SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_feron_decoder, + .encoder = &subghz_protocol_feron_encoder, +}; + +void* subghz_protocol_encoder_feron_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderFeron* instance = malloc(sizeof(SubGhzProtocolEncoderFeron)); + + instance->base.protocol = &subghz_protocol_feron; + instance->generic.protocol_name = instance->base.protocol->name; + + 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_feron_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderFeron* instance = context; + free(instance->encoder.upload); + free(instance); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderFeron instance + */ +static void subghz_protocol_encoder_feron_get_upload(SubGhzProtocolEncoderFeron* instance) { + furi_assert(instance); + size_t index = 0; + + // Send key and GAP + 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_feron_const.te_long); + if(i == 1) { + //Send 500/500 and gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_feron_const.te_short + 150); + instance->encoder.upload[index++] = level_duration_make( + true, (uint32_t)subghz_protocol_feron_const.te_short + 150); + // Gap + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_feron_const.te_long * 6); + } else { + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_feron_const.te_short); + } + } else { + // Send bit 0 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_feron_const.te_short); + if(i == 1) { + //Send 500/500 and gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_feron_const.te_short + 150); + instance->encoder.upload[index++] = level_duration_make( + true, (uint32_t)subghz_protocol_feron_const.te_short + 150); + // Gap + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_feron_const.te_long * 6); + } else { + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_feron_const.te_long); + } + } + } + + instance->encoder.size_upload = index; + return; +} + +/** + * Analysis of received data + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_feron_check_remote_controller(SubGhzBlockGeneric* instance) { + instance->serial = instance->data >> 16; +} + +SubGhzProtocolStatus + subghz_protocol_encoder_feron_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderFeron* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_feron_const.min_count_bit_for_found); + if(ret != SubGhzProtocolStatusOk) { + break; + } + //optional parameter parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + subghz_protocol_feron_check_remote_controller(&instance->generic); + subghz_protocol_encoder_feron_get_upload(instance); + instance->encoder.front = 0; + instance->encoder.is_running = true; + } while(false); + + return ret; +} + +void subghz_protocol_encoder_feron_stop(void* context) { + SubGhzProtocolEncoderFeron* instance = context; + instance->encoder.is_running = false; + instance->encoder.front = 0; +} + +LevelDuration subghz_protocol_encoder_feron_yield(void* context) { + SubGhzProtocolEncoderFeron* 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_feron_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderFeron* instance = malloc(sizeof(SubGhzProtocolDecoderFeron)); + instance->base.protocol = &subghz_protocol_feron; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_feron_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderFeron* instance = context; + free(instance); +} + +void subghz_protocol_decoder_feron_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderFeron* instance = context; + instance->decoder.parser_step = FeronDecoderStepReset; +} + +void subghz_protocol_decoder_feron_feed(void* context, bool level, volatile uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderFeron* instance = context; + + // Feron Decoder + // 2025.04 - @xMasterX (MMX) + + // Key samples + /* + 0110001100111000 1000010101111010 - ON + 0110001100111000 1000010001111011 - OFF + + 0110001100111000 1000011001111001 - brightness up + 0110001100111000 1000011101111000 - brightness down + + 0110001100111000 1000001001111101 - scroll mode command + + ------------------------------------------ + 0110001100111000 0111000010001111 - R + 0110001100111000 0001101011100101 - B + 0110001100111000 0100000010111111 - G + */ + + switch(instance->decoder.parser_step) { + case FeronDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_feron_const.te_long * 6) < + subghz_protocol_feron_const.te_delta * 4)) { + //Found GAP + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = FeronDecoderStepSaveDuration; + } + break; + case FeronDecoderStepSaveDuration: + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = FeronDecoderStepCheckDuration; + } else { + instance->decoder.parser_step = FeronDecoderStepReset; + } + break; + case FeronDecoderStepCheckDuration: + if(!level) { + // Bit 0 is short and long timing = 350us HIGH (te_last) and 750us LOW + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_feron_const.te_short) < + subghz_protocol_feron_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_feron_const.te_long) < + subghz_protocol_feron_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = FeronDecoderStepSaveDuration; + // Bit 1 is long and short timing = 750us HIGH (te_last) and 350us LOW + } else if( + (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_feron_const.te_long) < + subghz_protocol_feron_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_feron_const.te_short) < + subghz_protocol_feron_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = FeronDecoderStepSaveDuration; + } else if( + // End of the key 500Low(we are here)/500High us + DURATION_DIFF( + duration, (uint16_t)(subghz_protocol_feron_const.te_short + (uint16_t)150)) < + subghz_protocol_feron_const.te_delta) { + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_feron_const.te_short) < + subghz_protocol_feron_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + } + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_feron_const.te_long) < + subghz_protocol_feron_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + } + // If got 32 bits key reading is finished + if(instance->decoder.decode_count_bit == + subghz_protocol_feron_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; + instance->decoder.parser_step = FeronDecoderStepReset; + } else { + instance->decoder.parser_step = FeronDecoderStepReset; + } + } else { + instance->decoder.parser_step = FeronDecoderStepReset; + } + break; + } +} + +uint8_t subghz_protocol_decoder_feron_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderFeron* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_feron_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderFeron* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + subghz_protocol_decoder_feron_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderFeron* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, flipper_format, subghz_protocol_feron_const.min_count_bit_for_found); +} + +void subghz_protocol_decoder_feron_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderFeron* instance = context; + + subghz_protocol_feron_check_remote_controller(&instance->generic); + + furi_string_cat_printf( + output, + "%s %db\r\n" + "Key: 0x%08lX\r\n" + "Serial: 0x%04lX\r\n" + "Command: 0x%04lX\r\n", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data & 0xFFFFFFFF), + instance->generic.serial, + (uint32_t)(instance->generic.data & 0xFFFF)); +} diff --git a/lib/subghz/protocols/feron.h b/lib/subghz/protocols/feron.h new file mode 100644 index 00000000000..97f0eb6fe8c --- /dev/null +++ b/lib/subghz/protocols/feron.h @@ -0,0 +1,109 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_FERON_NAME "Feron" + +typedef struct SubGhzProtocolDecoderFeron SubGhzProtocolDecoderFeron; +typedef struct SubGhzProtocolEncoderFeron SubGhzProtocolEncoderFeron; + +extern const SubGhzProtocolDecoder subghz_protocol_feron_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_feron_encoder; +extern const SubGhzProtocol subghz_protocol_feron; + +/** + * Allocate SubGhzProtocolEncoderFeron. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderFeron* pointer to a SubGhzProtocolEncoderFeron instance + */ +void* subghz_protocol_encoder_feron_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderFeron. + * @param context Pointer to a SubGhzProtocolEncoderFeron instance + */ +void subghz_protocol_encoder_feron_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderFeron instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_encoder_feron_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderFeron instance + */ +void subghz_protocol_encoder_feron_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderFeron instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_feron_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderFeron. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderFeron* pointer to a SubGhzProtocolDecoderFeron instance + */ +void* subghz_protocol_decoder_feron_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderFeron. + * @param context Pointer to a SubGhzProtocolDecoderFeron instance + */ +void subghz_protocol_decoder_feron_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderFeron. + * @param context Pointer to a SubGhzProtocolDecoderFeron instance + */ +void subghz_protocol_decoder_feron_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderFeron instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_feron_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderFeron instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_feron_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderFeron. + * @param context Pointer to a SubGhzProtocolDecoderFeron 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_feron_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderFeron. + * @param context Pointer to a SubGhzProtocolDecoderFeron instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_feron_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderFeron instance + * @param output Resulting text + */ +void subghz_protocol_decoder_feron_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/gangqi.c b/lib/subghz/protocols/gangqi.c new file mode 100644 index 00000000000..c8a2413370c --- /dev/null +++ b/lib/subghz/protocols/gangqi.c @@ -0,0 +1,407 @@ +#include "gangqi.h" +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolGangQi" + +static const SubGhzBlockConst subghz_protocol_gangqi_const = { + .te_short = 500, + .te_long = 1200, + .te_delta = 200, + .min_count_bit_for_found = 34, +}; + +struct SubGhzProtocolDecoderGangQi { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; +}; + +struct SubGhzProtocolEncoderGangQi { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + GangQiDecoderStepReset = 0, + GangQiDecoderStepSaveDuration, + GangQiDecoderStepCheckDuration, +} GangQiDecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_gangqi_decoder = { + .alloc = subghz_protocol_decoder_gangqi_alloc, + .free = subghz_protocol_decoder_gangqi_free, + + .feed = subghz_protocol_decoder_gangqi_feed, + .reset = subghz_protocol_decoder_gangqi_reset, + + .get_hash_data = subghz_protocol_decoder_gangqi_get_hash_data, + .serialize = subghz_protocol_decoder_gangqi_serialize, + .deserialize = subghz_protocol_decoder_gangqi_deserialize, + .get_string = subghz_protocol_decoder_gangqi_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_gangqi_encoder = { + .alloc = subghz_protocol_encoder_gangqi_alloc, + .free = subghz_protocol_encoder_gangqi_free, + + .deserialize = subghz_protocol_encoder_gangqi_deserialize, + .stop = subghz_protocol_encoder_gangqi_stop, + .yield = subghz_protocol_encoder_gangqi_yield, +}; + +const SubGhzProtocol subghz_protocol_gangqi = { + .name = SUBGHZ_PROTOCOL_GANGQI_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | + SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_gangqi_decoder, + .encoder = &subghz_protocol_gangqi_encoder, +}; + +void* subghz_protocol_encoder_gangqi_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderGangQi* instance = malloc(sizeof(SubGhzProtocolEncoderGangQi)); + + instance->base.protocol = &subghz_protocol_gangqi; + instance->generic.protocol_name = instance->base.protocol->name; + + instance->encoder.repeat = 10; + instance->encoder.size_upload = 1024; + instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); + instance->encoder.is_running = false; + return instance; +} + +void subghz_protocol_encoder_gangqi_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderGangQi* instance = context; + free(instance->encoder.upload); + free(instance); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderGangQi instance + */ +static void subghz_protocol_encoder_gangqi_get_upload(SubGhzProtocolEncoderGangQi* instance) { + furi_assert(instance); + + // Generate new key + uint16_t serial = (uint16_t)((instance->generic.data >> 18) & 0xFFFF); + uint8_t const_and_button = (uint8_t)(0xD0 | instance->generic.btn); + uint8_t serial_high = (uint8_t)(serial >> 8); + uint8_t serial_low = (uint8_t)(serial & 0xFF); + uint8_t bytesum = (uint8_t)(0xC8 - serial_high - serial_low - const_and_button); + + instance->generic.data = (instance->generic.data >> 14) << 14 | (instance->generic.btn << 10) | + (bytesum << 2); + + size_t index = 0; + + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_long * 2); + + for(size_t r = 0; r < 5; r++) { + // Send key and GAP between parcels + 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_gangqi_const.te_long); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, + (uint32_t)subghz_protocol_gangqi_const.te_short * 4 + + subghz_protocol_gangqi_const.te_delta); + } else { + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_gangqi_const.te_short); + } + } else { + // Send bit 0 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_gangqi_const.te_short); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, + (uint32_t)subghz_protocol_gangqi_const.te_short * 4 + + subghz_protocol_gangqi_const.te_delta); + } else { + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_gangqi_const.te_long); + } + } + } + } + + instance->encoder.size_upload = index; + return; +} + +/** + * Analysis of received data and parsing serial number + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_gangqi_remote_controller(SubGhzBlockGeneric* instance) { + instance->btn = (instance->data >> 10) & 0xF; + instance->serial = (instance->data & 0xFFFFF0000) >> 16; + + // GangQi Decoder + // 09.2024 - @xMasterX (MMX) (last update - bytesum calculation at 02.2025) + // Thanks @Skorpionm for support! + // Thanks @Drone1950 and @mishamyte (who spent 2 weeks on this) for making this work properly + + // Example of correct bytesum calculation + // 0xC8 - serial_high - serial_low - constant_and_button +} + +SubGhzProtocolStatus + subghz_protocol_encoder_gangqi_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderGangQi* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_gangqi_const.min_count_bit_for_found); + if(ret != SubGhzProtocolStatusOk) { + break; + } + //optional parameter parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + subghz_protocol_gangqi_remote_controller(&instance->generic); + subghz_protocol_encoder_gangqi_get_upload(instance); + instance->encoder.front = 0; + + 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; + } while(false); + + return ret; +} + +void subghz_protocol_encoder_gangqi_stop(void* context) { + SubGhzProtocolEncoderGangQi* instance = context; + instance->encoder.is_running = false; + instance->encoder.front = 0; +} + +LevelDuration subghz_protocol_encoder_gangqi_yield(void* context) { + SubGhzProtocolEncoderGangQi* 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_gangqi_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderGangQi* instance = malloc(sizeof(SubGhzProtocolDecoderGangQi)); + instance->base.protocol = &subghz_protocol_gangqi; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_gangqi_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderGangQi* instance = context; + free(instance); +} + +void subghz_protocol_decoder_gangqi_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderGangQi* instance = context; + instance->decoder.parser_step = GangQiDecoderStepReset; +} + +void subghz_protocol_decoder_gangqi_feed(void* context, bool level, volatile uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderGangQi* instance = context; + + switch(instance->decoder.parser_step) { + case GangQiDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_gangqi_const.te_long * 2) < + subghz_protocol_gangqi_const.te_delta * 5)) { + //Found GAP + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = GangQiDecoderStepSaveDuration; + } + break; + case GangQiDecoderStepSaveDuration: + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = GangQiDecoderStepCheckDuration; + } else { + instance->decoder.parser_step = GangQiDecoderStepReset; + } + break; + case GangQiDecoderStepCheckDuration: + if(!level) { + // Bit 0 is short and long timing + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_gangqi_const.te_short) < + subghz_protocol_gangqi_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_gangqi_const.te_long) < + subghz_protocol_gangqi_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = GangQiDecoderStepSaveDuration; + // Bit 1 is long and short timing + } else if( + (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_gangqi_const.te_long) < + subghz_protocol_gangqi_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_gangqi_const.te_short) < + subghz_protocol_gangqi_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = GangQiDecoderStepSaveDuration; + } else if( + // End of the key + DURATION_DIFF(duration, subghz_protocol_gangqi_const.te_long * 2) < + subghz_protocol_gangqi_const.te_delta * 5) { + //Found next GAP and add bit 0 or 1 (only bit 0 was found on the remotes) + if((DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_gangqi_const.te_short) < + subghz_protocol_gangqi_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + } + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_gangqi_const.te_long) < + subghz_protocol_gangqi_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + } + // If got 34 bits key reading is finished + if(instance->decoder.decode_count_bit == + subghz_protocol_gangqi_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; + instance->decoder.parser_step = GangQiDecoderStepReset; + } else { + instance->decoder.parser_step = GangQiDecoderStepReset; + } + } else { + instance->decoder.parser_step = GangQiDecoderStepReset; + } + break; + } +} + +/** + * Get button name. + * @param btn Button number, 4 bit + */ +static const char* subghz_protocol_gangqi_get_button_name(uint8_t btn) { + const char* name_btn[16] = { + "Unknown", + "Exit settings", + "Volume setting", + "0x3", + "Vibro sens. setting", + "Settings mode", + "Ringtone setting", + "Ring", // D + "0x8", + "0x9", + "0xA", + "Alarm", // C + "0xC", + "Arm", // A + "Disarm", // B + "0xF"}; + return btn <= 0xf ? name_btn[btn] : name_btn[0]; +} + +uint8_t subghz_protocol_decoder_gangqi_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderGangQi* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_gangqi_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderGangQi* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + subghz_protocol_decoder_gangqi_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderGangQi* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, flipper_format, subghz_protocol_gangqi_const.min_count_bit_for_found); +} + +void subghz_protocol_decoder_gangqi_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderGangQi* instance = context; + + // Parse serial + subghz_protocol_gangqi_remote_controller(&instance->generic); + + // Get byte sum + uint16_t serial = (uint16_t)((instance->generic.data >> 18) & 0xFFFF); + uint8_t const_and_button = (uint8_t)(0xD0 | instance->generic.btn); + uint8_t serial_high = (uint8_t)(serial >> 8); + uint8_t serial_low = (uint8_t)(serial & 0xFF); + // Type 1 is what original remotes use, type 2 is "backdoor" sum that receiver accepts too + uint8_t sum_type1 = (uint8_t)(0xC8 - serial_high - serial_low - const_and_button); + uint8_t sum_type2 = (uint8_t)(0x02 + serial_high + serial_low + const_and_button); + + furi_string_cat_printf( + output, + "%s %db\r\n" + "Key: 0x%X%08lX\r\n" + "Serial: 0x%05lX\r\n" + "Sum: 0x%02X Sum2: 0x%02X\r\n" + "Btn: 0x%01X - %s\r\n", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint8_t)(instance->generic.data >> 32), + (uint32_t)(instance->generic.data & 0xFFFFFFFF), + instance->generic.serial, + sum_type1, + sum_type2, + instance->generic.btn, + subghz_protocol_gangqi_get_button_name(instance->generic.btn)); +} diff --git a/lib/subghz/protocols/gangqi.h b/lib/subghz/protocols/gangqi.h new file mode 100644 index 00000000000..e90f4e7c364 --- /dev/null +++ b/lib/subghz/protocols/gangqi.h @@ -0,0 +1,109 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_GANGQI_NAME "GangQi" + +typedef struct SubGhzProtocolDecoderGangQi SubGhzProtocolDecoderGangQi; +typedef struct SubGhzProtocolEncoderGangQi SubGhzProtocolEncoderGangQi; + +extern const SubGhzProtocolDecoder subghz_protocol_gangqi_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_gangqi_encoder; +extern const SubGhzProtocol subghz_protocol_gangqi; + +/** + * Allocate SubGhzProtocolEncoderGangQi. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderGangQi* pointer to a SubGhzProtocolEncoderGangQi instance + */ +void* subghz_protocol_encoder_gangqi_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderGangQi. + * @param context Pointer to a SubGhzProtocolEncoderGangQi instance + */ +void subghz_protocol_encoder_gangqi_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderGangQi instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_encoder_gangqi_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderGangQi instance + */ +void subghz_protocol_encoder_gangqi_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderGangQi instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_gangqi_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderGangQi. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderGangQi* pointer to a SubGhzProtocolDecoderGangQi instance + */ +void* subghz_protocol_decoder_gangqi_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderGangQi. + * @param context Pointer to a SubGhzProtocolDecoderGangQi instance + */ +void subghz_protocol_decoder_gangqi_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderGangQi. + * @param context Pointer to a SubGhzProtocolDecoderGangQi instance + */ +void subghz_protocol_decoder_gangqi_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderGangQi instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_gangqi_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderGangQi instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_gangqi_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderGangQi. + * @param context Pointer to a SubGhzProtocolDecoderGangQi 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_gangqi_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderGangQi. + * @param context Pointer to a SubGhzProtocolDecoderGangQi instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_gangqi_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderGangQi instance + * @param output Resulting text + */ +void subghz_protocol_decoder_gangqi_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/hay21.c b/lib/subghz/protocols/hay21.c new file mode 100644 index 00000000000..f4e1094962f --- /dev/null +++ b/lib/subghz/protocols/hay21.c @@ -0,0 +1,269 @@ +#include "hay21.h" +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolHay21" + +static const SubGhzBlockConst subghz_protocol_hay21_const = { + .te_short = 300, + .te_long = 700, + .te_delta = 150, + .min_count_bit_for_found = 21, +}; + +struct SubGhzProtocolDecoderHay21 { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; +}; + +struct SubGhzProtocolEncoderHay21 { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + Hay21DecoderStepReset = 0, + Hay21DecoderStepSaveDuration, + Hay21DecoderStepCheckDuration, +} Hay21DecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_hay21_decoder = { + .alloc = subghz_protocol_decoder_hay21_alloc, + .free = subghz_protocol_decoder_hay21_free, + + .feed = subghz_protocol_decoder_hay21_feed, + .reset = subghz_protocol_decoder_hay21_reset, + + .get_hash_data = subghz_protocol_decoder_hay21_get_hash_data, + .serialize = subghz_protocol_decoder_hay21_serialize, + .deserialize = subghz_protocol_decoder_hay21_deserialize, + .get_string = subghz_protocol_decoder_hay21_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_hay21_encoder = { + .alloc = NULL, + .free = NULL, + + .deserialize = NULL, + .stop = NULL, + .yield = NULL, +}; + +const SubGhzProtocol subghz_protocol_hay21 = { + .name = SUBGHZ_PROTOCOL_HAY21_NAME, + .type = SubGhzProtocolTypeDynamic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + + .decoder = &subghz_protocol_hay21_decoder, + .encoder = &subghz_protocol_hay21_encoder, +}; + +/** + * Analysis of received data and parsing serial number + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_hay21_remote_controller(SubGhzBlockGeneric* instance) { + instance->btn = (instance->data >> 13) & 0xFF; + instance->serial = (instance->data >> 5) & 0xFF; + instance->cnt = (instance->data >> 1) & 0xF; + + // Hay21 Decoder + // 09.2024 - @xMasterX (MMX) + + // Key samples (inverted) + // button serial CNT (goes lower since 0/1 are inverted) + //14A84A = 000 10100101 01000010 0101 0 (cnt 5) + //14A848 = 000 10100101 01000010 0100 0 (cnt 4) + //14A846 = 000 10100101 01000010 0011 0 (cnt 3) + //14A844 = 000 10100101 01000010 0010 0 (cnt 2) + //14A842 = 000 10100101 01000010 0001 0 (cnt 1) + //14A840 = 000 10100101 01000010 0000 0 (cnt 0) + //14A85E = 000 10100101 01000010 1111 0 (cnt F) + //14A85C = 000 10100101 01000010 1110 0 (cnt E) + //14A85A = 000 10100101 01000010 1101 0 (cnt D) + //14A858 = 000 10100101 01000010 1100 0 (cnt C) + //14A856 = 000 10100101 01000010 1011 0 (cnt B) + // 0xA5 (Labeled as On/Off on the remote board) + // 0x3C (Labeled as Mode on the remote board) + // 0x42 (Serial) + // BTN Serial CNT + //078854 = 000 00111100 01000010 1010 0 (cnt A) + //078852 = 000 00111100 01000010 1001 0 (cnt 9) + //078850 = 000 00111100 01000010 1000 0 (cnt 8) + //07884E = 000 00111100 01000010 0111 0 (cnt 7) + // Inverted back + //1877B9 = 000 11000011 10111101 1100 1 + //1877BB = 000 11000011 10111101 1101 1 + //1877BD = 000 11000011 10111101 1110 1 + //0B57BF = 000 01011010 10111101 1111 1 +} + +void* subghz_protocol_decoder_hay21_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderHay21* instance = malloc(sizeof(SubGhzProtocolDecoderHay21)); + instance->base.protocol = &subghz_protocol_hay21; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_hay21_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHay21* instance = context; + free(instance); +} + +void subghz_protocol_decoder_hay21_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHay21* instance = context; + instance->decoder.parser_step = Hay21DecoderStepReset; +} + +void subghz_protocol_decoder_hay21_feed(void* context, bool level, volatile uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderHay21* instance = context; + + switch(instance->decoder.parser_step) { + case Hay21DecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_hay21_const.te_long * 6) < + subghz_protocol_hay21_const.te_delta * 3)) { + //Found GAP + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = Hay21DecoderStepSaveDuration; + } + break; + case Hay21DecoderStepSaveDuration: + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = Hay21DecoderStepCheckDuration; + } else { + instance->decoder.parser_step = Hay21DecoderStepReset; + } + break; + case Hay21DecoderStepCheckDuration: + if(!level) { + // Bit 1 is long + short timing + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_hay21_const.te_long) < + subghz_protocol_hay21_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_hay21_const.te_short) < + subghz_protocol_hay21_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = Hay21DecoderStepSaveDuration; + // Bit 0 is short + long timing + } else if( + (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_hay21_const.te_short) < + subghz_protocol_hay21_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_hay21_const.te_long) < + subghz_protocol_hay21_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = Hay21DecoderStepSaveDuration; + } else if( + // End of the key + DURATION_DIFF(duration, subghz_protocol_hay21_const.te_long * 6) < + subghz_protocol_hay21_const.te_delta * 2) { + //Found next GAP and add bit 0 or 1 + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_hay21_const.te_long) < + subghz_protocol_hay21_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + } + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_hay21_const.te_short) < + subghz_protocol_hay21_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + } + // If got 21 bits key reading is finished + if(instance->decoder.decode_count_bit == + subghz_protocol_hay21_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; + instance->decoder.parser_step = Hay21DecoderStepReset; + } else { + instance->decoder.parser_step = Hay21DecoderStepReset; + } + } else { + instance->decoder.parser_step = Hay21DecoderStepReset; + } + break; + } +} + +/** + * Get button name. + * @param btn Button number, 4 bit + */ +static const char* subghz_protocol_hay21_get_button_name(uint8_t btn) { + const char* btn_name; + switch(btn) { + case 0x5A: + btn_name = "On/Off"; + break; + case 0xC3: + btn_name = "Mode"; + break; + case 0x88: + btn_name = "Hold"; + break; + default: + btn_name = "Unknown"; + break; + } + return btn_name; +} + +uint8_t subghz_protocol_decoder_hay21_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHay21* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_hay21_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderHay21* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + subghz_protocol_decoder_hay21_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderHay21* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, flipper_format, subghz_protocol_hay21_const.min_count_bit_for_found); +} + +void subghz_protocol_decoder_hay21_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderHay21* instance = context; + + // Parse serial, button, counter + subghz_protocol_hay21_remote_controller(&instance->generic); + + furi_string_cat_printf( + output, + "%s - %dbit\r\n" + "Key: 0x%06lX\r\n" + "Serial: 0x%02X\r\n" + "Btn: 0x%01X - %s\r\n" + "Cnt: 0x%01X\r\n", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data & 0xFFFFFFFF), + (uint8_t)(instance->generic.serial & 0xFF), + instance->generic.btn, + subghz_protocol_hay21_get_button_name(instance->generic.btn), + (uint8_t)(instance->generic.cnt & 0xF)); +} diff --git a/lib/subghz/protocols/hay21.h b/lib/subghz/protocols/hay21.h new file mode 100644 index 00000000000..22720d7ddcd --- /dev/null +++ b/lib/subghz/protocols/hay21.h @@ -0,0 +1,74 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_HAY21_NAME "Hay21" + +typedef struct SubGhzProtocolDecoderHay21 SubGhzProtocolDecoderHay21; +typedef struct SubGhzProtocolEncoderHay21 SubGhzProtocolEncoderHay21; + +extern const SubGhzProtocolDecoder subghz_protocol_hay21_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_hay21_encoder; +extern const SubGhzProtocol subghz_protocol_hay21; + +/** + * Allocate SubGhzProtocolDecoderHay21. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderHay21* pointer to a SubGhzProtocolDecoderHay21 instance + */ +void* subghz_protocol_decoder_hay21_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderHay21. + * @param context Pointer to a SubGhzProtocolDecoderHay21 instance + */ +void subghz_protocol_decoder_hay21_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderHay21. + * @param context Pointer to a SubGhzProtocolDecoderHay21 instance + */ +void subghz_protocol_decoder_hay21_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderHay21 instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_hay21_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderHay21 instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_hay21_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderHay21. + * @param context Pointer to a SubGhzProtocolDecoderHay21 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_hay21_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderHay21. + * @param context Pointer to a SubGhzProtocolDecoderHay21 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_hay21_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderHay21 instance + * @param output Resulting text + */ +void subghz_protocol_decoder_hay21_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/hollarm.c b/lib/subghz/protocols/hollarm.c new file mode 100644 index 00000000000..70ba6c58659 --- /dev/null +++ b/lib/subghz/protocols/hollarm.c @@ -0,0 +1,408 @@ +#include "hollarm.h" +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolHollarm" + +static const SubGhzBlockConst subghz_protocol_hollarm_const = { + .te_short = 200, + .te_long = 1000, + .te_delta = 200, + .min_count_bit_for_found = 42, +}; + +struct SubGhzProtocolDecoderHollarm { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; +}; + +struct SubGhzProtocolEncoderHollarm { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + HollarmDecoderStepReset = 0, + HollarmDecoderStepSaveDuration, + HollarmDecoderStepCheckDuration, +} HollarmDecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_hollarm_decoder = { + .alloc = subghz_protocol_decoder_hollarm_alloc, + .free = subghz_protocol_decoder_hollarm_free, + + .feed = subghz_protocol_decoder_hollarm_feed, + .reset = subghz_protocol_decoder_hollarm_reset, + + .get_hash_data = subghz_protocol_decoder_hollarm_get_hash_data, + .serialize = subghz_protocol_decoder_hollarm_serialize, + .deserialize = subghz_protocol_decoder_hollarm_deserialize, + .get_string = subghz_protocol_decoder_hollarm_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_hollarm_encoder = { + .alloc = subghz_protocol_encoder_hollarm_alloc, + .free = subghz_protocol_encoder_hollarm_free, + + .deserialize = subghz_protocol_encoder_hollarm_deserialize, + .stop = subghz_protocol_encoder_hollarm_stop, + .yield = subghz_protocol_encoder_hollarm_yield, +}; + +const SubGhzProtocol subghz_protocol_hollarm = { + .name = SUBGHZ_PROTOCOL_HOLLARM_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | + SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_hollarm_decoder, + .encoder = &subghz_protocol_hollarm_encoder, +}; + +void* subghz_protocol_encoder_hollarm_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderHollarm* instance = malloc(sizeof(SubGhzProtocolEncoderHollarm)); + + instance->base.protocol = &subghz_protocol_hollarm; + instance->generic.protocol_name = instance->base.protocol->name; + + 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_hollarm_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderHollarm* instance = context; + free(instance->encoder.upload); + free(instance); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderHollarm instance + */ +static void subghz_protocol_encoder_hollarm_get_upload(SubGhzProtocolEncoderHollarm* instance) { + furi_assert(instance); + + // Generate new key + uint64_t new_key = (instance->generic.data >> 12) << 12 | (instance->generic.btn << 8); + + uint8_t bytesum = ((new_key >> 32) & 0xFF) + ((new_key >> 24) & 0xFF) + + ((new_key >> 16) & 0xFF) + ((new_key >> 8) & 0xFF); + + instance->generic.data = (new_key | bytesum); + + size_t index = 0; + + // Send key and GAP between parcels + for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { + // Read and prepare levels with 2 bit (was saved for better parsing) to the left offset to fit with the original remote transmission + if(bit_read((instance->generic.data << 2), i - 1)) { + // Send bit 1 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_hollarm_const.te_short); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_hollarm_const.te_short * 12); + } else { + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_hollarm_const.te_short * 8); + } + } else { + // Send bit 0 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_hollarm_const.te_short); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_hollarm_const.te_short * 12); + } else { + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_hollarm_const.te_long); + } + } + } + + instance->encoder.size_upload = index; + return; +} + +/** + * Analysis of received data and parsing serial number + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_hollarm_remote_controller(SubGhzBlockGeneric* instance) { + instance->btn = (instance->data >> 8) & 0xF; + instance->serial = (instance->data & 0xFFFFFFF0000) >> 16; + + // Hollarm Decoder + // 09.2024 - @xMasterX (MMX) + // Thanks @Skorpionm for support! + + // F0B93422FF = FF 8bit Sum + // F0B93421FE = FE 8bit Sum + // F0B9342401 = 01 8bit Sum + // F0B9342805 = 05 8bit Sum + + // Serial (moved 2bit to right) | Btn | 8b previous 4 bytes sum + // 00001111000010111001001101000010 0010 11111111 btn = (0x2) + // 00001111000010111001001101000010 0001 11111110 btn = (0x1) + // 00001111000010111001001101000010 0100 00000001 btn = (0x4) + // 00001111000010111001001101000010 1000 00000101 btn = (0x8) +} + +SubGhzProtocolStatus + subghz_protocol_encoder_hollarm_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderHollarm* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_hollarm_const.min_count_bit_for_found); + if(ret != SubGhzProtocolStatusOk) { + break; + } + //optional parameter parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + subghz_protocol_hollarm_remote_controller(&instance->generic); + subghz_protocol_encoder_hollarm_get_upload(instance); + instance->encoder.front = 0; + + 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; + } while(false); + + return ret; +} + +void subghz_protocol_encoder_hollarm_stop(void* context) { + SubGhzProtocolEncoderHollarm* instance = context; + instance->encoder.is_running = false; + instance->encoder.front = 0; +} + +LevelDuration subghz_protocol_encoder_hollarm_yield(void* context) { + SubGhzProtocolEncoderHollarm* 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_hollarm_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderHollarm* instance = malloc(sizeof(SubGhzProtocolDecoderHollarm)); + instance->base.protocol = &subghz_protocol_hollarm; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_hollarm_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHollarm* instance = context; + free(instance); +} + +void subghz_protocol_decoder_hollarm_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHollarm* instance = context; + instance->decoder.parser_step = HollarmDecoderStepReset; +} + +void subghz_protocol_decoder_hollarm_feed(void* context, bool level, volatile uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderHollarm* instance = context; + + switch(instance->decoder.parser_step) { + case HollarmDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_hollarm_const.te_short * 12) < + subghz_protocol_hollarm_const.te_delta * 2)) { + //Found GAP between parcels + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = HollarmDecoderStepSaveDuration; + } + break; + case HollarmDecoderStepSaveDuration: + // Save HIGH level timing for next step + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = HollarmDecoderStepCheckDuration; + } else { + instance->decoder.parser_step = HollarmDecoderStepReset; + } + break; + case HollarmDecoderStepCheckDuration: + if(!level) { + // Bit 0 is short 200us HIGH + long 1000us LOW timing + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_hollarm_const.te_short) < + subghz_protocol_hollarm_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_hollarm_const.te_long) < + subghz_protocol_hollarm_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = HollarmDecoderStepSaveDuration; + // Bit 1 is short 200us HIGH + short x8 = 1600us LOW timing + } else if( + (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_hollarm_const.te_short) < + subghz_protocol_hollarm_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_hollarm_const.te_short * 8) < + subghz_protocol_hollarm_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = HollarmDecoderStepSaveDuration; + } else if( + // End of the key + DURATION_DIFF(duration, subghz_protocol_hollarm_const.te_short * 12) < + subghz_protocol_hollarm_const.te_delta) { + // When next GAP is found add bit 0 and do check for read finish + // (we have 42 high level pulses, last or first one may be a stop/start bit but we will parse it as zero) + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + + // If got 42 bits key reading is finished + if(instance->decoder.decode_count_bit == + subghz_protocol_hollarm_const.min_count_bit_for_found) { + // Saving with 2bit to the right offset for proper parsing + instance->generic.data = (instance->decoder.decode_data >> 2); + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + + uint8_t bytesum = ((instance->generic.data >> 32) & 0xFF) + + ((instance->generic.data >> 24) & 0xFF) + + ((instance->generic.data >> 16) & 0xFF) + + ((instance->generic.data >> 8) & 0xFF); + + if(bytesum != (instance->generic.data & 0xFF)) { + // Check if the key is valid by verifying the sum + instance->generic.data = 0; + instance->generic.data_count_bit = 0; + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = HollarmDecoderStepReset; + break; + } + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + } + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = HollarmDecoderStepReset; + } else { + instance->decoder.parser_step = HollarmDecoderStepReset; + } + } else { + instance->decoder.parser_step = HollarmDecoderStepReset; + } + break; + } +} + +/** + * Get button name. + * @param btn Button number, 4 bit + */ +static const char* subghz_protocol_hollarm_get_button_name(uint8_t btn) { + const char* name_btn[16] = { + "Unknown", + "Disarm", // B (2) + "Arm", // A (1) + "0x3", + "Ringtone/Alarm", // C (3) + "0x5", + "0x6", + "0x7", + "Ring", // D (4) + "Settings mode", + "Exit settings", + "Vibro sens. setting", + "Not used\n(in settings)", + "Volume setting", + "0xE", + "0xF"}; + return btn <= 0xf ? name_btn[btn] : name_btn[0]; +} + +uint8_t subghz_protocol_decoder_hollarm_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderHollarm* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_hollarm_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderHollarm* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + subghz_protocol_decoder_hollarm_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderHollarm* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, flipper_format, subghz_protocol_hollarm_const.min_count_bit_for_found); +} + +void subghz_protocol_decoder_hollarm_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderHollarm* instance = context; + + // Parse serial + subghz_protocol_hollarm_remote_controller(&instance->generic); + // Get byte sum + uint8_t bytesum = + ((instance->generic.data >> 32) & 0xFF) + ((instance->generic.data >> 24) & 0xFF) + + ((instance->generic.data >> 16) & 0xFF) + ((instance->generic.data >> 8) & 0xFF); + + furi_string_cat_printf( + output, + "%s %db\r\n" + "Key: 0x%02lX%08lX\r\n" + "Serial: 0x%06lX Sum: %02X\r\n" + "Btn: 0x%01X - %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, + bytesum, + instance->generic.btn, + subghz_protocol_hollarm_get_button_name(instance->generic.btn)); +} diff --git a/lib/subghz/protocols/hollarm.h b/lib/subghz/protocols/hollarm.h new file mode 100644 index 00000000000..8749198a102 --- /dev/null +++ b/lib/subghz/protocols/hollarm.h @@ -0,0 +1,109 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_HOLLARM_NAME "Hollarm" + +typedef struct SubGhzProtocolDecoderHollarm SubGhzProtocolDecoderHollarm; +typedef struct SubGhzProtocolEncoderHollarm SubGhzProtocolEncoderHollarm; + +extern const SubGhzProtocolDecoder subghz_protocol_hollarm_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_hollarm_encoder; +extern const SubGhzProtocol subghz_protocol_hollarm; + +/** + * Allocate SubGhzProtocolEncoderHollarm. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderHollarm* pointer to a SubGhzProtocolEncoderHollarm instance + */ +void* subghz_protocol_encoder_hollarm_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderHollarm. + * @param context Pointer to a SubGhzProtocolEncoderHollarm instance + */ +void subghz_protocol_encoder_hollarm_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderHollarm instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_encoder_hollarm_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderHollarm instance + */ +void subghz_protocol_encoder_hollarm_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderHollarm instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_hollarm_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderHollarm. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderHollarm* pointer to a SubGhzProtocolDecoderHollarm instance + */ +void* subghz_protocol_decoder_hollarm_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderHollarm. + * @param context Pointer to a SubGhzProtocolDecoderHollarm instance + */ +void subghz_protocol_decoder_hollarm_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderHollarm. + * @param context Pointer to a SubGhzProtocolDecoderHollarm instance + */ +void subghz_protocol_decoder_hollarm_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderHollarm instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_hollarm_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderHollarm instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_hollarm_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderHollarm. + * @param context Pointer to a SubGhzProtocolDecoderHollarm 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_hollarm_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderHollarm. + * @param context Pointer to a SubGhzProtocolDecoderHollarm instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_hollarm_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderHollarm instance + * @param output Resulting text + */ +void subghz_protocol_decoder_hollarm_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/holtek_ht12x.c b/lib/subghz/protocols/holtek_ht12x.c index 302b78598b9..be2dfd406d7 100644 --- a/lib/subghz/protocols/holtek_ht12x.c +++ b/lib/subghz/protocols/holtek_ht12x.c @@ -234,8 +234,10 @@ void subghz_protocol_decoder_holtek_th12x_feed(void* context, bool level, uint32 switch(instance->decoder.parser_step) { case Holtek_HT12XDecoderStepReset: - if((!level) && (DURATION_DIFF(duration, subghz_protocol_holtek_th12x_const.te_short * 36) < - subghz_protocol_holtek_th12x_const.te_delta * 36)) { + if((!level) && (DURATION_DIFF(duration, subghz_protocol_holtek_th12x_const.te_short * 28) < + subghz_protocol_holtek_th12x_const.te_delta * 20)) { + // 18720 us old max value + // 12960 us corrected max value //Found Preambula instance->decoder.parser_step = Holtek_HT12XDecoderStepFoundStartBit; } diff --git a/lib/subghz/protocols/hormann.c b/lib/subghz/protocols/hormann.c index 70954bb39d4..43a490ff900 100644 --- a/lib/subghz/protocols/hormann.c +++ b/lib/subghz/protocols/hormann.c @@ -158,6 +158,7 @@ SubGhzProtocolStatus flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); if(!subghz_protocol_encoder_hormann_get_upload(instance)) { + instance->encoder.front = 0; // reset position before start ret = SubGhzProtocolStatusErrorEncoderGetUpload; break; } @@ -170,6 +171,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_hormann_stop(void* context) { SubGhzProtocolEncoderHormann* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position } LevelDuration subghz_protocol_encoder_hormann_yield(void* context) { diff --git a/lib/subghz/protocols/intertechno_v3.c b/lib/subghz/protocols/intertechno_v3.c index b9af72a579b..da25e1e75c9 100644 --- a/lib/subghz/protocols/intertechno_v3.c +++ b/lib/subghz/protocols/intertechno_v3.c @@ -193,6 +193,7 @@ SubGhzProtocolStatus subghz_protocol_encoder_intertechno_v3_deserialize( void subghz_protocol_encoder_intertechno_v3_stop(void* context) { SubGhzProtocolEncoderIntertechno_V3* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position } LevelDuration subghz_protocol_encoder_intertechno_v3_yield(void* context) { diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index b38abb75b50..11b9e1587ac 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -299,7 +299,7 @@ SubGhzProtocolStatus ret = SubGhzProtocolStatusErrorParserKey; break; } - + instance->encoder.front = 0; // reset before start instance->encoder.is_running = true; } while(false); @@ -309,6 +309,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_keeloq_stop(void* context) { SubGhzProtocolEncoderKeeloq* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position } LevelDuration subghz_protocol_encoder_keeloq_yield(void* context) { diff --git a/lib/subghz/protocols/legrand.c b/lib/subghz/protocols/legrand.c new file mode 100644 index 00000000000..0df0d255ced --- /dev/null +++ b/lib/subghz/protocols/legrand.c @@ -0,0 +1,398 @@ +#include "legrand.h" + +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolLegrand" + +static const SubGhzBlockConst subghz_protocol_legrand_const = { + .te_short = 375, + .te_long = 1125, + .te_delta = 150, + .min_count_bit_for_found = 18, +}; + +struct SubGhzProtocolDecoderLegrand { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; + + uint32_t te; + uint32_t last_data; +}; + +struct SubGhzProtocolEncoderLegrand { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; + + uint32_t te; +}; + +typedef enum { + LegrandDecoderStepReset = 0, + LegrandDecoderStepFirstBit, + LegrandDecoderStepSaveDuration, + LegrandDecoderStepCheckDuration, +} LegrandDecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_legrand_decoder = { + .alloc = subghz_protocol_decoder_legrand_alloc, + .free = subghz_protocol_decoder_legrand_free, + + .feed = subghz_protocol_decoder_legrand_feed, + .reset = subghz_protocol_decoder_legrand_reset, + + .get_hash_data = subghz_protocol_decoder_legrand_get_hash_data, + .serialize = subghz_protocol_decoder_legrand_serialize, + .deserialize = subghz_protocol_decoder_legrand_deserialize, + .get_string = subghz_protocol_decoder_legrand_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_legrand_encoder = { + .alloc = subghz_protocol_encoder_legrand_alloc, + .free = subghz_protocol_encoder_legrand_free, + + .deserialize = subghz_protocol_encoder_legrand_deserialize, + .stop = subghz_protocol_encoder_legrand_stop, + .yield = subghz_protocol_encoder_legrand_yield, +}; + +const SubGhzProtocol subghz_protocol_legrand = { + .name = SUBGHZ_PROTOCOL_LEGRAND_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | + SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_legrand_decoder, + .encoder = &subghz_protocol_legrand_encoder, +}; + +void* subghz_protocol_encoder_legrand_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderLegrand* instance = malloc(sizeof(SubGhzProtocolEncoderLegrand)); + + instance->base.protocol = &subghz_protocol_legrand; + instance->generic.protocol_name = instance->base.protocol->name; + + instance->encoder.repeat = 10; + instance->encoder.size_upload = + (subghz_protocol_legrand_const.min_count_bit_for_found * 6) * 2 + 2; + instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); + instance->encoder.is_running = false; + return instance; +} + +void subghz_protocol_encoder_legrand_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderLegrand* instance = context; + free(instance->encoder.upload); + free(instance); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderLegrand instance + * @return true On success + */ +static bool subghz_protocol_encoder_legrand_get_upload(SubGhzProtocolEncoderLegrand* instance) { + furi_assert(instance); + + //size_t size_upload = (instance->generic.data_count_bit * 2) + 1; + //if(size_upload != instance->encoder.size_upload) { + // FURI_LOG_E(TAG, "Invalid data bit count"); + // return false; + //} + + size_t index = 0; + + for(size_t r = 0; r < 5; r++) { + // Send sync + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)instance->te * 16); // 5728 + // 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 + if(i == instance->generic.data_count_bit) { + //Send first bit + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)instance->te * 3); + } else { + // send bit 1 regular + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)instance->te); + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)instance->te * 3); + } + } else { + // send bit 0 + if(i == instance->generic.data_count_bit) { + //Send first bit + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)instance->te); + } else { + // send bit 0 regular + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)instance->te * 3); + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)instance->te); + } + } + } + } + instance->encoder.size_upload = index; + + return true; +} + +SubGhzProtocolStatus + subghz_protocol_encoder_legrand_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderLegrand* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_legrand_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; + } + if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) { + FURI_LOG_E(TAG, "Missing TE"); + ret = SubGhzProtocolStatusErrorParserTe; + break; + } + // optional parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + if(!subghz_protocol_encoder_legrand_get_upload(instance)) { + ret = SubGhzProtocolStatusErrorEncoderGetUpload; + break; + } + instance->encoder.is_running = true; + } while(false); + + return ret; +} + +void subghz_protocol_encoder_legrand_stop(void* context) { + SubGhzProtocolEncoderLegrand* instance = context; + instance->encoder.is_running = false; +} + +LevelDuration subghz_protocol_encoder_legrand_yield(void* context) { + SubGhzProtocolEncoderLegrand* 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_legrand_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderLegrand* instance = malloc(sizeof(SubGhzProtocolDecoderLegrand)); + instance->base.protocol = &subghz_protocol_legrand; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_legrand_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderLegrand* instance = context; + free(instance); +} + +void subghz_protocol_decoder_legrand_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderLegrand* instance = context; + instance->decoder.parser_step = LegrandDecoderStepReset; + instance->last_data = 0; +} + +void subghz_protocol_decoder_legrand_feed(void* context, bool level, uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderLegrand* instance = context; + + switch(instance->decoder.parser_step) { + case LegrandDecoderStepReset: + if(!level && DURATION_DIFF(duration, subghz_protocol_legrand_const.te_short * 16) < + subghz_protocol_legrand_const.te_delta * 8) { // 6000 +- 1200 + instance->decoder.parser_step = LegrandDecoderStepFirstBit; + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->te = 0; + } + break; + case LegrandDecoderStepFirstBit: + if(level) { + if(DURATION_DIFF(duration, subghz_protocol_legrand_const.te_short) < + subghz_protocol_legrand_const.te_delta) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->te += duration * 4; // long low that is part of sync, then short high + } + + if(DURATION_DIFF(duration, subghz_protocol_legrand_const.te_long) < + subghz_protocol_legrand_const.te_delta * 3) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->te += duration / 3 * 4; // short low that is part of sync, then long high + } + + if(instance->decoder.decode_count_bit > 0) { + // advance to the next step if either short or long is found + instance->decoder.parser_step = LegrandDecoderStepSaveDuration; + break; + } + } + + instance->decoder.parser_step = LegrandDecoderStepReset; + break; + case LegrandDecoderStepSaveDuration: + if(!level) { + instance->decoder.te_last = duration; + instance->te += duration; + instance->decoder.parser_step = LegrandDecoderStepCheckDuration; + break; + } + + instance->decoder.parser_step = LegrandDecoderStepReset; + break; + case LegrandDecoderStepCheckDuration: + if(level) { + uint8_t found = 0; + + if(DURATION_DIFF(instance->decoder.te_last, subghz_protocol_legrand_const.te_long) < + subghz_protocol_legrand_const.te_delta * 3 && + DURATION_DIFF(duration, subghz_protocol_legrand_const.te_short) < + subghz_protocol_legrand_const.te_delta) { + found = 1; + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + } + + if(DURATION_DIFF(instance->decoder.te_last, subghz_protocol_legrand_const.te_short) < + subghz_protocol_legrand_const.te_delta && + DURATION_DIFF(duration, subghz_protocol_legrand_const.te_long) < + subghz_protocol_legrand_const.te_delta * 3) { + found = 1; + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + } + + if(found) { + instance->te += duration; + + if(instance->decoder.decode_count_bit < + subghz_protocol_legrand_const.min_count_bit_for_found) { + instance->decoder.parser_step = LegrandDecoderStepSaveDuration; + break; + } + + // enough bits for a packet found, save it only if there was a previous packet + // with the same data + if(instance->last_data && (instance->last_data == instance->decoder.decode_data)) { + instance->te /= instance->decoder.decode_count_bit * 4; + + 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->last_data = instance->decoder.decode_data; + // fallthrough to reset, the next bit is expected to be a sync + // it also takes care of resetting the decoder state + } + } + + instance->decoder.parser_step = LegrandDecoderStepReset; + break; + } +} + +uint8_t subghz_protocol_decoder_legrand_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderLegrand* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_legrand_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderLegrand* instance = context; + SubGhzProtocolStatus ret = + subghz_block_generic_serialize(&instance->generic, flipper_format, preset); + if((ret == SubGhzProtocolStatusOk) && + !flipper_format_write_uint32(flipper_format, "TE", &instance->te, 1)) { + FURI_LOG_E(TAG, "Unable to add TE"); + ret = SubGhzProtocolStatusErrorParserTe; + } + return ret; +} + +SubGhzProtocolStatus + subghz_protocol_decoder_legrand_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderLegrand* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_legrand_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; + } + if(!flipper_format_read_uint32(flipper_format, "TE", (uint32_t*)&instance->te, 1)) { + FURI_LOG_E(TAG, "Missing TE"); + ret = SubGhzProtocolStatusErrorParserTe; + break; + } + } while(false); + + return ret; +} + +void subghz_protocol_decoder_legrand_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderLegrand* instance = context; + + furi_string_cat_printf( + output, + "%s %dbit\r\n" + "Key:0x%05lX\r\n" + "Te:%luus\r\n", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data & 0xFFFFFF), + instance->te); +} diff --git a/lib/subghz/protocols/legrand.h b/lib/subghz/protocols/legrand.h new file mode 100644 index 00000000000..0948ddb8b04 --- /dev/null +++ b/lib/subghz/protocols/legrand.h @@ -0,0 +1,117 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_LEGRAND_NAME "Legrand" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct SubGhzProtocolDecoderLegrand SubGhzProtocolDecoderLegrand; +typedef struct SubGhzProtocolEncoderLegrand SubGhzProtocolEncoderLegrand; + +extern const SubGhzProtocolDecoder subghz_protocol_legrand_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_legrand_encoder; +extern const SubGhzProtocol subghz_protocol_legrand; + +/** + * Allocate SubGhzProtocolEncoderLegrand. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderLegrand* pointer to a SubGhzProtocolEncoderLegrand instance + */ +void* subghz_protocol_encoder_legrand_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderLegrand. + * @param context Pointer to a SubGhzProtocolEncoderLegrand instance + */ +void subghz_protocol_encoder_legrand_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderLegrand instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_encoder_legrand_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderLegrand instance + */ +void subghz_protocol_encoder_legrand_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderLegrand instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_legrand_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderLegrand. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderLegrand* pointer to a SubGhzProtocolDecoderLegrand instance + */ +void* subghz_protocol_decoder_legrand_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderLegrand. + * @param context Pointer to a SubGhzProtocolDecoderLegrand instance + */ +void subghz_protocol_decoder_legrand_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderLegrand. + * @param context Pointer to a SubGhzProtocolDecoderLegrand instance + */ +void subghz_protocol_decoder_legrand_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderLegrand instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_legrand_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderLegrand instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_legrand_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderLegrand. + * @param context Pointer to a SubGhzProtocolDecoderLegrand 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_legrand_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderLegrand. + * @param context Pointer to a SubGhzProtocolDecoderLegrand instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_legrand_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderLegrand instance + * @param output Resulting text + */ +void subghz_protocol_decoder_legrand_get_string(void* context, FuriString* output); + +#ifdef __cplusplus +} +#endif diff --git a/lib/subghz/protocols/magellan.c b/lib/subghz/protocols/magellan.c index 1b8eccc36e3..0706eec5969 100644 --- a/lib/subghz/protocols/magellan.c +++ b/lib/subghz/protocols/magellan.c @@ -168,6 +168,7 @@ SubGhzProtocolStatus flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); if(!subghz_protocol_encoder_magellan_get_upload(instance)) { + instance->encoder.front = 0; // reset before start ret = SubGhzProtocolStatusErrorEncoderGetUpload; break; } @@ -180,6 +181,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_magellan_stop(void* context) { SubGhzProtocolEncoderMagellan* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position } LevelDuration subghz_protocol_encoder_magellan_yield(void* context) { @@ -359,15 +361,38 @@ static void subghz_protocol_magellan_check_remote_controller(SubGhzBlockGeneric* * * 0x1275EC => 0x12-event codes, 0x75EC-serial (dec 117236) * -* event codes -* bit_0: 1-Open/Motion, 0-close/ok -* bit_1: 1-Tamper On (alarm), 0-Tamper Off (ok) -* bit_2: ? -* bit_3: 1-power on -* bit_4: model type - wireless reed -* bit_5: model type - motion sensor -* bit_6: ? -* bit_7: ? +* Event codes consist of two parts: +* - The upper nibble (bits 7-4) represents the event type: +* - 0x00: Nothing +* - 0x01: Door +* - 0x02: Motion +* - 0x03: Smoke Alarm +* - 0x04: REM1 +* - 0x05: REM1 with subtype Off1 +* - 0x06: REM2 +* - 0x07: REM2 with subtype Off1 +* - Others: Unknown +* - The lower nibble (bits 3-0) represents the event subtype, which varies based on the model type: +* - If the model type is greater than 0x03 (e.g., REM1 or REM2): +* - 0x00: Arm1 +* - 0x01: Btn1 +* - 0x02: Btn2 +* - 0x03: Btn3 +* - 0x08: Reset +* - 0x09: LowBatt +* - 0x0A: BattOk +* - 0x0B: Learn +* - Others: Unknown +* - Otherwise: +* - 0x00: Sealed +* - 0x01: Alarm +* - 0x02: Tamper +* - 0x03: Alarm + Tamper +* - 0x08: Reset +* - 0x09: LowBatt +* - 0x0A: BattOk +* - 0x0B: Learn +* - Others: Unknown * */ uint64_t data_rev = subghz_protocol_blocks_reverse_key(instance->data >> 8, 24); @@ -376,18 +401,71 @@ static void subghz_protocol_magellan_check_remote_controller(SubGhzBlockGeneric* } static void subghz_protocol_magellan_get_event_serialize(uint8_t event, FuriString* output) { - furi_string_cat_printf( - output, - "%s%s%s%s%s%s%s%s", - ((event >> 4) & 0x1 ? (event & 0x1 ? " Open" : " Close") : - (event & 0x1 ? " Motion" : " Ok")), - ((event >> 1) & 0x1 ? ", Tamper On\n(Alarm)" : ""), - ((event >> 2) & 0x1 ? ", ?" : ""), - ((event >> 3) & 0x1 ? ", Power On" : ""), - ((event >> 4) & 0x1 ? ", MT:Wireless_Reed" : ""), - ((event >> 5) & 0x1 ? ", MT:Motion_Sensor" : ""), - ((event >> 6) & 0x1 ? ", ?" : ""), - ((event >> 7) & 0x1 ? ", ?" : "")); + const char* event_type; + const char* event_subtype; + + switch((event >> 4) & 0x0F) { + case 0x00: + event_type = "Nothing"; + break; + case 0x01: + event_type = "Door"; + break; + case 0x02: + event_type = "Motion"; + break; + case 0x03: + event_type = "Smoke Alarm"; + break; + case 0x04: + event_type = "REM1"; + break; + case 0x05: + event_type = "REM1"; + event_subtype = "Off1"; + furi_string_cat_printf(output, "%s - %s", event_type, event_subtype); + return; + case 0x06: + event_type = "REM2"; + event_subtype = "Off1"; + furi_string_cat_printf(output, "%s - %s", event_type, event_subtype); + return; + default: + event_type = "Unknown"; + break; + } + + switch(event & 0x0F) { + case 0x00: + event_subtype = (((event >> 4) & 0x0F) > 0x03) ? "Arm1" : "Sealed"; + break; + case 0x01: + event_subtype = (((event >> 4) & 0x0F) > 0x03) ? "Btn1" : "Alarm"; + break; + case 0x02: + event_subtype = (((event >> 4) & 0x0F) > 0x03) ? "Btn2" : "Tamper"; + break; + case 0x03: + event_subtype = (((event >> 4) & 0x0F) > 0x03) ? "Btn3" : "Alarm + Tamper"; + break; + case 0x08: + event_subtype = "Reset"; + break; + case 0x09: + event_subtype = "LowBatt"; + break; + case 0x0A: + event_subtype = "BattOk"; + break; + case 0x0B: + event_subtype = "Learn"; + break; + default: + event_subtype = "Unknown"; + break; + } + + furi_string_cat_printf(output, "%s - %s", event_type, event_subtype); } uint8_t subghz_protocol_decoder_magellan_get_hash_data(void* context) { diff --git a/lib/subghz/protocols/marantec.c b/lib/subghz/protocols/marantec.c index fc4aa0dca4e..658aac61052 100644 --- a/lib/subghz/protocols/marantec.c +++ b/lib/subghz/protocols/marantec.c @@ -165,7 +165,7 @@ static void subghz_protocol_encoder_marantec_get_upload(SubGhzProtocolEncoderMar } uint8_t subghz_protocol_marantec_crc8(uint8_t* data, size_t len) { - uint8_t crc = 0x08; + uint8_t crc = 0x01; size_t i, j; for(i = 0; i < len; i++) { crc ^= data[i]; @@ -184,6 +184,18 @@ uint8_t subghz_protocol_marantec_crc8(uint8_t* data, size_t len) { * @param instance Pointer to a SubGhzBlockGeneric* instance */ static void subghz_protocol_marantec_remote_controller(SubGhzBlockGeneric* instance) { + // Key samples + // 1307EDF6486C5 = 000 100110000 01111110110111110110 0100 10000110 11000101 + // 1303EFAFD8683 = 000 100110000 00111110111110101111 1101 10000110 10000011 + + // From unittests + // 1300710DF869F + + // const serial button serial crc + // 130 7EDF6 4 86 C5 + // 130 3EFAF D 86 83 + // 130 0710D F 86 9F + instance->btn = (instance->data >> 16) & 0xF; instance->serial = ((instance->data >> 12) & 0xFFFFFF00) | ((instance->data >> 8) & 0xFF); } @@ -207,6 +219,7 @@ SubGhzProtocolStatus subghz_protocol_marantec_remote_controller(&instance->generic); subghz_protocol_encoder_marantec_get_upload(instance); + instance->encoder.front = 0; instance->encoder.is_running = true; } while(false); @@ -216,6 +229,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_marantec_stop(void* context) { SubGhzProtocolEncoderMarantec* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; } LevelDuration subghz_protocol_encoder_marantec_yield(void* context) { @@ -253,6 +267,7 @@ void subghz_protocol_decoder_marantec_free(void* context) { void subghz_protocol_decoder_marantec_reset(void* context) { furi_assert(context); SubGhzProtocolDecoderMarantec* instance = context; + instance->decoder.parser_step = MarantecDecoderStepReset; manchester_advance( instance->manchester_saved_state, ManchesterEventReset, @@ -367,16 +382,30 @@ void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* outp SubGhzProtocolDecoderMarantec* instance = context; subghz_protocol_marantec_remote_controller(&instance->generic); + uint8_t tdata[6] = { + instance->generic.data >> 48, + instance->generic.data >> 40, + instance->generic.data >> 32, + instance->generic.data >> 24, + instance->generic.data >> 16, + instance->generic.data >> 8}; + + uint8_t crc = subghz_protocol_marantec_crc8(tdata, sizeof(tdata)); + bool crc_ok = (crc == (instance->generic.data & 0xFF)); + furi_string_cat_printf( output, "%s %db\r\n" - "Key:0x%lX%08lX\r\n" - "Sn:0x%07lX \r\n" - "Btn:%X\r\n", + "Key: 0x%lX%08lX\r\n" + "Sn: 0x%07lX \r\n" + "CRC: 0x%02X - %s\r\n" + "Btn: %X\r\n", instance->generic.protocol_name, instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32), (uint32_t)(instance->generic.data & 0xFFFFFFFF), instance->generic.serial, + crc, + crc_ok ? "Valid" : "Invalid", instance->generic.btn); } diff --git a/lib/subghz/protocols/marantec.h b/lib/subghz/protocols/marantec.h index 485c563b2fb..9a7b55b7edb 100644 --- a/lib/subghz/protocols/marantec.h +++ b/lib/subghz/protocols/marantec.h @@ -107,3 +107,11 @@ SubGhzProtocolStatus * @param output Resulting text */ void subghz_protocol_decoder_marantec_get_string(void* context, FuriString* output); + +/** + * Calculate CRC8 for Marantec protocol. + * @param data Pointer to the data buffer + * @param len Length of the data buffer + * @return CRC8 value + */ +uint8_t subghz_protocol_marantec_crc8(uint8_t* data, size_t len); diff --git a/lib/subghz/protocols/marantec24.c b/lib/subghz/protocols/marantec24.c new file mode 100644 index 00000000000..e2ff9218b27 --- /dev/null +++ b/lib/subghz/protocols/marantec24.c @@ -0,0 +1,352 @@ +#include "marantec24.h" +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolMarantec24" + +static const SubGhzBlockConst subghz_protocol_marantec24_const = { + .te_short = 800, + .te_long = 1600, + .te_delta = 200, + .min_count_bit_for_found = 24, +}; + +struct SubGhzProtocolDecoderMarantec24 { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; +}; + +struct SubGhzProtocolEncoderMarantec24 { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + Marantec24DecoderStepReset = 0, + Marantec24DecoderStepSaveDuration, + Marantec24DecoderStepCheckDuration, +} Marantec24DecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_marantec24_decoder = { + .alloc = subghz_protocol_decoder_marantec24_alloc, + .free = subghz_protocol_decoder_marantec24_free, + + .feed = subghz_protocol_decoder_marantec24_feed, + .reset = subghz_protocol_decoder_marantec24_reset, + + .get_hash_data = subghz_protocol_decoder_marantec24_get_hash_data, + .serialize = subghz_protocol_decoder_marantec24_serialize, + .deserialize = subghz_protocol_decoder_marantec24_deserialize, + .get_string = subghz_protocol_decoder_marantec24_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_marantec24_encoder = { + .alloc = subghz_protocol_encoder_marantec24_alloc, + .free = subghz_protocol_encoder_marantec24_free, + + .deserialize = subghz_protocol_encoder_marantec24_deserialize, + .stop = subghz_protocol_encoder_marantec24_stop, + .yield = subghz_protocol_encoder_marantec24_yield, +}; + +const SubGhzProtocol subghz_protocol_marantec24 = { + .name = SUBGHZ_PROTOCOL_MARANTEC24_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_868 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | + SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_marantec24_decoder, + .encoder = &subghz_protocol_marantec24_encoder, +}; + +void* subghz_protocol_encoder_marantec24_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderMarantec24* instance = malloc(sizeof(SubGhzProtocolEncoderMarantec24)); + + instance->base.protocol = &subghz_protocol_marantec24; + instance->generic.protocol_name = instance->base.protocol->name; + + instance->encoder.repeat = 10; + instance->encoder.size_upload = 512; + instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); + instance->encoder.is_running = false; + return instance; +} + +void subghz_protocol_encoder_marantec24_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderMarantec24* instance = context; + free(instance->encoder.upload); + free(instance); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderMarantec24 instance + */ +static void + subghz_protocol_encoder_marantec24_get_upload(SubGhzProtocolEncoderMarantec24* instance) { + furi_assert(instance); + size_t index = 0; + // Send initial GAP to trigger decoder + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_marantec24_const.te_long * 9); + for(size_t r = 0; r < 4; r++) { + // Send key and GAP + 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_marantec24_const.te_short); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, + (uint32_t)subghz_protocol_marantec24_const.te_long * 9 + + subghz_protocol_marantec24_const.te_short); + } else { + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_marantec24_const.te_long * 2); + } + } else { + // Send bit 0 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_marantec24_const.te_long); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, + (uint32_t)subghz_protocol_marantec24_const.te_long * 9 + + subghz_protocol_marantec24_const.te_short); // 15200 + } else { + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_marantec24_const.te_short * 3); + } + } + } + } + + instance->encoder.size_upload = index; + return; +} + +/** + * Analysis of received data + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_marantec24_check_remote_controller(SubGhzBlockGeneric* instance) { + instance->serial = instance->data >> 4; + instance->btn = instance->data & 0xF; +} + +SubGhzProtocolStatus + subghz_protocol_encoder_marantec24_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderMarantec24* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_marantec24_const.min_count_bit_for_found); + if(ret != SubGhzProtocolStatusOk) { + break; + } + //optional parameter parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + subghz_protocol_marantec24_check_remote_controller(&instance->generic); + subghz_protocol_encoder_marantec24_get_upload(instance); + instance->encoder.front = 0; // reset before start + instance->encoder.is_running = true; + } while(false); + + return ret; +} + +void subghz_protocol_encoder_marantec24_stop(void* context) { + SubGhzProtocolEncoderMarantec24* instance = context; + instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position +} + +LevelDuration subghz_protocol_encoder_marantec24_yield(void* context) { + SubGhzProtocolEncoderMarantec24* 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_marantec24_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderMarantec24* instance = malloc(sizeof(SubGhzProtocolDecoderMarantec24)); + instance->base.protocol = &subghz_protocol_marantec24; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_marantec24_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderMarantec24* instance = context; + free(instance); +} + +void subghz_protocol_decoder_marantec24_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderMarantec24* instance = context; + instance->decoder.parser_step = Marantec24DecoderStepReset; +} + +void subghz_protocol_decoder_marantec24_feed(void* context, bool level, volatile uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderMarantec24* instance = context; + + // Marantec24 Decoder + // 2024 - @xMasterX (MMX) + + // 2025 update - The protocol is not real marantec, + // it comes from chinese remote that pretends to be replica of original marantec, actually it was a cloner + // which had some thing written on it, which is uknown, but since its pretentding to be marantec, + // it was decided to keep the name of the protocol as marantec24 (24 bits) + + // Key samples + // 101011000000010111001000 = AC05C8 + // 101011000000010111000100 = AC05C4 + // 101011000000010111001100 = AC05CC + // 101011000000010111000000 = AC05C0 + + switch(instance->decoder.parser_step) { + case Marantec24DecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_marantec24_const.te_long * 9) < + subghz_protocol_marantec24_const.te_delta * 6)) { + //Found GAP + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = Marantec24DecoderStepSaveDuration; + } + break; + case Marantec24DecoderStepSaveDuration: + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = Marantec24DecoderStepCheckDuration; + } else { + instance->decoder.parser_step = Marantec24DecoderStepReset; + } + break; + case Marantec24DecoderStepCheckDuration: + if(!level) { + // Bit 0 is long and short x2 timing = 1600us HIGH (te_last) and 2400us LOW + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_marantec24_const.te_long) < + subghz_protocol_marantec24_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_marantec24_const.te_short * 3) < + subghz_protocol_marantec24_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = Marantec24DecoderStepSaveDuration; + // Bit 1 is short and long x2 timing = 800us HIGH (te_last) and 3200us LOW + } else if( + (DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_marantec24_const.te_short) < + subghz_protocol_marantec24_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_marantec24_const.te_long * 2) < + subghz_protocol_marantec24_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = Marantec24DecoderStepSaveDuration; + } else if( + // End of the key + DURATION_DIFF(duration, subghz_protocol_marantec24_const.te_long * 9) < + subghz_protocol_marantec24_const.te_delta * 6) { + //Found next GAP and add bit 0 or 1 (only bit 0 was found on the remotes) + if((DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_marantec24_const.te_long) < + subghz_protocol_marantec24_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + } + if((DURATION_DIFF( + instance->decoder.te_last, subghz_protocol_marantec24_const.te_short) < + subghz_protocol_marantec24_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + } + // If got 24 bits key reading is finished + if(instance->decoder.decode_count_bit == + subghz_protocol_marantec24_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; + instance->decoder.parser_step = Marantec24DecoderStepReset; + } else { + instance->decoder.parser_step = Marantec24DecoderStepReset; + } + } else { + instance->decoder.parser_step = Marantec24DecoderStepReset; + } + break; + } +} + +uint8_t subghz_protocol_decoder_marantec24_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderMarantec24* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_marantec24_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderMarantec24* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + subghz_protocol_decoder_marantec24_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderMarantec24* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_marantec24_const.min_count_bit_for_found); +} + +void subghz_protocol_decoder_marantec24_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderMarantec24* instance = context; + + subghz_protocol_marantec24_check_remote_controller(&instance->generic); + + furi_string_cat_printf( + output, + "%s %db\r\n" + "Key: 0x%06lX\r\n" + "Serial: 0x%05lX\r\n" + "Btn: %01X", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data & 0xFFFFFF), + instance->generic.serial, + instance->generic.btn); +} diff --git a/lib/subghz/protocols/marantec24.h b/lib/subghz/protocols/marantec24.h new file mode 100644 index 00000000000..862eb7e2a93 --- /dev/null +++ b/lib/subghz/protocols/marantec24.h @@ -0,0 +1,109 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_MARANTEC24_NAME "Marantec24" + +typedef struct SubGhzProtocolDecoderMarantec24 SubGhzProtocolDecoderMarantec24; +typedef struct SubGhzProtocolEncoderMarantec24 SubGhzProtocolEncoderMarantec24; + +extern const SubGhzProtocolDecoder subghz_protocol_marantec24_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_marantec24_encoder; +extern const SubGhzProtocol subghz_protocol_marantec24; + +/** + * Allocate SubGhzProtocolEncoderMarantec24. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderMarantec24* pointer to a SubGhzProtocolEncoderMarantec24 instance + */ +void* subghz_protocol_encoder_marantec24_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderMarantec24. + * @param context Pointer to a SubGhzProtocolEncoderMarantec24 instance + */ +void subghz_protocol_encoder_marantec24_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderMarantec24 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_encoder_marantec24_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderMarantec24 instance + */ +void subghz_protocol_encoder_marantec24_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderMarantec24 instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_marantec24_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderMarantec24. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderMarantec24* pointer to a SubGhzProtocolDecoderMarantec24 instance + */ +void* subghz_protocol_decoder_marantec24_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderMarantec24. + * @param context Pointer to a SubGhzProtocolDecoderMarantec24 instance + */ +void subghz_protocol_decoder_marantec24_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderMarantec24. + * @param context Pointer to a SubGhzProtocolDecoderMarantec24 instance + */ +void subghz_protocol_decoder_marantec24_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderMarantec24 instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_marantec24_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderMarantec24 instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_marantec24_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderMarantec24. + * @param context Pointer to a SubGhzProtocolDecoderMarantec24 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_marantec24_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderMarantec24. + * @param context Pointer to a SubGhzProtocolDecoderMarantec24 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_marantec24_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderMarantec24 instance + * @param output Resulting text + */ +void subghz_protocol_decoder_marantec24_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/phoenix_v2.c b/lib/subghz/protocols/phoenix_v2.c index 2fabed73d5e..5665fd29679 100644 --- a/lib/subghz/protocols/phoenix_v2.c +++ b/lib/subghz/protocols/phoenix_v2.c @@ -7,7 +7,6 @@ #include "../blocks/math.h" #define TAG "SubGhzProtocolPhoenixV2" - //transmission only static mode static const SubGhzBlockConst subghz_protocol_phoenix_v2_const = { @@ -91,6 +90,9 @@ void subghz_protocol_encoder_phoenix_v2_free(void* context) { free(instance); } +// Pre define functions +static void subghz_protocol_phoenix_v2_check_remote_controller(SubGhzBlockGeneric* instance); + /** * Generating an upload from data. * @param instance Pointer to a SubGhzProtocolEncoderPhoenix_V2 instance @@ -107,6 +109,7 @@ static bool } else { instance->encoder.size_upload = size_upload; } + //Send header instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)subghz_protocol_phoenix_v2_const.te_short * 60); @@ -153,6 +156,7 @@ SubGhzProtocolStatus ret = SubGhzProtocolStatusErrorEncoderGetUpload; break; } + instance->encoder.is_running = true; } while(false); @@ -274,16 +278,66 @@ void subghz_protocol_decoder_phoenix_v2_feed(void* context, bool level, uint32_t } } +static uint16_t subghz_protocol_phoenix_v2_decrypt_counter(uint64_t full_key) { + uint16_t encrypted_value = (uint16_t)((full_key >> 40) & 0xFFFF); + + uint8_t byte1 = (uint8_t)(encrypted_value >> 8); // First encrypted counter byte + uint8_t byte2 = (uint8_t)(encrypted_value & 0xFF); // Second encrypted counter byte + + uint8_t xor_key1 = (uint8_t)(full_key >> 24); // First byte of serial + uint8_t xor_key2 = (uint8_t)((full_key >> 16) & 0xFF); // Second byte of serial + + for(int i = 0; i < 16; i++) { + // Store the most significant bit (MSB) of byte1. + // The check `(msb_of_byte1 == 0)` will determine if we apply the XOR keys. + uint8_t msb_of_byte1 = byte1 & 0x80; + + // Store the least significant bit (LSB) of byte2. + uint8_t lsb_of_byte2 = byte2 & 1; + + // Perform a bit shuffle between the two bytes + byte2 = (byte2 >> 1) | msb_of_byte1; + byte1 = (byte1 << 1) | lsb_of_byte2; + + // Conditionally apply the XOR keys based on the original MSB of byte1. + if(msb_of_byte1 == 0) { + byte1 ^= xor_key1; + // The mask `& 0x7F` clears the MSB of byte2 after the XOR. + byte2 = (byte2 ^ xor_key2) & 0x7F; + } + } + + return (uint16_t)byte2 << 8 | byte1; +} + /** * Analysis of received data * @param instance Pointer to a SubGhzBlockGeneric* instance */ static void subghz_protocol_phoenix_v2_check_remote_controller(SubGhzBlockGeneric* instance) { + // 2022.08 - @Skorpionm + // 2025.07 - @xMasterX & @RocketGod-git + // Fully supported now, with button switch and add manually + // + // Key samples + // Full key example: 0xC63E01B9615720 - after subghz_protocol_blocks_reverse_key was applied + // Serial - B9615720 + // Button - 01 + // Encrypted -> Decrypted counters + // C63E - 025C + // BCC1 - 025D + // 3341 - 025E + // 49BE - 025F + // 99D3 - 0260 + // E32C - 0261 + uint64_t data_rev = subghz_protocol_blocks_reverse_key(instance->data, instance->data_count_bit + 4); + instance->serial = data_rev & 0xFFFFFFFF; - instance->cnt = (data_rev >> 40) & 0xFFFF; + instance->cnt = subghz_protocol_phoenix_v2_decrypt_counter(data_rev); instance->btn = (data_rev >> 32) & 0xF; + // encrypted cnt is (data_rev >> 40) & 0xFFFF } uint8_t subghz_protocol_decoder_phoenix_v2_get_hash_data(void* context) { @@ -318,14 +372,15 @@ void subghz_protocol_decoder_phoenix_v2_get_string(void* context, FuriString* ou subghz_protocol_phoenix_v2_check_remote_controller(&instance->generic); furi_string_cat_printf( output, - "%s %dbit\r\n" - "Key:%02lX%08lX\r\n" + "V2 Phoenix %dbit\r\n" + "Key:%05lX%08lX\r\n" "Sn:0x%07lX \r\n" - "Btn:%X\r\n", - instance->generic.protocol_name, + "Cnt: 0x%04lX\r\n" + "Btn: %X\r\n", instance->generic.data_count_bit, (uint32_t)(instance->generic.data >> 32) & 0xFFFFFFFF, (uint32_t)(instance->generic.data & 0xFFFFFFFF), instance->generic.serial, + instance->generic.cnt, instance->generic.btn); } diff --git a/lib/subghz/protocols/power_smart.c b/lib/subghz/protocols/power_smart.c index 828c4a76eaa..1359f416d7f 100644 --- a/lib/subghz/protocols/power_smart.c +++ b/lib/subghz/protocols/power_smart.c @@ -212,6 +212,7 @@ SubGhzProtocolStatus subghz_protocol_power_smart_remote_controller(&instance->generic); subghz_protocol_encoder_power_smart_get_upload(instance); + instance->encoder.front = 0; // reset before start instance->encoder.is_running = true; } while(false); @@ -221,6 +222,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_power_smart_stop(void* context) { SubGhzProtocolEncoderPowerSmart* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position } LevelDuration subghz_protocol_encoder_power_smart_yield(void* context) { diff --git a/lib/subghz/protocols/protocol_items.c b/lib/subghz/protocols/protocol_items.c index d7a14cd1cb8..91ceaec3202 100644 --- a/lib/subghz/protocols/protocol_items.c +++ b/lib/subghz/protocols/protocol_items.c @@ -44,7 +44,15 @@ const SubGhzProtocol* const subghz_protocol_registry_items[] = { &subghz_protocol_kinggates_stylo_4k, &subghz_protocol_bin_raw, &subghz_protocol_mastercode, + &subghz_protocol_legrand, &subghz_protocol_dickert_mahs, + &subghz_protocol_gangqi, + &subghz_protocol_marantec24, + &subghz_protocol_hollarm, + &subghz_protocol_hay21, + &subghz_protocol_revers_rb2, + &subghz_protocol_feron, + &subghz_protocol_roger, }; const SubGhzProtocolRegistry subghz_protocol_registry = { diff --git a/lib/subghz/protocols/protocol_items.h b/lib/subghz/protocols/protocol_items.h index ae531c3f9b6..1cde46ef500 100644 --- a/lib/subghz/protocols/protocol_items.h +++ b/lib/subghz/protocols/protocol_items.h @@ -45,4 +45,12 @@ #include "kinggates_stylo_4k.h" #include "bin_raw.h" #include "mastercode.h" +#include "legrand.h" #include "dickert_mahs.h" +#include "gangqi.h" +#include "marantec24.h" +#include "hollarm.h" +#include "hay21.h" +#include "revers_rb2.h" +#include "feron.h" +#include "roger.h" diff --git a/lib/subghz/protocols/public_api.h b/lib/subghz/protocols/public_api.h index 174f175cdfa..a5a980b3bba 100644 --- a/lib/subghz/protocols/public_api.h +++ b/lib/subghz/protocols/public_api.h @@ -31,7 +31,7 @@ bool subghz_protocol_secplus_v2_create_data( * @param flipper_format Pointer to a FlipperFormat instance * @param serial Serial number, 28 bit * @param btn Button number, 4 bit - * @param cnt Container value, 16 bit + * @param cnt Counter value, 16 bit * @param manufacture_name Name of manufacturer's key * @param preset Modulation, SubGhzRadioPreset * @return true On success diff --git a/lib/subghz/protocols/raw.c b/lib/subghz/protocols/raw.c index d7b31be3791..96908130e9e 100644 --- a/lib/subghz/protocols/raw.c +++ b/lib/subghz/protocols/raw.c @@ -245,8 +245,8 @@ void subghz_protocol_decoder_raw_reset(void* context) { void subghz_protocol_decoder_raw_feed(void* context, bool level, uint32_t duration) { furi_check(context); SubGhzProtocolDecoderRAW* instance = context; - - if(!instance->pause && (instance->upload_raw != NULL)) { + // Add check if we got duration higher than 1 second, we skipping it, temp fix + if((!instance->pause && (instance->upload_raw != NULL)) && (duration < ((uint32_t)1000000))) { if(duration > subghz_protocol_raw_const.te_short) { if(instance->last_level != level) { instance->last_level = (level ? true : false); @@ -273,7 +273,7 @@ void subghz_protocol_decoder_raw_get_string(void* context, FuriString* output) { furi_check(context); //SubGhzProtocolDecoderRAW* instance = context; UNUSED(context); - furi_string_cat_printf(output, "RAW Date"); + furi_string_cat_printf(output, "RAW Data"); } void* subghz_protocol_encoder_raw_alloc(SubGhzEnvironment* environment) { diff --git a/lib/subghz/protocols/revers_rb2.c b/lib/subghz/protocols/revers_rb2.c new file mode 100644 index 00000000000..156a506be0f --- /dev/null +++ b/lib/subghz/protocols/revers_rb2.c @@ -0,0 +1,415 @@ +#include "revers_rb2.h" +#include +#include +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolRevers_RB2" + +static const SubGhzBlockConst subghz_protocol_revers_rb2_const = { + .te_short = 250, + .te_long = 500, + .te_delta = 160, + .min_count_bit_for_found = 64, +}; + +struct SubGhzProtocolDecoderRevers_RB2 { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; + ManchesterState manchester_saved_state; + uint16_t header_count; +}; + +struct SubGhzProtocolEncoderRevers_RB2 { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + Revers_RB2DecoderStepReset = 0, + Revers_RB2DecoderStepHeader, + Revers_RB2DecoderStepDecoderData, +} Revers_RB2DecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_revers_rb2_decoder = { + .alloc = subghz_protocol_decoder_revers_rb2_alloc, + .free = subghz_protocol_decoder_revers_rb2_free, + + .feed = subghz_protocol_decoder_revers_rb2_feed, + .reset = subghz_protocol_decoder_revers_rb2_reset, + + .get_hash_data = subghz_protocol_decoder_revers_rb2_get_hash_data, + .serialize = subghz_protocol_decoder_revers_rb2_serialize, + .deserialize = subghz_protocol_decoder_revers_rb2_deserialize, + .get_string = subghz_protocol_decoder_revers_rb2_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_revers_rb2_encoder = { + .alloc = subghz_protocol_encoder_revers_rb2_alloc, + .free = subghz_protocol_encoder_revers_rb2_free, + + .deserialize = subghz_protocol_encoder_revers_rb2_deserialize, + .stop = subghz_protocol_encoder_revers_rb2_stop, + .yield = subghz_protocol_encoder_revers_rb2_yield, +}; + +const SubGhzProtocol subghz_protocol_revers_rb2 = { + .name = SUBGHZ_PROTOCOL_REVERSRB2_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable | + SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_revers_rb2_decoder, + .encoder = &subghz_protocol_revers_rb2_encoder, +}; + +void* subghz_protocol_encoder_revers_rb2_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderRevers_RB2* instance = malloc(sizeof(SubGhzProtocolEncoderRevers_RB2)); + + instance->base.protocol = &subghz_protocol_revers_rb2; + instance->generic.protocol_name = instance->base.protocol->name; + + instance->encoder.repeat = 10; + instance->encoder.size_upload = 1768; + instance->encoder.upload = malloc(instance->encoder.size_upload * sizeof(LevelDuration)); + instance->encoder.is_running = false; + return instance; +} + +void subghz_protocol_encoder_revers_rb2_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderRevers_RB2* instance = context; + free(instance->encoder.upload); + free(instance); +} + +static LevelDuration + subghz_protocol_encoder_revers_rb2_add_duration_to_upload(ManchesterEncoderResult result) { + LevelDuration data = {.duration = 0, .level = 0}; + switch(result) { + case ManchesterEncoderResultShortLow: + data.duration = subghz_protocol_revers_rb2_const.te_short; + data.level = false; + break; + case ManchesterEncoderResultLongLow: + data.duration = subghz_protocol_revers_rb2_const.te_long; + data.level = false; + break; + case ManchesterEncoderResultLongHigh: + data.duration = subghz_protocol_revers_rb2_const.te_long; + data.level = true; + break; + case ManchesterEncoderResultShortHigh: + data.duration = subghz_protocol_revers_rb2_const.te_short; + data.level = true; + break; + + default: + furi_crash("SubGhz: ManchesterEncoderResult is incorrect."); + break; + } + return level_duration_make(data.level, data.duration); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderRevers_RB2 instance + */ +static void + subghz_protocol_encoder_revers_rb2_get_upload(SubGhzProtocolEncoderRevers_RB2* instance) { + furi_assert(instance); + size_t index = 0; + + for(size_t r = 0; r < 6; r++) { + ManchesterEncoderState enc_state; + manchester_encoder_reset(&enc_state); + ManchesterEncoderResult result; + + for(uint8_t i = instance->generic.data_count_bit; i > 0; i--) { + if(!manchester_encoder_advance( + &enc_state, bit_read(instance->generic.data, i - 1), &result)) { + instance->encoder.upload[index++] = + subghz_protocol_encoder_revers_rb2_add_duration_to_upload(result); + manchester_encoder_advance( + &enc_state, bit_read(instance->generic.data, i - 1), &result); + } + instance->encoder.upload[index++] = + subghz_protocol_encoder_revers_rb2_add_duration_to_upload(result); + } + instance->encoder.upload[index] = + subghz_protocol_encoder_revers_rb2_add_duration_to_upload( + manchester_encoder_finish(&enc_state)); + if(level_duration_get_level(instance->encoder.upload[index])) { + index++; + } + instance->encoder.upload[index++] = level_duration_make(false, (uint32_t)320); + } + instance->encoder.size_upload = index; +} + +/** + * Analysis of received data + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_revers_rb2_remote_controller(SubGhzBlockGeneric* instance) { + // Revers RB2 / RB2M Decoder + // 02.2025 - @xMasterX (MMX) + instance->serial = (((instance->data << 16) >> 16) >> 10); +} + +SubGhzProtocolStatus + subghz_protocol_encoder_revers_rb2_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderRevers_RB2* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_revers_rb2_const.min_count_bit_for_found); + if(ret != SubGhzProtocolStatusOk) { + break; + } + //optional parameter parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + subghz_protocol_revers_rb2_remote_controller(&instance->generic); + subghz_protocol_encoder_revers_rb2_get_upload(instance); + instance->encoder.front = 0; + instance->encoder.is_running = true; + } while(false); + + return ret; +} + +void subghz_protocol_encoder_revers_rb2_stop(void* context) { + SubGhzProtocolEncoderRevers_RB2* instance = context; + instance->encoder.is_running = false; + instance->encoder.front = 0; +} + +LevelDuration subghz_protocol_encoder_revers_rb2_yield(void* context) { + SubGhzProtocolEncoderRevers_RB2* 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_revers_rb2_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderRevers_RB2* instance = malloc(sizeof(SubGhzProtocolDecoderRevers_RB2)); + instance->base.protocol = &subghz_protocol_revers_rb2; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_revers_rb2_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderRevers_RB2* instance = context; + free(instance); +} + +void subghz_protocol_decoder_revers_rb2_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderRevers_RB2* instance = context; + instance->decoder.parser_step = Revers_RB2DecoderStepReset; + instance->header_count = 0; + manchester_advance( + instance->manchester_saved_state, + ManchesterEventReset, + &instance->manchester_saved_state, + NULL); +} + +void subghz_protocol_decoder_revers_rb2_addbit(void* context, bool data) { + SubGhzProtocolDecoderRevers_RB2* instance = context; + instance->decoder.decode_data = (instance->decoder.decode_data << 1) | data; + instance->decoder.decode_count_bit++; + + if(instance->decoder.decode_count_bit >= 65) { + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + return; + } + + if(instance->decoder.decode_count_bit < + subghz_protocol_revers_rb2_const.min_count_bit_for_found) { + return; + } + + // Revers RB2 / RB2M Decoder + // 02.2025 - @xMasterX (MMX) + + uint16_t preamble = (instance->decoder.decode_data >> 48) & 0xFF; + uint16_t stop_code = (instance->decoder.decode_data & 0x3FF); + + if(preamble == 0xFF && stop_code == 0x200) { + //Found header and stop code + 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; + manchester_advance( + instance->manchester_saved_state, + ManchesterEventReset, + &instance->manchester_saved_state, + NULL); + } +} + +void subghz_protocol_decoder_revers_rb2_feed(void* context, bool level, volatile uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderRevers_RB2* instance = context; + ManchesterEvent event = ManchesterEventReset; + + switch(instance->decoder.parser_step) { + case Revers_RB2DecoderStepReset: + if((!level) && + (DURATION_DIFF(duration, 600) < subghz_protocol_revers_rb2_const.te_delta)) { + instance->decoder.parser_step = Revers_RB2DecoderStepHeader; + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + manchester_advance( + instance->manchester_saved_state, + ManchesterEventReset, + &instance->manchester_saved_state, + NULL); + } + break; + case Revers_RB2DecoderStepHeader: + if(!level) { + if(DURATION_DIFF(duration, subghz_protocol_revers_rb2_const.te_short) < + subghz_protocol_revers_rb2_const.te_delta) { + if(instance->decoder.te_last == 1) { + instance->header_count++; + } + instance->decoder.te_last = level; + } else { + instance->header_count = 0; + instance->decoder.te_last = 0; + instance->decoder.parser_step = Revers_RB2DecoderStepReset; + } + } else { + if(DURATION_DIFF(duration, subghz_protocol_revers_rb2_const.te_short) < + subghz_protocol_revers_rb2_const.te_delta) { + if(instance->decoder.te_last == 0) { + instance->header_count++; + } + instance->decoder.te_last = level; + } else { + instance->header_count = 0; + instance->decoder.te_last = 0; + instance->decoder.parser_step = Revers_RB2DecoderStepReset; + } + } + + if(instance->header_count == 4) { + instance->header_count = 0; + instance->decoder.decode_data = 0xF; + instance->decoder.decode_count_bit = 4; + instance->decoder.parser_step = Revers_RB2DecoderStepDecoderData; + } + break; + case Revers_RB2DecoderStepDecoderData: + if(!level) { + if(DURATION_DIFF(duration, subghz_protocol_revers_rb2_const.te_short) < + subghz_protocol_revers_rb2_const.te_delta) { + event = ManchesterEventShortLow; + } else if( + DURATION_DIFF(duration, subghz_protocol_revers_rb2_const.te_long) < + subghz_protocol_revers_rb2_const.te_delta) { + event = ManchesterEventLongLow; + } else { + instance->decoder.parser_step = Revers_RB2DecoderStepReset; + } + } else { + if(DURATION_DIFF(duration, subghz_protocol_revers_rb2_const.te_short) < + subghz_protocol_revers_rb2_const.te_delta) { + event = ManchesterEventShortHigh; + } else if( + DURATION_DIFF(duration, subghz_protocol_revers_rb2_const.te_long) < + subghz_protocol_revers_rb2_const.te_delta) { + event = ManchesterEventLongHigh; + } else { + instance->decoder.parser_step = Revers_RB2DecoderStepReset; + } + } + if(event != ManchesterEventReset) { + bool data; + bool data_ok = manchester_advance( + instance->manchester_saved_state, event, &instance->manchester_saved_state, &data); + + if(data_ok) { + subghz_protocol_decoder_revers_rb2_addbit(instance, data); + } + } + break; + } +} + +uint8_t subghz_protocol_decoder_revers_rb2_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderRevers_RB2* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_revers_rb2_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderRevers_RB2* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + subghz_protocol_decoder_revers_rb2_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderRevers_RB2* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_revers_rb2_const.min_count_bit_for_found); +} + +void subghz_protocol_decoder_revers_rb2_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderRevers_RB2* instance = context; + subghz_protocol_revers_rb2_remote_controller(&instance->generic); + + furi_string_cat_printf( + output, + "%s %db\r\n" + "Key:%lX%08lX\r\n" + "Sn:0x%08lX \r\n", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data >> 32), + (uint32_t)(instance->generic.data & 0xFFFFFFFF), + instance->generic.serial); +} diff --git a/lib/subghz/protocols/revers_rb2.h b/lib/subghz/protocols/revers_rb2.h new file mode 100644 index 00000000000..7ccd2a9a217 --- /dev/null +++ b/lib/subghz/protocols/revers_rb2.h @@ -0,0 +1,109 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_REVERSRB2_NAME "Revers_RB2" + +typedef struct SubGhzProtocolDecoderRevers_RB2 SubGhzProtocolDecoderRevers_RB2; +typedef struct SubGhzProtocolEncoderRevers_RB2 SubGhzProtocolEncoderRevers_RB2; + +extern const SubGhzProtocolDecoder subghz_protocol_revers_rb2_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_revers_rb2_encoder; +extern const SubGhzProtocol subghz_protocol_revers_rb2; + +/** + * Allocate SubGhzProtocolEncoderRevers_RB2. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderRevers_RB2* pointer to a SubGhzProtocolEncoderRevers_RB2 instance + */ +void* subghz_protocol_encoder_revers_rb2_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderRevers_RB2. + * @param context Pointer to a SubGhzProtocolEncoderRevers_RB2 instance + */ +void subghz_protocol_encoder_revers_rb2_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderRevers_RB2 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_encoder_revers_rb2_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderRevers_RB2 instance + */ +void subghz_protocol_encoder_revers_rb2_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderRevers_RB2 instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_revers_rb2_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderRevers_RB2. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderRevers_RB2* pointer to a SubGhzProtocolDecoderRevers_RB2 instance + */ +void* subghz_protocol_decoder_revers_rb2_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderRevers_RB2. + * @param context Pointer to a SubGhzProtocolDecoderRevers_RB2 instance + */ +void subghz_protocol_decoder_revers_rb2_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderRevers_RB2. + * @param context Pointer to a SubGhzProtocolDecoderRevers_RB2 instance + */ +void subghz_protocol_decoder_revers_rb2_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderRevers_RB2 instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_revers_rb2_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderRevers_RB2 instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_revers_rb2_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderRevers_RB2. + * @param context Pointer to a SubGhzProtocolDecoderRevers_RB2 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_revers_rb2_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderRevers_RB2. + * @param context Pointer to a SubGhzProtocolDecoderRevers_RB2 instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_revers_rb2_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderRevers_RB2 instance + * @param output Resulting text + */ +void subghz_protocol_decoder_revers_rb2_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/roger.c b/lib/subghz/protocols/roger.c new file mode 100644 index 00000000000..f93b3366efd --- /dev/null +++ b/lib/subghz/protocols/roger.c @@ -0,0 +1,341 @@ +#include "roger.h" +#include "../blocks/const.h" +#include "../blocks/decoder.h" +#include "../blocks/encoder.h" +#include "../blocks/generic.h" +#include "../blocks/math.h" + +#define TAG "SubGhzProtocolRoger" + +static const SubGhzBlockConst subghz_protocol_roger_const = { + .te_short = 500, + .te_long = 1000, + .te_delta = 270, + .min_count_bit_for_found = 28, +}; + +struct SubGhzProtocolDecoderRoger { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + SubGhzBlockGeneric generic; +}; + +struct SubGhzProtocolEncoderRoger { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + SubGhzBlockGeneric generic; +}; + +typedef enum { + RogerDecoderStepReset = 0, + RogerDecoderStepSaveDuration, + RogerDecoderStepCheckDuration, +} RogerDecoderStep; + +const SubGhzProtocolDecoder subghz_protocol_roger_decoder = { + .alloc = subghz_protocol_decoder_roger_alloc, + .free = subghz_protocol_decoder_roger_free, + + .feed = subghz_protocol_decoder_roger_feed, + .reset = subghz_protocol_decoder_roger_reset, + + .get_hash_data = subghz_protocol_decoder_roger_get_hash_data, + .serialize = subghz_protocol_decoder_roger_serialize, + .deserialize = subghz_protocol_decoder_roger_deserialize, + .get_string = subghz_protocol_decoder_roger_get_string, +}; + +const SubGhzProtocolEncoder subghz_protocol_roger_encoder = { + .alloc = subghz_protocol_encoder_roger_alloc, + .free = subghz_protocol_encoder_roger_free, + + .deserialize = subghz_protocol_encoder_roger_deserialize, + .stop = subghz_protocol_encoder_roger_stop, + .yield = subghz_protocol_encoder_roger_yield, +}; + +const SubGhzProtocol subghz_protocol_roger = { + .name = SUBGHZ_PROTOCOL_ROGER_NAME, + .type = SubGhzProtocolTypeStatic, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_868 | SubGhzProtocolFlag_AM | + SubGhzProtocolFlag_Decodable | SubGhzProtocolFlag_Load | SubGhzProtocolFlag_Save | + SubGhzProtocolFlag_Send, + + .decoder = &subghz_protocol_roger_decoder, + .encoder = &subghz_protocol_roger_encoder, +}; + +void* subghz_protocol_encoder_roger_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolEncoderRoger* instance = malloc(sizeof(SubGhzProtocolEncoderRoger)); + + instance->base.protocol = &subghz_protocol_roger; + instance->generic.protocol_name = instance->base.protocol->name; + + 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_roger_free(void* context) { + furi_assert(context); + SubGhzProtocolEncoderRoger* instance = context; + free(instance->encoder.upload); + free(instance); +} + +/** + * Generating an upload from data. + * @param instance Pointer to a SubGhzProtocolEncoderRoger instance + */ +static void subghz_protocol_encoder_roger_get_upload(SubGhzProtocolEncoderRoger* instance) { + furi_assert(instance); + size_t index = 0; + + // Send key and GAP + 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_roger_const.te_long); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_roger_const.te_short * 19); + } else { + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_roger_const.te_short); + } + } else { + // Send bit 0 + instance->encoder.upload[index++] = + level_duration_make(true, (uint32_t)subghz_protocol_roger_const.te_short); + if(i == 1) { + //Send gap if bit was last + instance->encoder.upload[index++] = level_duration_make( + false, (uint32_t)subghz_protocol_roger_const.te_short * 19); + } else { + instance->encoder.upload[index++] = + level_duration_make(false, (uint32_t)subghz_protocol_roger_const.te_long); + } + } + } + + instance->encoder.size_upload = index; + return; +} + +/** + * Analysis of received data + * @param instance Pointer to a SubGhzBlockGeneric* instance + */ +static void subghz_protocol_roger_check_remote_controller(SubGhzBlockGeneric* instance) { + // Roger Decoder + // 2025.07 - @xMasterX (MMX) + + // Key samples + // 0010001111111001 0001 00100000 // S/N: 0x23F9 Btn: 0x1 End: 0x20 + // 0010001111111001 0010 00100011 // S/N: 0x23F9 Btn: 0x2 End: 0x23 + // 0101011001010110 0001 00000001 // S/N: 0x5656 Btn: 0x1 End: 0x01 + // 0101011001010110 0010 00000010 // S/N: 0x5656 Btn: 0x2 End: 0x02 + // 0000110111111110 0001 00000001 // S/N: 0x0DFE Btn: 0x1 End: 0x01 + // 0000110111111110 0100 00000100 // S/N: 0x0DFE Btn: 0x4 End: 0x04 + // 0000110111111110 0010 00000010 // S/N: 0x0DFE Btn: 0x2 End: 0x02 + // 0000110111111110 1000 00001000 // S/N: 0x0DFE Btn: 0x8 End: 0x08 + + instance->serial = instance->data >> 12; + instance->btn = (instance->data >> 8) & 0xF; +} + +SubGhzProtocolStatus + subghz_protocol_encoder_roger_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolEncoderRoger* instance = context; + SubGhzProtocolStatus ret = SubGhzProtocolStatusError; + do { + ret = subghz_block_generic_deserialize_check_count_bit( + &instance->generic, + flipper_format, + subghz_protocol_roger_const.min_count_bit_for_found); + if(ret != SubGhzProtocolStatusOk) { + break; + } + //optional parameter parameter + flipper_format_read_uint32( + flipper_format, "Repeat", (uint32_t*)&instance->encoder.repeat, 1); + + subghz_protocol_roger_check_remote_controller(&instance->generic); + subghz_protocol_encoder_roger_get_upload(instance); + instance->encoder.front = 0; + + instance->encoder.is_running = true; + } while(false); + + return ret; +} + +void subghz_protocol_encoder_roger_stop(void* context) { + SubGhzProtocolEncoderRoger* instance = context; + instance->encoder.is_running = false; + instance->encoder.front = 0; +} + +LevelDuration subghz_protocol_encoder_roger_yield(void* context) { + SubGhzProtocolEncoderRoger* 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_roger_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + SubGhzProtocolDecoderRoger* instance = malloc(sizeof(SubGhzProtocolDecoderRoger)); + instance->base.protocol = &subghz_protocol_roger; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void subghz_protocol_decoder_roger_free(void* context) { + furi_assert(context); + SubGhzProtocolDecoderRoger* instance = context; + free(instance); +} + +void subghz_protocol_decoder_roger_reset(void* context) { + furi_assert(context); + SubGhzProtocolDecoderRoger* instance = context; + instance->decoder.parser_step = RogerDecoderStepReset; +} + +void subghz_protocol_decoder_roger_feed(void* context, bool level, volatile uint32_t duration) { + furi_assert(context); + SubGhzProtocolDecoderRoger* instance = context; + + switch(instance->decoder.parser_step) { + case RogerDecoderStepReset: + if((!level) && (DURATION_DIFF(duration, subghz_protocol_roger_const.te_short * 19) < + subghz_protocol_roger_const.te_delta * 5)) { + //Found GAP + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = RogerDecoderStepSaveDuration; + } + break; + case RogerDecoderStepSaveDuration: + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = RogerDecoderStepCheckDuration; + } else { + instance->decoder.parser_step = RogerDecoderStepReset; + } + break; + case RogerDecoderStepCheckDuration: + if(!level) { + // Bit 1 is long and short timing = 1000us HIGH (te_last) and 500us LOW + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_roger_const.te_long) < + subghz_protocol_roger_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_roger_const.te_short) < + subghz_protocol_roger_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = RogerDecoderStepSaveDuration; + // Bit 0 is short and long timing = 500us HIGH (te_last) and 1000us LOW + } else if( + (DURATION_DIFF(instance->decoder.te_last, subghz_protocol_roger_const.te_short) < + subghz_protocol_roger_const.te_delta) && + (DURATION_DIFF(duration, subghz_protocol_roger_const.te_long) < + subghz_protocol_roger_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = RogerDecoderStepSaveDuration; + } else if( + // End of the key + DURATION_DIFF(duration, subghz_protocol_roger_const.te_short * 19) < + subghz_protocol_roger_const.te_delta * 5) { + //Found next GAP and add bit 1 or 0 + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_roger_const.te_long) < + subghz_protocol_roger_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + } + if((DURATION_DIFF(instance->decoder.te_last, subghz_protocol_roger_const.te_short) < + subghz_protocol_roger_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + } + // If got full 28 bits key reading is finished + if(instance->decoder.decode_count_bit == + subghz_protocol_roger_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; + instance->decoder.parser_step = RogerDecoderStepReset; + } else { + instance->decoder.parser_step = RogerDecoderStepReset; + } + } else { + instance->decoder.parser_step = RogerDecoderStepReset; + } + break; + } +} + +uint8_t subghz_protocol_decoder_roger_get_hash_data(void* context) { + furi_assert(context); + SubGhzProtocolDecoderRoger* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +SubGhzProtocolStatus subghz_protocol_decoder_roger_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + SubGhzProtocolDecoderRoger* instance = context; + return subghz_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +SubGhzProtocolStatus + subghz_protocol_decoder_roger_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + SubGhzProtocolDecoderRoger* instance = context; + return subghz_block_generic_deserialize_check_count_bit( + &instance->generic, flipper_format, subghz_protocol_roger_const.min_count_bit_for_found); +} + +void subghz_protocol_decoder_roger_get_string(void* context, FuriString* output) { + furi_assert(context); + SubGhzProtocolDecoderRoger* instance = context; + + subghz_protocol_roger_check_remote_controller(&instance->generic); + + furi_string_cat_printf( + output, + "%s %db\r\n" + "Key: 0x%07lX\r\n" + "Serial: 0x%04lX\r\n" + "End: 0x%02lX\r\n" + "Btn: %01X", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data & 0xFFFFFFF), + instance->generic.serial, + (uint32_t)(instance->generic.data & 0xFF), + instance->generic.btn); +} diff --git a/lib/subghz/protocols/roger.h b/lib/subghz/protocols/roger.h new file mode 100644 index 00000000000..c279164f955 --- /dev/null +++ b/lib/subghz/protocols/roger.h @@ -0,0 +1,109 @@ +#pragma once + +#include "base.h" + +#define SUBGHZ_PROTOCOL_ROGER_NAME "Roger" + +typedef struct SubGhzProtocolDecoderRoger SubGhzProtocolDecoderRoger; +typedef struct SubGhzProtocolEncoderRoger SubGhzProtocolEncoderRoger; + +extern const SubGhzProtocolDecoder subghz_protocol_roger_decoder; +extern const SubGhzProtocolEncoder subghz_protocol_roger_encoder; +extern const SubGhzProtocol subghz_protocol_roger; + +/** + * Allocate SubGhzProtocolEncoderRoger. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolEncoderRoger* pointer to a SubGhzProtocolEncoderRoger instance + */ +void* subghz_protocol_encoder_roger_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolEncoderRoger. + * @param context Pointer to a SubGhzProtocolEncoderRoger instance + */ +void subghz_protocol_encoder_roger_free(void* context); + +/** + * Deserialize and generating an upload to send. + * @param context Pointer to a SubGhzProtocolEncoderRoger instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_encoder_roger_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Forced transmission stop. + * @param context Pointer to a SubGhzProtocolEncoderRoger instance + */ +void subghz_protocol_encoder_roger_stop(void* context); + +/** + * Getting the level and duration of the upload to be loaded into DMA. + * @param context Pointer to a SubGhzProtocolEncoderRoger instance + * @return LevelDuration + */ +LevelDuration subghz_protocol_encoder_roger_yield(void* context); + +/** + * Allocate SubGhzProtocolDecoderRoger. + * @param environment Pointer to a SubGhzEnvironment instance + * @return SubGhzProtocolDecoderRoger* pointer to a SubGhzProtocolDecoderRoger instance + */ +void* subghz_protocol_decoder_roger_alloc(SubGhzEnvironment* environment); + +/** + * Free SubGhzProtocolDecoderRoger. + * @param context Pointer to a SubGhzProtocolDecoderRoger instance + */ +void subghz_protocol_decoder_roger_free(void* context); + +/** + * Reset decoder SubGhzProtocolDecoderRoger. + * @param context Pointer to a SubGhzProtocolDecoderRoger instance + */ +void subghz_protocol_decoder_roger_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a SubGhzProtocolDecoderRoger instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void subghz_protocol_decoder_roger_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a SubGhzProtocolDecoderRoger instance + * @return hash Hash sum + */ +uint8_t subghz_protocol_decoder_roger_get_hash_data(void* context); + +/** + * Serialize data SubGhzProtocolDecoderRoger. + * @param context Pointer to a SubGhzProtocolDecoderRoger 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_roger_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data SubGhzProtocolDecoderRoger. + * @param context Pointer to a SubGhzProtocolDecoderRoger instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return status + */ +SubGhzProtocolStatus + subghz_protocol_decoder_roger_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a SubGhzProtocolDecoderRoger instance + * @param output Resulting text + */ +void subghz_protocol_decoder_roger_get_string(void* context, FuriString* output); diff --git a/lib/subghz/protocols/scher_khan.c b/lib/subghz/protocols/scher_khan.c index bf8de10c96f..f1c41bd1e4a 100644 --- a/lib/subghz/protocols/scher_khan.c +++ b/lib/subghz/protocols/scher_khan.c @@ -219,18 +219,48 @@ static void subghz_protocol_scher_khan_check_remote_controller( */ switch(instance->data_count_bit) { - // case 35: //MAGIC CODE, Static - // instance->protocol_name = "MAGIC CODE, Static"; - // break; + 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 - // instance->protocol_name = "MAGIC CODE PRO / PRO2"; - // 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 ??? + *protocol_name = "MAGIC CODE PRO,\n Response"; + instance->serial = 0; + instance->btn = 0; + instance->cnt = 0; + break; + 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"; diff --git a/lib/subghz/protocols/secplus_v2.c b/lib/subghz/protocols/secplus_v2.c index 4f11e22b6bd..3a7a465133b 100644 --- a/lib/subghz/protocols/secplus_v2.c +++ b/lib/subghz/protocols/secplus_v2.c @@ -554,6 +554,7 @@ SubGhzProtocolStatus break; } + instance->encoder.front = 0; // reset before start instance->encoder.is_running = true; } while(false); @@ -563,6 +564,7 @@ SubGhzProtocolStatus void subghz_protocol_encoder_secplus_v2_stop(void* context) { SubGhzProtocolEncoderSecPlus_v2* instance = context; instance->encoder.is_running = false; + instance->encoder.front = 0; // reset position } LevelDuration subghz_protocol_encoder_secplus_v2_yield(void* context) {