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
|
||||||
|
|||||||
24
.github/workflows/lint_c.yml
vendored
24
.github/workflows/lint_c.yml
vendored
@ -1,6 +1,6 @@
|
|||||||
name: 'Lint C/C++ with clang-format'
|
name: 'Lint C/C++ with clang-format'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
@ -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.
|
||||||
|
|||||||
14
.github/workflows/lint_python.yml
vendored
14
.github/workflows/lint_python.yml
vendored
@ -1,6 +1,6 @@
|
|||||||
name: 'Python Lint'
|
name: 'Python Lint'
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- dev
|
- dev
|
||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -118,4 +118,4 @@ void slideshow_draw(Slideshow* slideshow, Canvas* canvas, uint8_t x, uint8_t y)
|
|||||||
slideshow->icon.width,
|
slideshow->icon.width,
|
||||||
slideshow->icon.height,
|
slideshow->icon.height,
|
||||||
slideshow->icon.frames[slideshow->current_frame]);
|
slideshow->icon.frames[slideshow->current_frame]);
|
||||||
}
|
}
|
||||||
|
|||||||
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