1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 20:49:49 +04:00

Compare commits

..

11 Commits

Author SHA1 Message Date
MX
ec6a169bf8 Merge branch 'dev' into release 2022-12-19 21:57:35 +03:00
MX
f1dec87c1b Merge branch 'dev' into release 2022-12-19 20:52:17 +03:00
MX
ab29951a99 Merge branch 'dev' into release 2022-12-19 19:26:06 +03:00
MX
bbe9f88bbe Merge branch 'dev' into release 2022-12-11 01:34:50 +03:00
MX
9188bf0013 Merge branch 'dev' into release 2022-12-10 04:38:04 +03:00
MX
f33ed59567 Merge branch 'dev' into release 2022-12-03 01:04:48 +03:00
MX
3fd8c80861 Merge branch 'dev' into release 2022-12-03 00:59:18 +03:00
MX
7b8ac3a5a0 Merge branch 'dev' into release 2022-11-30 21:05:08 +03:00
MX
6fef957001 Merge branch 'dev' into release 2022-11-24 04:02:59 +03:00
MX
0de1c9df89 Merge branch 'dev' into release 2022-11-24 03:45:52 +03:00
MX
a0e8cfbe97 Merge branch 'dev' into release 2022-11-24 03:41:01 +03:00
1028 changed files with 8719 additions and 41758 deletions

View File

@@ -140,10 +140,3 @@ Max butthurt: 10
Min level: 3
Max level: 3
Weight: 3
Name: L1_Sleigh_ride_128x64
Min butthurt: 0
Max butthurt: 14
Min level: 1
Max level: 3
Weight: 4

View File

@@ -2,10 +2,6 @@ kind: pipeline
type: docker
name: "Release firmware"
platform:
os: linux
arch: amd64
steps:
- name: "Update submodules"
image: alpine/git
@@ -28,50 +24,25 @@ steps:
- ls -laS artifacts-default/f7-update-${DRONE_TAG}
- sed -i 's/(version)/'${DRONE_TAG}'/g' CHANGELOG.md
- echo '# [Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw/${DRONE_TAG}/flipper-z-f7-update-'${DRONE_TAG}'.tgz&channel=release-cfw&version='${DRONE_TAG}')' >> CHANGELOG.md
- echo '' >> CHANGELOG.md
- echo '### [Version without custom animations - Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw_no_anim/flipper-z-f7-update-'${DRONE_TAG}'n.tgz&channel=release-cfw&version='${DRONE_TAG}'n)' >> CHANGELOG.md
- echo '' >> CHANGELOG.md
- echo '### [Version with extra apps - Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_TAG}'e.tgz&channel=release-cfw&version='${DRONE_TAG}'e)' >> CHANGELOG.md
environment:
FBT_TOOLS_CUSTOM_LINK:
from_secret: fbt_link
- name: "Build with extra apps"
image: hfdj/fztools
pull: never
commands:
- git clone https://github.com/xMasterX/unleashed-extra-pack.git
- cp -R unleashed-extra-pack/apps/* assets/resources/apps/
- rm -rf unleashed-extra-pack
- export DIST_SUFFIX=${DRONE_TAG}e
- export WORKFLOW_BRANCH_OR_TAG=release-cfw
- export FORCE_NO_DIRTY=yes
- rm -f build/f7-firmware-C/toolbox/version.*
- ./fbt COMPACT=1 DEBUG=0 updater_package
- mkdir artifacts-extra-apps
- mv dist/f7-C/* artifacts-extra-apps/
- ls -laS artifacts-extra-apps
- ls -laS artifacts-extra-apps/f7-update-${DRONE_TAG}e
environment:
FBT_TOOLS_CUSTOM_LINK:
from_secret: fbt_link
- name: "Build with ofw anims"
- name: "Build no anims FW"
image: hfdj/fztools
pull: never
commands:
- rm -f assets/dolphin/external/manifest.txt
- cp .ci_files/anims_ofw.txt assets/dolphin/external/manifest.txt
- rm -rf assets/resources/apps/
- export DIST_SUFFIX=${DRONE_TAG}n
- export WORKFLOW_BRANCH_OR_TAG=no-custom-anims
- export FORCE_NO_DIRTY=yes
- rm -f build/f7-firmware-C/toolbox/version.*
- ./fbt COMPACT=1 DEBUG=0 updater_package
- mkdir artifacts-ofw-anims
- mv dist/f7-C/* artifacts-ofw-anims/
- ls -laS artifacts-ofw-anims
- ls -laS artifacts-ofw-anims/f7-update-${DRONE_TAG}n
- echo '' >> CHANGELOG.md
- echo '### [Version without custom animations - Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/fw_no_anim/flipper-z-f7-update-'${DRONE_TAG}'n.tgz&channel=release-cfw&version='${DRONE_TAG}'n)' >> CHANGELOG.md
environment:
FBT_TOOLS_CUSTOM_LINK:
from_secret: fbt_link
@@ -79,24 +50,20 @@ steps:
- name: "Bundle self-update packages"
image: kramos/alpine-zip
commands:
- cp artifacts-extra-apps/flipper-z-f7-update-${DRONE_TAG}e.tgz .
- cp artifacts-ofw-anims/flipper-z-f7-update-${DRONE_TAG}n.tgz .
- cp artifacts-default/flipper-z-f7-update-${DRONE_TAG}.tgz .
- zip -r artifacts-extra-apps/flipper-z-f7-update-${DRONE_TAG}e.zip artifacts-extra-apps/f7-update-${DRONE_TAG}e
- zip -r artifacts-ofw-anims/flipper-z-f7-update-${DRONE_TAG}n.zip artifacts-ofw-anims/f7-update-${DRONE_TAG}n
- zip -r artifacts-default/flipper-z-f7-update-${DRONE_TAG}.zip artifacts-default/f7-update-${DRONE_TAG}
- tar czpf artifacts-default/flipper-z-any-scripts-${DRONE_TAG}.tgz scripts debug
- rm -rf artifacts-extra-apps/f7-update-${DRONE_TAG}
- rm -rf artifacts-ofw-anims/f7-update-${DRONE_TAG}
- rm -rf artifacts-default/f7-update-${DRONE_TAG}
- ls -laS artifacts-extra-apps
- ls -laS artifacts-ofw-anims
- ls -laS artifacts-default
- mv artifacts-default/ ${DRONE_TAG}
- ls -laS ${DRONE_TAG}
- name: "Upload default to updates srv"
image: appleboy/drone-scp:linux-amd64
image: appleboy/drone-scp
settings:
host:
from_secret: dep_host
@@ -117,7 +84,7 @@ steps:
- ${DRONE_TAG}/*.bin
- name: "Upload no-anims to updates srv"
image: appleboy/drone-scp:linux-amd64
image: appleboy/drone-scp
settings:
host:
from_secret: dep_host
@@ -131,21 +98,6 @@ steps:
from_secret: dep_target_noanim
source: flipper-z-f7-update-${DRONE_TAG}n.tgz
- name: "Upload extra apps version to updates srv"
image: appleboy/drone-scp:linux-amd64
settings:
host:
from_secret: dep_host
username:
from_secret: dep_user
password:
from_secret: dep_passwd
port:
from_secret: dep_port
target:
from_secret: dep_target_extra
source: flipper-z-f7-update-${DRONE_TAG}e.tgz
- name: "Do Github release"
image: ddplugins/github-release
pull: never
@@ -159,7 +111,6 @@ steps:
- ${DRONE_TAG}/*.tgz
- ${DRONE_TAG}/*.zip
- artifacts-ofw-anims/*.tgz
- artifacts-extra-apps/*.tgz
title: ${DRONE_TAG}
note: CHANGELOG.md
checksum:
@@ -192,7 +143,7 @@ steps:
Version: {{build.tag}}
[-Github - Changelog-](https://github.com/DarkFlippers/unleashed-firmware/releases/tag/${DRONE_TAG})
[-Github-](https://github.com/DarkFlippers/unleashed-firmware/releases/tag/${DRONE_TAG})
[-How to install firmware-](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/HowToInstall.md)
@@ -201,38 +152,39 @@ steps:
[-Download latest extra apps pack-](https://download-directory.github.io/?url=https://github.com/xMasterX/unleashed-extra-pack/tree/main/apps)
[-Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw/${DRONE_TAG}/flipper-z-f7-update-${DRONE_TAG}.tgz&channel=release-cfw&version=${DRONE_TAG})
[-Version without custom animations - Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_no_anim/flipper-z-f7-update-${DRONE_TAG}n.tgz&channel=release-cfw&version=${DRONE_TAG}n)
[-Version without custom animations - Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_no_anim/flipper-z-f7-update-${DRONE_TAG}n.tgz&channel=release-cfw&version=${DRONE_TAG}n)
[-Version with extra apps - Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-${DRONE_TAG}e.tgz&channel=release-cfw&version=${DRONE_TAG}e)"
[-Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw/${DRONE_TAG}/flipper-z-f7-update-${DRONE_TAG}.tgz&channel=release-cfw&version=${DRONE_TAG})"
document:
- ${DRONE_TAG}/flipper-z-f7-update-${DRONE_TAG}.tgz
- name: "Send discord notification"
image: hfdj/fztools
pull: never
environment:
DISCORD_WEBHOOK:
from_secret: dis_release_webhook
commands:
- wget "https://raw.githubusercontent.com/fieu/discord.sh/e1dc1a7595efad2cad8f072f0b3531c470f5b7c8/discord.sh"
- chmod +x ./discord.sh
- ./discord.sh --text 'New Unleashed firmware released!\n\nVersion - '${DRONE_TAG}'\n\n[[Github - Changelog]](https://github.com/DarkFlippers/unleashed-firmware/releases/tag/'${DRONE_TAG}')\n\n[-How to install firmware-](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/HowToInstall.md)\n\n[-Download latest extra apps pack-](https://download-directory.github.io/?url=https://github.com/xMasterX/unleashed-extra-pack/tree/main/apps)\n\n[-Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw/'${DRONE_TAG}'/flipper-z-f7-update-'${DRONE_TAG}'.tgz&channel=release-cfw&version='${DRONE_TAG}')\n\n[-Version without custom animations - Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_no_anim/flipper-z-f7-update-'${DRONE_TAG}'n.tgz&channel=release-cfw&version='${DRONE_TAG}'n)\n\n[-Version with extra apps - Install FW via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_TAG}'e.tgz&channel=release-cfw&version='${DRONE_TAG}'e)'
- name: "Send extra pack build to telegram"
image: appleboy/drone-telegram
image: appleboy/drone-discord
settings:
token:
from_secret: tgtoken
to:
from_secret: tgid
format: markdown
message: "Build with extra apps pack:"
document:
- flipper-z-f7-update-${DRONE_TAG}e.tgz
webhook_id:
from_secret: ds_wh_id
webhook_token:
from_secret: ds_wh_token
message: "New Unleashed firmware released!
Version: {{build.tag}}
[[Github]](https://github.com/DarkFlippers/unleashed-firmware/releases/tag/${DRONE_TAG})
[-How to install firmware-](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/HowToInstall.md)
[-Download latest extra apps pack-](https://download-directory.github.io/?url=https://github.com/xMasterX/unleashed-extra-pack/tree/main/apps)
[-Version without custom animations - Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_no_anim/flipper-z-f7-update-${DRONE_TAG}n.tgz&channel=release-cfw&version=${DRONE_TAG}n)
[-Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw/${DRONE_TAG}/flipper-z-f7-update-${DRONE_TAG}.tgz&channel=release-cfw&version=${DRONE_TAG})"
trigger:
event:
@@ -246,10 +198,6 @@ kind: pipeline
type: docker
name: "Dev build"
platform:
os: linux
arch: amd64
steps:
- name: "Update submodules"
image: alpine/git
@@ -274,30 +222,9 @@ steps:
FBT_TOOLS_CUSTOM_LINK:
from_secret: fbt_link
- name: "Build dev with extra apps"
image: hfdj/fztools
pull: never
commands:
- git clone https://github.com/xMasterX/unleashed-extra-pack.git
- cp -R unleashed-extra-pack/apps/* assets/resources/apps/
- rm -rf unleashed-extra-pack
- export DIST_SUFFIX=${DRONE_BUILD_NUMBER}e
- export WORKFLOW_BRANCH_OR_TAG=dev-cfw
- export FORCE_NO_DIRTY=yes
- rm -f build/f7-firmware-C/toolbox/version.*
- ./fbt COMPACT=1 DEBUG=0 updater_package
- mkdir artifacts-extra-apps
- mv dist/f7-C/* artifacts-extra-apps/
- ls -laS artifacts-extra-apps
- ls -laS artifacts-extra-apps/f7-update-${DRONE_BUILD_NUMBER}e
environment:
FBT_TOOLS_CUSTOM_LINK:
from_secret: fbt_link
- name: "Bundle self-update packages"
image: kramos/alpine-zip
commands:
- cp artifacts-extra-apps/flipper-z-f7-update-${DRONE_BUILD_NUMBER}e.tgz .
- cp artifacts-default/flipper-z-f7-update-${DRONE_BUILD_NUMBER}.tgz .
- rm -rf artifacts-default/f7-update-${DRONE_BUILD_NUMBER}
- ls -laS artifacts-default
@@ -305,7 +232,7 @@ steps:
- ls -laS dev
- name: "Clean dev folder"
image: appleboy/drone-ssh:linux-amd64
image: appleboy/drone-ssh
settings:
host:
from_secret: dep_host
@@ -317,10 +244,11 @@ steps:
from_secret: dep_port
command_timeout: 30s
script:
- cd web/unleashedflip.com/public_html/fw/dev && rm -f ./*
- cd web/unleashedflip.com/public_html/fw/dev
- rm -f ./*
- name: "Upload default to updates srv"
image: appleboy/drone-scp:linux-amd64
image: appleboy/drone-scp
settings:
host:
from_secret: dep_host
@@ -340,21 +268,6 @@ steps:
- dev/*.dfu
- dev/*.bin
- name: "Upload extra apps version to updates srv"
image: appleboy/drone-scp:linux-amd64
settings:
host:
from_secret: dep_host
username:
from_secret: dep_user
password:
from_secret: dep_passwd
port:
from_secret: dep_port
target:
from_secret: dep_target_extra
source: flipper-z-f7-update-${DRONE_BUILD_NUMBER}e.tgz
- name: "Trigger update server reindex"
image: hfdj/fztools
pull: never
@@ -385,36 +298,10 @@ steps:
Commit: {{commit.message}}
[-Version with extra apps - Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-${DRONE_BUILD_NUMBER}e.tgz&channel=dev-cfw&version=${DRONE_BUILD_NUMBER}e)
[-Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw/dev/flipper-z-f7-update-${DRONE_BUILD_NUMBER}.tgz&channel=dev-cfw&version=${DRONE_BUILD_NUMBER})"
document:
- dev/flipper-z-f7-update-${DRONE_BUILD_NUMBER}.tgz
- name: "Send extra pack build to telegram"
image: appleboy/drone-telegram
settings:
token:
from_secret: tgtoken
to:
from_secret: tgid_dev
format: markdown
message: "Build with extra apps pack:"
document:
- flipper-z-f7-update-${DRONE_BUILD_NUMBER}e.tgz
- name: "Send discord notification"
image: hfdj/fztools
pull: never
environment:
DISCORD_WEBHOOK:
from_secret: dis_dev_webhook
commands:
- wget "https://raw.githubusercontent.com/fieu/discord.sh/e1dc1a7595efad2cad8f072f0b3531c470f5b7c8/discord.sh"
- chmod +x ./discord.sh
- ./discord.sh --text 'Unleashed firmware dev build successful!\n\nBuild - '${DRONE_BUILD_NUMBER}'\n\nSHA - '${DRONE_COMMIT_SHA}'\n\n[-Version with extra apps - Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw_extra_apps/flipper-z-f7-update-'${DRONE_BUILD_NUMBER}'e.tgz&channel=dev-cfw&version='${DRONE_BUILD_NUMBER}'e)\n\n[-Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/fw/dev/flipper-z-f7-update-'${DRONE_BUILD_NUMBER}'.tgz&channel=dev-cfw&version='${DRONE_BUILD_NUMBER}')'
trigger:
branch:
- dev

6
.github/CODEOWNERS vendored
View File

@@ -1,5 +1 @@
# Default
* @xMasterX
# Assets
/assets/resources/infrared/ @xMasterX @amec0e
* @xMasterX

7
.github/FUNDING.yml vendored
View File

@@ -1,7 +1,2 @@
ko_fi: masterx
custom:
[
"https://boosty.to/mmxdev",
"https://pay.cloudtips.ru/p/7b3e9d65",
"https://yoomoney.ru/fundraise/XA49mgQLPA0.221209",
]
custom: ['https://boosty.to/mmxdev', 'https://destream.net/live/MMX/donate', 'https://pay.cloudtips.ru/p/7b3e9d65', 'https://yoomoney.ru/fundraise/XA49mgQLPA0.221209']

5
.gitignore vendored
View File

@@ -1,5 +1,4 @@
*.swp
*.swo
*.gdb_history
@@ -31,10 +30,6 @@ Brewfile.lock.json
# Visual Studio Code
.vscode/
# Kate
.kateproject
.kateconfig
# legendary cmake's
build
CMakeLists.txt

View File

@@ -1,5 +1,4 @@
# MLib macros we can't do much about.
//-V:M_LET:1048,1044
//-V:M_EACH:1048,1044
//-V:ARRAY_DEF:760,747,568,776,729,712,654
//-V:LIST_DEF:760,747,568,712,729,654,776
@@ -17,30 +16,8 @@
# Potentially null argument warnings
//-V:memset:575
//-V:memcpy:575
//-V:memcmp:575
//-V:strlen:575
//-V:strcpy:575
//-V:strncpy:575
//-V:strchr:575
# For loop warning on M_FOREACH
//-V:for:1044
# Bitwise OR
//-V:bit:792
# Do not complain about similar code
//-V::525
# Common embedded development pointer operations
//-V::566
//-V::1032
# Warnings about length mismatch
//-V:property_value_out:666
# Model-related warnings
//-V:with_view_model:1044,1048
# Functions that always return the same error code
//-V:picopass_device_decrypt:1048

View File

@@ -1 +1 @@
--ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/micro-ecc -e lib/microtar -e lib/mlib -e lib/qrcode -e lib/ST25RFAL002 -e lib/STM32CubeWB -e lib/u8g2 -e lib/nanopb -e */arm-none-eabi/* -e applications/plugins/dap_link/lib/free-dap
--rules-config .pvsconfig -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/micro-ecc -e lib/microtar -e lib/mlib -e lib/qrcode -e lib/ST25RFAL002 -e lib/STM32CubeWB -e lib/u8g2 -e */arm-none-eabi/*

View File

@@ -105,12 +105,6 @@
"type": "shell",
"command": "./fbt COMPACT=1 DEBUG=0 FORCE=1 flash_usb_full"
},
{
"label": "[Debug] Create PVS-Studio report",
"group": "build",
"type": "shell",
"command": "./fbt firmware_pvs"
},
{
"label": "[Debug] Build FAPs",
"group": "build",
@@ -144,18 +138,6 @@
"Serial Console"
]
},
{
"label": "[Debug] Build and upload all FAPs to Flipper over USB",
"group": "build",
"type": "shell",
"command": "./fbt fap_deploy"
},
{
"label": "[Release] Build and upload all FAPs to Flipper over USB",
"group": "build",
"type": "shell",
"command": "./fbt COMPACT=1 DEBUG=0 fap_deploy"
},
{
// Press Ctrl+] to quit
"label": "Serial Console",
@@ -163,7 +145,7 @@
"command": "./fbt cli",
"group": "none",
"isBackground": true,
"options": {
"options": {
"env": {
"FBT_NO_SYNC": "0"
}
@@ -180,4 +162,4 @@
}
}
]
}
}

View File

@@ -11,8 +11,5 @@
"augustocdias.tasks-shell-input"
],
// List of extensions recommended by VS Code that should not be recommended for users of this workspace.
"unwantedRecommendations": [
"twxs.cmake",
"ms-vscode.cmake-tools"
]
}
"unwantedRecommendations": []
}

View File

@@ -1,12 +1,23 @@
### New changes
* SubGHz: **Nice ON2E (Nice One)** support (by @assasinfil | PR #335)
* SubGHz: Remove 467.75 From freq analyzer since it has too much noise (Frequency is still can be used, just excluded from FA to avoid false detections)
* Archive and FileBrowser: **Fixed more navigation issues** (by @Willy-JL | PR #334)
* Plugins -> SubGHz Bruteforcer: Fix Linear Delta 3 repeats (now its more stable and we will be sure signal is received correctly)
* Plugins: Updated TOTP (Authenticator) [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator)
* OFW: **Fix Cyfral & Metakom emulation (My temp fix removed and proper fix from OFW applied)**
* OFW: BadUSB: disable CDC mode, USB mode switch fix
* OFW: Updater visual fixes
* **Fixed sound issues with WAV Player, Metronome, Morse code, DTMF Dolphin**
* API: Version was changed due to breaking changes - from 10.x to 11.x - Extra pack was updated, download it by using link below ([- Download latest extra apps pack](https://download-directory.github.io/?url=https://github.com/xMasterX/unleashed-extra-pack/tree/main/apps))
* Plugins: Add (UniTemp) Temp sensor reader (PR #216 | by @quen0n) [(plugin repo)](https://github.com/quen0n/unitemp-flipperzero) and Remove DHT Monitor and AM2320 plugins (unitemp has support for that sensors)
* Plugins -> SubGHz Bruteforcer: Add support for PT2260, SMC5326, UNILARM, Honeywell(file only) protocols
* Plugins: Add mouse jiggler to USB Keyboard&Mouse App
* Clock: Use system locale settings
* Infrared: Update universal remote assets (by @Amec0e) + (PR #215 | by @airs0urce)
* SubGHz: Removing duplicate code in subghz FAAC scenes. (PR #208 | by @gid9798)
* Plugins -> Weather Station: Fix display of temps lower than -9
* Misc fixes
* OFW: Notification: fix recursive speaker acquire
* OFW: Locale settings
* OFW: Audio support for SubGhz **(Breaking API change)**
* OFW: Dolphin: add new animation (Happy holidays)
* OFW: SubGhz: add SMC5326, UNILARM protocol
* OFW: Added support for IDTECK cards
* OFW: WS: fix protocol and add new (Oregon_v1, TX8300)
* OFW: VSCode: add task 'Serial console' and group task with sequence calling
* OFW: Dictionary stuff: iClass keys
#### [🎲 Download latest extra apps pack](https://download-directory.github.io/?url=https://github.com/xMasterX/unleashed-extra-pack/tree/main/apps)
@@ -17,6 +28,7 @@
## Please support development of the project
* Boosty: https://boosty.to/mmxdev
* Ko-Fi: https://ko-fi.com/masterx
* destream (100 EUR min): https://destream.net/live/MMX/donate
* cloudtips (only RU payments accepted): https://pay.cloudtips.ru/p/7b3e9d65
* YooMoney (only RU payments accepted): https://yoomoney.ru/fundraise/XA49mgQLPA0.221209
* USDT(TRC20): `TSXcitMSnWXUFqiUfEXrTVpVewXy2cYhrs`
@@ -36,8 +48,7 @@ and all other great people who supported our project and me (xMasterX), thanks t
**Recommended option - Web Updater**
What means `n` or `e` in - `flipper-z-f7-update-(version)(n / e).tgz` ? - `n` means this build comes without our custom animations, only official flipper animations,
`e` means build has extra apps pack preinstalled
What means `n` in - `flipper-z-f7-update-(version)n.tgz` ? - that means this build comes without our custom animations, only official flipper animations
Self-update package (update from microSD) - `flipper-z-f7-update-(version).zip` or download `.tgz` for mobile app / qFlipper

View File

@@ -3,15 +3,15 @@
Nice to see you reading this document, we really appreciate it.
As all documents of this kind it's unable to cover everything.
But it will cover general rules that we are enforcing on PR review.
But it will cover general rules that we enforcing on PR review.
Also, we already have automatic rules checking and formatting,
but it got its limitations and this guide is still mandatory.
Also we already have automatic rules checking and formatting,
but it got it's limitations and this guide is still mandatory.
Some part of this project do have its own naming and coding guides.
Some part of this project do have it's own naming and coding guides.
For example: assets. Take a look into `ReadMe.md` in assets folder for more details.
Also, 3rd party libraries are none of our concern.
Also 3rd party libraries are none of our concern.
And yes, this set is not final and we are open to discussion.
If you want to add/remove/change something here please feel free to open new ticket.
@@ -30,7 +30,7 @@ Our guide is inspired by, but not claiming to be compatible with:
Code we write is intended to be public.
Avoid one-liners from hell and keep code complexity under control.
Try to make code self-explanatory and add comments if needed.
Try to make code self explanatory and add comments if needed.
Leave references to standards that you are implementing.
Use project wiki to document new/reverse engineered standards.
@@ -52,7 +52,7 @@ Almost everything in flipper firmware is built around this concept.
## Naming
### Type names are PascalCase
### Type names are CamelCase
Examples:
@@ -89,7 +89,7 @@ Enforced by linter.
Suffixes:
- `alloc` - allocate and init instance. C style constructor. Returns pointer to instance.
- `free` - de-init and release instance. C style destructor. Takes pointer to instance.
- `free` - deinit and release instance. C style destructor. Takes pointer to instance.
# C++ coding style

21
Makefile Normal file
View File

@@ -0,0 +1,21 @@
$(info +-------------------------------------------------+)
$(info | |)
$(info | Hello, this is Flipper team speaking! |)
$(info | |)
$(info | We've migrated to new build system |)
$(info | It's nice and based on scons |)
$(info | |)
$(info | Crash course: |)
$(info | |)
$(info | `./fbt` |)
$(info | `./fbt flash` |)
$(info | `./fbt debug` |)
$(info | |)
$(info | More details in documentation/fbt.md |)
$(info | |)
$(info | Also Please leave your feedback here: |)
$(info | https://flipp.dev/4RDu |)
$(info | or |)
$(info | https://flipp.dev/2XM8 |)
$(info | |)
$(info +-------------------------------------------------+)

106
ReadMe.md
View File

@@ -4,19 +4,19 @@
</a>
</h3>
### Welcome to the Flipper Zero Unleashed Firmware repo!
### Welcome to Flipper Zero Unleashed Firmware repo!
**This firmware is a fork from** [flipperdevices/flipperzero-firmware](https://github.com/flipperdevices/flipperzero-firmware)
<br>
Our goal is to make all features possible on this device without any limitations!
Our goal is to make any features possible in this device without any limitations!
Please help us implement emulation for all Sub-GHz dynamic (rolling code) protocols!
Please help us implement emulation for all subghz dynamic (rolling code) protocols!
<br>
### This software is for experimental purposes only and is not meant for any illegal activity/purposes. <br> We do not condone illegal activity and strongly encourage keeping transmissions to legal/valid uses allowed by law. <br> Also, this software is made without any support from Flipper Devices and is in no way related to the official devs.
### This software is for experimental purposes only and is not meant for any illegal activity/purposes. <br> We do not condone illegal activity and strongly encourage keeping transmissions to legal/valid uses allowed by law. <br> Also this software is made without any support from Flipper Devices and in no way related to official devs.
<br>
Our Discord Community:
@@ -34,32 +34,27 @@ Our Discord Community:
- https://t.me/unleashed_fw
# What's changed
* Sub-GHz regional TX restrictions removed
* Sub-GHz frequency range can be extended in settings file (Warning: It can damage Flipper's hardware)
* SubGHz regional TX restrictions removed
* SubGHz frequency range can be extended in settings file (Warning: It can damage flipper's hardware)
* Many rolling code protocols now have the ability to save & send captured signals
* FAAC SLH (Spa) & BFT Mitto (secure with seed) manual creation
* Sub-GHz static code brute-force plugin
* LFRFID Fuzzer plugin
* Custom community plugins and games added + all known working apps can be downloaded in extra pack in every release
* Extra Sub-GHz frequencies + extra Mifare Classic keys
* Custom community plugins and games added
* Extra SubGHz frequencies + extra Mifare Classic keys
* Picopass/iClass plugin included in releases
* Recompiled IR TV Universal Remote for ALL buttons
* Universal remote for Projectors, Fans, A/Cs and Audio(soundbars, etc.)
* BadUSB keyboard layouts
* Customizable Flipper name
* Sub-GHz -> Press OK in frequency analyzer to use detected frequency in Read modes
* Sub-GHz -> Long press OK button in Sub-GHz Frequency analyzer to switch to Read menu
* Sub-GHz -> External CC1101 module support
* SubGHz -> Press OK in frequency analyzer to use detected frequency in Read modes
* SubGHz -> Long press OK button in SubGHz Frequency analyzer to switch to Read menu
* Other small fixes and changes throughout
* See other changes in changelog and in readme below
Also check the changelog in releases for latest updates!
### Current modified and new Sub-GHz protocols list:
Thanks to Official team (to thier SubGHz Developer, Skorp) for implementing decoders for these protocols.
Encoders/sending made by Eng1n33r & @xMasterX:
Also check changelog in releases for latest updates!
### Current modified and new SubGHz protocols list:
- Keeloq [Not ALL systems supported for decode or emulation yet!] - [Supported manufacturers list](https://0bin.net/paste/VwR2lNJY#WH9vnPgvcp7w6zVKucFCuNREKAcOij8KsJ6vqLfMn3b)
- Keeloq: HCS101
- Keeloq: AN-Motors
@@ -77,28 +72,10 @@ Encoders/sending made by Eng1n33r & @xMasterX:
- Security+ v1 & v2
- Star Line
Encoders made by @assasinfil & @xMasterX:
- Somfy Telis
- Somfy Keytis
- KingGates Stylo 4k
- Alutech AT-4N
- Nice ON2E (Nice One)
## Please support development of the project
The majority of this project is developed and maintained by me, @xMasterX.
I'm unemployed because of the war, and the only income I receive is from your donations.
Our team is small and the guys are working on this project as much as they can solely based on the enthusiasm they have for this project and the community.
- @assasinfil - SubGHz
- @Svaarich - UI design and animations
- @Amec0e - Infrared assets
- Community moderators in Telegram, Discord, and Reddit
- And of course our GitHub community. Your PRs are a very important part of this firmware and open-source development.
The amount of work done on this project is huge and we need your support, no matter how large or small. Even if you just say, "Thank you Unleashed firmware developers!" somewhere. Doing so will help us continue our work and will help drive us to make the firmware better every time.
Also, regarding our releases, every build has and always will be free and open-source. There will be no paywall releases or closed-source apps within the firmware. As long as I am working on this project it will never happen.
You can support us by using links or addresses below:
* Boosty: https://boosty.to/mmxdev
* Ko-Fi: https://ko-fi.com/masterx
* destream (100 EUR min): https://destream.net/live/MMX/donate
* cloudtips (only RU payments accepted): https://pay.cloudtips.ru/p/7b3e9d65
* YooMoney (only RU payments accepted): https://yoomoney.ru/fundraise/XA49mgQLPA0.221209
* USDT(TRC20): `TSXcitMSnWXUFqiUfEXrTVpVewXy2cYhrs`
@@ -112,36 +89,34 @@ You can support us by using links or addresses below:
### Community apps included:
- **RFID Fuzzer** [(by Ganapati & @xMasterX)](https://github.com/DarkFlippers/unleashed-firmware/pull/54) & New protocols by @mvanzanten
- **Sub-GHz bruteforcer** [(by @derskythe & xMasterX)](https://github.com/derskythe/flipperzero-subbrute) [(original by Ganapati & xMasterX)](https://github.com/DarkFlippers/unleashed-firmware/pull/57)
- **Sub-GHz playlist** [(by darmiel)](https://github.com/DarkFlippers/unleashed-firmware/pull/62)
- RFID Fuzzer plugin [(by Ganapati & @xMasterX)](https://github.com/DarkFlippers/unleashed-firmware/pull/54) & New protocols by @mvanzanten
- Sub-GHz bruteforce plugin [(by @derskythe & xMasterX)](https://github.com/derskythe/flipperzero-subbrute) [(original by Ganapati & xMasterX)](https://github.com/DarkFlippers/unleashed-firmware/pull/57)
- Sub-GHz playlist plugin [(by darmiel)](https://github.com/DarkFlippers/unleashed-firmware/pull/62)
- ESP8266 Deauther plugin [(by SequoiaSan)](https://github.com/SequoiaSan/FlipperZero-Wifi-ESP8266-Deauther-Module)
- WiFi Scanner plugin [(by SequoiaSan)](https://github.com/SequoiaSan/FlipperZero-WiFi-Scanner_Module)
- MultiConverter plugin [(by theisolinearchip)](https://github.com/theisolinearchip/flipperzero_stuff)
- USB Keyboard plugin [(by huuck)](https://github.com/huuck/FlipperZeroUSBKeyboard)
- WAV Player [(OFW: DrZlo13)](https://github.com/flipperdevices/flipperzero-firmware/tree/zlo/wav-player) - Fixed and improved by [LTVA1](https://github.com/LTVA1/wav_player)
- WAV player plugin (fixed) [(OFW: DrZlo13)](https://github.com/flipperdevices/flipperzero-firmware/tree/zlo/wav-player)
- Barcode generator plugin [(original by McAzzaMan)](https://github.com/McAzzaMan/flipperzero-firmware/tree/UPC-A_Barcode_Generator/applications/barcode_generator) - [EAN-8 and refactoring](https://github.com/DarkFlippers/unleashed-firmware/pull/154) by @msvsergey
- GPIO: Sentry Safe plugin [(by H4ckd4ddy)](https://github.com/H4ckd4ddy/flipperzero-sentry-safe-plugin)
- ESP32: WiFi Marauder companion plugin [(by 0xchocolate)](https://github.com/0xchocolate/flipperzero-firmware-with-wifi-marauder-companion)
- NRF24: Sniffer & MouseJacker (with changes) [(by mothball187)](https://github.com/mothball187/flipperzero-nrf24/tree/main/mousejacker)
- Simple Clock (timer by GMMan) [(original by CompaqDisc)](https://gist.github.com/CompaqDisc/4e329c501bd03c1e801849b81f48ea61)
- **Sub-GHz Remote** (UniversalRF Remix) [(by @darmiel & @xMasterX)](https://github.com/darmiel/flipper-playlist/tree/feat/unirf-protocols) (original by @ESurge)
- Simple Clock (timer by GMMan / settings by kowalski7cc) [(original by CompaqDisc)](https://gist.github.com/CompaqDisc/4e329c501bd03c1e801849b81f48ea61)
- UniversalRF Remix / Sub-GHz Remote [(by @darmiel & @xMasterX)](https://github.com/darmiel/flipper-playlist/tree/feat/unirf-protocols) (original by @ESurge)
- Spectrum Analyzer (with changes) [(by jolcese)](https://github.com/jolcese/flipperzero-firmware/tree/spectrum/applications/spectrum_analyzer) - [Ultra Narrow mode & scan channels non-consecutively](https://github.com/theY4Kman/flipperzero-firmware/commits?author=theY4Kman)
- Metronome [(by panki27)](https://github.com/panki27/Metronome)
- DTMF Dolphin [(by litui)](https://github.com/litui/dtmf_dolphin)
- **TOTP (Authenticator)** [(by akopachov)](https://github.com/akopachov/flipper-zero_authenticator)
- GPS [(by ezod)](https://github.com/ezod/flipperzero-gps) works with module `NMEA 0183` via UART (13TX, 14RX, GND pins on Flipper)
- i2c Tools [(by NaejEL)](https://github.com/NaejEL/flipperzero-i2ctools) - C0 -> SCL / C1 -> SDA / GND -> GND | 3v3 logic levels only!
- Temperature Sensor Plugin - HTU2xD, SHT2x, SI702x, SI700x, SI701x, AM2320 [(by Mywk)](https://github.com/Mywk/FlipperTemperatureSensor) - [How to Connect](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/applications/plugins/htu21d_temp_sensor/Readme.md)
- HC-SR04 Distance sensor - Ported and modified by @xMasterX [(original by Sanqui)](https://github.com/Sanqui/flipperzero-firmware/tree/hc_sr04) - How to connect -> (5V -> VCC) / (GND -> GND) / (13|TX -> Trig) / (14|RX -> Echo)
- Morse Code [(by wh00hw)](https://github.com/wh00hw/MorseCodeFAP)
- **Unitemp - Temperature sensors reader** (DHT11/22, DS18B20, BMP280, HTU21x and more) [(by quen0n)](https://github.com/quen0n/unitemp-flipperzero)
- (UniTemp) Temp sensor reader [(by quen0n)](https://github.com/quen0n/unitemp-flipperzero)
- BH1750 - Lightmeter [(by oleksiikutuzov)](https://github.com/oleksiikutuzov/flipperzero-lightmeter)
- **iButton Fuzzer** [(by xMasterX)](https://github.com/xMasterX/ibutton-fuzzer)
- iButton Fuzzer [(by xMasterX)](https://github.com/xMasterX/ibutton-fuzzer)
- HEX Viewer [(by QtRoS)](https://github.com/QtRoS/flipper-zero-hex-viewer)
- POCSAG Pager [(by xMasterX & Shmuma)](https://github.com/xMasterX/flipper-pager)
- Text Viewer [(by kowalski7cc & kyhwana)](https://github.com/kowalski7cc/flipper-zero-text-viewer/tree/refactor-text-app)
- **UART Terminal** [(by cool4uma)](https://github.com/cool4uma/UART_Terminal/tree/main)
- **ProtoView** [(by antirez)](https://github.com/antirez/protoview)
Games:
- DOOM (fixed) [(by p4nic4ttack)](https://github.com/p4nic4ttack/doom-flipper-zero/)
@@ -155,16 +130,15 @@ Games:
- Game15 [(by x27)](https://github.com/x27/flipperzero-game15)
- Solitaire [(by teeebor)](https://github.com/teeebor/flipper_games)
- BlackJack [(by teeebor)](https://github.com/teeebor/flipper_games)
- 2048 game [(by eugene-kirzhanov)](https://github.com/eugene-kirzhanov/flipper-zero-2048-game)
### Other changes
- BadUSB -> Keyboard layouts [(by rien > dummy-decoy)](https://github.com/dummy-decoy/flipperzero-firmware/tree/dummy_decoy/bad_usb_keyboard_layout)
- Sub-GHz -> External CC1101 module support - [(by quen0n)](https://github.com/DarkFlippers/unleashed-firmware/pull/307)
- Sub-GHz -> New frequency analyzer - [(by ClusterM)](https://github.com/DarkFlippers/unleashed-firmware/pull/43)
- Sub-GHz -> Save last used frequency [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/77)
- Sub-GHz -> Press OK in frequency analyzer to use detected frequency in Read modes [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/77)
- Sub-GHz -> Long press OK button in Sub-GHz Frequency analyzer to switch to Read menu [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/79)
- SubGHz -> New frequency analyzer - [(by ClusterM)](https://github.com/DarkFlippers/unleashed-firmware/pull/43)
- SubGHz -> Detect RAW feature - [(by perspecdev)](https://github.com/RogueMaster/flipperzero-firmware-wPlugins/pull/152)
- SubGHz -> Save last used frequency [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/77)
- SubGHz -> Press OK in frequency analyzer to use detected frequency in Read modes [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/77)
- SubGHz -> Long press OK button in SubGHz Frequency analyzer to switch to Read menu [(by derskythe)](https://github.com/DarkFlippers/unleashed-firmware/pull/79)
- Lock device with pin(or regular lock if pin not set) by holding UP button on main screen [(by an4tur0r)](https://github.com/DarkFlippers/unleashed-firmware/pull/107)
# Instructions
@@ -172,8 +146,6 @@ Games:
## [- How to build firmware](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/HowToBuild.md)
## [- How to connect external CC1101 module](https://github.com/quen0n/flipperzero-ext-cc1101)
## [- BadUSB: how to add new keyboard layouts](https://github.com/dummy-decoy/flipperzero_badusb_kl)
## [- How to change Flipper name](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/CustomFlipperName.md)
@@ -192,11 +164,15 @@ Games:
## [- WAV Player sample files & how to convert](https://github.com/UberGuidoZ/Flipper/tree/main/Wav_Player#readme)
## [- Sub-GHz playlist generator script](https://github.com/darmiel/flipper-scripts/blob/main/playlist/playlist_creator_by_chunk.py)
## [- SubGHz playlist generator script](https://github.com/darmiel/flipper-scripts/blob/main/playlist/playlist_creator_by_chunk.py)
### **Plugins that works with external hardware**
## [- How to use: Unitemp - Temperature sensors reader](https://github.com/quen0n/unitemp-flipperzero#readme)
## [- How to use: Temperature Sensor Plugin - HTU21D / SI7021](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/applications/plugins/htu21d_temp_sensor/Readme.md)
## [- How to use: DHT11/22 Temp. Sensor Monitor](https://github.com/quen0n/FipperZero-DHT-Monitor#readme)
## [- How to use: AM2320/AM2321 Temp. Sensor plugin](https://github.com/xMasterX/AM2320_Flipper_Plugin)
## [- How to use: [NMEA] GPS](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/applications/plugins/gps_nmea_uart/README.md)
@@ -218,20 +194,20 @@ Games:
## [- How to use: [GPIO] SentrySafe plugin](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SentrySafe.md)
### **Sub-GHz**
### **SubGHz**
## [- Transmission is blocked? - How to extend Sub-GHz frequency range](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/DangerousSettings.md)
## [- Transmission is blocked? - How to extend SubGHz frequency range](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/DangerousSettings.md)
## [- How to add extra Sub-GHz frequencies](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzSettings.md)
## [- How to add extra SubGHz frequencies](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/SubGHzSettings.md)
<br>
<br>
# Where I can find IR, Sub-GHz, ... files, DBs, and other stuff?
# Where I can find IR, SubGhz, ... files, DBs, and other stuff?
## [UberGuidoZ Playground - Large collection of files - Github](https://github.com/UberGuidoZ/Flipper)
## [Awesome Flipper Zero - Github](https://github.com/djsime1/awesome-flipperzero)
## [CAME-12bit, NICE-12bit, Linear-10bit, PT-2240 - Sub-GHz fixed code bruteforce](https://github.com/tobiabocchi/flipperzero-bruteforce)
## [SMC5326, UNILARM - Sub-GHz fixed code bruteforce](https://github.com/Hong5489/flipperzero-gate-bruteforce)
## [CAME-12bit, NICE-12bit, Linear-10bit, PT-2240 - SubGHz fixed code bruteforce](https://github.com/tobiabocchi/flipperzero-bruteforce)
## [SMC5326, UNILARM - SubGHz fixed code bruteforce](https://github.com/Hong5489/flipperzero-gate-bruteforce)
<br>
<br>
@@ -248,7 +224,7 @@ Games:
- `applications` - Applications and services used in firmware
- `assets` - Assets used by applications and services
- `furi` - Furi Core: OS-level primitives and helpers
- `furi` - Furi Core: os level primitives and helpers
- `debug` - Debug tool: GDB-plugins, SVD-file and etc
- `documentation` - Documentation generation system configs and input files
- `firmware` - Firmware source code
@@ -256,4 +232,4 @@ Games:
- `site_scons` - Build helpers
- `scripts` - Supplementary scripts and python libraries home
Also, pay attention to the `ReadMe.md` files inside those directories.
Also pay attention to `ReadMe.md` files inside those directories.

View File

@@ -148,12 +148,9 @@ fap_dist = [
for app_artifact in firmware_env["FW_EXTAPPS"].applications.values()
),
),
*(
distenv.Install(
f"#/dist/{dist_dir}/apps/{app_artifact.app.fap_category}",
app_artifact.compact[0],
)
for app_artifact in firmware_env["FW_EXTAPPS"].applications.values()
distenv.Install(
f"#/dist/{dist_dir}/apps",
"#/assets/resources/apps",
),
]
Depends(
@@ -168,14 +165,6 @@ Alias("fap_dist", fap_dist)
distenv.Depends(firmware_env["FW_RESOURCES"], firmware_env["FW_EXTAPPS"].resources_dist)
# Copy all faps to device
fap_deploy = distenv.PhonyTarget(
"fap_deploy",
"${PYTHON3} ${ROOT_DIR}/scripts/storage.py send ${SOURCE} /ext/apps",
source=Dir("#/assets/resources/apps"),
)
# Target for bundling core2 package for qFlipper
copro_dist = distenv.CoproBuilder(
@@ -205,20 +194,6 @@ firmware_bm_flash = distenv.PhonyTarget(
],
)
gdb_backtrace_all_threads = distenv.PhonyTarget(
"gdb_trace_all",
"$GDB $GDBOPTS $SOURCES $GDBFLASH",
source=firmware_env["FW_ELF"],
GDBOPTS="${GDBOPTS_BASE}",
GDBREMOTE="${OPENOCD_GDB_PIPE}",
GDBFLASH=[
"-ex",
"thread apply all bt",
"-ex",
"quit",
],
)
# Debugging firmware
firmware_debug = distenv.PhonyTarget(
"debug",

View File

@@ -31,10 +31,9 @@ void AccessorApp::run(void) {
onewire_host_stop(onewire_host);
}
AccessorApp::AccessorApp()
: text_store{0} {
AccessorApp::AccessorApp() {
notification = static_cast<NotificationApp*>(furi_record_open(RECORD_NOTIFICATION));
onewire_host = onewire_host_alloc(&ibutton_gpio);
onewire_host = onewire_host_alloc();
furi_hal_power_enable_otg();
}

View File

@@ -2,7 +2,6 @@ App(
appid="accessor",
name="Accessor",
apptype=FlipperAppType.DEBUG,
targets=["f7"],
entry_point="accessor_app",
cdefines=["APP_ACCESSOR"],
requires=["gui"],

View File

@@ -171,6 +171,9 @@ bool WIEGAND::DoWiegandConversion() {
return true;
} else {
_lastWiegand = sysTick;
_bitCount = 0;
_cardTemp = 0;
_cardTempHigh = 0;
return false;
}

View File

@@ -11,5 +11,4 @@ App(
stack_size=1 * 1024,
order=130,
fap_category="Debug",
fap_libs=["assets"],
)

View File

@@ -1,148 +0,0 @@
#include "battery_info.h"
#include <furi.h>
#include <gui/elements.h>
#include <assets_icons.h>
#define LOW_CHARGE_THRESHOLD 10
#define HIGH_DRAIN_CURRENT_THRESHOLD 100
struct BatteryInfo {
View* view;
};
static void draw_stat(Canvas* canvas, int x, int y, const Icon* icon, char* val) {
canvas_draw_frame(canvas, x - 7, y + 7, 30, 13);
canvas_draw_icon(canvas, x, y, icon);
canvas_set_color(canvas, ColorWhite);
canvas_draw_box(canvas, x - 4, y + 16, 24, 6);
canvas_set_color(canvas, ColorBlack);
canvas_draw_str_aligned(canvas, x + 8, y + 22, AlignCenter, AlignBottom, val);
};
static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) {
char emote[20] = {};
char header[20] = {};
char value[20] = {};
int32_t drain_current = data->gauge_current * (-1000);
uint32_t charge_current = data->gauge_current * 1000;
// Draw battery
canvas_draw_icon(canvas, x, y, &I_BatteryBody_52x28);
if(charge_current > 0) {
canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceCharging_29x14);
} else if(drain_current > HIGH_DRAIN_CURRENT_THRESHOLD) {
canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceConfused_29x14);
} else if(data->charge < LOW_CHARGE_THRESHOLD) {
canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceNopower_29x14);
} else {
canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceNormal_29x14);
}
// Draw bubble
elements_bubble(canvas, 53, 0, 71, 39);
// Set text
if(charge_current > 0) {
snprintf(emote, sizeof(emote), "%s", "Yummy!");
snprintf(header, sizeof(header), "%s", "Charging at");
snprintf(
value,
sizeof(value),
"%lu.%luV %lumA",
(uint32_t)(data->vbus_voltage),
(uint32_t)(data->vbus_voltage * 10) % 10,
charge_current);
} else if(drain_current > 0) {
snprintf(
emote,
sizeof(emote),
"%s",
drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "Oh no!" : "Om-nom-nom!");
snprintf(header, sizeof(header), "%s", "Consumption is");
snprintf(
value,
sizeof(value),
"%ld %s",
drain_current,
drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA");
} else if(drain_current != 0) {
snprintf(header, 20, "...");
} else if(data->charging_voltage < 4.2) {
// Non-default battery charging limit, mention it
snprintf(emote, sizeof(emote), "Charged!");
snprintf(header, sizeof(header), "Limited to");
snprintf(
value,
sizeof(value),
"%lu.%luV",
(uint32_t)(data->charging_voltage),
(uint32_t)(data->charging_voltage * 10) % 10);
} else {
snprintf(header, sizeof(header), "Charged!");
}
canvas_draw_str_aligned(canvas, 92, y + 3, AlignCenter, AlignCenter, emote);
canvas_draw_str_aligned(canvas, 92, y + 15, AlignCenter, AlignCenter, header);
canvas_draw_str_aligned(canvas, 92, y + 27, AlignCenter, AlignCenter, value);
};
static void battery_info_draw_callback(Canvas* canvas, void* context) {
furi_assert(context);
BatteryInfoModel* model = context;
canvas_clear(canvas);
canvas_set_color(canvas, ColorBlack);
draw_battery(canvas, model, 0, 5);
char batt_level[10];
char temperature[10];
char voltage[10];
char health[10];
snprintf(batt_level, sizeof(batt_level), "%lu%%", (uint32_t)model->charge);
snprintf(temperature, sizeof(temperature), "%lu C", (uint32_t)model->gauge_temperature);
snprintf(
voltage,
sizeof(voltage),
"%lu.%01lu V",
(uint32_t)model->gauge_voltage,
(uint32_t)(model->gauge_voltage * 10) % 10UL);
snprintf(health, sizeof(health), "%d%%", model->health);
draw_stat(canvas, 8, 42, &I_Battery_16x16, batt_level);
draw_stat(canvas, 40, 42, &I_Temperature_16x16, temperature);
draw_stat(canvas, 72, 42, &I_Voltage_16x16, voltage);
draw_stat(canvas, 104, 42, &I_Health_16x16, health);
}
BatteryInfo* battery_info_alloc() {
BatteryInfo* battery_info = malloc(sizeof(BatteryInfo));
battery_info->view = view_alloc();
view_set_context(battery_info->view, battery_info);
view_allocate_model(battery_info->view, ViewModelTypeLocking, sizeof(BatteryInfoModel));
view_set_draw_callback(battery_info->view, battery_info_draw_callback);
return battery_info;
}
void battery_info_free(BatteryInfo* battery_info) {
furi_assert(battery_info);
view_free(battery_info->view);
free(battery_info);
}
View* battery_info_get_view(BatteryInfo* battery_info) {
furi_assert(battery_info);
return battery_info->view;
}
void battery_info_set_data(BatteryInfo* battery_info, BatteryInfoModel* data) {
furi_assert(battery_info);
furi_assert(data);
with_view_model(
battery_info->view,
BatteryInfoModel * model,
{ memcpy(model, data, sizeof(BatteryInfoModel)); },
true);
}

View File

@@ -1,23 +0,0 @@
#pragma once
#include <gui/view.h>
typedef struct BatteryInfo BatteryInfo;
typedef struct {
float vbus_voltage;
float gauge_voltage;
float gauge_current;
float gauge_temperature;
float charging_voltage;
uint8_t charge;
uint8_t health;
} BatteryInfoModel;
BatteryInfo* battery_info_alloc();
void battery_info_free(BatteryInfo* battery_info);
View* battery_info_get_view(BatteryInfo* battery_info);
void battery_info_set_data(BatteryInfo* battery_info, BatteryInfoModel* data);

View File

@@ -31,6 +31,9 @@ uint32_t bt_debug_start_view(void* context) {
BtDebugApp* bt_debug_app_alloc() {
BtDebugApp* app = malloc(sizeof(BtDebugApp));
// Load settings
bt_settings_load(&app->settings);
// Gui
app->gui = furi_record_open(RECORD_GUI);
@@ -102,15 +105,13 @@ int32_t bt_debug_app(void* p) {
}
BtDebugApp* app = bt_debug_app_alloc();
// Was bt active?
const bool was_active = furi_hal_bt_is_active();
// Stop advertising
furi_hal_bt_stop_advertising();
view_dispatcher_run(app->view_dispatcher);
// Restart advertising
if(was_active) {
if(app->settings.enabled) {
furi_hal_bt_start_advertising();
}
bt_debug_app_free(app);

View File

@@ -4,14 +4,15 @@
#include <gui/gui.h>
#include <gui/view.h>
#include <gui/view_dispatcher.h>
#include <gui/modules/submenu.h>
#include <dialogs/dialogs.h>
#include <gui/modules/submenu.h>
#include "views/bt_carrier_test.h"
#include "views/bt_packet_test.h"
#include <bt/bt_settings.h>
typedef struct {
BtSettings settings;
Gui* gui;
ViewDispatcher* view_dispatcher;
Submenu* submenu;

View File

@@ -1,7 +1,7 @@
#include "bt_carrier_test.h"
#include "bt_test.h"
#include "bt_test_types.h"
#include <furi_hal_bt.h>
#include "furi_hal_bt.h"
struct BtCarrierTest {
BtTest* bt_test;

View File

@@ -1,7 +1,7 @@
#include "bt_packet_test.h"
#include "bt_test.h"
#include "bt_test_types.h"
#include <furi_hal_bt.h>
#include "furi_hal_bt.h"
struct BtPacketTest {
BtTest* bt_test;

View File

@@ -2,11 +2,8 @@
#include <gui/canvas.h>
#include <gui/elements.h>
#include <lib/toolbox/float_tools.h>
#include <m-array.h>
#include <furi.h>
#include <inttypes.h>
#include <stdint.h>
struct BtTestParam {
@@ -101,16 +98,16 @@ static void bt_test_draw_callback(Canvas* canvas, void* _model) {
elements_scrollbar(canvas, model->position, BtTestParamArray_size(model->params));
canvas_draw_str(canvas, 6, 60, model->message);
if(model->state == BtTestStateStarted) {
if(!float_is_equal(model->rssi, 0.0f)) {
if(model->rssi != 0.0f) {
snprintf(info_str, sizeof(info_str), "RSSI:%3.1f dB", (double)model->rssi);
canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str);
}
} else if(model->state == BtTestStateStopped) {
if(model->packets_num_rx) {
snprintf(info_str, sizeof(info_str), "%" PRIu32 " pack rcv", model->packets_num_rx);
snprintf(info_str, sizeof(info_str), "%ld pack rcv", model->packets_num_rx);
canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str);
} else if(model->packets_num_tx) {
snprintf(info_str, sizeof(info_str), "%" PRIu32 " pack sent", model->packets_num_tx);
snprintf(info_str, sizeof(info_str), "%ld pack sent", model->packets_num_tx);
canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str);
}
}
@@ -156,7 +153,7 @@ static bool bt_test_input_callback(InputEvent* event, void* context) {
}
void bt_test_process_up(BtTest* bt_test) {
with_view_model( // -V658
with_view_model(
bt_test->view,
BtTestModel * model,
{

View File

@@ -1,10 +0,0 @@
App(
appid="direct_draw",
name="Direct Draw",
apptype=FlipperAppType.DEBUG,
entry_point="direct_draw_app",
requires=["gui", "input"],
stack_size=2 * 1024,
order=70,
fap_category="Debug",
)

View File

@@ -1,112 +0,0 @@
#include <furi.h>
#include <gui/gui.h>
#include <gui/canvas_i.h>
#include <input/input.h>
#define BUFFER_SIZE (32U)
typedef struct {
FuriPubSub* input;
FuriPubSubSubscription* input_subscription;
Gui* gui;
Canvas* canvas;
bool stop;
uint32_t counter;
} DirectDraw;
static void gui_input_events_callback(const void* value, void* ctx) {
furi_assert(value);
furi_assert(ctx);
DirectDraw* instance = ctx;
const InputEvent* event = value;
if(event->key == InputKeyBack && event->type == InputTypeShort) {
instance->stop = true;
}
}
static DirectDraw* direct_draw_alloc() {
DirectDraw* instance = malloc(sizeof(DirectDraw));
instance->input = furi_record_open(RECORD_INPUT_EVENTS);
instance->gui = furi_record_open(RECORD_GUI);
instance->canvas = gui_direct_draw_acquire(instance->gui);
instance->input_subscription =
furi_pubsub_subscribe(instance->input, gui_input_events_callback, instance);
return instance;
}
static void direct_draw_free(DirectDraw* instance) {
furi_pubsub_unsubscribe(instance->input, instance->input_subscription);
instance->canvas = NULL;
gui_direct_draw_release(instance->gui);
furi_record_close(RECORD_GUI);
furi_record_close(RECORD_INPUT_EVENTS);
}
static void direct_draw_block(Canvas* canvas, uint32_t size, uint32_t counter) {
size += 16;
uint8_t width = canvas_width(canvas) - size;
uint8_t height = canvas_height(canvas) - size;
uint8_t x = counter % width;
if((counter / width) % 2) {
x = width - x;
}
uint8_t y = counter % height;
if((counter / height) % 2) {
y = height - y;
}
canvas_draw_box(canvas, x, y, size, size);
}
static void direct_draw_run(DirectDraw* instance) {
size_t start = DWT->CYCCNT;
size_t counter = 0;
float fps = 0;
vTaskPrioritySet(furi_thread_get_current_id(), FuriThreadPriorityIdle);
do {
size_t elapsed = DWT->CYCCNT - start;
char buffer[BUFFER_SIZE] = {0};
if(elapsed >= 64000000) {
fps = (float)counter / ((float)elapsed / 64000000.0f);
start = DWT->CYCCNT;
counter = 0;
}
snprintf(buffer, BUFFER_SIZE, "FPS: %.1f", (double)fps);
canvas_reset(instance->canvas);
canvas_set_color(instance->canvas, ColorXOR);
direct_draw_block(instance->canvas, instance->counter % 16, instance->counter);
direct_draw_block(instance->canvas, instance->counter * 2 % 16, instance->counter * 2);
direct_draw_block(instance->canvas, instance->counter * 3 % 16, instance->counter * 3);
direct_draw_block(instance->canvas, instance->counter * 4 % 16, instance->counter * 4);
direct_draw_block(instance->canvas, instance->counter * 5 % 16, instance->counter * 5);
canvas_draw_str(instance->canvas, 10, 10, buffer);
canvas_commit(instance->canvas);
counter++;
instance->counter++;
furi_thread_yield();
} while(!instance->stop);
}
int32_t direct_draw_app(void* p) {
UNUSED(p);
DirectDraw* instance = direct_draw_alloc();
direct_draw_run(instance);
direct_draw_free(instance);
return 0;
}

View File

@@ -5,7 +5,6 @@ App(
entry_point="display_test_app",
cdefines=["APP_DISPLAY_TEST"],
requires=["gui"],
fap_libs=["misc"],
stack_size=1 * 1024,
order=120,
fap_category="Debug",

View File

@@ -91,6 +91,7 @@ static void display_test_reload_config(DisplayTest* instance) {
instance->config_contrast,
instance->config_regulation_ratio,
instance->config_bias);
gui_update(instance->gui);
}
static void display_config_set_bias(VariableItem* item) {

View File

@@ -1,9 +0,0 @@
App(
appid="example_custom_font",
name="Example: custom font",
apptype=FlipperAppType.DEBUG,
entry_point="example_custom_font_main",
requires=["gui"],
stack_size=1 * 1024,
fap_category="Debug",
)

View File

@@ -1,98 +0,0 @@
#include <furi.h>
#include <furi_hal.h>
#include <gui/gui.h>
#include <input/input.h>
//This arrays contains the font itself. You can use any u8g2 font you want
/*
Fontname: -Raccoon-Fixed4x6-Medium-R-Normal--6-60-75-75-P-40-ISO10646-1
Copyright:
Glyphs: 95/203
BBX Build Mode: 0
*/
const uint8_t u8g2_font_tom_thumb_4x6_tr[725] =
"_\0\2\2\2\3\3\4\4\3\6\0\377\5\377\5\0\0\352\1\330\2\270 \5\340\315\0!\6\265\310"
"\254\0\42\6\213\313$\25#\10\227\310\244\241\206\12$\10\227\310\215\70b\2%\10\227\310d\324F\1"
"&\10\227\310(\65R\22'\5\251\313\10(\6\266\310\251\62)\10\226\310\304\224\24\0*\6\217\312\244"
"\16+\7\217\311\245\225\0,\6\212\310)\0-\5\207\312\14.\5\245\310\4/\7\227\310Ve\4\60"
"\7\227\310-k\1\61\6\226\310\255\6\62\10\227\310h\220\312\1\63\11\227\310h\220\62X\0\64\10\227"
"\310$\65b\1\65\10\227\310\214\250\301\2\66\10\227\310\315\221F\0\67\10\227\310\314TF\0\70\10\227"
"\310\214\64\324\10\71\10\227\310\214\64\342\2:\6\255\311\244\0;\7\222\310e\240\0<\10\227\310\246\32"
"d\20=\6\217\311l\60>\11\227\310d\220A*\1\77\10\227\310\314\224a\2@\10\227\310UC\3"
"\1A\10\227\310UC\251\0B\10\227\310\250\264\322\2C\7\227\310\315\32\10D\10\227\310\250d-\0"
"E\10\227\310\214\70\342\0F\10\227\310\214\70b\4G\10\227\310\315\221\222\0H\10\227\310$\65\224\12"
"I\7\227\310\254X\15J\7\227\310\226\252\2K\10\227\310$\265\222\12L\7\227\310\304\346\0M\10\227"
"\310\244\61\224\12N\10\227\310\244q\250\0O\7\227\310UV\5P\10\227\310\250\264b\4Q\10\227\310"
"Uj$\1R\10\227\310\250\64V\1S\10\227\310m\220\301\2T\7\227\310\254\330\2U\7\227\310$"
"W\22V\10\227\310$\253L\0W\10\227\310$\65\206\12X\10\227\310$\325R\1Y\10\227\310$U"
"V\0Z\7\227\310\314T\16[\7\227\310\214X\16\134\10\217\311d\220A\0]\7\227\310\314r\4^"
"\5\213\313\65_\5\207\310\14`\6\212\313\304\0a\7\223\310\310\65\2b\10\227\310D\225\324\2c\7"
"\223\310\315\14\4d\10\227\310\246\245\222\0e\6\223\310\235\2f\10\227\310\246\264b\2g\10\227\307\35"
"\61%\0h\10\227\310D\225\254\0i\6\265\310\244\1j\10\233\307f\30U\5k\10\227\310\304\264T"
"\1l\7\227\310\310\326\0m\7\223\310<R\0n\7\223\310\250d\5o\7\223\310U\252\2p\10\227"
"\307\250\244V\4q\10\227\307-\225d\0r\6\223\310\315\22s\10\223\310\215\70\22\0t\10\227\310\245"
"\25\243\0u\7\223\310$+\11v\10\223\310$\65R\2w\7\223\310\244q\4x\7\223\310\244\62\25"
"y\11\227\307$\225dJ\0z\7\223\310\254\221\6{\10\227\310\251\32D\1|\6\265\310(\1}\11"
"\227\310\310\14RR\0~\6\213\313\215\4\0\0\0\4\377\377\0";
// Screen is 128x64 px
static void app_draw_callback(Canvas* canvas, void* ctx) {
UNUSED(ctx);
canvas_clear(canvas);
canvas_set_custom_u8g2_font(canvas, u8g2_font_tom_thumb_4x6_tr);
canvas_draw_str(canvas, 0, 6, "This is a tiny custom font");
canvas_draw_str(canvas, 0, 12, "012345.?! ,:;\"\'@#$%");
}
static void app_input_callback(InputEvent* input_event, void* ctx) {
furi_assert(ctx);
FuriMessageQueue* event_queue = ctx;
furi_message_queue_put(event_queue, input_event, FuriWaitForever);
}
int32_t example_custom_font_main(void* p) {
UNUSED(p);
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
// Configure view port
ViewPort* view_port = view_port_alloc();
view_port_draw_callback_set(view_port, app_draw_callback, view_port);
view_port_input_callback_set(view_port, app_input_callback, event_queue);
// Register view port in GUI
Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
InputEvent event;
bool running = true;
while(running) {
if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) {
if((event.type == InputTypePress) || (event.type == InputTypeRepeat)) {
switch(event.key) {
case InputKeyBack:
running = false;
break;
default:
break;
}
}
}
}
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
view_port_free(view_port);
furi_message_queue_free(event_queue);
furi_record_close(RECORD_GUI);
return 0;
}

View File

@@ -1,11 +1,10 @@
#include "file_browser_app_i.h"
#include <file_browser_test_icons.h>
#include <gui/modules/file_browser.h>
#include <storage/storage.h>
#include <lib/toolbox/path.h>
#include "file_browser_app_i.h"
#include "gui/modules/file_browser.h"
#include <furi.h>
#include <furi_hal.h>
#include <storage/storage.h>
#include <lib/toolbox/path.h>
static bool file_browser_app_custom_event_callback(void* context, uint32_t event) {
furi_assert(context);
@@ -49,7 +48,7 @@ FileBrowserApp* file_browser_app_alloc(char* arg) {
app->file_path = furi_string_alloc();
app->file_browser = file_browser_alloc(app->file_path);
file_browser_configure(app->file_browser, "*", NULL, true, false, &I_badusb_10px, true);
file_browser_configure(app->file_browser, "*", NULL, true, &I_badusb_10px, true);
view_dispatcher_add_view(
app->view_dispatcher, FileBrowserAppViewStart, widget_get_view(app->widget));

View File

@@ -2,7 +2,6 @@ App(
appid="lfrfid_debug",
name="LF-RFID Debug",
apptype=FlipperAppType.DEBUG,
targets=["f7"],
entry_point="lfrfid_debug_app",
requires=[
"gui",

View File

@@ -44,11 +44,7 @@ bool rpc_debug_app_scene_input_error_code_on_event(void* context, SceneManagerEv
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == RpcDebugAppCustomEventInputErrorCode) {
char* end;
int error_code = strtol(app->text_store, &end, 10);
if(!*end) {
rpc_system_app_set_error_code(app->rpc, error_code);
}
rpc_system_app_set_error_code(app->rpc, (uint32_t)atol(app->text_store));
scene_manager_previous_scene(app->scene_manager);
consumed = true;
}

View File

@@ -8,5 +8,5 @@ App(
stack_size=2 * 1024,
order=70,
fap_icon="uart_10px.png",
fap_category="GPIO",
fap_category="Misc",
)

View File

@@ -1,110 +0,0 @@
#include <furi.h>
#include <furi_hal.h>
#include "../minunit.h"
#include <bt/bt_service/bt_keys_storage.h>
#include <storage/storage.h>
#define BT_TEST_KEY_STORAGE_FILE_PATH EXT_PATH("unit_tests/bt_test.keys")
#define BT_TEST_NVM_RAM_BUFF_SIZE (507 * 4) // The same as in ble NVM storage
typedef struct {
Storage* storage;
BtKeysStorage* bt_keys_storage;
uint8_t* nvm_ram_buff_dut;
uint8_t* nvm_ram_buff_ref;
} BtTest;
BtTest* bt_test = NULL;
void bt_test_alloc() {
bt_test = malloc(sizeof(BtTest));
bt_test->storage = furi_record_open(RECORD_STORAGE);
bt_test->nvm_ram_buff_dut = malloc(BT_TEST_NVM_RAM_BUFF_SIZE);
bt_test->nvm_ram_buff_ref = malloc(BT_TEST_NVM_RAM_BUFF_SIZE);
bt_test->bt_keys_storage = bt_keys_storage_alloc(BT_TEST_KEY_STORAGE_FILE_PATH);
bt_keys_storage_set_ram_params(
bt_test->bt_keys_storage, bt_test->nvm_ram_buff_dut, BT_TEST_NVM_RAM_BUFF_SIZE);
}
void bt_test_free() {
furi_assert(bt_test);
free(bt_test->nvm_ram_buff_ref);
free(bt_test->nvm_ram_buff_dut);
bt_keys_storage_free(bt_test->bt_keys_storage);
furi_record_close(RECORD_STORAGE);
free(bt_test);
bt_test = NULL;
}
static void bt_test_keys_storage_profile() {
// Emulate nvm change on initial connection
const int nvm_change_size_on_connection = 88;
for(size_t i = 0; i < nvm_change_size_on_connection; i++) {
bt_test->nvm_ram_buff_dut[i] = rand();
bt_test->nvm_ram_buff_ref[i] = bt_test->nvm_ram_buff_dut[i];
}
// Emulate update storage on initial connect
mu_assert(
bt_keys_storage_update(
bt_test->bt_keys_storage, bt_test->nvm_ram_buff_dut, nvm_change_size_on_connection),
"Failed to update key storage on initial connect");
memset(bt_test->nvm_ram_buff_dut, 0, BT_TEST_NVM_RAM_BUFF_SIZE);
mu_assert(bt_keys_storage_load(bt_test->bt_keys_storage), "Failed to load NVM");
mu_assert(
memcmp(
bt_test->nvm_ram_buff_ref, bt_test->nvm_ram_buff_dut, nvm_change_size_on_connection) ==
0,
"Wrong buffer loaded");
const int nvm_disconnect_update_offset = 84;
const int nvm_disconnect_update_size = 324;
const int nvm_total_size = nvm_change_size_on_connection -
(nvm_change_size_on_connection - nvm_disconnect_update_offset) +
nvm_disconnect_update_size;
// Emulate update storage on initial disconnect
for(size_t i = nvm_disconnect_update_offset;
i < nvm_disconnect_update_offset + nvm_disconnect_update_size;
i++) {
bt_test->nvm_ram_buff_dut[i] = rand();
bt_test->nvm_ram_buff_ref[i] = bt_test->nvm_ram_buff_dut[i];
}
mu_assert(
bt_keys_storage_update(
bt_test->bt_keys_storage,
&bt_test->nvm_ram_buff_dut[nvm_disconnect_update_offset],
nvm_disconnect_update_size),
"Failed to update key storage on initial disconnect");
memset(bt_test->nvm_ram_buff_dut, 0, BT_TEST_NVM_RAM_BUFF_SIZE);
mu_assert(bt_keys_storage_load(bt_test->bt_keys_storage), "Failed to load NVM");
mu_assert(
memcmp(bt_test->nvm_ram_buff_ref, bt_test->nvm_ram_buff_dut, nvm_total_size) == 0,
"Wrong buffer loaded");
}
static void bt_test_keys_remove_test_file() {
mu_assert(
storage_simply_remove(bt_test->storage, BT_TEST_KEY_STORAGE_FILE_PATH),
"Can't remove test file");
}
MU_TEST(bt_test_keys_storage_serial_profile) {
furi_assert(bt_test);
bt_test_keys_remove_test_file();
bt_test_keys_storage_profile();
bt_test_keys_remove_test_file();
}
MU_TEST_SUITE(test_bt) {
bt_test_alloc();
MU_RUN_TEST(bt_test_keys_storage_serial_profile);
bt_test_free();
}
int run_minunit_test_bt() {
MU_RUN_SUITE(test_bt);
return MU_EXIT_CODE;
}

View File

@@ -1,60 +0,0 @@
#include <float.h>
#include <float_tools.h>
#include "../minunit.h"
MU_TEST(float_tools_equal_test) {
mu_check(float_is_equal(FLT_MAX, FLT_MAX));
mu_check(float_is_equal(FLT_MIN, FLT_MIN));
mu_check(float_is_equal(-FLT_MAX, -FLT_MAX));
mu_check(float_is_equal(-FLT_MIN, -FLT_MIN));
mu_check(!float_is_equal(FLT_MIN, FLT_MAX));
mu_check(!float_is_equal(-FLT_MIN, FLT_MAX));
mu_check(!float_is_equal(FLT_MIN, -FLT_MAX));
mu_check(!float_is_equal(-FLT_MIN, -FLT_MAX));
const float pi = 3.14159f;
mu_check(float_is_equal(pi, pi));
mu_check(float_is_equal(-pi, -pi));
mu_check(!float_is_equal(pi, -pi));
mu_check(!float_is_equal(-pi, pi));
const float one_third = 1.f / 3.f;
const float one_third_dec = 0.3333333f;
mu_check(one_third != one_third_dec);
mu_check(float_is_equal(one_third, one_third_dec));
const float big_num = 1.e12f;
const float med_num = 95.389f;
const float smol_num = 1.e-12f;
mu_check(float_is_equal(big_num, big_num));
mu_check(float_is_equal(med_num, med_num));
mu_check(float_is_equal(smol_num, smol_num));
mu_check(!float_is_equal(smol_num, big_num));
mu_check(!float_is_equal(med_num, smol_num));
mu_check(!float_is_equal(big_num, med_num));
const float more_than_one = 1.f + FLT_EPSILON;
const float less_than_one = 1.f - FLT_EPSILON;
mu_check(!float_is_equal(more_than_one, less_than_one));
mu_check(!float_is_equal(more_than_one, -less_than_one));
mu_check(!float_is_equal(-more_than_one, less_than_one));
mu_check(!float_is_equal(-more_than_one, -less_than_one));
const float slightly_more_than_one = 1.f + FLT_EPSILON / 2.f;
const float slightly_less_than_one = 1.f - FLT_EPSILON / 2.f;
mu_check(float_is_equal(slightly_more_than_one, slightly_less_than_one));
mu_check(float_is_equal(-slightly_more_than_one, -slightly_less_than_one));
mu_check(!float_is_equal(slightly_more_than_one, -slightly_less_than_one));
mu_check(!float_is_equal(-slightly_more_than_one, slightly_less_than_one));
}
MU_TEST_SUITE(float_tools_suite) {
MU_RUN_TEST(float_tools_equal_test);
}
int run_minunit_test_float_tools() {
MU_RUN_SUITE(float_tools_suite);
return MU_EXIT_CODE;
}

View File

@@ -3,37 +3,98 @@
#include <string.h>
#include <stdbool.h>
// this test is not accurate, but gives a basic understanding
// that memory management is working fine
// do not include memmgr.h here
// we also test that we are linking against stdlib
extern size_t memmgr_get_free_heap(void);
extern size_t memmgr_get_minimum_free_heap(void);
// current heap management realization consume:
// X bytes after allocate and 0 bytes after allocate and free,
// where X = sizeof(void*) + sizeof(size_t), look to BlockLink_t
const size_t heap_overhead_max_size = sizeof(void*) + sizeof(size_t);
bool heap_equal(size_t heap_size, size_t heap_size_old) {
// heap borders with overhead
const size_t heap_low = heap_size_old - heap_overhead_max_size;
const size_t heap_high = heap_size_old + heap_overhead_max_size;
// not exact, so we must test it against bigger numbers than "overhead size"
const bool result = ((heap_size >= heap_low) && (heap_size <= heap_high));
// debug allocation info
if(!result) {
printf("\n(hl: %zu) <= (p: %zu) <= (hh: %zu)\n", heap_low, heap_size, heap_high);
}
return result;
}
void test_furi_memmgr() {
void* ptr;
size_t heap_size = 0;
size_t heap_size_old = 0;
const int alloc_size = 128;
void* ptr = NULL;
void* original_ptr = NULL;
// do not include furi memmgr.h case
#ifdef FURI_MEMMGR_GUARD
mu_fail("do not link against furi memmgr.h");
#endif
// allocate memory case
ptr = malloc(100);
mu_check(ptr != NULL);
// test that memory is zero-initialized after allocation
for(int i = 0; i < 100; i++) {
mu_assert_int_eq(0, ((uint8_t*)ptr)[i]);
}
heap_size_old = memmgr_get_free_heap();
ptr = malloc(alloc_size);
heap_size = memmgr_get_free_heap();
mu_assert_pointers_not_eq(ptr, NULL);
mu_assert(heap_equal(heap_size, heap_size_old - alloc_size), "allocate failed");
// free memory case
heap_size_old = memmgr_get_free_heap();
free(ptr);
ptr = NULL;
heap_size = memmgr_get_free_heap();
mu_assert(heap_equal(heap_size, heap_size_old + alloc_size), "free failed");
// reallocate memory case
ptr = malloc(100);
memset(ptr, 66, 100);
ptr = realloc(ptr, 200);
mu_check(ptr != NULL);
// test that memory is really reallocated
for(int i = 0; i < 100; i++) {
mu_assert_int_eq(66, ((uint8_t*)ptr)[i]);
// get filled array with some data
original_ptr = malloc(alloc_size);
mu_assert_pointers_not_eq(original_ptr, NULL);
for(int i = 0; i < alloc_size; i++) {
*(unsigned char*)(original_ptr + i) = i;
}
// TODO: fix realloc to copy only old size, and write testcase that leftover of reallocated memory is zero-initialized
// malloc array and copy data
ptr = malloc(alloc_size);
mu_assert_pointers_not_eq(ptr, NULL);
memcpy(ptr, original_ptr, alloc_size);
// reallocate array
heap_size_old = memmgr_get_free_heap();
ptr = realloc(ptr, alloc_size * 2);
heap_size = memmgr_get_free_heap();
mu_assert(heap_equal(heap_size, heap_size_old - alloc_size), "reallocate failed");
mu_assert_int_eq(memcmp(original_ptr, ptr, alloc_size), 0);
free(original_ptr);
free(ptr);
// allocate and zero-initialize array (calloc)
ptr = calloc(100, 2);
mu_check(ptr != NULL);
for(int i = 0; i < 100 * 2; i++) {
mu_assert_int_eq(0, ((uint8_t*)ptr)[i]);
original_ptr = malloc(alloc_size);
mu_assert_pointers_not_eq(original_ptr, NULL);
for(int i = 0; i < alloc_size; i++) {
*(unsigned char*)(original_ptr + i) = 0;
}
heap_size_old = memmgr_get_free_heap();
ptr = calloc(1, alloc_size);
heap_size = memmgr_get_free_heap();
mu_assert(heap_equal(heap_size, heap_size_old - alloc_size), "callocate failed");
mu_assert_int_eq(memcmp(original_ptr, ptr, alloc_size), 0);
free(original_ptr);
free(ptr);
}

View File

@@ -1,75 +0,0 @@
#include <furi.c>
#include "../minunit.h"
#include <update_util/resources/manifest.h>
#define TAG "Manifest"
MU_TEST(manifest_type_test) {
mu_assert(ResourceManifestEntryTypeUnknown == 0, "ResourceManifestEntryTypeUnknown != 0\r\n");
mu_assert(ResourceManifestEntryTypeVersion == 1, "ResourceManifestEntryTypeVersion != 1\r\n");
mu_assert(
ResourceManifestEntryTypeTimestamp == 2, "ResourceManifestEntryTypeTimestamp != 2\r\n");
mu_assert(
ResourceManifestEntryTypeDirectory == 3, "ResourceManifestEntryTypeDirectory != 3\r\n");
mu_assert(ResourceManifestEntryTypeFile == 4, "ResourceManifestEntryTypeFile != 4\r\n");
}
MU_TEST(manifest_iteration_test) {
bool result = true;
size_t counters[5] = {0};
Storage* storage = furi_record_open(RECORD_STORAGE);
ResourceManifestReader* manifest_reader = resource_manifest_reader_alloc(storage);
do {
// Open manifest file
if(!resource_manifest_reader_open(manifest_reader, EXT_PATH("unit_tests/Manifest"))) {
result = false;
break;
}
// Iterate forward
ResourceManifestEntry* entry_ptr = NULL;
while((entry_ptr = resource_manifest_reader_next(manifest_reader))) {
FURI_LOG_D(TAG, "F:%u:%s", entry_ptr->type, furi_string_get_cstr(entry_ptr->name));
if(entry_ptr->type > 4) {
mu_fail("entry_ptr->type > 4\r\n");
result = false;
break;
}
counters[entry_ptr->type]++;
}
if(!result) break;
// Iterate backward
while((entry_ptr = resource_manifest_reader_previous(manifest_reader))) {
FURI_LOG_D(TAG, "B:%u:%s", entry_ptr->type, furi_string_get_cstr(entry_ptr->name));
if(entry_ptr->type > 4) {
mu_fail("entry_ptr->type > 4\r\n");
result = false;
break;
}
counters[entry_ptr->type]--;
}
} while(false);
resource_manifest_reader_free(manifest_reader);
furi_record_close(RECORD_STORAGE);
mu_assert(counters[ResourceManifestEntryTypeUnknown] == 0, "Unknown counter != 0\r\n");
mu_assert(counters[ResourceManifestEntryTypeVersion] == 0, "Version counter != 0\r\n");
mu_assert(counters[ResourceManifestEntryTypeTimestamp] == 0, "Timestamp counter != 0\r\n");
mu_assert(counters[ResourceManifestEntryTypeDirectory] == 0, "Directory counter != 0\r\n");
mu_assert(counters[ResourceManifestEntryTypeFile] == 0, "File counter != 0\r\n");
mu_assert(result, "Manifest forward iterate failed\r\n");
}
MU_TEST_SUITE(manifest_suite) {
MU_RUN_TEST(manifest_type_test);
MU_RUN_TEST(manifest_iteration_test);
}
int run_minunit_test_manifest() {
MU_RUN_SUITE(manifest_suite);
return MU_EXIT_CODE;
}

View File

@@ -348,37 +348,13 @@ static void mf_classic_generator_test(uint8_t uid_len, MfClassicType type) {
memcpy(atqa, nfc_dev->dev_data.nfc_data.atqa, 2);
MfClassicData* mf_data = &nfc_dev->dev_data.mf_classic_data;
// Check the manufacturer block (should be uid[uid_len] + BCC (for 4byte only) + SAK + ATQA0 + ATQA1 + 0xFF[rest])
// Check the manufacturer block (should be uid[uid_len] + 0xFF[rest])
uint8_t manufacturer_block[16] = {0};
memcpy(manufacturer_block, nfc_dev->dev_data.mf_classic_data.block[0].value, 16);
mu_assert(
memcmp(manufacturer_block, uid, uid_len) == 0,
"manufacturer_block uid doesn't match the file\r\n");
uint8_t position = 0;
if(uid_len == 4) {
position = uid_len;
uint8_t bcc = 0;
for(int i = 0; i < uid_len; i++) {
bcc ^= uid[i];
}
mu_assert(manufacturer_block[position] == bcc, "manufacturer_block bcc assert failed\r\n");
} else {
position = uid_len - 1;
}
mu_assert(manufacturer_block[position + 1] == sak, "manufacturer_block sak assert failed\r\n");
mu_assert(
manufacturer_block[position + 2] == atqa[0], "manufacturer_block atqa0 assert failed\r\n");
mu_assert(
manufacturer_block[position + 3] == atqa[1], "manufacturer_block atqa1 assert failed\r\n");
for(uint8_t i = position + 4; i < 16; i++) {
for(uint8_t i = uid_len; i < 16; i++) {
mu_assert(
manufacturer_block[i] == 0xFF, "manufacturer_block[i] == 0xFF assert failed\r\n");
}
@@ -490,10 +466,6 @@ static void mf_classic_generator_test(uint8_t uid_len, MfClassicType type) {
nfc_device_free(nfc_keys);
}
MU_TEST(mf_mini_file_test) {
mf_classic_generator_test(4, MfClassicTypeMini);
}
MU_TEST(mf_classic_1k_4b_file_test) {
mf_classic_generator_test(4, MfClassicType1k);
}
@@ -514,7 +486,6 @@ MU_TEST_SUITE(nfc) {
nfc_test_alloc();
MU_RUN_TEST(nfca_file_test);
MU_RUN_TEST(mf_mini_file_test);
MU_RUN_TEST(mf_classic_1k_4b_file_test);
MU_RUN_TEST(mf_classic_4k_4b_file_test);
MU_RUN_TEST(mf_classic_1k_7b_file_test);

View File

@@ -89,7 +89,7 @@ static void test_rpc_setup(void) {
}
furi_check(rpc_session[0].session);
rpc_session[0].output_stream = furi_stream_buffer_alloc(4096, 1);
rpc_session[0].output_stream = furi_stream_buffer_alloc(1000, 1);
rpc_session_set_send_bytes_callback(rpc_session[0].session, output_bytes_callback);
rpc_session[0].close_session_semaphore = xSemaphoreCreateBinary();
rpc_session[0].terminate_semaphore = xSemaphoreCreateBinary();

View File

@@ -72,32 +72,8 @@ MU_TEST_1(stream_composite_subtest, Stream* stream) {
mu_check(stream_seek(stream, -3, StreamOffsetFromEnd));
mu_check(stream_tell(stream) == 4);
// test seeks to char. content: '1337_69'
stream_rewind(stream);
mu_check(stream_seek_to_char(stream, '3', StreamDirectionForward));
mu_check(stream_tell(stream) == 1);
mu_check(stream_seek_to_char(stream, '3', StreamDirectionForward));
mu_check(stream_tell(stream) == 2);
mu_check(stream_seek_to_char(stream, '_', StreamDirectionForward));
mu_check(stream_tell(stream) == 4);
mu_check(stream_seek_to_char(stream, '9', StreamDirectionForward));
mu_check(stream_tell(stream) == 6);
mu_check(!stream_seek_to_char(stream, '9', StreamDirectionForward));
mu_check(stream_tell(stream) == 6);
mu_check(stream_seek_to_char(stream, '_', StreamDirectionBackward));
mu_check(stream_tell(stream) == 4);
mu_check(stream_seek_to_char(stream, '3', StreamDirectionBackward));
mu_check(stream_tell(stream) == 2);
mu_check(stream_seek_to_char(stream, '3', StreamDirectionBackward));
mu_check(stream_tell(stream) == 1);
mu_check(!stream_seek_to_char(stream, '3', StreamDirectionBackward));
mu_check(stream_tell(stream) == 1);
mu_check(stream_seek_to_char(stream, '1', StreamDirectionBackward));
mu_check(stream_tell(stream) == 0);
// write string with replacement
// write string with replacemet
// "1337_69" -> "1337lee"
mu_check(stream_seek(stream, 4, StreamOffsetFromStart));
mu_check(stream_write_string(stream, string_lee) == 3);
mu_check(stream_size(stream) == 7);
mu_check(stream_tell(stream) == 7);

View File

@@ -12,9 +12,8 @@
#define KEYSTORE_DIR_NAME EXT_PATH("subghz/assets/keeloq_mfcodes")
#define CAME_ATOMO_DIR_NAME EXT_PATH("subghz/assets/came_atomo")
#define NICE_FLOR_S_DIR_NAME EXT_PATH("subghz/assets/nice_flor_s")
#define ALUTECH_AT_4N_DIR_NAME EXT_PATH("subghz/assets/alutech_at_4n")
#define TEST_RANDOM_DIR_NAME EXT_PATH("unit_tests/subghz/test_random_raw.sub")
#define TEST_RANDOM_COUNT_PARSE 329
#define TEST_RANDOM_COUNT_PARSE 253
#define TEST_TIMEOUT 10000
static SubGhzEnvironment* environment_handler;
@@ -44,8 +43,6 @@ static void subghz_test_init(void) {
environment_handler, CAME_ATOMO_DIR_NAME);
subghz_environment_set_nice_flor_s_rainbow_table_file_name(
environment_handler, NICE_FLOR_S_DIR_NAME);
subghz_environment_set_alutech_at_4n_rainbow_table_file_name(
environment_handler, ALUTECH_AT_4N_DIR_NAME);
subghz_environment_set_protocol_registry(
environment_handler, (void*)&subghz_protocol_registry);
@@ -321,10 +318,7 @@ bool subghz_hal_async_tx_test_run(SubGhzHalAsyncTxTestType type) {
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
furi_hal_subghz_set_frequency_and_path(433920000);
if(!furi_hal_subghz_start_async_tx(subghz_hal_async_tx_test_yield, &test)) {
return false;
}
furi_hal_subghz_start_async_tx(subghz_hal_async_tx_test_yield, &test);
while(!furi_hal_subghz_is_async_tx_complete()) {
furi_delay_ms(10);
}
@@ -492,14 +486,6 @@ MU_TEST(subghz_decoder_linear_test) {
"Test decoder " SUBGHZ_PROTOCOL_LINEAR_NAME " error\r\n");
}
MU_TEST(subghz_decoder_linear_delta3_test) {
mu_assert(
subghz_decoder_test(
EXT_PATH("unit_tests/subghz/linear_delta3_raw.sub"),
SUBGHZ_PROTOCOL_LINEAR_DELTA3_NAME),
"Test decoder " SUBGHZ_PROTOCOL_LINEAR_DELTA3_NAME " error\r\n");
}
MU_TEST(subghz_decoder_megacode_test) {
mu_assert(
subghz_decoder_test(
@@ -608,43 +594,6 @@ MU_TEST(subghz_decoder_smc5326_test) {
"Test decoder " SUBGHZ_PROTOCOL_SMC5326_NAME " error\r\n");
}
MU_TEST(subghz_decoder_holtek_ht12x_test) {
mu_assert(
subghz_decoder_test(
EXT_PATH("unit_tests/subghz/holtek_ht12x_raw.sub"), SUBGHZ_PROTOCOL_HOLTEK_HT12X_NAME),
"Test decoder " SUBGHZ_PROTOCOL_HOLTEK_HT12X_NAME " error\r\n");
}
MU_TEST(subghz_decoder_dooya_test) {
mu_assert(
subghz_decoder_test(
EXT_PATH("unit_tests/subghz/dooya_raw.sub"), SUBGHZ_PROTOCOL_DOOYA_NAME),
"Test decoder " SUBGHZ_PROTOCOL_DOOYA_NAME " error\r\n");
}
MU_TEST(subghz_decoder_alutech_at_4n_test) {
mu_assert(
subghz_decoder_test(
EXT_PATH("unit_tests/subghz/alutech_at_4n_raw.sub"),
SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME),
"Test decoder " SUBGHZ_PROTOCOL_ALUTECH_AT_4N_NAME " error\r\n");
}
MU_TEST(subghz_decoder_nice_one_test) {
mu_assert(
subghz_decoder_test(
EXT_PATH("unit_tests/subghz/nice_one_raw.sub"), SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME),
"Test decoder " SUBGHZ_PROTOCOL_NICE_FLOR_S_NAME " error\r\n");
}
MU_TEST(subghz_decoder_kinggates_stylo4k_test) {
mu_assert(
subghz_decoder_test(
EXT_PATH("unit_tests/subghz/kinggates_stylo4k_raw.sub"),
SUBGHZ_PROTOCOL_KINGGATES_STYLO_4K_NAME),
"Test decoder " SUBGHZ_PROTOCOL_KINGGATES_STYLO_4K_NAME " error\r\n");
}
//test encoders
MU_TEST(subghz_encoder_princeton_test) {
mu_assert(
@@ -688,12 +637,6 @@ MU_TEST(subghz_encoder_linear_test) {
"Test encoder " SUBGHZ_PROTOCOL_LINEAR_NAME " error\r\n");
}
MU_TEST(subghz_encoder_linear_delta3_test) {
mu_assert(
subghz_encoder_test(EXT_PATH("unit_tests/subghz/linear_delta3.sub")),
"Test encoder " SUBGHZ_PROTOCOL_LINEAR_DELTA3_NAME " error\r\n");
}
MU_TEST(subghz_encoder_megacode_test) {
mu_assert(
subghz_encoder_test(EXT_PATH("unit_tests/subghz/megacode.sub")),
@@ -784,18 +727,6 @@ MU_TEST(subghz_encoder_smc5326_test) {
"Test encoder " SUBGHZ_PROTOCOL_SMC5326_NAME " error\r\n");
}
MU_TEST(subghz_encoder_holtek_ht12x_test) {
mu_assert(
subghz_encoder_test(EXT_PATH("unit_tests/subghz/holtek_ht12x.sub")),
"Test encoder " SUBGHZ_PROTOCOL_HOLTEK_HT12X_NAME " error\r\n");
}
MU_TEST(subghz_encoder_dooya_test) {
mu_assert(
subghz_encoder_test(EXT_PATH("unit_tests/subghz/dooya.sub")),
"Test encoder " SUBGHZ_PROTOCOL_DOOYA_NAME " error\r\n");
}
MU_TEST(subghz_random_test) {
mu_assert(subghz_decode_random_test(TEST_RANDOM_DIR_NAME), "Random test error\r\n");
}
@@ -825,7 +756,6 @@ MU_TEST_SUITE(subghz) {
MU_RUN_TEST(subghz_decoder_somfy_telis_test);
MU_RUN_TEST(subghz_decoder_star_line_test);
MU_RUN_TEST(subghz_decoder_linear_test);
MU_RUN_TEST(subghz_decoder_linear_delta3_test);
MU_RUN_TEST(subghz_decoder_megacode_test);
MU_RUN_TEST(subghz_decoder_secplus_v1_test);
MU_RUN_TEST(subghz_decoder_secplus_v2_test);
@@ -841,11 +771,6 @@ MU_TEST_SUITE(subghz) {
MU_RUN_TEST(subghz_decoder_clemsa_test);
MU_RUN_TEST(subghz_decoder_ansonic_test);
MU_RUN_TEST(subghz_decoder_smc5326_test);
MU_RUN_TEST(subghz_decoder_holtek_ht12x_test);
MU_RUN_TEST(subghz_decoder_dooya_test);
MU_RUN_TEST(subghz_decoder_alutech_at_4n_test);
MU_RUN_TEST(subghz_decoder_nice_one_test);
MU_RUN_TEST(subghz_decoder_kinggates_stylo4k_test);
MU_RUN_TEST(subghz_encoder_princeton_test);
MU_RUN_TEST(subghz_encoder_came_test);
@@ -854,7 +779,6 @@ MU_TEST_SUITE(subghz) {
MU_RUN_TEST(subghz_encoder_nice_flo_test);
MU_RUN_TEST(subghz_encoder_keelog_test);
MU_RUN_TEST(subghz_encoder_linear_test);
MU_RUN_TEST(subghz_encoder_linear_delta3_test);
MU_RUN_TEST(subghz_encoder_megacode_test);
MU_RUN_TEST(subghz_encoder_holtek_test);
MU_RUN_TEST(subghz_encoder_secplus_v1_test);
@@ -870,8 +794,6 @@ MU_TEST_SUITE(subghz) {
MU_RUN_TEST(subghz_encoder_clemsa_test);
MU_RUN_TEST(subghz_encoder_ansonic_test);
MU_RUN_TEST(subghz_encoder_smc5326_test);
MU_RUN_TEST(subghz_encoder_holtek_ht12x_test);
MU_RUN_TEST(subghz_encoder_dooya_test);
MU_RUN_TEST(subghz_random_test);
subghz_test_deinit();

View File

@@ -13,7 +13,6 @@ int run_minunit_test_furi_hal();
int run_minunit_test_furi_string();
int run_minunit_test_infrared();
int run_minunit_test_rpc();
int run_minunit_test_manifest();
int run_minunit_test_flipper_format();
int run_minunit_test_flipper_format_string();
int run_minunit_test_stream();
@@ -25,8 +24,6 @@ int run_minunit_test_protocol_dict();
int run_minunit_test_lfrfid_protocols();
int run_minunit_test_nfc();
int run_minunit_test_bit_lib();
int run_minunit_test_float_tools();
int run_minunit_test_bt();
typedef int (*UnitTestEntry)();
@@ -42,7 +39,6 @@ const UnitTest unit_tests[] = {
{.name = "storage", .entry = run_minunit_test_storage},
{.name = "stream", .entry = run_minunit_test_stream},
{.name = "dirwalk", .entry = run_minunit_test_dirwalk},
{.name = "manifest", .entry = run_minunit_test_manifest},
{.name = "flipper_format", .entry = run_minunit_test_flipper_format},
{.name = "flipper_format_string", .entry = run_minunit_test_flipper_format_string},
{.name = "rpc", .entry = run_minunit_test_rpc},
@@ -53,8 +49,6 @@ const UnitTest unit_tests[] = {
{.name = "protocol_dict", .entry = run_minunit_test_protocol_dict},
{.name = "lfrfid", .entry = run_minunit_test_lfrfid_protocols},
{.name = "bit_lib", .entry = run_minunit_test_bit_lib},
{.name = "float_tools", .entry = run_minunit_test_float_tools},
{.name = "bt", .entry = run_minunit_test_bt},
};
void minunit_print_progress() {
@@ -70,13 +64,14 @@ void minunit_print_progress() {
}
void minunit_print_fail(const char* str) {
printf(_FURI_LOG_CLR_E "%s\r\n" _FURI_LOG_CLR_RESET, str);
printf(FURI_LOG_CLR_E "%s\r\n" FURI_LOG_CLR_RESET, str);
}
void unit_tests_cli(Cli* cli, FuriString* args, void* context) {
UNUSED(cli);
UNUSED(args);
UNUSED(context);
uint32_t failed_tests = 0;
minunit_run = 0;
minunit_assert = 0;
minunit_fail = 0;
@@ -102,35 +97,32 @@ void unit_tests_cli(Cli* cli, FuriString* args, void* context) {
if(furi_string_size(args)) {
if(furi_string_cmp_str(args, unit_tests[i].name) == 0) {
unit_tests[i].entry();
failed_tests += unit_tests[i].entry();
} else {
printf("Skipping %s\r\n", unit_tests[i].name);
}
} else {
unit_tests[i].entry();
failed_tests += unit_tests[i].entry();
}
}
printf("\r\nFailed tests: %lu\r\n", failed_tests);
if(minunit_run != 0) {
printf("\r\nFailed tests: %u\r\n", minunit_fail);
// Time report
cycle_counter = (furi_get_tick() - cycle_counter);
printf("Consumed: %lu ms\r\n", cycle_counter);
// Time report
cycle_counter = (furi_get_tick() - cycle_counter);
printf("Consumed: %lu ms\r\n", cycle_counter);
// Wait for tested services and apps to deallocate memory
furi_delay_ms(200);
uint32_t heap_after = memmgr_get_free_heap();
printf("Leaked: %ld\r\n", heap_before - heap_after);
// Wait for tested services and apps to deallocate memory
furi_delay_ms(200);
uint32_t heap_after = memmgr_get_free_heap();
printf("Leaked: %ld\r\n", heap_before - heap_after);
// Final Report
if(minunit_fail == 0) {
notification_message(notification, &sequence_success);
printf("Status: PASSED\r\n");
} else {
notification_message(notification, &sequence_error);
printf("Status: FAILED\r\n");
}
// Final Report
if(failed_tests == 0) {
notification_message(notification, &sequence_success);
printf("Status: PASSED\r\n");
} else {
notification_message(notification, &sequence_error);
printf("Status: FAILED\r\n");
}
}

View File

@@ -1,5 +1,5 @@
App(
appid="example_apps",
name="Example apps bundle",
appid="sample_apps",
name="Sample apps bundle",
apptype=FlipperAppType.METAPACKAGE,
)

View File

@@ -1,44 +0,0 @@
# 1-Wire Thermometer
This example application demonstrates the use of the 1-Wire library with a DS18B20 thermometer.
It also covers basic GUI, input handling, threads and localisation.
## Electrical connections
Before launching the application, connect the sensor to Flipper's external GPIO according to the table below:
| DS18B20 | Flipper |
| :-----: | :-----: |
| VDD | 9 |
| GND | 18 |
| DQ | 17 |
*NOTE 1*: GND is also available on pins 8 and 11.
*NOTE 2*: For any other pin than 17, connect an external 4.7k pull-up resistor to pin 9.
## Launching the application
In order to launch this demo, follow the steps below:
1. Make sure your Flipper has an SD card installed.
2. Connect your Flipper to the computer via a USB cable.
3. Run `./fbt launch_app APPSRC=example_thermo` in your terminal emulator of choice.
## Changing the data pin
It is possible to use other GPIO pin as a 1-Wire data pin. In order to change it, set the `THERMO_GPIO_PIN` macro to any of the options listed below:
```c
/* Possible GPIO pin choices:
- gpio_ext_pc0
- gpio_ext_pc1
- gpio_ext_pc3
- gpio_ext_pb2
- gpio_ext_pb3
- gpio_ext_pa4
- gpio_ext_pa6
- gpio_ext_pa7
- ibutton_gpio
*/
#define THERMO_GPIO_PIN (ibutton_gpio)
```
Do not forget about the external pull-up resistor as these pins do not have one built-in.
With the changes been made, recompile and launch the application again.
The on-screen text should reflect it by asking to connect the thermometer to another pin.

View File

@@ -1,10 +0,0 @@
App(
appid="example_thermo",
name="Example: Thermometer",
apptype=FlipperAppType.EXTERNAL,
entry_point="example_thermo_main",
requires=["gui"],
stack_size=1 * 1024,
fap_icon="example_thermo_10px.png",
fap_category="Examples",
)

View File

@@ -1,356 +0,0 @@
/*
* This file contains an example application that reads and displays
* the temperature from a DS18B20 1-wire thermometer.
*
* It also covers basic GUI, input handling, threads and localisation.
*
* References:
* [1] DS18B20 Datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/DS18B20.pdf
*/
#include <gui/gui.h>
#include <gui/view_port.h>
#include <core/thread.h>
#include <core/kernel.h>
#include <locale/locale.h>
#include <one_wire/maxim_crc.h>
#include <one_wire/one_wire_host.h>
#define UPDATE_PERIOD_MS 1000UL
#define TEXT_STORE_SIZE 64U
#define DS18B20_CMD_CONVERT 0x44U
#define DS18B20_CMD_READ_SCRATCHPAD 0xbeU
#define DS18B20_CFG_RESOLUTION_POS 5U
#define DS18B20_CFG_RESOLUTION_MASK 0x03U
#define DS18B20_DECIMAL_PART_MASK 0x0fU
#define DS18B20_SIGN_MASK 0xf0U
/* Possible GPIO pin choices:
- gpio_ext_pc0
- gpio_ext_pc1
- gpio_ext_pc3
- gpio_ext_pb2
- gpio_ext_pb3
- gpio_ext_pa4
- gpio_ext_pa6
- gpio_ext_pa7
- ibutton_gpio
*/
#define THERMO_GPIO_PIN (ibutton_gpio)
/* Flags which the reader thread responds to */
typedef enum {
ReaderThreadFlagExit = 1,
} ReaderThreadFlag;
typedef union {
struct {
uint8_t temp_lsb; /* Least significant byte of the temperature */
uint8_t temp_msb; /* Most significant byte of the temperature */
uint8_t user_alarm_high; /* User register 1 (Temp high alarm) */
uint8_t user_alarm_low; /* User register 2 (Temp low alarm) */
uint8_t config; /* Configuration register */
uint8_t reserved[3]; /* Not used */
uint8_t crc; /* CRC checksum for error detection */
} fields;
uint8_t bytes[9];
} DS18B20Scratchpad;
/* Application context structure */
typedef struct {
Gui* gui;
ViewPort* view_port;
FuriThread* reader_thread;
FuriMessageQueue* event_queue;
OneWireHost* onewire;
float temp_celsius;
bool has_device;
} ExampleThermoContext;
/*************** 1-Wire Communication and Processing *****************/
/* Commands the thermometer to begin measuring the temperature. */
static void example_thermo_request_temperature(ExampleThermoContext* context) {
OneWireHost* onewire = context->onewire;
/* All 1-wire transactions must happen in a critical section, i.e
not interrupted by other threads. */
FURI_CRITICAL_ENTER();
bool success = false;
do {
/* Each communication with a 1-wire device starts by a reset.
The functon will return true if a device responded with a presence pulse. */
if(!onewire_host_reset(onewire)) break;
/* After the reset, a ROM operation must follow.
If there is only one device connected, the "Skip ROM" command is most appropriate
(it can also be used to address all of the connected devices in some cases).*/
onewire_host_skip(onewire);
/* After the ROM operation, a device-specific command is issued.
In this case, it's a request to start measuring the temperature. */
onewire_host_write(onewire, DS18B20_CMD_CONVERT);
success = true;
} while(false);
context->has_device = success;
FURI_CRITICAL_EXIT();
}
/* Reads the measured temperature from the thermometer. */
static void example_thermo_read_temperature(ExampleThermoContext* context) {
/* If there was no device detected, don't try to read the temperature */
if(!context->has_device) {
return;
}
OneWireHost* onewire = context->onewire;
/* All 1-wire transactions must happen in a critical section, i.e
not interrupted by other threads. */
FURI_CRITICAL_ENTER();
bool success = false;
do {
DS18B20Scratchpad buf;
/* Attempt reading the temperature 10 times before giving up */
size_t attempts_left = 10;
do {
/* Each communication with a 1-wire device starts by a reset.
The functon will return true if a device responded with a presence pulse. */
if(!onewire_host_reset(onewire)) continue;
/* After the reset, a ROM operation must follow.
If there is only one device connected, the "Skip ROM" command is most appropriate
(it can also be used to address all of the connected devices in some cases).*/
onewire_host_skip(onewire);
/* After the ROM operation, a device-specific command is issued.
This time, it will be the "Read Scratchpad" command which will
prepare the device's internal buffer memory for reading. */
onewire_host_write(onewire, DS18B20_CMD_READ_SCRATCHPAD);
/* The actual reading happens here. A total of 9 bytes is read. */
onewire_host_read_bytes(onewire, buf.bytes, sizeof(buf.bytes));
/* Calculate the checksum and compare it with one provided by the device. */
const uint8_t crc = maxim_crc8(buf.bytes, sizeof(buf.bytes) - 1, MAXIM_CRC8_INIT);
/* Checksums match, exit the loop */
if(crc == buf.fields.crc) break;
} while(--attempts_left);
if(attempts_left == 0) break;
/* Get the measurement resolution from the configuration register. (See [1] page 9) */
const uint8_t resolution_mode = (buf.fields.config >> DS18B20_CFG_RESOLUTION_POS) &
DS18B20_CFG_RESOLUTION_MASK;
/* Generate a mask for undefined bits in the decimal part. (See [1] page 6) */
const uint8_t decimal_mask =
(DS18B20_DECIMAL_PART_MASK << (DS18B20_CFG_RESOLUTION_MASK - resolution_mode)) &
DS18B20_DECIMAL_PART_MASK;
/* Get the integer and decimal part of the temperature (See [1] page 6) */
const uint8_t integer_part = (buf.fields.temp_msb << 4U) | (buf.fields.temp_lsb >> 4U);
const uint8_t decimal_part = buf.fields.temp_lsb & decimal_mask;
/* Calculate the sign of the temperature (See [1] page 6) */
const bool is_negative = (buf.fields.temp_msb & DS18B20_SIGN_MASK) != 0;
/* Combine the integer and decimal part together */
const float temp_celsius_abs = integer_part + decimal_part / 16.f;
/* Set the appropriate sign */
context->temp_celsius = is_negative ? -temp_celsius_abs : temp_celsius_abs;
success = true;
} while(false);
context->has_device = success;
FURI_CRITICAL_EXIT();
}
/* Periodically requests measurements and reads temperature. This function runs in a separare thread. */
static int32_t example_thermo_reader_thread_callback(void* ctx) {
ExampleThermoContext* context = ctx;
for(;;) {
/* Tell the termometer to start measuring the temperature. The process may take up to 750ms. */
example_thermo_request_temperature(context);
/* Wait for the measurement to finish. At the same time wait for an exit signal. */
const uint32_t flags =
furi_thread_flags_wait(ReaderThreadFlagExit, FuriFlagWaitAny, UPDATE_PERIOD_MS);
/* If an exit signal was received, return from this thread. */
if(flags != (unsigned)FuriFlagErrorTimeout) break;
/* The measurement is now ready, read it from the termometer. */
example_thermo_read_temperature(context);
}
return 0;
}
/*************** GUI, Input and Main Loop *****************/
/* Draw the GUI of the application. The screen is completely redrawn during each call. */
static void example_thermo_draw_callback(Canvas* canvas, void* ctx) {
ExampleThermoContext* context = ctx;
char text_store[TEXT_STORE_SIZE];
const size_t middle_x = canvas_width(canvas) / 2U;
canvas_set_font(canvas, FontPrimary);
canvas_draw_str_aligned(canvas, middle_x, 12, AlignCenter, AlignBottom, "Thermometer Demo");
canvas_draw_line(canvas, 0, 16, 128, 16);
canvas_set_font(canvas, FontSecondary);
canvas_draw_str_aligned(
canvas, middle_x, 30, AlignCenter, AlignBottom, "Connnect thermometer");
snprintf(
text_store,
TEXT_STORE_SIZE,
"to GPIO pin %ld",
furi_hal_resources_get_ext_pin_number(&THERMO_GPIO_PIN));
canvas_draw_str_aligned(canvas, middle_x, 42, AlignCenter, AlignBottom, text_store);
canvas_set_font(canvas, FontKeyboard);
if(context->has_device) {
float temp;
char temp_units;
/* The applicaton is locale-aware.
Change Settings->System->Units to check it out. */
switch(locale_get_measurement_unit()) {
case LocaleMeasurementUnitsMetric:
temp = context->temp_celsius;
temp_units = 'C';
break;
case LocaleMeasurementUnitsImperial:
temp = locale_celsius_to_fahrenheit(context->temp_celsius);
temp_units = 'F';
break;
default:
furi_crash("Illegal measurement units");
}
/* If a reading is available, display it */
snprintf(text_store, TEXT_STORE_SIZE, "Temperature: %+.1f%c", (double)temp, temp_units);
} else {
/* Or show a message that no data is available */
strncpy(text_store, "-- No data --", TEXT_STORE_SIZE);
}
canvas_draw_str_aligned(canvas, middle_x, 58, AlignCenter, AlignBottom, text_store);
}
/* This function is called from the GUI thread. All it does is put the event
into the application's queue so it can be processed later. */
static void example_thermo_input_callback(InputEvent* event, void* ctx) {
ExampleThermoContext* context = ctx;
furi_message_queue_put(context->event_queue, event, FuriWaitForever);
}
/* Starts the reader thread and handles the input */
static void example_thermo_run(ExampleThermoContext* context) {
/* Configure the hardware in host mode */
onewire_host_start(context->onewire);
/* Start the reader thread. It will talk to the thermometer in the background. */
furi_thread_start(context->reader_thread);
/* An endless loop which handles the input*/
for(bool is_running = true; is_running;) {
InputEvent event;
/* Wait for an input event. Input events come from the GUI thread via a callback. */
const FuriStatus status =
furi_message_queue_get(context->event_queue, &event, FuriWaitForever);
/* This application is only interested in short button presses. */
if((status != FuriStatusOk) || (event.type != InputTypeShort)) {
continue;
}
/* When the user presses the "Back" button, break the loop and exit the application. */
if(event.key == InputKeyBack) {
is_running = false;
}
}
/* Signal the reader thread to cease operation and exit */
furi_thread_flags_set(furi_thread_get_id(context->reader_thread), ReaderThreadFlagExit);
/* Wait for the reader thread to finish */
furi_thread_join(context->reader_thread);
/* Reset the hardware */
onewire_host_stop(context->onewire);
}
/******************** Initialisation & startup *****************************/
/* Allocate the memory and initialise the variables */
static ExampleThermoContext* example_thermo_context_alloc() {
ExampleThermoContext* context = malloc(sizeof(ExampleThermoContext));
context->view_port = view_port_alloc();
view_port_draw_callback_set(context->view_port, example_thermo_draw_callback, context);
view_port_input_callback_set(context->view_port, example_thermo_input_callback, context);
context->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
context->reader_thread = furi_thread_alloc();
furi_thread_set_stack_size(context->reader_thread, 1024U);
furi_thread_set_context(context->reader_thread, context);
furi_thread_set_callback(context->reader_thread, example_thermo_reader_thread_callback);
context->gui = furi_record_open(RECORD_GUI);
gui_add_view_port(context->gui, context->view_port, GuiLayerFullscreen);
context->onewire = onewire_host_alloc(&THERMO_GPIO_PIN);
return context;
}
/* Release the unused resources and deallocate memory */
static void example_thermo_context_free(ExampleThermoContext* context) {
view_port_enabled_set(context->view_port, false);
gui_remove_view_port(context->gui, context->view_port);
onewire_host_free(context->onewire);
furi_thread_free(context->reader_thread);
furi_message_queue_free(context->event_queue);
view_port_free(context->view_port);
furi_record_close(RECORD_GUI);
}
/* The application's entry point. Execution starts from here. */
int32_t example_thermo_main(void* p) {
UNUSED(p);
/* Allocate all of the necessary structures */
ExampleThermoContext* context = example_thermo_context_alloc();
/* Start the applicaton's main loop. It won't return until the application was requested to exit. */
example_thermo_run(context);
/* Release all unneeded resources */
example_thermo_context_free(context);
return 0;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

View File

@@ -13,7 +13,7 @@ ArchiveAppTypeEnum archive_get_app_type(const char* path) {
}
app_name++;
for(size_t i = 0; i < COUNT_OF(known_apps); i++) { //-V1008
for(size_t i = 0; i < COUNT_OF(known_apps); i++) {
if(strncmp(app_name, known_apps[i], strlen(known_apps[i])) == 0) {
return i;
}

View File

@@ -1,14 +1,12 @@
#include <archive/views/archive_browser_view.h>
#include "archive_files.h"
#include "archive_apps.h"
#include "archive_browser.h"
#include "../views/archive_browser_view.h"
#include <core/common_defines.h>
#include <core/log.h>
#include <gui/modules/file_browser_worker.h>
#include "gui/modules/file_browser_worker.h"
#include <fap_loader/fap_loader_app.h>
#include <math.h>
#include <furi_hal.h>
static void
archive_folder_open_cb(void* context, uint32_t item_cnt, int32_t file_idx, bool is_root) {
@@ -57,29 +55,16 @@ static void archive_list_load_cb(void* context, uint32_t list_load_offset) {
false);
}
static void archive_list_item_cb(
void* context,
FuriString* item_path,
uint32_t idx,
bool is_folder,
bool is_last) {
static void
archive_list_item_cb(void* context, FuriString* item_path, bool is_folder, bool is_last) {
furi_assert(context);
UNUSED(idx);
ArchiveBrowserView* browser = (ArchiveBrowserView*)context;
if(!is_last) {
archive_add_file_item(browser, is_folder, furi_string_get_cstr(item_path));
} else {
with_view_model(
browser->view,
ArchiveBrowserViewModel * model,
{
if(model->item_cnt <= BROWSER_SORT_THRESHOLD) {
files_array_sort(model->files);
}
model->list_loading = false;
},
true);
browser->view, ArchiveBrowserViewModel * model, { model->list_loading = false; }, true);
}
}
@@ -154,7 +139,7 @@ void archive_update_focus(ArchiveBrowserView* browser, const char* target) {
archive_get_items(browser, furi_string_get_cstr(browser->path));
if(!archive_file_get_array_size(browser) && archive_is_home(browser)) {
archive_switch_tab(browser, TAB_LEFT);
archive_switch_tab(browser, TAB_RIGHT);
} else {
with_view_model(
browser->view,
@@ -221,7 +206,7 @@ void archive_file_array_rm_selected(ArchiveBrowserView* browser) {
false);
if((items_cnt == 0) && (archive_is_home(browser))) {
archive_switch_tab(browser, TAB_LEFT);
archive_switch_tab(browser, TAB_RIGHT);
}
archive_update_offset(browser);
@@ -470,13 +455,6 @@ void archive_switch_tab(ArchiveBrowserView* browser, InputKey key) {
} else {
tab = (tab + 1) % ArchiveTabTotal;
}
if(tab == ArchiveTabInternal && !furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
if(key == InputKeyLeft) {
tab = ((tab - 1) + ArchiveTabTotal) % ArchiveTabTotal;
} else {
tab = (tab + 1) % ArchiveTabTotal;
}
}
browser->is_root = true;
archive_set_tab(browser, tab);

View File

@@ -3,7 +3,7 @@
#include "../archive_i.h"
#include <storage/storage.h>
#define TAB_LEFT InputKeyLeft // Default tab switch direction
#define TAB_RIGHT InputKeyRight // Default tab switch direction
#define TAB_DEFAULT ArchiveTabFavorites // Start tab
#define FILE_LIST_BUF_LEN 50
@@ -17,7 +17,6 @@ static const char* tab_default_paths[] = {
[ArchiveTabBadUsb] = ANY_PATH("badusb"),
[ArchiveTabU2f] = "/app:u2f",
[ArchiveTabApplications] = ANY_PATH("apps"),
[ArchiveTabInternal] = STORAGE_INT_PATH_PREFIX,
[ArchiveTabBrowser] = STORAGE_ANY_PATH_PREFIX,
};
@@ -45,7 +44,6 @@ static const ArchiveFileTypeEnum known_type[] = {
[ArchiveTabBadUsb] = ArchiveFileTypeBadUsb,
[ArchiveTabU2f] = ArchiveFileTypeU2f,
[ArchiveTabApplications] = ArchiveFileTypeApplication,
[ArchiveTabInternal] = ArchiveFileTypeUnknown,
[ArchiveTabBrowser] = ArchiveFileTypeUnknown,
};

View File

@@ -177,7 +177,7 @@ bool archive_favorites_read(void* context) {
archive_set_item_count(browser, file_count);
if(need_refresh) { //-V547
if(need_refresh) {
archive_favourites_rescan();
}

View File

@@ -2,7 +2,6 @@
#include <m-array.h>
#include <furi.h>
#include <m-algo.h>
#include <storage/storage.h>
#include "toolbox/path.h"
@@ -82,29 +81,13 @@ static void ArchiveFile_t_clear(ArchiveFile_t* obj) {
furi_string_free(obj->custom_name);
}
static int ArchiveFile_t_cmp(const ArchiveFile_t* a, const ArchiveFile_t* b) {
if(a->type == ArchiveFileTypeFolder && b->type != ArchiveFileTypeFolder) {
return -1;
}
if(a->type != ArchiveFileTypeFolder && b->type == ArchiveFileTypeFolder) {
return 1;
}
return furi_string_cmpi(a->path, b->path);
}
#define M_OPL_ArchiveFile_t() \
(INIT(API_2(ArchiveFile_t_init)), \
SET(API_6(ArchiveFile_t_set)), \
INIT_SET(API_6(ArchiveFile_t_init_set)), \
CLEAR(API_2(ArchiveFile_t_clear)), \
CMP(API_6(ArchiveFile_t_cmp)), \
SWAP(M_SWAP_DEFAULT), \
EQUAL(API_6(M_EQUAL_DEFAULT)))
ARRAY_DEF(files_array, ArchiveFile_t)
ALGO_DEF(files_array, ARRAY_OPLIST(files_array, M_OPL_ArchiveFile_t()))
ARRAY_DEF(
files_array,
ArchiveFile_t,
(INIT(API_2(ArchiveFile_t_init)),
SET(API_6(ArchiveFile_t_set)),
INIT_SET(API_6(ArchiveFile_t_init_set)),
CLEAR(API_2(ArchiveFile_t_clear))))
void archive_set_file_type(ArchiveFile_t* file, const char* path, bool is_folder, bool is_app);
bool archive_get_items(void* context, const char* path);

View File

@@ -116,7 +116,7 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) {
case ArchiveBrowserEventFileMenuPin: {
const char* name = archive_get_name(browser);
if(favorites) {
archive_favorites_delete("%s", name);
archive_favorites_delete(name);
archive_file_array_rm_selected(browser);
archive_show_file_menu(browser, false);
} else if(archive_is_known_app(selected->type)) {
@@ -159,8 +159,6 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) {
break;
case ArchiveBrowserEventFileMenuDelete:
if(archive_get_tab(browser) != ArchiveTabFavorites) {
scene_manager_set_scene_state(
archive->scene_manager, ArchiveAppSceneBrowser, SCENE_STATE_NEED_REFRESH);
scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneDelete);
}
consumed = true;

View File

@@ -6,8 +6,6 @@
#include "../helpers/archive_browser.h"
#define TAG "Archive"
#define SCROLL_INTERVAL (333)
#define SCROLL_DELAY (2)
static const char* ArchiveTabNames[] = {
[ArchiveTabFavorites] = "Favorites",
@@ -19,7 +17,6 @@ static const char* ArchiveTabNames[] = {
[ArchiveTabBadUsb] = "Bad USB",
[ArchiveTabU2f] = "U2F",
[ArchiveTabApplications] = "Apps",
[ArchiveTabInternal] = "Internal",
[ArchiveTabBrowser] = "Browser",
};
@@ -271,18 +268,13 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) {
furi_string_set(str_buf, "---");
}
size_t scroll_counter = model->scroll_counter;
elements_string_fit_width(
canvas, str_buf, (scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX) - x_offset);
if(model->item_idx == idx) {
archive_draw_frame(canvas, i, scrollbar, model->move_fav);
if(scroll_counter < SCROLL_DELAY) {
scroll_counter = 0;
} else {
scroll_counter -= SCROLL_DELAY;
}
} else {
canvas_set_color(canvas, ColorBlack);
scroll_counter = 0;
}
if(custom_icon_data) {
@@ -292,15 +284,8 @@ static void draw_list(Canvas* canvas, ArchiveBrowserViewModel* model) {
canvas_draw_icon(
canvas, 2 + x_offset, 16 + i * FRAME_HEIGHT, ArchiveItemIcons[file_type]);
}
elements_scrollable_text_line(
canvas,
15 + x_offset,
24 + i * FRAME_HEIGHT,
((scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX) - x_offset),
str_buf,
scroll_counter,
(model->item_idx != idx));
canvas_draw_str(
canvas, 15 + x_offset, 24 + i * FRAME_HEIGHT, furi_string_get_cstr(str_buf));
furi_string_free(str_buf);
}
@@ -398,20 +383,15 @@ static bool archive_view_input(InputEvent* event, void* context) {
bool in_menu;
bool move_fav_mode;
bool is_loading;
with_view_model(
browser->view,
ArchiveBrowserViewModel * model,
{
in_menu = model->menu;
move_fav_mode = model->move_fav;
is_loading = model->folder_loading || model->list_loading;
},
false);
if(is_loading) {
return false;
}
if(in_menu) {
if(event->type != InputTypeShort) {
return true; // RETURN
@@ -474,7 +454,6 @@ static bool archive_view_input(InputEvent* event, void* context) {
if(move_fav_mode) {
browser->callback(ArchiveBrowserEventFavMoveUp, browser->context);
}
model->scroll_counter = 0;
} else if(event->key == InputKeyDown) {
model->item_idx = (model->item_idx + 1) % model->item_cnt;
if(is_file_list_load_required(model)) {
@@ -484,10 +463,9 @@ static bool archive_view_input(InputEvent* event, void* context) {
if(move_fav_mode) {
browser->callback(ArchiveBrowserEventFavMoveDown, browser->context);
}
model->scroll_counter = 0;
}
},
false);
true);
archive_update_offset(browser);
}
@@ -524,27 +502,6 @@ static bool archive_view_input(InputEvent* event, void* context) {
return true;
}
static void browser_scroll_timer(void* context) {
furi_assert(context);
ArchiveBrowserView* browser = context;
with_view_model(
browser->view, ArchiveBrowserViewModel * model, { model->scroll_counter++; }, true);
}
static void browser_view_enter(void* context) {
furi_assert(context);
ArchiveBrowserView* browser = context;
with_view_model(
browser->view, ArchiveBrowserViewModel * model, { model->scroll_counter = 0; }, true);
furi_timer_start(browser->scroll_timer, SCROLL_INTERVAL);
}
static void browser_view_exit(void* context) {
furi_assert(context);
ArchiveBrowserView* browser = context;
furi_timer_stop(browser->scroll_timer);
}
ArchiveBrowserView* browser_alloc() {
ArchiveBrowserView* browser = malloc(sizeof(ArchiveBrowserView));
browser->view = view_alloc();
@@ -552,10 +509,6 @@ ArchiveBrowserView* browser_alloc() {
view_set_context(browser->view, browser);
view_set_draw_callback(browser->view, archive_view_render);
view_set_input_callback(browser->view, archive_view_input);
view_set_enter_callback(browser->view, browser_view_enter);
view_set_exit_callback(browser->view, browser_view_exit);
browser->scroll_timer = furi_timer_alloc(browser_scroll_timer, FuriTimerTypePeriodic, browser);
browser->path = furi_string_alloc_set(archive_get_default_path(TAB_DEFAULT));
@@ -575,8 +528,6 @@ ArchiveBrowserView* browser_alloc() {
void browser_free(ArchiveBrowserView* browser) {
furi_assert(browser);
furi_timer_free(browser->scroll_timer);
if(browser->worker_running) {
file_browser_worker_free(browser->worker);
}

View File

@@ -1,13 +1,10 @@
#pragma once
#include "../helpers/archive_files.h"
#include "../helpers/archive_favorites.h"
#include <gui/gui_i.h>
#include <gui/view.h>
#include <gui/canvas.h>
#include <gui/elements.h>
#include <gui/modules/file_browser_worker.h>
#include <furi.h>
#include <storage/storage.h>
#include "../helpers/archive_files.h"
#include "../helpers/archive_menu.h"
@@ -31,7 +28,6 @@ typedef enum {
ArchiveTabBadUsb,
ArchiveTabU2f,
ArchiveTabApplications,
ArchiveTabInternal,
ArchiveTabBrowser,
ArchiveTabTotal,
} ArchiveTabEnum;
@@ -82,7 +78,6 @@ struct ArchiveBrowserView {
FuriString* path;
InputKey last_tab_switch_dir;
bool is_root;
FuriTimer* scroll_timer;
};
typedef struct {
@@ -101,7 +96,6 @@ typedef struct {
int32_t item_idx;
int32_t array_offset;
int32_t list_offset;
size_t scroll_counter;
} ArchiveBrowserViewModel;
void archive_browser_set_callback(

View File

@@ -33,26 +33,9 @@ static void bad_usb_load_settings(BadUsbApp* app) {
!storage_file_eof(settings_file) && !isspace(chr)) {
furi_string_push_back(app->keyboard_layout, chr);
}
} else {
furi_string_reset(app->keyboard_layout);
}
storage_file_close(settings_file);
storage_file_free(settings_file);
if(!furi_string_empty(app->keyboard_layout)) {
Storage* fs_api = furi_record_open(RECORD_STORAGE);
FileInfo layout_file_info;
FS_Error file_check_err = storage_common_stat(
fs_api, furi_string_get_cstr(app->keyboard_layout), &layout_file_info);
furi_record_close(RECORD_STORAGE);
if(file_check_err != FSE_OK) {
furi_string_reset(app->keyboard_layout);
return;
}
if(layout_file_info.size != 256) {
furi_string_reset(app->keyboard_layout);
}
}
}
static void bad_usb_save_settings(BadUsbApp* app) {
@@ -115,12 +98,8 @@ BadUsbApp* bad_usb_app_alloc(char* arg) {
if(furi_hal_usb_is_locked()) {
app->error = BadUsbAppErrorCloseRpc;
app->usb_if_prev = NULL;
scene_manager_next_scene(app->scene_manager, BadUsbSceneError);
} else {
app->usb_if_prev = furi_hal_usb_get_config();
furi_check(furi_hal_usb_set_config(NULL, NULL));
if(!furi_string_empty(app->file_path)) {
app->bad_usb_script = bad_usb_script_open(app->file_path);
bad_usb_script_set_keyboard_layout(app->bad_usb_script, app->keyboard_layout);
@@ -142,10 +121,6 @@ void bad_usb_app_free(BadUsbApp* app) {
app->bad_usb_script = NULL;
}
if(app->usb_if_prev) {
furi_check(furi_hal_usb_set_config(app->usb_if_prev, NULL));
}
// Views
view_dispatcher_remove_view(app->view_dispatcher, BadUsbAppViewWork);
bad_usb_free(app->bad_usb_view);

View File

@@ -14,10 +14,9 @@
#include <gui/modules/variable_item_list.h>
#include <gui/modules/widget.h>
#include "views/bad_usb_view.h"
#include <furi_hal_usb.h>
#define BAD_USB_APP_BASE_FOLDER ANY_PATH("badusb")
#define BAD_USB_APP_PATH_LAYOUT_FOLDER BAD_USB_APP_BASE_FOLDER "/assets/layouts"
#define BAD_USB_APP_PATH_LAYOUT_FOLDER BAD_USB_APP_BASE_FOLDER "/layouts"
#define BAD_USB_APP_SCRIPT_EXTENSION ".txt"
#define BAD_USB_APP_LAYOUT_EXTENSION ".kl"
@@ -40,8 +39,6 @@ struct BadUsbApp {
FuriString* keyboard_layout;
BadUsb* bad_usb_view;
BadUsbScript* bad_usb_script;
FuriHalUsbInterface* usb_if_prev;
};
typedef enum {

View File

@@ -54,7 +54,6 @@ static const DuckyKey ducky_keys[] = {
{"ALT-SHIFT", KEY_MOD_LEFT_ALT | KEY_MOD_LEFT_SHIFT},
{"ALT-GUI", KEY_MOD_LEFT_ALT | KEY_MOD_LEFT_GUI},
{"GUI-SHIFT", KEY_MOD_LEFT_GUI | KEY_MOD_LEFT_SHIFT},
{"GUI-CTRL", KEY_MOD_LEFT_GUI | KEY_MOD_LEFT_CTRL},
{"CTRL", KEY_MOD_LEFT_CTRL},
{"CONTROL", KEY_MOD_LEFT_CTRL},
@@ -76,8 +75,8 @@ static const DuckyKey ducky_keys[] = {
{"BREAK", HID_KEYBOARD_PAUSE},
{"PAUSE", HID_KEYBOARD_PAUSE},
{"CAPSLOCK", HID_KEYBOARD_CAPS_LOCK},
{"DELETE", HID_KEYBOARD_DELETE_FORWARD},
{"BACKSPACE", HID_KEYBOARD_DELETE},
{"DELETE", HID_KEYBOARD_DELETE},
{"BACKSPACE", HID_KEYPAD_BACKSPACE},
{"END", HID_KEYBOARD_END},
{"ESC", HID_KEYBOARD_ESCAPE},
{"ESCAPE", HID_KEYBOARD_ESCAPE},
@@ -120,6 +119,8 @@ static const char ducky_cmd_altchar[] = {"ALTCHAR "};
static const char ducky_cmd_altstr_1[] = {"ALTSTRING "};
static const char ducky_cmd_altstr_2[] = {"ALTCODE "};
static const char ducky_cmd_lang[] = {"DUCKY_LANG"};
static const uint8_t numpad_keys[10] = {
HID_KEYPAD_0,
HID_KEYPAD_1,
@@ -223,8 +224,8 @@ static bool ducky_string(BadUsbScript* bad_usb, const char* param) {
}
static uint16_t ducky_get_keycode(BadUsbScript* bad_usb, const char* param, bool accept_chars) {
for(size_t i = 0; i < (sizeof(ducky_keys) / sizeof(ducky_keys[0])); i++) {
size_t key_cmd_len = strlen(ducky_keys[i].name);
for(uint8_t i = 0; i < (sizeof(ducky_keys) / sizeof(ducky_keys[0])); i++) {
uint8_t key_cmd_len = strlen(ducky_keys[i].name);
if((strncmp(param, ducky_keys[i].name, key_cmd_len) == 0) &&
(ducky_is_line_end(param[key_cmd_len]))) {
return ducky_keys[i].keycode;
@@ -255,6 +256,9 @@ static int32_t
} else if(strncmp(line_tmp, ducky_cmd_id, strlen(ducky_cmd_id)) == 0) {
// ID - executed in ducky_script_preload
return (0);
} else if(strncmp(line_tmp, ducky_cmd_lang, strlen(ducky_cmd_lang)) == 0) {
// DUCKY_LANG - ignore command to retain compatibility with existing scripts
return (0);
} else if(strncmp(line_tmp, ducky_cmd_delay, strlen(ducky_cmd_delay)) == 0) {
// DELAY
line_tmp = &line_tmp[ducky_get_command_len(line_tmp) + 1];
@@ -422,7 +426,7 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil
return 0;
} else if(delay_val < 0) { // Script error
bad_usb->st.error_line = bad_usb->st.line_cur - 1;
FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur - 1U);
FURI_LOG_E(WORKER_TAG, "Unknown command at line %u", bad_usb->st.line_cur - 1);
return SCRIPT_STATE_ERROR;
} else {
return (delay_val + bad_usb->defdelay);
@@ -490,6 +494,8 @@ static int32_t bad_usb_worker(void* context) {
BadUsbWorkerState worker_state = BadUsbStateInit;
int32_t delay_val = 0;
FuriHalUsbInterface* usb_mode_prev = furi_hal_usb_get_config();
FURI_LOG_I(WORKER_TAG, "Init");
File* script_file = storage_file_alloc(furi_record_open(RECORD_STORAGE));
bad_usb->line = furi_string_alloc();
@@ -599,9 +605,7 @@ static int32_t bad_usb_worker(void* context) {
}
bad_usb->st.state = worker_state;
continue;
} else if(
(flags == (unsigned)FuriFlagErrorTimeout) ||
(flags == (unsigned)FuriFlagErrorResource)) {
} else if((flags == FuriFlagErrorTimeout) || (flags == FuriFlagErrorResource)) {
if(delay_val > 0) {
bad_usb->st.delay_remain--;
continue;
@@ -640,6 +644,8 @@ static int32_t bad_usb_worker(void* context) {
furi_hal_hid_set_state_callback(NULL, NULL);
furi_hal_usb_set_config(usb_mode_prev, NULL);
storage_file_close(script_file);
storage_file_free(script_file);
furi_string_free(bad_usb->line);
@@ -659,7 +665,7 @@ static void bad_usb_script_set_default_keyboard_layout(BadUsbScript* bad_usb) {
BadUsbScript* bad_usb_script_open(FuriString* file_path) {
furi_assert(file_path);
BadUsbScript* bad_usb = malloc(sizeof(BadUsbScript));
BadUsbScript* bad_usb = malloc(sizeof(BadUsbScript)); //-V773
bad_usb->file_path = furi_string_alloc();
furi_string_set(bad_usb->file_path, file_path);
bad_usb_script_set_default_keyboard_layout(bad_usb);
@@ -670,7 +676,7 @@ BadUsbScript* bad_usb_script_open(FuriString* file_path) {
bad_usb->thread = furi_thread_alloc_ex("BadUsbWorker", 2048, bad_usb_worker, bad_usb);
furi_thread_start(bad_usb->thread);
return bad_usb;
} //-V773
}
void bad_usb_script_close(BadUsbScript* bad_usb) {
furi_assert(bad_usb);
@@ -690,7 +696,7 @@ void bad_usb_script_set_keyboard_layout(BadUsbScript* bad_usb, FuriString* layou
}
File* layout_file = storage_file_alloc(furi_record_open(RECORD_STORAGE));
if(!furi_string_empty(layout_path)) { //-V1051
if(!furi_string_empty(layout_path)) {
if(storage_file_open(
layout_file, furi_string_get_cstr(layout_path), FSAM_READ, FSOM_OPEN_EXISTING)) {
uint16_t layout[128];

View File

@@ -17,8 +17,6 @@ static bool bad_usb_layout_select(BadUsbApp* bad_usb) {
DialogsFileBrowserOptions browser_options;
dialog_file_browser_set_basic_options(
&browser_options, BAD_USB_APP_LAYOUT_EXTENSION, &I_keyboard_10px);
browser_options.base_path = BAD_USB_APP_PATH_LAYOUT_FOLDER;
browser_options.skip_assets = false;
// Input events and views are managed by file_browser
bool res = dialog_file_browser_show(

View File

@@ -1,6 +1,6 @@
#include "../bad_usb_app_i.h"
#include <furi_hal_power.h>
#include <furi_hal_usb.h>
#include "furi_hal_power.h"
#include "furi_hal_usb.h"
#include <storage/storage.h>
static bool bad_usb_file_select(BadUsbApp* bad_usb) {

View File

@@ -1,7 +1,7 @@
#include "../bad_usb_script.h"
#include "../bad_usb_app_i.h"
#include "../views/bad_usb_view.h"
#include <furi_hal.h>
#include "furi_hal.h"
#include "toolbox/path.h"
void bad_usb_scene_work_button_callback(InputKey key, void* context) {

View File

@@ -39,12 +39,11 @@ static void clock_render_callback(Canvas* const canvas, void* ctx) {
} else {
bool pm = curr_dt.hour > 12;
bool pm12 = curr_dt.hour >= 12;
bool am12 = curr_dt.hour == 0;
snprintf(
time_string,
TIME_LEN,
CLOCK_TIME_FORMAT,
pm ? curr_dt.hour - 12 : (am12 ? 12 : curr_dt.hour),
pm ? curr_dt.hour - 12 : curr_dt.hour,
curr_dt.minute,
curr_dt.second);
@@ -238,4 +237,4 @@ int32_t clock_app(void* p) {
free(plugin_state);
return 0;
}
}

View File

@@ -156,7 +156,7 @@ static bool fap_loader_select_app(FapLoader* loader) {
}
static FapLoader* fap_loader_alloc(const char* path) {
FapLoader* loader = malloc(sizeof(FapLoader)); //-V799
FapLoader* loader = malloc(sizeof(FapLoader)); //-V773
loader->fap_path = furi_string_alloc_set(path);
loader->storage = furi_record_open(RECORD_STORAGE);
loader->dialogs = furi_record_open(RECORD_DIALOGS);
@@ -167,7 +167,7 @@ static FapLoader* fap_loader_alloc(const char* path) {
loader->view_dispatcher, loader->gui, ViewDispatcherTypeFullscreen);
view_dispatcher_add_view(loader->view_dispatcher, 0, loading_get_view(loader->loading));
return loader;
} //-V773
}
static void fap_loader_free(FapLoader* loader) {
view_dispatcher_remove_view(loader->view_dispatcher, 0);

View File

@@ -25,7 +25,6 @@ GpioApp* gpio_app_alloc() {
GpioApp* app = malloc(sizeof(GpioApp));
app->gui = furi_record_open(RECORD_GUI);
app->gpio_items = gpio_items_alloc();
app->view_dispatcher = view_dispatcher_alloc();
app->scene_manager = scene_manager_alloc(&gpio_scene_handlers, app);
@@ -48,7 +47,7 @@ GpioApp* gpio_app_alloc() {
app->view_dispatcher,
GpioAppViewVarItemList,
variable_item_list_get_view(app->var_item_list));
app->gpio_test = gpio_test_alloc(app->gpio_items);
app->gpio_test = gpio_test_alloc();
view_dispatcher_add_view(
app->view_dispatcher, GpioAppViewGpioTest, gpio_test_get_view(app->gpio_test));
@@ -92,7 +91,6 @@ void gpio_app_free(GpioApp* app) {
furi_record_close(RECORD_GUI);
furi_record_close(RECORD_NOTIFICATION);
gpio_items_free(app->gpio_items);
free(app);
}

View File

@@ -1,7 +1,7 @@
#pragma once
#include "gpio_app.h"
#include "gpio_items.h"
#include "gpio_item.h"
#include "scenes/gpio_scene.h"
#include "gpio_custom_event.h"
#include "usb_uart_bridge.h"
@@ -28,7 +28,6 @@ struct GpioApp {
VariableItem* var_item_flow;
GpioTest* gpio_test;
GpioUsbUart* gpio_usb_uart;
GPIOItems* gpio_items;
UsbUartBridge* usb_uart_bridge;
UsbUartConfig* usb_uart_cfg;
};

View File

@@ -0,0 +1,51 @@
#include "gpio_item.h"
#include <furi_hal_resources.h>
typedef struct {
const char* name;
const GpioPin* pin;
} GpioItem;
static const GpioItem gpio_item[GPIO_ITEM_COUNT] = {
{"1.2: PA7", &gpio_ext_pa7},
{"1.3: PA6", &gpio_ext_pa6},
{"1.4: PA4", &gpio_ext_pa4},
{"1.5: PB3", &gpio_ext_pb3},
{"1.6: PB2", &gpio_ext_pb2},
{"1.7: PC3", &gpio_ext_pc3},
{"2.7: PC1", &gpio_ext_pc1},
{"2.8: PC0", &gpio_ext_pc0},
};
void gpio_item_configure_pin(uint8_t index, GpioMode mode) {
furi_assert(index < GPIO_ITEM_COUNT);
furi_hal_gpio_write(gpio_item[index].pin, false);
furi_hal_gpio_init(gpio_item[index].pin, mode, GpioPullNo, GpioSpeedVeryHigh);
}
void gpio_item_configure_all_pins(GpioMode mode) {
for(uint8_t i = 0; i < GPIO_ITEM_COUNT; i++) {
gpio_item_configure_pin(i, mode);
}
}
void gpio_item_set_pin(uint8_t index, bool level) {
furi_assert(index < GPIO_ITEM_COUNT);
furi_hal_gpio_write(gpio_item[index].pin, level);
}
void gpio_item_set_all_pins(bool level) {
for(uint8_t i = 0; i < GPIO_ITEM_COUNT; i++) {
gpio_item_set_pin(i, level);
}
}
const char* gpio_item_get_pin_name(uint8_t index) {
furi_assert(index < GPIO_ITEM_COUNT + 1);
if(index == GPIO_ITEM_COUNT) {
return "ALL";
} else {
return gpio_item[index].name;
}
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include <furi_hal_gpio.h>
#define GPIO_ITEM_COUNT 8
void gpio_item_configure_pin(uint8_t index, GpioMode mode);
void gpio_item_configure_all_pins(GpioMode mode);
void gpio_item_set_pin(uint8_t index, bool level);
void gpio_item_set_all_pins(bool level);
const char* gpio_item_get_pin_name(uint8_t index);

View File

@@ -1,69 +0,0 @@
#include "gpio_items.h"
#include <furi_hal_resources.h>
struct GPIOItems {
GpioPinRecord* pins;
size_t count;
};
GPIOItems* gpio_items_alloc() {
GPIOItems* items = malloc(sizeof(GPIOItems));
items->count = 0;
for(size_t i = 0; i < gpio_pins_count; i++) {
if(!gpio_pins[i].debug) {
items->count++;
}
}
items->pins = malloc(sizeof(GpioPinRecord) * items->count);
for(size_t i = 0; i < items->count; i++) {
if(!gpio_pins[i].debug) {
items->pins[i].pin = gpio_pins[i].pin;
items->pins[i].name = gpio_pins[i].name;
}
}
return items;
}
void gpio_items_free(GPIOItems* items) {
free(items->pins);
free(items);
}
uint8_t gpio_items_get_count(GPIOItems* items) {
return items->count;
}
void gpio_items_configure_pin(GPIOItems* items, uint8_t index, GpioMode mode) {
furi_assert(index < items->count);
furi_hal_gpio_write(items->pins[index].pin, false);
furi_hal_gpio_init(items->pins[index].pin, mode, GpioPullNo, GpioSpeedVeryHigh);
}
void gpio_items_configure_all_pins(GPIOItems* items, GpioMode mode) {
for(uint8_t i = 0; i < items->count; i++) {
gpio_items_configure_pin(items, i, mode);
}
}
void gpio_items_set_pin(GPIOItems* items, uint8_t index, bool level) {
furi_assert(index < items->count);
furi_hal_gpio_write(items->pins[index].pin, level);
}
void gpio_items_set_all_pins(GPIOItems* items, bool level) {
for(uint8_t i = 0; i < items->count; i++) {
gpio_items_set_pin(items, i, level);
}
}
const char* gpio_items_get_pin_name(GPIOItems* items, uint8_t index) {
furi_assert(index < items->count + 1);
if(index == items->count) {
return "ALL";
} else {
return items->pins[index].name;
}
}

View File

@@ -1,29 +0,0 @@
#pragma once
#include <furi_hal_gpio.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct GPIOItems GPIOItems;
GPIOItems* gpio_items_alloc();
void gpio_items_free(GPIOItems* items);
uint8_t gpio_items_get_count(GPIOItems* items);
void gpio_items_configure_pin(GPIOItems* items, uint8_t index, GpioMode mode);
void gpio_items_configure_all_pins(GPIOItems* items, GpioMode mode);
void gpio_items_set_pin(GPIOItems* items, uint8_t index, bool level);
void gpio_items_set_all_pins(GPIOItems* items, bool level);
const char* gpio_items_get_pin_name(GPIOItems* items, uint8_t index);
#ifdef __cplusplus
}
#endif

View File

@@ -1,6 +1,6 @@
#include "../gpio_app_i.h"
#include <furi_hal_power.h>
#include <furi_hal_usb.h>
#include "furi_hal_power.h"
#include "furi_hal_usb.h"
#include <dolphin/dolphin.h>
enum GpioItem {

View File

@@ -12,9 +12,8 @@ void gpio_scene_test_ok_callback(InputType type, void* context) {
}
void gpio_scene_test_on_enter(void* context) {
furi_assert(context);
GpioApp* app = context;
gpio_items_configure_all_pins(app->gpio_items, GpioModeOutputPushPull);
gpio_item_configure_all_pins(GpioModeOutputPushPull);
gpio_test_set_ok_callback(app->gpio_test, gpio_scene_test_ok_callback, app);
view_dispatcher_switch_to_view(app->view_dispatcher, GpioAppViewGpioTest);
}
@@ -26,7 +25,6 @@ bool gpio_scene_test_on_event(void* context, SceneManagerEvent event) {
}
void gpio_scene_test_on_exit(void* context) {
furi_assert(context);
GpioApp* app = context;
gpio_items_configure_all_pins(app->gpio_items, GpioModeAnalog);
UNUSED(context);
gpio_item_configure_all_pins(GpioModeAnalog);
}

View File

@@ -1,6 +1,6 @@
#include "../usb_uart_bridge.h"
#include "../gpio_app_i.h"
#include <furi_hal.h>
#include "furi_hal.h"
typedef enum {
UsbUartLineIndexVcp,
@@ -14,12 +14,9 @@ static const char* uart_ch[] = {"13,14", "15,16"};
static const char* flow_pins[] = {"None", "2,3", "6,7", "16,15"};
static const char* baudrate_mode[] = {"Host"};
static const uint32_t baudrate_list[] = {
1200,
2400,
4800,
9600,
19200,
28800,
38400,
57600,
115200,

View File

@@ -1,10 +1,10 @@
#include "usb_uart_bridge.h"
#include "usb_cdc.h"
#include <cli/cli_vcp.h>
#include <cli/cli.h>
#include <toolbox/api_lock.h>
#include <furi_hal.h>
#include "furi_hal.h"
#include <furi_hal_usb_cdc.h>
#include "usb_cdc.h"
#include "cli/cli_vcp.h"
#include <toolbox/api_lock.h>
#include "cli/cli.h"
#define USB_CDC_PKT_LEN CDC_DATA_SZ
#define USB_UART_RX_BUF_SIZE (USB_CDC_PKT_LEN * 5)

View File

@@ -1,5 +1,5 @@
#include "gpio_test.h"
#include "../gpio_items.h"
#include "../gpio_item.h"
#include <gui/elements.h>
@@ -11,7 +11,6 @@ struct GpioTest {
typedef struct {
uint8_t pin_idx;
GPIOItems* gpio_items;
} GpioTestModel;
static bool gpio_test_process_left(GpioTest* gpio_test);
@@ -26,12 +25,7 @@ static void gpio_test_draw_callback(Canvas* canvas, void* _model) {
elements_multiline_text_aligned(
canvas, 64, 16, AlignCenter, AlignTop, "Press < or > to change pin");
elements_multiline_text_aligned(
canvas,
64,
32,
AlignCenter,
AlignTop,
gpio_items_get_pin_name(model->gpio_items, model->pin_idx));
canvas, 64, 32, AlignCenter, AlignTop, gpio_item_get_pin_name(model->pin_idx));
}
static bool gpio_test_input_callback(InputEvent* event, void* context) {
@@ -70,7 +64,7 @@ static bool gpio_test_process_right(GpioTest* gpio_test) {
gpio_test->view,
GpioTestModel * model,
{
if(model->pin_idx < gpio_items_get_count(model->gpio_items)) {
if(model->pin_idx < GPIO_ITEM_COUNT) {
model->pin_idx++;
}
},
@@ -86,17 +80,17 @@ static bool gpio_test_process_ok(GpioTest* gpio_test, InputEvent* event) {
GpioTestModel * model,
{
if(event->type == InputTypePress) {
if(model->pin_idx < gpio_items_get_count(model->gpio_items)) {
gpio_items_set_pin(model->gpio_items, model->pin_idx, true);
if(model->pin_idx < GPIO_ITEM_COUNT) {
gpio_item_set_pin(model->pin_idx, true);
} else {
gpio_items_set_all_pins(model->gpio_items, true);
gpio_item_set_all_pins(true);
}
consumed = true;
} else if(event->type == InputTypeRelease) {
if(model->pin_idx < gpio_items_get_count(model->gpio_items)) {
gpio_items_set_pin(model->gpio_items, model->pin_idx, false);
if(model->pin_idx < GPIO_ITEM_COUNT) {
gpio_item_set_pin(model->pin_idx, false);
} else {
gpio_items_set_all_pins(model->gpio_items, false);
gpio_item_set_all_pins(false);
}
consumed = true;
}
@@ -107,15 +101,11 @@ static bool gpio_test_process_ok(GpioTest* gpio_test, InputEvent* event) {
return consumed;
}
GpioTest* gpio_test_alloc(GPIOItems* gpio_items) {
GpioTest* gpio_test_alloc() {
GpioTest* gpio_test = malloc(sizeof(GpioTest));
gpio_test->view = view_alloc();
view_allocate_model(gpio_test->view, ViewModelTypeLocking, sizeof(GpioTestModel));
with_view_model(
gpio_test->view, GpioTestModel * model, { model->gpio_items = gpio_items; }, false);
view_set_context(gpio_test->view, gpio_test);
view_set_draw_callback(gpio_test->view, gpio_test_draw_callback);
view_set_input_callback(gpio_test->view, gpio_test_input_callback);

View File

@@ -1,13 +1,11 @@
#pragma once
#include "../gpio_items.h"
#include <gui/view.h>
typedef struct GpioTest GpioTest;
typedef void (*GpioTestOkCallback)(InputType type, void* context);
GpioTest* gpio_test_alloc(GPIOItems* gpio_items);
GpioTest* gpio_test_alloc();
void gpio_test_free(GpioTest* gpio_test);

View File

@@ -1,6 +1,6 @@
#include "../usb_uart_bridge.h"
#include "../gpio_app_i.h"
#include <furi_hal.h>
#include "furi_hal.h"
#include <gui/elements.h>
struct GpioUsbUart {

View File

@@ -2,7 +2,6 @@ App(
appid="ibutton",
name="iButton",
apptype=FlipperAppType.APP,
targets=["f7"],
entry_point="ibutton_app",
cdefines=["APP_IBUTTON"],
requires=[

View File

@@ -278,7 +278,7 @@ bool ibutton_save_key(iButton* ibutton, const char* key_name) {
flipper_format_free(file);
if(!result) { //-V547
if(!result) {
dialog_message_show_storage_error(ibutton->dialogs, "Cannot save\nkey file");
}
@@ -302,7 +302,7 @@ void ibutton_text_store_set(iButton* ibutton, const char* text, ...) {
}
void ibutton_text_store_clear(iButton* ibutton) {
memset(ibutton->text_store, 0, IBUTTON_TEXT_STORE_SIZE + 1);
memset(ibutton->text_store, 0, IBUTTON_TEXT_STORE_SIZE);
}
void ibutton_notification_message(iButton* ibutton, uint32_t message) {
@@ -343,7 +343,7 @@ int32_t ibutton_app(void* p) {
} else {
view_dispatcher_attach_to_gui(
ibutton->view_dispatcher, ibutton->gui, ViewDispatcherTypeFullscreen);
if(key_loaded) { //-V547
if(key_loaded) {
scene_manager_next_scene(ibutton->scene_manager, iButtonSceneEmulate);
DOLPHIN_DEED(DolphinDeedIbuttonEmulate);
} else {

View File

@@ -271,7 +271,7 @@ void onewire_cli_print_usage() {
static void onewire_cli_search(Cli* cli) {
UNUSED(cli);
OneWireHost* onewire = onewire_host_alloc(&ibutton_gpio);
OneWireHost* onewire = onewire_host_alloc();
uint8_t address[8];
bool done = false;

View File

@@ -52,6 +52,7 @@ bool ibutton_scene_read_on_event(void* context, SceneManagerEvent event) {
if(success) {
ibutton_notification_message(ibutton, iButtonNotificationMessageSuccess);
ibutton_notification_message(ibutton, iButtonNotificationMessageGreenOn);
scene_manager_next_scene(scene_manager, iButtonSceneReadSuccess);
DOLPHIN_DEED(DolphinDeedIbuttonReadSuccess);
}

View File

@@ -48,8 +48,6 @@ void ibutton_scene_read_success_on_enter(void* context) {
dialog_ex_set_context(dialog_ex, ibutton);
view_dispatcher_switch_to_view(ibutton->view_dispatcher, iButtonViewDialogEx);
ibutton_notification_message(ibutton, iButtonNotificationMessageGreenOn);
}
bool ibutton_scene_read_success_on_event(void* context, SceneManagerEvent event) {

View File

@@ -3,7 +3,6 @@ App(
name="Infrared",
apptype=FlipperAppType.APP,
entry_point="infrared_app",
targets=["f7"],
cdefines=["APP_INFRARED"],
requires=[
"gui",

View File

@@ -360,7 +360,7 @@ void infrared_text_store_set(Infrared* infrared, uint32_t bank, const char* text
}
void infrared_text_store_clear(Infrared* infrared, uint32_t bank) {
memset(infrared->text_store[bank], 0, INFRARED_TEXT_STORE_SIZE + 1);
memset(infrared->text_store[bank], 0, INFRARED_TEXT_STORE_SIZE);
}
void infrared_play_notification_message(Infrared* infrared, uint32_t message) {
@@ -455,7 +455,7 @@ int32_t infrared_app(void* p) {
} else {
view_dispatcher_attach_to_gui(
infrared->view_dispatcher, infrared->gui, ViewDispatcherTypeFullscreen);
if(is_remote_loaded) { //-V547
if(is_remote_loaded) {
scene_manager_next_scene(infrared->scene_manager, InfraredSceneRemote);
} else {
scene_manager_next_scene(infrared->scene_manager, InfraredSceneStart);

View File

@@ -65,7 +65,7 @@ bool infrared_brute_force_calculate_messages(InfraredBruteForce* brute_force) {
while(flipper_format_read_string(ff, "name", signal_name)) {
InfraredBruteForceRecord* record =
InfraredBruteForceRecordDict_get(brute_force->records, signal_name);
if(record) { //-V547
if(record) {
++(record->count);
}
}

View File

@@ -55,7 +55,7 @@ static void signal_received_callback(void* context, InfraredWorkerSignal* receiv
size_t timings_cnt;
infrared_worker_get_raw_signal(received_signal, &timings, &timings_cnt);
buf_cnt = snprintf(buf, sizeof(buf), "RAW, %zu samples:\r\n", timings_cnt);
buf_cnt = snprintf(buf, sizeof(buf), "RAW, %d samples:\r\n", timings_cnt);
cli_write(cli, (uint8_t*)buf, buf_cnt);
for(size_t i = 0; i < timings_cnt; ++i) {
buf_cnt = snprintf(buf, sizeof(buf), "%lu ", timings[i]);
@@ -86,7 +86,7 @@ static void infrared_cli_print_usage(void) {
printf("\tir universal <remote_name> <signal_name>\r\n");
printf("\tir universal list <remote_name>\r\n");
// TODO: Do not hardcode universal remote names
printf("\tAvailable universal remotes: tv audio ac projector\r\n");
printf("\tAvailable universal remotes: tv audio ac\r\n");
}
static void infrared_cli_start_ir_rx(Cli* cli, FuriString* args) {
@@ -276,9 +276,7 @@ static bool infrared_cli_decode_file(FlipperFormat* input_file, FlipperFormat* o
}
InfraredRawSignal* raw_signal = infrared_signal_get_raw_signal(signal);
printf(
"Raw signal: %s, %zu samples\r\n",
furi_string_get_cstr(tmp),
raw_signal->timings_size);
"Raw signal: %s, %u samples\r\n", furi_string_get_cstr(tmp), raw_signal->timings_size);
if(!infrared_cli_decode_raw_signal(
raw_signal, decoder, output_file, furi_string_get_cstr(tmp)))
break;
@@ -384,7 +382,7 @@ static void infrared_cli_list_remote_signals(FuriString* remote_name) {
while(flipper_format_read_string(ff, "name", signal_name)) {
furi_string_set_str(key, furi_string_get_cstr(signal_name));
int* v = dict_signals_get(signals_dict, key);
if(v != NULL) { //-V547
if(v != NULL) {
(*v)++;
max = M_MAX(*v, max);
} else {
@@ -438,7 +436,7 @@ static void
break;
}
printf("Sending %lu signal(s)...\r\n", record_count);
printf("Sending %ld signal(s)...\r\n", record_count);
printf("Press Ctrl-C to stop.\r\n");
int records_sent = 0;

View File

@@ -145,14 +145,15 @@ bool infrared_remote_load(InfraredRemote* remote, FuriString* path) {
buf = furi_string_alloc();
FURI_LOG_I(TAG, "load file: \'%s\'", furi_string_get_cstr(path));
bool success = false;
bool success = flipper_format_buffered_file_open_existing(ff, furi_string_get_cstr(path));
do {
if(!flipper_format_buffered_file_open_existing(ff, furi_string_get_cstr(path))) break;
if(success) {
uint32_t version;
if(!flipper_format_read_header(ff, buf, &version)) break;
if(!furi_string_equal(buf, "IR signals file") || (version != 1)) break;
success = flipper_format_read_header(ff, buf, &version) &&
!furi_string_cmp(buf, "IR signals file") && (version == 1);
}
if(success) {
path_extract_filename(path, buf, true);
infrared_remote_clear_buttons(remote);
infrared_remote_set_name(remote, furi_string_get_cstr(buf));
@@ -168,8 +169,7 @@ bool infrared_remote_load(InfraredRemote* remote, FuriString* path) {
infrared_remote_button_free(button);
}
}
success = true;
} while(false);
}
furi_string_free(buf);
flipper_format_free(ff);

View File

@@ -74,7 +74,7 @@ static bool infrared_signal_is_raw_valid(InfraredRawSignal* raw) {
} else if((raw->timings_size <= 0) || (raw->timings_size > MAX_TIMINGS_AMOUNT)) {
FURI_LOG_E(
TAG,
"Timings amount is out of range (0 - %X): %zX",
"Timings amount is out of range (0 - %X): %X",
MAX_TIMINGS_AMOUNT,
raw->timings_size);
return false;
@@ -275,8 +275,8 @@ bool infrared_signal_search_and_read(
is_name_found = furi_string_equal(name, tmp);
if(is_name_found) break;
}
if(!is_name_found) break; //-V547
if(!infrared_signal_read_body(signal, ff)) break; //-V779
if(!is_name_found) break;
if(!infrared_signal_read_body(signal, ff)) break;
success = true;
} while(false);

View File

@@ -26,7 +26,7 @@ bool infrared_scene_debug_on_event(void* context, SceneManagerEvent event) {
InfraredRawSignal* raw = infrared_signal_get_raw_signal(signal);
infrared_debug_view_set_text(debug_view, "RAW\n%d samples\n", raw->timings_size);
printf("RAW, %zu samples:\r\n", raw->timings_size);
printf("RAW, %d samples:\r\n", raw->timings_size);
for(size_t i = 0; i < raw->timings_size; ++i) {
printf("%lu ", raw->timings[i]);
}

View File

@@ -1,5 +1,5 @@
#include "../infrared_i.h"
#include <gui/canvas.h>
#include "gui/canvas.h"
typedef enum {
InfraredRpcStateIdle,

View File

@@ -3,7 +3,6 @@
enum SubmenuIndex {
SubmenuIndexUniversalRemotes,
SubmenuIndexLearnNewRemote,
SubmenuIndexLearnNewRemoteRaw,
SubmenuIndexSavedRemotes,
SubmenuIndexDebug
};
@@ -38,12 +37,6 @@ void infrared_scene_start_on_enter(void* context) {
infrared);
if(infrared->app_state.is_debug_enabled) {
submenu_add_item(
submenu,
"Learn New Remote RAW",
SubmenuIndexLearnNewRemoteRaw,
infrared_scene_start_submenu_callback,
infrared);
submenu_add_item(
submenu, "Debug", SubmenuIndexDebug, infrared_scene_start_submenu_callback, infrared);
}
@@ -68,14 +61,7 @@ bool infrared_scene_start_on_event(void* context, SceneManagerEvent event) {
if(submenu_index == SubmenuIndexUniversalRemotes) {
scene_manager_next_scene(scene_manager, InfraredSceneUniversal);
consumed = true;
} else if(
submenu_index == SubmenuIndexLearnNewRemote ||
submenu_index == SubmenuIndexLearnNewRemoteRaw) {
// enable automatic signal decoding if "Learn New Remote"
// disable automatic signal decoding if "Learn New Remote (RAW)"
infrared_worker_rx_enable_signal_decoding(
infrared->worker, submenu_index == SubmenuIndexLearnNewRemote);
} else if(submenu_index == SubmenuIndexLearnNewRemote) {
infrared->app_state.is_learning_new_remote = true;
scene_manager_next_scene(scene_manager, InfraredSceneLearn);
consumed = true;

View File

@@ -52,8 +52,7 @@ void infrared_scene_universal_on_enter(void* context) {
infrared_scene_universal_submenu_callback,
context);
submenu_set_selected_item(
submenu, scene_manager_get_scene_state(infrared->scene_manager, InfraredSceneUniversal));
submenu_set_selected_item(submenu, 0);
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewSubmenu);
}
@@ -80,7 +79,6 @@ bool infrared_scene_universal_on_event(void* context, SceneManagerEvent event) {
scene_manager_next_scene(scene_manager, InfraredSceneUniversalAC);
consumed = true;
}
scene_manager_set_scene_state(scene_manager, InfraredSceneUniversal, event.event);
}
return consumed;

View File

@@ -1,11 +1,11 @@
#include "infrared_debug_view.h"
#include <gui/canvas.h>
#include <gui/elements.h>
#include <stdlib.h>
#include <string.h>
#include <gui/canvas.h>
#include <gui/elements.h>
#define INFRARED_DEBUG_TEXT_LENGTH 64
struct InfraredDebugView {

View File

@@ -1,15 +1,13 @@
#include "infrared_progress_view.h"
#include <assets_icons.h>
#include <gui/canvas.h>
#include <gui/view.h>
#include <gui/elements.h>
#include <gui/modules/button_panel.h>
#include <input/input.h>
#include <furi.h>
#include <furi_hal_resources.h>
#include <core/check.h>
#include "furi_hal_resources.h"
#include "assets_icons.h"
#include "gui/canvas.h"
#include "gui/view.h"
#include "input/input.h"
#include <gui/elements.h>
#include <furi.h>
#include "infrared_progress_view.h"
#include "gui/modules/button_panel.h"
#include <stdint.h>
struct InfraredProgressView {

View File

@@ -2,7 +2,6 @@ App(
appid="lfrfid",
name="125 kHz RFID",
apptype=FlipperAppType.APP,
targets=["f7"],
entry_point="lfrfid_app",
cdefines=["APP_LF_RFID"],
requires=[

View File

@@ -1,96 +0,0 @@
#include "rfid_writer.h"
#include <furi_hal.h>
void writer_start() {
furi_hal_rfid_tim_read(125000, 0.5);
furi_hal_rfid_pins_read();
furi_hal_rfid_tim_read_start();
// do not ground the antenna
furi_hal_rfid_pin_pull_release();
}
void writer_stop() {
furi_hal_rfid_tim_read_stop();
furi_hal_rfid_tim_reset();
furi_hal_rfid_pins_reset();
}
void write_gap(uint32_t gap_time) {
furi_hal_rfid_tim_read_stop();
furi_delay_us(gap_time * 8);
furi_hal_rfid_tim_read_start();
}
void write_bit(T55xxTiming* t55xxtiming, bool value) {
if(value) {
furi_delay_us(t55xxtiming->data_1 * 8);
} else {
furi_delay_us(t55xxtiming->data_0 * 8);
}
write_gap(t55xxtiming->write_gap);
}
void write_block(
T55xxTiming* t55xxtiming,
uint8_t page,
uint8_t block,
bool lock_bit,
uint32_t data,
bool password_enable,
uint32_t password) {
furi_delay_us(t55xxtiming->wait_time * 8);
//client: https://github.com/Proxmark/proxmark3/blob/6116334485ca77343eda51c557cdc81032afcf38/client/cmdlft55xx.c#L944
//hardware: https://github.com/Proxmark/proxmark3/blob/555fa197730c061bbf0ab01334e99bc47fb3dc06/armsrc/lfops.c#L1465
//hardware: https://github.com/Proxmark/proxmark3/blob/555fa197730c061bbf0ab01334e99bc47fb3dc06/armsrc/lfops.c#L1396
// start gap
write_gap(t55xxtiming->start_gap);
// opcode
switch(page) {
case 0:
write_bit(t55xxtiming, 1);
write_bit(t55xxtiming, 0);
break;
case 1:
write_bit(t55xxtiming, 1);
write_bit(t55xxtiming, 1);
break;
default:
furi_check(false);
break;
}
// password
if(password_enable) {
for(uint8_t i = 0; i < 32; i++) {
write_bit(t55xxtiming, (password >> (31 - i)) & 1);
}
}
// lock bit
write_bit(t55xxtiming, lock_bit);
// data
for(uint8_t i = 0; i < 32; i++) {
write_bit(t55xxtiming, (data >> (31 - i)) & 1);
}
// block address
write_bit(t55xxtiming, (block >> 2) & 1);
write_bit(t55xxtiming, (block >> 1) & 1);
write_bit(t55xxtiming, (block >> 0) & 1);
furi_delay_us(t55xxtiming->program * 8);
furi_delay_us(t55xxtiming->wait_time * 8);
write_reset(t55xxtiming);
}
void write_reset(T55xxTiming* t55xxtiming) {
write_gap(t55xxtiming->start_gap);
write_bit(t55xxtiming, 1);
write_bit(t55xxtiming, 0);
}

View File

@@ -1,26 +0,0 @@
#include <stdint.h>
#include <stdbool.h>
typedef struct {
uint16_t wait_time;
uint8_t start_gap;
uint8_t write_gap;
uint8_t data_0;
uint8_t data_1;
uint16_t program;
} T55xxTiming;
void writer_start();
void writer_stop();
void write_gap(uint32_t gap_time);
void write_bit(T55xxTiming* t55xxtiming, bool value);
void write_block(
T55xxTiming* t55xxtiming,
uint8_t page,
uint8_t block,
bool lock_bit,
uint32_t data,
bool password_enable,
uint32_t password);
void write_reset(T55xxTiming* t55xxtiming);

View File

@@ -32,7 +32,7 @@ static void rpc_command_callback(RpcAppSystemEvent rpc_event, void* context) {
}
static LfRfid* lfrfid_alloc() {
LfRfid* lfrfid = malloc(sizeof(LfRfid));
LfRfid* lfrfid = malloc(sizeof(LfRfid)); //-V773
lfrfid->storage = furi_record_open(RECORD_STORAGE);
lfrfid->dialogs = furi_record_open(RECORD_DIALOGS);
@@ -100,7 +100,7 @@ static LfRfid* lfrfid_alloc() {
lfrfid->view_dispatcher, LfRfidViewRead, lfrfid_view_read_get_view(lfrfid->read_view));
return lfrfid;
} //-V773
}
static void lfrfid_free(LfRfid* lfrfid) {
furi_assert(lfrfid);

View File

@@ -88,7 +88,7 @@ static void lfrfid_cli_read(Cli* cli, FuriString* args) {
uint32_t flags =
furi_event_flag_wait(context.event, available_flags, FuriFlagWaitAny, 100);
if(flags != (unsigned)FuriFlagErrorTimeout) {
if(flags != FuriFlagErrorTimeout) {
if(FURI_BIT(flags, LFRFIDWorkerReadDone)) {
break;
}
@@ -154,7 +154,7 @@ static bool lfrfid_cli_parse_args(FuriString* args, ProtocolDict* dict, Protocol
for(ProtocolId i = 0; i < LFRFIDProtocolMax; i++) {
printf(
"\t%s, %zu bytes long\r\n",
"\t%s, %d bytes long\r\n",
protocol_dict_get_name(dict, i),
protocol_dict_get_data_size(dict, i));
}
@@ -166,7 +166,7 @@ static bool lfrfid_cli_parse_args(FuriString* args, ProtocolDict* dict, Protocol
// check data arg
if(!args_read_hex_bytes(data_text, data, data_size)) {
printf(
"%s data needs to be %zu bytes long\r\n",
"%s data needs to be %d bytes long\r\n",
protocol_dict_get_name(dict, *protocol),
data_size);
break;
@@ -212,7 +212,7 @@ static void lfrfid_cli_write(Cli* cli, FuriString* args) {
while(!cli_cmd_interrupt_received(cli)) {
uint32_t flags = furi_event_flag_wait(event, available_flags, FuriFlagWaitAny, 100);
if(flags != (unsigned)FuriFlagErrorTimeout) {
if(flags != FuriFlagErrorTimeout) {
if(FURI_BIT(flags, LFRFIDWorkerWriteOK)) {
printf("Written!\r\n");
break;
@@ -310,9 +310,9 @@ static void lfrfid_cli_raw_analyze(Cli* cli, FuriString* args) {
warn = true;
}
furi_string_printf(info_string, "[%lu %lu]", pulse, duration);
furi_string_printf(info_string, "[%ld %ld]", pulse, duration);
printf("%-16s", furi_string_get_cstr(info_string));
furi_string_printf(info_string, "[%lu %lu]", pulse, duration - pulse);
furi_string_printf(info_string, "[%ld %ld]", pulse, duration - pulse);
printf("%-16s", furi_string_get_cstr(info_string));
if(warn) {
@@ -336,7 +336,7 @@ static void lfrfid_cli_raw_analyze(Cli* cli, FuriString* args) {
total_pulse += pulse;
total_duration += duration;
if(total_protocol != PROTOCOL_NO) { //-V1051
if(total_protocol != PROTOCOL_NO) {
break;
}
} else {
@@ -347,9 +347,9 @@ static void lfrfid_cli_raw_analyze(Cli* cli, FuriString* args) {
printf(" Frequency: %f\r\n", (double)frequency);
printf(" Duty Cycle: %f\r\n", (double)duty_cycle);
printf(" Warns: %lu\r\n", total_warns);
printf(" Pulse sum: %lu\r\n", total_pulse);
printf("Duration sum: %lu\r\n", total_duration);
printf(" Warns: %ld\r\n", total_warns);
printf(" Pulse sum: %ld\r\n", total_pulse);
printf("Duration sum: %ld\r\n", total_duration);
printf(" Average: %f\r\n", (double)((float)total_pulse / (float)total_duration));
printf(" Protocol: ");
@@ -436,7 +436,7 @@ static void lfrfid_cli_raw_read(Cli* cli, FuriString* args) {
while(true) {
uint32_t flags = furi_event_flag_wait(event, available_flags, FuriFlagWaitAny, 100);
if(flags != (unsigned)FuriFlagErrorTimeout) {
if(flags != FuriFlagErrorTimeout) {
if(FURI_BIT(flags, LFRFIDWorkerReadRawFileError)) {
printf("File is not RFID raw file\r\n");
break;
@@ -511,7 +511,7 @@ static void lfrfid_cli_raw_emulate(Cli* cli, FuriString* args) {
while(true) {
uint32_t flags = furi_event_flag_wait(event, available_flags, FuriFlagWaitAny, 100);
if(flags != (unsigned)FuriFlagErrorTimeout) {
if(flags != FuriFlagErrorTimeout) {
if(FURI_BIT(flags, LFRFIDWorkerEmulateRawFileError)) {
printf("File is not RFID raw file\r\n");
break;
@@ -574,4 +574,4 @@ static void lfrfid_cli(Cli* cli, FuriString* args, void* context) {
}
furi_string_free(cmd);
}
}

Some files were not shown because too many files have changed in this diff Show More