Merge branch 'release-candidate' into release
This commit is contained in:
		
						commit
						0c592ff84a
					
				
							
								
								
									
										3
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							| @ -1 +1,4 @@ | |||||||
| * text=auto eol=lf | * text=auto eol=lf | ||||||
|  | *.bat eol=crlf | ||||||
|  | *.ps1 eol=crlf | ||||||
|  | *.cmd eol=crlf | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								.github/CODEOWNERS
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/CODEOWNERS
									
									
									
									
										vendored
									
									
								
							| @ -40,7 +40,7 @@ | |||||||
| /assets/ @skotopes @DrZlo13 @hedger | /assets/ @skotopes @DrZlo13 @hedger | ||||||
| 
 | 
 | ||||||
| # Furi Core | # Furi Core | ||||||
| /core/ @skotopes @DrZlo13 @hedger | /furi/ @skotopes @DrZlo13 @hedger | ||||||
| 
 | 
 | ||||||
| # Debug tools and plugins | # Debug tools and plugins | ||||||
| /debug/ @skotopes @DrZlo13 @hedger | /debug/ @skotopes @DrZlo13 @hedger | ||||||
| @ -76,7 +76,7 @@ | |||||||
| /lib/microtar/ @skotopes @DrZlo13 @hedger | /lib/microtar/ @skotopes @DrZlo13 @hedger | ||||||
| /lib/mlib/ @skotopes @DrZlo13 @hedger | /lib/mlib/ @skotopes @DrZlo13 @hedger | ||||||
| /lib/nanopb/ @skotopes @DrZlo13 @hedger | /lib/nanopb/ @skotopes @DrZlo13 @hedger | ||||||
| /lib/nfc_protocols/ @skotopes @DrZlo13 @hedger @gornekich | /lib/nfc/ @skotopes @DrZlo13 @hedger @gornekich | ||||||
| /lib/one_wire/ @skotopes @DrZlo13 @hedger | /lib/one_wire/ @skotopes @DrZlo13 @hedger | ||||||
| /lib/qrcode/ @skotopes @DrZlo13 @hedger | /lib/qrcode/ @skotopes @DrZlo13 @hedger | ||||||
| /lib/subghz/ @skotopes @DrZlo13 @hedger @Skorpionm | /lib/subghz/ @skotopes @DrZlo13 @hedger @Skorpionm | ||||||
|  | |||||||
							
								
								
									
										46
									
								
								.github/ISSUE_TEMPLATE/01_bug_report.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								.github/ISSUE_TEMPLATE/01_bug_report.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | |||||||
|  | name: Bug report | ||||||
|  | description: File a bug reports regarding the firmware. | ||||||
|  | labels: ['bug'] | ||||||
|  | body: | ||||||
|  | - type: markdown | ||||||
|  |   attributes: | ||||||
|  |     value: | | ||||||
|  |       Thank you for taking the time to fill out an issue, this template is meant for any issues related to the Flipper Zero firmware. | ||||||
|  |       If you require help with the Flipper zero and its firmware, we ask that you join [our forum](https://forum.flipperzero.one) | ||||||
|  | - type: textarea | ||||||
|  |   id: description | ||||||
|  |   attributes: | ||||||
|  |     label: Describe the bug. | ||||||
|  |     description: "A clear and concise description of what the bug is." | ||||||
|  |   validations: | ||||||
|  |     required: true | ||||||
|  | - type: textarea | ||||||
|  |   id: repro | ||||||
|  |   attributes:  | ||||||
|  |     label: Reproduction | ||||||
|  |     description: "How can this bug be reproduced?" | ||||||
|  |     placeholder: | | ||||||
|  |       1. Switch on... | ||||||
|  |       2. Press button '....' | ||||||
|  |       3. Wait for the moon phase | ||||||
|  |       4. It burns | ||||||
|  |   validations: | ||||||
|  |     required: true | ||||||
|  | - type: input | ||||||
|  |   id: target | ||||||
|  |   attributes: | ||||||
|  |     label: Target | ||||||
|  |     description: Specify the target | ||||||
|  |     # Target seems to be largely ignored by outside sources. | ||||||
|  | - type: textarea | ||||||
|  |   id: logs | ||||||
|  |   attributes: | ||||||
|  |     label: Logs | ||||||
|  |     description: Attach your debug logs here | ||||||
|  |     render: Text | ||||||
|  |     # Avoid rendering as Markdown here. | ||||||
|  | - type: textarea | ||||||
|  |   id: anything-else | ||||||
|  |   attributes: | ||||||
|  |     label: Anything else? | ||||||
|  |     description: Let us know if you have anything else to share. | ||||||
							
								
								
									
										21
									
								
								.github/ISSUE_TEMPLATE/02_enhancements.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								.github/ISSUE_TEMPLATE/02_enhancements.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | name: Enhancements | ||||||
|  | description: Suggest improvements for any existing functionality within the firmware. | ||||||
|  | body: | ||||||
|  | - type: markdown | ||||||
|  |   attributes: | ||||||
|  |     value: | | ||||||
|  |       Thank you for taking the time to fill out an issue. This template is meant for feature requests and improvements to already existing functionality. | ||||||
|  |       If you require help with the Flipper zero and its firmware, we ask that you join [our forum](https://forum.flipperzero.one) | ||||||
|  | - type: textarea | ||||||
|  |   id: proposal | ||||||
|  |   attributes: | ||||||
|  |     label: "Describe the enhancement you're suggesting." | ||||||
|  |     description: | | ||||||
|  |       Feel free to describe in as much detail as you wish. | ||||||
|  |   validations: | ||||||
|  |     required: true | ||||||
|  | - type: textarea | ||||||
|  |   id: anything-else | ||||||
|  |   attributes: | ||||||
|  |     label: Anything else? | ||||||
|  |     description: Let us know if you have anything else to share. | ||||||
							
								
								
									
										24
									
								
								.github/ISSUE_TEMPLATE/03_feature_request.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								.github/ISSUE_TEMPLATE/03_feature_request.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | name: Feature Request | ||||||
|  | description: For feature requests regarding the firmware. | ||||||
|  | labels: ['feature request'] | ||||||
|  | body: | ||||||
|  | - type: markdown | ||||||
|  |   attributes: | ||||||
|  |     value: | | ||||||
|  |       Thank you for taking the time to fill out an issue, this template is meant for any feature suggestions. | ||||||
|  |       If you require help with the Flipper zero and its firmware, we ask that you join [our forum](https://forum.flipperzero.one) | ||||||
|  | - type: textarea | ||||||
|  |   id: proposal | ||||||
|  |   attributes: | ||||||
|  |     label: "Description of the feature you're suggesting." | ||||||
|  |     description: | | ||||||
|  |       Please describe your feature request in as many details as possible. | ||||||
|  |         - Describe what it should do. | ||||||
|  |         - Note whetever it is to extend existing functionality or introduce new functionality. | ||||||
|  |   validations: | ||||||
|  |     required: true | ||||||
|  | - type: textarea | ||||||
|  |   id: anything-else | ||||||
|  |   attributes: | ||||||
|  |     label: Anything else? | ||||||
|  |     description: Let us know if you have anything else to share. | ||||||
							
								
								
									
										30
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										30
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
								
							| @ -1,30 +0,0 @@ | |||||||
| --- |  | ||||||
| name: Bug report |  | ||||||
| about: Create a report to help us improve |  | ||||||
| title: '' |  | ||||||
| labels: bug |  | ||||||
| assignees: '' |  | ||||||
| 
 |  | ||||||
| --- |  | ||||||
| 
 |  | ||||||
| **Describe the bug** |  | ||||||
| A clear and concise description of what the bug is. |  | ||||||
| 
 |  | ||||||
| **To Reproduce** |  | ||||||
| Steps to reproduce the behavior: |  | ||||||
| 1. Switch on... |  | ||||||
| 2. Press button '....' |  | ||||||
| 3. Wait for the moon phase |  | ||||||
| 4. It burns |  | ||||||
| 
 |  | ||||||
| **Expected behavior** |  | ||||||
| A clear and concise description of what you expected to happen. |  | ||||||
| 
 |  | ||||||
| **Logs** |  | ||||||
| Add debug logs |  | ||||||
| 
 |  | ||||||
| **Target** |  | ||||||
| Specify the target |  | ||||||
| 
 |  | ||||||
| **Additional context** |  | ||||||
| Add any other context about the problem here. |  | ||||||
							
								
								
									
										5
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								.github/ISSUE_TEMPLATE/config.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | blank_issues_enabled: true | ||||||
|  | contact_links: | ||||||
|  |   - name: Need help? | ||||||
|  |     url: https://forum.flipperzero.one | ||||||
|  |     about: For any question regarding on how to use the Flipper Zero and its firmware. | ||||||
							
								
								
									
										12
									
								
								.github/ISSUE_TEMPLATE/discuss-issue.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.github/ISSUE_TEMPLATE/discuss-issue.md
									
									
									
									
										vendored
									
									
								
							| @ -1,12 +0,0 @@ | |||||||
| --- |  | ||||||
| name: Discuss issue |  | ||||||
| about: Start discussion about improvements |  | ||||||
| title: '' |  | ||||||
| labels: discussion |  | ||||||
| assignees: '' |  | ||||||
| 
 |  | ||||||
| --- |  | ||||||
| 
 |  | ||||||
| # What are you want to add or change |  | ||||||
| 
 |  | ||||||
| # What questions do you have |  | ||||||
							
								
								
									
										20
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										20
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
								
							| @ -1,20 +0,0 @@ | |||||||
| --- |  | ||||||
| name: Feature request |  | ||||||
| about: Suggest an idea for this project |  | ||||||
| title: '' |  | ||||||
| labels: feature request |  | ||||||
| assignees: '' |  | ||||||
| 
 |  | ||||||
| --- |  | ||||||
| 
 |  | ||||||
| **Is your feature request related to a problem? Please describe.** |  | ||||||
| A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] |  | ||||||
| 
 |  | ||||||
| **Describe the solution you'd like** |  | ||||||
| A clear and concise description of what you want to happen. |  | ||||||
| 
 |  | ||||||
| **Describe alternatives you've considered** |  | ||||||
| A clear and concise description of any alternative solutions or features you've considered. |  | ||||||
| 
 |  | ||||||
| **Additional context** |  | ||||||
| Add any other context or screenshots about the feature request here. |  | ||||||
							
								
								
									
										10
									
								
								.github/ISSUE_TEMPLATE/in-progress.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.github/ISSUE_TEMPLATE/in-progress.md
									
									
									
									
										vendored
									
									
								
							| @ -1,10 +0,0 @@ | |||||||
| --- |  | ||||||
| name: In progress |  | ||||||
| about: When you start doing your big deal |  | ||||||
| title: '' |  | ||||||
| labels: in progress |  | ||||||
| assignees: '' |  | ||||||
| 
 |  | ||||||
| --- |  | ||||||
| 
 |  | ||||||
| Shortly (or not) describe what are you will do |  | ||||||
							
								
								
									
										10
									
								
								.github/ISSUE_TEMPLATE/need-help.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.github/ISSUE_TEMPLATE/need-help.md
									
									
									
									
										vendored
									
									
								
							| @ -1,10 +0,0 @@ | |||||||
| --- |  | ||||||
| name: Need help |  | ||||||
| about: Ask the community for help if you confused and can't figure out something |  | ||||||
| title: '' |  | ||||||
| labels: need help |  | ||||||
| assignees: '' |  | ||||||
| 
 |  | ||||||
| --- |  | ||||||
| 
 |  | ||||||
| # Describe you problem here |  | ||||||
							
								
								
									
										115
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										115
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							| @ -15,11 +15,8 @@ env: | |||||||
| 
 | 
 | ||||||
| jobs: | jobs: | ||||||
|   main: |   main: | ||||||
|     runs-on: [self-hosted,FlipperZero] |     runs-on: [self-hosted,FlipperZeroShell] | ||||||
|     steps: |     steps: | ||||||
|       - name: 'Cleanup workspace' |  | ||||||
|         uses: AutoModality/action-clean@v1 |  | ||||||
| 
 |  | ||||||
|       - name: 'Decontaminate previous build leftovers' |       - name: 'Decontaminate previous build leftovers' | ||||||
|         run: | |         run: | | ||||||
|           if [ -d .git ] |           if [ -d .git ] | ||||||
| @ -32,12 +29,8 @@ jobs: | |||||||
|         uses: actions/checkout@v2 |         uses: actions/checkout@v2 | ||||||
|         with: |         with: | ||||||
|           fetch-depth: 0 |           fetch-depth: 0 | ||||||
|           submodules: true |  | ||||||
|           ref: ${{ github.event.pull_request.head.sha }} |           ref: ${{ github.event.pull_request.head.sha }} | ||||||
| 
 | 
 | ||||||
|       - name: 'Build docker image' |  | ||||||
|         uses: ./.github/actions/docker |  | ||||||
| 
 |  | ||||||
|       - name: 'Make artifacts directory' |       - name: 'Make artifacts directory' | ||||||
|         run: | |         run: | | ||||||
|           test -d artifacts && rm -rf artifacts || true |           test -d artifacts && rm -rf artifacts || true | ||||||
| @ -71,40 +64,38 @@ jobs: | |||||||
|         run: | |         run: | | ||||||
|           tar czpf artifacts/flipper-z-any-scripts-${{steps.names.outputs.suffix}}.tgz scripts |           tar czpf artifacts/flipper-z-any-scripts-${{steps.names.outputs.suffix}}.tgz scripts | ||||||
| 
 | 
 | ||||||
|       - name: 'Build the firmware in docker' |       - name: 'Build the firmware' | ||||||
|         uses: ./.github/actions/docker |         run: | | ||||||
|         with: |           set -e | ||||||
|           run: | |           for TARGET in ${TARGETS} | ||||||
|             set -e |           do | ||||||
|             for TARGET in ${TARGETS} |             FBT_TOOLCHAIN_PATH=/opt ./fbt TARGET_HW=`echo ${TARGET} | sed 's/f//'` updater_package ${{ startsWith(github.ref, 'refs/tags') && 'DEBUG=0 COMPACT=1' || '' }} | ||||||
|             do |           done | ||||||
|               ./fbt TARGET_HW=`echo ${TARGET} | sed 's/f//'` --with-updater updater_package ${{ startsWith(github.ref, 'refs/tags') && 'DEBUG=0 COMPACT=1' || '' }} |  | ||||||
|             done |  | ||||||
| 
 | 
 | ||||||
|       - name: 'Move upload files' |       - name: 'Move upload files' | ||||||
|         if: ${{ !github.event.pull_request.head.repo.fork }} |         if: ${{ !github.event.pull_request.head.repo.fork }} | ||||||
|         uses: ./.github/actions/docker |         run: | | ||||||
|         with: |           set -e | ||||||
|           run: | |           for TARGET in ${TARGETS} | ||||||
|             set -e |           do | ||||||
|             for TARGET in ${TARGETS} |             mv dist/${TARGET}-*/* artifacts/ | ||||||
|             do |           done | ||||||
|               mv dist/${TARGET}-*/* artifacts/ |  | ||||||
|             done |  | ||||||
| 
 | 
 | ||||||
|       - name: 'Bundle self-update package' |       - name: 'Bundle self-update package' | ||||||
|         if: ${{ !github.event.pull_request.head.repo.fork }} |         if: ${{ !github.event.pull_request.head.repo.fork }} | ||||||
|         uses: ./.github/actions/docker |         run: | | ||||||
|         with: |           set -e | ||||||
|           run: | |           for UPDATEBUNDLE in artifacts/*/ | ||||||
|             set -e |           do | ||||||
|             for UPDATEBUNDLE in artifacts/*/ |             BUNDLE_NAME=`echo $UPDATEBUNDLE | cut -d'/' -f2` | ||||||
|             do |             echo Packaging ${BUNDLE_NAME} | ||||||
|               BUNDLE_NAME=`echo $UPDATEBUNDLE | cut -d'/' -f2` |             tar czpf artifacts/flipper-z-${BUNDLE_NAME}.tgz -C artifacts ${BUNDLE_NAME} | ||||||
|               echo Packaging ${BUNDLE_NAME} |             rm -rf artifacts/${BUNDLE_NAME} | ||||||
|               tar czpf artifacts/flipper-z-${BUNDLE_NAME}.tgz -C artifacts ${BUNDLE_NAME} |           done | ||||||
|               rm -rf artifacts/${BUNDLE_NAME} | 
 | ||||||
|             done |       - name: "Check for uncommited changes" | ||||||
|  |         run: | | ||||||
|  |           git diff --exit-code | ||||||
| 
 | 
 | ||||||
|       - name: 'Bundle resources' |       - name: 'Bundle resources' | ||||||
|         if: ${{ !github.event.pull_request.head.repo.fork }} |         if: ${{ !github.event.pull_request.head.repo.fork }} | ||||||
| @ -113,29 +104,23 @@ jobs: | |||||||
| 
 | 
 | ||||||
|       - name: 'Bundle core2 firmware' |       - name: 'Bundle core2 firmware' | ||||||
|         if: ${{ !github.event.pull_request.head.repo.fork }} |         if: ${{ !github.event.pull_request.head.repo.fork }} | ||||||
|         uses: ./.github/actions/docker |         run: | | ||||||
|         with: |           FBT_TOOLCHAIN_PATH=/opt ./fbt copro_dist | ||||||
|           run: | |           tar czpf artifacts/flipper-z-any-core2_firmware-${{steps.names.outputs.suffix}}.tgz -C assets core2_firmware | ||||||
|             ./fbt copro_dist |  | ||||||
|             tar czpf artifacts/flipper-z-any-core2_firmware-${{steps.names.outputs.suffix}}.tgz -C assets core2_firmware |  | ||||||
| 
 | 
 | ||||||
|       - name: 'Upload artifacts to update server' |       - name: 'Upload artifacts to update server' | ||||||
|         if: ${{ !github.event.pull_request.head.repo.fork }} |         if: ${{ !github.event.pull_request.head.repo.fork }} | ||||||
|         uses: burnett01/rsync-deployments@5.1 |         run: | | ||||||
|         with: |           echo "${{ secrets.RSYNC_DEPLOY_KEY }}" > deploy_key; | ||||||
|           switches: -avzP --delete --mkpath |           chmod 600 ./deploy_key; | ||||||
|           path: artifacts/ |           rsync -avzP --mkpath \ | ||||||
|           remote_path: "${{ secrets.RSYNC_DEPLOY_BASE_PATH }}${{steps.names.outputs.artifacts-path}}/" |               -e 'ssh -p ${{ secrets.RSYNC_DEPLOY_PORT }} -i ./deploy_key' \ | ||||||
|           remote_host: ${{ secrets.RSYNC_DEPLOY_HOST }} |               artifacts/ ${{ secrets.RSYNC_DEPLOY_USER }}@${{ secrets.RSYNC_DEPLOY_HOST }}:"${{ secrets.RSYNC_DEPLOY_BASE_PATH }}${{steps.names.outputs.artifacts-path}}/"; | ||||||
|           remote_port: ${{ secrets.RSYNC_DEPLOY_PORT }} |           rm ./deploy_key; | ||||||
|           remote_user: ${{ secrets.RSYNC_DEPLOY_USER }} |  | ||||||
|           remote_key: ${{ secrets.RSYNC_DEPLOY_KEY }} |  | ||||||
| 
 | 
 | ||||||
|       - name: 'Trigger update server reindex' |       - name: 'Trigger update server reindex' | ||||||
|         if: ${{ !github.event.pull_request.head.repo.fork }} |         if: ${{ !github.event.pull_request.head.repo.fork }} | ||||||
|         uses: wei/curl@master |         run: curl -X POST -F 'key=${{ secrets.REINDEX_KEY }}' ${{ secrets.REINDEX_URL }} | ||||||
|         with: |  | ||||||
|           args: -X POST -F 'key=${{ secrets.REINDEX_KEY }}' ${{ secrets.REINDEX_URL }} |  | ||||||
| 
 | 
 | ||||||
|       - name: 'Find Previous Comment' |       - name: 'Find Previous Comment' | ||||||
|         if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request }} |         if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request }} | ||||||
| @ -161,11 +146,8 @@ jobs: | |||||||
| 
 | 
 | ||||||
|   compact: |   compact: | ||||||
|     if: ${{ !startsWith(github.ref, 'refs/tags') }} |     if: ${{ !startsWith(github.ref, 'refs/tags') }} | ||||||
|     runs-on: [self-hosted,FlipperZero] |     runs-on: [self-hosted,FlipperZeroShell] | ||||||
|     steps: |     steps: | ||||||
|       - name: 'Cleanup workspace' |  | ||||||
|         uses: AutoModality/action-clean@v1 |  | ||||||
| 
 |  | ||||||
|       - name: 'Decontaminate previous build leftovers' |       - name: 'Decontaminate previous build leftovers' | ||||||
|         run: | |         run: | | ||||||
|           if [ -d .git ] |           if [ -d .git ] | ||||||
| @ -181,9 +163,6 @@ jobs: | |||||||
|           submodules: true |           submodules: true | ||||||
|           ref: ${{ github.event.pull_request.head.sha }} |           ref: ${{ github.event.pull_request.head.sha }} | ||||||
| 
 | 
 | ||||||
|       - name: 'Build docker image' |  | ||||||
|         uses: ./.github/actions/docker |  | ||||||
| 
 |  | ||||||
|       - name: 'Generate suffix and folder name' |       - name: 'Generate suffix and folder name' | ||||||
|         id: names |         id: names | ||||||
|         run: | |         run: | | ||||||
| @ -203,12 +182,10 @@ jobs: | |||||||
|           echo "WORKFLOW_BRANCH_OR_TAG=${BRANCH_OR_TAG}" >> $GITHUB_ENV |           echo "WORKFLOW_BRANCH_OR_TAG=${BRANCH_OR_TAG}" >> $GITHUB_ENV | ||||||
|           echo "DIST_SUFFIX=${SUFFIX}" >> $GITHUB_ENV |           echo "DIST_SUFFIX=${SUFFIX}" >> $GITHUB_ENV | ||||||
| 
 | 
 | ||||||
|       - name: 'Build the firmware in docker' |       - name: 'Build the firmware' | ||||||
|         uses: ./.github/actions/docker |         run: | | ||||||
|         with: |           set -e | ||||||
|           run: | |           for TARGET in ${TARGETS} | ||||||
|             set -e |           do | ||||||
|             for TARGET in ${TARGETS} |             FBT_TOOLCHAIN_PATH=/opt ./fbt TARGET_HW=`echo ${TARGET} | sed 's/f//'` updater_package DEBUG=0 COMPACT=1 | ||||||
|             do |           done | ||||||
|               ./fbt TARGET_HW=`echo ${TARGET} | sed 's/f//'` --with-updater updater_package DEBUG=0 COMPACT=1 |  | ||||||
|             done |  | ||||||
|  | |||||||
							
								
								
									
										46
									
								
								.github/workflows/build_toolchain.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								.github/workflows/build_toolchain.yml
									
									
									
									
										vendored
									
									
								
							| @ -1,46 +0,0 @@ | |||||||
| name: 'Build toolchain Docker image' |  | ||||||
| 
 |  | ||||||
| on: |  | ||||||
|   push: |  | ||||||
|     branches: |  | ||||||
|       - dev |  | ||||||
|     tags: |  | ||||||
|       - '*' |  | ||||||
| 
 |  | ||||||
| jobs: |  | ||||||
|   build: |  | ||||||
|     runs-on: ubuntu-latest |  | ||||||
|     steps: |  | ||||||
|       - name: Checkout code |  | ||||||
|         uses: actions/checkout@v2 |  | ||||||
|         with: |  | ||||||
|           fetch-depth: 0 |  | ||||||
|       - name: Docker meta |  | ||||||
|         id: meta |  | ||||||
|         uses: docker/metadata-action@v3 |  | ||||||
|         with: |  | ||||||
|           images: flipperdevices/flipperzero-toolchain |  | ||||||
|           flavor: latest=${{ startsWith(github.ref, 'refs/tags/') && !endsWith(github.ref, 'rc')}} |  | ||||||
|           tags: | |  | ||||||
|             type=ref,event=branch |  | ||||||
|             type=ref,event=tag |  | ||||||
|       - name: Set up QEMU |  | ||||||
|         uses: docker/setup-qemu-action@v1 |  | ||||||
|       - name: Set up Docker Buildx |  | ||||||
|         uses: docker/setup-buildx-action@v1 |  | ||||||
|       - name: Login to DockerHub |  | ||||||
|         uses: docker/login-action@v1 |  | ||||||
|         with: |  | ||||||
|           username: ${{ secrets.DOCKERHUB_USERNAME }} |  | ||||||
|           password: ${{ secrets.DOCKERHUB_TOKEN }} |  | ||||||
|       - name: Build and push |  | ||||||
|         id: docker_build |  | ||||||
|         uses: docker/build-push-action@v2 |  | ||||||
|         with: |  | ||||||
|           context: docker/ |  | ||||||
|           push: true |  | ||||||
|           tags: ${{ steps.meta.outputs.tags }} |  | ||||||
|           labels: ${{ steps.meta.outputs.labels }} |  | ||||||
|           platforms: linux/amd64,linux/arm64 |  | ||||||
|           cache-from: type=registry,ref=flipperdevices/flipperzero-toolchain:buildcache |  | ||||||
|           cache-to: type=registry,ref=flipperdevices/flipperzero-toolchain:buildcache,mode=max |  | ||||||
							
								
								
									
										52
									
								
								.github/workflows/check_submodules.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								.github/workflows/check_submodules.yml
									
									
									
									
										vendored
									
									
								
							| @ -1,17 +1,47 @@ | |||||||
| name: 'Check submodules' | name: 'Check submodules branch' | ||||||
| 
 | 
 | ||||||
| on: | on: | ||||||
|  |   push: | ||||||
|  |     branches: | ||||||
|  |       - dev | ||||||
|  |       - "release*" | ||||||
|  |     tags: | ||||||
|  |       - '*' | ||||||
|   pull_request: |   pull_request: | ||||||
| 
 | 
 | ||||||
| jobs: | jobs: | ||||||
|   protobuf: |   check_protobuf: | ||||||
|     runs-on: ubuntu-latest |     runs-on: [self-hosted, FlipperZeroShell] | ||||||
|     steps: |     steps: | ||||||
|     - name: 'Checkout code' |       - name: 'Decontaminate previous build leftovers' | ||||||
|       uses: actions/checkout@v2 |         run: | | ||||||
|     - name: 'Check submodule commit branch' |           if [ -d .git ] | ||||||
|       uses: jtmullen/submodule-branch-check-action@v1 |           then | ||||||
|       with: |             git submodule status \ | ||||||
|         path: assets/protobuf |               || git checkout `git rev-list --max-parents=0 HEAD | tail -n 1` | ||||||
|         branch: dev |           fi | ||||||
|         fetch_depth: 50 | 
 | ||||||
|  |       - name: 'Checkout code' | ||||||
|  |         uses: actions/checkout@v2 | ||||||
|  |         with: | ||||||
|  |           fetch-depth: 0 | ||||||
|  | 
 | ||||||
|  |       - name: 'Check protobuf branch' | ||||||
|  |         run: | | ||||||
|  |           SUB_PATH="assets/protobuf"; | ||||||
|  |           SUB_BRANCH="dev"; | ||||||
|  |           SUB_COMMITS_MIN=40; | ||||||
|  |           cd "$SUB_PATH"; | ||||||
|  |           SUBMODULE_HASH="$(git rev-parse HEAD)"; | ||||||
|  |           BRANCHES=$(git branch -r --contains "$SUBMODULE_HASH"); | ||||||
|  |           COMMITS_IN_BRANCH="$(git rev-list --count dev)"; | ||||||
|  |           if [ $COMMITS_IN_BRANCH -lt $SUB_COMMITS_MIN ]; then | ||||||
|  |             echo "::set-output name=fails::error"; | ||||||
|  |             echo "::error::Error: Too low commits in $SUB_BRANCH of submodule $SUB_PATH: $COMMITS_IN_BRANCH(expected $SUB_COMMITS_MIN+)"; | ||||||
|  |             exit 1; | ||||||
|  |           fi | ||||||
|  |           if ! grep -q "/$SUB_BRANCH" <<< "$BRANCHES"; then | ||||||
|  |             echo "::set-output name=fails::error"; | ||||||
|  |             echo "::error::Error: Submodule $SUB_PATH is not on branch $SUB_BRANCH"; | ||||||
|  |             exit 1; | ||||||
|  |           fi | ||||||
|  | |||||||
							
								
								
									
										22
									
								
								.github/workflows/lint_c.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								.github/workflows/lint_c.yml
									
									
									
									
										vendored
									
									
								
							| @ -14,11 +14,8 @@ env: | |||||||
| 
 | 
 | ||||||
| jobs: | jobs: | ||||||
|   lint_c_cpp: |   lint_c_cpp: | ||||||
|     runs-on: [self-hosted,FlipperZero] |     runs-on: [self-hosted,FlipperZeroShell] | ||||||
|     steps: |     steps: | ||||||
|       - name: 'Cleanup workspace' |  | ||||||
|         uses: AutoModality/action-clean@v1 |  | ||||||
| 
 |  | ||||||
|       - name: 'Decontaminate previous build leftovers' |       - name: 'Decontaminate previous build leftovers' | ||||||
|         run: | |         run: | | ||||||
|           if [ -d .git ] |           if [ -d .git ] | ||||||
| @ -31,23 +28,10 @@ jobs: | |||||||
|         uses: actions/checkout@v2 |         uses: actions/checkout@v2 | ||||||
|         with: |         with: | ||||||
|           fetch-depth: 0 |           fetch-depth: 0 | ||||||
|           submodules: true |  | ||||||
| 
 |  | ||||||
|       - name: 'Docker cache' |  | ||||||
|         uses: satackey/action-docker-layer-caching@v0.0.11 |  | ||||||
|         continue-on-error: true |  | ||||||
|         with: |  | ||||||
|           key: docker-cache-${{ hashFiles('docker/**') }}-{hash} |  | ||||||
|           restore-keys: docker-cache-${{ hashFiles('docker/**') }}- |  | ||||||
| 
 |  | ||||||
|       - name: 'Build docker image' |  | ||||||
|         uses: ./.github/actions/docker |  | ||||||
| 
 | 
 | ||||||
|       - name: 'Check code formatting' |       - name: 'Check code formatting' | ||||||
|         id: syntax_check |         id: syntax_check | ||||||
|         uses: ./.github/actions/docker |         run: SET_GH_OUTPUT=1 FBT_TOOLCHAIN_PATH=/opt ./fbt lint | ||||||
|         with: |  | ||||||
|           run: SET_GH_OUTPUT=1 ./fbt lint |  | ||||||
| 
 | 
 | ||||||
|       - name: Report code formatting errors |       - name: Report code formatting errors | ||||||
|         if: failure() && steps.syntax_check.outputs.errors && github.event.pull_request |         if: failure() && steps.syntax_check.outputs.errors && github.event.pull_request | ||||||
| @ -59,4 +43,4 @@ jobs: | |||||||
|             ``` |             ``` | ||||||
|             ${{ steps.syntax_check.outputs.errors }} |             ${{ steps.syntax_check.outputs.errors }} | ||||||
|             ``` |             ``` | ||||||
|             You might want to run `docker compose exec dev make format` for an auto-fix. |             You might want to run `./fbt format` for an auto-fix. | ||||||
|  | |||||||
							
								
								
									
										12
									
								
								.github/workflows/lint_python.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.github/workflows/lint_python.yml
									
									
									
									
										vendored
									
									
								
							| @ -11,11 +11,8 @@ on: | |||||||
| 
 | 
 | ||||||
| jobs: | jobs: | ||||||
|   lint_python: |   lint_python: | ||||||
|     runs-on: ubuntu-latest |     runs-on: [self-hosted,FlipperZeroShell] | ||||||
|     steps: |     steps: | ||||||
|       - name: 'Cleanup workspace' |  | ||||||
|         uses: AutoModality/action-clean@v1 |  | ||||||
| 
 |  | ||||||
|       - name: 'Decontaminate previous build leftovers' |       - name: 'Decontaminate previous build leftovers' | ||||||
|         run: | |         run: | | ||||||
|           if [ -d .git ] |           if [ -d .git ] | ||||||
| @ -29,8 +26,5 @@ jobs: | |||||||
|         with: |         with: | ||||||
|           fetch-depth: 0 |           fetch-depth: 0 | ||||||
| 
 | 
 | ||||||
|       - name: 'Setup python' |       - name: 'Check code formatting' | ||||||
|         uses: actions/setup-python@v2 |         run: SET_GH_OUTPUT=1 FBT_TOOLCHAIN_PATH=/opt ./fbt lint_py | ||||||
| 
 |  | ||||||
|       - name: 'Check python code with black' |  | ||||||
|         uses: psf/black@20.8b1 |  | ||||||
|  | |||||||
							
								
								
									
										7
									
								
								.github/workflows/reindex.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								.github/workflows/reindex.yml
									
									
									
									
										vendored
									
									
								
							| @ -7,9 +7,8 @@ on: | |||||||
| jobs: | jobs: | ||||||
|   reindex: |   reindex: | ||||||
|     name: 'Reindex updates' |     name: 'Reindex updates' | ||||||
|     runs-on: [self-hosted,FlipperZero] |     runs-on: [self-hosted,FlipperZeroShell] | ||||||
|     steps: |     steps: | ||||||
|       - name: Trigger reindex |       - name: Trigger reindex | ||||||
|         uses: wei/curl@master |         run: | | ||||||
|         with: |           curl -X POST -F 'key=${{ secrets.REINDEX_KEY }}' ${{ secrets.REINDEX_URL }} | ||||||
|           args: -X POST -F 'key=${{ secrets.REINDEX_KEY }}' ${{ secrets.REINDEX_URL }} |  | ||||||
|  | |||||||
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -46,4 +46,7 @@ dist | |||||||
| build/ | build/ | ||||||
| 
 | 
 | ||||||
| # Toolchain | # Toolchain | ||||||
| toolchain*/ | /toolchain | ||||||
|  | 
 | ||||||
|  | # openocd output file | ||||||
|  | openocd.log | ||||||
|  | |||||||
| @ -23,17 +23,17 @@ Flipper Zero's firmware consists of two components: | |||||||
| - Core2 firmware set - proprietary components by ST: FUS + radio stack. FUS is flashed at factory and you should never update it. | - Core2 firmware set - proprietary components by ST: FUS + radio stack. FUS is flashed at factory and you should never update it. | ||||||
| - Core1 Firmware - HAL + OS + Drivers + Applications. | - Core1 Firmware - HAL + OS + Drivers + Applications. | ||||||
| 
 | 
 | ||||||
| They both must be flashed in order described. | They both must be flashed in the order described. | ||||||
| 
 | 
 | ||||||
| ## With offline update package | ## With offline update package | ||||||
| 
 | 
 | ||||||
| With Flipper attached over USB: | With Flipper attached over USB: | ||||||
| 
 | 
 | ||||||
| `./fbt --with-updater flash_usb` | `./fbt flash_usb` | ||||||
| 
 | 
 | ||||||
| Just building the package: | Just building the package: | ||||||
| 
 | 
 | ||||||
| `./fbt --with-updater updater_package` | `./fbt updater_package` | ||||||
| 
 | 
 | ||||||
| To update, copy the resulting directory to Flipper's SD card and navigate to `update.fuf` file in Archive app.  | To update, copy the resulting directory to Flipper's SD card and navigate to `update.fuf` file in Archive app.  | ||||||
| 
 | 
 | ||||||
| @ -155,7 +155,7 @@ Connect your device via ST-Link and run: | |||||||
| 
 | 
 | ||||||
| - `applications`    - Applications and services used in firmware | - `applications`    - Applications and services used in firmware | ||||||
| - `assets`          - Assets used by applications and services | - `assets`          - Assets used by applications and services | ||||||
| - `core`            - Furi Core: os level primitives and helpers | - `furi`            - Furi Core: os level primitives and helpers | ||||||
| - `debug`           - Debug tool: GDB-plugins, SVD-file and etc | - `debug`           - Debug tool: GDB-plugins, SVD-file and etc | ||||||
| - `docker`          - Docker image sources (used for firmware build automation) | - `docker`          - Docker image sources (used for firmware build automation) | ||||||
| - `documentation`   - Documentation generation system configs and input files | - `documentation`   - Documentation generation system configs and input files | ||||||
|  | |||||||
							
								
								
									
										107
									
								
								SConstruct
									
									
									
									
									
								
							
							
						
						
									
										107
									
								
								SConstruct
									
									
									
									
									
								
							| @ -7,6 +7,9 @@ | |||||||
| # construction of certain targets behind command-line options. | # construction of certain targets behind command-line options. | ||||||
| 
 | 
 | ||||||
| import os | import os | ||||||
|  | import subprocess | ||||||
|  | 
 | ||||||
|  | EnsurePythonVersion(3, 8) | ||||||
| 
 | 
 | ||||||
| DefaultEnvironment(tools=[]) | DefaultEnvironment(tools=[]) | ||||||
| # Progress(["OwO\r", "owo\r", "uwu\r", "owo\r"], interval=15) | # Progress(["OwO\r", "owo\r", "uwu\r", "owo\r"], interval=15) | ||||||
| @ -31,8 +34,10 @@ coreenv["ROOT_DIR"] = Dir(".") | |||||||
| 
 | 
 | ||||||
| # Create a separate "dist" environment and add construction envs to it | # Create a separate "dist" environment and add construction envs to it | ||||||
| distenv = coreenv.Clone( | distenv = coreenv.Clone( | ||||||
|     tools=["fbt_dist", "openocd", "blackmagic"], |     tools=["fbt_dist", "openocd", "blackmagic", "jflash"], | ||||||
|     OPENOCD_GDB_PIPE=["|openocd -c 'gdb_port pipe' ${[SINGLEQUOTEFUNC(OPENOCD_OPTS)]}"], |     OPENOCD_GDB_PIPE=[ | ||||||
|  |         "|openocd -c 'gdb_port pipe; log_output debug/openocd.log' ${[SINGLEQUOTEFUNC(OPENOCD_OPTS)]}" | ||||||
|  |     ], | ||||||
|     GDBOPTS_BASE=[ |     GDBOPTS_BASE=[ | ||||||
|         "-ex", |         "-ex", | ||||||
|         "target extended-remote ${GDBREMOTE}", |         "target extended-remote ${GDBREMOTE}", | ||||||
| @ -59,6 +64,7 @@ distenv = coreenv.Clone( | |||||||
|         "-ex", |         "-ex", | ||||||
|         "compare-sections", |         "compare-sections", | ||||||
|     ], |     ], | ||||||
|  |     JFLASHPROJECT="${ROOT_DIR.abspath}/debug/fw.jflash", | ||||||
|     ENV=os.environ, |     ENV=os.environ, | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @ -69,7 +75,9 @@ firmware_env = distenv.AddFwProject( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| # If enabled, initialize updater-related targets | # If enabled, initialize updater-related targets | ||||||
| if GetOption("fullenv"): | if GetOption("fullenv") or any( | ||||||
|  |     filter(lambda target: "updater" in target or "flash_usb" in target, BUILD_TARGETS) | ||||||
|  | ): | ||||||
|     updater_env = distenv.AddFwProject( |     updater_env = distenv.AddFwProject( | ||||||
|         base_env=coreenv, |         base_env=coreenv, | ||||||
|         fw_type="updater", |         fw_type="updater", | ||||||
| @ -77,11 +85,11 @@ if GetOption("fullenv"): | |||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     # Target for self-update package |     # Target for self-update package | ||||||
|     dist_arguments = [ |     dist_basic_arguments = [ | ||||||
|         "-r", |  | ||||||
|         '"${ROOT_DIR.abspath}/assets/resources"', |  | ||||||
|         "--bundlever", |         "--bundlever", | ||||||
|         '"${UPDATE_VERSION_STRING}"', |         '"${UPDATE_VERSION_STRING}"', | ||||||
|  |     ] | ||||||
|  |     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", | ||||||
| @ -90,16 +98,34 @@ if GetOption("fullenv"): | |||||||
|         "--obdata", |         "--obdata", | ||||||
|         '"${ROOT_DIR.abspath}/${COPRO_OB_DATA}"', |         '"${ROOT_DIR.abspath}/${COPRO_OB_DATA}"', | ||||||
|     ] |     ] | ||||||
|     if distenv["UPDATE_SPLASH"]: |     dist_resource_arguments = [ | ||||||
|         dist_arguments += [ |         "-r", | ||||||
|  |         '"${ROOT_DIR.abspath}/assets/resources"', | ||||||
|  |     ] | ||||||
|  |     dist_splash_arguments = ( | ||||||
|  |         [ | ||||||
|             "--splash", |             "--splash", | ||||||
|             distenv.subst("assets/slideshow/$UPDATE_SPLASH"), |             distenv.subst("assets/slideshow/$UPDATE_SPLASH"), | ||||||
|         ] |         ] | ||||||
|  |         if distenv["UPDATE_SPLASH"] | ||||||
|  |         else [] | ||||||
|  |     ) | ||||||
| 
 | 
 | ||||||
|     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"]), | ||||||
|         DIST_EXTRA=dist_arguments, |         DIST_EXTRA=[ | ||||||
|  |             *dist_basic_arguments, | ||||||
|  |             *dist_radio_arguments, | ||||||
|  |             *dist_resource_arguments, | ||||||
|  |             *dist_splash_arguments, | ||||||
|  |         ], | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     selfupdate_min_dist = distenv.DistCommand( | ||||||
|  |         "updater_minpackage", | ||||||
|  |         distenv["DIST_DEPENDS"], | ||||||
|  |         DIST_EXTRA=dist_basic_arguments, | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     # Updater debug |     # Updater debug | ||||||
| @ -119,18 +145,16 @@ if GetOption("fullenv"): | |||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     # Installation over USB & CLI |     # Installation over USB & CLI | ||||||
|     usb_update_package = distenv.UsbInstall( |     usb_update_package = distenv.AddUsbFlashTarget( | ||||||
|         "#build/usbinstall.flag", |         "#build/usbinstall.flag", (firmware_env["FW_RESOURCES"], selfupdate_dist) | ||||||
|         ( |  | ||||||
|             distenv["DIST_DEPENDS"], |  | ||||||
|             firmware_env["FW_RESOURCES"], |  | ||||||
|             selfupdate_dist, |  | ||||||
|         ), |  | ||||||
|     ) |     ) | ||||||
|     if distenv["FORCE"]: |     distenv.Alias("flash_usb_full", usb_update_package) | ||||||
|         distenv.AlwaysBuild(usb_update_package) | 
 | ||||||
|     distenv.Depends(usb_update_package, selfupdate_dist) |     usb_minupdate_package = distenv.AddUsbFlashTarget( | ||||||
|     distenv.Alias("flash_usb", usb_update_package) |         "#build/minusbinstall.flag", (selfupdate_min_dist,) | ||||||
|  |     ) | ||||||
|  |     distenv.Alias("flash_usb", usb_minupdate_package) | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| # Target for copying & renaming binaries to dist folder | # Target for copying & renaming binaries to dist folder | ||||||
| basic_dist = distenv.DistCommand("fw_dist", distenv["DIST_DEPENDS"]) | basic_dist = distenv.DistCommand("fw_dist", distenv["DIST_DEPENDS"]) | ||||||
| @ -146,6 +170,9 @@ distenv.Alias("copro_dist", copro_dist) | |||||||
| firmware_flash = distenv.AddOpenOCDFlashTarget(firmware_env) | firmware_flash = distenv.AddOpenOCDFlashTarget(firmware_env) | ||||||
| distenv.Alias("flash", firmware_flash) | distenv.Alias("flash", firmware_flash) | ||||||
| 
 | 
 | ||||||
|  | firmware_jflash = distenv.AddJFlashTarget(firmware_env) | ||||||
|  | distenv.Alias("jflash", firmware_jflash) | ||||||
|  | 
 | ||||||
| firmware_bm_flash = distenv.PhonyTarget( | firmware_bm_flash = distenv.PhonyTarget( | ||||||
|     "flash_blackmagic", |     "flash_blackmagic", | ||||||
|     "$GDB $GDBOPTS $SOURCES $GDBFLASH", |     "$GDB $GDBOPTS $SOURCES $GDBFLASH", | ||||||
| @ -205,6 +232,46 @@ distenv.PhonyTarget( | |||||||
|     LINT_SOURCES=firmware_env["LINT_SOURCES"], |     LINT_SOURCES=firmware_env["LINT_SOURCES"], | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | # PY_LINT_SOURCES contains recursively-built modules' SConscript files + application manifests | ||||||
|  | # Here we add additional Python files residing in repo root | ||||||
|  | firmware_env.Append( | ||||||
|  |     PY_LINT_SOURCES=[ | ||||||
|  |         # Py code folders | ||||||
|  |         "site_scons", | ||||||
|  |         "scripts", | ||||||
|  |         # Extra files | ||||||
|  |         "applications/extapps.scons", | ||||||
|  |         "SConstruct", | ||||||
|  |         "firmware.scons", | ||||||
|  |         "fbt_options.py", | ||||||
|  |     ] | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | black_commandline = "@${PYTHON3} -m black ${PY_BLACK_ARGS} ${PY_LINT_SOURCES}" | ||||||
|  | black_base_args = ["--include", '"\\.scons|\\.py|SConscript|SConstruct"'] | ||||||
|  | 
 | ||||||
|  | distenv.PhonyTarget( | ||||||
|  |     "lint_py", | ||||||
|  |     black_commandline, | ||||||
|  |     PY_BLACK_ARGS=[ | ||||||
|  |         "--check", | ||||||
|  |         "--diff", | ||||||
|  |         *black_base_args, | ||||||
|  |     ], | ||||||
|  |     PY_LINT_SOURCES=firmware_env["PY_LINT_SOURCES"], | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | distenv.PhonyTarget( | ||||||
|  |     "format_py", | ||||||
|  |     black_commandline, | ||||||
|  |     PY_BLACK_ARGS=black_base_args, | ||||||
|  |     PY_LINT_SOURCES=firmware_env["PY_LINT_SOURCES"], | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | # Start Flipper CLI via PySerial's miniterm | ||||||
|  | distenv.PhonyTarget("cli", "${PYTHON3} scripts/serial_cli.py") | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| # Find blackmagic probe | # Find blackmagic probe | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -156,10 +156,10 @@ const size_t about_screens_count = sizeof(about_screens) / sizeof(AboutDialogScr | |||||||
| 
 | 
 | ||||||
| int32_t about_settings_app(void* p) { | int32_t about_settings_app(void* p) { | ||||||
|     UNUSED(p); |     UNUSED(p); | ||||||
|     DialogsApp* dialogs = furi_record_open("dialogs"); |     DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); | ||||||
|     DialogMessage* message = dialog_message_alloc(); |     DialogMessage* message = dialog_message_alloc(); | ||||||
| 
 | 
 | ||||||
|     Gui* gui = furi_record_open("gui"); |     Gui* gui = furi_record_open(RECORD_GUI); | ||||||
|     ViewDispatcher* view_dispatcher = view_dispatcher_alloc(); |     ViewDispatcher* view_dispatcher = view_dispatcher_alloc(); | ||||||
|     EmptyScreen* empty_screen = empty_screen_alloc(); |     EmptyScreen* empty_screen = empty_screen_alloc(); | ||||||
|     const uint32_t empty_screen_index = 0; |     const uint32_t empty_screen_index = 0; | ||||||
| @ -198,12 +198,12 @@ int32_t about_settings_app(void* p) { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     dialog_message_free(message); |     dialog_message_free(message); | ||||||
|     furi_record_close("dialogs"); |     furi_record_close(RECORD_DIALOGS); | ||||||
| 
 | 
 | ||||||
|     view_dispatcher_remove_view(view_dispatcher, empty_screen_index); |     view_dispatcher_remove_view(view_dispatcher, empty_screen_index); | ||||||
|     view_dispatcher_free(view_dispatcher); |     view_dispatcher_free(view_dispatcher); | ||||||
|     empty_screen_free(empty_screen); |     empty_screen_free(empty_screen); | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
| 
 | 
 | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| @ -3,7 +3,7 @@ | |||||||
| #include <callback-connector.h> | #include <callback-connector.h> | ||||||
| 
 | 
 | ||||||
| AccessorAppViewManager::AccessorAppViewManager() { | AccessorAppViewManager::AccessorAppViewManager() { | ||||||
|     event_queue = osMessageQueueNew(10, sizeof(AccessorEvent), NULL); |     event_queue = furi_message_queue_alloc(10, sizeof(AccessorEvent)); | ||||||
| 
 | 
 | ||||||
|     view_dispatcher = view_dispatcher_alloc(); |     view_dispatcher = view_dispatcher_alloc(); | ||||||
|     auto callback = cbc::obtain_connector(this, &AccessorAppViewManager::previous_view_callback); |     auto callback = cbc::obtain_connector(this, &AccessorAppViewManager::previous_view_callback); | ||||||
| @ -38,7 +38,7 @@ AccessorAppViewManager::~AccessorAppViewManager() { | |||||||
|     view_dispatcher_free(view_dispatcher); |     view_dispatcher_free(view_dispatcher); | ||||||
| 
 | 
 | ||||||
|     // free event queue
 |     // free event queue
 | ||||||
|     osMessageQueueDelete(event_queue); |     furi_message_queue_free(event_queue); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AccessorAppViewManager::switch_to(ViewType type) { | void AccessorAppViewManager::switch_to(ViewType type) { | ||||||
| @ -54,14 +54,14 @@ Popup* AccessorAppViewManager::get_popup() { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AccessorAppViewManager::receive_event(AccessorEvent* event) { | void AccessorAppViewManager::receive_event(AccessorEvent* event) { | ||||||
|     if(osMessageQueueGet(event_queue, event, NULL, 100) != osOK) { |     if(furi_message_queue_get(event_queue, event, 100) != FuriStatusOk) { | ||||||
|         event->type = AccessorEvent::Type::Tick; |         event->type = AccessorEvent::Type::Tick; | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void AccessorAppViewManager::send_event(AccessorEvent* event) { | void AccessorAppViewManager::send_event(AccessorEvent* event) { | ||||||
|     osStatus_t result = osMessageQueuePut(event_queue, event, 0, 0); |     FuriStatus result = furi_message_queue_put(event_queue, event, 0); | ||||||
|     furi_check(result == osOK); |     furi_check(result == FuriStatusOk); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t AccessorAppViewManager::previous_view_callback(void*) { | uint32_t AccessorAppViewManager::previous_view_callback(void*) { | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ public: | |||||||
|         Tune, |         Tune, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     osMessageQueueId_t event_queue; |     FuriMessageQueue* event_queue; | ||||||
| 
 | 
 | ||||||
|     AccessorAppViewManager(); |     AccessorAppViewManager(); | ||||||
|     ~AccessorAppViewManager(); |     ~AccessorAppViewManager(); | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ bool archive_back_event_callback(void* context) { | |||||||
| ArchiveApp* archive_alloc() { | ArchiveApp* archive_alloc() { | ||||||
|     ArchiveApp* archive = malloc(sizeof(ArchiveApp)); |     ArchiveApp* archive = malloc(sizeof(ArchiveApp)); | ||||||
| 
 | 
 | ||||||
|     archive->gui = furi_record_open("gui"); |     archive->gui = furi_record_open(RECORD_GUI); | ||||||
|     archive->text_input = text_input_alloc(); |     archive->text_input = text_input_alloc(); | ||||||
|     string_init(archive->fav_move_str); |     string_init(archive->fav_move_str); | ||||||
| 
 | 
 | ||||||
| @ -62,7 +62,7 @@ void archive_free(ArchiveApp* archive) { | |||||||
| 
 | 
 | ||||||
|     text_input_free(archive->text_input); |     text_input_free(archive->text_input); | ||||||
| 
 | 
 | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
|     archive->gui = NULL; |     archive->gui = NULL; | ||||||
| 
 | 
 | ||||||
|     free(archive); |     free(archive); | ||||||
|  | |||||||
| @ -29,21 +29,22 @@ bool archive_app_is_available(void* context, const char* path) { | |||||||
| 
 | 
 | ||||||
|     if(app == ArchiveAppTypeU2f) { |     if(app == ArchiveAppTypeU2f) { | ||||||
|         bool file_exists = false; |         bool file_exists = false; | ||||||
|         Storage* fs_api = furi_record_open("storage"); |         Storage* fs_api = furi_record_open(RECORD_STORAGE); | ||||||
|         File* file = storage_file_alloc(fs_api); |         File* file = storage_file_alloc(fs_api); | ||||||
| 
 | 
 | ||||||
|         file_exists = storage_file_open(file, "/any/u2f/key.u2f", FSAM_READ, FSOM_OPEN_EXISTING); |         file_exists = | ||||||
|  |             storage_file_open(file, ANY_PATH("u2f/key.u2f"), FSAM_READ, FSOM_OPEN_EXISTING); | ||||||
|         if(file_exists) { |         if(file_exists) { | ||||||
|             storage_file_close(file); |             storage_file_close(file); | ||||||
|             file_exists = |             file_exists = | ||||||
|                 storage_file_open(file, "/any/u2f/cnt.u2f", FSAM_READ, FSOM_OPEN_EXISTING); |                 storage_file_open(file, ANY_PATH("u2f/cnt.u2f"), FSAM_READ, FSOM_OPEN_EXISTING); | ||||||
|             if(file_exists) { |             if(file_exists) { | ||||||
|                 storage_file_close(file); |                 storage_file_close(file); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         storage_file_free(file); |         storage_file_free(file); | ||||||
|         furi_record_close("storage"); |         furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|         return file_exists; |         return file_exists; | ||||||
|     } else { |     } else { | ||||||
| @ -77,10 +78,10 @@ void archive_app_delete_file(void* context, const char* path) { | |||||||
|     bool res = false; |     bool res = false; | ||||||
| 
 | 
 | ||||||
|     if(app == ArchiveAppTypeU2f) { |     if(app == ArchiveAppTypeU2f) { | ||||||
|         Storage* fs_api = furi_record_open("storage"); |         Storage* fs_api = furi_record_open(RECORD_STORAGE); | ||||||
|         res = (storage_common_remove(fs_api, "/any/u2f/key.u2f") == FSE_OK); |         res = (storage_common_remove(fs_api, ANY_PATH("u2f/key.u2f")) == FSE_OK); | ||||||
|         res |= (storage_common_remove(fs_api, "/any/u2f/cnt.u2f") == FSE_OK); |         res |= (storage_common_remove(fs_api, ANY_PATH("u2f/cnt.u2f")) == FSE_OK); | ||||||
|         furi_record_close("storage"); |         furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|         if(archive_is_favorite("/app:u2f/U2F Token")) { |         if(archive_is_favorite("/app:u2f/U2F Token")) { | ||||||
|             archive_favorites_delete("/app:u2f/U2F Token"); |             archive_favorites_delete("/app:u2f/U2F Token"); | ||||||
|  | |||||||
| @ -2,8 +2,8 @@ | |||||||
| #include "archive_files.h" | #include "archive_files.h" | ||||||
| #include "archive_apps.h" | #include "archive_apps.h" | ||||||
| #include "archive_browser.h" | #include "archive_browser.h" | ||||||
| #include "furi/common_defines.h" | #include <core/common_defines.h> | ||||||
| #include "furi/log.h" | #include <core/log.h> | ||||||
| #include "gui/modules/file_browser_worker.h" | #include "gui/modules/file_browser_worker.h" | ||||||
| #include "m-string.h" | #include "m-string.h" | ||||||
| #include <math.h> | #include <math.h> | ||||||
| @ -391,18 +391,18 @@ void archive_favorites_move_mode(ArchiveBrowserView* browser, bool active) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool archive_is_dir_exists(string_t path) { | static bool archive_is_dir_exists(string_t path) { | ||||||
|     if(string_equal_str_p(path, "/any")) { |     if(string_equal_str_p(path, STORAGE_ANY_PATH_PREFIX)) { | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|     bool state = false; |     bool state = false; | ||||||
|     FileInfo file_info; |     FileInfo file_info; | ||||||
|     Storage* storage = furi_record_open("storage"); |     Storage* storage = furi_record_open(RECORD_STORAGE); | ||||||
|     if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) { |     if(storage_common_stat(storage, string_get_cstr(path), &file_info) == FSE_OK) { | ||||||
|         if(file_info.flags & FSF_DIRECTORY) { |         if(file_info.flags & FSF_DIRECTORY) { | ||||||
|             state = true; |             state = true; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
|     return state; |     return state; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include "../archive_i.h" | #include "../archive_i.h" | ||||||
|  | #include <storage/storage.h> | ||||||
| 
 | 
 | ||||||
| #define TAB_RIGHT InputKeyRight // Default tab swith direction
 | #define TAB_RIGHT InputKeyRight // Default tab swith direction
 | ||||||
| #define TAB_DEFAULT ArchiveTabFavorites // Start tab
 | #define TAB_DEFAULT ArchiveTabFavorites // Start tab
 | ||||||
| @ -8,14 +9,14 @@ | |||||||
| 
 | 
 | ||||||
| static const char* tab_default_paths[] = { | static const char* tab_default_paths[] = { | ||||||
|     [ArchiveTabFavorites] = "/app:favorites", |     [ArchiveTabFavorites] = "/app:favorites", | ||||||
|     [ArchiveTabIButton] = "/any/ibutton", |     [ArchiveTabIButton] = ANY_PATH("ibutton"), | ||||||
|     [ArchiveTabNFC] = "/any/nfc", |     [ArchiveTabNFC] = ANY_PATH("nfc"), | ||||||
|     [ArchiveTabSubGhz] = "/any/subghz", |     [ArchiveTabSubGhz] = ANY_PATH("subghz"), | ||||||
|     [ArchiveTabLFRFID] = "/any/lfrfid", |     [ArchiveTabLFRFID] = ANY_PATH("lfrfid"), | ||||||
|     [ArchiveTabInfrared] = "/any/infrared", |     [ArchiveTabInfrared] = ANY_PATH("infrared"), | ||||||
|     [ArchiveTabBadUsb] = "/any/badusb", |     [ArchiveTabBadUsb] = ANY_PATH("badusb"), | ||||||
|     [ArchiveTabU2f] = "/app:u2f", |     [ArchiveTabU2f] = "/app:u2f", | ||||||
|     [ArchiveTabBrowser] = "/any", |     [ArchiveTabBrowser] = STORAGE_ANY_PATH_PREFIX, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static const char* known_ext[] = { | static const char* known_ext[] = { | ||||||
|  | |||||||
| @ -49,7 +49,7 @@ static bool archive_favorites_read_line(File* file, string_t str_result) { | |||||||
| uint16_t archive_favorites_count(void* context) { | uint16_t archive_favorites_count(void* context) { | ||||||
|     furi_assert(context); |     furi_assert(context); | ||||||
| 
 | 
 | ||||||
|     Storage* fs_api = furi_record_open("storage"); |     Storage* fs_api = furi_record_open(RECORD_STORAGE); | ||||||
|     File* file = storage_file_alloc(fs_api); |     File* file = storage_file_alloc(fs_api); | ||||||
| 
 | 
 | ||||||
|     string_t buffer; |     string_t buffer; | ||||||
| @ -74,7 +74,7 @@ uint16_t archive_favorites_count(void* context) { | |||||||
| 
 | 
 | ||||||
|     string_clear(buffer); |     string_clear(buffer); | ||||||
|     storage_file_free(file); |     storage_file_free(file); | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|     return lines; |     return lines; | ||||||
| } | } | ||||||
| @ -82,7 +82,7 @@ uint16_t archive_favorites_count(void* context) { | |||||||
| static bool archive_favourites_rescan() { | static bool archive_favourites_rescan() { | ||||||
|     string_t buffer; |     string_t buffer; | ||||||
|     string_init(buffer); |     string_init(buffer); | ||||||
|     Storage* fs_api = furi_record_open("storage"); |     Storage* fs_api = furi_record_open(RECORD_STORAGE); | ||||||
|     File* file = storage_file_alloc(fs_api); |     File* file = storage_file_alloc(fs_api); | ||||||
|     File* fav_item_file = storage_file_alloc(fs_api); |     File* fav_item_file = storage_file_alloc(fs_api); | ||||||
| 
 | 
 | ||||||
| @ -122,7 +122,7 @@ static bool archive_favourites_rescan() { | |||||||
| 
 | 
 | ||||||
|     storage_file_free(file); |     storage_file_free(file); | ||||||
|     storage_file_free(fav_item_file); |     storage_file_free(fav_item_file); | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| @ -131,7 +131,7 @@ bool archive_favorites_read(void* context) { | |||||||
|     furi_assert(context); |     furi_assert(context); | ||||||
| 
 | 
 | ||||||
|     ArchiveBrowserView* browser = context; |     ArchiveBrowserView* browser = context; | ||||||
|     Storage* fs_api = furi_record_open("storage"); |     Storage* fs_api = furi_record_open(RECORD_STORAGE); | ||||||
|     File* file = storage_file_alloc(fs_api); |     File* file = storage_file_alloc(fs_api); | ||||||
|     File* fav_item_file = storage_file_alloc(fs_api); |     File* fav_item_file = storage_file_alloc(fs_api); | ||||||
| 
 | 
 | ||||||
| @ -184,7 +184,7 @@ bool archive_favorites_read(void* context) { | |||||||
|     string_clear(buffer); |     string_clear(buffer); | ||||||
|     storage_file_free(file); |     storage_file_free(file); | ||||||
|     storage_file_free(fav_item_file); |     storage_file_free(fav_item_file); | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|     archive_set_item_count(browser, file_count); |     archive_set_item_count(browser, file_count); | ||||||
| 
 | 
 | ||||||
| @ -204,7 +204,7 @@ bool archive_favorites_delete(const char* format, ...) { | |||||||
|     va_end(args); |     va_end(args); | ||||||
| 
 | 
 | ||||||
|     string_init(buffer); |     string_init(buffer); | ||||||
|     Storage* fs_api = furi_record_open("storage"); |     Storage* fs_api = furi_record_open(RECORD_STORAGE); | ||||||
|     File* file = storage_file_alloc(fs_api); |     File* file = storage_file_alloc(fs_api); | ||||||
| 
 | 
 | ||||||
|     bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); |     bool result = storage_file_open(file, ARCHIVE_FAV_PATH, FSAM_READ, FSOM_OPEN_EXISTING); | ||||||
| @ -233,7 +233,7 @@ bool archive_favorites_delete(const char* format, ...) { | |||||||
|     storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH); |     storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH); | ||||||
| 
 | 
 | ||||||
|     storage_file_free(file); |     storage_file_free(file); | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| @ -247,7 +247,7 @@ bool archive_is_favorite(const char* format, ...) { | |||||||
|     va_end(args); |     va_end(args); | ||||||
| 
 | 
 | ||||||
|     string_init(buffer); |     string_init(buffer); | ||||||
|     Storage* fs_api = furi_record_open("storage"); |     Storage* fs_api = furi_record_open(RECORD_STORAGE); | ||||||
|     File* file = storage_file_alloc(fs_api); |     File* file = storage_file_alloc(fs_api); | ||||||
| 
 | 
 | ||||||
|     bool found = false; |     bool found = false; | ||||||
| @ -272,7 +272,7 @@ bool archive_is_favorite(const char* format, ...) { | |||||||
|     string_clear(buffer); |     string_clear(buffer); | ||||||
|     string_clear(filename); |     string_clear(filename); | ||||||
|     storage_file_free(file); |     storage_file_free(file); | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|     return found; |     return found; | ||||||
| } | } | ||||||
| @ -281,7 +281,7 @@ bool archive_favorites_rename(const char* src, const char* dst) { | |||||||
|     furi_assert(src); |     furi_assert(src); | ||||||
|     furi_assert(dst); |     furi_assert(dst); | ||||||
| 
 | 
 | ||||||
|     Storage* fs_api = furi_record_open("storage"); |     Storage* fs_api = furi_record_open(RECORD_STORAGE); | ||||||
|     File* file = storage_file_alloc(fs_api); |     File* file = storage_file_alloc(fs_api); | ||||||
| 
 | 
 | ||||||
|     string_t path; |     string_t path; | ||||||
| @ -318,7 +318,7 @@ bool archive_favorites_rename(const char* src, const char* dst) { | |||||||
|     storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH); |     storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH); | ||||||
| 
 | 
 | ||||||
|     storage_file_free(file); |     storage_file_free(file); | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| @ -333,7 +333,7 @@ void archive_favorites_save(void* context) { | |||||||
|     furi_assert(context); |     furi_assert(context); | ||||||
| 
 | 
 | ||||||
|     ArchiveBrowserView* browser = context; |     ArchiveBrowserView* browser = context; | ||||||
|     Storage* fs_api = furi_record_open("storage"); |     Storage* fs_api = furi_record_open(RECORD_STORAGE); | ||||||
|     File* file = storage_file_alloc(fs_api); |     File* file = storage_file_alloc(fs_api); | ||||||
| 
 | 
 | ||||||
|     for(size_t i = 0; i < archive_file_get_array_size(browser); i++) { |     for(size_t i = 0; i < archive_file_get_array_size(browser); i++) { | ||||||
| @ -346,5 +346,5 @@ void archive_favorites_save(void* context) { | |||||||
|     storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH); |     storage_common_remove(fs_api, ARCHIVE_FAV_TEMP_PATH); | ||||||
| 
 | 
 | ||||||
|     storage_file_free(file); |     storage_file_free(file); | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
| } | } | ||||||
|  | |||||||
| @ -2,8 +2,8 @@ | |||||||
| 
 | 
 | ||||||
| #include <storage/storage.h> | #include <storage/storage.h> | ||||||
| 
 | 
 | ||||||
| #define ARCHIVE_FAV_PATH "/any/favorites.txt" | #define ARCHIVE_FAV_PATH ANY_PATH("favorites.txt") | ||||||
| #define ARCHIVE_FAV_TEMP_PATH "/any/favorites.tmp" | #define ARCHIVE_FAV_TEMP_PATH ANY_PATH("favorites.tmp") | ||||||
| 
 | 
 | ||||||
| uint16_t archive_favorites_count(void* context); | uint16_t archive_favorites_count(void* context); | ||||||
| bool archive_favorites_read(void* context); | bool archive_favorites_read(void* context); | ||||||
|  | |||||||
| @ -60,7 +60,7 @@ void archive_file_append(const char* path, const char* format, ...) { | |||||||
|     string_init_vprintf(string, format, args); |     string_init_vprintf(string, format, args); | ||||||
|     va_end(args); |     va_end(args); | ||||||
| 
 | 
 | ||||||
|     Storage* fs_api = furi_record_open("storage"); |     Storage* fs_api = furi_record_open(RECORD_STORAGE); | ||||||
|     File* file = storage_file_alloc(fs_api); |     File* file = storage_file_alloc(fs_api); | ||||||
| 
 | 
 | ||||||
|     bool res = storage_file_open(file, path, FSAM_WRITE, FSOM_OPEN_APPEND); |     bool res = storage_file_open(file, path, FSAM_WRITE, FSOM_OPEN_APPEND); | ||||||
| @ -71,7 +71,7 @@ void archive_file_append(const char* path, const char* format, ...) { | |||||||
| 
 | 
 | ||||||
|     storage_file_close(file); |     storage_file_close(file); | ||||||
|     storage_file_free(file); |     storage_file_free(file); | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void archive_delete_file(void* context, const char* format, ...) { | void archive_delete_file(void* context, const char* format, ...) { | ||||||
| @ -84,7 +84,7 @@ void archive_delete_file(void* context, const char* format, ...) { | |||||||
|     va_end(args); |     va_end(args); | ||||||
| 
 | 
 | ||||||
|     ArchiveBrowserView* browser = context; |     ArchiveBrowserView* browser = context; | ||||||
|     Storage* fs_api = furi_record_open("storage"); |     Storage* fs_api = furi_record_open(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|     FileInfo fileinfo; |     FileInfo fileinfo; | ||||||
|     storage_common_stat(fs_api, string_get_cstr(filename), &fileinfo); |     storage_common_stat(fs_api, string_get_cstr(filename), &fileinfo); | ||||||
| @ -97,7 +97,7 @@ void archive_delete_file(void* context, const char* format, ...) { | |||||||
|         res = (storage_common_remove(fs_api, string_get_cstr(filename)) == FSE_OK); |         res = (storage_common_remove(fs_api, string_get_cstr(filename)) == FSE_OK); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|     if(archive_is_favorite("%s", string_get_cstr(filename))) { |     if(archive_is_favorite("%s", string_get_cstr(filename))) { | ||||||
|         archive_favorites_delete("%s", string_get_cstr(filename)); |         archive_favorites_delete("%s", string_get_cstr(filename)); | ||||||
|  | |||||||
| @ -36,7 +36,7 @@ static void archive_loader_callback(const void* message, void* context) { | |||||||
| 
 | 
 | ||||||
| static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selected) { | static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selected) { | ||||||
|     UNUSED(browser); |     UNUSED(browser); | ||||||
|     Loader* loader = furi_record_open("loader"); |     Loader* loader = furi_record_open(RECORD_LOADER); | ||||||
| 
 | 
 | ||||||
|     LoaderStatus status; |     LoaderStatus status; | ||||||
|     if(selected->is_app) { |     if(selected->is_app) { | ||||||
| @ -54,7 +54,7 @@ static void archive_run_in_app(ArchiveBrowserView* browser, ArchiveFile_t* selec | |||||||
|         FURI_LOG_E(TAG, "loader_start failed: %d", status); |         FURI_LOG_E(TAG, "loader_start failed: %d", status); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     furi_record_close("loader"); |     furi_record_close(RECORD_LOADER); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void archive_scene_browser_callback(ArchiveBrowserEvent event, void* context) { | void archive_scene_browser_callback(ArchiveBrowserEvent event, void* context) { | ||||||
| @ -71,10 +71,10 @@ void archive_scene_browser_on_enter(void* context) { | |||||||
|     archive_update_focus(browser, archive->text_store); |     archive_update_focus(browser, archive->text_store); | ||||||
|     view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewBrowser); |     view_dispatcher_switch_to_view(archive->view_dispatcher, ArchiveViewBrowser); | ||||||
| 
 | 
 | ||||||
|     Loader* loader = furi_record_open("loader"); |     Loader* loader = furi_record_open(RECORD_LOADER); | ||||||
|     archive->loader_stop_subscription = |     archive->loader_stop_subscription = | ||||||
|         furi_pubsub_subscribe(loader_get_pubsub(loader), archive_loader_callback, archive); |         furi_pubsub_subscribe(loader_get_pubsub(loader), archive_loader_callback, archive); | ||||||
|     furi_record_close("loader"); |     furi_record_close(RECORD_LOADER); | ||||||
| 
 | 
 | ||||||
|     uint32_t state = scene_manager_get_scene_state(archive->scene_manager, ArchiveAppSceneBrowser); |     uint32_t state = scene_manager_get_scene_state(archive->scene_manager, ArchiveAppSceneBrowser); | ||||||
| 
 | 
 | ||||||
| @ -196,10 +196,10 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { | |||||||
|             if(!archive_is_home(browser)) { |             if(!archive_is_home(browser)) { | ||||||
|                 archive_leave_dir(browser); |                 archive_leave_dir(browser); | ||||||
|             } else { |             } else { | ||||||
|                 Loader* loader = furi_record_open("loader"); |                 Loader* loader = furi_record_open(RECORD_LOADER); | ||||||
|                 furi_pubsub_unsubscribe( |                 furi_pubsub_unsubscribe( | ||||||
|                     loader_get_pubsub(loader), archive->loader_stop_subscription); |                     loader_get_pubsub(loader), archive->loader_stop_subscription); | ||||||
|                 furi_record_close("loader"); |                 furi_record_close(RECORD_LOADER); | ||||||
| 
 | 
 | ||||||
|                 view_dispatcher_stop(archive->view_dispatcher); |                 view_dispatcher_stop(archive->view_dispatcher); | ||||||
|             } |             } | ||||||
| @ -216,7 +216,7 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { | |||||||
| void archive_scene_browser_on_exit(void* context) { | void archive_scene_browser_on_exit(void* context) { | ||||||
|     ArchiveApp* archive = (ArchiveApp*)context; |     ArchiveApp* archive = (ArchiveApp*)context; | ||||||
| 
 | 
 | ||||||
|     Loader* loader = furi_record_open("loader"); |     Loader* loader = furi_record_open(RECORD_LOADER); | ||||||
|     furi_pubsub_unsubscribe(loader_get_pubsub(loader), archive->loader_stop_subscription); |     furi_pubsub_unsubscribe(loader_get_pubsub(loader), archive->loader_stop_subscription); | ||||||
|     furi_record_close("loader"); |     furi_record_close(RECORD_LOADER); | ||||||
| } | } | ||||||
|  | |||||||
| @ -51,7 +51,7 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) { | |||||||
| 
 | 
 | ||||||
|     if(event.type == SceneManagerEventTypeCustom) { |     if(event.type == SceneManagerEventTypeCustom) { | ||||||
|         if(event.event == SCENE_RENAME_CUSTOM_EVENT) { |         if(event.event == SCENE_RENAME_CUSTOM_EVENT) { | ||||||
|             Storage* fs_api = furi_record_open("storage"); |             Storage* fs_api = furi_record_open(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|             const char* path_src = archive_get_name(archive->browser); |             const char* path_src = archive_get_name(archive->browser); | ||||||
|             ArchiveFile_t* file = archive_get_current_file(archive->browser); |             ArchiveFile_t* file = archive_get_current_file(archive->browser); | ||||||
| @ -62,7 +62,7 @@ bool archive_scene_rename_on_event(void* context, SceneManagerEvent event) { | |||||||
|             string_cat_printf(path_dst, "/%s%s", archive->text_store, known_ext[file->type]); |             string_cat_printf(path_dst, "/%s%s", archive->text_store, known_ext[file->type]); | ||||||
| 
 | 
 | ||||||
|             storage_common_rename(fs_api, path_src, string_get_cstr(path_dst)); |             storage_common_rename(fs_api, path_src, string_get_cstr(path_dst)); | ||||||
|             furi_record_close("storage"); |             furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|             if(file->fav) { |             if(file->fav) { | ||||||
|                 archive_favorites_rename(path_src, string_get_cstr(path_dst)); |                 archive_favorites_rename(path_src, string_get_cstr(path_dst)); | ||||||
|  | |||||||
| @ -105,17 +105,10 @@ static void archive_draw_frame(Canvas* canvas, uint16_t idx, bool scrollbar, boo | |||||||
| static void archive_draw_loading(Canvas* canvas, ArchiveBrowserViewModel* model) { | static void archive_draw_loading(Canvas* canvas, ArchiveBrowserViewModel* model) { | ||||||
|     furi_assert(model); |     furi_assert(model); | ||||||
| 
 | 
 | ||||||
|     uint8_t width = 49; |     uint8_t x = 128 / 2 - 24 / 2; | ||||||
|     uint8_t height = 47; |     uint8_t y = 64 / 2 - 24 / 2; | ||||||
|     uint8_t x = 128 / 2 - width / 2; |  | ||||||
|     uint8_t y = 64 / 2 - height / 2 + 6; |  | ||||||
| 
 | 
 | ||||||
|     elements_bold_rounded_frame(canvas, x, y, width, height); |     canvas_draw_icon(canvas, x, y, &A_Loading_24); | ||||||
| 
 |  | ||||||
|     canvas_set_font(canvas, FontSecondary); |  | ||||||
|     elements_multiline_text(canvas, x + 7, y + 13, "Loading..."); |  | ||||||
| 
 |  | ||||||
|     canvas_draw_icon(canvas, x + 13, y + 19, &A_Loading_24); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) { | static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) { | ||||||
|  | |||||||
| @ -32,9 +32,9 @@ BadUsbApp* bad_usb_app_alloc(char* arg) { | |||||||
|         string_set_str(app->file_path, arg); |         string_set_str(app->file_path, arg); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     app->gui = furi_record_open("gui"); |     app->gui = furi_record_open(RECORD_GUI); | ||||||
|     app->notifications = furi_record_open("notification"); |     app->notifications = furi_record_open(RECORD_NOTIFICATION); | ||||||
|     app->dialogs = furi_record_open("dialogs"); |     app->dialogs = furi_record_open(RECORD_DIALOGS); | ||||||
| 
 | 
 | ||||||
|     app->view_dispatcher = view_dispatcher_alloc(); |     app->view_dispatcher = view_dispatcher_alloc(); | ||||||
|     view_dispatcher_enable_queue(app->view_dispatcher); |     view_dispatcher_enable_queue(app->view_dispatcher); | ||||||
| @ -92,9 +92,9 @@ void bad_usb_app_free(BadUsbApp* app) { | |||||||
|     scene_manager_free(app->scene_manager); |     scene_manager_free(app->scene_manager); | ||||||
| 
 | 
 | ||||||
|     // Close records
 |     // Close records
 | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
|     furi_record_close("notification"); |     furi_record_close(RECORD_NOTIFICATION); | ||||||
|     furi_record_close("dialogs"); |     furi_record_close(RECORD_DIALOGS); | ||||||
| 
 | 
 | ||||||
|     string_clear(app->file_path); |     string_clear(app->file_path); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ | |||||||
| #include <gui/modules/widget.h> | #include <gui/modules/widget.h> | ||||||
| #include "views/bad_usb_view.h" | #include "views/bad_usb_view.h" | ||||||
| 
 | 
 | ||||||
| #define BAD_USB_APP_PATH_FOLDER "/any/badusb" | #define BAD_USB_APP_PATH_FOLDER ANY_PATH("badusb") | ||||||
| #define BAD_USB_APP_EXTENSION ".txt" | #define BAD_USB_APP_EXTENSION ".txt" | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
|  | |||||||
| @ -171,7 +171,7 @@ static bool ducky_altchar(const char* charcode) { | |||||||
| 
 | 
 | ||||||
|     FURI_LOG_I(WORKER_TAG, "char %s", charcode); |     FURI_LOG_I(WORKER_TAG, "char %s", charcode); | ||||||
| 
 | 
 | ||||||
|     furi_hal_hid_kb_press(HID_KEYBOARD_L_ALT); |     furi_hal_hid_kb_press(KEY_MOD_LEFT_ALT); | ||||||
| 
 | 
 | ||||||
|     while(!ducky_is_line_end(charcode[i])) { |     while(!ducky_is_line_end(charcode[i])) { | ||||||
|         state = ducky_numpad_press(charcode[i]); |         state = ducky_numpad_press(charcode[i]); | ||||||
| @ -179,7 +179,7 @@ static bool ducky_altchar(const char* charcode) { | |||||||
|         i++; |         i++; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     furi_hal_hid_kb_release(HID_KEYBOARD_L_ALT); |     furi_hal_hid_kb_release(KEY_MOD_LEFT_ALT); | ||||||
|     return state; |     return state; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -455,7 +455,7 @@ static int32_t bad_usb_worker(void* context) { | |||||||
|     FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config(); |     FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config(); | ||||||
| 
 | 
 | ||||||
|     FURI_LOG_I(WORKER_TAG, "Init"); |     FURI_LOG_I(WORKER_TAG, "Init"); | ||||||
|     File* script_file = storage_file_alloc(furi_record_open("storage")); |     File* script_file = storage_file_alloc(furi_record_open(RECORD_STORAGE)); | ||||||
|     string_init(bad_usb->line); |     string_init(bad_usb->line); | ||||||
|     string_init(bad_usb->line_prev); |     string_init(bad_usb->line_prev); | ||||||
| 
 | 
 | ||||||
| @ -485,8 +485,8 @@ static int32_t bad_usb_worker(void* context) { | |||||||
| 
 | 
 | ||||||
|         } else if(worker_state == BadUsbStateNotConnected) { // State: USB not connected
 |         } else if(worker_state == BadUsbStateNotConnected) { // State: USB not connected
 | ||||||
|             uint32_t flags = furi_thread_flags_wait( |             uint32_t flags = furi_thread_flags_wait( | ||||||
|                 WorkerEvtEnd | WorkerEvtConnect, osFlagsWaitAny, osWaitForever); |                 WorkerEvtEnd | WorkerEvtConnect, FuriFlagWaitAny, FuriWaitForever); | ||||||
|             furi_check((flags & osFlagsError) == 0); |             furi_check((flags & FuriFlagError) == 0); | ||||||
|             if(flags & WorkerEvtEnd) { |             if(flags & WorkerEvtEnd) { | ||||||
|                 break; |                 break; | ||||||
|             } else if(flags & WorkerEvtConnect) { |             } else if(flags & WorkerEvtConnect) { | ||||||
| @ -497,9 +497,9 @@ static int32_t bad_usb_worker(void* context) { | |||||||
|         } else if(worker_state == BadUsbStateIdle) { // State: ready to start
 |         } else if(worker_state == BadUsbStateIdle) { // State: ready to start
 | ||||||
|             uint32_t flags = furi_thread_flags_wait( |             uint32_t flags = furi_thread_flags_wait( | ||||||
|                 WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, |                 WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, | ||||||
|                 osFlagsWaitAny, |                 FuriFlagWaitAny, | ||||||
|                 osWaitForever); |                 FuriWaitForever); | ||||||
|             furi_check((flags & osFlagsError) == 0); |             furi_check((flags & FuriFlagError) == 0); | ||||||
|             if(flags & WorkerEvtEnd) { |             if(flags & WorkerEvtEnd) { | ||||||
|                 break; |                 break; | ||||||
|             } else if(flags & WorkerEvtToggle) { // Start executing script
 |             } else if(flags & WorkerEvtToggle) { // Start executing script
 | ||||||
| @ -520,9 +520,9 @@ static int32_t bad_usb_worker(void* context) { | |||||||
|         } else if(worker_state == BadUsbStateRunning) { // State: running
 |         } else if(worker_state == BadUsbStateRunning) { // State: running
 | ||||||
|             uint16_t delay_cur = (delay_val > 1000) ? (1000) : (delay_val); |             uint16_t delay_cur = (delay_val > 1000) ? (1000) : (delay_val); | ||||||
|             uint32_t flags = furi_thread_flags_wait( |             uint32_t flags = furi_thread_flags_wait( | ||||||
|                 WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, osFlagsWaitAny, delay_cur); |                 WorkerEvtEnd | WorkerEvtToggle | WorkerEvtDisconnect, FuriFlagWaitAny, delay_cur); | ||||||
|             delay_val -= delay_cur; |             delay_val -= delay_cur; | ||||||
|             if(!(flags & osFlagsError)) { |             if(!(flags & FuriFlagError)) { | ||||||
|                 if(flags & WorkerEvtEnd) { |                 if(flags & WorkerEvtEnd) { | ||||||
|                     break; |                     break; | ||||||
|                 } else if(flags & WorkerEvtToggle) { |                 } else if(flags & WorkerEvtToggle) { | ||||||
| @ -534,7 +534,7 @@ static int32_t bad_usb_worker(void* context) { | |||||||
|                 } |                 } | ||||||
|                 bad_usb->st.state = worker_state; |                 bad_usb->st.state = worker_state; | ||||||
|                 continue; |                 continue; | ||||||
|             } else if((flags == osFlagsErrorTimeout) || (flags == osFlagsErrorResource)) { |             } else if((flags == FuriFlagErrorTimeout) || (flags == FuriFlagErrorResource)) { | ||||||
|                 if(delay_val > 0) { |                 if(delay_val > 0) { | ||||||
|                     bad_usb->st.delay_remain--; |                     bad_usb->st.delay_remain--; | ||||||
|                     continue; |                     continue; | ||||||
| @ -556,15 +556,15 @@ static int32_t bad_usb_worker(void* context) { | |||||||
|                     bad_usb->st.delay_remain = delay_val / 1000; |                     bad_usb->st.delay_remain = delay_val / 1000; | ||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
|                 furi_check((flags & osFlagsError) == 0); |                 furi_check((flags & FuriFlagError) == 0); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|         } else if( |         } else if( | ||||||
|             (worker_state == BadUsbStateFileError) || |             (worker_state == BadUsbStateFileError) || | ||||||
|             (worker_state == BadUsbStateScriptError)) { // State: error
 |             (worker_state == BadUsbStateScriptError)) { // State: error
 | ||||||
|             uint32_t flags = furi_thread_flags_wait( |             uint32_t flags = furi_thread_flags_wait( | ||||||
|                 WorkerEvtEnd, osFlagsWaitAny, osWaitForever); // Waiting for exit command
 |                 WorkerEvtEnd, FuriFlagWaitAny, FuriWaitForever); // Waiting for exit command
 | ||||||
|             furi_check((flags & osFlagsError) == 0); |             furi_check((flags & FuriFlagError) == 0); | ||||||
|             if(flags & WorkerEvtEnd) { |             if(flags & WorkerEvtEnd) { | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|  | |||||||
| @ -27,20 +27,22 @@ void bad_usb_scene_error_on_enter(void* context) { | |||||||
|             AlignTop, |             AlignTop, | ||||||
|             FontSecondary, |             FontSecondary, | ||||||
|             "No SD card or\napp data found.\nThis app will not\nwork without\nrequired files."); |             "No SD card or\napp data found.\nThis app will not\nwork without\nrequired files."); | ||||||
|  |         widget_add_button_element( | ||||||
|  |             app->widget, GuiButtonTypeLeft, "Back", bad_usb_scene_error_event_callback, app); | ||||||
|     } else if(app->error == BadUsbAppErrorCloseRpc) { |     } else if(app->error == BadUsbAppErrorCloseRpc) { | ||||||
|  |         widget_add_icon_element(app->widget, 78, 0, &I_ActiveConnection_50x64); | ||||||
|  |         widget_add_string_multiline_element( | ||||||
|  |             app->widget, 3, 2, AlignLeft, AlignTop, FontPrimary, "Connection\nis active!"); | ||||||
|         widget_add_string_multiline_element( |         widget_add_string_multiline_element( | ||||||
|             app->widget, |             app->widget, | ||||||
|             63, |             3, | ||||||
|             10, |             30, | ||||||
|             AlignCenter, |             AlignLeft, | ||||||
|             AlignTop, |             AlignTop, | ||||||
|             FontSecondary, |             FontSecondary, | ||||||
|             "Disconnect from\ncompanion app\nto use this function"); |             "Disconnect from\nPC or phone to\nuse this function."); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     widget_add_button_element( |  | ||||||
|         app->widget, GuiButtonTypeLeft, "Back", bad_usb_scene_error_event_callback, app); |  | ||||||
| 
 |  | ||||||
|     view_dispatcher_switch_to_view(app->view_dispatcher, BadUsbAppViewError); |     view_dispatcher_switch_to_view(app->view_dispatcher, BadUsbAppViewError); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -33,7 +33,7 @@ static void bt_cli_command_carrier_tx(Cli* cli, string_t args, void* context) { | |||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Bt* bt = furi_record_open("bt"); |         Bt* bt = furi_record_open(RECORD_BT); | ||||||
|         bt_disconnect(bt); |         bt_disconnect(bt); | ||||||
|         furi_hal_bt_reinit(); |         furi_hal_bt_reinit(); | ||||||
|         printf("Transmitting carrier at %d channel at %d dB power\r\n", channel, power); |         printf("Transmitting carrier at %d channel at %d dB power\r\n", channel, power); | ||||||
| @ -41,12 +41,12 @@ static void bt_cli_command_carrier_tx(Cli* cli, string_t args, void* context) { | |||||||
|         furi_hal_bt_start_tone_tx(channel, 0x19 + power); |         furi_hal_bt_start_tone_tx(channel, 0x19 + power); | ||||||
| 
 | 
 | ||||||
|         while(!cli_cmd_interrupt_received(cli)) { |         while(!cli_cmd_interrupt_received(cli)) { | ||||||
|             osDelay(250); |             furi_delay_ms(250); | ||||||
|         } |         } | ||||||
|         furi_hal_bt_stop_tone_tx(); |         furi_hal_bt_stop_tone_tx(); | ||||||
| 
 | 
 | ||||||
|         bt_set_profile(bt, BtProfileSerial); |         bt_set_profile(bt, BtProfileSerial); | ||||||
|         furi_record_close("bt"); |         furi_record_close(RECORD_BT); | ||||||
|     } while(false); |     } while(false); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -60,7 +60,7 @@ static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) { | |||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Bt* bt = furi_record_open("bt"); |         Bt* bt = furi_record_open(RECORD_BT); | ||||||
|         bt_disconnect(bt); |         bt_disconnect(bt); | ||||||
|         furi_hal_bt_reinit(); |         furi_hal_bt_reinit(); | ||||||
|         printf("Receiving carrier at %d channel\r\n", channel); |         printf("Receiving carrier at %d channel\r\n", channel); | ||||||
| @ -69,7 +69,7 @@ static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) { | |||||||
|         furi_hal_bt_start_packet_rx(channel, 1); |         furi_hal_bt_start_packet_rx(channel, 1); | ||||||
| 
 | 
 | ||||||
|         while(!cli_cmd_interrupt_received(cli)) { |         while(!cli_cmd_interrupt_received(cli)) { | ||||||
|             osDelay(250); |             furi_delay_ms(250); | ||||||
|             printf("RSSI: %6.1f dB\r", (double)furi_hal_bt_get_rssi()); |             printf("RSSI: %6.1f dB\r", (double)furi_hal_bt_get_rssi()); | ||||||
|             fflush(stdout); |             fflush(stdout); | ||||||
|         } |         } | ||||||
| @ -77,7 +77,7 @@ static void bt_cli_command_carrier_rx(Cli* cli, string_t args, void* context) { | |||||||
|         furi_hal_bt_stop_packet_test(); |         furi_hal_bt_stop_packet_test(); | ||||||
| 
 | 
 | ||||||
|         bt_set_profile(bt, BtProfileSerial); |         bt_set_profile(bt, BtProfileSerial); | ||||||
|         furi_record_close("bt"); |         furi_record_close(RECORD_BT); | ||||||
|     } while(false); |     } while(false); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -107,7 +107,7 @@ static void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) { | |||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Bt* bt = furi_record_open("bt"); |         Bt* bt = furi_record_open(RECORD_BT); | ||||||
|         bt_disconnect(bt); |         bt_disconnect(bt); | ||||||
|         furi_hal_bt_reinit(); |         furi_hal_bt_reinit(); | ||||||
|         printf( |         printf( | ||||||
| @ -119,13 +119,13 @@ static void bt_cli_command_packet_tx(Cli* cli, string_t args, void* context) { | |||||||
|         furi_hal_bt_start_packet_tx(channel, pattern, datarate); |         furi_hal_bt_start_packet_tx(channel, pattern, datarate); | ||||||
| 
 | 
 | ||||||
|         while(!cli_cmd_interrupt_received(cli)) { |         while(!cli_cmd_interrupt_received(cli)) { | ||||||
|             osDelay(250); |             furi_delay_ms(250); | ||||||
|         } |         } | ||||||
|         furi_hal_bt_stop_packet_test(); |         furi_hal_bt_stop_packet_test(); | ||||||
|         printf("Transmitted %lu packets", furi_hal_bt_get_transmitted_packets()); |         printf("Transmitted %lu packets", furi_hal_bt_get_transmitted_packets()); | ||||||
| 
 | 
 | ||||||
|         bt_set_profile(bt, BtProfileSerial); |         bt_set_profile(bt, BtProfileSerial); | ||||||
|         furi_record_close("bt"); |         furi_record_close(RECORD_BT); | ||||||
|     } while(false); |     } while(false); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -144,7 +144,7 @@ static void bt_cli_command_packet_rx(Cli* cli, string_t args, void* context) { | |||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Bt* bt = furi_record_open("bt"); |         Bt* bt = furi_record_open(RECORD_BT); | ||||||
|         bt_disconnect(bt); |         bt_disconnect(bt); | ||||||
|         furi_hal_bt_reinit(); |         furi_hal_bt_reinit(); | ||||||
|         printf("Receiving packets at %d channel at %d M datarate\r\n", channel, datarate); |         printf("Receiving packets at %d channel at %d M datarate\r\n", channel, datarate); | ||||||
| @ -152,7 +152,7 @@ static void bt_cli_command_packet_rx(Cli* cli, string_t args, void* context) { | |||||||
|         furi_hal_bt_start_packet_rx(channel, datarate); |         furi_hal_bt_start_packet_rx(channel, datarate); | ||||||
| 
 | 
 | ||||||
|         while(!cli_cmd_interrupt_received(cli)) { |         while(!cli_cmd_interrupt_received(cli)) { | ||||||
|             osDelay(250); |             furi_delay_ms(250); | ||||||
|             printf("RSSI: %03.1f dB\r", (double)furi_hal_bt_get_rssi()); |             printf("RSSI: %03.1f dB\r", (double)furi_hal_bt_get_rssi()); | ||||||
|             fflush(stdout); |             fflush(stdout); | ||||||
|         } |         } | ||||||
| @ -160,7 +160,7 @@ static void bt_cli_command_packet_rx(Cli* cli, string_t args, void* context) { | |||||||
|         printf("Received %hu packets", packets_received); |         printf("Received %hu packets", packets_received); | ||||||
| 
 | 
 | ||||||
|         bt_set_profile(bt, BtProfileSerial); |         bt_set_profile(bt, BtProfileSerial); | ||||||
|         furi_record_close("bt"); |         furi_record_close(RECORD_BT); | ||||||
|     } while(false); |     } while(false); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -180,7 +180,7 @@ static void bt_cli_print_usage() { | |||||||
| 
 | 
 | ||||||
| static void bt_cli(Cli* cli, string_t args, void* context) { | static void bt_cli(Cli* cli, string_t args, void* context) { | ||||||
|     UNUSED(context); |     UNUSED(context); | ||||||
|     furi_record_open("bt"); |     furi_record_open(RECORD_BT); | ||||||
| 
 | 
 | ||||||
|     string_t cmd; |     string_t cmd; | ||||||
|     string_init(cmd); |     string_init(cmd); | ||||||
| @ -223,14 +223,14 @@ static void bt_cli(Cli* cli, string_t args, void* context) { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     string_clear(cmd); |     string_clear(cmd); | ||||||
|     furi_record_close("bt"); |     furi_record_close(RECORD_BT); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void bt_on_system_start() { | void bt_on_system_start() { | ||||||
| #ifdef SRV_CLI | #ifdef SRV_CLI | ||||||
|     Cli* cli = furi_record_open("cli"); |     Cli* cli = furi_record_open(RECORD_CLI); | ||||||
|     cli_add_command(cli, "bt", CliCommandFlagDefault, bt_cli, NULL); |     cli_add_command(cli, RECORD_BT, CliCommandFlagDefault, bt_cli, NULL); | ||||||
|     furi_record_close("cli"); |     furi_record_close(RECORD_CLI); | ||||||
| #else | #else | ||||||
|     UNUSED(bt_cli); |     UNUSED(bt_cli); | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -35,7 +35,7 @@ BtDebugApp* bt_debug_app_alloc() { | |||||||
|     bt_settings_load(&app->settings); |     bt_settings_load(&app->settings); | ||||||
| 
 | 
 | ||||||
|     // Gui
 |     // Gui
 | ||||||
|     app->gui = furi_record_open("gui"); |     app->gui = furi_record_open(RECORD_GUI); | ||||||
| 
 | 
 | ||||||
|     // View dispatcher
 |     // View dispatcher
 | ||||||
|     app->view_dispatcher = view_dispatcher_alloc(); |     app->view_dispatcher = view_dispatcher_alloc(); | ||||||
| @ -88,7 +88,7 @@ void bt_debug_app_free(BtDebugApp* app) { | |||||||
|     view_dispatcher_free(app->view_dispatcher); |     view_dispatcher_free(app->view_dispatcher); | ||||||
| 
 | 
 | ||||||
|     // Close gui record
 |     // Close gui record
 | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
|     app->gui = NULL; |     app->gui = NULL; | ||||||
| 
 | 
 | ||||||
|     // Free rest
 |     // Free rest
 | ||||||
| @ -99,7 +99,7 @@ int32_t bt_debug_app(void* p) { | |||||||
|     UNUSED(p); |     UNUSED(p); | ||||||
|     if(!furi_hal_bt_is_testing_supported()) { |     if(!furi_hal_bt_is_testing_supported()) { | ||||||
|         FURI_LOG_E(TAG, "Incorrect radio stack: radio testing fetures are absent."); |         FURI_LOG_E(TAG, "Incorrect radio stack: radio testing fetures are absent."); | ||||||
|         DialogsApp* dialogs = furi_record_open("dialogs"); |         DialogsApp* dialogs = furi_record_open(RECORD_DIALOGS); | ||||||
|         dialog_message_show_storage_error(dialogs, "Incorrect\nRadioStack"); |         dialog_message_show_storage_error(dialogs, "Incorrect\nRadioStack"); | ||||||
|         return 255; |         return 255; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ struct BtCarrierTest { | |||||||
|     BtTestMode mode; |     BtTestMode mode; | ||||||
|     BtTestChannel channel; |     BtTestChannel channel; | ||||||
|     BtTestPower power; |     BtTestPower power; | ||||||
|     osTimerId_t timer; |     FuriTimer* timer; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static BtTestParamValue bt_param_mode[] = { | static BtTestParamValue bt_param_mode[] = { | ||||||
| @ -35,10 +35,10 @@ static void bt_carrier_test_start(BtCarrierTest* bt_carrier_test) { | |||||||
|     furi_assert(bt_carrier_test); |     furi_assert(bt_carrier_test); | ||||||
|     if(bt_carrier_test->mode == BtTestModeRx) { |     if(bt_carrier_test->mode == BtTestModeRx) { | ||||||
|         furi_hal_bt_start_packet_rx(bt_carrier_test->channel, 1); |         furi_hal_bt_start_packet_rx(bt_carrier_test->channel, 1); | ||||||
|         osTimerStart(bt_carrier_test->timer, osKernelGetTickFreq() / 4); |         furi_timer_start(bt_carrier_test->timer, furi_kernel_get_tick_frequency() / 4); | ||||||
|     } else if(bt_carrier_test->mode == BtTestModeTxHopping) { |     } else if(bt_carrier_test->mode == BtTestModeTxHopping) { | ||||||
|         furi_hal_bt_start_tone_tx(bt_carrier_test->channel, bt_carrier_test->power); |         furi_hal_bt_start_tone_tx(bt_carrier_test->channel, bt_carrier_test->power); | ||||||
|         osTimerStart(bt_carrier_test->timer, osKernelGetTickFreq() * 2); |         furi_timer_start(bt_carrier_test->timer, furi_kernel_get_tick_frequency() * 2); | ||||||
|     } else if(bt_carrier_test->mode == BtTestModeTx) { |     } else if(bt_carrier_test->mode == BtTestModeTx) { | ||||||
|         furi_hal_bt_start_tone_tx(bt_carrier_test->channel, bt_carrier_test->power); |         furi_hal_bt_start_tone_tx(bt_carrier_test->channel, bt_carrier_test->power); | ||||||
|     } |     } | ||||||
| @ -68,12 +68,12 @@ static void bt_carrier_test_stop(BtCarrierTest* bt_carrier_test) { | |||||||
|     furi_assert(bt_carrier_test); |     furi_assert(bt_carrier_test); | ||||||
|     if(bt_carrier_test->mode == BtTestModeTxHopping) { |     if(bt_carrier_test->mode == BtTestModeTxHopping) { | ||||||
|         furi_hal_bt_stop_tone_tx(); |         furi_hal_bt_stop_tone_tx(); | ||||||
|         osTimerStop(bt_carrier_test->timer); |         furi_timer_stop(bt_carrier_test->timer); | ||||||
|     } else if(bt_carrier_test->mode == BtTestModeTx) { |     } else if(bt_carrier_test->mode == BtTestModeTx) { | ||||||
|         furi_hal_bt_stop_tone_tx(); |         furi_hal_bt_stop_tone_tx(); | ||||||
|     } else if(bt_carrier_test->mode == BtTestModeRx) { |     } else if(bt_carrier_test->mode == BtTestModeRx) { | ||||||
|         furi_hal_bt_stop_packet_test(); |         furi_hal_bt_stop_packet_test(); | ||||||
|         osTimerStop(bt_carrier_test->timer); |         furi_timer_stop(bt_carrier_test->timer); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -170,7 +170,7 @@ BtCarrierTest* bt_carrier_test_alloc() { | |||||||
|     bt_carrier_test->power = BtPower0dB; |     bt_carrier_test->power = BtPower0dB; | ||||||
| 
 | 
 | ||||||
|     bt_carrier_test->timer = |     bt_carrier_test->timer = | ||||||
|         osTimerNew(bt_test_carrier_timer_callback, osTimerPeriodic, bt_carrier_test, NULL); |         furi_timer_alloc(bt_test_carrier_timer_callback, FuriTimerTypePeriodic, bt_carrier_test); | ||||||
| 
 | 
 | ||||||
|     return bt_carrier_test; |     return bt_carrier_test; | ||||||
| } | } | ||||||
| @ -178,7 +178,7 @@ BtCarrierTest* bt_carrier_test_alloc() { | |||||||
| void bt_carrier_test_free(BtCarrierTest* bt_carrier_test) { | void bt_carrier_test_free(BtCarrierTest* bt_carrier_test) { | ||||||
|     furi_assert(bt_carrier_test); |     furi_assert(bt_carrier_test); | ||||||
|     bt_test_free(bt_carrier_test->bt_test); |     bt_test_free(bt_carrier_test->bt_test); | ||||||
|     osTimerDelete(bt_carrier_test->timer); |     furi_timer_free(bt_carrier_test->timer); | ||||||
|     free(bt_carrier_test); |     free(bt_carrier_test); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ struct BtPacketTest { | |||||||
|     BtTestMode mode; |     BtTestMode mode; | ||||||
|     BtTestChannel channel; |     BtTestChannel channel; | ||||||
|     BtTestDataRate data_rate; |     BtTestDataRate data_rate; | ||||||
|     osTimerId_t timer; |     FuriTimer* timer; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static BtTestParamValue bt_param_mode[] = { | static BtTestParamValue bt_param_mode[] = { | ||||||
| @ -31,7 +31,7 @@ static void bt_packet_test_start(BtPacketTest* bt_packet_test) { | |||||||
|     furi_assert(bt_packet_test); |     furi_assert(bt_packet_test); | ||||||
|     if(bt_packet_test->mode == BtTestModeRx) { |     if(bt_packet_test->mode == BtTestModeRx) { | ||||||
|         furi_hal_bt_start_packet_rx(bt_packet_test->channel, bt_packet_test->data_rate); |         furi_hal_bt_start_packet_rx(bt_packet_test->channel, bt_packet_test->data_rate); | ||||||
|         osTimerStart(bt_packet_test->timer, osKernelGetTickFreq() / 4); |         furi_timer_start(bt_packet_test->timer, furi_kernel_get_tick_frequency() / 4); | ||||||
|     } else if(bt_packet_test->mode == BtTestModeTx) { |     } else if(bt_packet_test->mode == BtTestModeTx) { | ||||||
|         furi_hal_bt_start_packet_tx(bt_packet_test->channel, 1, bt_packet_test->data_rate); |         furi_hal_bt_start_packet_tx(bt_packet_test->channel, 1, bt_packet_test->data_rate); | ||||||
|     } |     } | ||||||
| @ -44,7 +44,7 @@ static void bt_packet_test_stop(BtPacketTest* bt_packet_test) { | |||||||
|         bt_test_set_packets_tx(bt_packet_test->bt_test, furi_hal_bt_get_transmitted_packets()); |         bt_test_set_packets_tx(bt_packet_test->bt_test, furi_hal_bt_get_transmitted_packets()); | ||||||
|     } else if(bt_packet_test->mode == BtTestModeRx) { |     } else if(bt_packet_test->mode == BtTestModeRx) { | ||||||
|         bt_test_set_packets_rx(bt_packet_test->bt_test, furi_hal_bt_stop_packet_test()); |         bt_test_set_packets_rx(bt_packet_test->bt_test, furi_hal_bt_stop_packet_test()); | ||||||
|         osTimerStop(bt_packet_test->timer); |         furi_timer_stop(bt_packet_test->timer); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -137,7 +137,7 @@ BtPacketTest* bt_packet_test_alloc() { | |||||||
|     bt_packet_test->data_rate = BtDataRate1M; |     bt_packet_test->data_rate = BtDataRate1M; | ||||||
| 
 | 
 | ||||||
|     bt_packet_test->timer = |     bt_packet_test->timer = | ||||||
|         osTimerNew(bt_test_packet_timer_callback, osTimerPeriodic, bt_packet_test, NULL); |         furi_timer_alloc(bt_test_packet_timer_callback, FuriTimerTypePeriodic, bt_packet_test); | ||||||
| 
 | 
 | ||||||
|     return bt_packet_test; |     return bt_packet_test; | ||||||
| } | } | ||||||
| @ -145,7 +145,7 @@ BtPacketTest* bt_packet_test_alloc() { | |||||||
| void bt_packet_test_free(BtPacketTest* bt_packet_test) { | void bt_packet_test_free(BtPacketTest* bt_packet_test) { | ||||||
|     furi_assert(bt_packet_test); |     furi_assert(bt_packet_test); | ||||||
|     bt_test_free(bt_packet_test->bt_test); |     bt_test_free(bt_packet_test->bt_test); | ||||||
|     osTimerDelete(bt_packet_test->timer); |     furi_timer_free(bt_packet_test->timer); | ||||||
|     free(bt_packet_test); |     free(bt_packet_test); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -70,13 +70,13 @@ BtHid* bt_hid_app_alloc() { | |||||||
|     BtHid* app = malloc(sizeof(BtHid)); |     BtHid* app = malloc(sizeof(BtHid)); | ||||||
| 
 | 
 | ||||||
|     // Gui
 |     // Gui
 | ||||||
|     app->gui = furi_record_open("gui"); |     app->gui = furi_record_open(RECORD_GUI); | ||||||
| 
 | 
 | ||||||
|     // Bt
 |     // Bt
 | ||||||
|     app->bt = furi_record_open("bt"); |     app->bt = furi_record_open(RECORD_BT); | ||||||
| 
 | 
 | ||||||
|     // Notifications
 |     // Notifications
 | ||||||
|     app->notifications = furi_record_open("notification"); |     app->notifications = furi_record_open(RECORD_NOTIFICATION); | ||||||
| 
 | 
 | ||||||
|     // View dispatcher
 |     // View dispatcher
 | ||||||
|     app->view_dispatcher = view_dispatcher_alloc(); |     app->view_dispatcher = view_dispatcher_alloc(); | ||||||
| @ -161,11 +161,11 @@ void bt_hid_app_free(BtHid* app) { | |||||||
|     view_dispatcher_free(app->view_dispatcher); |     view_dispatcher_free(app->view_dispatcher); | ||||||
| 
 | 
 | ||||||
|     // Close records
 |     // Close records
 | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
|     app->gui = NULL; |     app->gui = NULL; | ||||||
|     furi_record_close("notification"); |     furi_record_close(RECORD_NOTIFICATION); | ||||||
|     app->notifications = NULL; |     app->notifications = NULL; | ||||||
|     furi_record_close("bt"); |     furi_record_close(RECORD_BT); | ||||||
|     app->bt = NULL; |     app->bt = NULL; | ||||||
| 
 | 
 | ||||||
|     // Free rest
 |     // Free rest
 | ||||||
|  | |||||||
| @ -96,12 +96,14 @@ static void bt_battery_level_changed_callback(const void* _event, void* context) | |||||||
|     if(event->type == PowerEventTypeBatteryLevelChanged) { |     if(event->type == PowerEventTypeBatteryLevelChanged) { | ||||||
|         message.type = BtMessageTypeUpdateBatteryLevel; |         message.type = BtMessageTypeUpdateBatteryLevel; | ||||||
|         message.data.battery_level = event->data.battery_level; |         message.data.battery_level = event->data.battery_level; | ||||||
|         furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); |         furi_check( | ||||||
|  |             furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); | ||||||
|     } else if( |     } else if( | ||||||
|         event->type == PowerEventTypeStartCharging || event->type == PowerEventTypeFullyCharged || |         event->type == PowerEventTypeStartCharging || event->type == PowerEventTypeFullyCharged || | ||||||
|         event->type == PowerEventTypeStopCharging) { |         event->type == PowerEventTypeStopCharging) { | ||||||
|         message.type = BtMessageTypeUpdatePowerState; |         message.type = BtMessageTypeUpdatePowerState; | ||||||
|         furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); |         furi_check( | ||||||
|  |             furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -115,34 +117,34 @@ Bt* bt_alloc() { | |||||||
|         bt_settings_save(&bt->bt_settings); |         bt_settings_save(&bt->bt_settings); | ||||||
|     } |     } | ||||||
|     // Alloc queue
 |     // Alloc queue
 | ||||||
|     bt->message_queue = osMessageQueueNew(8, sizeof(BtMessage), NULL); |     bt->message_queue = furi_message_queue_alloc(8, sizeof(BtMessage)); | ||||||
| 
 | 
 | ||||||
|     // Setup statusbar view port
 |     // Setup statusbar view port
 | ||||||
|     bt->statusbar_view_port = bt_statusbar_view_port_alloc(bt); |     bt->statusbar_view_port = bt_statusbar_view_port_alloc(bt); | ||||||
|     // Pin code view port
 |     // Pin code view port
 | ||||||
|     bt->pin_code_view_port = bt_pin_code_view_port_alloc(bt); |     bt->pin_code_view_port = bt_pin_code_view_port_alloc(bt); | ||||||
|     // Notification
 |     // Notification
 | ||||||
|     bt->notification = furi_record_open("notification"); |     bt->notification = furi_record_open(RECORD_NOTIFICATION); | ||||||
|     // Gui
 |     // Gui
 | ||||||
|     bt->gui = furi_record_open("gui"); |     bt->gui = furi_record_open(RECORD_GUI); | ||||||
|     gui_add_view_port(bt->gui, bt->statusbar_view_port, GuiLayerStatusBarLeft); |     gui_add_view_port(bt->gui, bt->statusbar_view_port, GuiLayerStatusBarLeft); | ||||||
|     gui_add_view_port(bt->gui, bt->pin_code_view_port, GuiLayerFullscreen); |     gui_add_view_port(bt->gui, bt->pin_code_view_port, GuiLayerFullscreen); | ||||||
| 
 | 
 | ||||||
|     // Dialogs
 |     // Dialogs
 | ||||||
|     bt->dialogs = furi_record_open("dialogs"); |     bt->dialogs = furi_record_open(RECORD_DIALOGS); | ||||||
|     bt->dialog_message = dialog_message_alloc(); |     bt->dialog_message = dialog_message_alloc(); | ||||||
| 
 | 
 | ||||||
|     // Power
 |     // Power
 | ||||||
|     bt->power = furi_record_open("power"); |     bt->power = furi_record_open(RECORD_POWER); | ||||||
|     FuriPubSub* power_pubsub = power_get_pubsub(bt->power); |     FuriPubSub* power_pubsub = power_get_pubsub(bt->power); | ||||||
|     furi_pubsub_subscribe(power_pubsub, bt_battery_level_changed_callback, bt); |     furi_pubsub_subscribe(power_pubsub, bt_battery_level_changed_callback, bt); | ||||||
| 
 | 
 | ||||||
|     // RPC
 |     // RPC
 | ||||||
|     bt->rpc = furi_record_open("rpc"); |     bt->rpc = furi_record_open(RECORD_RPC); | ||||||
|     bt->rpc_event = osEventFlagsNew(NULL); |     bt->rpc_event = furi_event_flag_alloc(); | ||||||
| 
 | 
 | ||||||
|     // API evnent
 |     // API evnent
 | ||||||
|     bt->api_event = osEventFlagsNew(NULL); |     bt->api_event = furi_event_flag_alloc(); | ||||||
| 
 | 
 | ||||||
|     return bt; |     return bt; | ||||||
| } | } | ||||||
| @ -162,7 +164,7 @@ static uint16_t bt_serial_event_callback(SerialServiceEvent event, void* context | |||||||
|         } |         } | ||||||
|         ret = rpc_session_get_available_size(bt->rpc_session); |         ret = rpc_session_get_available_size(bt->rpc_session); | ||||||
|     } else if(event.event == SerialServiceEventTypeDataSent) { |     } else if(event.event == SerialServiceEventTypeDataSent) { | ||||||
|         osEventFlagsSet(bt->rpc_event, BT_RPC_EVENT_BUFF_SENT); |         furi_event_flag_set(bt->rpc_event, BT_RPC_EVENT_BUFF_SENT); | ||||||
|     } |     } | ||||||
|     return ret; |     return ret; | ||||||
| } | } | ||||||
| @ -172,11 +174,11 @@ static void bt_rpc_send_bytes_callback(void* context, uint8_t* bytes, size_t byt | |||||||
|     furi_assert(context); |     furi_assert(context); | ||||||
|     Bt* bt = context; |     Bt* bt = context; | ||||||
| 
 | 
 | ||||||
|     if(osEventFlagsGet(bt->rpc_event) & BT_RPC_EVENT_DISCONNECTED) { |     if(furi_event_flag_get(bt->rpc_event) & BT_RPC_EVENT_DISCONNECTED) { | ||||||
|         // Early stop from sending if we're already disconnected
 |         // Early stop from sending if we're already disconnected
 | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     osEventFlagsClear(bt->rpc_event, BT_RPC_EVENT_ALL & (~BT_RPC_EVENT_DISCONNECTED)); |     furi_event_flag_clear(bt->rpc_event, BT_RPC_EVENT_ALL & (~BT_RPC_EVENT_DISCONNECTED)); | ||||||
|     size_t bytes_sent = 0; |     size_t bytes_sent = 0; | ||||||
|     while(bytes_sent < bytes_len) { |     while(bytes_sent < bytes_len) { | ||||||
|         size_t bytes_remain = bytes_len - bytes_sent; |         size_t bytes_remain = bytes_len - bytes_sent; | ||||||
| @ -188,13 +190,13 @@ static void bt_rpc_send_bytes_callback(void* context, uint8_t* bytes, size_t byt | |||||||
|             bytes_sent += bytes_remain; |             bytes_sent += bytes_remain; | ||||||
|         } |         } | ||||||
|         // We want BT_RPC_EVENT_DISCONNECTED to stick, so don't clear
 |         // We want BT_RPC_EVENT_DISCONNECTED to stick, so don't clear
 | ||||||
|         uint32_t event_flag = osEventFlagsWait( |         uint32_t event_flag = furi_event_flag_wait( | ||||||
|             bt->rpc_event, BT_RPC_EVENT_ALL, osFlagsWaitAny | osFlagsNoClear, osWaitForever); |             bt->rpc_event, BT_RPC_EVENT_ALL, FuriFlagWaitAny | FuriFlagNoClear, FuriWaitForever); | ||||||
|         if(event_flag & BT_RPC_EVENT_DISCONNECTED) { |         if(event_flag & BT_RPC_EVENT_DISCONNECTED) { | ||||||
|             break; |             break; | ||||||
|         } else { |         } else { | ||||||
|             // If we didn't get BT_RPC_EVENT_DISCONNECTED, then clear everything else
 |             // If we didn't get BT_RPC_EVENT_DISCONNECTED, then clear everything else
 | ||||||
|             osEventFlagsClear(bt->rpc_event, BT_RPC_EVENT_ALL & (~BT_RPC_EVENT_DISCONNECTED)); |             furi_event_flag_clear(bt->rpc_event, BT_RPC_EVENT_ALL & (~BT_RPC_EVENT_DISCONNECTED)); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -209,9 +211,10 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { | |||||||
|         // Update status bar
 |         // Update status bar
 | ||||||
|         bt->status = BtStatusConnected; |         bt->status = BtStatusConnected; | ||||||
|         BtMessage message = {.type = BtMessageTypeUpdateStatus}; |         BtMessage message = {.type = BtMessageTypeUpdateStatus}; | ||||||
|         furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); |         furi_check( | ||||||
|  |             furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); | ||||||
|         // Clear BT_RPC_EVENT_DISCONNECTED because it might be set from previous session
 |         // Clear BT_RPC_EVENT_DISCONNECTED because it might be set from previous session
 | ||||||
|         osEventFlagsClear(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); |         furi_event_flag_clear(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); | ||||||
|         if(bt->profile == BtProfileSerial) { |         if(bt->profile == BtProfileSerial) { | ||||||
|             // Open RPC session
 |             // Open RPC session
 | ||||||
|             bt->rpc_session = rpc_session_open(bt->rpc); |             bt->rpc_session = rpc_session_open(bt->rpc); | ||||||
| @ -232,12 +235,13 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { | |||||||
|         power_get_info(bt->power, &info); |         power_get_info(bt->power, &info); | ||||||
|         message.type = BtMessageTypeUpdateBatteryLevel; |         message.type = BtMessageTypeUpdateBatteryLevel; | ||||||
|         message.data.battery_level = info.charge; |         message.data.battery_level = info.charge; | ||||||
|         furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); |         furi_check( | ||||||
|  |             furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); | ||||||
|         ret = true; |         ret = true; | ||||||
|     } else if(event.type == GapEventTypeDisconnected) { |     } else if(event.type == GapEventTypeDisconnected) { | ||||||
|         if(bt->profile == BtProfileSerial && bt->rpc_session) { |         if(bt->profile == BtProfileSerial && bt->rpc_session) { | ||||||
|             FURI_LOG_I(TAG, "Close RPC connection"); |             FURI_LOG_I(TAG, "Close RPC connection"); | ||||||
|             osEventFlagsSet(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); |             furi_event_flag_set(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); | ||||||
|             rpc_session_close(bt->rpc_session); |             rpc_session_close(bt->rpc_session); | ||||||
|             furi_hal_bt_serial_set_event_callback(0, NULL, NULL); |             furi_hal_bt_serial_set_event_callback(0, NULL, NULL); | ||||||
|             bt->rpc_session = NULL; |             bt->rpc_session = NULL; | ||||||
| @ -246,17 +250,20 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) { | |||||||
|     } else if(event.type == GapEventTypeStartAdvertising) { |     } else if(event.type == GapEventTypeStartAdvertising) { | ||||||
|         bt->status = BtStatusAdvertising; |         bt->status = BtStatusAdvertising; | ||||||
|         BtMessage message = {.type = BtMessageTypeUpdateStatus}; |         BtMessage message = {.type = BtMessageTypeUpdateStatus}; | ||||||
|         furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); |         furi_check( | ||||||
|  |             furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); | ||||||
|         ret = true; |         ret = true; | ||||||
|     } else if(event.type == GapEventTypeStopAdvertising) { |     } else if(event.type == GapEventTypeStopAdvertising) { | ||||||
|         bt->status = BtStatusOff; |         bt->status = BtStatusOff; | ||||||
|         BtMessage message = {.type = BtMessageTypeUpdateStatus}; |         BtMessage message = {.type = BtMessageTypeUpdateStatus}; | ||||||
|         furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); |         furi_check( | ||||||
|  |             furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); | ||||||
|         ret = true; |         ret = true; | ||||||
|     } else if(event.type == GapEventTypePinCodeShow) { |     } else if(event.type == GapEventTypePinCodeShow) { | ||||||
|         BtMessage message = { |         BtMessage message = { | ||||||
|             .type = BtMessageTypePinCodeShow, .data.pin_code = event.data.pin_code}; |             .type = BtMessageTypePinCodeShow, .data.pin_code = event.data.pin_code}; | ||||||
|         furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); |         furi_check( | ||||||
|  |             furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); | ||||||
|         ret = true; |         ret = true; | ||||||
|     } else if(event.type == GapEventTypePinCodeVerify) { |     } else if(event.type == GapEventTypePinCodeVerify) { | ||||||
|         ret = bt_pin_code_verify_event_handler(bt, event.data.pin_code); |         ret = bt_pin_code_verify_event_handler(bt, event.data.pin_code); | ||||||
| @ -272,7 +279,8 @@ static void bt_on_key_storage_change_callback(uint8_t* addr, uint16_t size, void | |||||||
|     Bt* bt = context; |     Bt* bt = context; | ||||||
|     FURI_LOG_I(TAG, "Changed addr start: %08lX, size changed: %d", addr, size); |     FURI_LOG_I(TAG, "Changed addr start: %08lX, size changed: %d", addr, size); | ||||||
|     BtMessage message = {.type = BtMessageTypeKeysStorageUpdated}; |     BtMessage message = {.type = BtMessageTypeKeysStorageUpdated}; | ||||||
|     furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); |     furi_check( | ||||||
|  |         furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void bt_statusbar_update(Bt* bt) { | static void bt_statusbar_update(Bt* bt) { | ||||||
| @ -296,7 +304,7 @@ static void bt_show_warning(Bt* bt, const char* text) { | |||||||
| static void bt_close_rpc_connection(Bt* bt) { | static void bt_close_rpc_connection(Bt* bt) { | ||||||
|     if(bt->profile == BtProfileSerial && bt->rpc_session) { |     if(bt->profile == BtProfileSerial && bt->rpc_session) { | ||||||
|         FURI_LOG_I(TAG, "Close RPC connection"); |         FURI_LOG_I(TAG, "Close RPC connection"); | ||||||
|         osEventFlagsSet(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); |         furi_event_flag_set(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED); | ||||||
|         rpc_session_close(bt->rpc_session); |         rpc_session_close(bt->rpc_session); | ||||||
|         furi_hal_bt_serial_set_event_callback(0, NULL, NULL); |         furi_hal_bt_serial_set_event_callback(0, NULL, NULL); | ||||||
|         bt->rpc_session = NULL; |         bt->rpc_session = NULL; | ||||||
| @ -331,12 +339,12 @@ static void bt_change_profile(Bt* bt, BtMessage* message) { | |||||||
|         bt_show_warning(bt, "Radio stack doesn't support this app"); |         bt_show_warning(bt, "Radio stack doesn't support this app"); | ||||||
|         *message->result = false; |         *message->result = false; | ||||||
|     } |     } | ||||||
|     osEventFlagsSet(bt->api_event, BT_API_UNLOCK_EVENT); |     furi_event_flag_set(bt->api_event, BT_API_UNLOCK_EVENT); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void bt_close_connection(Bt* bt) { | static void bt_close_connection(Bt* bt) { | ||||||
|     bt_close_rpc_connection(bt); |     bt_close_rpc_connection(bt); | ||||||
|     osEventFlagsSet(bt->api_event, BT_API_UNLOCK_EVENT); |     furi_event_flag_set(bt->api_event, BT_API_UNLOCK_EVENT); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int32_t bt_srv() { | int32_t bt_srv() { | ||||||
| @ -345,7 +353,7 @@ int32_t bt_srv() { | |||||||
|     if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) { |     if(furi_hal_rtc_get_boot_mode() != FuriHalRtcBootModeNormal) { | ||||||
|         FURI_LOG_W(TAG, "Skipped BT init: device in special startup mode"); |         FURI_LOG_W(TAG, "Skipped BT init: device in special startup mode"); | ||||||
|         ble_glue_wait_for_c2_start(FURI_HAL_BT_C2_START_TIMEOUT); |         ble_glue_wait_for_c2_start(FURI_HAL_BT_C2_START_TIMEOUT); | ||||||
|         furi_record_create("bt", bt); |         furi_record_create(RECORD_BT, bt); | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -373,11 +381,12 @@ int32_t bt_srv() { | |||||||
|         bt->status = BtStatusUnavailable; |         bt->status = BtStatusUnavailable; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     furi_record_create("bt", bt); |     furi_record_create(RECORD_BT, bt); | ||||||
| 
 | 
 | ||||||
|     BtMessage message; |     BtMessage message; | ||||||
|     while(1) { |     while(1) { | ||||||
|         furi_check(osMessageQueueGet(bt->message_queue, &message, NULL, osWaitForever) == osOK); |         furi_check( | ||||||
|  |             furi_message_queue_get(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); | ||||||
|         if(message.type == BtMessageTypeUpdateStatus) { |         if(message.type == BtMessageTypeUpdateStatus) { | ||||||
|             // Update view ports
 |             // Update view ports
 | ||||||
|             bt_statusbar_update(bt); |             bt_statusbar_update(bt); | ||||||
|  | |||||||
| @ -7,6 +7,8 @@ | |||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #define RECORD_BT "bt" | ||||||
|  | 
 | ||||||
| typedef struct Bt Bt; | typedef struct Bt Bt; | ||||||
| 
 | 
 | ||||||
| typedef enum { | typedef enum { | ||||||
|  | |||||||
							
								
								
									
										13
									
								
								applications/bt/bt_service/bt_api.c
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										13
									
								
								applications/bt/bt_service/bt_api.c
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							| @ -7,9 +7,10 @@ bool bt_set_profile(Bt* bt, BtProfile profile) { | |||||||
|     bool result = false; |     bool result = false; | ||||||
|     BtMessage message = { |     BtMessage message = { | ||||||
|         .type = BtMessageTypeSetProfile, .data.profile = profile, .result = &result}; |         .type = BtMessageTypeSetProfile, .data.profile = profile, .result = &result}; | ||||||
|     furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); |     furi_check( | ||||||
|  |         furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); | ||||||
|     // Wait for unlock
 |     // Wait for unlock
 | ||||||
|     osEventFlagsWait(bt->api_event, BT_API_UNLOCK_EVENT, osFlagsWaitAny, osWaitForever); |     furi_event_flag_wait(bt->api_event, BT_API_UNLOCK_EVENT, FuriFlagWaitAny, FuriWaitForever); | ||||||
| 
 | 
 | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| @ -19,9 +20,10 @@ void bt_disconnect(Bt* bt) { | |||||||
| 
 | 
 | ||||||
|     // Send message
 |     // Send message
 | ||||||
|     BtMessage message = {.type = BtMessageTypeDisconnect}; |     BtMessage message = {.type = BtMessageTypeDisconnect}; | ||||||
|     furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); |     furi_check( | ||||||
|  |         furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); | ||||||
|     // Wait for unlock
 |     // Wait for unlock
 | ||||||
|     osEventFlagsWait(bt->api_event, BT_API_UNLOCK_EVENT, osFlagsWaitAny, osWaitForever); |     furi_event_flag_wait(bt->api_event, BT_API_UNLOCK_EVENT, FuriFlagWaitAny, FuriWaitForever); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void bt_set_status_changed_callback(Bt* bt, BtStatusChangedCallback callback, void* context) { | void bt_set_status_changed_callback(Bt* bt, BtStatusChangedCallback callback, void* context) { | ||||||
| @ -34,5 +36,6 @@ void bt_set_status_changed_callback(Bt* bt, BtStatusChangedCallback callback, vo | |||||||
| void bt_forget_bonded_devices(Bt* bt) { | void bt_forget_bonded_devices(Bt* bt) { | ||||||
|     furi_assert(bt); |     furi_assert(bt); | ||||||
|     BtMessage message = {.type = BtMessageTypeForgetBondedDevices}; |     BtMessage message = {.type = BtMessageTypeForgetBondedDevices}; | ||||||
|     furi_check(osMessageQueuePut(bt->message_queue, &message, 0, osWaitForever) == osOK); |     furi_check( | ||||||
|  |         furi_message_queue_put(bt->message_queue, &message, FuriWaitForever) == FuriStatusOk); | ||||||
| } | } | ||||||
|  | |||||||
| @ -48,7 +48,7 @@ struct Bt { | |||||||
|     BtSettings bt_settings; |     BtSettings bt_settings; | ||||||
|     BtStatus status; |     BtStatus status; | ||||||
|     BtProfile profile; |     BtProfile profile; | ||||||
|     osMessageQueueId_t message_queue; |     FuriMessageQueue* message_queue; | ||||||
|     NotificationApp* notification; |     NotificationApp* notification; | ||||||
|     Gui* gui; |     Gui* gui; | ||||||
|     ViewPort* statusbar_view_port; |     ViewPort* statusbar_view_port; | ||||||
| @ -59,8 +59,8 @@ struct Bt { | |||||||
|     Power* power; |     Power* power; | ||||||
|     Rpc* rpc; |     Rpc* rpc; | ||||||
|     RpcSession* rpc_session; |     RpcSession* rpc_session; | ||||||
|     osEventFlagsId_t rpc_event; |     FuriEventFlag* rpc_event; | ||||||
|     osEventFlagsId_t api_event; |     FuriEventFlag* api_event; | ||||||
|     BtStatusChangedCallback status_changed_cb; |     BtStatusChangedCallback status_changed_cb; | ||||||
|     void* status_changed_ctx; |     void* status_changed_ctx; | ||||||
| }; | }; | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								applications/bt/bt_service/bt_keys_filename.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								applications/bt/bt_service/bt_keys_filename.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #define BT_KEYS_STORAGE_FILE_NAME ".bt.keys" | ||||||
| @ -2,8 +2,9 @@ | |||||||
| 
 | 
 | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <lib/toolbox/saved_struct.h> | #include <lib/toolbox/saved_struct.h> | ||||||
|  | #include <storage/storage.h> | ||||||
| 
 | 
 | ||||||
| #define BT_KEYS_STORAGE_PATH "/int/bt.keys" | #define BT_KEYS_STORAGE_PATH INT_PATH(BT_KEYS_STORAGE_FILE_NAME) | ||||||
| #define BT_KEYS_STORAGE_VERSION (0) | #define BT_KEYS_STORAGE_VERSION (0) | ||||||
| #define BT_KEYS_STORAGE_MAGIC (0x18) | #define BT_KEYS_STORAGE_MAGIC (0x18) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include "bt_i.h" | #include "bt_i.h" | ||||||
|  | #include "bt_keys_filename.h" | ||||||
| 
 | 
 | ||||||
| bool bt_keys_storage_load(Bt* bt); | bool bt_keys_storage_load(Bt* bt); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,8 +2,9 @@ | |||||||
| 
 | 
 | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <lib/toolbox/saved_struct.h> | #include <lib/toolbox/saved_struct.h> | ||||||
|  | #include <storage/storage.h> | ||||||
| 
 | 
 | ||||||
| #define BT_SETTINGS_PATH "/int/bt.settings" | #define BT_SETTINGS_PATH INT_PATH(BT_SETTINGS_FILE_NAME) | ||||||
| #define BT_SETTINGS_VERSION (0) | #define BT_SETTINGS_VERSION (0) | ||||||
| #define BT_SETTINGS_MAGIC (0x19) | #define BT_SETTINGS_MAGIC (0x19) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,5 +1,7 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include "bt_settings_filename.h" | ||||||
|  | 
 | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -17,8 +17,8 @@ BtSettingsApp* bt_settings_app_alloc() { | |||||||
| 
 | 
 | ||||||
|     // Load settings
 |     // Load settings
 | ||||||
|     bt_settings_load(&app->settings); |     bt_settings_load(&app->settings); | ||||||
|     app->gui = furi_record_open("gui"); |     app->gui = furi_record_open(RECORD_GUI); | ||||||
|     app->bt = furi_record_open("bt"); |     app->bt = furi_record_open(RECORD_BT); | ||||||
| 
 | 
 | ||||||
|     // View Dispatcher and Scene Manager
 |     // View Dispatcher and Scene Manager
 | ||||||
|     app->view_dispatcher = view_dispatcher_alloc(); |     app->view_dispatcher = view_dispatcher_alloc(); | ||||||
| @ -70,8 +70,8 @@ void bt_settings_app_free(BtSettingsApp* app) { | |||||||
|     scene_manager_free(app->scene_manager); |     scene_manager_free(app->scene_manager); | ||||||
| 
 | 
 | ||||||
|     // Records
 |     // Records
 | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
|     furi_record_close("bt"); |     furi_record_close(RECORD_BT); | ||||||
|     free(app); |     free(app); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								applications/bt/bt_settings_filename.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								applications/bt/bt_settings_filename.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #define BT_SETTINGS_FILE_NAME ".bt.settings" | ||||||
| @ -16,10 +16,10 @@ Cli* cli_alloc() { | |||||||
| 
 | 
 | ||||||
|     cli->session = NULL; |     cli->session = NULL; | ||||||
| 
 | 
 | ||||||
|     cli->mutex = osMutexNew(NULL); |     cli->mutex = furi_mutex_alloc(FuriMutexTypeNormal); | ||||||
|     furi_check(cli->mutex); |     furi_check(cli->mutex); | ||||||
| 
 | 
 | ||||||
|     cli->idle_sem = osSemaphoreNew(1, 0, NULL); |     cli->idle_sem = furi_semaphore_alloc(1, 0); | ||||||
| 
 | 
 | ||||||
|     return cli; |     return cli; | ||||||
| } | } | ||||||
| @ -35,7 +35,7 @@ char cli_getc(Cli* cli) { | |||||||
|     furi_assert(cli); |     furi_assert(cli); | ||||||
|     char c = 0; |     char c = 0; | ||||||
|     if(cli->session != NULL) { |     if(cli->session != NULL) { | ||||||
|         if(cli->session->rx((uint8_t*)&c, 1, osWaitForever) == 0) { |         if(cli->session->rx((uint8_t*)&c, 1, FuriWaitForever) == 0) { | ||||||
|             cli_reset(cli); |             cli_reset(cli); | ||||||
|         } |         } | ||||||
|     } else { |     } else { | ||||||
| @ -54,7 +54,7 @@ void cli_write(Cli* cli, const uint8_t* buffer, size_t size) { | |||||||
| size_t cli_read(Cli* cli, uint8_t* buffer, size_t size) { | size_t cli_read(Cli* cli, uint8_t* buffer, size_t size) { | ||||||
|     furi_assert(cli); |     furi_assert(cli); | ||||||
|     if(cli->session != NULL) { |     if(cli->session != NULL) { | ||||||
|         return cli->session->rx(buffer, size, osWaitForever); |         return cli->session->rx(buffer, size, FuriWaitForever); | ||||||
|     } else { |     } else { | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
| @ -69,17 +69,6 @@ size_t cli_read_timeout(Cli* cli, uint8_t* buffer, size_t size, uint32_t timeout | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool cli_cmd_interrupt_received(Cli* cli) { |  | ||||||
|     furi_assert(cli); |  | ||||||
|     char c = '\0'; |  | ||||||
|     if(cli->session != NULL) { |  | ||||||
|         if(cli->session->rx((uint8_t*)&c, 1, 0) == 1) { |  | ||||||
|             return c == CliSymbolAsciiETX; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     return false; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| bool cli_is_connected(Cli* cli) { | bool cli_is_connected(Cli* cli) { | ||||||
|     furi_assert(cli); |     furi_assert(cli); | ||||||
|     if(cli->session != NULL) { |     if(cli->session != NULL) { | ||||||
| @ -88,6 +77,19 @@ bool cli_is_connected(Cli* cli) { | |||||||
|     return false; |     return false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | bool cli_cmd_interrupt_received(Cli* cli) { | ||||||
|  |     furi_assert(cli); | ||||||
|  |     char c = '\0'; | ||||||
|  |     if(cli_is_connected(cli)) { | ||||||
|  |         if(cli->session->rx((uint8_t*)&c, 1, 0) == 1) { | ||||||
|  |             return c == CliSymbolAsciiETX; | ||||||
|  |         } | ||||||
|  |     } else { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |     return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void cli_print_usage(const char* cmd, const char* usage, const char* arg) { | void cli_print_usage(const char* cmd, const char* usage, const char* arg) { | ||||||
|     furi_assert(cmd); |     furi_assert(cmd); | ||||||
|     furi_assert(arg); |     furi_assert(arg); | ||||||
| @ -183,7 +185,7 @@ static void cli_execute_command(Cli* cli, CliCommand* command, string_t args) { | |||||||
| 
 | 
 | ||||||
|     // Ensure that we running alone
 |     // Ensure that we running alone
 | ||||||
|     if(!(command->flags & CliCommandFlagParallelSafe)) { |     if(!(command->flags & CliCommandFlagParallelSafe)) { | ||||||
|         Loader* loader = furi_record_open("loader"); |         Loader* loader = furi_record_open(RECORD_LOADER); | ||||||
|         bool safety_lock = loader_lock(loader); |         bool safety_lock = loader_lock(loader); | ||||||
|         if(safety_lock) { |         if(safety_lock) { | ||||||
|             // Execute command
 |             // Execute command
 | ||||||
| @ -192,7 +194,7 @@ static void cli_execute_command(Cli* cli, CliCommand* command, string_t args) { | |||||||
|         } else { |         } else { | ||||||
|             printf("Other application is running, close it first"); |             printf("Other application is running, close it first"); | ||||||
|         } |         } | ||||||
|         furi_record_close("loader"); |         furi_record_close(RECORD_LOADER); | ||||||
|     } else { |     } else { | ||||||
|         // Execute command
 |         // Execute command
 | ||||||
|         command->callback(cli, args, command->context); |         command->callback(cli, args, command->context); | ||||||
| @ -228,17 +230,17 @@ static void cli_handle_enter(Cli* cli) { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Search for command
 |     // Search for command
 | ||||||
|     furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK); |     furi_check(furi_mutex_acquire(cli->mutex, FuriWaitForever) == FuriStatusOk); | ||||||
|     CliCommand* cli_command_ptr = CliCommandTree_get(cli->commands, command); |     CliCommand* cli_command_ptr = CliCommandTree_get(cli->commands, command); | ||||||
| 
 | 
 | ||||||
|     if(cli_command_ptr) { |     if(cli_command_ptr) { | ||||||
|         CliCommand cli_command; |         CliCommand cli_command; | ||||||
|         memcpy(&cli_command, cli_command_ptr, sizeof(CliCommand)); |         memcpy(&cli_command, cli_command_ptr, sizeof(CliCommand)); | ||||||
|         furi_check(osMutexRelease(cli->mutex) == osOK); |         furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); | ||||||
|         cli_nl(cli); |         cli_nl(cli); | ||||||
|         cli_execute_command(cli, &cli_command, args); |         cli_execute_command(cli, &cli_command, args); | ||||||
|     } else { |     } else { | ||||||
|         furi_check(osMutexRelease(cli->mutex) == osOK); |         furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); | ||||||
|         cli_nl(cli); |         cli_nl(cli); | ||||||
|         printf( |         printf( | ||||||
|             "`%s` command not found, use `help` or `?` to list all available commands", |             "`%s` command not found, use `help` or `?` to list all available commands", | ||||||
| @ -339,7 +341,7 @@ void cli_process_input(Cli* cli) { | |||||||
|     if(in_chr == CliSymbolAsciiTab) { |     if(in_chr == CliSymbolAsciiTab) { | ||||||
|         cli_handle_autocomplete(cli); |         cli_handle_autocomplete(cli); | ||||||
|     } else if(in_chr == CliSymbolAsciiSOH) { |     } else if(in_chr == CliSymbolAsciiSOH) { | ||||||
|         osDelay(33); // We are too fast, Minicom is not ready yet
 |         furi_delay_ms(33); // We are too fast, Minicom is not ready yet
 | ||||||
|         cli_motd(); |         cli_motd(); | ||||||
|         cli_prompt(cli); |         cli_prompt(cli); | ||||||
|     } else if(in_chr == CliSymbolAsciiETX) { |     } else if(in_chr == CliSymbolAsciiETX) { | ||||||
| @ -406,9 +408,9 @@ void cli_add_command( | |||||||
|     c.context = context; |     c.context = context; | ||||||
|     c.flags = flags; |     c.flags = flags; | ||||||
| 
 | 
 | ||||||
|     furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK); |     furi_check(furi_mutex_acquire(cli->mutex, FuriWaitForever) == FuriStatusOk); | ||||||
|     CliCommandTree_set_at(cli->commands, name_str, c); |     CliCommandTree_set_at(cli->commands, name_str, c); | ||||||
|     furi_check(osMutexRelease(cli->mutex) == osOK); |     furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); | ||||||
| 
 | 
 | ||||||
|     string_clear(name_str); |     string_clear(name_str); | ||||||
| } | } | ||||||
| @ -423,9 +425,9 @@ void cli_delete_command(Cli* cli, const char* name) { | |||||||
|         name_replace = string_replace_str(name_str, " ", "_"); |         name_replace = string_replace_str(name_str, " ", "_"); | ||||||
|     } while(name_replace != STRING_FAILURE); |     } while(name_replace != STRING_FAILURE); | ||||||
| 
 | 
 | ||||||
|     furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK); |     furi_check(furi_mutex_acquire(cli->mutex, FuriWaitForever) == FuriStatusOk); | ||||||
|     CliCommandTree_erase(cli->commands, name_str); |     CliCommandTree_erase(cli->commands, name_str); | ||||||
|     furi_check(osMutexRelease(cli->mutex) == osOK); |     furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); | ||||||
| 
 | 
 | ||||||
|     string_clear(name_str); |     string_clear(name_str); | ||||||
| } | } | ||||||
| @ -433,7 +435,7 @@ void cli_delete_command(Cli* cli, const char* name) { | |||||||
| void cli_session_open(Cli* cli, void* session) { | void cli_session_open(Cli* cli, void* session) { | ||||||
|     furi_assert(cli); |     furi_assert(cli); | ||||||
| 
 | 
 | ||||||
|     furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK); |     furi_check(furi_mutex_acquire(cli->mutex, FuriWaitForever) == FuriStatusOk); | ||||||
|     cli->session = session; |     cli->session = session; | ||||||
|     if(cli->session != NULL) { |     if(cli->session != NULL) { | ||||||
|         cli->session->init(); |         cli->session->init(); | ||||||
| @ -441,20 +443,20 @@ void cli_session_open(Cli* cli, void* session) { | |||||||
|     } else { |     } else { | ||||||
|         furi_stdglue_set_thread_stdout_callback(NULL); |         furi_stdglue_set_thread_stdout_callback(NULL); | ||||||
|     } |     } | ||||||
|     osSemaphoreRelease(cli->idle_sem); |     furi_semaphore_release(cli->idle_sem); | ||||||
|     furi_check(osMutexRelease(cli->mutex) == osOK); |     furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void cli_session_close(Cli* cli) { | void cli_session_close(Cli* cli) { | ||||||
|     furi_assert(cli); |     furi_assert(cli); | ||||||
| 
 | 
 | ||||||
|     furi_check(osMutexAcquire(cli->mutex, osWaitForever) == osOK); |     furi_check(furi_mutex_acquire(cli->mutex, FuriWaitForever) == FuriStatusOk); | ||||||
|     if(cli->session != NULL) { |     if(cli->session != NULL) { | ||||||
|         cli->session->deinit(); |         cli->session->deinit(); | ||||||
|     } |     } | ||||||
|     cli->session = NULL; |     cli->session = NULL; | ||||||
|     furi_stdglue_set_thread_stdout_callback(NULL); |     furi_stdglue_set_thread_stdout_callback(NULL); | ||||||
|     furi_check(osMutexRelease(cli->mutex) == osOK); |     furi_check(furi_mutex_release(cli->mutex) == FuriStatusOk); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int32_t cli_srv(void* p) { | int32_t cli_srv(void* p) { | ||||||
| @ -464,7 +466,7 @@ int32_t cli_srv(void* p) { | |||||||
|     // Init basic cli commands
 |     // Init basic cli commands
 | ||||||
|     cli_commands_init(cli); |     cli_commands_init(cli); | ||||||
| 
 | 
 | ||||||
|     furi_record_create("cli", cli); |     furi_record_create(RECORD_CLI, cli); | ||||||
| 
 | 
 | ||||||
|     if(cli->session != NULL) { |     if(cli->session != NULL) { | ||||||
|         furi_stdglue_set_thread_stdout_callback(cli->session->tx_stdout); |         furi_stdglue_set_thread_stdout_callback(cli->session->tx_stdout); | ||||||
| @ -482,7 +484,7 @@ int32_t cli_srv(void* p) { | |||||||
|         if(cli->session != NULL) { |         if(cli->session != NULL) { | ||||||
|             cli_process_input(cli); |             cli_process_input(cli); | ||||||
|         } else { |         } else { | ||||||
|             furi_check(osSemaphoreAcquire(cli->idle_sem, osWaitForever) == osOK); |             furi_check(furi_semaphore_acquire(cli->idle_sem, FuriWaitForever) == FuriStatusOk); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -33,6 +33,8 @@ typedef enum { | |||||||
|     CliCommandFlagInsomniaSafe = (1 << 1), /**< Safe to run with insomnia mode on */ |     CliCommandFlagInsomniaSafe = (1 << 1), /**< Safe to run with insomnia mode on */ | ||||||
| } CliCommandFlag; | } CliCommandFlag; | ||||||
| 
 | 
 | ||||||
|  | #define RECORD_CLI "cli" | ||||||
|  | 
 | ||||||
| /** Cli type anonymous structure */ | /** Cli type anonymous structure */ | ||||||
| typedef struct Cli Cli; | typedef struct Cli Cli; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -166,13 +166,13 @@ void cli_command_vibro(Cli* cli, string_t args, void* context) { | |||||||
|     UNUSED(cli); |     UNUSED(cli); | ||||||
|     UNUSED(context); |     UNUSED(context); | ||||||
|     if(!string_cmp(args, "0")) { |     if(!string_cmp(args, "0")) { | ||||||
|         NotificationApp* notification = furi_record_open("notification"); |         NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); | ||||||
|         notification_message_block(notification, &sequence_reset_vibro); |         notification_message_block(notification, &sequence_reset_vibro); | ||||||
|         furi_record_close("notification"); |         furi_record_close(RECORD_NOTIFICATION); | ||||||
|     } else if(!string_cmp(args, "1")) { |     } else if(!string_cmp(args, "1")) { | ||||||
|         NotificationApp* notification = furi_record_open("notification"); |         NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); | ||||||
|         notification_message_block(notification, &sequence_set_vibro_on); |         notification_message_block(notification, &sequence_set_vibro_on); | ||||||
|         furi_record_close("notification"); |         furi_record_close(RECORD_NOTIFICATION); | ||||||
|     } else { |     } else { | ||||||
|         cli_print_usage("vibro", "<1|0>", string_get_cstr(args)); |         cli_print_usage("vibro", "<1|0>", string_get_cstr(args)); | ||||||
|     } |     } | ||||||
| @ -244,9 +244,9 @@ void cli_command_led(Cli* cli, string_t args, void* context) { | |||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     // Send notification
 |     // Send notification
 | ||||||
|     NotificationApp* notification = furi_record_open("notification"); |     NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); | ||||||
|     notification_internal_message_block(notification, ¬ification_sequence); |     notification_internal_message_block(notification, ¬ification_sequence); | ||||||
|     furi_record_close("notification"); |     furi_record_close(RECORD_NOTIFICATION); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void cli_command_ps(Cli* cli, string_t args, void* context) { | void cli_command_ps(Cli* cli, string_t args, void* context) { | ||||||
|  | |||||||
| @ -41,8 +41,8 @@ BPTREE_DEF2( | |||||||
| 
 | 
 | ||||||
| struct Cli { | struct Cli { | ||||||
|     CliCommandTree_t commands; |     CliCommandTree_t commands; | ||||||
|     osMutexId_t mutex; |     FuriMutex* mutex; | ||||||
|     osSemaphoreId_t idle_sem; |     FuriSemaphore* idle_sem; | ||||||
|     string_t last_line; |     string_t last_line; | ||||||
|     string_t line; |     string_t line; | ||||||
|     CliSession* session; |     CliSession* session; | ||||||
|  | |||||||
| @ -103,8 +103,8 @@ static int32_t vcp_worker(void* context) { | |||||||
| 
 | 
 | ||||||
|     while(1) { |     while(1) { | ||||||
|         uint32_t flags = |         uint32_t flags = | ||||||
|             furi_thread_flags_wait(VCP_THREAD_FLAG_ALL, osFlagsWaitAny, osWaitForever); |             furi_thread_flags_wait(VCP_THREAD_FLAG_ALL, FuriFlagWaitAny, FuriWaitForever); | ||||||
|         furi_assert((flags & osFlagsError) == 0); |         furi_assert((flags & FuriFlagError) == 0); | ||||||
| 
 | 
 | ||||||
|         // VCP session opened
 |         // VCP session opened
 | ||||||
|         if(flags & VcpEvtConnect) { |         if(flags & VcpEvtConnect) { | ||||||
| @ -113,7 +113,7 @@ static int32_t vcp_worker(void* context) { | |||||||
| #endif | #endif | ||||||
|             if(vcp->connected == false) { |             if(vcp->connected == false) { | ||||||
|                 vcp->connected = true; |                 vcp->connected = true; | ||||||
|                 xStreamBufferSend(vcp->rx_stream, &ascii_soh, 1, osWaitForever); |                 xStreamBufferSend(vcp->rx_stream, &ascii_soh, 1, FuriWaitForever); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -125,7 +125,7 @@ static int32_t vcp_worker(void* context) { | |||||||
|             if(vcp->connected == true) { |             if(vcp->connected == true) { | ||||||
|                 vcp->connected = false; |                 vcp->connected = false; | ||||||
|                 xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); |                 xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); | ||||||
|                 xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, osWaitForever); |                 xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -149,7 +149,7 @@ static int32_t vcp_worker(void* context) { | |||||||
| #endif | #endif | ||||||
|                 if(len > 0) { |                 if(len > 0) { | ||||||
|                     furi_check( |                     furi_check( | ||||||
|                         xStreamBufferSend(vcp->rx_stream, vcp->data_buffer, len, osWaitForever) == |                         xStreamBufferSend(vcp->rx_stream, vcp->data_buffer, len, FuriWaitForever) == | ||||||
|                         (size_t)len); |                         (size_t)len); | ||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
| @ -203,7 +203,7 @@ static int32_t vcp_worker(void* context) { | |||||||
|                 furi_hal_usb_set_config(vcp->usb_if_prev, NULL); |                 furi_hal_usb_set_config(vcp->usb_if_prev, NULL); | ||||||
|             } |             } | ||||||
|             xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); |             xStreamBufferReceive(vcp->tx_stream, vcp->data_buffer, USB_CDC_PKT_LEN, 0); | ||||||
|             xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, osWaitForever); |             xStreamBufferSend(vcp->rx_stream, &ascii_eot, 1, FuriWaitForever); | ||||||
|             break; |             break; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @ -262,7 +262,7 @@ static void cli_vcp_tx(const uint8_t* buffer, size_t size) { | |||||||
|         size_t batch_size = size; |         size_t batch_size = size; | ||||||
|         if(batch_size > USB_CDC_PKT_LEN) batch_size = USB_CDC_PKT_LEN; |         if(batch_size > USB_CDC_PKT_LEN) batch_size = USB_CDC_PKT_LEN; | ||||||
| 
 | 
 | ||||||
|         xStreamBufferSend(vcp->tx_stream, buffer, batch_size, osWaitForever); |         xStreamBufferSend(vcp->tx_stream, buffer, batch_size, FuriWaitForever); | ||||||
|         furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtStreamTx); |         furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtStreamTx); | ||||||
| #ifdef CLI_VCP_DEBUG | #ifdef CLI_VCP_DEBUG | ||||||
|         FURI_LOG_D(TAG, "tx %u", batch_size); |         FURI_LOG_D(TAG, "tx %u", batch_size); | ||||||
| @ -304,7 +304,7 @@ static void vcp_on_cdc_control_line(void* context, uint8_t state) { | |||||||
| static void vcp_on_cdc_rx(void* context) { | static void vcp_on_cdc_rx(void* context) { | ||||||
|     UNUSED(context); |     UNUSED(context); | ||||||
|     uint32_t ret = furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtRx); |     uint32_t ret = furi_thread_flags_set(furi_thread_get_id(vcp->thread), VcpEvtRx); | ||||||
|     furi_check((ret & osFlagsError) == 0); |     furi_check((ret & FuriFlagError) == 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void vcp_on_cdc_tx_complete(void* context) { | static void vcp_on_cdc_tx_complete(void* context) { | ||||||
|  | |||||||
| @ -317,9 +317,9 @@ static void crypto_cli(Cli* cli, string_t args, void* context) { | |||||||
| 
 | 
 | ||||||
| void crypto_on_system_start() { | void crypto_on_system_start() { | ||||||
| #ifdef SRV_CLI | #ifdef SRV_CLI | ||||||
|     Cli* cli = furi_record_open("cli"); |     Cli* cli = furi_record_open(RECORD_CLI); | ||||||
|     cli_add_command(cli, "crypto", CliCommandFlagDefault, crypto_cli, NULL); |     cli_add_command(cli, "crypto", CliCommandFlagDefault, crypto_cli, NULL); | ||||||
|     furi_record_close("cli"); |     furi_record_close(RECORD_CLI); | ||||||
| #else | #else | ||||||
|     UNUSED(crypto_cli); |     UNUSED(crypto_cli); | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| #include "furi/common_defines.h" | #include <core/common_defines.h> | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <furi_hal.h> | #include <furi_hal.h> | ||||||
| 
 | 
 | ||||||
| @ -55,10 +55,10 @@ static const NotificationSequence* blink_test_colors[] = { | |||||||
| 
 | 
 | ||||||
| static void blink_test_update(void* ctx) { | static void blink_test_update(void* ctx) { | ||||||
|     furi_assert(ctx); |     furi_assert(ctx); | ||||||
|     osMessageQueueId_t event_queue = ctx; |     FuriMessageQueue* event_queue = ctx; | ||||||
|     BlinkEvent event = {.type = BlinkEventTypeTick}; |     BlinkEvent event = {.type = BlinkEventTypeTick}; | ||||||
|     // It's OK to loose this event if system overloaded
 |     // It's OK to loose this event if system overloaded
 | ||||||
|     osMessageQueuePut(event_queue, &event, 0, 0); |     furi_message_queue_put(event_queue, &event, 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void blink_test_draw_callback(Canvas* canvas, void* ctx) { | static void blink_test_draw_callback(Canvas* canvas, void* ctx) { | ||||||
| @ -70,34 +70,34 @@ static void blink_test_draw_callback(Canvas* canvas, void* ctx) { | |||||||
| 
 | 
 | ||||||
| static void blink_test_input_callback(InputEvent* input_event, void* ctx) { | static void blink_test_input_callback(InputEvent* input_event, void* ctx) { | ||||||
|     furi_assert(ctx); |     furi_assert(ctx); | ||||||
|     osMessageQueueId_t event_queue = ctx; |     FuriMessageQueue* event_queue = ctx; | ||||||
| 
 | 
 | ||||||
|     BlinkEvent event = {.type = BlinkEventTypeInput, .input = *input_event}; |     BlinkEvent event = {.type = BlinkEventTypeInput, .input = *input_event}; | ||||||
|     osMessageQueuePut(event_queue, &event, 0, osWaitForever); |     furi_message_queue_put(event_queue, &event, FuriWaitForever); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int32_t blink_test_app(void* p) { | int32_t blink_test_app(void* p) { | ||||||
|     UNUSED(p); |     UNUSED(p); | ||||||
|     osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(BlinkEvent), NULL); |     FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(BlinkEvent)); | ||||||
| 
 | 
 | ||||||
|     // Configure view port
 |     // Configure view port
 | ||||||
|     ViewPort* view_port = view_port_alloc(); |     ViewPort* view_port = view_port_alloc(); | ||||||
|     view_port_draw_callback_set(view_port, blink_test_draw_callback, NULL); |     view_port_draw_callback_set(view_port, blink_test_draw_callback, NULL); | ||||||
|     view_port_input_callback_set(view_port, blink_test_input_callback, event_queue); |     view_port_input_callback_set(view_port, blink_test_input_callback, event_queue); | ||||||
|     osTimerId_t timer = osTimerNew(blink_test_update, osTimerPeriodic, event_queue, NULL); |     FuriTimer* timer = furi_timer_alloc(blink_test_update, FuriTimerTypePeriodic, event_queue); | ||||||
|     osTimerStart(timer, osKernelGetTickFreq()); |     furi_timer_start(timer, furi_kernel_get_tick_frequency()); | ||||||
| 
 | 
 | ||||||
|     // Register view port in GUI
 |     // Register view port in GUI
 | ||||||
|     Gui* gui = furi_record_open("gui"); |     Gui* gui = furi_record_open(RECORD_GUI); | ||||||
|     gui_add_view_port(gui, view_port, GuiLayerFullscreen); |     gui_add_view_port(gui, view_port, GuiLayerFullscreen); | ||||||
| 
 | 
 | ||||||
|     NotificationApp* notifications = furi_record_open("notification"); |     NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION); | ||||||
| 
 | 
 | ||||||
|     uint8_t state = 0; |     uint8_t state = 0; | ||||||
|     BlinkEvent event; |     BlinkEvent event; | ||||||
| 
 | 
 | ||||||
|     while(1) { |     while(1) { | ||||||
|         furi_check(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK); |         furi_check(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk); | ||||||
|         if(event.type == BlinkEventTypeInput) { |         if(event.type == BlinkEventTypeInput) { | ||||||
|             if((event.input.type == InputTypeShort) && (event.input.key == InputKeyBack)) { |             if((event.input.type == InputTypeShort) && (event.input.key == InputKeyBack)) { | ||||||
|                 break; |                 break; | ||||||
| @ -113,14 +113,14 @@ int32_t blink_test_app(void* p) { | |||||||
| 
 | 
 | ||||||
|     notification_message(notifications, &blink_test_sequence_hw_blink_stop); |     notification_message(notifications, &blink_test_sequence_hw_blink_stop); | ||||||
| 
 | 
 | ||||||
|     osTimerDelete(timer); |     furi_timer_free(timer); | ||||||
| 
 | 
 | ||||||
|     gui_remove_view_port(gui, view_port); |     gui_remove_view_port(gui, view_port); | ||||||
|     view_port_free(view_port); |     view_port_free(view_port); | ||||||
|     osMessageQueueDelete(event_queue); |     furi_message_queue_free(event_queue); | ||||||
| 
 | 
 | ||||||
|     furi_record_close("notification"); |     furi_record_close(RECORD_NOTIFICATION); | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
| 
 | 
 | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  | |||||||
| @ -127,7 +127,7 @@ DisplayTest* display_test_alloc() { | |||||||
| 
 | 
 | ||||||
|     View* view = NULL; |     View* view = NULL; | ||||||
| 
 | 
 | ||||||
|     instance->gui = furi_record_open("gui"); |     instance->gui = furi_record_open(RECORD_GUI); | ||||||
|     instance->view_dispatcher = view_dispatcher_alloc(); |     instance->view_dispatcher = view_dispatcher_alloc(); | ||||||
|     view_dispatcher_enable_queue(instance->view_dispatcher); |     view_dispatcher_enable_queue(instance->view_dispatcher); | ||||||
|     view_dispatcher_attach_to_gui( |     view_dispatcher_attach_to_gui( | ||||||
| @ -206,7 +206,7 @@ void display_test_free(DisplayTest* instance) { | |||||||
|     view_display_test_free(instance->view_display_test); |     view_display_test_free(instance->view_display_test); | ||||||
| 
 | 
 | ||||||
|     view_dispatcher_free(instance->view_dispatcher); |     view_dispatcher_free(instance->view_dispatcher); | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
| 
 | 
 | ||||||
|     free(instance); |     free(instance); | ||||||
| } | } | ||||||
|  | |||||||
| @ -9,7 +9,7 @@ typedef struct { | |||||||
| 
 | 
 | ||||||
| struct ViewDisplayTest { | struct ViewDisplayTest { | ||||||
|     View* view; |     View* view; | ||||||
|     osTimerId_t timer; |     FuriTimer* timer; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static void view_display_test_draw_callback_intro(Canvas* canvas, void* _model) { | static void view_display_test_draw_callback_intro(Canvas* canvas, void* _model) { | ||||||
| @ -138,12 +138,12 @@ static bool view_display_test_input_callback(InputEvent* event, void* context) { | |||||||
| 
 | 
 | ||||||
| static void view_display_test_enter(void* context) { | static void view_display_test_enter(void* context) { | ||||||
|     ViewDisplayTest* instance = context; |     ViewDisplayTest* instance = context; | ||||||
|     osTimerStart(instance->timer, osKernelGetTickFreq() / 32); |     furi_timer_start(instance->timer, furi_kernel_get_tick_frequency() / 32); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void view_display_test_exit(void* context) { | static void view_display_test_exit(void* context) { | ||||||
|     ViewDisplayTest* instance = context; |     ViewDisplayTest* instance = context; | ||||||
|     osTimerStop(instance->timer); |     furi_timer_stop(instance->timer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void view_display_test_timer_callback(void* context) { | static void view_display_test_timer_callback(void* context) { | ||||||
| @ -167,7 +167,7 @@ ViewDisplayTest* view_display_test_alloc() { | |||||||
|     view_set_exit_callback(instance->view, view_display_test_exit); |     view_set_exit_callback(instance->view, view_display_test_exit); | ||||||
| 
 | 
 | ||||||
|     instance->timer = |     instance->timer = | ||||||
|         osTimerNew(view_display_test_timer_callback, osTimerPeriodic, instance, NULL); |         furi_timer_alloc(view_display_test_timer_callback, FuriTimerTypePeriodic, instance); | ||||||
| 
 | 
 | ||||||
|     return instance; |     return instance; | ||||||
| } | } | ||||||
| @ -175,7 +175,7 @@ ViewDisplayTest* view_display_test_alloc() { | |||||||
| void view_display_test_free(ViewDisplayTest* instance) { | void view_display_test_free(ViewDisplayTest* instance) { | ||||||
|     furi_assert(instance); |     furi_assert(instance); | ||||||
| 
 | 
 | ||||||
|     osTimerDelete(instance->timer); |     furi_timer_free(instance->timer); | ||||||
|     view_free(instance->view); |     view_free(instance->view); | ||||||
|     free(instance); |     free(instance); | ||||||
| } | } | ||||||
|  | |||||||
| @ -29,8 +29,8 @@ FileBrowserApp* file_browser_app_alloc(char* arg) { | |||||||
|     UNUSED(arg); |     UNUSED(arg); | ||||||
|     FileBrowserApp* app = malloc(sizeof(FileBrowserApp)); |     FileBrowserApp* app = malloc(sizeof(FileBrowserApp)); | ||||||
| 
 | 
 | ||||||
|     app->gui = furi_record_open("gui"); |     app->gui = furi_record_open(RECORD_GUI); | ||||||
|     app->dialogs = furi_record_open("dialogs"); |     app->dialogs = furi_record_open(RECORD_DIALOGS); | ||||||
| 
 | 
 | ||||||
|     app->view_dispatcher = view_dispatcher_alloc(); |     app->view_dispatcher = view_dispatcher_alloc(); | ||||||
|     view_dispatcher_enable_queue(app->view_dispatcher); |     view_dispatcher_enable_queue(app->view_dispatcher); | ||||||
| @ -80,9 +80,9 @@ void file_browser_app_free(FileBrowserApp* app) { | |||||||
|     scene_manager_free(app->scene_manager); |     scene_manager_free(app->scene_manager); | ||||||
| 
 | 
 | ||||||
|     // Close records
 |     // Close records
 | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
|     furi_record_close("notification"); |     furi_record_close(RECORD_NOTIFICATION); | ||||||
|     furi_record_close("dialogs"); |     furi_record_close(RECORD_DIALOGS); | ||||||
| 
 | 
 | ||||||
|     string_clear(app->file_path); |     string_clear(app->file_path); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,6 @@ | |||||||
| #include "../file_browser_app_i.h" | #include "../file_browser_app_i.h" | ||||||
| #include "furi/check.h" | #include <core/check.h> | ||||||
| #include "furi/log.h" | #include <core/log.h> | ||||||
| #include "furi_hal.h" | #include "furi_hal.h" | ||||||
| #include "m-string.h" | #include "m-string.h" | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,8 @@ | |||||||
| #include "../file_browser_app_i.h" | #include "../file_browser_app_i.h" | ||||||
| #include "furi_hal.h" | 
 | ||||||
| #include "gui/modules/widget_elements/widget_element_i.h" | #include <furi_hal.h> | ||||||
|  | #include <gui/modules/widget_elements/widget_element_i.h> | ||||||
|  | #include <storage/storage.h> | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
|     file_browser_scene_start_ok_callback(GuiButtonType result, InputType type, void* context) { |     file_browser_scene_start_ok_callback(GuiButtonType result, InputType type, void* context) { | ||||||
| @ -17,7 +19,7 @@ bool file_browser_scene_start_on_event(void* context, SceneManagerEvent event) { | |||||||
|     bool consumed = false; |     bool consumed = false; | ||||||
| 
 | 
 | ||||||
|     if(event.type == SceneManagerEventTypeCustom) { |     if(event.type == SceneManagerEventTypeCustom) { | ||||||
|         string_set_str(app->file_path, "/any/badusb/demo_windows.txt"); |         string_set_str(app->file_path, ANY_PATH("badusb/demo_windows.txt")); | ||||||
|         scene_manager_next_scene(app->scene_manager, FileBrowserSceneBrowser); |         scene_manager_next_scene(app->scene_manager, FileBrowserSceneBrowser); | ||||||
|         consumed = true; |         consumed = true; | ||||||
|     } else if(event.type == SceneManagerEventTypeTick) { |     } else if(event.type == SceneManagerEventTypeTick) { | ||||||
|  | |||||||
| @ -55,13 +55,13 @@ static void keypad_test_render_callback(Canvas* canvas, void* ctx) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void keypad_test_input_callback(InputEvent* input_event, void* ctx) { | static void keypad_test_input_callback(InputEvent* input_event, void* ctx) { | ||||||
|     osMessageQueueId_t event_queue = ctx; |     FuriMessageQueue* event_queue = ctx; | ||||||
|     osMessageQueuePut(event_queue, input_event, 0, osWaitForever); |     furi_message_queue_put(event_queue, input_event, FuriWaitForever); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int32_t keypad_test_app(void* p) { | int32_t keypad_test_app(void* p) { | ||||||
|     UNUSED(p); |     UNUSED(p); | ||||||
|     osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(InputEvent), NULL); |     FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent)); | ||||||
|     furi_check(event_queue); |     furi_check(event_queue); | ||||||
| 
 | 
 | ||||||
|     KeypadTestState _state = {{false, false, false, false, false}, 0, 0, 0, 0, 0}; |     KeypadTestState _state = {{false, false, false, false, false}, 0, 0, 0, 0, 0}; | ||||||
| @ -78,11 +78,11 @@ int32_t keypad_test_app(void* p) { | |||||||
|     view_port_input_callback_set(view_port, keypad_test_input_callback, event_queue); |     view_port_input_callback_set(view_port, keypad_test_input_callback, event_queue); | ||||||
| 
 | 
 | ||||||
|     // Open GUI and register view_port
 |     // Open GUI and register view_port
 | ||||||
|     Gui* gui = furi_record_open("gui"); |     Gui* gui = furi_record_open(RECORD_GUI); | ||||||
|     gui_add_view_port(gui, view_port, GuiLayerFullscreen); |     gui_add_view_port(gui, view_port, GuiLayerFullscreen); | ||||||
| 
 | 
 | ||||||
|     InputEvent event; |     InputEvent event; | ||||||
|     while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) { |     while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) { | ||||||
|         KeypadTestState* state = (KeypadTestState*)acquire_mutex_block(&state_mutex); |         KeypadTestState* state = (KeypadTestState*)acquire_mutex_block(&state_mutex); | ||||||
|         FURI_LOG_I( |         FURI_LOG_I( | ||||||
|             TAG, |             TAG, | ||||||
| @ -146,10 +146,10 @@ int32_t keypad_test_app(void* p) { | |||||||
|     // remove & free all stuff created by app
 |     // remove & free all stuff created by app
 | ||||||
|     gui_remove_view_port(gui, view_port); |     gui_remove_view_port(gui, view_port); | ||||||
|     view_port_free(view_port); |     view_port_free(view_port); | ||||||
|     osMessageQueueDelete(event_queue); |     furi_message_queue_free(event_queue); | ||||||
|     delete_mutex(&state_mutex); |     delete_mutex(&state_mutex); | ||||||
| 
 | 
 | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
| 
 | 
 | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  | |||||||
| @ -65,13 +65,13 @@ static void text_box_test_render_callback(Canvas* canvas, void* ctx) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void text_box_test_input_callback(InputEvent* input_event, void* ctx) { | static void text_box_test_input_callback(InputEvent* input_event, void* ctx) { | ||||||
|     osMessageQueueId_t event_queue = ctx; |     FuriMessageQueue* event_queue = ctx; | ||||||
|     osMessageQueuePut(event_queue, input_event, 0, osWaitForever); |     furi_message_queue_put(event_queue, input_event, FuriWaitForever); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int32_t text_box_test_app(void* p) { | int32_t text_box_test_app(void* p) { | ||||||
|     UNUSED(p); |     UNUSED(p); | ||||||
|     osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(InputEvent), NULL); |     FuriMessageQueue* event_queue = furi_message_queue_alloc(32, sizeof(InputEvent)); | ||||||
|     furi_check(event_queue); |     furi_check(event_queue); | ||||||
| 
 | 
 | ||||||
|     TextBoxTestState _state = {.idx = 0}; |     TextBoxTestState _state = {.idx = 0}; | ||||||
| @ -88,12 +88,12 @@ int32_t text_box_test_app(void* p) { | |||||||
|     view_port_input_callback_set(view_port, text_box_test_input_callback, event_queue); |     view_port_input_callback_set(view_port, text_box_test_input_callback, event_queue); | ||||||
| 
 | 
 | ||||||
|     // Open GUI and register view_port
 |     // Open GUI and register view_port
 | ||||||
|     Gui* gui = furi_record_open("gui"); |     Gui* gui = furi_record_open(RECORD_GUI); | ||||||
|     gui_add_view_port(gui, view_port, GuiLayerFullscreen); |     gui_add_view_port(gui, view_port, GuiLayerFullscreen); | ||||||
| 
 | 
 | ||||||
|     uint32_t test_renders_num = COUNT_OF(text_box_test_render); |     uint32_t test_renders_num = COUNT_OF(text_box_test_render); | ||||||
|     InputEvent event; |     InputEvent event; | ||||||
|     while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) { |     while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) { | ||||||
|         TextBoxTestState* state = acquire_mutex_block(&state_mutex); |         TextBoxTestState* state = acquire_mutex_block(&state_mutex); | ||||||
| 
 | 
 | ||||||
|         if(event.type == InputTypeShort) { |         if(event.type == InputTypeShort) { | ||||||
| @ -118,10 +118,10 @@ int32_t text_box_test_app(void* p) { | |||||||
|     // remove & free all stuff created by app
 |     // remove & free all stuff created by app
 | ||||||
|     gui_remove_view_port(gui, view_port); |     gui_remove_view_port(gui, view_port); | ||||||
|     view_port_free(view_port); |     view_port_free(view_port); | ||||||
|     osMessageQueueDelete(event_queue); |     furi_message_queue_free(event_queue); | ||||||
|     delete_mutex(&state_mutex); |     delete_mutex(&state_mutex); | ||||||
| 
 | 
 | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
| 
 | 
 | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  | |||||||
| @ -150,8 +150,8 @@ static int32_t uart_echo_worker(void* context) { | |||||||
| 
 | 
 | ||||||
|     while(1) { |     while(1) { | ||||||
|         uint32_t events = |         uint32_t events = | ||||||
|             furi_thread_flags_wait(WORKER_EVENTS_MASK, osFlagsWaitAny, osWaitForever); |             furi_thread_flags_wait(WORKER_EVENTS_MASK, FuriFlagWaitAny, FuriWaitForever); | ||||||
|         furi_check((events & osFlagsError) == 0); |         furi_check((events & FuriFlagError) == 0); | ||||||
| 
 | 
 | ||||||
|         if(events & WorkerEventStop) break; |         if(events & WorkerEventStop) break; | ||||||
|         if(events & WorkerEventRx) { |         if(events & WorkerEventRx) { | ||||||
| @ -189,8 +189,8 @@ static UartEchoApp* uart_echo_app_alloc() { | |||||||
|     app->rx_stream = xStreamBufferCreate(2048, 1); |     app->rx_stream = xStreamBufferCreate(2048, 1); | ||||||
| 
 | 
 | ||||||
|     // Gui
 |     // Gui
 | ||||||
|     app->gui = furi_record_open("gui"); |     app->gui = furi_record_open(RECORD_GUI); | ||||||
|     app->notification = furi_record_open("notification"); |     app->notification = furi_record_open(RECORD_NOTIFICATION); | ||||||
| 
 | 
 | ||||||
|     // View dispatcher
 |     // View dispatcher
 | ||||||
|     app->view_dispatcher = view_dispatcher_alloc(); |     app->view_dispatcher = view_dispatcher_alloc(); | ||||||
| @ -256,8 +256,8 @@ static void uart_echo_app_free(UartEchoApp* app) { | |||||||
|     view_dispatcher_free(app->view_dispatcher); |     view_dispatcher_free(app->view_dispatcher); | ||||||
| 
 | 
 | ||||||
|     // Close gui record
 |     // Close gui record
 | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
|     furi_record_close("notification"); |     furi_record_close(RECORD_NOTIFICATION); | ||||||
|     app->gui = NULL; |     app->gui = NULL; | ||||||
| 
 | 
 | ||||||
|     vStreamBufferDelete(app->rx_stream); |     vStreamBufferDelete(app->rx_stream); | ||||||
|  | |||||||
| @ -29,17 +29,17 @@ static void usb_mouse_render_callback(Canvas* canvas, void* ctx) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void usb_mouse_input_callback(InputEvent* input_event, void* ctx) { | static void usb_mouse_input_callback(InputEvent* input_event, void* ctx) { | ||||||
|     osMessageQueueId_t event_queue = ctx; |     FuriMessageQueue* event_queue = ctx; | ||||||
| 
 | 
 | ||||||
|     UsbMouseEvent event; |     UsbMouseEvent event; | ||||||
|     event.type = EventTypeInput; |     event.type = EventTypeInput; | ||||||
|     event.input = *input_event; |     event.input = *input_event; | ||||||
|     osMessageQueuePut(event_queue, &event, 0, osWaitForever); |     furi_message_queue_put(event_queue, &event, FuriWaitForever); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int32_t usb_mouse_app(void* p) { | int32_t usb_mouse_app(void* p) { | ||||||
|     UNUSED(p); |     UNUSED(p); | ||||||
|     osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(UsbMouseEvent), NULL); |     FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(UsbMouseEvent)); | ||||||
|     furi_check(event_queue); |     furi_check(event_queue); | ||||||
|     ViewPort* view_port = view_port_alloc(); |     ViewPort* view_port = view_port_alloc(); | ||||||
| 
 | 
 | ||||||
| @ -51,14 +51,14 @@ int32_t usb_mouse_app(void* p) { | |||||||
|     view_port_input_callback_set(view_port, usb_mouse_input_callback, event_queue); |     view_port_input_callback_set(view_port, usb_mouse_input_callback, event_queue); | ||||||
| 
 | 
 | ||||||
|     // Open GUI and register view_port
 |     // Open GUI and register view_port
 | ||||||
|     Gui* gui = furi_record_open("gui"); |     Gui* gui = furi_record_open(RECORD_GUI); | ||||||
|     gui_add_view_port(gui, view_port, GuiLayerFullscreen); |     gui_add_view_port(gui, view_port, GuiLayerFullscreen); | ||||||
| 
 | 
 | ||||||
|     UsbMouseEvent event; |     UsbMouseEvent event; | ||||||
|     while(1) { |     while(1) { | ||||||
|         osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, osWaitForever); |         FuriStatus event_status = furi_message_queue_get(event_queue, &event, FuriWaitForever); | ||||||
| 
 | 
 | ||||||
|         if(event_status == osOK) { |         if(event_status == FuriStatusOk) { | ||||||
|             if(event.type == EventTypeInput) { |             if(event.type == EventTypeInput) { | ||||||
|                 if(event.input.type == InputTypeLong && event.input.key == InputKeyBack) { |                 if(event.input.type == InputTypeLong && event.input.key == InputKeyBack) { | ||||||
|                     break; |                     break; | ||||||
| @ -118,7 +118,7 @@ int32_t usb_mouse_app(void* p) { | |||||||
|     // remove & free all stuff created by app
 |     // remove & free all stuff created by app
 | ||||||
|     gui_remove_view_port(gui, view_port); |     gui_remove_view_port(gui, view_port); | ||||||
|     view_port_free(view_port); |     view_port_free(view_port); | ||||||
|     osMessageQueueDelete(event_queue); |     furi_message_queue_free(event_queue); | ||||||
| 
 | 
 | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  | |||||||
| @ -59,7 +59,7 @@ UsbTestApp* usb_test_app_alloc() { | |||||||
|     UsbTestApp* app = malloc(sizeof(UsbTestApp)); |     UsbTestApp* app = malloc(sizeof(UsbTestApp)); | ||||||
| 
 | 
 | ||||||
|     // Gui
 |     // Gui
 | ||||||
|     app->gui = furi_record_open("gui"); |     app->gui = furi_record_open(RECORD_GUI); | ||||||
| 
 | 
 | ||||||
|     // View dispatcher
 |     // View dispatcher
 | ||||||
|     app->view_dispatcher = view_dispatcher_alloc(); |     app->view_dispatcher = view_dispatcher_alloc(); | ||||||
| @ -106,7 +106,7 @@ void usb_test_app_free(UsbTestApp* app) { | |||||||
|     view_dispatcher_free(app->view_dispatcher); |     view_dispatcher_free(app->view_dispatcher); | ||||||
| 
 | 
 | ||||||
|     // Close gui record
 |     // Close gui record
 | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
|     app->gui = NULL; |     app->gui = NULL; | ||||||
| 
 | 
 | ||||||
|     // Free rest
 |     // Free rest
 | ||||||
|  | |||||||
| @ -18,13 +18,13 @@ void vibro_test_draw_callback(Canvas* canvas, void* ctx) { | |||||||
| 
 | 
 | ||||||
| void vibro_test_input_callback(InputEvent* input_event, void* ctx) { | void vibro_test_input_callback(InputEvent* input_event, void* ctx) { | ||||||
|     furi_assert(ctx); |     furi_assert(ctx); | ||||||
|     osMessageQueueId_t event_queue = ctx; |     FuriMessageQueue* event_queue = ctx; | ||||||
|     osMessageQueuePut(event_queue, input_event, 0, osWaitForever); |     furi_message_queue_put(event_queue, input_event, FuriWaitForever); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int32_t vibro_test_app(void* p) { | int32_t vibro_test_app(void* p) { | ||||||
|     UNUSED(p); |     UNUSED(p); | ||||||
|     osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(InputEvent), NULL); |     FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); | ||||||
| 
 | 
 | ||||||
|     // Configure view port
 |     // Configure view port
 | ||||||
|     ViewPort* view_port = view_port_alloc(); |     ViewPort* view_port = view_port_alloc(); | ||||||
| @ -32,14 +32,14 @@ int32_t vibro_test_app(void* p) { | |||||||
|     view_port_input_callback_set(view_port, vibro_test_input_callback, event_queue); |     view_port_input_callback_set(view_port, vibro_test_input_callback, event_queue); | ||||||
| 
 | 
 | ||||||
|     // Register view port in GUI
 |     // Register view port in GUI
 | ||||||
|     Gui* gui = furi_record_open("gui"); |     Gui* gui = furi_record_open(RECORD_GUI); | ||||||
|     gui_add_view_port(gui, view_port, GuiLayerFullscreen); |     gui_add_view_port(gui, view_port, GuiLayerFullscreen); | ||||||
| 
 | 
 | ||||||
|     NotificationApp* notification = furi_record_open("notification"); |     NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); | ||||||
| 
 | 
 | ||||||
|     InputEvent event; |     InputEvent event; | ||||||
| 
 | 
 | ||||||
|     while(osMessageQueueGet(event_queue, &event, NULL, osWaitForever) == osOK) { |     while(furi_message_queue_get(event_queue, &event, FuriWaitForever) == FuriStatusOk) { | ||||||
|         if(event.type == InputTypeShort && event.key == InputKeyBack) { |         if(event.type == InputTypeShort && event.key == InputKeyBack) { | ||||||
|             notification_message(notification, &sequence_reset_vibro); |             notification_message(notification, &sequence_reset_vibro); | ||||||
|             notification_message(notification, &sequence_reset_green); |             notification_message(notification, &sequence_reset_green); | ||||||
| @ -58,10 +58,10 @@ int32_t vibro_test_app(void* p) { | |||||||
| 
 | 
 | ||||||
|     gui_remove_view_port(gui, view_port); |     gui_remove_view_port(gui, view_port); | ||||||
|     view_port_free(view_port); |     view_port_free(view_port); | ||||||
|     osMessageQueueDelete(event_queue); |     furi_message_queue_free(event_queue); | ||||||
| 
 | 
 | ||||||
|     furi_record_close("notification"); |     furi_record_close(RECORD_NOTIFICATION); | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
| 
 | 
 | ||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  | |||||||
| @ -44,7 +44,7 @@ struct AnimationManager { | |||||||
|     FuriPubSubSubscription* pubsub_subscription_dolphin; |     FuriPubSubSubscription* pubsub_subscription_dolphin; | ||||||
|     BubbleAnimationView* animation_view; |     BubbleAnimationView* animation_view; | ||||||
|     OneShotView* one_shot_view; |     OneShotView* one_shot_view; | ||||||
|     osTimerId_t idle_animation_timer; |     FuriTimer* idle_animation_timer; | ||||||
|     StorageAnimation* current_animation; |     StorageAnimation* current_animation; | ||||||
|     AnimationManagerInteractCallback interact_callback; |     AnimationManagerInteractCallback interact_callback; | ||||||
|     AnimationManagerSetNewIdleAnimationCallback new_idle_callback; |     AnimationManagerSetNewIdleAnimationCallback new_idle_callback; | ||||||
| @ -137,9 +137,9 @@ void animation_manager_check_blocking_process(AnimationManager* animation_manage | |||||||
|         bool blocked = animation_manager_check_blocking(animation_manager); |         bool blocked = animation_manager_check_blocking(animation_manager); | ||||||
| 
 | 
 | ||||||
|         if(!blocked) { |         if(!blocked) { | ||||||
|             Dolphin* dolphin = furi_record_open("dolphin"); |             Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); | ||||||
|             DolphinStats stats = dolphin_stats(dolphin); |             DolphinStats stats = dolphin_stats(dolphin); | ||||||
|             furi_record_close("dolphin"); |             furi_record_close(RECORD_DOLPHIN); | ||||||
| 
 | 
 | ||||||
|             const StorageAnimationManifestInfo* manifest_info = |             const StorageAnimationManifestInfo* manifest_info = | ||||||
|                 animation_storage_get_meta(animation_manager->current_animation); |                 animation_storage_get_meta(animation_manager->current_animation); | ||||||
| @ -170,9 +170,9 @@ bool animation_manager_interact_process(AnimationManager* animation_manager) { | |||||||
|         animation_manager->levelup_pending = false; |         animation_manager->levelup_pending = false; | ||||||
|         animation_manager->levelup_active = true; |         animation_manager->levelup_active = true; | ||||||
|         animation_manager_switch_to_one_shot_view(animation_manager); |         animation_manager_switch_to_one_shot_view(animation_manager); | ||||||
|         Dolphin* dolphin = furi_record_open("dolphin"); |         Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); | ||||||
|         dolphin_upgrade_level(dolphin); |         dolphin_upgrade_level(dolphin); | ||||||
|         furi_record_close("dolphin"); |         furi_record_close(RECORD_DOLPHIN); | ||||||
|     } else if(animation_manager->levelup_active) { |     } else if(animation_manager->levelup_active) { | ||||||
|         animation_manager->levelup_active = false; |         animation_manager->levelup_active = false; | ||||||
|         animation_manager_start_new_idle(animation_manager); |         animation_manager_start_new_idle(animation_manager); | ||||||
| @ -198,14 +198,14 @@ static void animation_manager_start_new_idle(AnimationManager* animation_manager | |||||||
|     const BubbleAnimation* bubble_animation = |     const BubbleAnimation* bubble_animation = | ||||||
|         animation_storage_get_bubble_animation(animation_manager->current_animation); |         animation_storage_get_bubble_animation(animation_manager->current_animation); | ||||||
|     animation_manager->state = AnimationManagerStateIdle; |     animation_manager->state = AnimationManagerStateIdle; | ||||||
|     osTimerStart(animation_manager->idle_animation_timer, bubble_animation->duration * 1000); |     furi_timer_start(animation_manager->idle_animation_timer, bubble_animation->duration * 1000); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool animation_manager_check_blocking(AnimationManager* animation_manager) { | static bool animation_manager_check_blocking(AnimationManager* animation_manager) { | ||||||
|     furi_assert(animation_manager); |     furi_assert(animation_manager); | ||||||
| 
 | 
 | ||||||
|     StorageAnimation* blocking_animation = NULL; |     StorageAnimation* blocking_animation = NULL; | ||||||
|     Storage* storage = furi_record_open("storage"); |     Storage* storage = furi_record_open(RECORD_STORAGE); | ||||||
|     FS_Error sd_status = storage_sd_status(storage); |     FS_Error sd_status = storage_sd_status(storage); | ||||||
| 
 | 
 | ||||||
|     if(sd_status == FSE_INTERNAL) { |     if(sd_status == FSE_INTERNAL) { | ||||||
| @ -220,7 +220,7 @@ static bool animation_manager_check_blocking(AnimationManager* animation_manager | |||||||
|             furi_assert(blocking_animation); |             furi_assert(blocking_animation); | ||||||
|             animation_manager->sd_shown_sd_ok = true; |             animation_manager->sd_shown_sd_ok = true; | ||||||
|         } else if(!animation_manager->sd_shown_no_db) { |         } else if(!animation_manager->sd_shown_no_db) { | ||||||
|             bool db_exists = storage_common_stat(storage, "/ext/Manifest", NULL) == FSE_OK; |             bool db_exists = storage_common_stat(storage, EXT_PATH("Manifest"), NULL) == FSE_OK; | ||||||
|             if(!db_exists) { |             if(!db_exists) { | ||||||
|                 blocking_animation = animation_storage_find_animation(NO_DB_ANIMATION_NAME); |                 blocking_animation = animation_storage_find_animation(NO_DB_ANIMATION_NAME); | ||||||
|                 furi_assert(blocking_animation); |                 furi_assert(blocking_animation); | ||||||
| @ -234,9 +234,9 @@ static bool animation_manager_check_blocking(AnimationManager* animation_manager | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     Dolphin* dolphin = furi_record_open("dolphin"); |     Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); | ||||||
|     DolphinStats stats = dolphin_stats(dolphin); |     DolphinStats stats = dolphin_stats(dolphin); | ||||||
|     furi_record_close("dolphin"); |     furi_record_close(RECORD_DOLPHIN); | ||||||
|     if(!blocking_animation && stats.level_up_is_pending) { |     if(!blocking_animation && stats.level_up_is_pending) { | ||||||
|         blocking_animation = animation_storage_find_animation(NEW_MAIL_ANIMATION_NAME); |         blocking_animation = animation_storage_find_animation(NEW_MAIL_ANIMATION_NAME); | ||||||
|         furi_assert(blocking_animation); |         furi_assert(blocking_animation); | ||||||
| @ -246,13 +246,13 @@ static bool animation_manager_check_blocking(AnimationManager* animation_manager | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if(blocking_animation) { |     if(blocking_animation) { | ||||||
|         osTimerStop(animation_manager->idle_animation_timer); |         furi_timer_stop(animation_manager->idle_animation_timer); | ||||||
|         animation_manager_replace_current_animation(animation_manager, blocking_animation); |         animation_manager_replace_current_animation(animation_manager, blocking_animation); | ||||||
|         /* no timer starting because this is blocking animation */ |         /* no timer starting because this is blocking animation */ | ||||||
|         animation_manager->state = AnimationManagerStateBlocked; |         animation_manager->state = AnimationManagerStateBlocked; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|     return !!blocking_animation; |     return !!blocking_animation; | ||||||
| } | } | ||||||
| @ -283,19 +283,19 @@ AnimationManager* animation_manager_alloc(void) { | |||||||
|     string_init(animation_manager->freezed_animation_name); |     string_init(animation_manager->freezed_animation_name); | ||||||
| 
 | 
 | ||||||
|     animation_manager->idle_animation_timer = |     animation_manager->idle_animation_timer = | ||||||
|         osTimerNew(animation_manager_timer_callback, osTimerOnce, animation_manager, NULL); |         furi_timer_alloc(animation_manager_timer_callback, FuriTimerTypeOnce, animation_manager); | ||||||
|     bubble_animation_view_set_interact_callback( |     bubble_animation_view_set_interact_callback( | ||||||
|         animation_manager->animation_view, animation_manager_interact_callback, animation_manager); |         animation_manager->animation_view, animation_manager_interact_callback, animation_manager); | ||||||
| 
 | 
 | ||||||
|     Storage* storage = furi_record_open("storage"); |     Storage* storage = furi_record_open(RECORD_STORAGE); | ||||||
|     animation_manager->pubsub_subscription_storage = furi_pubsub_subscribe( |     animation_manager->pubsub_subscription_storage = furi_pubsub_subscribe( | ||||||
|         storage_get_pubsub(storage), animation_manager_check_blocking_callback, animation_manager); |         storage_get_pubsub(storage), animation_manager_check_blocking_callback, animation_manager); | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|     Dolphin* dolphin = furi_record_open("dolphin"); |     Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); | ||||||
|     animation_manager->pubsub_subscription_dolphin = furi_pubsub_subscribe( |     animation_manager->pubsub_subscription_dolphin = furi_pubsub_subscribe( | ||||||
|         dolphin_get_pubsub(dolphin), animation_manager_check_blocking_callback, animation_manager); |         dolphin_get_pubsub(dolphin), animation_manager_check_blocking_callback, animation_manager); | ||||||
|     furi_record_close("dolphin"); |     furi_record_close(RECORD_DOLPHIN); | ||||||
| 
 | 
 | ||||||
|     animation_manager->sd_shown_sd_ok = true; |     animation_manager->sd_shown_sd_ok = true; | ||||||
|     if(!animation_manager_check_blocking(animation_manager)) { |     if(!animation_manager_check_blocking(animation_manager)) { | ||||||
| @ -308,21 +308,21 @@ AnimationManager* animation_manager_alloc(void) { | |||||||
| void animation_manager_free(AnimationManager* animation_manager) { | void animation_manager_free(AnimationManager* animation_manager) { | ||||||
|     furi_assert(animation_manager); |     furi_assert(animation_manager); | ||||||
| 
 | 
 | ||||||
|     Dolphin* dolphin = furi_record_open("dolphin"); |     Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); | ||||||
|     furi_pubsub_unsubscribe( |     furi_pubsub_unsubscribe( | ||||||
|         dolphin_get_pubsub(dolphin), animation_manager->pubsub_subscription_dolphin); |         dolphin_get_pubsub(dolphin), animation_manager->pubsub_subscription_dolphin); | ||||||
|     furi_record_close("dolphin"); |     furi_record_close(RECORD_DOLPHIN); | ||||||
| 
 | 
 | ||||||
|     Storage* storage = furi_record_open("storage"); |     Storage* storage = furi_record_open(RECORD_STORAGE); | ||||||
|     furi_pubsub_unsubscribe( |     furi_pubsub_unsubscribe( | ||||||
|         storage_get_pubsub(storage), animation_manager->pubsub_subscription_storage); |         storage_get_pubsub(storage), animation_manager->pubsub_subscription_storage); | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|     string_clear(animation_manager->freezed_animation_name); |     string_clear(animation_manager->freezed_animation_name); | ||||||
|     View* animation_view = bubble_animation_get_view(animation_manager->animation_view); |     View* animation_view = bubble_animation_get_view(animation_manager->animation_view); | ||||||
|     view_stack_remove_view(animation_manager->view_stack, animation_view); |     view_stack_remove_view(animation_manager->view_stack, animation_view); | ||||||
|     bubble_animation_view_free(animation_manager->animation_view); |     bubble_animation_view_free(animation_manager->animation_view); | ||||||
|     osTimerDelete(animation_manager->idle_animation_timer); |     furi_timer_free(animation_manager->idle_animation_timer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| View* animation_manager_get_animation_view(AnimationManager* animation_manager) { | View* animation_manager_get_animation_view(AnimationManager* animation_manager) { | ||||||
| @ -340,16 +340,16 @@ static bool animation_manager_is_valid_idle_animation( | |||||||
|     bool result = true; |     bool result = true; | ||||||
| 
 | 
 | ||||||
|     if(!strcmp(info->name, BAD_BATTERY_ANIMATION_NAME)) { |     if(!strcmp(info->name, BAD_BATTERY_ANIMATION_NAME)) { | ||||||
|         Power* power = furi_record_open("power"); |         Power* power = furi_record_open(RECORD_POWER); | ||||||
|         bool battery_is_well = power_is_battery_healthy(power); |         bool battery_is_well = power_is_battery_healthy(power); | ||||||
|         furi_record_close("power"); |         furi_record_close(RECORD_POWER); | ||||||
| 
 | 
 | ||||||
|         result = !battery_is_well; |         result = !battery_is_well; | ||||||
|     } |     } | ||||||
|     if(!strcmp(info->name, NO_SD_ANIMATION_NAME)) { |     if(!strcmp(info->name, NO_SD_ANIMATION_NAME)) { | ||||||
|         Storage* storage = furi_record_open("storage"); |         Storage* storage = furi_record_open(RECORD_STORAGE); | ||||||
|         FS_Error sd_status = storage_sd_status(storage); |         FS_Error sd_status = storage_sd_status(storage); | ||||||
|         furi_record_close("storage"); |         furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|         result = (sd_status == FSE_NOT_READY); |         result = (sd_status == FSE_NOT_READY); | ||||||
|     } |     } | ||||||
| @ -370,9 +370,9 @@ static StorageAnimation* | |||||||
|     StorageAnimationList_init(animation_list); |     StorageAnimationList_init(animation_list); | ||||||
|     animation_storage_fill_animation_list(&animation_list); |     animation_storage_fill_animation_list(&animation_list); | ||||||
| 
 | 
 | ||||||
|     Dolphin* dolphin = furi_record_open("dolphin"); |     Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); | ||||||
|     DolphinStats stats = dolphin_stats(dolphin); |     DolphinStats stats = dolphin_stats(dolphin); | ||||||
|     furi_record_close("dolphin"); |     furi_record_close(RECORD_DOLPHIN); | ||||||
|     uint32_t whole_weight = 0; |     uint32_t whole_weight = 0; | ||||||
| 
 | 
 | ||||||
|     StorageAnimationList_it_t it; |     StorageAnimationList_it_t it; | ||||||
| @ -449,7 +449,7 @@ void animation_manager_unload_and_stall_animation(AnimationManager* animation_ma | |||||||
|         if(animation_manager->freezed_animation_time_left < 0) { |         if(animation_manager->freezed_animation_time_left < 0) { | ||||||
|             animation_manager->freezed_animation_time_left = 0; |             animation_manager->freezed_animation_time_left = 0; | ||||||
|         } |         } | ||||||
|         osTimerStop(animation_manager->idle_animation_timer); |         furi_timer_stop(animation_manager->idle_animation_timer); | ||||||
|     } else { |     } else { | ||||||
|         furi_assert(0); |         furi_assert(0); | ||||||
|     } |     } | ||||||
| @ -492,9 +492,9 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m | |||||||
|             StorageAnimation* restore_animation = animation_storage_find_animation( |             StorageAnimation* restore_animation = animation_storage_find_animation( | ||||||
|                 string_get_cstr(animation_manager->freezed_animation_name)); |                 string_get_cstr(animation_manager->freezed_animation_name)); | ||||||
|             if(restore_animation) { |             if(restore_animation) { | ||||||
|                 Dolphin* dolphin = furi_record_open("dolphin"); |                 Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); | ||||||
|                 DolphinStats stats = dolphin_stats(dolphin); |                 DolphinStats stats = dolphin_stats(dolphin); | ||||||
|                 furi_record_close("dolphin"); |                 furi_record_close(RECORD_DOLPHIN); | ||||||
|                 const StorageAnimationManifestInfo* manifest_info = |                 const StorageAnimationManifestInfo* manifest_info = | ||||||
|                     animation_storage_get_meta(restore_animation); |                     animation_storage_get_meta(restore_animation); | ||||||
|                 bool valid = animation_manager_is_valid_idle_animation(manifest_info, &stats); |                 bool valid = animation_manager_is_valid_idle_animation(manifest_info, &stats); | ||||||
| @ -504,13 +504,13 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m | |||||||
|                     animation_manager->state = AnimationManagerStateIdle; |                     animation_manager->state = AnimationManagerStateIdle; | ||||||
| 
 | 
 | ||||||
|                     if(animation_manager->freezed_animation_time_left) { |                     if(animation_manager->freezed_animation_time_left) { | ||||||
|                         osTimerStart( |                         furi_timer_start( | ||||||
|                             animation_manager->idle_animation_timer, |                             animation_manager->idle_animation_timer, | ||||||
|                             animation_manager->freezed_animation_time_left); |                             animation_manager->freezed_animation_time_left); | ||||||
|                     } else { |                     } else { | ||||||
|                         const BubbleAnimation* animation = animation_storage_get_bubble_animation( |                         const BubbleAnimation* animation = animation_storage_get_bubble_animation( | ||||||
|                             animation_manager->current_animation); |                             animation_manager->current_animation); | ||||||
|                         osTimerStart( |                         furi_timer_start( | ||||||
|                             animation_manager->idle_animation_timer, animation->duration * 1000); |                             animation_manager->idle_animation_timer, animation->duration * 1000); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @ -543,9 +543,9 @@ void animation_manager_load_and_continue_animation(AnimationManager* animation_m | |||||||
| static void animation_manager_switch_to_one_shot_view(AnimationManager* animation_manager) { | static void animation_manager_switch_to_one_shot_view(AnimationManager* animation_manager) { | ||||||
|     furi_assert(animation_manager); |     furi_assert(animation_manager); | ||||||
|     furi_assert(!animation_manager->one_shot_view); |     furi_assert(!animation_manager->one_shot_view); | ||||||
|     Dolphin* dolphin = furi_record_open("dolphin"); |     Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); | ||||||
|     DolphinStats stats = dolphin_stats(dolphin); |     DolphinStats stats = dolphin_stats(dolphin); | ||||||
|     furi_record_close("dolphin"); |     furi_record_close(RECORD_DOLPHIN); | ||||||
| 
 | 
 | ||||||
|     animation_manager->one_shot_view = one_shot_view_alloc(); |     animation_manager->one_shot_view = one_shot_view_alloc(); | ||||||
|     one_shot_view_set_interact_callback( |     one_shot_view_set_interact_callback( | ||||||
|  | |||||||
| @ -2,7 +2,7 @@ | |||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <flipper_format/flipper_format.h> | #include <flipper_format/flipper_format.h> | ||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <furi/dangerous_defines.h> | #include <core/dangerous_defines.h> | ||||||
| #include <storage/storage.h> | #include <storage/storage.h> | ||||||
| #include <gui/icon_i.h> | #include <gui/icon_i.h> | ||||||
| #include <m-string.h> | #include <m-string.h> | ||||||
| @ -14,7 +14,7 @@ | |||||||
| #include <assets_dolphin_blocking.h> | #include <assets_dolphin_blocking.h> | ||||||
| 
 | 
 | ||||||
| #define ANIMATION_META_FILE "meta.txt" | #define ANIMATION_META_FILE "meta.txt" | ||||||
| #define ANIMATION_DIR "/ext/dolphin" | #define ANIMATION_DIR EXT_PATH("dolphin") | ||||||
| #define ANIMATION_MANIFEST_FILE ANIMATION_DIR "/manifest.txt" | #define ANIMATION_MANIFEST_FILE ANIMATION_DIR "/manifest.txt" | ||||||
| #define TAG "AnimationStorage" | #define TAG "AnimationStorage" | ||||||
| 
 | 
 | ||||||
| @ -29,7 +29,7 @@ static bool animation_storage_load_single_manifest_info( | |||||||
|     furi_assert(manifest_info); |     furi_assert(manifest_info); | ||||||
| 
 | 
 | ||||||
|     bool result = false; |     bool result = false; | ||||||
|     Storage* storage = furi_record_open("storage"); |     Storage* storage = furi_record_open(RECORD_STORAGE); | ||||||
|     FlipperFormat* file = flipper_format_file_alloc(storage); |     FlipperFormat* file = flipper_format_file_alloc(storage); | ||||||
|     flipper_format_set_strict_mode(file, true); |     flipper_format_set_strict_mode(file, true); | ||||||
|     string_t read_string; |     string_t read_string; | ||||||
| @ -75,7 +75,7 @@ static bool animation_storage_load_single_manifest_info( | |||||||
|     string_clear(read_string); |     string_clear(read_string); | ||||||
|     flipper_format_free(file); |     flipper_format_free(file); | ||||||
| 
 | 
 | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| @ -84,7 +84,7 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis | |||||||
|     furi_assert(sizeof(StorageAnimationList_t) == sizeof(void*)); |     furi_assert(sizeof(StorageAnimationList_t) == sizeof(void*)); | ||||||
|     furi_assert(!StorageAnimationList_size(*animation_list)); |     furi_assert(!StorageAnimationList_size(*animation_list)); | ||||||
| 
 | 
 | ||||||
|     Storage* storage = furi_record_open("storage"); |     Storage* storage = furi_record_open(RECORD_STORAGE); | ||||||
|     FlipperFormat* file = flipper_format_file_alloc(storage); |     FlipperFormat* file = flipper_format_file_alloc(storage); | ||||||
|     /* Forbid skipping fields */ |     /* Forbid skipping fields */ | ||||||
|     flipper_format_set_strict_mode(file, true); |     flipper_format_set_strict_mode(file, true); | ||||||
| @ -134,7 +134,7 @@ void animation_storage_fill_animation_list(StorageAnimationList_t* animation_lis | |||||||
|         StorageAnimationList_push_back(*animation_list, (StorageAnimation*)&dolphin_internal[i]); |         StorageAnimationList_push_back(*animation_list, (StorageAnimation*)&dolphin_internal[i]); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| StorageAnimation* animation_storage_find_animation(const char* name) { | StorageAnimation* animation_storage_find_animation(const char* name) { | ||||||
| @ -434,7 +434,7 @@ static BubbleAnimation* animation_storage_load_animation(const char* name) { | |||||||
|     uint32_t height = 0; |     uint32_t height = 0; | ||||||
|     uint32_t width = 0; |     uint32_t width = 0; | ||||||
|     uint32_t* u32array = NULL; |     uint32_t* u32array = NULL; | ||||||
|     Storage* storage = furi_record_open("storage"); |     Storage* storage = furi_record_open(RECORD_STORAGE); | ||||||
|     FlipperFormat* ff = flipper_format_file_alloc(storage); |     FlipperFormat* ff = flipper_format_file_alloc(storage); | ||||||
|     /* Forbid skipping fields */ |     /* Forbid skipping fields */ | ||||||
|     flipper_format_set_strict_mode(ff, true); |     flipper_format_set_strict_mode(ff, true); | ||||||
|  | |||||||
| @ -11,9 +11,7 @@ | |||||||
| #include <gui/icon_i.h> | #include <gui/icon_i.h> | ||||||
| #include <input/input.h> | #include <input/input.h> | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <FreeRTOS.h> | #include <core/dangerous_defines.h> | ||||||
| #include <timers.h> |  | ||||||
| #include <furi/dangerous_defines.h> |  | ||||||
| 
 | 
 | ||||||
| #define ACTIVE_SHIFT 2 | #define ACTIVE_SHIFT 2 | ||||||
| 
 | 
 | ||||||
| @ -31,7 +29,7 @@ typedef struct { | |||||||
| 
 | 
 | ||||||
| struct BubbleAnimationView { | struct BubbleAnimationView { | ||||||
|     View* view; |     View* view; | ||||||
|     osTimerId_t timer; |     FuriTimer* timer; | ||||||
|     BubbleAnimationInteractCallback interact_callback; |     BubbleAnimationInteractCallback interact_callback; | ||||||
|     void* interact_callback_context; |     void* interact_callback_context; | ||||||
| }; | }; | ||||||
| @ -192,7 +190,7 @@ static void bubble_animation_activate_right_now(BubbleAnimationView* view) { | |||||||
|     view_commit_model(view->view, true); |     view_commit_model(view->view, true); | ||||||
| 
 | 
 | ||||||
|     if(frame_rate) { |     if(frame_rate) { | ||||||
|         osTimerStart(view->timer, 1000 / frame_rate); |         furi_timer_start(view->timer, 1000 / frame_rate); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -294,21 +292,21 @@ static void bubble_animation_enter(void* context) { | |||||||
|     view_commit_model(view->view, false); |     view_commit_model(view->view, false); | ||||||
| 
 | 
 | ||||||
|     if(frame_rate) { |     if(frame_rate) { | ||||||
|         osTimerStart(view->timer, 1000 / frame_rate); |         furi_timer_start(view->timer, 1000 / frame_rate); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void bubble_animation_exit(void* context) { | static void bubble_animation_exit(void* context) { | ||||||
|     furi_assert(context); |     furi_assert(context); | ||||||
|     BubbleAnimationView* view = context; |     BubbleAnimationView* view = context; | ||||||
|     osTimerStop(view->timer); |     furi_timer_stop(view->timer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| BubbleAnimationView* bubble_animation_view_alloc(void) { | BubbleAnimationView* bubble_animation_view_alloc(void) { | ||||||
|     BubbleAnimationView* view = malloc(sizeof(BubbleAnimationView)); |     BubbleAnimationView* view = malloc(sizeof(BubbleAnimationView)); | ||||||
|     view->view = view_alloc(); |     view->view = view_alloc(); | ||||||
|     view->interact_callback = NULL; |     view->interact_callback = NULL; | ||||||
|     view->timer = osTimerNew(bubble_animation_timer_callback, osTimerPeriodic, view, NULL); |     view->timer = furi_timer_alloc(bubble_animation_timer_callback, FuriTimerTypePeriodic, view); | ||||||
| 
 | 
 | ||||||
|     view_allocate_model(view->view, ViewModelTypeLocking, sizeof(BubbleAnimationViewModel)); |     view_allocate_model(view->view, ViewModelTypeLocking, sizeof(BubbleAnimationViewModel)); | ||||||
|     view_set_context(view->view, view); |     view_set_context(view->view, view); | ||||||
| @ -369,7 +367,7 @@ void bubble_animation_view_set_animation( | |||||||
|     model->active_cycle = 0; |     model->active_cycle = 0; | ||||||
|     view_commit_model(view->view, true); |     view_commit_model(view->view, true); | ||||||
| 
 | 
 | ||||||
|     osTimerStart(view->timer, 1000 / new_animation->icon_animation.frame_rate); |     furi_timer_start(view->timer, 1000 / new_animation->icon_animation.frame_rate); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void bubble_animation_freeze(BubbleAnimationView* view) { | void bubble_animation_freeze(BubbleAnimationView* view) { | ||||||
| @ -381,7 +379,7 @@ void bubble_animation_freeze(BubbleAnimationView* view) { | |||||||
|     model->freeze_frame = bubble_animation_clone_first_frame(&model->current->icon_animation); |     model->freeze_frame = bubble_animation_clone_first_frame(&model->current->icon_animation); | ||||||
|     model->current = NULL; |     model->current = NULL; | ||||||
|     view_commit_model(view->view, false); |     view_commit_model(view->view, false); | ||||||
|     osTimerStop(view->timer); |     furi_timer_stop(view->timer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void bubble_animation_unfreeze(BubbleAnimationView* view) { | void bubble_animation_unfreeze(BubbleAnimationView* view) { | ||||||
| @ -395,7 +393,7 @@ void bubble_animation_unfreeze(BubbleAnimationView* view) { | |||||||
|     frame_rate = model->current->icon_animation.frame_rate; |     frame_rate = model->current->icon_animation.frame_rate; | ||||||
|     view_commit_model(view->view, true); |     view_commit_model(view->view, true); | ||||||
| 
 | 
 | ||||||
|     osTimerStart(view->timer, 1000 / frame_rate); |     furi_timer_start(view->timer, 1000 / frame_rate); | ||||||
|     bubble_animation_activate(view, false); |     bubble_animation_activate(view, false); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -15,6 +15,7 @@ | |||||||
| #include "desktop/views/desktop_view_pin_timeout.h" | #include "desktop/views/desktop_view_pin_timeout.h" | ||||||
| #include "desktop_i.h" | #include "desktop_i.h" | ||||||
| #include "helpers/pin_lock.h" | #include "helpers/pin_lock.h" | ||||||
|  | #include "helpers/slideshow_filename.h" | ||||||
| 
 | 
 | ||||||
| static void desktop_auto_lock_arm(Desktop*); | static void desktop_auto_lock_arm(Desktop*); | ||||||
| static void desktop_auto_lock_inhibit(Desktop*); | static void desktop_auto_lock_inhibit(Desktop*); | ||||||
| @ -93,12 +94,12 @@ static void desktop_auto_lock_timer_callback(void* context) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void desktop_start_auto_lock_timer(Desktop* desktop) { | static void desktop_start_auto_lock_timer(Desktop* desktop) { | ||||||
|     osTimerStart( |     furi_timer_start( | ||||||
|         desktop->auto_lock_timer, furi_hal_ms_to_ticks(desktop->settings.auto_lock_delay_ms)); |         desktop->auto_lock_timer, furi_ms_to_ticks(desktop->settings.auto_lock_delay_ms)); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void desktop_stop_auto_lock_timer(Desktop* desktop) { | static void desktop_stop_auto_lock_timer(Desktop* desktop) { | ||||||
|     osTimerStop(desktop->auto_lock_timer); |     furi_timer_stop(desktop->auto_lock_timer); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void desktop_auto_lock_arm(Desktop* desktop) { | static void desktop_auto_lock_arm(Desktop* desktop) { | ||||||
| @ -127,9 +128,9 @@ void desktop_lock(Desktop* desktop) { | |||||||
| 
 | 
 | ||||||
| void desktop_unlock(Desktop* desktop) { | void desktop_unlock(Desktop* desktop) { | ||||||
|     view_port_enabled_set(desktop->lock_viewport, false); |     view_port_enabled_set(desktop->lock_viewport, false); | ||||||
|     Gui* gui = furi_record_open("gui"); |     Gui* gui = furi_record_open(RECORD_GUI); | ||||||
|     gui_set_lockdown(gui, false); |     gui_set_lockdown(gui, false); | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
|     desktop_view_locked_unlock(desktop->locked_view); |     desktop_view_locked_unlock(desktop->locked_view); | ||||||
|     scene_manager_search_and_switch_to_previous_scene(desktop->scene_manager, DesktopSceneMain); |     scene_manager_search_and_switch_to_previous_scene(desktop->scene_manager, DesktopSceneMain); | ||||||
|     desktop_auto_lock_arm(desktop); |     desktop_auto_lock_arm(desktop); | ||||||
| @ -139,7 +140,7 @@ Desktop* desktop_alloc() { | |||||||
|     Desktop* desktop = malloc(sizeof(Desktop)); |     Desktop* desktop = malloc(sizeof(Desktop)); | ||||||
| 
 | 
 | ||||||
|     desktop->animation_manager = animation_manager_alloc(); |     desktop->animation_manager = animation_manager_alloc(); | ||||||
|     desktop->gui = furi_record_open("gui"); |     desktop->gui = furi_record_open(RECORD_GUI); | ||||||
|     desktop->scene_thread = furi_thread_alloc(); |     desktop->scene_thread = furi_thread_alloc(); | ||||||
|     desktop->view_dispatcher = view_dispatcher_alloc(); |     desktop->view_dispatcher = view_dispatcher_alloc(); | ||||||
|     desktop->scene_manager = scene_manager_alloc(&desktop_scene_handlers, desktop); |     desktop->scene_manager = scene_manager_alloc(&desktop_scene_handlers, desktop); | ||||||
| @ -218,21 +219,21 @@ Desktop* desktop_alloc() { | |||||||
|     gui_add_view_port(desktop->gui, desktop->lock_viewport, GuiLayerStatusBarLeft); |     gui_add_view_port(desktop->gui, desktop->lock_viewport, GuiLayerStatusBarLeft); | ||||||
| 
 | 
 | ||||||
|     // Special case: autostart application is already running
 |     // Special case: autostart application is already running
 | ||||||
|     desktop->loader = furi_record_open("loader"); |     desktop->loader = furi_record_open(RECORD_LOADER); | ||||||
|     if(loader_is_locked(desktop->loader) && |     if(loader_is_locked(desktop->loader) && | ||||||
|        animation_manager_is_animation_loaded(desktop->animation_manager)) { |        animation_manager_is_animation_loaded(desktop->animation_manager)) { | ||||||
|         animation_manager_unload_and_stall_animation(desktop->animation_manager); |         animation_manager_unload_and_stall_animation(desktop->animation_manager); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     desktop->notification = furi_record_open("notification"); |     desktop->notification = furi_record_open(RECORD_NOTIFICATION); | ||||||
|     desktop->app_start_stop_subscription = furi_pubsub_subscribe( |     desktop->app_start_stop_subscription = furi_pubsub_subscribe( | ||||||
|         loader_get_pubsub(desktop->loader), desktop_loader_callback, desktop); |         loader_get_pubsub(desktop->loader), desktop_loader_callback, desktop); | ||||||
| 
 | 
 | ||||||
|     desktop->input_events_pubsub = furi_record_open("input_events"); |     desktop->input_events_pubsub = furi_record_open(RECORD_INPUT_EVENTS); | ||||||
|     desktop->input_events_subscription = NULL; |     desktop->input_events_subscription = NULL; | ||||||
| 
 | 
 | ||||||
|     desktop->auto_lock_timer = |     desktop->auto_lock_timer = | ||||||
|         osTimerNew(desktop_auto_lock_timer_callback, osTimerOnce, desktop, NULL); |         furi_timer_alloc(desktop_auto_lock_timer_callback, FuriTimerTypeOnce, desktop); | ||||||
| 
 | 
 | ||||||
|     return desktop; |     return desktop; | ||||||
| } | } | ||||||
| @ -250,9 +251,9 @@ void desktop_free(Desktop* desktop) { | |||||||
| 
 | 
 | ||||||
|     desktop->loader = NULL; |     desktop->loader = NULL; | ||||||
|     desktop->input_events_pubsub = NULL; |     desktop->input_events_pubsub = NULL; | ||||||
|     furi_record_close("loader"); |     furi_record_close(RECORD_LOADER); | ||||||
|     furi_record_close("notification"); |     furi_record_close(RECORD_NOTIFICATION); | ||||||
|     furi_record_close("input_events"); |     furi_record_close(RECORD_INPUT_EVENTS); | ||||||
| 
 | 
 | ||||||
|     view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdMain); |     view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdMain); | ||||||
|     view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdLockMenu); |     view_dispatcher_remove_view(desktop->view_dispatcher, DesktopViewIdLockMenu); | ||||||
| @ -276,22 +277,22 @@ void desktop_free(Desktop* desktop) { | |||||||
|     popup_free(desktop->hw_mismatch_popup); |     popup_free(desktop->hw_mismatch_popup); | ||||||
|     desktop_view_pin_timeout_free(desktop->pin_timeout_view); |     desktop_view_pin_timeout_free(desktop->pin_timeout_view); | ||||||
| 
 | 
 | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
|     desktop->gui = NULL; |     desktop->gui = NULL; | ||||||
| 
 | 
 | ||||||
|     furi_thread_free(desktop->scene_thread); |     furi_thread_free(desktop->scene_thread); | ||||||
| 
 | 
 | ||||||
|     furi_record_close("menu"); |     furi_record_close("menu"); | ||||||
| 
 | 
 | ||||||
|     osTimerDelete(desktop->auto_lock_timer); |     furi_timer_free(desktop->auto_lock_timer); | ||||||
| 
 | 
 | ||||||
|     free(desktop); |     free(desktop); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static bool desktop_check_file_flag(const char* flag_path) { | static bool desktop_check_file_flag(const char* flag_path) { | ||||||
|     Storage* storage = furi_record_open("storage"); |     Storage* storage = furi_record_open(RECORD_STORAGE); | ||||||
|     bool exists = storage_common_stat(storage, flag_path, NULL) == FSE_OK; |     bool exists = storage_common_stat(storage, flag_path, NULL) == FSE_OK; | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
| 
 | 
 | ||||||
|     return exists; |     return exists; | ||||||
| } | } | ||||||
| @ -318,7 +319,7 @@ int32_t desktop_srv(void* p) { | |||||||
|         desktop_lock(desktop); |         desktop_lock(desktop); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if(desktop_check_file_flag("/int/slideshow")) { |     if(desktop_check_file_flag(SLIDESHOW_FS_PATH)) { | ||||||
|         scene_manager_next_scene(desktop->scene_manager, DesktopSceneSlideshow); |         scene_manager_next_scene(desktop->scene_manager, DesktopSceneSlideshow); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -67,7 +67,7 @@ struct Desktop { | |||||||
|     FuriPubSubSubscription* app_start_stop_subscription; |     FuriPubSubSubscription* app_start_stop_subscription; | ||||||
|     FuriPubSub* input_events_pubsub; |     FuriPubSub* input_events_pubsub; | ||||||
|     FuriPubSubSubscription* input_events_subscription; |     FuriPubSubSubscription* input_events_subscription; | ||||||
|     osTimerId_t auto_lock_timer; |     FuriTimer* auto_lock_timer; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Desktop* desktop_alloc(); | Desktop* desktop_alloc(); | ||||||
|  | |||||||
| @ -1,12 +1,16 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include "desktop_settings_filename.h" | ||||||
|  | 
 | ||||||
| #include <furi_hal.h> | #include <furi_hal.h> | ||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <stdbool.h> | #include <stdbool.h> | ||||||
| #include <toolbox/saved_struct.h> | #include <toolbox/saved_struct.h> | ||||||
|  | #include <storage/storage.h> | ||||||
| 
 | 
 | ||||||
| #define DESKTOP_SETTINGS_VER (4) | #define DESKTOP_SETTINGS_VER (4) | ||||||
| #define DESKTOP_SETTINGS_PATH "/int/desktop.settings" | 
 | ||||||
|  | #define DESKTOP_SETTINGS_PATH INT_PATH(DESKTOP_SETTINGS_FILE_NAME) | ||||||
| #define DESKTOP_SETTINGS_MAGIC (0x17) | #define DESKTOP_SETTINGS_MAGIC (0x17) | ||||||
| #define PIN_MAX_LENGTH 12 | #define PIN_MAX_LENGTH 12 | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -21,7 +21,7 @@ static bool desktop_settings_back_event_callback(void* context) { | |||||||
| DesktopSettingsApp* desktop_settings_app_alloc() { | DesktopSettingsApp* desktop_settings_app_alloc() { | ||||||
|     DesktopSettingsApp* app = malloc(sizeof(DesktopSettingsApp)); |     DesktopSettingsApp* app = malloc(sizeof(DesktopSettingsApp)); | ||||||
| 
 | 
 | ||||||
|     app->gui = furi_record_open("gui"); |     app->gui = furi_record_open(RECORD_GUI); | ||||||
|     app->view_dispatcher = view_dispatcher_alloc(); |     app->view_dispatcher = view_dispatcher_alloc(); | ||||||
|     app->scene_manager = scene_manager_alloc(&desktop_settings_scene_handlers, app); |     app->scene_manager = scene_manager_alloc(&desktop_settings_scene_handlers, app); | ||||||
|     view_dispatcher_enable_queue(app->view_dispatcher); |     view_dispatcher_enable_queue(app->view_dispatcher); | ||||||
| @ -83,7 +83,7 @@ void desktop_settings_app_free(DesktopSettingsApp* app) { | |||||||
|     view_dispatcher_free(app->view_dispatcher); |     view_dispatcher_free(app->view_dispatcher); | ||||||
|     scene_manager_free(app->scene_manager); |     scene_manager_free(app->scene_manager); | ||||||
|     // Records
 |     // Records
 | ||||||
|     furi_record_close("gui"); |     furi_record_close(RECORD_GUI); | ||||||
|     free(app); |     free(app); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -0,0 +1,3 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #define DESKTOP_SETTINGS_FILE_NAME ".desktop.settings" | ||||||
| @ -1,5 +1,5 @@ | |||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <furi/check.h> | #include <core/check.h> | ||||||
| #include <gui/scene_manager.h> | #include <gui/scene_manager.h> | ||||||
| #include "../../helpers/pin_lock.h" | #include "../../helpers/pin_lock.h" | ||||||
| #include "../desktop_settings_app.h" | #include "../desktop_settings_app.h" | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <furi/check.h> | #include <core/check.h> | ||||||
| #include <gui/scene_manager.h> | #include <gui/scene_manager.h> | ||||||
| #include <gui/modules/popup.h> | #include <gui/modules/popup.h> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <furi/check.h> | #include <core/check.h> | ||||||
| #include <gui/scene_manager.h> | #include <gui/scene_manager.h> | ||||||
| 
 | 
 | ||||||
| #include "desktop/desktop_settings/desktop_settings.h" | #include "desktop/desktop_settings/desktop_settings.h" | ||||||
|  | |||||||
| @ -1,5 +1,5 @@ | |||||||
| #include <stdint.h> | #include <stdint.h> | ||||||
| #include <furi/check.h> | #include <core/check.h> | ||||||
| #include <gui/scene_manager.h> | #include <gui/scene_manager.h> | ||||||
| 
 | 
 | ||||||
| #include "../desktop_settings_app.h" | #include "../desktop_settings_app.h" | ||||||
|  | |||||||
| @ -25,9 +25,9 @@ void desktop_settings_scene_pin_setup_done_on_enter(void* context) { | |||||||
| 
 | 
 | ||||||
|     app->settings.pin_code = app->pincode_buffer; |     app->settings.pin_code = app->pincode_buffer; | ||||||
|     SAVE_DESKTOP_SETTINGS(&app->settings); |     SAVE_DESKTOP_SETTINGS(&app->settings); | ||||||
|     NotificationApp* notification = furi_record_open("notification"); |     NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); | ||||||
|     notification_message(notification, &sequence_single_vibro); |     notification_message(notification, &sequence_single_vibro); | ||||||
|     furi_record_close("notification"); |     furi_record_close(RECORD_NOTIFICATION); | ||||||
| 
 | 
 | ||||||
|     desktop_view_pin_input_set_context(app->pin_input_view, app); |     desktop_view_pin_input_set_context(app->pin_input_view, app); | ||||||
|     desktop_view_pin_input_set_back_callback(app->pin_input_view, NULL); |     desktop_view_pin_input_set_back_callback(app->pin_input_view, NULL); | ||||||
|  | |||||||
| @ -44,9 +44,9 @@ static const uint8_t desktop_helpers_fails_timeout[] = { | |||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| void desktop_pin_lock_error_notify() { | void desktop_pin_lock_error_notify() { | ||||||
|     NotificationApp* notification = furi_record_open("notification"); |     NotificationApp* notification = furi_record_open(RECORD_NOTIFICATION); | ||||||
|     notification_message(notification, &sequence_pin_fail); |     notification_message(notification, &sequence_pin_fail); | ||||||
|     furi_record_close("notification"); |     furi_record_close(RECORD_NOTIFICATION); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t desktop_pin_lock_get_fail_timeout() { | uint32_t desktop_pin_lock_get_fail_timeout() { | ||||||
| @ -67,9 +67,9 @@ void desktop_pin_lock(DesktopSettings* settings) { | |||||||
| 
 | 
 | ||||||
|     furi_hal_rtc_set_pin_fails(0); |     furi_hal_rtc_set_pin_fails(0); | ||||||
|     furi_hal_rtc_set_flag(FuriHalRtcFlagLock); |     furi_hal_rtc_set_flag(FuriHalRtcFlagLock); | ||||||
|     Cli* cli = furi_record_open("cli"); |     Cli* cli = furi_record_open(RECORD_CLI); | ||||||
|     cli_session_close(cli); |     cli_session_close(cli); | ||||||
|     furi_record_close("cli"); |     furi_record_close(RECORD_CLI); | ||||||
|     settings->is_locked = 1; |     settings->is_locked = 1; | ||||||
|     SAVE_DESKTOP_SETTINGS(settings); |     SAVE_DESKTOP_SETTINGS(settings); | ||||||
| } | } | ||||||
| @ -78,9 +78,9 @@ void desktop_pin_unlock(DesktopSettings* settings) { | |||||||
|     furi_assert(settings); |     furi_assert(settings); | ||||||
| 
 | 
 | ||||||
|     furi_hal_rtc_reset_flag(FuriHalRtcFlagLock); |     furi_hal_rtc_reset_flag(FuriHalRtcFlagLock); | ||||||
|     Cli* cli = furi_record_open("cli"); |     Cli* cli = furi_record_open(RECORD_CLI); | ||||||
|     cli_session_open(cli, &cli_vcp); |     cli_session_open(cli, &cli_vcp); | ||||||
|     furi_record_close("cli"); |     furi_record_close(RECORD_CLI); | ||||||
|     settings->is_locked = 0; |     settings->is_locked = 0; | ||||||
|     SAVE_DESKTOP_SETTINGS(settings); |     SAVE_DESKTOP_SETTINGS(settings); | ||||||
| } | } | ||||||
| @ -103,9 +103,9 @@ void desktop_pin_lock_init(DesktopSettings* settings) { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if(desktop_pin_lock_is_locked()) { |     if(desktop_pin_lock_is_locked()) { | ||||||
|         Cli* cli = furi_record_open("cli"); |         Cli* cli = furi_record_open(RECORD_CLI); | ||||||
|         cli_session_close(cli); |         cli_session_close(cli); | ||||||
|         furi_record_close("cli"); |         furi_record_close(RECORD_CLI); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ | |||||||
| #include <storage/storage.h> | #include <storage/storage.h> | ||||||
| #include <gui/icon.h> | #include <gui/icon.h> | ||||||
| #include <gui/icon_i.h> | #include <gui/icon_i.h> | ||||||
| #include <furi/dangerous_defines.h> | #include <core/dangerous_defines.h> | ||||||
| 
 | 
 | ||||||
| #define SLIDESHOW_MAGIC 0x72676468 | #define SLIDESHOW_MAGIC 0x72676468 | ||||||
| #define SLIDESHOW_MAX_SUPPORTED_VERSION 1 | #define SLIDESHOW_MAX_SUPPORTED_VERSION 1 | ||||||
| @ -52,7 +52,7 @@ void slideshow_free(Slideshow* slideshow) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool slideshow_load(Slideshow* slideshow, const char* fspath) { | bool slideshow_load(Slideshow* slideshow, const char* fspath) { | ||||||
|     Storage* storage = furi_record_open("storage"); |     Storage* storage = furi_record_open(RECORD_STORAGE); | ||||||
|     File* slideshow_file = storage_file_alloc(storage); |     File* slideshow_file = storage_file_alloc(storage); | ||||||
|     slideshow->loaded = false; |     slideshow->loaded = false; | ||||||
|     do { |     do { | ||||||
| @ -86,7 +86,7 @@ bool slideshow_load(Slideshow* slideshow, const char* fspath) { | |||||||
|         } |         } | ||||||
|     } while(false); |     } while(false); | ||||||
|     storage_file_free(slideshow_file); |     storage_file_free(slideshow_file); | ||||||
|     furi_record_close("storage"); |     furi_record_close(RECORD_STORAGE); | ||||||
|     return slideshow->loaded; |     return slideshow->loaded; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										3
									
								
								applications/desktop/helpers/slideshow_filename.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								applications/desktop/helpers/slideshow_filename.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #define SLIDESHOW_FILE_NAME ".slideshow" | ||||||
| @ -22,7 +22,7 @@ void desktop_scene_debug_on_enter(void* context) { | |||||||
| 
 | 
 | ||||||
| bool desktop_scene_debug_on_event(void* context, SceneManagerEvent event) { | bool desktop_scene_debug_on_event(void* context, SceneManagerEvent event) { | ||||||
|     Desktop* desktop = (Desktop*)context; |     Desktop* desktop = (Desktop*)context; | ||||||
|     Dolphin* dolphin = furi_record_open("dolphin"); |     Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); | ||||||
|     bool consumed = false; |     bool consumed = false; | ||||||
| 
 | 
 | ||||||
|     if(event.type == SceneManagerEventTypeCustom) { |     if(event.type == SceneManagerEventTypeCustom) { | ||||||
| @ -55,7 +55,7 @@ bool desktop_scene_debug_on_event(void* context, SceneManagerEvent event) { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     furi_record_close("dolphin"); |     furi_record_close(RECORD_DOLPHIN); | ||||||
|     return consumed; |     return consumed; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -47,9 +47,9 @@ void desktop_scene_locked_on_enter(void* context) { | |||||||
|     if(state == SCENE_LOCKED_FIRST_ENTER) { |     if(state == SCENE_LOCKED_FIRST_ENTER) { | ||||||
|         bool pin_locked = desktop_pin_lock_is_locked(); |         bool pin_locked = desktop_pin_lock_is_locked(); | ||||||
|         view_port_enabled_set(desktop->lock_viewport, true); |         view_port_enabled_set(desktop->lock_viewport, true); | ||||||
|         Gui* gui = furi_record_open("gui"); |         Gui* gui = furi_record_open(RECORD_GUI); | ||||||
|         gui_set_lockdown(gui, true); |         gui_set_lockdown(gui, true); | ||||||
|         furi_record_close("gui"); |         furi_record_close(RECORD_GUI); | ||||||
| 
 | 
 | ||||||
|         if(pin_locked) { |         if(pin_locked) { | ||||||
|             LOAD_DESKTOP_SETTINGS(&desktop->settings); |             LOAD_DESKTOP_SETTINGS(&desktop->settings); | ||||||
|  | |||||||
| @ -24,13 +24,13 @@ typedef struct { | |||||||
| } DesktopScenePinInputState; | } DesktopScenePinInputState; | ||||||
| 
 | 
 | ||||||
| static void desktop_scene_locked_light_red(bool value) { | static void desktop_scene_locked_light_red(bool value) { | ||||||
|     NotificationApp* app = furi_record_open("notification"); |     NotificationApp* app = furi_record_open(RECORD_NOTIFICATION); | ||||||
|     if(value) { |     if(value) { | ||||||
|         notification_message(app, &sequence_set_only_red_255); |         notification_message(app, &sequence_set_only_red_255); | ||||||
|     } else { |     } else { | ||||||
|         notification_message(app, &sequence_reset_red); |         notification_message(app, &sequence_reset_red); | ||||||
|     } |     } | ||||||
|     furi_record_close("notification"); |     furi_record_close(RECORD_NOTIFICATION); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| @ -150,7 +150,7 @@ void desktop_scene_pin_input_on_exit(void* context) { | |||||||
|         desktop->scene_manager, DesktopScenePinInput); |         desktop->scene_manager, DesktopScenePinInput); | ||||||
|     xTimerStop(state->timer, portMAX_DELAY); |     xTimerStop(state->timer, portMAX_DELAY); | ||||||
|     while(xTimerIsTimerActive(state->timer)) { |     while(xTimerIsTimerActive(state->timer)) { | ||||||
|         furi_hal_delay_ms(1); |         furi_delay_tick(1); | ||||||
|     } |     } | ||||||
|     xTimerDelete(state->timer, portMAX_DELAY); |     xTimerDelete(state->timer, portMAX_DELAY); | ||||||
|     free(state); |     free(state); | ||||||
|  | |||||||
| @ -3,6 +3,7 @@ | |||||||
| #include "../desktop_i.h" | #include "../desktop_i.h" | ||||||
| #include "../views/desktop_view_slideshow.h" | #include "../views/desktop_view_slideshow.h" | ||||||
| #include "../views/desktop_events.h" | #include "../views/desktop_events.h" | ||||||
|  | #include <power/power_service/power.h> | ||||||
| 
 | 
 | ||||||
| void desktop_scene_slideshow_callback(DesktopEvent event, void* context) { | void desktop_scene_slideshow_callback(DesktopEvent event, void* context) { | ||||||
|     Desktop* desktop = (Desktop*)context; |     Desktop* desktop = (Desktop*)context; | ||||||
| @ -22,16 +23,23 @@ bool desktop_scene_slideshow_on_event(void* context, SceneManagerEvent event) { | |||||||
|     Desktop* desktop = (Desktop*)context; |     Desktop* desktop = (Desktop*)context; | ||||||
|     bool consumed = false; |     bool consumed = false; | ||||||
|     Storage* storage = NULL; |     Storage* storage = NULL; | ||||||
|  |     Power* power = NULL; | ||||||
| 
 | 
 | ||||||
|     if(event.type == SceneManagerEventTypeCustom) { |     if(event.type == SceneManagerEventTypeCustom) { | ||||||
|         switch(event.event) { |         switch(event.event) { | ||||||
|         case DesktopSlideshowCompleted: |         case DesktopSlideshowCompleted: | ||||||
|             storage = furi_record_open("storage"); |             storage = furi_record_open(RECORD_STORAGE); | ||||||
|             storage_common_remove(storage, "/int/slideshow"); |             storage_common_remove(storage, SLIDESHOW_FS_PATH); | ||||||
|             furi_record_close("storage"); |             furi_record_close(RECORD_STORAGE); | ||||||
|             scene_manager_previous_scene(desktop->scene_manager); |             scene_manager_previous_scene(desktop->scene_manager); | ||||||
|             consumed = true; |             consumed = true; | ||||||
|             break; |             break; | ||||||
|  |         case DesktopSlideshowPoweroff: | ||||||
|  |             power = furi_record_open(RECORD_POWER); | ||||||
|  |             power_off(power); | ||||||
|  |             furi_record_close(RECORD_POWER); | ||||||
|  |             consumed = true; | ||||||
|  |             break; | ||||||
| 
 | 
 | ||||||
|         default: |         default: | ||||||
|             break; |             break; | ||||||
|  | |||||||
| @ -35,6 +35,7 @@ typedef enum { | |||||||
|     DesktopAnimationEventInteractAnimation, |     DesktopAnimationEventInteractAnimation, | ||||||
| 
 | 
 | ||||||
|     DesktopSlideshowCompleted, |     DesktopSlideshowCompleted, | ||||||
|  |     DesktopSlideshowPoweroff, | ||||||
| 
 | 
 | ||||||
|     // Global events
 |     // Global events
 | ||||||
|     DesktopGlobalBeforeAppStarted, |     DesktopGlobalBeforeAppStarted, | ||||||
|  | |||||||
| @ -79,9 +79,9 @@ void desktop_debug_render(Canvas* canvas, void* model) { | |||||||
| 
 | 
 | ||||||
|     } else { |     } else { | ||||||
|         char buffer[64]; |         char buffer[64]; | ||||||
|         Dolphin* dolphin = furi_record_open("dolphin"); |         Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); | ||||||
|         DolphinStats stats = dolphin_stats(dolphin); |         DolphinStats stats = dolphin_stats(dolphin); | ||||||
|         furi_record_close("dolphin"); |         furi_record_close(RECORD_DOLPHIN); | ||||||
| 
 | 
 | ||||||
|         uint32_t current_lvl = stats.level; |         uint32_t current_lvl = stats.level; | ||||||
|         uint32_t remaining = dolphin_state_xp_to_levelup(m->icounter); |         uint32_t remaining = dolphin_state_xp_to_levelup(m->icounter); | ||||||
| @ -175,7 +175,7 @@ void desktop_debug_free(DesktopDebugView* debug_view) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void desktop_debug_get_dolphin_data(DesktopDebugView* debug_view) { | void desktop_debug_get_dolphin_data(DesktopDebugView* debug_view) { | ||||||
|     Dolphin* dolphin = furi_record_open("dolphin"); |     Dolphin* dolphin = furi_record_open(RECORD_DOLPHIN); | ||||||
|     DolphinStats stats = dolphin_stats(dolphin); |     DolphinStats stats = dolphin_stats(dolphin); | ||||||
|     with_view_model( |     with_view_model( | ||||||
|         debug_view->view, (DesktopDebugViewModel * model) { |         debug_view->view, (DesktopDebugViewModel * model) { | ||||||
| @ -185,7 +185,7 @@ void desktop_debug_get_dolphin_data(DesktopDebugView* debug_view) { | |||||||
|             return true; |             return true; | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|     furi_record_close("dolphin"); |     furi_record_close(RECORD_DOLPHIN); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void desktop_debug_reset_screen_idx(DesktopDebugView* debug_view) { | void desktop_debug_reset_screen_idx(DesktopDebugView* debug_view) { | ||||||
|  | |||||||
| @ -206,7 +206,7 @@ DesktopViewLocked* desktop_view_locked_alloc() { | |||||||
| 
 | 
 | ||||||
| void desktop_view_locked_free(DesktopViewLocked* locked_view) { | void desktop_view_locked_free(DesktopViewLocked* locked_view) { | ||||||
|     furi_assert(locked_view); |     furi_assert(locked_view); | ||||||
|     osTimerDelete(locked_view->timer); |     furi_timer_free(locked_view->timer); | ||||||
|     view_free(locked_view->view); |     view_free(locked_view->view); | ||||||
|     free(locked_view); |     free(locked_view); | ||||||
| } | } | ||||||
|  | |||||||
| @ -99,6 +99,6 @@ DesktopMainView* desktop_main_alloc() { | |||||||
| void desktop_main_free(DesktopMainView* main_view) { | void desktop_main_free(DesktopMainView* main_view) { | ||||||
|     furi_assert(main_view); |     furi_assert(main_view); | ||||||
|     view_free(main_view->view); |     view_free(main_view->view); | ||||||
|     osTimerDelete(main_view->poweroff_timer); |     furi_timer_free(main_view->poweroff_timer); | ||||||
|     free(main_view); |     free(main_view); | ||||||
| } | } | ||||||
|  | |||||||
| @ -214,7 +214,7 @@ void desktop_view_pin_input_free(DesktopViewPinInput* pin_input) { | |||||||
| 
 | 
 | ||||||
|     xTimerStop(pin_input->timer, portMAX_DELAY); |     xTimerStop(pin_input->timer, portMAX_DELAY); | ||||||
|     while(xTimerIsTimerActive(pin_input->timer)) { |     while(xTimerIsTimerActive(pin_input->timer)) { | ||||||
|         furi_hal_delay_ms(1); |         furi_delay_tick(1); | ||||||
|     } |     } | ||||||
|     xTimerDelete(pin_input->timer, portMAX_DELAY); |     xTimerDelete(pin_input->timer, portMAX_DELAY); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -2,14 +2,19 @@ | |||||||
| #include <furi_hal.h> | #include <furi_hal.h> | ||||||
| #include <gui/elements.h> | #include <gui/elements.h> | ||||||
| 
 | 
 | ||||||
| #include "../desktop_i.h" |  | ||||||
| #include "desktop_view_slideshow.h" | #include "desktop_view_slideshow.h" | ||||||
|  | #include "../desktop_i.h" | ||||||
| #include "../helpers/slideshow.h" | #include "../helpers/slideshow.h" | ||||||
|  | #include "../helpers/slideshow_filename.h" | ||||||
|  | 
 | ||||||
|  | #define DESKTOP_SLIDESHOW_POWEROFF_SHORT 5000 | ||||||
|  | #define DESKTOP_SLIDESHOW_POWEROFF_LONG (60 * 60 * 1000) | ||||||
| 
 | 
 | ||||||
| struct DesktopSlideshowView { | struct DesktopSlideshowView { | ||||||
|     View* view; |     View* view; | ||||||
|     DesktopSlideshowViewCallback callback; |     DesktopSlideshowViewCallback callback; | ||||||
|     void* context; |     void* context; | ||||||
|  |     FuriTimer* timer; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
| @ -50,17 +55,35 @@ static bool desktop_view_slideshow_input(InputEvent* event, void* context) { | |||||||
|             instance->callback(DesktopSlideshowCompleted, instance->context); |             instance->callback(DesktopSlideshowCompleted, instance->context); | ||||||
|         } |         } | ||||||
|         view_commit_model(instance->view, true); |         view_commit_model(instance->view, true); | ||||||
|  |     } else if(event->key == InputKeyOk) { | ||||||
|  |         if(event->type == InputTypePress) { | ||||||
|  |             furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_SHORT); | ||||||
|  |         } else if(event->type == InputTypeRelease) { | ||||||
|  |             furi_timer_stop(instance->timer); | ||||||
|  |             furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_LONG); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static void desktop_first_start_timer_callback(void* context) { | ||||||
|  |     DesktopSlideshowView* instance = context; | ||||||
|  |     instance->callback(DesktopSlideshowPoweroff, instance->context); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static void desktop_view_slideshow_enter(void* context) { | static void desktop_view_slideshow_enter(void* context) { | ||||||
|     DesktopSlideshowView* instance = context; |     DesktopSlideshowView* instance = context; | ||||||
| 
 | 
 | ||||||
|  |     furi_assert(instance->timer == NULL); | ||||||
|  |     instance->timer = | ||||||
|  |         furi_timer_alloc(desktop_first_start_timer_callback, FuriTimerTypeOnce, instance); | ||||||
|  | 
 | ||||||
|  |     furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_LONG); | ||||||
|  | 
 | ||||||
|     DesktopSlideshowViewModel* model = view_get_model(instance->view); |     DesktopSlideshowViewModel* model = view_get_model(instance->view); | ||||||
|     model->slideshow = slideshow_alloc(); |     model->slideshow = slideshow_alloc(); | ||||||
|     if(!slideshow_load(model->slideshow, "/int/slideshow")) { |     if(!slideshow_load(model->slideshow, SLIDESHOW_FS_PATH)) { | ||||||
|         instance->callback(DesktopSlideshowCompleted, instance->context); |         instance->callback(DesktopSlideshowCompleted, instance->context); | ||||||
|     } |     } | ||||||
|     view_commit_model(instance->view, false); |     view_commit_model(instance->view, false); | ||||||
| @ -69,6 +92,10 @@ static void desktop_view_slideshow_enter(void* context) { | |||||||
| static void desktop_view_slideshow_exit(void* context) { | static void desktop_view_slideshow_exit(void* context) { | ||||||
|     DesktopSlideshowView* instance = context; |     DesktopSlideshowView* instance = context; | ||||||
| 
 | 
 | ||||||
|  |     furi_timer_stop(instance->timer); | ||||||
|  |     furi_timer_free(instance->timer); | ||||||
|  |     instance->timer = NULL; | ||||||
|  | 
 | ||||||
|     DesktopSlideshowViewModel* model = view_get_model(instance->view); |     DesktopSlideshowViewModel* model = view_get_model(instance->view); | ||||||
|     slideshow_free(model->slideshow); |     slideshow_free(model->slideshow); | ||||||
|     view_commit_model(instance->view, false); |     view_commit_model(instance->view, false); | ||||||
|  | |||||||
| @ -3,6 +3,9 @@ | |||||||
| #include <gui/view.h> | #include <gui/view.h> | ||||||
| 
 | 
 | ||||||
| #include "desktop_events.h" | #include "desktop_events.h" | ||||||
|  | #include "../helpers/slideshow_filename.h" | ||||||
|  | 
 | ||||||
|  | #define SLIDESHOW_FS_PATH INT_PATH(SLIDESHOW_FILE_NAME) | ||||||
| 
 | 
 | ||||||
| typedef struct DesktopSlideshowView DesktopSlideshowView; | typedef struct DesktopSlideshowView DesktopSlideshowView; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -6,7 +6,7 @@ | |||||||
| 
 | 
 | ||||||
| static DialogsApp* dialogs_app_alloc() { | static DialogsApp* dialogs_app_alloc() { | ||||||
|     DialogsApp* app = malloc(sizeof(DialogsApp)); |     DialogsApp* app = malloc(sizeof(DialogsApp)); | ||||||
|     app->message_queue = osMessageQueueNew(8, sizeof(DialogsAppMessage), NULL); |     app->message_queue = furi_message_queue_alloc(8, sizeof(DialogsAppMessage)); | ||||||
| 
 | 
 | ||||||
|     return app; |     return app; | ||||||
| } | } | ||||||
| @ -29,11 +29,11 @@ static void dialogs_app_process_message(DialogsApp* app, DialogsAppMessage* mess | |||||||
| int32_t dialogs_srv(void* p) { | int32_t dialogs_srv(void* p) { | ||||||
|     UNUSED(p); |     UNUSED(p); | ||||||
|     DialogsApp* app = dialogs_app_alloc(); |     DialogsApp* app = dialogs_app_alloc(); | ||||||
|     furi_record_create("dialogs", app); |     furi_record_create(RECORD_DIALOGS, app); | ||||||
| 
 | 
 | ||||||
|     DialogsAppMessage message; |     DialogsAppMessage message; | ||||||
|     while(1) { |     while(1) { | ||||||
|         if(osMessageQueueGet(app->message_queue, &message, NULL, osWaitForever) == osOK) { |         if(furi_message_queue_get(app->message_queue, &message, FuriWaitForever) == FuriStatusOk) { | ||||||
|             dialogs_app_process_message(app, &message); |             dialogs_app_process_message(app, &message); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -9,6 +9,8 @@ extern "C" { | |||||||
| 
 | 
 | ||||||
| /****************** COMMON ******************/ | /****************** COMMON ******************/ | ||||||
| 
 | 
 | ||||||
|  | #define RECORD_DIALOGS "dialogs" | ||||||
|  | 
 | ||||||
| typedef struct DialogsApp DialogsApp; | typedef struct DialogsApp DialogsApp; | ||||||
| 
 | 
 | ||||||
| /****************** FILE BROWSER ******************/ | /****************** FILE BROWSER ******************/ | ||||||
|  | |||||||
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