Merge branch 'release-candidate' into release

This commit is contained in:
Aleksandr Kutuzov 2022-08-03 08:50:08 +09:00
commit 0c592ff84a
716 changed files with 15217 additions and 10304 deletions

3
.gitattributes vendored
View File

@ -1 +1,4 @@
* text=auto eol=lf * text=auto eol=lf
*.bat eol=crlf
*.ps1 eol=crlf
*.cmd eol=crlf

4
.github/CODEOWNERS vendored
View File

@ -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

View 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.

View 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.

View 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.

View File

@ -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
View 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.

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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
View File

@ -46,4 +46,7 @@ dist
build/ build/
# Toolchain # Toolchain
toolchain*/ /toolchain
# openocd output file
openocd.log

View File

@ -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

View File

@ -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

View File

@ -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;
} }

View File

@ -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*) {

View File

@ -13,7 +13,7 @@ public:
Tune, Tune,
}; };
osMessageQueueId_t event_queue; FuriMessageQueue* event_queue;
AccessorAppViewManager(); AccessorAppViewManager();
~AccessorAppViewManager(); ~AccessorAppViewManager();

View File

@ -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);

View File

@ -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");

View File

@ -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;
} }

View File

@ -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[] = {

View File

@ -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);
} }

View File

@ -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);

View File

@ -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));

View File

@ -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);
} }

View File

@ -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));

View File

@ -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) {

View File

@ -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);

View File

@ -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 {

View File

@ -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;
} }

View File

@ -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);
} }

View File

@ -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

View File

@ -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;
} }

View File

@ -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);
} }

View File

@ -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);
} }

View File

@ -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

View File

@ -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);

View File

@ -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
View 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);
} }

View File

@ -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;
}; };

View File

@ -0,0 +1,3 @@
#pragma once
#define BT_KEYS_STORAGE_FILE_NAME ".bt.keys"

View File

@ -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)

View File

@ -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);

View File

@ -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)

View File

@ -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>

View File

@ -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);
} }

View File

@ -0,0 +1,3 @@
#pragma once
#define BT_SETTINGS_FILE_NAME ".bt.settings"

View File

@ -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);
} }
} }

View File

@ -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;

View File

@ -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, &notification_sequence); notification_internal_message_block(notification, &notification_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) {

View File

@ -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;

View File

@ -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) {

View File

@ -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

View File

@ -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;
} }

View File

@ -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);
} }

View File

@ -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);
} }

View File

@ -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);

View File

@ -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"

View File

@ -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) {

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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);

View File

@ -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;
} }

View File

@ -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

View File

@ -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;
} }

View File

@ -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(

View File

@ -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);

View File

@ -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);
} }

View File

@ -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);
} }

View File

@ -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();

View File

@ -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

View File

@ -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);
} }

View File

@ -0,0 +1,3 @@
#pragma once
#define DESKTOP_SETTINGS_FILE_NAME ".desktop.settings"

View File

@ -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"

View File

@ -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>

View File

@ -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"

View File

@ -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"

View File

@ -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);

View File

@ -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);
} }
} }

View File

@ -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]);
} }

View File

@ -0,0 +1,3 @@
#pragma once
#define SLIDESHOW_FILE_NAME ".slideshow"

View File

@ -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;
} }

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -35,6 +35,7 @@ typedef enum {
DesktopAnimationEventInteractAnimation, DesktopAnimationEventInteractAnimation,
DesktopSlideshowCompleted, DesktopSlideshowCompleted,
DesktopSlideshowPoweroff,
// Global events // Global events
DesktopGlobalBeforeAppStarted, DesktopGlobalBeforeAppStarted,

View File

@ -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) {

View File

@ -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);
} }

View File

@ -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);
} }

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);
} }
} }

View File

@ -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