mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 20:49:49 +04:00
Compare commits
41 Commits
unlshd-065
...
nfcrefacto
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18377185c7 | ||
|
|
ef09dcf8f8 | ||
|
|
bee1a6c18a | ||
|
|
b958bfd5c9 | ||
|
|
49dcf81743 | ||
|
|
16ffa2bf75 | ||
|
|
32e2cbe60a | ||
|
|
a7e6eb7fe4 | ||
|
|
33ed5ea1f2 | ||
|
|
c8c191c0a4 | ||
|
|
78af3214c3 | ||
|
|
e244bedd64 | ||
|
|
ebe95a92d1 | ||
|
|
5921eb3d27 | ||
|
|
9ed23799eb | ||
|
|
19f524ec43 | ||
|
|
085c90af40 | ||
|
|
0d94abf856 | ||
|
|
0131eb3aa2 | ||
|
|
bee48f483c | ||
|
|
47cc05dab4 | ||
|
|
aa06328516 | ||
|
|
7bd3bd7ea4 | ||
|
|
bf8984a225 | ||
|
|
bbe68d6ffc | ||
|
|
9af81ce8d0 | ||
|
|
c8180747db | ||
|
|
917410a0a8 | ||
|
|
176fb21f5f | ||
|
|
593b5fc098 | ||
|
|
0fe93fcfa4 | ||
|
|
cfaf745523 | ||
|
|
3d872cf37a | ||
|
|
844e0f10e5 | ||
|
|
92969ecc1f | ||
|
|
3bbb326c9c | ||
|
|
d92b0a82cc | ||
|
|
ac5abdbb1d | ||
|
|
2958e5cef3 | ||
|
|
35c903494c | ||
|
|
1b6295b2bf |
31
.drone.yml
31
.drone.yml
@@ -22,7 +22,8 @@ steps:
|
|||||||
- export DIST_SUFFIX=${DRONE_TAG}c
|
- export DIST_SUFFIX=${DRONE_TAG}c
|
||||||
- export WORKFLOW_BRANCH_OR_TAG=release-cfw
|
- export WORKFLOW_BRANCH_OR_TAG=release-cfw
|
||||||
- export FORCE_NO_DIRTY=yes
|
- export FORCE_NO_DIRTY=yes
|
||||||
- rm -rf assets/resources/apps/
|
- export FBT_GIT_SUBMODULE_SHALLOW=1
|
||||||
|
- rm -rf applications/main/clock_app/resources/apps/
|
||||||
- rm -rf build/
|
- rm -rf build/
|
||||||
- rm -rf dist/
|
- rm -rf dist/
|
||||||
- rm -rf .sconsign.dblite
|
- rm -rf .sconsign.dblite
|
||||||
@@ -42,10 +43,11 @@ steps:
|
|||||||
- export DIST_SUFFIX=${DRONE_TAG}
|
- export DIST_SUFFIX=${DRONE_TAG}
|
||||||
- export WORKFLOW_BRANCH_OR_TAG=release-cfw
|
- export WORKFLOW_BRANCH_OR_TAG=release-cfw
|
||||||
- export FORCE_NO_DIRTY=yes
|
- export FORCE_NO_DIRTY=yes
|
||||||
|
- export FBT_GIT_SUBMODULE_SHALLOW=1
|
||||||
- wget https://github.com/xMasterX/all-the-plugins/releases/latest/download/all-the-apps-base.tgz
|
- wget https://github.com/xMasterX/all-the-plugins/releases/latest/download/all-the-apps-base.tgz
|
||||||
- tar zxvf all-the-apps-base.tgz
|
- tar zxvf all-the-apps-base.tgz
|
||||||
- cp -R base_pack_build/artifacts-base/* assets/resources/apps/
|
- cp -R base_pack_build/artifacts-base/* applications/main/clock_app/resources/apps/
|
||||||
- cp -R base_pack_build/apps_data/* assets/resources/apps_data/
|
- cp -R base_pack_build/apps_data/* applications/main/clock_app/resources/apps_data/
|
||||||
- rm -rf base_pack_build
|
- rm -rf base_pack_build
|
||||||
- rm -rf all-the-apps-base.tgz
|
- rm -rf all-the-apps-base.tgz
|
||||||
- rm -f build/f7-firmware-C/toolbox/version.*
|
- rm -f build/f7-firmware-C/toolbox/version.*
|
||||||
@@ -64,11 +66,12 @@ steps:
|
|||||||
commands:
|
commands:
|
||||||
- wget https://github.com/xMasterX/all-the-plugins/releases/latest/download/all-the-apps-extra.tgz
|
- wget https://github.com/xMasterX/all-the-plugins/releases/latest/download/all-the-apps-extra.tgz
|
||||||
- tar zxvf all-the-apps-extra.tgz
|
- tar zxvf all-the-apps-extra.tgz
|
||||||
- cp -R extra_pack_build/artifacts-extra/* assets/resources/apps/
|
- cp -R extra_pack_build/artifacts-extra/* applications/main/clock_app/resources/apps/
|
||||||
- rm -rf extra_pack_build
|
- rm -rf extra_pack_build
|
||||||
- export DIST_SUFFIX=${DRONE_TAG}e
|
- export DIST_SUFFIX=${DRONE_TAG}e
|
||||||
- export WORKFLOW_BRANCH_OR_TAG=release-cfw
|
- export WORKFLOW_BRANCH_OR_TAG=release-cfw
|
||||||
- export FORCE_NO_DIRTY=yes
|
- export FORCE_NO_DIRTY=yes
|
||||||
|
- export FBT_GIT_SUBMODULE_SHALLOW=1
|
||||||
- rm -f build/f7-firmware-C/toolbox/version.*
|
- rm -f build/f7-firmware-C/toolbox/version.*
|
||||||
- ./fbt COMPACT=1 DEBUG=0 updater_package
|
- ./fbt COMPACT=1 DEBUG=0 updater_package
|
||||||
- mkdir artifacts-extra-apps
|
- mkdir artifacts-extra-apps
|
||||||
@@ -87,6 +90,7 @@ steps:
|
|||||||
- export DIST_SUFFIX=${DRONE_TAG}r
|
- export DIST_SUFFIX=${DRONE_TAG}r
|
||||||
- export WORKFLOW_BRANCH_OR_TAG=release-cfw-rgb
|
- export WORKFLOW_BRANCH_OR_TAG=release-cfw-rgb
|
||||||
- export FORCE_NO_DIRTY=yes
|
- export FORCE_NO_DIRTY=yes
|
||||||
|
- export FBT_GIT_SUBMODULE_SHALLOW=1
|
||||||
- rm -f build/f7-firmware-C/toolbox/version.*
|
- rm -f build/f7-firmware-C/toolbox/version.*
|
||||||
- ./fbt COMPACT=1 DEBUG=0 updater_package
|
- ./fbt COMPACT=1 DEBUG=0 updater_package
|
||||||
- mkdir artifacts-rgb-patch
|
- mkdir artifacts-rgb-patch
|
||||||
@@ -105,16 +109,17 @@ steps:
|
|||||||
- git checkout -- .
|
- git checkout -- .
|
||||||
- rm -f assets/dolphin/external/manifest.txt
|
- rm -f assets/dolphin/external/manifest.txt
|
||||||
- cp .ci_files/anims_ofw.txt assets/dolphin/external/manifest.txt
|
- cp .ci_files/anims_ofw.txt assets/dolphin/external/manifest.txt
|
||||||
- rm -rf assets/resources/apps/
|
- rm -rf applications/main/clock_app/resources/apps/
|
||||||
- export DIST_SUFFIX=${DRONE_TAG}n
|
- export DIST_SUFFIX=${DRONE_TAG}n
|
||||||
- export WORKFLOW_BRANCH_OR_TAG=no-custom-anims
|
- export WORKFLOW_BRANCH_OR_TAG=no-custom-anims
|
||||||
- export FORCE_NO_DIRTY=yes
|
- export FORCE_NO_DIRTY=yes
|
||||||
|
- export FBT_GIT_SUBMODULE_SHALLOW=1
|
||||||
- rm -f build/f7-firmware-C/toolbox/version.*
|
- rm -f build/f7-firmware-C/toolbox/version.*
|
||||||
- ./fbt COMPACT=1 DEBUG=0 updater_package
|
- ./fbt COMPACT=1 DEBUG=0 updater_package
|
||||||
- wget https://github.com/xMasterX/all-the-plugins/releases/latest/download/all-the-apps-base.tgz
|
- wget https://github.com/xMasterX/all-the-plugins/releases/latest/download/all-the-apps-base.tgz
|
||||||
- tar zxvf all-the-apps-base.tgz
|
- tar zxvf all-the-apps-base.tgz
|
||||||
- cp -R base_pack_build/artifacts-base/* assets/resources/apps/
|
- cp -R base_pack_build/artifacts-base/* applications/main/clock_app/resources/apps/
|
||||||
- cp -R base_pack_build/apps_data/* assets/resources/apps_data/
|
- cp -R base_pack_build/apps_data/* applications/main/clock_app/resources/apps_data/
|
||||||
- rm -rf base_pack_build
|
- rm -rf base_pack_build
|
||||||
- rm -rf all-the-apps-base.tgz
|
- rm -rf all-the-apps-base.tgz
|
||||||
- rm -f build/f7-firmware-C/toolbox/version.*
|
- rm -f build/f7-firmware-C/toolbox/version.*
|
||||||
@@ -391,7 +396,8 @@ steps:
|
|||||||
- export DIST_SUFFIX=${DRONE_BUILD_NUMBER}c
|
- export DIST_SUFFIX=${DRONE_BUILD_NUMBER}c
|
||||||
- export WORKFLOW_BRANCH_OR_TAG=dev-cfw
|
- export WORKFLOW_BRANCH_OR_TAG=dev-cfw
|
||||||
- export FORCE_NO_DIRTY=yes
|
- export FORCE_NO_DIRTY=yes
|
||||||
- rm -rf assets/resources/apps/
|
- export FBT_GIT_SUBMODULE_SHALLOW=1
|
||||||
|
- rm -rf applications/main/clock_app/resources/apps/
|
||||||
- rm -rf build/
|
- rm -rf build/
|
||||||
- rm -rf dist/
|
- rm -rf dist/
|
||||||
- rm -rf .sconsign.dblite
|
- rm -rf .sconsign.dblite
|
||||||
@@ -412,10 +418,11 @@ steps:
|
|||||||
- export DIST_SUFFIX=${DRONE_BUILD_NUMBER}
|
- export DIST_SUFFIX=${DRONE_BUILD_NUMBER}
|
||||||
- export WORKFLOW_BRANCH_OR_TAG=dev-cfw
|
- export WORKFLOW_BRANCH_OR_TAG=dev-cfw
|
||||||
- export FORCE_NO_DIRTY=yes
|
- export FORCE_NO_DIRTY=yes
|
||||||
|
- export FBT_GIT_SUBMODULE_SHALLOW=1
|
||||||
- wget https://github.com/xMasterX/all-the-plugins/releases/latest/download/all-the-apps-base.tgz
|
- wget https://github.com/xMasterX/all-the-plugins/releases/latest/download/all-the-apps-base.tgz
|
||||||
- tar zxvf all-the-apps-base.tgz
|
- tar zxvf all-the-apps-base.tgz
|
||||||
- cp -R base_pack_build/artifacts-base/* assets/resources/apps/
|
- cp -R base_pack_build/artifacts-base/* applications/main/clock_app/resources/apps/
|
||||||
- cp -R base_pack_build/apps_data/* assets/resources/apps_data/
|
- cp -R base_pack_build/apps_data/* applications/main/clock_app/resources/apps_data/
|
||||||
- rm -rf base_pack_build
|
- rm -rf base_pack_build
|
||||||
- rm -rf all-the-apps-base.tgz
|
- rm -rf all-the-apps-base.tgz
|
||||||
- rm -f build/f7-firmware-C/toolbox/version.*
|
- rm -f build/f7-firmware-C/toolbox/version.*
|
||||||
@@ -434,11 +441,12 @@ steps:
|
|||||||
commands:
|
commands:
|
||||||
- wget https://github.com/xMasterX/all-the-plugins/releases/latest/download/all-the-apps-extra.tgz
|
- wget https://github.com/xMasterX/all-the-plugins/releases/latest/download/all-the-apps-extra.tgz
|
||||||
- tar zxvf all-the-apps-extra.tgz
|
- tar zxvf all-the-apps-extra.tgz
|
||||||
- cp -R extra_pack_build/artifacts-extra/* assets/resources/apps/
|
- cp -R extra_pack_build/artifacts-extra/* applications/main/clock_app/resources/apps/
|
||||||
- rm -rf extra_pack_build
|
- rm -rf extra_pack_build
|
||||||
- export DIST_SUFFIX=${DRONE_BUILD_NUMBER}e
|
- export DIST_SUFFIX=${DRONE_BUILD_NUMBER}e
|
||||||
- export WORKFLOW_BRANCH_OR_TAG=dev-cfw
|
- export WORKFLOW_BRANCH_OR_TAG=dev-cfw
|
||||||
- export FORCE_NO_DIRTY=yes
|
- export FORCE_NO_DIRTY=yes
|
||||||
|
- export FBT_GIT_SUBMODULE_SHALLOW=1
|
||||||
- rm -f build/f7-firmware-C/toolbox/version.*
|
- rm -f build/f7-firmware-C/toolbox/version.*
|
||||||
- ./fbt COMPACT=1 DEBUG=0 updater_package
|
- ./fbt COMPACT=1 DEBUG=0 updater_package
|
||||||
- mkdir artifacts-extra-apps
|
- mkdir artifacts-extra-apps
|
||||||
@@ -457,6 +465,7 @@ steps:
|
|||||||
- export DIST_SUFFIX=${DRONE_BUILD_NUMBER}r
|
- export DIST_SUFFIX=${DRONE_BUILD_NUMBER}r
|
||||||
- export WORKFLOW_BRANCH_OR_TAG=dev-cfw-rgb
|
- export WORKFLOW_BRANCH_OR_TAG=dev-cfw-rgb
|
||||||
- export FORCE_NO_DIRTY=yes
|
- export FORCE_NO_DIRTY=yes
|
||||||
|
- export FBT_GIT_SUBMODULE_SHALLOW=1
|
||||||
- rm -f build/f7-firmware-C/toolbox/version.*
|
- rm -f build/f7-firmware-C/toolbox/version.*
|
||||||
- ./fbt COMPACT=1 DEBUG=0 updater_package
|
- ./fbt COMPACT=1 DEBUG=0 updater_package
|
||||||
- mkdir artifacts-rgb-patch
|
- mkdir artifacts-rgb-patch
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
--ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/cmsis_core -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/stm32wb_cmsis -e lib/stm32wb_copro -e lib/stm32wb_hal -e lib/u8g2 -e lib/nanopb -e */arm-none-eabi/*
|
--ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/cmsis_core -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/stm32wb_cmsis -e lib/stm32wb_copro -e lib/stm32wb_hal -e lib/u8g2 -e lib/nanopb -e */arm-none-eabi/*
|
||||||
|
|||||||
35
SConstruct
35
SConstruct
@@ -67,22 +67,22 @@ if GetOption("fullenv") or any(
|
|||||||
# Target for self-update package
|
# Target for self-update package
|
||||||
dist_basic_arguments = [
|
dist_basic_arguments = [
|
||||||
"--bundlever",
|
"--bundlever",
|
||||||
'"${UPDATE_VERSION_STRING}"',
|
"${UPDATE_VERSION_STRING}",
|
||||||
]
|
]
|
||||||
dist_radio_arguments = [
|
dist_radio_arguments = [
|
||||||
"--radio",
|
"--radio",
|
||||||
'"${ROOT_DIR.abspath}/${COPRO_STACK_BIN_DIR}/${COPRO_STACK_BIN}"',
|
"${ROOT_DIR.abspath}/${COPRO_STACK_BIN_DIR}/${COPRO_STACK_BIN}",
|
||||||
"--radiotype",
|
"--radiotype",
|
||||||
"${COPRO_STACK_TYPE}",
|
"${COPRO_STACK_TYPE}",
|
||||||
"${COPRO_DISCLAIMER}",
|
"${COPRO_DISCLAIMER}",
|
||||||
"--obdata",
|
"--obdata",
|
||||||
'"${ROOT_DIR.abspath}/${COPRO_OB_DATA}"',
|
"${ROOT_DIR.abspath}/${COPRO_OB_DATA}",
|
||||||
"--stackversion",
|
"--stackversion",
|
||||||
"${COPRO_CUBE_VERSION}",
|
"${COPRO_CUBE_VERSION}",
|
||||||
]
|
]
|
||||||
dist_resource_arguments = [
|
dist_resource_arguments = [
|
||||||
"-r",
|
"-r",
|
||||||
'"${ROOT_DIR.abspath}/assets/resources"',
|
firmware_env.subst("${RESOURCES_ROOT}"),
|
||||||
]
|
]
|
||||||
dist_splash_arguments = (
|
dist_splash_arguments = (
|
||||||
[
|
[
|
||||||
@@ -95,7 +95,7 @@ if GetOption("fullenv") or any(
|
|||||||
|
|
||||||
selfupdate_dist = distenv.DistCommand(
|
selfupdate_dist = distenv.DistCommand(
|
||||||
"updater_package",
|
"updater_package",
|
||||||
(distenv["DIST_DEPENDS"], firmware_env["FW_RESOURCES"]),
|
(distenv["DIST_DEPENDS"], firmware_env["FW_RESOURCES_MANIFEST"]),
|
||||||
DIST_EXTRA=[
|
DIST_EXTRA=[
|
||||||
*dist_basic_arguments,
|
*dist_basic_arguments,
|
||||||
*dist_radio_arguments,
|
*dist_radio_arguments,
|
||||||
@@ -128,7 +128,8 @@ if GetOption("fullenv") or any(
|
|||||||
|
|
||||||
# Installation over USB & CLI
|
# Installation over USB & CLI
|
||||||
usb_update_package = distenv.AddUsbFlashTarget(
|
usb_update_package = distenv.AddUsbFlashTarget(
|
||||||
"#build/usbinstall.flag", (firmware_env["FW_RESOURCES"], selfupdate_dist)
|
"#build/usbinstall.flag",
|
||||||
|
(firmware_env["FW_RESOURCES_MANIFEST"], selfupdate_dist),
|
||||||
)
|
)
|
||||||
distenv.Alias("flash_usb_full", usb_update_package)
|
distenv.Alias("flash_usb_full", usb_update_package)
|
||||||
|
|
||||||
@@ -166,17 +167,25 @@ Depends(
|
|||||||
list(app_artifact.validator for app_artifact in external_app_list),
|
list(app_artifact.validator for app_artifact in external_app_list),
|
||||||
)
|
)
|
||||||
Alias("fap_dist", fap_dist)
|
Alias("fap_dist", fap_dist)
|
||||||
# distenv.Default(fap_dist)
|
|
||||||
|
|
||||||
distenv.Depends(firmware_env["FW_RESOURCES"], external_apps_artifacts.resources_dist)
|
|
||||||
|
|
||||||
# Copy all faps to device
|
# Copy all faps to device
|
||||||
|
|
||||||
fap_deploy = distenv.PhonyTarget(
|
fap_deploy = distenv.PhonyTarget(
|
||||||
"fap_deploy",
|
"fap_deploy",
|
||||||
"${PYTHON3} ${FBT_SCRIPT_DIR}/storage.py -p ${FLIP_PORT} send ${SOURCE} /ext/apps",
|
[
|
||||||
source=Dir("#/assets/resources/apps"),
|
[
|
||||||
|
"${PYTHON3}",
|
||||||
|
"${FBT_SCRIPT_DIR}/storage.py",
|
||||||
|
"-p",
|
||||||
|
"${FLIP_PORT}",
|
||||||
|
"send",
|
||||||
|
"${SOURCE}",
|
||||||
|
"/ext/apps",
|
||||||
|
]
|
||||||
|
],
|
||||||
|
source=firmware_env.Dir(("${RESOURCES_ROOT}/apps")),
|
||||||
)
|
)
|
||||||
|
Depends(fap_deploy, firmware_env["FW_RESOURCES_MANIFEST"])
|
||||||
|
|
||||||
|
|
||||||
# Target for bundling core2 package for qFlipper
|
# Target for bundling core2 package for qFlipper
|
||||||
@@ -314,9 +323,7 @@ distenv.PhonyTarget(
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Start Flipper CLI via PySerial's miniterm
|
# Start Flipper CLI via PySerial's miniterm
|
||||||
distenv.PhonyTarget(
|
distenv.PhonyTarget("cli", "${PYTHON3} ${FBT_SCRIPT_DIR}/serial_cli.py -p ${FLIP_PORT}")
|
||||||
"cli", "${PYTHON3} ${FBT_SCRIPT_DIR}/serial_cli.py -p ${FLIP_PORT}"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Update WiFi devboard firmware
|
# Update WiFi devboard firmware
|
||||||
distenv.PhonyTarget("devboard_flash", "${PYTHON3} ${FBT_SCRIPT_DIR}/wifi_board.py")
|
distenv.PhonyTarget("devboard_flash", "${PYTHON3} ${FBT_SCRIPT_DIR}/wifi_board.py")
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ static void direct_draw_run(DirectDraw* instance) {
|
|||||||
size_t counter = 0;
|
size_t counter = 0;
|
||||||
float fps = 0;
|
float fps = 0;
|
||||||
|
|
||||||
vTaskPrioritySet(furi_thread_get_current_id(), FuriThreadPriorityIdle);
|
furi_thread_set_current_priority(FuriThreadPriorityIdle);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
size_t elapsed = DWT->CYCCNT - start;
|
size_t elapsed = DWT->CYCCNT - start;
|
||||||
|
|||||||
@@ -21,22 +21,51 @@ static void rpc_debug_app_tick_event_callback(void* context) {
|
|||||||
scene_manager_handle_tick_event(app->scene_manager);
|
scene_manager_handle_tick_event(app->scene_manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rpc_debug_app_rpc_command_callback(RpcAppSystemEvent event, void* context) {
|
static void
|
||||||
|
rpc_debug_app_format_hex(const uint8_t* data, size_t data_size, char* buf, size_t buf_size) {
|
||||||
|
if(data == NULL || data_size == 0) {
|
||||||
|
strncpy(buf, "<Data empty>", buf_size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t byte_width = 3;
|
||||||
|
const size_t line_width = 7;
|
||||||
|
|
||||||
|
data_size = MIN(data_size, buf_size / (byte_width + 1));
|
||||||
|
|
||||||
|
for(size_t i = 0; i < data_size; ++i) {
|
||||||
|
char* p = buf + (i * byte_width);
|
||||||
|
char sep = !((i + 1) % line_width) ? '\n' : ' ';
|
||||||
|
snprintf(p, byte_width + 1, "%02X%c", data[i], sep);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[buf_size - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rpc_debug_app_rpc_command_callback(const RpcAppSystemEvent* event, void* context) {
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
RpcDebugApp* app = context;
|
RpcDebugApp* app = context;
|
||||||
furi_assert(app->rpc);
|
furi_assert(app->rpc);
|
||||||
|
|
||||||
if(event == RpcAppEventSessionClose) {
|
if(event->type == RpcAppEventTypeSessionClose) {
|
||||||
scene_manager_stop(app->scene_manager);
|
scene_manager_stop(app->scene_manager);
|
||||||
view_dispatcher_stop(app->view_dispatcher);
|
view_dispatcher_stop(app->view_dispatcher);
|
||||||
rpc_system_app_set_callback(app->rpc, NULL, NULL);
|
rpc_system_app_set_callback(app->rpc, NULL, NULL);
|
||||||
app->rpc = NULL;
|
app->rpc = NULL;
|
||||||
} else if(event == RpcAppEventAppExit) {
|
} else if(event->type == RpcAppEventTypeAppExit) {
|
||||||
scene_manager_stop(app->scene_manager);
|
scene_manager_stop(app->scene_manager);
|
||||||
view_dispatcher_stop(app->view_dispatcher);
|
view_dispatcher_stop(app->view_dispatcher);
|
||||||
rpc_system_app_confirm(app->rpc, RpcAppEventAppExit, true);
|
rpc_system_app_confirm(app->rpc, true);
|
||||||
|
} else if(event->type == RpcAppEventTypeDataExchange) {
|
||||||
|
furi_assert(event->data.type == RpcAppSystemEventDataTypeBytes);
|
||||||
|
|
||||||
|
rpc_debug_app_format_hex(
|
||||||
|
event->data.bytes.ptr, event->data.bytes.size, app->text_store, TEXT_STORE_SIZE);
|
||||||
|
|
||||||
|
view_dispatcher_send_custom_event(
|
||||||
|
app->view_dispatcher, RpcDebugAppCustomEventRpcDataExchange);
|
||||||
} else {
|
} else {
|
||||||
rpc_system_app_confirm(app->rpc, event, false);
|
rpc_system_app_confirm(app->rpc, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +1,5 @@
|
|||||||
#include "../rpc_debug_app.h"
|
#include "../rpc_debug_app.h"
|
||||||
|
|
||||||
static void rpc_debug_app_scene_start_format_hex(
|
|
||||||
const uint8_t* data,
|
|
||||||
size_t data_size,
|
|
||||||
char* buf,
|
|
||||||
size_t buf_size) {
|
|
||||||
furi_assert(data);
|
|
||||||
furi_assert(buf);
|
|
||||||
|
|
||||||
const size_t byte_width = 3;
|
|
||||||
const size_t line_width = 7;
|
|
||||||
|
|
||||||
data_size = MIN(data_size, buf_size / (byte_width + 1));
|
|
||||||
|
|
||||||
for(size_t i = 0; i < data_size; ++i) {
|
|
||||||
char* p = buf + (i * byte_width);
|
|
||||||
char sep = !((i + 1) % line_width) ? '\n' : ' ';
|
|
||||||
snprintf(p, byte_width + 1, "%02X%c", data[i], sep);
|
|
||||||
}
|
|
||||||
|
|
||||||
buf[buf_size - 1] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rpc_debug_app_scene_receive_data_exchange_callback(
|
|
||||||
const uint8_t* data,
|
|
||||||
size_t data_size,
|
|
||||||
void* context) {
|
|
||||||
RpcDebugApp* app = context;
|
|
||||||
if(data) {
|
|
||||||
rpc_debug_app_scene_start_format_hex(data, data_size, app->text_store, TEXT_STORE_SIZE);
|
|
||||||
} else {
|
|
||||||
strncpy(app->text_store, "<Data empty>", TEXT_STORE_SIZE);
|
|
||||||
}
|
|
||||||
view_dispatcher_send_custom_event(app->view_dispatcher, RpcDebugAppCustomEventRpcDataExchange);
|
|
||||||
}
|
|
||||||
|
|
||||||
void rpc_debug_app_scene_receive_data_exchange_on_enter(void* context) {
|
void rpc_debug_app_scene_receive_data_exchange_on_enter(void* context) {
|
||||||
RpcDebugApp* app = context;
|
RpcDebugApp* app = context;
|
||||||
strncpy(app->text_store, "Received data will appear here...", TEXT_STORE_SIZE);
|
strncpy(app->text_store, "Received data will appear here...", TEXT_STORE_SIZE);
|
||||||
@@ -42,8 +7,6 @@ void rpc_debug_app_scene_receive_data_exchange_on_enter(void* context) {
|
|||||||
text_box_set_text(app->text_box, app->text_store);
|
text_box_set_text(app->text_box, app->text_store);
|
||||||
text_box_set_font(app->text_box, TextBoxFontHex);
|
text_box_set_font(app->text_box, TextBoxFontHex);
|
||||||
|
|
||||||
rpc_system_app_set_data_exchange_callback(
|
|
||||||
app->rpc, rpc_debug_app_scene_receive_data_exchange_callback, app);
|
|
||||||
view_dispatcher_switch_to_view(app->view_dispatcher, RpcDebugAppViewTextBox);
|
view_dispatcher_switch_to_view(app->view_dispatcher, RpcDebugAppViewTextBox);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +16,7 @@ bool rpc_debug_app_scene_receive_data_exchange_on_event(void* context, SceneMana
|
|||||||
|
|
||||||
if(event.type == SceneManagerEventTypeCustom) {
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
if(event.event == RpcDebugAppCustomEventRpcDataExchange) {
|
if(event.event == RpcDebugAppCustomEventRpcDataExchange) {
|
||||||
|
rpc_system_app_confirm(app->rpc, true);
|
||||||
notification_message(app->notifications, &sequence_blink_cyan_100);
|
notification_message(app->notifications, &sequence_blink_cyan_100);
|
||||||
notification_message(app->notifications, &sequence_display_backlight_on);
|
notification_message(app->notifications, &sequence_display_backlight_on);
|
||||||
text_box_set_text(app->text_box, app->text_store);
|
text_box_set_text(app->text_box, app->text_store);
|
||||||
@@ -66,5 +30,4 @@ bool rpc_debug_app_scene_receive_data_exchange_on_event(void* context, SceneMana
|
|||||||
void rpc_debug_app_scene_receive_data_exchange_on_exit(void* context) {
|
void rpc_debug_app_scene_receive_data_exchange_on_exit(void* context) {
|
||||||
RpcDebugApp* app = context;
|
RpcDebugApp* app = context;
|
||||||
text_box_reset(app->text_box);
|
text_box_reset(app->text_box);
|
||||||
rpc_system_app_set_data_exchange_callback(app->rpc, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ App(
|
|||||||
cdefines=["APP_UNIT_TESTS"],
|
cdefines=["APP_UNIT_TESTS"],
|
||||||
requires=["system_settings"],
|
requires=["system_settings"],
|
||||||
provides=["delay_test"],
|
provides=["delay_test"],
|
||||||
|
resources="resources",
|
||||||
order=100,
|
order=100,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ void bt_test_alloc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bt_test_free() {
|
void bt_test_free() {
|
||||||
furi_assert(bt_test);
|
furi_check(bt_test);
|
||||||
free(bt_test->nvm_ram_buff_ref);
|
free(bt_test->nvm_ram_buff_ref);
|
||||||
free(bt_test->nvm_ram_buff_dut);
|
free(bt_test->nvm_ram_buff_dut);
|
||||||
bt_keys_storage_free(bt_test->bt_keys_storage);
|
bt_keys_storage_free(bt_test->bt_keys_storage);
|
||||||
@@ -89,7 +89,7 @@ static void bt_test_keys_remove_test_file() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
MU_TEST(bt_test_keys_storage_serial_profile) {
|
MU_TEST(bt_test_keys_storage_serial_profile) {
|
||||||
furi_assert(bt_test);
|
furi_check(bt_test);
|
||||||
|
|
||||||
bt_test_keys_remove_test_file();
|
bt_test_keys_remove_test_file();
|
||||||
bt_test_keys_storage_profile();
|
bt_test_keys_storage_profile();
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ static void infrared_test_alloc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void infrared_test_free() {
|
static void infrared_test_free() {
|
||||||
furi_assert(test);
|
furi_check(test);
|
||||||
infrared_free_decoder(test->decoder_handler);
|
infrared_free_decoder(test->decoder_handler);
|
||||||
infrared_free_encoder(test->encoder_handler);
|
infrared_free_encoder(test->encoder_handler);
|
||||||
flipper_format_free(test->ff);
|
flipper_format_free(test->ff);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ MU_TEST(manifest_iteration_test) {
|
|||||||
ResourceManifestReader* manifest_reader = resource_manifest_reader_alloc(storage);
|
ResourceManifestReader* manifest_reader = resource_manifest_reader_alloc(storage);
|
||||||
do {
|
do {
|
||||||
// Open manifest file
|
// Open manifest file
|
||||||
if(!resource_manifest_reader_open(manifest_reader, EXT_PATH("unit_tests/Manifest"))) {
|
if(!resource_manifest_reader_open(manifest_reader, EXT_PATH("unit_tests/Manifest_test"))) {
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
458
applications/debug/unit_tests/nfc/nfc_transport.c
Normal file
458
applications/debug/unit_tests/nfc/nfc_transport.c
Normal file
@@ -0,0 +1,458 @@
|
|||||||
|
#ifdef FW_CFG_unit_tests
|
||||||
|
|
||||||
|
#include <lib/nfc/nfc.h>
|
||||||
|
#include <lib/nfc/helpers/iso14443_crc.h>
|
||||||
|
#include <lib/nfc/protocols/iso14443_3a/iso14443_3a.h>
|
||||||
|
|
||||||
|
#include <furi/furi.h>
|
||||||
|
|
||||||
|
#define NFC_MAX_BUFFER_SIZE (256)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NfcTransportLogLevelWarning,
|
||||||
|
NfcTransportLogLevelInfo,
|
||||||
|
} NfcTransportLogLevel;
|
||||||
|
|
||||||
|
FuriMessageQueue* poller_queue = NULL;
|
||||||
|
FuriMessageQueue* listener_queue = NULL;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NfcMessageTypeTx,
|
||||||
|
NfcMessageTypeTimeout,
|
||||||
|
NfcMessageTypeAbort,
|
||||||
|
} NfcMessageType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t data_bits;
|
||||||
|
uint8_t data[NFC_MAX_BUFFER_SIZE];
|
||||||
|
} NfcMessageData;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
NfcMessageType type;
|
||||||
|
NfcMessageData data;
|
||||||
|
} NfcMessage;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NfcStateIdle,
|
||||||
|
NfcStateReady,
|
||||||
|
NfcStateReset,
|
||||||
|
} NfcState;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
Iso14443_3aColResStatusIdle,
|
||||||
|
Iso14443_3aColResStatusInProgress,
|
||||||
|
Iso14443_3aColResStatusDone,
|
||||||
|
} Iso14443_3aColResStatus;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Iso14443_3aSensResp sens_resp;
|
||||||
|
Iso14443_3aSddResp sdd_resp[2];
|
||||||
|
Iso14443_3aSelResp sel_resp[2];
|
||||||
|
} Iso14443_3aColResData;
|
||||||
|
|
||||||
|
struct Nfc {
|
||||||
|
NfcState state;
|
||||||
|
|
||||||
|
Iso14443_3aColResStatus col_res_status;
|
||||||
|
Iso14443_3aColResData col_res_data;
|
||||||
|
|
||||||
|
NfcEventCallback callback;
|
||||||
|
void* context;
|
||||||
|
|
||||||
|
NfcMode mode;
|
||||||
|
|
||||||
|
FuriThread* worker_thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void nfc_test_print(
|
||||||
|
NfcTransportLogLevel log_level,
|
||||||
|
const char* message,
|
||||||
|
uint8_t* buffer,
|
||||||
|
uint16_t bits) {
|
||||||
|
FuriString* str = furi_string_alloc();
|
||||||
|
size_t bytes = (bits + 7) / 8;
|
||||||
|
|
||||||
|
for(size_t i = 0; i < bytes; i++) {
|
||||||
|
furi_string_cat_printf(str, " %02X", buffer[i]);
|
||||||
|
}
|
||||||
|
if(log_level == NfcTransportLogLevelWarning) {
|
||||||
|
FURI_LOG_W(message, "%s", furi_string_get_cstr(str));
|
||||||
|
} else {
|
||||||
|
FURI_LOG_I(message, "%s", furi_string_get_cstr(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
furi_string_free(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nfc_prepare_col_res_data(
|
||||||
|
Nfc* instance,
|
||||||
|
uint8_t* uid,
|
||||||
|
uint8_t uid_len,
|
||||||
|
uint8_t* atqa,
|
||||||
|
uint8_t sak) {
|
||||||
|
memcpy(instance->col_res_data.sens_resp.sens_resp, atqa, 2);
|
||||||
|
|
||||||
|
if(uid_len == 7) {
|
||||||
|
instance->col_res_data.sdd_resp[0].nfcid[0] = 0x88;
|
||||||
|
memcpy(&instance->col_res_data.sdd_resp[0].nfcid[1], uid, 3);
|
||||||
|
uint8_t bss = 0;
|
||||||
|
for(size_t i = 0; i < 4; i++) {
|
||||||
|
bss ^= instance->col_res_data.sdd_resp[0].nfcid[i];
|
||||||
|
}
|
||||||
|
instance->col_res_data.sdd_resp[0].bss = bss;
|
||||||
|
instance->col_res_data.sel_resp[0].sak = 0x04;
|
||||||
|
|
||||||
|
memcpy(instance->col_res_data.sdd_resp[1].nfcid, &uid[3], 4);
|
||||||
|
bss = 0;
|
||||||
|
for(size_t i = 0; i < 4; i++) {
|
||||||
|
bss ^= instance->col_res_data.sdd_resp[1].nfcid[i];
|
||||||
|
}
|
||||||
|
instance->col_res_data.sdd_resp[1].bss = bss;
|
||||||
|
instance->col_res_data.sel_resp[1].sak = sak;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
furi_crash("Not supporting not 7 bytes");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Nfc* nfc_alloc() {
|
||||||
|
Nfc* instance = malloc(sizeof(Nfc));
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_free(Nfc* instance) {
|
||||||
|
furi_check(instance);
|
||||||
|
|
||||||
|
free(instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_config(Nfc* instance, NfcMode mode, NfcTech tech) {
|
||||||
|
UNUSED(instance);
|
||||||
|
UNUSED(tech);
|
||||||
|
|
||||||
|
instance->mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_set_fdt_poll_fc(Nfc* instance, uint32_t fdt_poll_fc) {
|
||||||
|
UNUSED(instance);
|
||||||
|
UNUSED(fdt_poll_fc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_set_fdt_listen_fc(Nfc* instance, uint32_t fdt_listen_fc) {
|
||||||
|
UNUSED(instance);
|
||||||
|
UNUSED(fdt_listen_fc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_set_mask_receive_time_fc(Nfc* instance, uint32_t mask_rx_time_fc) {
|
||||||
|
UNUSED(instance);
|
||||||
|
UNUSED(mask_rx_time_fc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_set_fdt_poll_poll_us(Nfc* instance, uint32_t fdt_poll_poll_us) {
|
||||||
|
UNUSED(instance);
|
||||||
|
UNUSED(fdt_poll_poll_us);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_set_guard_time_us(Nfc* instance, uint32_t guard_time_us) {
|
||||||
|
UNUSED(instance);
|
||||||
|
UNUSED(guard_time_us);
|
||||||
|
}
|
||||||
|
|
||||||
|
NfcError nfc_iso14443a_listener_set_col_res_data(
|
||||||
|
Nfc* instance,
|
||||||
|
uint8_t* uid,
|
||||||
|
uint8_t uid_len,
|
||||||
|
uint8_t* atqa,
|
||||||
|
uint8_t sak) {
|
||||||
|
furi_check(instance);
|
||||||
|
furi_check(uid);
|
||||||
|
furi_check(atqa);
|
||||||
|
|
||||||
|
nfc_prepare_col_res_data(instance, uid, uid_len, atqa, sak);
|
||||||
|
|
||||||
|
return NfcErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t nfc_worker_poller(void* context) {
|
||||||
|
Nfc* instance = context;
|
||||||
|
furi_check(instance->callback);
|
||||||
|
|
||||||
|
instance->state = NfcStateReady;
|
||||||
|
NfcCommand command = NfcCommandContinue;
|
||||||
|
NfcEvent event = {};
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
event.type = NfcEventTypePollerReady;
|
||||||
|
command = instance->callback(event, instance->context);
|
||||||
|
if(command == NfcCommandStop) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
instance->state = NfcStateIdle;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nfc_worker_listener_pass_col_res(Nfc* instance, uint8_t* rx_data, uint16_t rx_bits) {
|
||||||
|
furi_check(instance->col_res_status != Iso14443_3aColResStatusDone);
|
||||||
|
BitBuffer* tx_buffer = bit_buffer_alloc(NFC_MAX_BUFFER_SIZE);
|
||||||
|
|
||||||
|
bool processed = false;
|
||||||
|
|
||||||
|
if((rx_bits == 7) && (rx_data[0] == 0x52)) {
|
||||||
|
instance->col_res_status = Iso14443_3aColResStatusInProgress;
|
||||||
|
bit_buffer_copy_bytes(
|
||||||
|
tx_buffer,
|
||||||
|
instance->col_res_data.sens_resp.sens_resp,
|
||||||
|
sizeof(instance->col_res_data.sens_resp.sens_resp));
|
||||||
|
nfc_listener_tx(instance, tx_buffer);
|
||||||
|
processed = true;
|
||||||
|
} else if(rx_bits == 2 * 8) {
|
||||||
|
if((rx_data[0] == 0x93) && (rx_data[1] == 0x20)) {
|
||||||
|
bit_buffer_copy_bytes(
|
||||||
|
tx_buffer,
|
||||||
|
(const uint8_t*)&instance->col_res_data.sdd_resp[0],
|
||||||
|
sizeof(Iso14443_3aSddResp));
|
||||||
|
nfc_listener_tx(instance, tx_buffer);
|
||||||
|
processed = true;
|
||||||
|
} else if((rx_data[0] == 0x95) && (rx_data[1] == 0x20)) {
|
||||||
|
bit_buffer_copy_bytes(
|
||||||
|
tx_buffer,
|
||||||
|
(const uint8_t*)&instance->col_res_data.sdd_resp[1],
|
||||||
|
sizeof(Iso14443_3aSddResp));
|
||||||
|
nfc_listener_tx(instance, tx_buffer);
|
||||||
|
processed = true;
|
||||||
|
}
|
||||||
|
} else if(rx_bits == 9 * 8) {
|
||||||
|
if((rx_data[0] == 0x93) && (rx_data[1] == 0x70)) {
|
||||||
|
bit_buffer_set_size_bytes(tx_buffer, 1);
|
||||||
|
bit_buffer_set_byte(tx_buffer, 0, instance->col_res_data.sel_resp[0].sak);
|
||||||
|
iso14443_crc_append(Iso14443CrcTypeA, tx_buffer);
|
||||||
|
nfc_listener_tx(instance, tx_buffer);
|
||||||
|
processed = true;
|
||||||
|
} else if((rx_data[0] == 0x95) && (rx_data[1] == 0x70)) {
|
||||||
|
bit_buffer_set_size_bytes(tx_buffer, 1);
|
||||||
|
bit_buffer_set_byte(tx_buffer, 0, instance->col_res_data.sel_resp[1].sak);
|
||||||
|
iso14443_crc_append(Iso14443CrcTypeA, tx_buffer);
|
||||||
|
nfc_listener_tx(instance, tx_buffer);
|
||||||
|
instance->col_res_status = Iso14443_3aColResStatusDone;
|
||||||
|
NfcEvent event = {.type = NfcEventTypeListenerActivated};
|
||||||
|
instance->callback(event, instance->context);
|
||||||
|
|
||||||
|
processed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!processed) {
|
||||||
|
NfcMessage message = {.type = NfcMessageTypeTimeout};
|
||||||
|
furi_message_queue_put(poller_queue, &message, FuriWaitForever);
|
||||||
|
}
|
||||||
|
|
||||||
|
bit_buffer_free(tx_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int32_t nfc_worker_listener(void* context) {
|
||||||
|
Nfc* instance = context;
|
||||||
|
furi_check(instance->callback);
|
||||||
|
|
||||||
|
NfcMessage message = {};
|
||||||
|
|
||||||
|
NfcEventData event_data = {};
|
||||||
|
event_data.buffer = bit_buffer_alloc(NFC_MAX_BUFFER_SIZE);
|
||||||
|
NfcEvent nfc_event = {.data = event_data};
|
||||||
|
|
||||||
|
while(true) {
|
||||||
|
furi_message_queue_get(listener_queue, &message, FuriWaitForever);
|
||||||
|
bit_buffer_copy_bits(event_data.buffer, message.data.data, message.data.data_bits);
|
||||||
|
if((message.data.data[0] == 0x52) && (message.data.data_bits == 7)) {
|
||||||
|
instance->col_res_status = Iso14443_3aColResStatusIdle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message.type == NfcMessageTypeAbort) {
|
||||||
|
break;
|
||||||
|
} else if(message.type == NfcMessageTypeTx) {
|
||||||
|
nfc_test_print(
|
||||||
|
NfcTransportLogLevelInfo, "RDR", message.data.data, message.data.data_bits);
|
||||||
|
if(instance->col_res_status != Iso14443_3aColResStatusDone) {
|
||||||
|
nfc_worker_listener_pass_col_res(
|
||||||
|
instance, message.data.data, message.data.data_bits);
|
||||||
|
} else {
|
||||||
|
instance->state = NfcStateReady;
|
||||||
|
nfc_event.type = NfcEventTypeRxEnd;
|
||||||
|
instance->callback(nfc_event, instance->context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
instance->state = NfcStateIdle;
|
||||||
|
instance->col_res_status = Iso14443_3aColResStatusIdle;
|
||||||
|
memset(&instance->col_res_data, 0, sizeof(instance->col_res_data));
|
||||||
|
bit_buffer_free(nfc_event.data.buffer);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_start(Nfc* instance, NfcEventCallback callback, void* context) {
|
||||||
|
furi_check(instance);
|
||||||
|
furi_check(instance->worker_thread == NULL);
|
||||||
|
|
||||||
|
if(instance->mode == NfcModeListener) {
|
||||||
|
furi_check(listener_queue == NULL);
|
||||||
|
// Check that poller didn't start
|
||||||
|
furi_check(poller_queue == NULL);
|
||||||
|
} else {
|
||||||
|
furi_check(poller_queue == NULL);
|
||||||
|
// Check that poller is started after listener
|
||||||
|
furi_check(listener_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
instance->callback = callback;
|
||||||
|
instance->context = context;
|
||||||
|
|
||||||
|
if(instance->mode == NfcModeListener) {
|
||||||
|
listener_queue = furi_message_queue_alloc(4, sizeof(NfcMessage));
|
||||||
|
} else {
|
||||||
|
poller_queue = furi_message_queue_alloc(4, sizeof(NfcMessage));
|
||||||
|
}
|
||||||
|
|
||||||
|
instance->worker_thread = furi_thread_alloc();
|
||||||
|
furi_thread_set_context(instance->worker_thread, instance);
|
||||||
|
furi_thread_set_priority(instance->worker_thread, FuriThreadPriorityHigh);
|
||||||
|
furi_thread_set_stack_size(instance->worker_thread, 8 * 1024);
|
||||||
|
|
||||||
|
if(instance->mode == NfcModeListener) {
|
||||||
|
furi_thread_set_name(instance->worker_thread, "NfcWorkerListener");
|
||||||
|
furi_thread_set_callback(instance->worker_thread, nfc_worker_listener);
|
||||||
|
} else {
|
||||||
|
furi_thread_set_name(instance->worker_thread, "NfcWorkerPoller");
|
||||||
|
furi_thread_set_callback(instance->worker_thread, nfc_worker_poller);
|
||||||
|
}
|
||||||
|
|
||||||
|
furi_thread_start(instance->worker_thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nfc_stop(Nfc* instance) {
|
||||||
|
furi_check(instance);
|
||||||
|
furi_check(instance->worker_thread);
|
||||||
|
|
||||||
|
if(instance->mode == NfcModeListener) {
|
||||||
|
NfcMessage message = {.type = NfcMessageTypeAbort};
|
||||||
|
furi_message_queue_put(listener_queue, &message, FuriWaitForever);
|
||||||
|
furi_thread_join(instance->worker_thread);
|
||||||
|
|
||||||
|
furi_message_queue_free(listener_queue);
|
||||||
|
listener_queue = NULL;
|
||||||
|
|
||||||
|
furi_thread_free(instance->worker_thread);
|
||||||
|
instance->worker_thread = NULL;
|
||||||
|
} else {
|
||||||
|
furi_thread_join(instance->worker_thread);
|
||||||
|
|
||||||
|
furi_message_queue_free(poller_queue);
|
||||||
|
poller_queue = NULL;
|
||||||
|
|
||||||
|
furi_thread_free(instance->worker_thread);
|
||||||
|
instance->worker_thread = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called from worker thread
|
||||||
|
|
||||||
|
NfcError nfc_listener_tx(Nfc* instance, const BitBuffer* tx_buffer) {
|
||||||
|
furi_check(instance);
|
||||||
|
furi_check(poller_queue);
|
||||||
|
furi_check(listener_queue);
|
||||||
|
furi_check(tx_buffer);
|
||||||
|
|
||||||
|
NfcMessage message = {};
|
||||||
|
message.type = NfcMessageTypeTx;
|
||||||
|
message.data.data_bits = bit_buffer_get_size(tx_buffer);
|
||||||
|
bit_buffer_write_bytes(tx_buffer, message.data.data, bit_buffer_get_size_bytes(tx_buffer));
|
||||||
|
|
||||||
|
furi_message_queue_put(poller_queue, &message, FuriWaitForever);
|
||||||
|
|
||||||
|
return NfcErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
NfcError nfc_iso14443a_listener_tx_custom_parity(Nfc* instance, const BitBuffer* tx_buffer) {
|
||||||
|
return nfc_listener_tx(instance, tx_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
NfcError
|
||||||
|
nfc_poller_trx(Nfc* instance, const BitBuffer* tx_buffer, BitBuffer* rx_buffer, uint32_t fwt) {
|
||||||
|
furi_check(instance);
|
||||||
|
furi_check(tx_buffer);
|
||||||
|
furi_check(rx_buffer);
|
||||||
|
furi_check(poller_queue);
|
||||||
|
furi_check(listener_queue);
|
||||||
|
UNUSED(fwt);
|
||||||
|
|
||||||
|
NfcError error = NfcErrorNone;
|
||||||
|
|
||||||
|
NfcMessage message = {};
|
||||||
|
message.type = NfcMessageTypeTx;
|
||||||
|
message.data.data_bits = bit_buffer_get_size(tx_buffer);
|
||||||
|
bit_buffer_write_bytes(tx_buffer, message.data.data, bit_buffer_get_size_bytes(tx_buffer));
|
||||||
|
// Tx
|
||||||
|
furi_check(furi_message_queue_put(listener_queue, &message, FuriWaitForever) == FuriStatusOk);
|
||||||
|
// Rx
|
||||||
|
FuriStatus status = furi_message_queue_get(poller_queue, &message, 50);
|
||||||
|
|
||||||
|
if(status == FuriStatusErrorTimeout) {
|
||||||
|
error = NfcErrorTimeout;
|
||||||
|
} else if(message.type == NfcMessageTypeTx) {
|
||||||
|
bit_buffer_copy_bits(rx_buffer, message.data.data, message.data.data_bits);
|
||||||
|
nfc_test_print(
|
||||||
|
NfcTransportLogLevelWarning, "TAG", message.data.data, message.data.data_bits);
|
||||||
|
} else if(message.type == NfcMessageTypeTimeout) {
|
||||||
|
error = NfcErrorTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
NfcError nfc_iso14443a_poller_trx_custom_parity(
|
||||||
|
Nfc* instance,
|
||||||
|
const BitBuffer* tx_buffer,
|
||||||
|
BitBuffer* rx_buffer,
|
||||||
|
uint32_t fwt) {
|
||||||
|
return nfc_poller_trx(instance, tx_buffer, rx_buffer, fwt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Technology specific API
|
||||||
|
|
||||||
|
NfcError nfc_iso14443a_poller_trx_short_frame(
|
||||||
|
Nfc* instance,
|
||||||
|
NfcIso14443aShortFrame frame,
|
||||||
|
BitBuffer* rx_buffer,
|
||||||
|
uint32_t fwt) {
|
||||||
|
UNUSED(frame);
|
||||||
|
|
||||||
|
BitBuffer* tx_buffer = bit_buffer_alloc(32);
|
||||||
|
bit_buffer_set_size(tx_buffer, 7);
|
||||||
|
bit_buffer_set_byte(tx_buffer, 0, 0x52);
|
||||||
|
|
||||||
|
NfcError error = nfc_poller_trx(instance, tx_buffer, rx_buffer, fwt);
|
||||||
|
|
||||||
|
bit_buffer_free(tx_buffer);
|
||||||
|
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
NfcError nfc_iso14443a_poller_trx_sdd_frame(
|
||||||
|
Nfc* instance,
|
||||||
|
const BitBuffer* tx_buffer,
|
||||||
|
BitBuffer* rx_buffer,
|
||||||
|
uint32_t fwt) {
|
||||||
|
return nfc_poller_trx(instance, tx_buffer, rx_buffer, fwt);
|
||||||
|
}
|
||||||
|
|
||||||
|
NfcError nfc_iso15693_listener_tx_sof(Nfc* instance) {
|
||||||
|
UNUSED(instance);
|
||||||
|
|
||||||
|
return NfcErrorNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
Filetype: Flipper NFC device
|
||||||
|
Version: 3
|
||||||
|
# Nfc device type can be UID, Mifare Ultralight, Mifare Classic
|
||||||
|
Device type: NTAG213
|
||||||
|
# UID, ATQA and SAK are common for all formats
|
||||||
|
UID: 04 AC 6B 72 BA 6C 80
|
||||||
|
ATQA: 00 44
|
||||||
|
SAK: 00
|
||||||
|
# Mifare Ultralight specific data
|
||||||
|
Data format version: 1
|
||||||
|
Signature: 2D AE BC AF 84 B8 85 87 C2 FB FE 76 13 58 86 72 8E 1D 3C B5 DA 24 23 44 E5 63 4D 4C 82 FB D7 18
|
||||||
|
Mifare version: 00 04 04 02 01 00 0F 03
|
||||||
|
Counter 0: 0
|
||||||
|
Tearing 0: 00
|
||||||
|
Counter 1: 0
|
||||||
|
Tearing 1: 00
|
||||||
|
Counter 2: 0
|
||||||
|
Tearing 2: 00
|
||||||
|
Pages total: 45
|
||||||
|
Pages read: 45
|
||||||
|
Page 0: 04 AC 6B 4B
|
||||||
|
Page 1: 72 BA 6C 80
|
||||||
|
Page 2: 24 48 00 00
|
||||||
|
Page 3: E1 10 12 00
|
||||||
|
Page 4: 00 00 41 50
|
||||||
|
Page 5: 00 00 31 31
|
||||||
|
Page 6: 00 20 09 28
|
||||||
|
Page 7: 00 03 31 59
|
||||||
|
Page 8: 91 DF D3 00
|
||||||
|
Page 9: 00 00 00 00
|
||||||
|
Page 10: 00 00 00 00
|
||||||
|
Page 11: 00 00 00 00
|
||||||
|
Page 12: 00 00 00 00
|
||||||
|
Page 13: 00 00 00 00
|
||||||
|
Page 14: 00 00 00 00
|
||||||
|
Page 15: 00 00 00 00
|
||||||
|
Page 16: 00 00 00 00
|
||||||
|
Page 17: 00 00 00 00
|
||||||
|
Page 18: 00 00 00 00
|
||||||
|
Page 19: 00 00 00 00
|
||||||
|
Page 20: 00 00 00 00
|
||||||
|
Page 21: 00 00 00 00
|
||||||
|
Page 22: 00 00 00 00
|
||||||
|
Page 23: 00 00 00 00
|
||||||
|
Page 24: 00 00 00 00
|
||||||
|
Page 25: 00 00 00 00
|
||||||
|
Page 26: 00 00 00 00
|
||||||
|
Page 27: 00 00 00 00
|
||||||
|
Page 28: 00 00 00 00
|
||||||
|
Page 29: 00 00 00 00
|
||||||
|
Page 30: 00 00 00 00
|
||||||
|
Page 31: 00 00 00 00
|
||||||
|
Page 32: 00 00 00 00
|
||||||
|
Page 33: 00 00 00 00
|
||||||
|
Page 34: 00 00 00 00
|
||||||
|
Page 35: 00 00 00 00
|
||||||
|
Page 36: 00 00 00 00
|
||||||
|
Page 37: 00 00 00 00
|
||||||
|
Page 38: 00 00 00 00
|
||||||
|
Page 39: 00 00 00 00
|
||||||
|
Page 40: 00 00 00 BD
|
||||||
|
Page 41: 04 00 00 04
|
||||||
|
Page 42: C0 05 00 00
|
||||||
|
Page 43: 95 3F 52 FF
|
||||||
|
Page 44: 00 00 00 00
|
||||||
|
Failed authentication attempts: 0
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
Filetype: Flipper NFC device
|
||||||
|
Version: 3
|
||||||
|
# Nfc device type can be UID, Mifare Ultralight, Mifare Classic
|
||||||
|
Device type: NTAG215
|
||||||
|
# UID, ATQA and SAK are common for all formats
|
||||||
|
UID: 04 51 5C FA 6F 73 81
|
||||||
|
ATQA: 00 44
|
||||||
|
SAK: 00
|
||||||
|
# Mifare Ultralight specific data
|
||||||
|
Data format version: 1
|
||||||
|
Signature: 42 21 E4 6C 79 6A 81 5E EA 0D 93 6D 85 EE 4B 0C 2A 00 D5 77 F1 C5 67 F3 63 75 F8 EB 86 48 5E 6B
|
||||||
|
Mifare version: 00 04 04 02 01 00 11 03
|
||||||
|
Counter 0: 0
|
||||||
|
Tearing 0: 00
|
||||||
|
Counter 1: 0
|
||||||
|
Tearing 1: 00
|
||||||
|
Counter 2: 00
|
||||||
|
Tearing 2: 00
|
||||||
|
Pages total: 135
|
||||||
|
Pages read: 135
|
||||||
|
Page 0: 04 51 5C 81
|
||||||
|
Page 1: FA 6F 73 81
|
||||||
|
Page 2: 67 48 0F E0
|
||||||
|
Page 3: F1 10 FF EE
|
||||||
|
Page 4: A5 00 00 00
|
||||||
|
Page 5: 90 42 74 71
|
||||||
|
Page 6: FD 8F 50 61
|
||||||
|
Page 7: C5 65 1B 54
|
||||||
|
Page 8: EF 68 D0 8E
|
||||||
|
Page 9: 3D 35 DB 83
|
||||||
|
Page 10: D3 00 29 F6
|
||||||
|
Page 11: 42 2A A5 5C
|
||||||
|
Page 12: F1 69 0A FC
|
||||||
|
Page 13: B6 44 E9 6B
|
||||||
|
Page 14: 77 41 88 81
|
||||||
|
Page 15: 86 31 CB AD
|
||||||
|
Page 16: B1 DE F1 AB
|
||||||
|
Page 17: DF 96 C2 C5
|
||||||
|
Page 18: C1 26 99 96
|
||||||
|
Page 19: 85 AF 9F 0E
|
||||||
|
Page 20: 58 FE ED DC
|
||||||
|
Page 21: 0A 0A 00 01
|
||||||
|
Page 22: 03 C1 05 02
|
||||||
|
Page 23: 38 39 34 33
|
||||||
|
Page 24: 49 2D 4E 5C
|
||||||
|
Page 25: 5B 21 0F 44
|
||||||
|
Page 26: 3F 3F 76 69
|
||||||
|
Page 27: B4 72 D8 38
|
||||||
|
Page 28: A0 35 53 51
|
||||||
|
Page 29: 53 EB A6 7C
|
||||||
|
Page 30: 3E 8B 97 C0
|
||||||
|
Page 31: 00 7A 45 13
|
||||||
|
Page 32: 3A 8B D4 0F
|
||||||
|
Page 33: 31 C2 32 CC
|
||||||
|
Page 34: B4 24 A6 1B
|
||||||
|
Page 35: D3 F5 4A 1F
|
||||||
|
Page 36: CD 8F 1D 64
|
||||||
|
Page 37: 01 F4 DF C2
|
||||||
|
Page 38: 11 16 C2 C5
|
||||||
|
Page 39: 30 6D 49 AF
|
||||||
|
Page 40: 10 D4 7C 3C
|
||||||
|
Page 41: 6E 36 4E 08
|
||||||
|
Page 42: 95 76 BC 84
|
||||||
|
Page 43: 35 50 DD F0
|
||||||
|
Page 44: 21 0F EE D9
|
||||||
|
Page 45: 85 19 54 5F
|
||||||
|
Page 46: 3E A9 04 20
|
||||||
|
Page 47: 1B 97 E4 39
|
||||||
|
Page 48: FF 0A 45 F6
|
||||||
|
Page 49: 13 D4 3E DD
|
||||||
|
Page 50: 97 42 FC 67
|
||||||
|
Page 51: 6A AC 78 96
|
||||||
|
Page 52: D1 DA 25 23
|
||||||
|
Page 53: BF 4D B3 76
|
||||||
|
Page 54: F1 21 ED 15
|
||||||
|
Page 55: BD 55 11 C4
|
||||||
|
Page 56: 4E 8C E9 23
|
||||||
|
Page 57: C0 C4 6D 5A
|
||||||
|
Page 58: 58 25 FF 95
|
||||||
|
Page 59: 3C 2B 7A 57
|
||||||
|
Page 60: 66 BE A0 61
|
||||||
|
Page 61: BC FC 4A 31
|
||||||
|
Page 62: 4D AC EE 81
|
||||||
|
Page 63: BE 1A 86 04
|
||||||
|
Page 64: F6 D7 5E B3
|
||||||
|
Page 65: E7 A8 A2 86
|
||||||
|
Page 66: E9 40 AB 47
|
||||||
|
Page 67: C8 36 E4 3E
|
||||||
|
Page 68: A7 4D D3 EA
|
||||||
|
Page 69: 83 9A 64 F7
|
||||||
|
Page 70: 96 6B 5D BF
|
||||||
|
Page 71: 4E A2 A6 0F
|
||||||
|
Page 72: BD 3D BE 7C
|
||||||
|
Page 73: 22 0C 68 51
|
||||||
|
Page 74: 0F 9A B8 AE
|
||||||
|
Page 75: 38 2C C4 CD
|
||||||
|
Page 76: 53 D8 DD 18
|
||||||
|
Page 77: A6 5D 35 87
|
||||||
|
Page 78: C9 6D 99 59
|
||||||
|
Page 79: 61 9F B6 DC
|
||||||
|
Page 80: E6 22 0F 99
|
||||||
|
Page 81: 39 82 79 60
|
||||||
|
Page 82: 58 2E BE F7
|
||||||
|
Page 83: EF F7 95 62
|
||||||
|
Page 84: D5 06 1B 58
|
||||||
|
Page 85: 65 05 A9 08
|
||||||
|
Page 86: 75 ED 5D 90
|
||||||
|
Page 87: 5A E1 7E C9
|
||||||
|
Page 88: 35 D6 29 BB
|
||||||
|
Page 89: D0 67 6C F9
|
||||||
|
Page 90: A0 FF 0B 93
|
||||||
|
Page 91: 22 EA A3 3F
|
||||||
|
Page 92: E2 BD BD 58
|
||||||
|
Page 93: BE 93 D9 94
|
||||||
|
Page 94: 41 CC 7E 40
|
||||||
|
Page 95: E6 8C 5A 43
|
||||||
|
Page 96: 65 C1 24 94
|
||||||
|
Page 97: B9 97 61 13
|
||||||
|
Page 98: AD 74 FF 21
|
||||||
|
Page 99: 0F EC F6 03
|
||||||
|
Page 100: 89 5D 89 E5
|
||||||
|
Page 101: 8D 11 F8 D7
|
||||||
|
Page 102: 33 43 79 2E
|
||||||
|
Page 103: 23 E5 29 B5
|
||||||
|
Page 104: 53 98 13 FF
|
||||||
|
Page 105: E8 79 8B 33
|
||||||
|
Page 106: 45 6C 34 38
|
||||||
|
Page 107: 3B 69 28 D7
|
||||||
|
Page 108: D2 80 B0 2F
|
||||||
|
Page 109: D0 18 D5 DD
|
||||||
|
Page 110: 6C 2D D9 97
|
||||||
|
Page 111: CA 78 B4 A2
|
||||||
|
Page 112: B7 3E B8 79
|
||||||
|
Page 113: A2 BE 54 E4
|
||||||
|
Page 114: C8 28 0C 4A
|
||||||
|
Page 115: 81 E7 EC 1C
|
||||||
|
Page 116: 39 93 6F 70
|
||||||
|
Page 117: 75 77 5C FC
|
||||||
|
Page 118: 66 58 0C 1C
|
||||||
|
Page 119: 9F 70 2E C8
|
||||||
|
Page 120: 52 4A 52 BD
|
||||||
|
Page 121: 56 D5 6A 15
|
||||||
|
Page 122: 54 1B 33 90
|
||||||
|
Page 123: 44 11 C1 07
|
||||||
|
Page 124: 11 5C BA 80
|
||||||
|
Page 125: 10 14 20 9A
|
||||||
|
Page 126: 4A D8 E6 36
|
||||||
|
Page 127: DA B8 59 E5
|
||||||
|
Page 128: 5E 48 95 DA
|
||||||
|
Page 129: 96 6A 26 85
|
||||||
|
Page 130: 01 00 0F BD
|
||||||
|
Page 131: 00 00 00 04
|
||||||
|
Page 132: 5F 00 00 00
|
||||||
|
Page 133: 00 00 00 00
|
||||||
|
Page 134: 00 00 00 00
|
||||||
|
Failed authentication attempts: 0
|
||||||
@@ -0,0 +1,252 @@
|
|||||||
|
Filetype: Flipper NFC device
|
||||||
|
Version: 2
|
||||||
|
# Nfc device type can be UID, Mifare Ultralight, Mifare Classic, Bank card
|
||||||
|
Device type: NTAG216
|
||||||
|
# UID, ATQA and SAK are common for all formats
|
||||||
|
UID: 04 D9 65 0A 32 5E 80
|
||||||
|
ATQA: 44 00
|
||||||
|
SAK: 00
|
||||||
|
# Mifare Ultralight specific data
|
||||||
|
Data format version: 1
|
||||||
|
Signature: 48 2A F2 01 0F F2 F5 A7 9A D5 79 6E CB 14 54 48 98 D1 57 5D 8A 23 A9 B0 E8 20 02 3E CD C8 16 DB
|
||||||
|
Mifare version: 00 04 04 02 01 00 13 03
|
||||||
|
Counter 0: 0
|
||||||
|
Tearing 0: 00
|
||||||
|
Counter 1: 0
|
||||||
|
Tearing 1: 00
|
||||||
|
Counter 2: 0
|
||||||
|
Tearing 2: 00
|
||||||
|
Pages total: 231
|
||||||
|
Pages read: 231
|
||||||
|
Page 0: 04 D9 65 30
|
||||||
|
Page 1: 0A 32 5E 80
|
||||||
|
Page 2: E6 48 00 00
|
||||||
|
Page 3: E1 10 6D 00
|
||||||
|
Page 4: 03 37 D1 01
|
||||||
|
Page 5: 33 55 04 6D
|
||||||
|
Page 6: 2E 79 6F 75
|
||||||
|
Page 7: 74 75 62 65
|
||||||
|
Page 8: 2E 63 6F 6D
|
||||||
|
Page 9: 2F 77 61 74
|
||||||
|
Page 10: 63 68 3F 76
|
||||||
|
Page 11: 3D 62 78 71
|
||||||
|
Page 12: 4C 73 72 6C
|
||||||
|
Page 13: 61 6B 4B 38
|
||||||
|
Page 14: 26 66 65 61
|
||||||
|
Page 15: 74 75 72 65
|
||||||
|
Page 16: 3D 79 6F 75
|
||||||
|
Page 17: 74 75 2E 62
|
||||||
|
Page 18: 65 FE 00 00
|
||||||
|
Page 19: 00 00 00 00
|
||||||
|
Page 20: 00 00 00 00
|
||||||
|
Page 21: 00 00 00 00
|
||||||
|
Page 22: 00 00 00 00
|
||||||
|
Page 23: 00 00 00 00
|
||||||
|
Page 24: 00 00 00 00
|
||||||
|
Page 25: 00 00 00 00
|
||||||
|
Page 26: 00 00 00 00
|
||||||
|
Page 27: 00 00 00 00
|
||||||
|
Page 28: 00 00 00 00
|
||||||
|
Page 29: 00 00 00 00
|
||||||
|
Page 30: 00 00 00 00
|
||||||
|
Page 31: 00 00 00 00
|
||||||
|
Page 32: 00 00 00 00
|
||||||
|
Page 33: 00 00 00 00
|
||||||
|
Page 34: 00 00 00 00
|
||||||
|
Page 35: 00 00 00 00
|
||||||
|
Page 36: 00 00 00 00
|
||||||
|
Page 37: 00 00 00 00
|
||||||
|
Page 38: 00 00 00 00
|
||||||
|
Page 39: 00 00 00 00
|
||||||
|
Page 40: 00 00 00 00
|
||||||
|
Page 41: 00 00 00 00
|
||||||
|
Page 42: 00 00 00 00
|
||||||
|
Page 43: 00 00 00 00
|
||||||
|
Page 44: 00 00 00 00
|
||||||
|
Page 45: 00 00 00 00
|
||||||
|
Page 46: 00 00 00 00
|
||||||
|
Page 47: 00 00 00 00
|
||||||
|
Page 48: 00 00 00 00
|
||||||
|
Page 49: 00 00 00 00
|
||||||
|
Page 50: 00 00 00 00
|
||||||
|
Page 51: 00 00 00 00
|
||||||
|
Page 52: 00 00 00 00
|
||||||
|
Page 53: 00 00 00 00
|
||||||
|
Page 54: 00 00 00 00
|
||||||
|
Page 55: 00 00 00 00
|
||||||
|
Page 56: 00 00 00 00
|
||||||
|
Page 57: 00 00 00 00
|
||||||
|
Page 58: 00 00 00 00
|
||||||
|
Page 59: 00 00 00 00
|
||||||
|
Page 60: 00 00 00 00
|
||||||
|
Page 61: 00 00 00 00
|
||||||
|
Page 62: 00 00 00 00
|
||||||
|
Page 63: 00 00 00 00
|
||||||
|
Page 64: 00 00 00 00
|
||||||
|
Page 65: 00 00 00 00
|
||||||
|
Page 66: 00 00 00 00
|
||||||
|
Page 67: 00 00 00 00
|
||||||
|
Page 68: 00 00 00 00
|
||||||
|
Page 69: 00 00 00 00
|
||||||
|
Page 70: 00 00 00 00
|
||||||
|
Page 71: 00 00 00 00
|
||||||
|
Page 72: 00 00 00 00
|
||||||
|
Page 73: 00 00 00 00
|
||||||
|
Page 74: 00 00 00 00
|
||||||
|
Page 75: 00 00 00 00
|
||||||
|
Page 76: 00 00 00 00
|
||||||
|
Page 77: 00 00 00 00
|
||||||
|
Page 78: 00 00 00 00
|
||||||
|
Page 79: 00 00 00 00
|
||||||
|
Page 80: 00 00 00 00
|
||||||
|
Page 81: 00 00 00 00
|
||||||
|
Page 82: 00 00 00 00
|
||||||
|
Page 83: 00 00 00 00
|
||||||
|
Page 84: 00 00 00 00
|
||||||
|
Page 85: 00 00 00 00
|
||||||
|
Page 86: 00 00 00 00
|
||||||
|
Page 87: 00 00 00 00
|
||||||
|
Page 88: 00 00 00 00
|
||||||
|
Page 89: 00 00 00 00
|
||||||
|
Page 90: 00 00 00 00
|
||||||
|
Page 91: 00 00 00 00
|
||||||
|
Page 92: 00 00 00 00
|
||||||
|
Page 93: 00 00 00 00
|
||||||
|
Page 94: 00 00 00 00
|
||||||
|
Page 95: 00 00 00 00
|
||||||
|
Page 96: 00 00 00 00
|
||||||
|
Page 97: 00 00 00 00
|
||||||
|
Page 98: 00 00 00 00
|
||||||
|
Page 99: 00 00 00 00
|
||||||
|
Page 100: 00 00 00 00
|
||||||
|
Page 101: 00 00 00 00
|
||||||
|
Page 102: 00 00 00 00
|
||||||
|
Page 103: 00 00 00 00
|
||||||
|
Page 104: 00 00 00 00
|
||||||
|
Page 105: 00 00 00 00
|
||||||
|
Page 106: 00 00 00 00
|
||||||
|
Page 107: 00 00 00 00
|
||||||
|
Page 108: 00 00 00 00
|
||||||
|
Page 109: 00 00 00 00
|
||||||
|
Page 110: 00 00 00 00
|
||||||
|
Page 111: 00 00 00 00
|
||||||
|
Page 112: 00 00 00 00
|
||||||
|
Page 113: 00 00 00 00
|
||||||
|
Page 114: 00 00 00 00
|
||||||
|
Page 115: 00 00 00 00
|
||||||
|
Page 116: 00 00 00 00
|
||||||
|
Page 117: 00 00 00 00
|
||||||
|
Page 118: 00 00 00 00
|
||||||
|
Page 119: 00 00 00 00
|
||||||
|
Page 120: 00 00 00 00
|
||||||
|
Page 121: 00 00 00 00
|
||||||
|
Page 122: 00 00 00 00
|
||||||
|
Page 123: 00 00 00 00
|
||||||
|
Page 124: 00 00 00 00
|
||||||
|
Page 125: 00 00 00 00
|
||||||
|
Page 126: 00 00 00 00
|
||||||
|
Page 127: 00 00 00 00
|
||||||
|
Page 128: 00 00 00 00
|
||||||
|
Page 129: 00 00 00 00
|
||||||
|
Page 130: 00 00 00 00
|
||||||
|
Page 131: 00 00 00 00
|
||||||
|
Page 132: 00 00 00 00
|
||||||
|
Page 133: 00 00 00 00
|
||||||
|
Page 134: 00 00 00 00
|
||||||
|
Page 135: 00 00 00 00
|
||||||
|
Page 136: 00 00 00 00
|
||||||
|
Page 137: 00 00 00 00
|
||||||
|
Page 138: 00 00 00 00
|
||||||
|
Page 139: 00 00 00 00
|
||||||
|
Page 140: 00 00 00 00
|
||||||
|
Page 141: 00 00 00 00
|
||||||
|
Page 142: 00 00 00 00
|
||||||
|
Page 143: 00 00 00 00
|
||||||
|
Page 144: 00 00 00 00
|
||||||
|
Page 145: 00 00 00 00
|
||||||
|
Page 146: 00 00 00 00
|
||||||
|
Page 147: 00 00 00 00
|
||||||
|
Page 148: 00 00 00 00
|
||||||
|
Page 149: 00 00 00 00
|
||||||
|
Page 150: 00 00 00 00
|
||||||
|
Page 151: 00 00 00 00
|
||||||
|
Page 152: 00 00 00 00
|
||||||
|
Page 153: 00 00 00 00
|
||||||
|
Page 154: 00 00 00 00
|
||||||
|
Page 155: 00 00 00 00
|
||||||
|
Page 156: 00 00 00 00
|
||||||
|
Page 157: 00 00 00 00
|
||||||
|
Page 158: 00 00 00 00
|
||||||
|
Page 159: 00 00 00 00
|
||||||
|
Page 160: 00 00 00 00
|
||||||
|
Page 161: 00 00 00 00
|
||||||
|
Page 162: 00 00 00 00
|
||||||
|
Page 163: 00 00 00 00
|
||||||
|
Page 164: 00 00 00 00
|
||||||
|
Page 165: 00 00 00 00
|
||||||
|
Page 166: 00 00 00 00
|
||||||
|
Page 167: 00 00 00 00
|
||||||
|
Page 168: 00 00 00 00
|
||||||
|
Page 169: 00 00 00 00
|
||||||
|
Page 170: 00 00 00 00
|
||||||
|
Page 171: 00 00 00 00
|
||||||
|
Page 172: 00 00 00 00
|
||||||
|
Page 173: 00 00 00 00
|
||||||
|
Page 174: 00 00 00 00
|
||||||
|
Page 175: 00 00 00 00
|
||||||
|
Page 176: 00 00 00 00
|
||||||
|
Page 177: 00 00 00 00
|
||||||
|
Page 178: 00 00 00 00
|
||||||
|
Page 179: 00 00 00 00
|
||||||
|
Page 180: 00 00 00 00
|
||||||
|
Page 181: 00 00 00 00
|
||||||
|
Page 182: 00 00 00 00
|
||||||
|
Page 183: 00 00 00 00
|
||||||
|
Page 184: 00 00 00 00
|
||||||
|
Page 185: 00 00 00 00
|
||||||
|
Page 186: 00 00 00 00
|
||||||
|
Page 187: 00 00 00 00
|
||||||
|
Page 188: 00 00 00 00
|
||||||
|
Page 189: 00 00 00 00
|
||||||
|
Page 190: 00 00 00 00
|
||||||
|
Page 191: 00 00 00 00
|
||||||
|
Page 192: 00 00 00 00
|
||||||
|
Page 193: 00 00 00 00
|
||||||
|
Page 194: 00 00 00 00
|
||||||
|
Page 195: 00 00 00 00
|
||||||
|
Page 196: 00 00 00 00
|
||||||
|
Page 197: 00 00 00 00
|
||||||
|
Page 198: 00 00 00 00
|
||||||
|
Page 199: 00 00 00 00
|
||||||
|
Page 200: 00 00 00 00
|
||||||
|
Page 201: 00 00 00 00
|
||||||
|
Page 202: 00 00 00 00
|
||||||
|
Page 203: 00 00 00 00
|
||||||
|
Page 204: 00 00 00 00
|
||||||
|
Page 205: 00 00 00 00
|
||||||
|
Page 206: 00 00 00 00
|
||||||
|
Page 207: 00 00 00 00
|
||||||
|
Page 208: 00 00 00 00
|
||||||
|
Page 209: 00 00 00 00
|
||||||
|
Page 210: 00 00 00 00
|
||||||
|
Page 211: 00 00 00 00
|
||||||
|
Page 212: 00 00 00 00
|
||||||
|
Page 213: 00 00 00 00
|
||||||
|
Page 214: 00 00 00 00
|
||||||
|
Page 215: 00 00 00 00
|
||||||
|
Page 216: 00 00 00 00
|
||||||
|
Page 217: 00 00 00 00
|
||||||
|
Page 218: 00 00 00 00
|
||||||
|
Page 219: 00 00 00 00
|
||||||
|
Page 220: 00 00 00 00
|
||||||
|
Page 221: 00 00 00 00
|
||||||
|
Page 222: 00 00 00 00
|
||||||
|
Page 223: 00 00 00 00
|
||||||
|
Page 224: 00 00 00 00
|
||||||
|
Page 225: 00 00 00 00
|
||||||
|
Page 226: 00 00 00 BD
|
||||||
|
Page 227: 04 00 00 FF
|
||||||
|
Page 228: 00 05 00 00
|
||||||
|
Page 229: 00 00 00 00
|
||||||
|
Page 230: 00 00 00 00
|
||||||
|
Failed authentication attempts: 0
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
Filetype: Flipper NFC device
|
||||||
|
Version: 3
|
||||||
|
# Nfc device type can be UID, Mifare Ultralight, Mifare Classic
|
||||||
|
Device type: Mifare Ultralight 11
|
||||||
|
# UID, ATQA and SAK are common for all formats
|
||||||
|
UID: 04 15 74 F2 B0 5E 81
|
||||||
|
ATQA: 00 44
|
||||||
|
SAK: 00
|
||||||
|
# Mifare Ultralight specific data
|
||||||
|
Data format version: 1
|
||||||
|
Signature: A4 37 7D E5 8C 2F 88 D8 04 60 41 6E 3A C8 CD DB 19 94 26 12 C5 D0 12 B0 EB 88 05 72 89 F2 A5 61
|
||||||
|
Mifare version: 00 04 03 01 01 00 0B 03
|
||||||
|
Counter 0: 0
|
||||||
|
Tearing 0: BD
|
||||||
|
Counter 1: 0
|
||||||
|
Tearing 1: BD
|
||||||
|
Counter 2: 0
|
||||||
|
Tearing 2: BD
|
||||||
|
Pages total: 20
|
||||||
|
Pages read: 20
|
||||||
|
Page 0: 04 15 74 ED
|
||||||
|
Page 1: F2 B0 5E 81
|
||||||
|
Page 2: 9D 48 F8 FF
|
||||||
|
Page 3: C1 31 3E 3F
|
||||||
|
Page 4: B0 00 F0 02
|
||||||
|
Page 5: 2F B3 45 A0
|
||||||
|
Page 6: D4 9C 02 F2
|
||||||
|
Page 7: 4A B1 ED FF
|
||||||
|
Page 8: C8 01 00 02
|
||||||
|
Page 9: 4F B3 46 70
|
||||||
|
Page 10: EE F6 60 B0
|
||||||
|
Page 11: B6 C6 12 1B
|
||||||
|
Page 12: B9 1E 49 C3
|
||||||
|
Page 13: 49 DF 7A 57
|
||||||
|
Page 14: 08 52 2A 11
|
||||||
|
Page 15: 28 0A 28 59
|
||||||
|
Page 16: 00 00 00 FF
|
||||||
|
Page 17: 00 05 00 00
|
||||||
|
Page 18: FF FF FF FF
|
||||||
|
Page 19: 00 00 00 00
|
||||||
|
Failed authentication attempts: 0
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
Filetype: Flipper NFC device
|
||||||
|
Version: 3
|
||||||
|
# Nfc device type can be UID, Mifare Ultralight, Mifare Classic
|
||||||
|
Device type: Mifare Ultralight 21
|
||||||
|
# UID, ATQA and SAK are common for all formats
|
||||||
|
UID: 34 BF AB B1 AE 73 D6
|
||||||
|
ATQA: 00 44
|
||||||
|
SAK: 00
|
||||||
|
# Mifare Ultralight specific data
|
||||||
|
Data format version: 1
|
||||||
|
Signature: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||||
|
Mifare version: 00 34 21 01 01 00 0E 03
|
||||||
|
Counter 0: 0
|
||||||
|
Tearing 0: 00
|
||||||
|
Counter 1: 0
|
||||||
|
Tearing 1: 00
|
||||||
|
Counter 2: 0
|
||||||
|
Tearing 2: 00
|
||||||
|
Pages total: 41
|
||||||
|
Pages read: 41
|
||||||
|
Page 0: 34 BF AB A8
|
||||||
|
Page 1: B1 AE 73 D6
|
||||||
|
Page 2: BA 00 70 08
|
||||||
|
Page 3: FF FF FF FC
|
||||||
|
Page 4: 45 D9 BB A0
|
||||||
|
Page 5: 5D 9D FA 00
|
||||||
|
Page 6: 80 70 38 40
|
||||||
|
Page 7: 12 30 02 00
|
||||||
|
Page 8: 00 00 00 00
|
||||||
|
Page 9: 00 00 00 00
|
||||||
|
Page 10: AC A1 0D E4
|
||||||
|
Page 11: 80 70 38 40
|
||||||
|
Page 12: 00 57 A0 01
|
||||||
|
Page 13: 00 08 C1 40
|
||||||
|
Page 14: 00 00 00 00
|
||||||
|
Page 15: AC A1 0D E4
|
||||||
|
Page 16: 00 00 00 00
|
||||||
|
Page 17: 00 00 00 00
|
||||||
|
Page 18: 00 00 00 00
|
||||||
|
Page 19: 00 00 00 00
|
||||||
|
Page 20: 00 00 00 00
|
||||||
|
Page 21: 00 00 00 00
|
||||||
|
Page 22: 00 00 00 00
|
||||||
|
Page 23: 00 00 00 00
|
||||||
|
Page 24: 00 00 00 00
|
||||||
|
Page 25: 00 00 00 00
|
||||||
|
Page 26: 00 00 00 00
|
||||||
|
Page 27: 00 00 00 00
|
||||||
|
Page 28: 00 00 00 00
|
||||||
|
Page 29: 00 00 00 00
|
||||||
|
Page 30: 00 00 00 00
|
||||||
|
Page 31: 00 00 00 00
|
||||||
|
Page 32: 00 00 00 00
|
||||||
|
Page 33: 00 00 00 00
|
||||||
|
Page 34: 00 00 00 00
|
||||||
|
Page 35: 00 00 00 00
|
||||||
|
Page 36: 00 00 00 BD
|
||||||
|
Page 37: 00 00 00 FF
|
||||||
|
Page 38: 00 05 00 00
|
||||||
|
Page 39: FF FF FF FF
|
||||||
|
Page 40: 00 00 00 00
|
||||||
|
Failed authentication attempts: 0
|
||||||
@@ -18,6 +18,8 @@
|
|||||||
#include <cli/cli.h>
|
#include <cli/cli.h>
|
||||||
#include <loader/loader.h>
|
#include <loader/loader.h>
|
||||||
#include <protobuf_version.h>
|
#include <protobuf_version.h>
|
||||||
|
|
||||||
|
#include <FreeRTOS.h>
|
||||||
#include <semphr.h>
|
#include <semphr.h>
|
||||||
|
|
||||||
LIST_DEF(MsgList, PB_Main, M_POD_OPLIST)
|
LIST_DEF(MsgList, PB_Main, M_POD_OPLIST)
|
||||||
@@ -36,7 +38,7 @@ typedef struct {
|
|||||||
FuriStreamBuffer* output_stream;
|
FuriStreamBuffer* output_stream;
|
||||||
SemaphoreHandle_t close_session_semaphore;
|
SemaphoreHandle_t close_session_semaphore;
|
||||||
SemaphoreHandle_t terminate_semaphore;
|
SemaphoreHandle_t terminate_semaphore;
|
||||||
TickType_t timeout;
|
uint32_t timeout;
|
||||||
} RpcSessionContext;
|
} RpcSessionContext;
|
||||||
|
|
||||||
static RpcSessionContext rpc_session[TEST_RPC_SESSIONS];
|
static RpcSessionContext rpc_session[TEST_RPC_SESSIONS];
|
||||||
@@ -544,7 +546,7 @@ static bool test_rpc_pb_stream_read(pb_istream_t* istream, pb_byte_t* buf, size_
|
|||||||
RpcSessionContext* session_context = istream->state;
|
RpcSessionContext* session_context = istream->state;
|
||||||
size_t bytes_received = 0;
|
size_t bytes_received = 0;
|
||||||
|
|
||||||
TickType_t now = xTaskGetTickCount();
|
uint32_t now = furi_get_tick();
|
||||||
int32_t time_left = session_context->timeout - now;
|
int32_t time_left = session_context->timeout - now;
|
||||||
time_left = MAX(time_left, 0);
|
time_left = MAX(time_left, 0);
|
||||||
bytes_received =
|
bytes_received =
|
||||||
@@ -688,7 +690,7 @@ static void test_rpc_decode_and_compare(MsgList_t expected_msg_list, uint8_t ses
|
|||||||
furi_check(!MsgList_empty_p(expected_msg_list));
|
furi_check(!MsgList_empty_p(expected_msg_list));
|
||||||
furi_check(session < TEST_RPC_SESSIONS);
|
furi_check(session < TEST_RPC_SESSIONS);
|
||||||
|
|
||||||
rpc_session[session].timeout = xTaskGetTickCount() + MAX_RECEIVE_OUTPUT_TIMEOUT;
|
rpc_session[session].timeout = furi_get_tick() + MAX_RECEIVE_OUTPUT_TIMEOUT;
|
||||||
pb_istream_t istream = {
|
pb_istream_t istream = {
|
||||||
.callback = test_rpc_pb_stream_read,
|
.callback = test_rpc_pb_stream_read,
|
||||||
.state = &rpc_session[session],
|
.state = &rpc_session[session],
|
||||||
@@ -712,7 +714,7 @@ static void test_rpc_decode_and_compare(MsgList_t expected_msg_list, uint8_t ses
|
|||||||
pb_release(&PB_Main_msg, &result);
|
pb_release(&PB_Main_msg, &result);
|
||||||
}
|
}
|
||||||
|
|
||||||
rpc_session[session].timeout = xTaskGetTickCount() + 50;
|
rpc_session[session].timeout = furi_get_tick() + 50;
|
||||||
if(pb_decode_ex(&istream, &PB_Main_msg, &result, PB_DECODE_DELIMITED)) {
|
if(pb_decode_ex(&istream, &PB_Main_msg, &result, PB_DECODE_DELIMITED)) {
|
||||||
mu_fail("decoded more than expected");
|
mu_fail("decoded more than expected");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,8 +65,8 @@ const UnitTest unit_tests[] = {
|
|||||||
void minunit_print_progress() {
|
void minunit_print_progress() {
|
||||||
static const char progress[] = {'\\', '|', '/', '-'};
|
static const char progress[] = {'\\', '|', '/', '-'};
|
||||||
static uint8_t progress_counter = 0;
|
static uint8_t progress_counter = 0;
|
||||||
static TickType_t last_tick = 0;
|
static uint32_t last_tick = 0;
|
||||||
TickType_t current_tick = xTaskGetTickCount();
|
uint32_t current_tick = furi_get_tick();
|
||||||
if(current_tick - last_tick > 20) {
|
if(current_tick - last_tick > 20) {
|
||||||
last_tick = current_tick;
|
last_tick = current_tick;
|
||||||
printf("[%c]\033[3D", progress[++progress_counter % COUNT_OF(progress)]);
|
printf("[%c]\033[3D", progress[++progress_counter % COUNT_OF(progress)]);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user