Merge remote-tracking branch 'origin/dev' into release-candidate
This commit is contained in:
		
						commit
						9524a5ef74
					
				
							
								
								
									
										4
									
								
								.github/CODEOWNERS
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/CODEOWNERS
									
									
									
									
										vendored
									
									
								
							| @ -42,10 +42,10 @@ | |||||||
| /applications/examples/example_thermo/ @skotopes @DrZlo13 @hedger @gsurkov | /applications/examples/example_thermo/ @skotopes @DrZlo13 @hedger @gsurkov | ||||||
| 
 | 
 | ||||||
| # Firmware targets | # Firmware targets | ||||||
| /firmware/ @skotopes @DrZlo13 @hedger @nminaylov | /targets/ @skotopes @DrZlo13 @hedger @nminaylov | ||||||
| 
 | 
 | ||||||
| # Assets | # Assets | ||||||
| /assets/resources/infrared/ @skotopes @DrZlo13 @hedger @gsurkov | /applications/main/infrared/resources/ @skotopes @DrZlo13 @hedger @gsurkov | ||||||
| 
 | 
 | ||||||
| # Documentation | # Documentation | ||||||
| /documentation/ @skotopes @DrZlo13 @hedger @drunkbatya | /documentation/ @skotopes @DrZlo13 @hedger @drunkbatya | ||||||
|  | |||||||
							
								
								
									
										8
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							| @ -25,7 +25,7 @@ jobs: | |||||||
|         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; |         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; | ||||||
| 
 | 
 | ||||||
|       - name: 'Checkout code' |       - name: 'Checkout code' | ||||||
|         uses: actions/checkout@v3 |         uses: actions/checkout@v4 | ||||||
|         with: |         with: | ||||||
|           fetch-depth: 1 |           fetch-depth: 1 | ||||||
|           ref: ${{ github.event.pull_request.head.sha }} |           ref: ${{ github.event.pull_request.head.sha }} | ||||||
| @ -51,11 +51,11 @@ jobs: | |||||||
|       - name: 'Check API versions for consistency between targets' |       - name: 'Check API versions for consistency between targets' | ||||||
|         run: | |         run: | | ||||||
|           set -e |           set -e | ||||||
|           N_API_HEADER_SIGNATURES=`ls -1 firmware/targets/f*/api_symbols.csv | xargs -I {} sh -c "head -n2 {} | md5sum" | sort -u | wc -l` |           N_API_HEADER_SIGNATURES=`ls -1 targets/f*/api_symbols.csv | xargs -I {} sh -c "head -n2 {} | md5sum" | sort -u | wc -l` | ||||||
|           if [ $N_API_HEADER_SIGNATURES != 1 ] ; then |           if [ $N_API_HEADER_SIGNATURES != 1 ] ; then | ||||||
|             echo API versions aren\'t matching for available targets. Please update! |             echo API versions aren\'t matching for available targets. Please update! | ||||||
|             echo API versions are: |             echo API versions are: | ||||||
|             head -n2 firmware/targets/f*/api_symbols.csv |             head -n2 targets/f*/api_symbols.csv | ||||||
|             exit 1 |             exit 1 | ||||||
|           fi |           fi | ||||||
| 
 | 
 | ||||||
| @ -76,7 +76,7 @@ jobs: | |||||||
|           mkdir artifacts map_analyser_files |           mkdir artifacts map_analyser_files | ||||||
|           cp dist/${TARGET}-*/* artifacts/ || true |           cp dist/${TARGET}-*/* artifacts/ || true | ||||||
|           tar czpf "artifacts/flipper-z-${TARGET}-resources-${SUFFIX}.tgz" \ |           tar czpf "artifacts/flipper-z-${TARGET}-resources-${SUFFIX}.tgz" \ | ||||||
|             -C assets resources |             -C build/latest resources | ||||||
|           tar czpf "artifacts/flipper-z-${TARGET}-debugapps-${SUFFIX}.tgz" \ |           tar czpf "artifacts/flipper-z-${TARGET}-debugapps-${SUFFIX}.tgz" \ | ||||||
|             -C dist/${TARGET}-*/apps/Debug . |             -C dist/${TARGET}-*/apps/Debug . | ||||||
|           tar czpf "artifacts/flipper-z-${TARGET}-appsymbols-${SUFFIX}.tgz" \ |           tar czpf "artifacts/flipper-z-${TARGET}-appsymbols-${SUFFIX}.tgz" \ | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								.github/workflows/build_compact.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/build_compact.yml
									
									
									
									
										vendored
									
									
								
							| @ -19,7 +19,7 @@ jobs: | |||||||
|         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; |         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; | ||||||
| 
 | 
 | ||||||
|       - name: 'Checkout code' |       - name: 'Checkout code' | ||||||
|         uses: actions/checkout@v3 |         uses: actions/checkout@v4 | ||||||
|         with: |         with: | ||||||
|           fetch-depth: 1 |           fetch-depth: 1 | ||||||
|           submodules: false |           submodules: false | ||||||
| @ -46,7 +46,7 @@ jobs: | |||||||
|           echo "hw-target-code=$TARGET" >> $GITHUB_OUTPUT |           echo "hw-target-code=$TARGET" >> $GITHUB_OUTPUT | ||||||
| 
 | 
 | ||||||
|       - name: Deploy uFBT with SDK |       - name: Deploy uFBT with SDK | ||||||
|         uses: flipperdevices/flipperzero-ufbt-action@v0.1.0 |         uses: flipperdevices/flipperzero-ufbt-action@v0.1 | ||||||
|         with: |         with: | ||||||
|           task: setup |           task: setup | ||||||
|           sdk-file: ${{ steps.build-fw.outputs.sdk-file }} |           sdk-file: ${{ steps.build-fw.outputs.sdk-file }} | ||||||
|  | |||||||
| @ -16,14 +16,14 @@ jobs: | |||||||
|         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; |         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; | ||||||
| 
 | 
 | ||||||
|       - name: 'Checkout code' |       - name: 'Checkout code' | ||||||
|         uses: actions/checkout@v3 |         uses: actions/checkout@v4 | ||||||
|         with: |         with: | ||||||
|           fetch-depth: 2 |           fetch-depth: 2 | ||||||
|           ref: ${{ github.sha }} |           ref: ${{ github.sha }} | ||||||
| 
 | 
 | ||||||
|       - name: 'Check protobuf branch' |       - name: 'Check protobuf branch' | ||||||
|         run: | |         run: | | ||||||
|           git submodule update --init |           git submodule update --init; | ||||||
|           SUB_PATH="assets/protobuf"; |           SUB_PATH="assets/protobuf"; | ||||||
|           SUB_BRANCH="dev"; |           SUB_BRANCH="dev"; | ||||||
|           SUB_COMMITS_MIN=40; |           SUB_COMMITS_MIN=40; | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								.github/workflows/merge_report.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/merge_report.yml
									
									
									
									
										vendored
									
									
								
							| @ -16,7 +16,7 @@ jobs: | |||||||
|         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; |         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; | ||||||
| 
 | 
 | ||||||
|       - name: 'Checkout code' |       - name: 'Checkout code' | ||||||
|         uses: actions/checkout@v3 |         uses: actions/checkout@v4 | ||||||
|         with: |         with: | ||||||
|           fetch-depth: 1 |           fetch-depth: 1 | ||||||
|           ref: ${{ github.event.pull_request.head.sha }} |           ref: ${{ github.event.pull_request.head.sha }} | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								.github/workflows/pvs_studio.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/pvs_studio.yml
									
									
									
									
										vendored
									
									
								
							| @ -21,7 +21,7 @@ jobs: | |||||||
|         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; |         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; | ||||||
| 
 | 
 | ||||||
|       - name: 'Checkout code' |       - name: 'Checkout code' | ||||||
|         uses: actions/checkout@v3 |         uses: actions/checkout@v4 | ||||||
|         with: |         with: | ||||||
|           fetch-depth: 1 |           fetch-depth: 1 | ||||||
|           ref: ${{ github.event.pull_request.head.sha }} |           ref: ${{ github.event.pull_request.head.sha }} | ||||||
|  | |||||||
							
								
								
									
										8
									
								
								.github/workflows/unit_tests.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/unit_tests.yml
									
									
									
									
										vendored
									
									
								
							| @ -17,7 +17,7 @@ jobs: | |||||||
|         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; |         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; | ||||||
| 
 | 
 | ||||||
|       - name: Checkout code |       - name: Checkout code | ||||||
|         uses: actions/checkout@v3 |         uses: actions/checkout@v4 | ||||||
|         with: |         with: | ||||||
|           fetch-depth: 1 |           fetch-depth: 1 | ||||||
|           ref: ${{ github.event.pull_request.head.sha }} |           ref: ${{ github.event.pull_request.head.sha }} | ||||||
| @ -32,7 +32,7 @@ jobs: | |||||||
|         if: success() |         if: success() | ||||||
|         timeout-minutes: 10 |         timeout-minutes: 10 | ||||||
|         run: | |         run: | | ||||||
|           ./fbt flash SWD_TRANSPORT_SERIAL=2A0906016415303030303032 LIB_DEBUG=1 FIRMWARE_APP_SET=unit_tests FORCE=1 |           ./fbt resources firmware_latest flash SWD_TRANSPORT_SERIAL=2A0906016415303030303032 LIB_DEBUG=1 FIRMWARE_APP_SET=unit_tests FORCE=1 | ||||||
| 
 | 
 | ||||||
|       - name: 'Wait for flipper and format ext' |       - name: 'Wait for flipper and format ext' | ||||||
|         id: format_ext |         id: format_ext | ||||||
| @ -50,8 +50,8 @@ jobs: | |||||||
|         run: | |         run: | | ||||||
|           source scripts/toolchain/fbtenv.sh |           source scripts/toolchain/fbtenv.sh | ||||||
|           python3 scripts/testing/await_flipper.py ${{steps.device.outputs.flipper}} |           python3 scripts/testing/await_flipper.py ${{steps.device.outputs.flipper}} | ||||||
|           python3 scripts/storage.py -p ${{steps.device.outputs.flipper}} -f send assets/resources /ext |           rm -rf build/latest/resources/dolphin | ||||||
|           python3 scripts/storage.py -p ${{steps.device.outputs.flipper}} -f send assets/unit_tests /ext/unit_tests |           python3 scripts/storage.py -p ${{steps.device.outputs.flipper}} -f send build/latest/resources /ext | ||||||
|           python3 scripts/power.py -p ${{steps.device.outputs.flipper}} reboot |           python3 scripts/power.py -p ${{steps.device.outputs.flipper}} reboot | ||||||
|           python3 scripts/testing/await_flipper.py ${{steps.device.outputs.flipper}} |           python3 scripts/testing/await_flipper.py ${{steps.device.outputs.flipper}} | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								.github/workflows/updater_test.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/updater_test.yml
									
									
									
									
										vendored
									
									
								
							| @ -17,7 +17,7 @@ jobs: | |||||||
|         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; |         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; | ||||||
| 
 | 
 | ||||||
|       - name: Checkout code |       - name: Checkout code | ||||||
|         uses: actions/checkout@v3 |         uses: actions/checkout@v4 | ||||||
|         with: |         with: | ||||||
|           fetch-depth: 1 |           fetch-depth: 1 | ||||||
|           submodules: false |           submodules: false | ||||||
| @ -56,7 +56,7 @@ jobs: | |||||||
|         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; |         run: find ./ -mount -maxdepth 1 -exec rm -rf {} \; | ||||||
| 
 | 
 | ||||||
|       - name: 'Checkout latest release' |       - name: 'Checkout latest release' | ||||||
|         uses: actions/checkout@v3 |         uses: actions/checkout@v4 | ||||||
|         if: failure() |         if: failure() | ||||||
|         with: |         with: | ||||||
|           fetch-depth: 1 |           fetch-depth: 1 | ||||||
|  | |||||||
							
								
								
									
										47
									
								
								SConstruct
									
									
									
									
									
								
							
							
						
						
									
										47
									
								
								SConstruct
									
									
									
									
									
								
							| @ -67,22 +67,22 @@ if GetOption("fullenv") or any( | |||||||
|     # Target for self-update package |     # Target for self-update package | ||||||
|     dist_basic_arguments = [ |     dist_basic_arguments = [ | ||||||
|         "--bundlever", |         "--bundlever", | ||||||
|         '"${UPDATE_VERSION_STRING}"', |         "${UPDATE_VERSION_STRING}", | ||||||
|     ] |     ] | ||||||
|     dist_radio_arguments = [ |     dist_radio_arguments = [ | ||||||
|         "--radio", |         "--radio", | ||||||
|         '"${ROOT_DIR.abspath}/${COPRO_STACK_BIN_DIR}/${COPRO_STACK_BIN}"', |         "${ROOT_DIR.abspath}/${COPRO_STACK_BIN_DIR}/${COPRO_STACK_BIN}", | ||||||
|         "--radiotype", |         "--radiotype", | ||||||
|         "${COPRO_STACK_TYPE}", |         "${COPRO_STACK_TYPE}", | ||||||
|         "${COPRO_DISCLAIMER}", |         "${COPRO_DISCLAIMER}", | ||||||
|         "--obdata", |         "--obdata", | ||||||
|         '"${ROOT_DIR.abspath}/${COPRO_OB_DATA}"', |         "${ROOT_DIR.abspath}/${COPRO_OB_DATA}", | ||||||
|         "--stackversion", |         "--stackversion", | ||||||
|         "${COPRO_CUBE_VERSION}", |         "${COPRO_CUBE_VERSION}", | ||||||
|     ] |     ] | ||||||
|     dist_resource_arguments = [ |     dist_resource_arguments = [ | ||||||
|         "-r", |         "-r", | ||||||
|         '"${ROOT_DIR.abspath}/assets/resources"', |         firmware_env.subst("${RESOURCES_ROOT}"), | ||||||
|     ] |     ] | ||||||
|     dist_splash_arguments = ( |     dist_splash_arguments = ( | ||||||
|         [ |         [ | ||||||
| @ -95,7 +95,7 @@ if GetOption("fullenv") or any( | |||||||
| 
 | 
 | ||||||
|     selfupdate_dist = distenv.DistCommand( |     selfupdate_dist = distenv.DistCommand( | ||||||
|         "updater_package", |         "updater_package", | ||||||
|         (distenv["DIST_DEPENDS"], firmware_env["FW_RESOURCES"]), |         (distenv["DIST_DEPENDS"], firmware_env["FW_RESOURCES_MANIFEST"]), | ||||||
|         DIST_EXTRA=[ |         DIST_EXTRA=[ | ||||||
|             *dist_basic_arguments, |             *dist_basic_arguments, | ||||||
|             *dist_radio_arguments, |             *dist_radio_arguments, | ||||||
| @ -128,7 +128,8 @@ if GetOption("fullenv") or any( | |||||||
| 
 | 
 | ||||||
|     # Installation over USB & CLI |     # Installation over USB & CLI | ||||||
|     usb_update_package = distenv.AddUsbFlashTarget( |     usb_update_package = distenv.AddUsbFlashTarget( | ||||||
|         "#build/usbinstall.flag", (firmware_env["FW_RESOURCES"], selfupdate_dist) |         "#build/usbinstall.flag", | ||||||
|  |         (firmware_env["FW_RESOURCES_MANIFEST"], selfupdate_dist), | ||||||
|     ) |     ) | ||||||
|     distenv.Alias("flash_usb_full", usb_update_package) |     distenv.Alias("flash_usb_full", usb_update_package) | ||||||
| 
 | 
 | ||||||
| @ -166,17 +167,27 @@ Depends( | |||||||
|     list(app_artifact.validator for app_artifact in external_app_list), |     list(app_artifact.validator for app_artifact in external_app_list), | ||||||
| ) | ) | ||||||
| Alias("fap_dist", fap_dist) | Alias("fap_dist", fap_dist) | ||||||
| # distenv.Default(fap_dist) |  | ||||||
| 
 |  | ||||||
| distenv.Depends(firmware_env["FW_RESOURCES"], external_apps_artifacts.resources_dist) |  | ||||||
| 
 | 
 | ||||||
| # Copy all faps to device | # Copy all faps to device | ||||||
| 
 | 
 | ||||||
| fap_deploy = distenv.PhonyTarget( | fap_deploy = distenv.PhonyTarget( | ||||||
|     "fap_deploy", |     "fap_deploy", | ||||||
|     "${PYTHON3} ${FBT_SCRIPT_DIR}/storage.py -p ${FLIP_PORT} send ${SOURCE} /ext/apps", |     Action( | ||||||
|     source=Dir("#/assets/resources/apps"), |         [ | ||||||
|  |             [ | ||||||
|  |                 "${PYTHON3}", | ||||||
|  |                 "${FBT_SCRIPT_DIR}/storage.py", | ||||||
|  |                 "-p", | ||||||
|  |                 "${FLIP_PORT}", | ||||||
|  |                 "send", | ||||||
|  |                 "${SOURCE}", | ||||||
|  |                 "/ext/apps", | ||||||
|  |             ] | ||||||
|  |         ] | ||||||
|  |     ), | ||||||
|  |     source=firmware_env.Dir(("${RESOURCES_ROOT}/apps")), | ||||||
| ) | ) | ||||||
|  | Depends(fap_deploy, firmware_env["FW_RESOURCES_MANIFEST"]) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # Target for bundling core2 package for qFlipper | # Target for bundling core2 package for qFlipper | ||||||
| @ -252,7 +263,7 @@ distenv.PhonyTarget( | |||||||
| distenv.PhonyTarget( | distenv.PhonyTarget( | ||||||
|     "debug_other_blackmagic", |     "debug_other_blackmagic", | ||||||
|     "${GDBPYCOM}", |     "${GDBPYCOM}", | ||||||
|     GDBOPTS="${GDBOPTS_BASE}  ${GDBOPTS_BLACKMAGIC}", |     GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}", | ||||||
|     GDBREMOTE="${BLACKMAGIC_ADDR}", |     GDBREMOTE="${BLACKMAGIC_ADDR}", | ||||||
|     GDBPYOPTS=debug_other_opts, |     GDBPYOPTS=debug_other_opts, | ||||||
| ) | ) | ||||||
| @ -267,13 +278,13 @@ distenv.PhonyTarget( | |||||||
| # Linter | # Linter | ||||||
| distenv.PhonyTarget( | distenv.PhonyTarget( | ||||||
|     "lint", |     "lint", | ||||||
|     "${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py check ${LINT_SOURCES}", |     [["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "check", "${LINT_SOURCES}"]], | ||||||
|     LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]], |     LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]], | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| distenv.PhonyTarget( | distenv.PhonyTarget( | ||||||
|     "format", |     "format", | ||||||
|     "${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py format ${LINT_SOURCES}", |     [["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "format", "${LINT_SOURCES}"]], | ||||||
|     LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]], |     LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]], | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @ -315,11 +326,13 @@ distenv.PhonyTarget( | |||||||
| 
 | 
 | ||||||
| # Start Flipper CLI via PySerial's miniterm | # Start Flipper CLI via PySerial's miniterm | ||||||
| distenv.PhonyTarget( | distenv.PhonyTarget( | ||||||
|     "cli", "${PYTHON3} ${FBT_SCRIPT_DIR}/serial_cli.py  -p ${FLIP_PORT}" |     "cli", [["${PYTHON3}", "${FBT_SCRIPT_DIR}/serial_cli.py", "-p", "${FLIP_PORT}"]] | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| # Update WiFi devboard firmware | # Update WiFi devboard firmware | ||||||
| distenv.PhonyTarget("devboard_flash", "${PYTHON3} ${FBT_SCRIPT_DIR}/wifi_board.py") | distenv.PhonyTarget( | ||||||
|  |     "devboard_flash", [["${PYTHON3}", "${FBT_SCRIPT_DIR}/wifi_board.py"]] | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # Find blackmagic probe | # Find blackmagic probe | ||||||
| @ -354,5 +367,5 @@ distenv.Alias("vscode_dist", vscode_dist) | |||||||
| # Configure shell with build tools | # Configure shell with build tools | ||||||
| distenv.PhonyTarget( | distenv.PhonyTarget( | ||||||
|     "env", |     "env", | ||||||
|     "@echo $( ${FBT_SCRIPT_DIR}/toolchain/fbtenv.sh $)", |     "@echo $( ${FBT_SCRIPT_DIR.abspath}/toolchain/fbtenv.sh $)", | ||||||
| ) | ) | ||||||
|  | |||||||
| @ -4,7 +4,6 @@ App( | |||||||
|     apptype=FlipperAppType.DEBUG, |     apptype=FlipperAppType.DEBUG, | ||||||
|     targets=["f7"], |     targets=["f7"], | ||||||
|     entry_point="accessor_app", |     entry_point="accessor_app", | ||||||
|     cdefines=["APP_ACCESSOR"], |  | ||||||
|     requires=["gui"], |     requires=["gui"], | ||||||
|     stack_size=4 * 1024, |     stack_size=4 * 1024, | ||||||
|     order=40, |     order=40, | ||||||
|  | |||||||
| @ -3,7 +3,6 @@ App( | |||||||
|     name="Battery Test", |     name="Battery Test", | ||||||
|     apptype=FlipperAppType.DEBUG, |     apptype=FlipperAppType.DEBUG, | ||||||
|     entry_point="battery_test_app", |     entry_point="battery_test_app", | ||||||
|     cdefines=["APP_BATTERY_TEST"], |  | ||||||
|     requires=[ |     requires=[ | ||||||
|         "gui", |         "gui", | ||||||
|         "power", |         "power", | ||||||
|  | |||||||
| @ -3,7 +3,6 @@ App( | |||||||
|     name="Blink Test", |     name="Blink Test", | ||||||
|     apptype=FlipperAppType.DEBUG, |     apptype=FlipperAppType.DEBUG, | ||||||
|     entry_point="blink_test_app", |     entry_point="blink_test_app", | ||||||
|     cdefines=["APP_BLINK"], |  | ||||||
|     requires=["gui"], |     requires=["gui"], | ||||||
|     stack_size=1 * 1024, |     stack_size=1 * 1024, | ||||||
|     order=10, |     order=10, | ||||||
|  | |||||||
| @ -3,7 +3,6 @@ App( | |||||||
|     name="CCID Debug", |     name="CCID Debug", | ||||||
|     apptype=FlipperAppType.DEBUG, |     apptype=FlipperAppType.DEBUG, | ||||||
|     entry_point="ccid_test_app", |     entry_point="ccid_test_app", | ||||||
|     cdefines=["CCID_TEST"], |  | ||||||
|     requires=[ |     requires=[ | ||||||
|         "gui", |         "gui", | ||||||
|     ], |     ], | ||||||
|  | |||||||
| @ -3,7 +3,6 @@ App( | |||||||
|     name="Crash Test", |     name="Crash Test", | ||||||
|     apptype=FlipperAppType.DEBUG, |     apptype=FlipperAppType.DEBUG, | ||||||
|     entry_point="crash_test_app", |     entry_point="crash_test_app", | ||||||
|     cdefines=["APP_CRASH_TEST"], |  | ||||||
|     requires=["gui"], |     requires=["gui"], | ||||||
|     stack_size=1 * 1024, |     stack_size=1 * 1024, | ||||||
|     fap_category="Debug", |     fap_category="Debug", | ||||||
|  | |||||||
| @ -71,7 +71,7 @@ static void direct_draw_run(DirectDraw* instance) { | |||||||
|     size_t counter = 0; |     size_t counter = 0; | ||||||
|     float fps = 0; |     float fps = 0; | ||||||
| 
 | 
 | ||||||
|     vTaskPrioritySet(furi_thread_get_current_id(), FuriThreadPriorityIdle); |     furi_thread_set_current_priority(FuriThreadPriorityIdle); | ||||||
| 
 | 
 | ||||||
|     do { |     do { | ||||||
|         size_t elapsed = DWT->CYCCNT - start; |         size_t elapsed = DWT->CYCCNT - start; | ||||||
|  | |||||||
| @ -3,7 +3,6 @@ App( | |||||||
|     name="Display Test", |     name="Display Test", | ||||||
|     apptype=FlipperAppType.DEBUG, |     apptype=FlipperAppType.DEBUG, | ||||||
|     entry_point="display_test_app", |     entry_point="display_test_app", | ||||||
|     cdefines=["APP_DISPLAY_TEST"], |  | ||||||
|     requires=["gui"], |     requires=["gui"], | ||||||
|     fap_libs=["misc"], |     fap_libs=["misc"], | ||||||
|     stack_size=1 * 1024, |     stack_size=1 * 1024, | ||||||
|  | |||||||
| @ -3,7 +3,6 @@ App( | |||||||
|     name="File Browser Test", |     name="File Browser Test", | ||||||
|     apptype=FlipperAppType.DEBUG, |     apptype=FlipperAppType.DEBUG, | ||||||
|     entry_point="file_browser_app", |     entry_point="file_browser_app", | ||||||
|     cdefines=["APP_FILE_BROWSER_TEST"], |  | ||||||
|     requires=["gui"], |     requires=["gui"], | ||||||
|     stack_size=2 * 1024, |     stack_size=2 * 1024, | ||||||
|     order=150, |     order=150, | ||||||
|  | |||||||
| @ -3,7 +3,6 @@ App( | |||||||
|     name="Keypad Test", |     name="Keypad Test", | ||||||
|     apptype=FlipperAppType.DEBUG, |     apptype=FlipperAppType.DEBUG, | ||||||
|     entry_point="keypad_test_app", |     entry_point="keypad_test_app", | ||||||
|     cdefines=["APP_KEYPAD_TEST"], |  | ||||||
|     requires=["gui"], |     requires=["gui"], | ||||||
|     stack_size=1 * 1024, |     stack_size=1 * 1024, | ||||||
|     order=30, |     order=30, | ||||||
|  | |||||||
| @ -3,7 +3,6 @@ App( | |||||||
|     name="Locale Test", |     name="Locale Test", | ||||||
|     apptype=FlipperAppType.DEBUG, |     apptype=FlipperAppType.DEBUG, | ||||||
|     entry_point="locale_test_app", |     entry_point="locale_test_app", | ||||||
|     cdefines=["APP_LOCALE"], |  | ||||||
|     requires=["gui", "locale"], |     requires=["gui", "locale"], | ||||||
|     stack_size=2 * 1024, |     stack_size=2 * 1024, | ||||||
|     order=70, |     order=70, | ||||||
|  | |||||||
| @ -21,22 +21,51 @@ static void rpc_debug_app_tick_event_callback(void* context) { | |||||||
|     scene_manager_handle_tick_event(app->scene_manager); |     scene_manager_handle_tick_event(app->scene_manager); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void rpc_debug_app_rpc_command_callback(RpcAppSystemEvent event, void* context) { | static void | ||||||
|  |     rpc_debug_app_format_hex(const uint8_t* data, size_t data_size, char* buf, size_t buf_size) { | ||||||
|  |     if(data == NULL || data_size == 0) { | ||||||
|  |         strncpy(buf, "<Data empty>", buf_size); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     const size_t byte_width = 3; | ||||||
|  |     const size_t line_width = 7; | ||||||
|  | 
 | ||||||
|  |     data_size = MIN(data_size, buf_size / (byte_width + 1)); | ||||||
|  | 
 | ||||||
|  |     for(size_t i = 0; i < data_size; ++i) { | ||||||
|  |         char* p = buf + (i * byte_width); | ||||||
|  |         char sep = !((i + 1) % line_width) ? '\n' : ' '; | ||||||
|  |         snprintf(p, byte_width + 1, "%02X%c", data[i], sep); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     buf[buf_size - 1] = '\0'; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void rpc_debug_app_rpc_command_callback(const RpcAppSystemEvent* event, void* context) { | ||||||
|     furi_assert(context); |     furi_assert(context); | ||||||
|     RpcDebugApp* app = context; |     RpcDebugApp* app = context; | ||||||
|     furi_assert(app->rpc); |     furi_assert(app->rpc); | ||||||
| 
 | 
 | ||||||
|     if(event == RpcAppEventSessionClose) { |     if(event->type == RpcAppEventTypeSessionClose) { | ||||||
|         scene_manager_stop(app->scene_manager); |         scene_manager_stop(app->scene_manager); | ||||||
|         view_dispatcher_stop(app->view_dispatcher); |         view_dispatcher_stop(app->view_dispatcher); | ||||||
|         rpc_system_app_set_callback(app->rpc, NULL, NULL); |         rpc_system_app_set_callback(app->rpc, NULL, NULL); | ||||||
|         app->rpc = NULL; |         app->rpc = NULL; | ||||||
|     } else if(event == RpcAppEventAppExit) { |     } else if(event->type == RpcAppEventTypeAppExit) { | ||||||
|         scene_manager_stop(app->scene_manager); |         scene_manager_stop(app->scene_manager); | ||||||
|         view_dispatcher_stop(app->view_dispatcher); |         view_dispatcher_stop(app->view_dispatcher); | ||||||
|         rpc_system_app_confirm(app->rpc, RpcAppEventAppExit, true); |         rpc_system_app_confirm(app->rpc, true); | ||||||
|  |     } else if(event->type == RpcAppEventTypeDataExchange) { | ||||||
|  |         furi_assert(event->data.type == RpcAppSystemEventDataTypeBytes); | ||||||
|  | 
 | ||||||
|  |         rpc_debug_app_format_hex( | ||||||
|  |             event->data.bytes.ptr, event->data.bytes.size, app->text_store, TEXT_STORE_SIZE); | ||||||
|  | 
 | ||||||
|  |         view_dispatcher_send_custom_event( | ||||||
|  |             app->view_dispatcher, RpcDebugAppCustomEventRpcDataExchange); | ||||||
|     } else { |     } else { | ||||||
|         rpc_system_app_confirm(app->rpc, event, false); |         rpc_system_app_confirm(app->rpc, false); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,40 +1,5 @@ | |||||||
| #include "../rpc_debug_app.h" | #include "../rpc_debug_app.h" | ||||||
| 
 | 
 | ||||||
| static void rpc_debug_app_scene_start_format_hex( |  | ||||||
|     const uint8_t* data, |  | ||||||
|     size_t data_size, |  | ||||||
|     char* buf, |  | ||||||
|     size_t buf_size) { |  | ||||||
|     furi_assert(data); |  | ||||||
|     furi_assert(buf); |  | ||||||
| 
 |  | ||||||
|     const size_t byte_width = 3; |  | ||||||
|     const size_t line_width = 7; |  | ||||||
| 
 |  | ||||||
|     data_size = MIN(data_size, buf_size / (byte_width + 1)); |  | ||||||
| 
 |  | ||||||
|     for(size_t i = 0; i < data_size; ++i) { |  | ||||||
|         char* p = buf + (i * byte_width); |  | ||||||
|         char sep = !((i + 1) % line_width) ? '\n' : ' '; |  | ||||||
|         snprintf(p, byte_width + 1, "%02X%c", data[i], sep); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     buf[buf_size - 1] = '\0'; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static void rpc_debug_app_scene_receive_data_exchange_callback( |  | ||||||
|     const uint8_t* data, |  | ||||||
|     size_t data_size, |  | ||||||
|     void* context) { |  | ||||||
|     RpcDebugApp* app = context; |  | ||||||
|     if(data) { |  | ||||||
|         rpc_debug_app_scene_start_format_hex(data, data_size, app->text_store, TEXT_STORE_SIZE); |  | ||||||
|     } else { |  | ||||||
|         strncpy(app->text_store, "<Data empty>", TEXT_STORE_SIZE); |  | ||||||
|     } |  | ||||||
|     view_dispatcher_send_custom_event(app->view_dispatcher, RpcDebugAppCustomEventRpcDataExchange); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void rpc_debug_app_scene_receive_data_exchange_on_enter(void* context) { | void rpc_debug_app_scene_receive_data_exchange_on_enter(void* context) { | ||||||
|     RpcDebugApp* app = context; |     RpcDebugApp* app = context; | ||||||
|     strncpy(app->text_store, "Received data will appear here...", TEXT_STORE_SIZE); |     strncpy(app->text_store, "Received data will appear here...", TEXT_STORE_SIZE); | ||||||
| @ -42,8 +7,6 @@ void rpc_debug_app_scene_receive_data_exchange_on_enter(void* context) { | |||||||
|     text_box_set_text(app->text_box, app->text_store); |     text_box_set_text(app->text_box, app->text_store); | ||||||
|     text_box_set_font(app->text_box, TextBoxFontHex); |     text_box_set_font(app->text_box, TextBoxFontHex); | ||||||
| 
 | 
 | ||||||
|     rpc_system_app_set_data_exchange_callback( |  | ||||||
|         app->rpc, rpc_debug_app_scene_receive_data_exchange_callback, app); |  | ||||||
|     view_dispatcher_switch_to_view(app->view_dispatcher, RpcDebugAppViewTextBox); |     view_dispatcher_switch_to_view(app->view_dispatcher, RpcDebugAppViewTextBox); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -53,6 +16,7 @@ bool rpc_debug_app_scene_receive_data_exchange_on_event(void* context, SceneMana | |||||||
| 
 | 
 | ||||||
|     if(event.type == SceneManagerEventTypeCustom) { |     if(event.type == SceneManagerEventTypeCustom) { | ||||||
|         if(event.event == RpcDebugAppCustomEventRpcDataExchange) { |         if(event.event == RpcDebugAppCustomEventRpcDataExchange) { | ||||||
|  |             rpc_system_app_confirm(app->rpc, true); | ||||||
|             notification_message(app->notifications, &sequence_blink_cyan_100); |             notification_message(app->notifications, &sequence_blink_cyan_100); | ||||||
|             notification_message(app->notifications, &sequence_display_backlight_on); |             notification_message(app->notifications, &sequence_display_backlight_on); | ||||||
|             text_box_set_text(app->text_box, app->text_store); |             text_box_set_text(app->text_box, app->text_store); | ||||||
| @ -66,5 +30,4 @@ bool rpc_debug_app_scene_receive_data_exchange_on_event(void* context, SceneMana | |||||||
| void rpc_debug_app_scene_receive_data_exchange_on_exit(void* context) { | void rpc_debug_app_scene_receive_data_exchange_on_exit(void* context) { | ||||||
|     RpcDebugApp* app = context; |     RpcDebugApp* app = context; | ||||||
|     text_box_reset(app->text_box); |     text_box_reset(app->text_box); | ||||||
|     rpc_system_app_set_data_exchange_callback(app->rpc, NULL, NULL); |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -3,7 +3,6 @@ App( | |||||||
|     name="Text Box Test", |     name="Text Box Test", | ||||||
|     apptype=FlipperAppType.DEBUG, |     apptype=FlipperAppType.DEBUG, | ||||||
|     entry_point="text_box_test_app", |     entry_point="text_box_test_app", | ||||||
|     cdefines=["APP_TEXT_BOX_TEST"], |  | ||||||
|     requires=["gui"], |     requires=["gui"], | ||||||
|     stack_size=1 * 1024, |     stack_size=1 * 1024, | ||||||
|     order=140, |     order=140, | ||||||
|  | |||||||
| @ -3,7 +3,6 @@ App( | |||||||
|     name="UART Echo", |     name="UART Echo", | ||||||
|     apptype=FlipperAppType.DEBUG, |     apptype=FlipperAppType.DEBUG, | ||||||
|     entry_point="uart_echo_app", |     entry_point="uart_echo_app", | ||||||
|     cdefines=["APP_UART_ECHO"], |  | ||||||
|     requires=["gui"], |     requires=["gui"], | ||||||
|     stack_size=2 * 1024, |     stack_size=2 * 1024, | ||||||
|     order=70, |     order=70, | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ App( | |||||||
|     cdefines=["APP_UNIT_TESTS"], |     cdefines=["APP_UNIT_TESTS"], | ||||||
|     requires=["system_settings"], |     requires=["system_settings"], | ||||||
|     provides=["delay_test"], |     provides=["delay_test"], | ||||||
|  |     resources="resources", | ||||||
|     order=100, |     order=100, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -28,7 +28,7 @@ void bt_test_alloc() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void bt_test_free() { | void bt_test_free() { | ||||||
|     furi_assert(bt_test); |     furi_check(bt_test); | ||||||
|     free(bt_test->nvm_ram_buff_ref); |     free(bt_test->nvm_ram_buff_ref); | ||||||
|     free(bt_test->nvm_ram_buff_dut); |     free(bt_test->nvm_ram_buff_dut); | ||||||
|     bt_keys_storage_free(bt_test->bt_keys_storage); |     bt_keys_storage_free(bt_test->bt_keys_storage); | ||||||
| @ -89,7 +89,7 @@ static void bt_test_keys_remove_test_file() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| MU_TEST(bt_test_keys_storage_serial_profile) { | MU_TEST(bt_test_keys_storage_serial_profile) { | ||||||
|     furi_assert(bt_test); |     furi_check(bt_test); | ||||||
| 
 | 
 | ||||||
|     bt_test_keys_remove_test_file(); |     bt_test_keys_remove_test_file(); | ||||||
|     bt_test_keys_storage_profile(); |     bt_test_keys_storage_profile(); | ||||||
|  | |||||||
| @ -3,18 +3,29 @@ | |||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include "../minunit.h" | #include "../minunit.h" | ||||||
| 
 | 
 | ||||||
| void test_furi_create_open() { | #define TEST_RECORD_NAME "test/holding" | ||||||
|     // 1. Create record
 |  | ||||||
|     uint8_t test_data = 0; |  | ||||||
|     furi_record_create("test/holding", (void*)&test_data); |  | ||||||
| 
 | 
 | ||||||
|     // 2. Open it
 | void test_furi_create_open() { | ||||||
|     void* record = furi_record_open("test/holding"); |     // Test that record does not exist
 | ||||||
|  |     mu_check(furi_record_exists(TEST_RECORD_NAME) == false); | ||||||
|  | 
 | ||||||
|  |     // Create record
 | ||||||
|  |     uint8_t test_data = 0; | ||||||
|  |     furi_record_create(TEST_RECORD_NAME, (void*)&test_data); | ||||||
|  | 
 | ||||||
|  |     // Test that record exists
 | ||||||
|  |     mu_check(furi_record_exists(TEST_RECORD_NAME) == true); | ||||||
|  | 
 | ||||||
|  |     // Open it
 | ||||||
|  |     void* record = furi_record_open(TEST_RECORD_NAME); | ||||||
|     mu_assert_pointers_eq(record, &test_data); |     mu_assert_pointers_eq(record, &test_data); | ||||||
| 
 | 
 | ||||||
|     // 3. Close it
 |     // Close it
 | ||||||
|     furi_record_close("test/holding"); |     furi_record_close(TEST_RECORD_NAME); | ||||||
| 
 | 
 | ||||||
|     // 4. Clean up
 |     // Clean up
 | ||||||
|     furi_record_destroy("test/holding"); |     furi_record_destroy(TEST_RECORD_NAME); | ||||||
|  | 
 | ||||||
|  |     // Test that record does not exist
 | ||||||
|  |     mu_check(furi_record_exists(TEST_RECORD_NAME) == false); | ||||||
| } | } | ||||||
|  | |||||||
| @ -27,7 +27,7 @@ static void infrared_test_alloc() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void infrared_test_free() { | static void infrared_test_free() { | ||||||
|     furi_assert(test); |     furi_check(test); | ||||||
|     infrared_free_decoder(test->decoder_handler); |     infrared_free_decoder(test->decoder_handler); | ||||||
|     infrared_free_encoder(test->encoder_handler); |     infrared_free_encoder(test->encoder_handler); | ||||||
|     flipper_format_free(test->ff); |     flipper_format_free(test->ff); | ||||||
|  | |||||||
| @ -22,7 +22,7 @@ MU_TEST(manifest_iteration_test) { | |||||||
|     ResourceManifestReader* manifest_reader = resource_manifest_reader_alloc(storage); |     ResourceManifestReader* manifest_reader = resource_manifest_reader_alloc(storage); | ||||||
|     do { |     do { | ||||||
|         // Open manifest file
 |         // Open manifest file
 | ||||||
|         if(!resource_manifest_reader_open(manifest_reader, EXT_PATH("unit_tests/Manifest"))) { |         if(!resource_manifest_reader_open(manifest_reader, EXT_PATH("unit_tests/Manifest_test"))) { | ||||||
|             result = false; |             result = false; | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -81,6 +81,7 @@ __attribute__((unused)) static void (*minunit_teardown)(void) = NULL; | |||||||
| 
 | 
 | ||||||
| void minunit_print_progress(void); | void minunit_print_progress(void); | ||||||
| void minunit_print_fail(const char* error); | void minunit_print_fail(const char* error); | ||||||
|  | void minunit_printf_warning(const char* format, ...); | ||||||
| 
 | 
 | ||||||
| /*  Definitions */ | /*  Definitions */ | ||||||
| #define MU_TEST(method_name) static void method_name(void) | #define MU_TEST(method_name) static void method_name(void) | ||||||
| @ -150,6 +151,10 @@ void minunit_print_fail(const char* error); | |||||||
|                        minunit_end_proc_timer - minunit_proc_timer);) |                        minunit_end_proc_timer - minunit_proc_timer);) | ||||||
| #define MU_EXIT_CODE minunit_fail | #define MU_EXIT_CODE minunit_fail | ||||||
| 
 | 
 | ||||||
|  | /* Warnings */ | ||||||
|  | #define mu_warn(message) \ | ||||||
|  |     MU__SAFE_BLOCK(minunit_printf_warning("%s:%d: %s", __FILE__, __LINE__, message);) | ||||||
|  | 
 | ||||||
| /*  Assertions */ | /*  Assertions */ | ||||||
| #define mu_check(test)                       \ | #define mu_check(test)                       \ | ||||||
|     MU__SAFE_BLOCK(                          \ |     MU__SAFE_BLOCK(                          \ | ||||||
|  | |||||||
| @ -7,10 +7,10 @@ | |||||||
| #include <nfc/nfc_poller.h> | #include <nfc/nfc_poller.h> | ||||||
| #include <nfc/nfc_listener.h> | #include <nfc/nfc_listener.h> | ||||||
| #include <nfc/protocols/iso14443_3a/iso14443_3a.h> | #include <nfc/protocols/iso14443_3a/iso14443_3a.h> | ||||||
| #include <nfc/protocols/iso14443_3a/iso14443_3a_poller_sync_api.h> | #include <nfc/protocols/iso14443_3a/iso14443_3a_poller_sync.h> | ||||||
| #include <nfc/protocols/mf_ultralight/mf_ultralight.h> | #include <nfc/protocols/mf_ultralight/mf_ultralight.h> | ||||||
| #include <nfc/protocols/mf_ultralight/mf_ultralight_poller_sync_api.h> | #include <nfc/protocols/mf_ultralight/mf_ultralight_poller_sync.h> | ||||||
| #include <nfc/protocols/mf_classic/mf_classic_poller_sync_api.h> | #include <nfc/protocols/mf_classic/mf_classic_poller_sync.h> | ||||||
| 
 | 
 | ||||||
| #include <nfc/helpers/nfc_dict.h> | #include <nfc/helpers/nfc_dict.h> | ||||||
| #include <nfc/nfc.h> | #include <nfc/nfc.h> | ||||||
| @ -34,7 +34,7 @@ static void nfc_test_alloc() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void nfc_test_free() { | static void nfc_test_free() { | ||||||
|     furi_assert(nfc_test); |     furi_check(nfc_test); | ||||||
| 
 | 
 | ||||||
|     furi_record_close(RECORD_STORAGE); |     furi_record_close(RECORD_STORAGE); | ||||||
|     free(nfc_test); |     free(nfc_test); | ||||||
| @ -182,8 +182,8 @@ MU_TEST(iso14443_3a_reader) { | |||||||
| 
 | 
 | ||||||
|     Iso14443_3aData iso14443_3a_poller_data = {}; |     Iso14443_3aData iso14443_3a_poller_data = {}; | ||||||
|     mu_assert( |     mu_assert( | ||||||
|         iso14443_3a_poller_read(poller, &iso14443_3a_poller_data) == Iso14443_3aErrorNone, |         iso14443_3a_poller_sync_read(poller, &iso14443_3a_poller_data) == Iso14443_3aErrorNone, | ||||||
|         "iso14443_3a_poller_read() failed"); |         "iso14443_3a_poller_sync_read() failed"); | ||||||
| 
 | 
 | ||||||
|     nfc_listener_stop(iso3_listener); |     nfc_listener_stop(iso3_listener); | ||||||
|     mu_assert( |     mu_assert( | ||||||
| @ -203,15 +203,26 @@ static void mf_ultralight_reader_test(const char* path) { | |||||||
|     NfcDevice* nfc_device = nfc_device_alloc(); |     NfcDevice* nfc_device = nfc_device_alloc(); | ||||||
|     mu_assert(nfc_device_load(nfc_device, path), "nfc_device_load() failed\r\n"); |     mu_assert(nfc_device_load(nfc_device, path), "nfc_device_load() failed\r\n"); | ||||||
| 
 | 
 | ||||||
|     NfcListener* mfu_listener = nfc_listener_alloc( |     MfUltralightData* data = | ||||||
|         listener, |         (MfUltralightData*)nfc_device_get_data(nfc_device, NfcProtocolMfUltralight); | ||||||
|         NfcProtocolMfUltralight, | 
 | ||||||
|         nfc_device_get_data(nfc_device, NfcProtocolMfUltralight)); |     uint32_t features = mf_ultralight_get_feature_support_set(data->type); | ||||||
|  |     bool pwd_supported = | ||||||
|  |         mf_ultralight_support_feature(features, MfUltralightFeatureSupportPasswordAuth); | ||||||
|  |     uint8_t pwd_num = mf_ultralight_get_pwd_page_num(data->type); | ||||||
|  |     const uint8_t zero_pwd[4] = {0, 0, 0, 0}; | ||||||
|  | 
 | ||||||
|  |     if(pwd_supported && !memcmp(data->page[pwd_num].data, zero_pwd, sizeof(zero_pwd))) { | ||||||
|  |         data->pages_read -= 2; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     NfcListener* mfu_listener = nfc_listener_alloc(listener, NfcProtocolMfUltralight, data); | ||||||
|  | 
 | ||||||
|     nfc_listener_start(mfu_listener, NULL, NULL); |     nfc_listener_start(mfu_listener, NULL, NULL); | ||||||
| 
 | 
 | ||||||
|     MfUltralightData* mfu_data = mf_ultralight_alloc(); |     MfUltralightData* mfu_data = mf_ultralight_alloc(); | ||||||
|     MfUltralightError error = mf_ultralight_poller_read_card(poller, mfu_data); |     MfUltralightError error = mf_ultralight_poller_sync_read_card(poller, mfu_data); | ||||||
|     mu_assert(error == MfUltralightErrorNone, "mf_ultralight_poller_read_card() failed"); |     mu_assert(error == MfUltralightErrorNone, "mf_ultralight_poller_sync_read_card() failed"); | ||||||
| 
 | 
 | ||||||
|     nfc_listener_stop(mfu_listener); |     nfc_listener_stop(mfu_listener); | ||||||
|     nfc_listener_free(mfu_listener); |     nfc_listener_free(mfu_listener); | ||||||
| @ -259,8 +270,8 @@ MU_TEST(ntag_213_locked_reader) { | |||||||
|     nfc_listener_start(mfu_listener, NULL, NULL); |     nfc_listener_start(mfu_listener, NULL, NULL); | ||||||
| 
 | 
 | ||||||
|     MfUltralightData* mfu_data = mf_ultralight_alloc(); |     MfUltralightData* mfu_data = mf_ultralight_alloc(); | ||||||
|     MfUltralightError error = mf_ultralight_poller_read_card(poller, mfu_data); |     MfUltralightError error = mf_ultralight_poller_sync_read_card(poller, mfu_data); | ||||||
|     mu_assert(error == MfUltralightErrorNone, "mf_ultralight_poller_read_card() failed"); |     mu_assert(error == MfUltralightErrorNone, "mf_ultralight_poller_sync_read_card() failed"); | ||||||
| 
 | 
 | ||||||
|     nfc_listener_stop(mfu_listener); |     nfc_listener_stop(mfu_listener); | ||||||
|     nfc_listener_free(mfu_listener); |     nfc_listener_free(mfu_listener); | ||||||
| @ -297,8 +308,8 @@ static void mf_ultralight_write() { | |||||||
|     MfUltralightData* mfu_data = mf_ultralight_alloc(); |     MfUltralightData* mfu_data = mf_ultralight_alloc(); | ||||||
| 
 | 
 | ||||||
|     // Initial read
 |     // Initial read
 | ||||||
|     MfUltralightError error = mf_ultralight_poller_read_card(poller, mfu_data); |     MfUltralightError error = mf_ultralight_poller_sync_read_card(poller, mfu_data); | ||||||
|     mu_assert(error == MfUltralightErrorNone, "mf_ultralight_poller_read_card() failed"); |     mu_assert(error == MfUltralightErrorNone, "mf_ultralight_poller_sync_read_card() failed"); | ||||||
| 
 | 
 | ||||||
|     mu_assert( |     mu_assert( | ||||||
|         mf_ultralight_is_equal(mfu_data, nfc_device_get_data(nfc_device, NfcProtocolMfUltralight)), |         mf_ultralight_is_equal(mfu_data, nfc_device_get_data(nfc_device, NfcProtocolMfUltralight)), | ||||||
| @ -310,13 +321,13 @@ static void mf_ultralight_write() { | |||||||
|         FURI_LOG_D(TAG, "Writing page %d", i); |         FURI_LOG_D(TAG, "Writing page %d", i); | ||||||
|         furi_hal_random_fill_buf(page.data, sizeof(MfUltralightPage)); |         furi_hal_random_fill_buf(page.data, sizeof(MfUltralightPage)); | ||||||
|         mfu_data->page[i] = page; |         mfu_data->page[i] = page; | ||||||
|         error = mf_ultralight_poller_write_page(poller, i, &page); |         error = mf_ultralight_poller_sync_write_page(poller, i, &page); | ||||||
|         mu_assert(error == MfUltralightErrorNone, "mf_ultralight_poller_write_page() failed"); |         mu_assert(error == MfUltralightErrorNone, "mf_ultralight_poller_sync_write_page() failed"); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Verification read
 |     // Verification read
 | ||||||
|     error = mf_ultralight_poller_read_card(poller, mfu_data); |     error = mf_ultralight_poller_sync_read_card(poller, mfu_data); | ||||||
|     mu_assert(error == MfUltralightErrorNone, "mf_ultralight_poller_read_card() failed"); |     mu_assert(error == MfUltralightErrorNone, "mf_ultralight_poller_sync_read_card() failed"); | ||||||
| 
 | 
 | ||||||
|     nfc_listener_stop(mfu_listener); |     nfc_listener_stop(mfu_listener); | ||||||
|     const MfUltralightData* mfu_listener_data = |     const MfUltralightData* mfu_listener_data = | ||||||
| @ -344,7 +355,7 @@ static void mf_classic_reader() { | |||||||
|     MfClassicBlock block = {}; |     MfClassicBlock block = {}; | ||||||
|     MfClassicKey key = {.data = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; |     MfClassicKey key = {.data = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; | ||||||
| 
 | 
 | ||||||
|     mf_classic_poller_read_block(poller, 0, &key, MfClassicKeyTypeA, &block); |     mf_classic_poller_sync_read_block(poller, 0, &key, MfClassicKeyTypeA, &block); | ||||||
| 
 | 
 | ||||||
|     nfc_listener_stop(mfc_listener); |     nfc_listener_stop(mfc_listener); | ||||||
|     nfc_listener_free(mfc_listener); |     nfc_listener_free(mfc_listener); | ||||||
| @ -372,8 +383,8 @@ static void mf_classic_write() { | |||||||
|     furi_hal_random_fill_buf(block_write.data, sizeof(MfClassicBlock)); |     furi_hal_random_fill_buf(block_write.data, sizeof(MfClassicBlock)); | ||||||
|     MfClassicKey key = {.data = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; |     MfClassicKey key = {.data = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}}; | ||||||
| 
 | 
 | ||||||
|     mf_classic_poller_write_block(poller, 1, &key, MfClassicKeyTypeA, &block_write); |     mf_classic_poller_sync_write_block(poller, 1, &key, MfClassicKeyTypeA, &block_write); | ||||||
|     mf_classic_poller_read_block(poller, 1, &key, MfClassicKeyTypeA, &block_read); |     mf_classic_poller_sync_read_block(poller, 1, &key, MfClassicKeyTypeA, &block_read); | ||||||
| 
 | 
 | ||||||
|     nfc_listener_stop(mfc_listener); |     nfc_listener_stop(mfc_listener); | ||||||
|     nfc_listener_free(mfc_listener); |     nfc_listener_free(mfc_listener); | ||||||
| @ -402,16 +413,18 @@ static void mf_classic_value_block() { | |||||||
|     mf_classic_value_to_block(value, 1, &block_write); |     mf_classic_value_to_block(value, 1, &block_write); | ||||||
| 
 | 
 | ||||||
|     MfClassicError error = MfClassicErrorNone; |     MfClassicError error = MfClassicErrorNone; | ||||||
|     error = mf_classic_poller_write_block(poller, 1, &key, MfClassicKeyTypeA, &block_write); |     error = mf_classic_poller_sync_write_block(poller, 1, &key, MfClassicKeyTypeA, &block_write); | ||||||
|     mu_assert(error == MfClassicErrorNone, "Write failed"); |     mu_assert(error == MfClassicErrorNone, "Write failed"); | ||||||
| 
 | 
 | ||||||
|     int32_t data = 200; |     int32_t data = 200; | ||||||
|     int32_t new_value = 0; |     int32_t new_value = 0; | ||||||
|     error = mf_classic_poller_change_value(poller, 1, &key, MfClassicKeyTypeA, data, &new_value); |     error = | ||||||
|  |         mf_classic_poller_sync_change_value(poller, 1, &key, MfClassicKeyTypeA, data, &new_value); | ||||||
|     mu_assert(error == MfClassicErrorNone, "Value increment failed"); |     mu_assert(error == MfClassicErrorNone, "Value increment failed"); | ||||||
|     mu_assert(new_value == value + data, "Value not match"); |     mu_assert(new_value == value + data, "Value not match"); | ||||||
| 
 | 
 | ||||||
|     error = mf_classic_poller_change_value(poller, 1, &key, MfClassicKeyTypeA, -data, &new_value); |     error = | ||||||
|  |         mf_classic_poller_sync_change_value(poller, 1, &key, MfClassicKeyTypeA, -data, &new_value); | ||||||
|     mu_assert(error == MfClassicErrorNone, "Value decrement failed"); |     mu_assert(error == MfClassicErrorNone, "Value decrement failed"); | ||||||
|     mu_assert(new_value == value, "Value not match"); |     mu_assert(new_value == value, "Value not match"); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -122,7 +122,7 @@ Nfc* nfc_alloc() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_free(Nfc* instance) { | void nfc_free(Nfc* instance) { | ||||||
|     furi_assert(instance); |     furi_check(instance); | ||||||
| 
 | 
 | ||||||
|     free(instance); |     free(instance); | ||||||
| } | } | ||||||
| @ -165,9 +165,9 @@ NfcError nfc_iso14443a_listener_set_col_res_data( | |||||||
|     uint8_t uid_len, |     uint8_t uid_len, | ||||||
|     uint8_t* atqa, |     uint8_t* atqa, | ||||||
|     uint8_t sak) { |     uint8_t sak) { | ||||||
|     furi_assert(instance); |     furi_check(instance); | ||||||
|     furi_assert(uid); |     furi_check(uid); | ||||||
|     furi_assert(atqa); |     furi_check(atqa); | ||||||
| 
 | 
 | ||||||
|     nfc_prepare_col_res_data(instance, uid, uid_len, atqa, sak); |     nfc_prepare_col_res_data(instance, uid, uid_len, atqa, sak); | ||||||
| 
 | 
 | ||||||
| @ -176,7 +176,7 @@ NfcError nfc_iso14443a_listener_set_col_res_data( | |||||||
| 
 | 
 | ||||||
| static int32_t nfc_worker_poller(void* context) { | static int32_t nfc_worker_poller(void* context) { | ||||||
|     Nfc* instance = context; |     Nfc* instance = context; | ||||||
|     furi_assert(instance->callback); |     furi_check(instance->callback); | ||||||
| 
 | 
 | ||||||
|     instance->state = NfcStateReady; |     instance->state = NfcStateReady; | ||||||
|     NfcCommand command = NfcCommandContinue; |     NfcCommand command = NfcCommandContinue; | ||||||
| @ -196,7 +196,7 @@ static int32_t nfc_worker_poller(void* context) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void nfc_worker_listener_pass_col_res(Nfc* instance, uint8_t* rx_data, uint16_t rx_bits) { | static void nfc_worker_listener_pass_col_res(Nfc* instance, uint8_t* rx_data, uint16_t rx_bits) { | ||||||
|     furi_assert(instance->col_res_status != Iso14443_3aColResStatusDone); |     furi_check(instance->col_res_status != Iso14443_3aColResStatusDone); | ||||||
|     BitBuffer* tx_buffer = bit_buffer_alloc(NFC_MAX_BUFFER_SIZE); |     BitBuffer* tx_buffer = bit_buffer_alloc(NFC_MAX_BUFFER_SIZE); | ||||||
| 
 | 
 | ||||||
|     bool processed = false; |     bool processed = false; | ||||||
| @ -255,7 +255,7 @@ static void nfc_worker_listener_pass_col_res(Nfc* instance, uint8_t* rx_data, ui | |||||||
| 
 | 
 | ||||||
| static int32_t nfc_worker_listener(void* context) { | static int32_t nfc_worker_listener(void* context) { | ||||||
|     Nfc* instance = context; |     Nfc* instance = context; | ||||||
|     furi_assert(instance->callback); |     furi_check(instance->callback); | ||||||
| 
 | 
 | ||||||
|     NfcMessage message = {}; |     NfcMessage message = {}; | ||||||
| 
 | 
 | ||||||
| @ -295,17 +295,17 @@ static int32_t nfc_worker_listener(void* context) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_start(Nfc* instance, NfcEventCallback callback, void* context) { | void nfc_start(Nfc* instance, NfcEventCallback callback, void* context) { | ||||||
|     furi_assert(instance); |     furi_check(instance); | ||||||
|     furi_assert(instance->worker_thread == NULL); |     furi_check(instance->worker_thread == NULL); | ||||||
| 
 | 
 | ||||||
|     if(instance->mode == NfcModeListener) { |     if(instance->mode == NfcModeListener) { | ||||||
|         furi_assert(listener_queue == NULL); |         furi_check(listener_queue == NULL); | ||||||
|         // Check that poller didn't start
 |         // Check that poller didn't start
 | ||||||
|         furi_assert(poller_queue == NULL); |         furi_check(poller_queue == NULL); | ||||||
|     } else { |     } else { | ||||||
|         furi_assert(poller_queue == NULL); |         furi_check(poller_queue == NULL); | ||||||
|         // Check that poller is started after listener
 |         // Check that poller is started after listener
 | ||||||
|         furi_assert(listener_queue); |         furi_check(listener_queue); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     instance->callback = callback; |     instance->callback = callback; | ||||||
| @ -334,8 +334,8 @@ void nfc_start(Nfc* instance, NfcEventCallback callback, void* context) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void nfc_stop(Nfc* instance) { | void nfc_stop(Nfc* instance) { | ||||||
|     furi_assert(instance); |     furi_check(instance); | ||||||
|     furi_assert(instance->worker_thread); |     furi_check(instance->worker_thread); | ||||||
| 
 | 
 | ||||||
|     if(instance->mode == NfcModeListener) { |     if(instance->mode == NfcModeListener) { | ||||||
|         NfcMessage message = {.type = NfcMessageTypeAbort}; |         NfcMessage message = {.type = NfcMessageTypeAbort}; | ||||||
| @ -361,10 +361,10 @@ void nfc_stop(Nfc* instance) { | |||||||
| // Called from worker thread
 | // Called from worker thread
 | ||||||
| 
 | 
 | ||||||
| NfcError nfc_listener_tx(Nfc* instance, const BitBuffer* tx_buffer) { | NfcError nfc_listener_tx(Nfc* instance, const BitBuffer* tx_buffer) { | ||||||
|     furi_assert(instance); |     furi_check(instance); | ||||||
|     furi_assert(poller_queue); |     furi_check(poller_queue); | ||||||
|     furi_assert(listener_queue); |     furi_check(listener_queue); | ||||||
|     furi_assert(tx_buffer); |     furi_check(tx_buffer); | ||||||
| 
 | 
 | ||||||
|     NfcMessage message = {}; |     NfcMessage message = {}; | ||||||
|     message.type = NfcMessageTypeTx; |     message.type = NfcMessageTypeTx; | ||||||
| @ -382,11 +382,11 @@ NfcError nfc_iso14443a_listener_tx_custom_parity(Nfc* instance, const BitBuffer* | |||||||
| 
 | 
 | ||||||
| NfcError | NfcError | ||||||
|     nfc_poller_trx(Nfc* instance, const BitBuffer* tx_buffer, BitBuffer* rx_buffer, uint32_t fwt) { |     nfc_poller_trx(Nfc* instance, const BitBuffer* tx_buffer, BitBuffer* rx_buffer, uint32_t fwt) { | ||||||
|     furi_assert(instance); |     furi_check(instance); | ||||||
|     furi_assert(tx_buffer); |     furi_check(tx_buffer); | ||||||
|     furi_assert(rx_buffer); |     furi_check(rx_buffer); | ||||||
|     furi_assert(poller_queue); |     furi_check(poller_queue); | ||||||
|     furi_assert(listener_queue); |     furi_check(listener_queue); | ||||||
|     UNUSED(fwt); |     UNUSED(fwt); | ||||||
| 
 | 
 | ||||||
|     NfcError error = NfcErrorNone; |     NfcError error = NfcErrorNone; | ||||||
| @ -396,7 +396,7 @@ NfcError | |||||||
|     message.data.data_bits = bit_buffer_get_size(tx_buffer); |     message.data.data_bits = bit_buffer_get_size(tx_buffer); | ||||||
|     bit_buffer_write_bytes(tx_buffer, message.data.data, bit_buffer_get_size_bytes(tx_buffer)); |     bit_buffer_write_bytes(tx_buffer, message.data.data, bit_buffer_get_size_bytes(tx_buffer)); | ||||||
|     // Tx
 |     // Tx
 | ||||||
|     furi_assert(furi_message_queue_put(listener_queue, &message, FuriWaitForever) == FuriStatusOk); |     furi_check(furi_message_queue_put(listener_queue, &message, FuriWaitForever) == FuriStatusOk); | ||||||
|     // Rx
 |     // Rx
 | ||||||
|     FuriStatus status = furi_message_queue_get(poller_queue, &message, 50); |     FuriStatus status = furi_message_queue_get(poller_queue, &message, 50); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -0,0 +1,7 @@ | |||||||
|  | Filetype: Flipper SubGhz Key File | ||||||
|  | Version: 1 | ||||||
|  | Frequency: 433920000 | ||||||
|  | Preset: FuriHalSubGhzPresetOok270Async | ||||||
|  | Protocol: Mastercode | ||||||
|  | Bit: 36 | ||||||
|  | Key: 00 00 00 0B 7E 00 3C 08 | ||||||
| @ -0,0 +1,6 @@ | |||||||
|  | Filetype: Flipper SubGhz RAW File | ||||||
|  | Version: 1 | ||||||
|  | Frequency: 433920000 | ||||||
|  | Preset: FuriHalSubGhzPresetOok270Async | ||||||
|  | Protocol: RAW | ||||||
|  | RAW_Data: 10389 -66 405095 -102 207 -106 1165 -130 963739 -1232 899 -2250 2003 -1190 2017 -1202 911 -2256 2021 -1162 2045 -1134 2047 -1164 2047 -1138 2031 -1180 2039 -1182 949 -2190 995 -2214 961 -2228 963 -2198 963 -2214 977 -2212 975 -2210 975 -2208 971 -2200 963 -2210 993 -2184 2075 -1130 2051 -1142 2055 -1136 2047 -1178 965 -2236 933 -2220 975 -2184 999 -2222 967 -2208 969 -2214 979 -2202 2027 -1156 975 -2242 943 -16080 2023 -1162 967 -2220 2057 -1114 2061 -1124 1007 -2242 2025 -1134 2055 -1168 2017 -1138 2075 -1134 2053 -1136 2075 -1130 979 -2214 979 -2174 999 -2182 1001 -2204 977 -2206 1003 -2188 979 -2176 999 -2182 1009 -2176 1009 -2176 1001 -2212 2029 -1116 2091 -1102 2109 -1092 2095 -1126 1001 -2150 1011 -2180 1011 -2180 1009 -2178 1009 -2172 1009 -2166 1001 -2198 2065 -1136 975 -2220 971 -16018 2097 -1166 951 -2240 2009 -1186 2011 -1160 979 -2208 2035 -1134 2053 -1138 2061 -1158 2045 -1152 2029 -1152 2051 -1166 963 -2188 993 -2222 951 -2214 963 -2220 965 -2212 979 -2212 977 -2180 1003 -2202 965 -2218 975 -2216 967 -2188 2061 -1124 2083 -1126 2071 -1130 2059 -1134 993 -2188 979 -2240 947 -2204 979 -2214 971 -2214 973 -2210 971 -2206 2053 -1130 979 -2216 969 -16056 2053 -1134 1001 -2224 2021 -1150 2051 -1154 953 -2240 2045 -1146 2023 -1168 2033 -1144 2065 -1146 2055 -1130 2071 -1160 961 -2192 973 -2190 1005 -2214 975 -2206 967 -2206 975 -2206 967 -2208 975 -2212 967 -2212 979 -2218 977 -2178 2063 -1156 2035 -1160 2061 -1126 2065 -1130 981 -2186 1003 -2210 977 -2208 973 -2202 977 -2200 965 -2248 943 -2206 2039 -1190 941 -48536 65 -7254 263 -68 363 -102 131 -232 263 -264 751 -230 225 -822 397 -634 231 -268 263 -134 267 -64 867 -132 305 -138 67 -100 331 -98 891 -66 455 -66 531 -100 299 -134 897 -98 693 -132 291 -132 333 -98 337 -68 331 | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Aleksandr Kutuzov
						Aleksandr Kutuzov