mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-13 15:18:35 -07:00
Merge remote-tracking branch 'origin/dev' into nfcf
This commit is contained in:
2
.github/workflows/amap_analyse.yml
vendored
2
.github/workflows/amap_analyse.yml
vendored
@@ -39,7 +39,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: 'Checkout code'
|
- name: 'Checkout code'
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
|||||||
13
.github/workflows/build.yml
vendored
13
.github/workflows/build.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: 'Checkout code'
|
- name: 'Checkout code'
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
@@ -35,6 +35,7 @@ jobs:
|
|||||||
mkdir artifacts
|
mkdir artifacts
|
||||||
|
|
||||||
- name: 'Get commit details'
|
- name: 'Get commit details'
|
||||||
|
id: names
|
||||||
run: |
|
run: |
|
||||||
if [[ ${{ github.event_name }} == 'pull_request' ]]; then
|
if [[ ${{ github.event_name }} == 'pull_request' ]]; then
|
||||||
TYPE="pull"
|
TYPE="pull"
|
||||||
@@ -45,14 +46,6 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE"
|
python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE"
|
||||||
|
|
||||||
- name: 'Generate suffixes for comment'
|
|
||||||
id: names
|
|
||||||
run: |
|
|
||||||
echo "::set-output name=branch_name::${BRANCH_NAME}"
|
|
||||||
echo "::set-output name=commit_sha::${COMMIT_SHA}"
|
|
||||||
echo "::set-output name=default_target::${DEFAULT_TARGET}"
|
|
||||||
echo "::set-output name=suffix::${SUFFIX}"
|
|
||||||
|
|
||||||
- name: 'Bundle scripts'
|
- name: 'Bundle scripts'
|
||||||
if: ${{ !github.event.pull_request.head.repo.fork }}
|
if: ${{ !github.event.pull_request.head.repo.fork }}
|
||||||
run: |
|
run: |
|
||||||
@@ -143,7 +136,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: 'Checkout code'
|
- name: 'Checkout code'
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
submodules: true
|
submodules: true
|
||||||
|
|||||||
6
.github/workflows/check_submodules.yml
vendored
6
.github/workflows/check_submodules.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: 'Checkout code'
|
- name: 'Checkout code'
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
@@ -36,12 +36,12 @@ jobs:
|
|||||||
BRANCHES=$(git branch -r --contains "$SUBMODULE_HASH");
|
BRANCHES=$(git branch -r --contains "$SUBMODULE_HASH");
|
||||||
COMMITS_IN_BRANCH="$(git rev-list --count dev)";
|
COMMITS_IN_BRANCH="$(git rev-list --count dev)";
|
||||||
if [ $COMMITS_IN_BRANCH -lt $SUB_COMMITS_MIN ]; then
|
if [ $COMMITS_IN_BRANCH -lt $SUB_COMMITS_MIN ]; then
|
||||||
echo "::set-output name=fails::error";
|
echo "name=fails::error" >> $GITHUB_OUTPUT
|
||||||
echo "::error::Error: Too low commits in $SUB_BRANCH of submodule $SUB_PATH: $COMMITS_IN_BRANCH(expected $SUB_COMMITS_MIN+)";
|
echo "::error::Error: Too low commits in $SUB_BRANCH of submodule $SUB_PATH: $COMMITS_IN_BRANCH(expected $SUB_COMMITS_MIN+)";
|
||||||
exit 1;
|
exit 1;
|
||||||
fi
|
fi
|
||||||
if ! grep -q "/$SUB_BRANCH" <<< "$BRANCHES"; then
|
if ! grep -q "/$SUB_BRANCH" <<< "$BRANCHES"; then
|
||||||
echo "::set-output name=fails::error";
|
echo "name=fails::error" >> $GITHUB_OUTPUT
|
||||||
echo "::error::Error: Submodule $SUB_PATH is not on branch $SUB_BRANCH";
|
echo "::error::Error: Submodule $SUB_PATH is not on branch $SUB_BRANCH";
|
||||||
exit 1;
|
exit 1;
|
||||||
fi
|
fi
|
||||||
|
|||||||
2
.github/workflows/lint_c.yml
vendored
2
.github/workflows/lint_c.yml
vendored
@@ -23,7 +23,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: 'Checkout code'
|
- name: 'Checkout code'
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
|||||||
2
.github/workflows/lint_python.yml
vendored
2
.github/workflows/lint_python.yml
vendored
@@ -20,7 +20,7 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: 'Checkout code'
|
- name: 'Checkout code'
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
|||||||
41
.github/workflows/merge_report.yml
vendored
Normal file
41
.github/workflows/merge_report.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
name: 'Check FL ticket in PR name'
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- dev
|
||||||
|
jobs:
|
||||||
|
merge_report:
|
||||||
|
runs-on: [self-hosted,FlipperZeroShell]
|
||||||
|
steps:
|
||||||
|
- name: 'Decontaminate previous build leftovers'
|
||||||
|
run: |
|
||||||
|
if [ -d .git ]; then
|
||||||
|
git submodule status || git checkout "$(git rev-list --max-parents=0 HEAD | tail -n 1)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: 'Checkout code'
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
|
||||||
|
- name: 'Get commit details'
|
||||||
|
run: |
|
||||||
|
if [[ ${{ github.event_name }} == 'pull_request' ]]; then
|
||||||
|
TYPE="pull"
|
||||||
|
elif [[ "${{ github.ref }}" == "refs/tags/"* ]]; then
|
||||||
|
TYPE="tag"
|
||||||
|
else
|
||||||
|
TYPE="other"
|
||||||
|
fi
|
||||||
|
python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE"
|
||||||
|
|
||||||
|
- name: 'Check ticket and report'
|
||||||
|
run: |
|
||||||
|
FBT_TOOLCHAIN_PATH=/runner/_work source scripts/toolchain/fbtenv.sh
|
||||||
|
python3 -m pip install slack_sdk
|
||||||
|
python3 scripts/merge_report_qa.py \
|
||||||
|
${{ secrets.QA_REPORT_SLACK_TOKEN }} \
|
||||||
|
${{ secrets.QA_REPORT_SLACK_CHANNEL }}
|
||||||
|
|
||||||
12
.github/workflows/pvs_studio.yml
vendored
12
.github/workflows/pvs_studio.yml
vendored
@@ -25,12 +25,13 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
- name: 'Checkout code'
|
- name: 'Checkout code'
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
|
||||||
- name: 'Get commit details'
|
- name: 'Get commit details'
|
||||||
|
id: names
|
||||||
run: |
|
run: |
|
||||||
if [[ ${{ github.event_name }} == 'pull_request' ]]; then
|
if [[ ${{ github.event_name }} == 'pull_request' ]]; then
|
||||||
TYPE="pull"
|
TYPE="pull"
|
||||||
@@ -41,15 +42,6 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE"
|
python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE"
|
||||||
|
|
||||||
- name: 'Generate suffixes for comment'
|
|
||||||
if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request }}
|
|
||||||
id: names
|
|
||||||
run: |
|
|
||||||
echo "::set-output name=branch_name::${BRANCH_NAME}"
|
|
||||||
echo "::set-output name=commit_sha::${COMMIT_SHA}"
|
|
||||||
echo "::set-output name=default_target::${DEFAULT_TARGET}"
|
|
||||||
echo "::set-output name=suffix::${SUFFIX}"
|
|
||||||
|
|
||||||
- name: 'Make reports directory'
|
- name: 'Make reports directory'
|
||||||
run: |
|
run: |
|
||||||
rm -rf reports/
|
rm -rf reports/
|
||||||
|
|||||||
8
.github/workflows/unit_tests.yml
vendored
8
.github/workflows/unit_tests.yml
vendored
@@ -11,8 +11,14 @@ jobs:
|
|||||||
run_units_on_test_bench:
|
run_units_on_test_bench:
|
||||||
runs-on: [self-hosted, FlipperZeroTest]
|
runs-on: [self-hosted, FlipperZeroTest]
|
||||||
steps:
|
steps:
|
||||||
|
- name: 'Decontaminate previous build leftovers'
|
||||||
|
run: |
|
||||||
|
if [ -d .git ]; then
|
||||||
|
git submodule status || git checkout "$(git rev-list --max-parents=0 HEAD | tail -n 1)"
|
||||||
|
fi
|
||||||
|
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
#include <lib/nfc/helpers/mf_classic_dict.h>
|
#include <lib/nfc/helpers/mf_classic_dict.h>
|
||||||
#include <lib/digital_signal/digital_signal.h>
|
#include <lib/digital_signal/digital_signal.h>
|
||||||
#include <lib/nfc/nfc_device.h>
|
#include <lib/nfc/nfc_device.h>
|
||||||
#include <applications/main/nfc/helpers/nfc_generators.h>
|
#include <lib/nfc/helpers/nfc_generators.h>
|
||||||
|
|
||||||
#include <lib/flipper_format/flipper_format_i.h>
|
#include <lib/flipper_format/flipper_format_i.h>
|
||||||
#include <lib/toolbox/stream/file_stream.h>
|
#include <lib/toolbox/stream/file_stream.h>
|
||||||
@@ -102,7 +102,10 @@ static bool nfc_test_digital_signal_test_encode(
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
// Read test data
|
// Read test data
|
||||||
if(!nfc_test_read_signal_from_file(file_name)) break;
|
if(!nfc_test_read_signal_from_file(file_name)) {
|
||||||
|
FURI_LOG_E(TAG, "Failed to read signal from file");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Encode signal
|
// Encode signal
|
||||||
FURI_CRITICAL_ENTER();
|
FURI_CRITICAL_ENTER();
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include <lib/nfc/nfc_device.h>
|
#include <lib/nfc/nfc_device.h>
|
||||||
#include <lib/nfc/helpers/mf_classic_dict.h>
|
#include <lib/nfc/helpers/mf_classic_dict.h>
|
||||||
#include <lib/nfc/parsers/nfc_supported_card.h>
|
#include <lib/nfc/parsers/nfc_supported_card.h>
|
||||||
|
#include <lib/nfc/helpers/nfc_generators.h>
|
||||||
|
|
||||||
#include "views/dict_attack.h"
|
#include "views/dict_attack.h"
|
||||||
#include "views/detect_reader.h"
|
#include "views/detect_reader.h"
|
||||||
@@ -63,9 +64,6 @@ typedef enum {
|
|||||||
NfcRpcStateEmulated,
|
NfcRpcStateEmulated,
|
||||||
} NfcRpcState;
|
} NfcRpcState;
|
||||||
|
|
||||||
// Forward declaration due to circular dependency
|
|
||||||
typedef struct NfcGenerator NfcGenerator;
|
|
||||||
|
|
||||||
struct Nfc {
|
struct Nfc {
|
||||||
NfcWorker* worker;
|
NfcWorker* worker;
|
||||||
ViewDispatcher* view_dispatcher;
|
ViewDispatcher* view_dispatcher;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
#include "../helpers/nfc_generators.h"
|
#include "lib/nfc/helpers/nfc_generators.h"
|
||||||
|
|
||||||
void nfc_scene_generate_info_dialog_callback(DialogExResult result, void* context) {
|
void nfc_scene_generate_info_dialog_callback(DialogExResult result, void* context) {
|
||||||
Nfc* nfc = context;
|
Nfc* nfc = context;
|
||||||
@@ -39,7 +39,12 @@ bool nfc_scene_generate_info_on_event(void* context, SceneManagerEvent event) {
|
|||||||
|
|
||||||
if(event.type == SceneManagerEventTypeCustom) {
|
if(event.type == SceneManagerEventTypeCustom) {
|
||||||
if(event.event == DialogExResultRight) {
|
if(event.event == DialogExResultRight) {
|
||||||
scene_manager_next_scene(nfc->scene_manager, nfc->generator->next_scene);
|
// Switch either to NfcSceneMfClassicMenu or NfcSceneMfUltralightMenu
|
||||||
|
if(nfc->dev->dev_data.protocol == NfcDeviceProtocolMifareClassic) {
|
||||||
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicMenu);
|
||||||
|
} else if(nfc->dev->dev_data.protocol == NfcDeviceProtocolMifareUl) {
|
||||||
|
scene_manager_next_scene(nfc->scene_manager, NfcSceneMfUltralightMenu);
|
||||||
|
}
|
||||||
consumed = true;
|
consumed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "../nfc_i.h"
|
#include "../nfc_i.h"
|
||||||
#include "../helpers/nfc_generators.h"
|
#include "lib/nfc/helpers/nfc_generators.h"
|
||||||
|
|
||||||
enum SubmenuIndex {
|
enum SubmenuIndex {
|
||||||
SubmenuIndexNFCA4,
|
SubmenuIndexNFCA4,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include <m-array.h>
|
#include <m-array.h>
|
||||||
|
|
||||||
#define FRAME_HEIGHT 12
|
#define FRAME_HEIGHT 12
|
||||||
#define MAX_LEN_PX 100
|
#define MAX_LEN_PX 111
|
||||||
#define MENU_ITEMS 4u
|
#define MENU_ITEMS 4u
|
||||||
#define UNLOCK_CNT 3
|
#define UNLOCK_CNT 3
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ void subghz_view_receiver_draw(Canvas* canvas, SubGhzViewReceiverModel* model) {
|
|||||||
size_t idx = CLAMP((uint16_t)(i + model->list_offset), model->history_item, 0);
|
size_t idx = CLAMP((uint16_t)(i + model->list_offset), model->history_item, 0);
|
||||||
item_menu = SubGhzReceiverMenuItemArray_get(model->history->data, idx);
|
item_menu = SubGhzReceiverMenuItemArray_get(model->history->data, idx);
|
||||||
furi_string_set(str_buff, item_menu->item_str);
|
furi_string_set(str_buff, item_menu->item_str);
|
||||||
elements_string_fit_width(canvas, str_buff, scrollbar ? MAX_LEN_PX - 6 : MAX_LEN_PX);
|
elements_string_fit_width(canvas, str_buff, scrollbar ? MAX_LEN_PX - 7 : MAX_LEN_PX);
|
||||||
if(model->idx == idx) {
|
if(model->idx == idx) {
|
||||||
subghz_view_receiver_draw_frame(canvas, i, scrollbar);
|
subghz_view_receiver_draw_frame(canvas, i, scrollbar);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
BIN
applications/plugins/weather_station/images/Humid_8x13.png
Normal file
BIN
applications/plugins/weather_station/images/Humid_8x13.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
BIN
applications/plugins/weather_station/images/Timer_11x11.png
Normal file
BIN
applications/plugins/weather_station/images/Timer_11x11.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
@@ -99,6 +99,17 @@ bool ws_block_generic_serialize(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//DATE AGE set
|
||||||
|
FuriHalRtcDateTime curr_dt;
|
||||||
|
furi_hal_rtc_get_datetime(&curr_dt);
|
||||||
|
uint32_t curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt);
|
||||||
|
|
||||||
|
temp_data = curr_ts;
|
||||||
|
if(!flipper_format_write_uint32(flipper_format, "Ts", &temp_data, 1)) {
|
||||||
|
FURI_LOG_E(TAG, "Unable to add timestamp");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
temp_data = instance->channel;
|
temp_data = instance->channel;
|
||||||
if(!flipper_format_write_uint32(flipper_format, "Ch", &temp_data, 1)) {
|
if(!flipper_format_write_uint32(flipper_format, "Ch", &temp_data, 1)) {
|
||||||
FURI_LOG_E(TAG, "Unable to add Channel");
|
FURI_LOG_E(TAG, "Unable to add Channel");
|
||||||
@@ -168,6 +179,12 @@ bool ws_block_generic_deserialize(WSBlockGeneric* instance, FlipperFormat* flipp
|
|||||||
}
|
}
|
||||||
instance->humidity = (uint8_t)temp_data;
|
instance->humidity = (uint8_t)temp_data;
|
||||||
|
|
||||||
|
if(!flipper_format_read_uint32(flipper_format, "Ts", (uint32_t*)&temp_data, 1)) {
|
||||||
|
FURI_LOG_E(TAG, "Missing timestamp");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
instance->timestamp = (uint32_t)temp_data;
|
||||||
|
|
||||||
if(!flipper_format_read_uint32(flipper_format, "Ch", (uint32_t*)&temp_data, 1)) {
|
if(!flipper_format_read_uint32(flipper_format, "Ch", (uint32_t*)&temp_data, 1)) {
|
||||||
FURI_LOG_E(TAG, "Missing Channel");
|
FURI_LOG_E(TAG, "Missing Channel");
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ struct WSBlockGeneric {
|
|||||||
uint8_t data_count_bit;
|
uint8_t data_count_bit;
|
||||||
uint8_t battery_low;
|
uint8_t battery_low;
|
||||||
uint8_t humidity;
|
uint8_t humidity;
|
||||||
|
uint32_t timestamp;
|
||||||
uint8_t channel;
|
uint8_t channel;
|
||||||
uint8_t btn;
|
uint8_t btn;
|
||||||
float temp;
|
float temp;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
#include <m-array.h>
|
#include <m-array.h>
|
||||||
|
|
||||||
#define FRAME_HEIGHT 12
|
#define FRAME_HEIGHT 12
|
||||||
#define MAX_LEN_PX 100
|
#define MAX_LEN_PX 112
|
||||||
#define MENU_ITEMS 4u
|
#define MENU_ITEMS 4u
|
||||||
#define UNLOCK_CNT 3
|
#define UNLOCK_CNT 3
|
||||||
|
|
||||||
@@ -189,7 +189,7 @@ void ws_view_receiver_draw(Canvas* canvas, WSReceiverModel* model) {
|
|||||||
canvas_set_color(canvas, ColorBlack);
|
canvas_set_color(canvas, ColorBlack);
|
||||||
}
|
}
|
||||||
canvas_draw_icon(canvas, 4, 2 + i * FRAME_HEIGHT, ReceiverItemIcons[item_menu->type]);
|
canvas_draw_icon(canvas, 4, 2 + i * FRAME_HEIGHT, ReceiverItemIcons[item_menu->type]);
|
||||||
canvas_draw_str(canvas, 15, 9 + i * FRAME_HEIGHT, furi_string_get_cstr(str_buff));
|
canvas_draw_str(canvas, 14, 9 + i * FRAME_HEIGHT, furi_string_get_cstr(str_buff));
|
||||||
furi_string_reset(str_buff);
|
furi_string_reset(str_buff);
|
||||||
}
|
}
|
||||||
if(scrollbar) {
|
if(scrollbar) {
|
||||||
|
|||||||
@@ -9,9 +9,11 @@
|
|||||||
|
|
||||||
struct WSReceiverInfo {
|
struct WSReceiverInfo {
|
||||||
View* view;
|
View* view;
|
||||||
|
FuriTimer* timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
uint32_t curr_ts;
|
||||||
FuriString* protocol_name;
|
FuriString* protocol_name;
|
||||||
WSBlockGeneric* generic;
|
WSBlockGeneric* generic;
|
||||||
} WSReceiverInfoModel;
|
} WSReceiverInfoModel;
|
||||||
@@ -28,6 +30,10 @@ void ws_view_receiver_info_update(WSReceiverInfo* ws_receiver_info, FlipperForma
|
|||||||
flipper_format_read_string(fff, "Protocol", model->protocol_name);
|
flipper_format_read_string(fff, "Protocol", model->protocol_name);
|
||||||
|
|
||||||
ws_block_generic_deserialize(model->generic, fff);
|
ws_block_generic_deserialize(model->generic, fff);
|
||||||
|
|
||||||
|
FuriHalRtcDateTime curr_dt;
|
||||||
|
furi_hal_rtc_get_datetime(&curr_dt);
|
||||||
|
model->curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt);
|
||||||
},
|
},
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
@@ -44,46 +50,76 @@ void ws_view_receiver_info_draw(Canvas* canvas, WSReceiverInfoModel* model) {
|
|||||||
"%s %db",
|
"%s %db",
|
||||||
furi_string_get_cstr(model->protocol_name),
|
furi_string_get_cstr(model->protocol_name),
|
||||||
model->generic->data_count_bit);
|
model->generic->data_count_bit);
|
||||||
canvas_draw_str(canvas, 5, 8, buffer);
|
canvas_draw_str(canvas, 0, 8, buffer);
|
||||||
|
|
||||||
if(model->generic->channel != WS_NO_CHANNEL) {
|
if(model->generic->channel != WS_NO_CHANNEL) {
|
||||||
snprintf(buffer, sizeof(buffer), "Ch: %01d", model->generic->channel);
|
snprintf(buffer, sizeof(buffer), "Ch: %01d", model->generic->channel);
|
||||||
canvas_draw_str(canvas, 105, 8, buffer);
|
canvas_draw_str(canvas, 106, 8, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(model->generic->id != WS_NO_ID) {
|
if(model->generic->id != WS_NO_ID) {
|
||||||
snprintf(buffer, sizeof(buffer), "Sn: 0x%02lX", model->generic->id);
|
snprintf(buffer, sizeof(buffer), "Sn: 0x%02lX", model->generic->id);
|
||||||
canvas_draw_str(canvas, 5, 20, buffer);
|
canvas_draw_str(canvas, 0, 20, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(model->generic->btn != WS_NO_BTN) {
|
if(model->generic->btn != WS_NO_BTN) {
|
||||||
snprintf(buffer, sizeof(buffer), "Btn: %01d", model->generic->btn);
|
snprintf(buffer, sizeof(buffer), "Btn: %01d", model->generic->btn);
|
||||||
canvas_draw_str(canvas, 62, 20, buffer);
|
canvas_draw_str(canvas, 57, 20, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(model->generic->battery_low != WS_NO_BATT) {
|
if(model->generic->battery_low != WS_NO_BATT) {
|
||||||
snprintf(
|
snprintf(
|
||||||
buffer, sizeof(buffer), "Batt: %s", (!model->generic->battery_low ? "ok" : "low"));
|
buffer, sizeof(buffer), "Batt: %s", (!model->generic->battery_low ? "ok" : "low"));
|
||||||
canvas_draw_str(canvas, 90, 20, buffer);
|
canvas_draw_str_aligned(canvas, 126, 17, AlignRight, AlignCenter, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(buffer, sizeof(buffer), "Data: 0x%llX", model->generic->data);
|
snprintf(buffer, sizeof(buffer), "Data: 0x%llX", model->generic->data);
|
||||||
canvas_draw_str(canvas, 5, 32, buffer);
|
canvas_draw_str(canvas, 0, 32, buffer);
|
||||||
|
|
||||||
elements_bold_rounded_frame(canvas, 2, 37, 123, 25);
|
elements_bold_rounded_frame(canvas, 0, 38, 127, 25);
|
||||||
canvas_set_font(canvas, FontPrimary);
|
canvas_set_font(canvas, FontPrimary);
|
||||||
|
|
||||||
if(model->generic->temp != WS_NO_TEMPERATURE) {
|
if(model->generic->temp != WS_NO_TEMPERATURE) {
|
||||||
canvas_draw_icon(canvas, 18, 42, &I_Therm_7x16);
|
canvas_draw_icon(canvas, 6, 43, &I_Therm_7x16);
|
||||||
snprintf(buffer, sizeof(buffer), "%3.1f C", (double)model->generic->temp);
|
snprintf(buffer, sizeof(buffer), "%3.1f C", (double)model->generic->temp);
|
||||||
canvas_draw_str_aligned(canvas, 63, 46, AlignRight, AlignTop, buffer);
|
canvas_draw_str_aligned(canvas, 47, 47, AlignRight, AlignTop, buffer);
|
||||||
canvas_draw_circle(canvas, 55, 45, 1);
|
canvas_draw_circle(canvas, 38, 46, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(model->generic->humidity != WS_NO_HUMIDITY) {
|
if(model->generic->humidity != WS_NO_HUMIDITY) {
|
||||||
canvas_draw_icon(canvas, 75, 42, &I_Humid_10x15);
|
canvas_draw_icon(canvas, 53, 44, &I_Humid_8x13);
|
||||||
snprintf(buffer, sizeof(buffer), "%d%%", model->generic->humidity);
|
snprintf(buffer, sizeof(buffer), "%d%%", model->generic->humidity);
|
||||||
canvas_draw_str(canvas, 91, 54, buffer);
|
canvas_draw_str(canvas, 64, 55, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if((int)model->generic->timestamp > 0 && model->curr_ts) {
|
||||||
|
int ts_diff = (int)model->curr_ts - (int)model->generic->timestamp;
|
||||||
|
|
||||||
|
canvas_draw_icon(canvas, 91, 46, &I_Timer_11x11);
|
||||||
|
|
||||||
|
if(ts_diff > 60) {
|
||||||
|
int tmp_sec = ts_diff;
|
||||||
|
int cnt_min = 1;
|
||||||
|
for(int i = 1; tmp_sec > 60; i++) {
|
||||||
|
tmp_sec = tmp_sec - 60;
|
||||||
|
cnt_min = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(model->curr_ts % 2 == 0) {
|
||||||
|
canvas_draw_str_aligned(canvas, 105, 51, AlignLeft, AlignCenter, "Old");
|
||||||
|
} else {
|
||||||
|
if(cnt_min >= 59) {
|
||||||
|
canvas_draw_str_aligned(canvas, 105, 51, AlignLeft, AlignCenter, "Old");
|
||||||
|
} else {
|
||||||
|
snprintf(buffer, sizeof(buffer), "%dm", cnt_min);
|
||||||
|
canvas_draw_str_aligned(canvas, 114, 51, AlignCenter, AlignCenter, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
snprintf(buffer, sizeof(buffer), "%d", ts_diff);
|
||||||
|
canvas_draw_str_aligned(canvas, 112, 51, AlignCenter, AlignCenter, buffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,14 +134,19 @@ bool ws_view_receiver_info_input(InputEvent* event, void* context) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ws_view_receiver_info_enter(void* context) {
|
static void ws_view_receiver_info_enter(void* context) {
|
||||||
furi_assert(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ws_view_receiver_info_exit(void* context) {
|
|
||||||
furi_assert(context);
|
furi_assert(context);
|
||||||
WSReceiverInfo* ws_receiver_info = context;
|
WSReceiverInfo* ws_receiver_info = context;
|
||||||
|
|
||||||
|
furi_timer_start(ws_receiver_info->timer, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ws_view_receiver_info_exit(void* context) {
|
||||||
|
furi_assert(context);
|
||||||
|
WSReceiverInfo* ws_receiver_info = context;
|
||||||
|
|
||||||
|
furi_timer_stop(ws_receiver_info->timer);
|
||||||
|
|
||||||
with_view_model(
|
with_view_model(
|
||||||
ws_receiver_info->view,
|
ws_receiver_info->view,
|
||||||
WSReceiverInfoModel * model,
|
WSReceiverInfoModel * model,
|
||||||
@@ -113,6 +154,20 @@ void ws_view_receiver_info_exit(void* context) {
|
|||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void ws_view_receiver_info_timer(void* context) {
|
||||||
|
WSReceiverInfo* ws_receiver_info = context;
|
||||||
|
// Force redraw
|
||||||
|
with_view_model(
|
||||||
|
ws_receiver_info->view,
|
||||||
|
WSReceiverInfoModel * model,
|
||||||
|
{
|
||||||
|
FuriHalRtcDateTime curr_dt;
|
||||||
|
furi_hal_rtc_get_datetime(&curr_dt);
|
||||||
|
model->curr_ts = furi_hal_rtc_datetime_to_timestamp(&curr_dt);
|
||||||
|
},
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
WSReceiverInfo* ws_view_receiver_info_alloc() {
|
WSReceiverInfo* ws_view_receiver_info_alloc() {
|
||||||
WSReceiverInfo* ws_receiver_info = malloc(sizeof(WSReceiverInfo));
|
WSReceiverInfo* ws_receiver_info = malloc(sizeof(WSReceiverInfo));
|
||||||
|
|
||||||
@@ -135,12 +190,17 @@ WSReceiverInfo* ws_view_receiver_info_alloc() {
|
|||||||
},
|
},
|
||||||
true);
|
true);
|
||||||
|
|
||||||
|
ws_receiver_info->timer =
|
||||||
|
furi_timer_alloc(ws_view_receiver_info_timer, FuriTimerTypePeriodic, ws_receiver_info);
|
||||||
|
|
||||||
return ws_receiver_info;
|
return ws_receiver_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ws_view_receiver_info_free(WSReceiverInfo* ws_receiver_info) {
|
void ws_view_receiver_info_free(WSReceiverInfo* ws_receiver_info) {
|
||||||
furi_assert(ws_receiver_info);
|
furi_assert(ws_receiver_info);
|
||||||
|
|
||||||
|
furi_timer_free(ws_receiver_info->timer);
|
||||||
|
|
||||||
with_view_model(
|
with_view_model(
|
||||||
ws_receiver_info->view,
|
ws_receiver_info->view,
|
||||||
WSReceiverInfoModel * model,
|
WSReceiverInfoModel * model,
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ struct ButtonMenu {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ButtonMenuItemArray_t items;
|
ButtonMenuItemArray_t items;
|
||||||
uint8_t position;
|
size_t position;
|
||||||
const char* header;
|
const char* header;
|
||||||
} ButtonMenuModel;
|
} ButtonMenuModel;
|
||||||
|
|
||||||
@@ -102,11 +102,9 @@ static void button_menu_view_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
ButtonMenuModel* model = (ButtonMenuModel*)_model;
|
ButtonMenuModel* model = (ButtonMenuModel*)_model;
|
||||||
canvas_set_font(canvas, FontSecondary);
|
canvas_set_font(canvas, FontSecondary);
|
||||||
|
|
||||||
uint8_t item_position = 0;
|
const size_t active_screen = model->position / BUTTONS_PER_SCREEN;
|
||||||
int8_t active_screen = model->position / BUTTONS_PER_SCREEN;
|
const size_t items_size = ButtonMenuItemArray_size(model->items);
|
||||||
size_t items_size = ButtonMenuItemArray_size(model->items);
|
const size_t max_screen = items_size ? (items_size - 1) / BUTTONS_PER_SCREEN : 0;
|
||||||
int8_t max_screen = ((int16_t)items_size - 1) / BUTTONS_PER_SCREEN;
|
|
||||||
ButtonMenuItemArray_it_t it;
|
|
||||||
|
|
||||||
if(active_screen > 0) {
|
if(active_screen > 0) {
|
||||||
canvas_draw_icon(canvas, 28, 1, &I_InfraredArrowUp_4x8);
|
canvas_draw_icon(canvas, 28, 1, &I_InfraredArrowUp_4x8);
|
||||||
@@ -125,6 +123,9 @@ static void button_menu_view_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
furi_string_free(disp_str);
|
furi_string_free(disp_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t item_position = 0;
|
||||||
|
ButtonMenuItemArray_it_t it;
|
||||||
|
|
||||||
for(ButtonMenuItemArray_it(it, model->items); !ButtonMenuItemArray_end_p(it);
|
for(ButtonMenuItemArray_it(it, model->items); !ButtonMenuItemArray_end_p(it);
|
||||||
ButtonMenuItemArray_next(it), ++item_position) {
|
ButtonMenuItemArray_next(it), ++item_position) {
|
||||||
if(active_screen == (item_position / BUTTONS_PER_SCREEN)) {
|
if(active_screen == (item_position / BUTTONS_PER_SCREEN)) {
|
||||||
@@ -195,14 +196,14 @@ static void button_menu_process_ok(ButtonMenu* button_menu, InputType type) {
|
|||||||
if(item) {
|
if(item) {
|
||||||
if(item->type == ButtonMenuItemTypeControl) {
|
if(item->type == ButtonMenuItemTypeControl) {
|
||||||
if(type == InputTypeShort) {
|
if(type == InputTypeShort) {
|
||||||
if(item && item->callback) {
|
if(item->callback) {
|
||||||
item->callback(item->callback_context, item->index, type);
|
item->callback(item->callback_context, item->index, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(item->type == ButtonMenuItemTypeCommon) {
|
if(item->type == ButtonMenuItemTypeCommon) {
|
||||||
if((type == InputTypePress) || (type == InputTypeRelease)) {
|
if((type == InputTypePress) || (type == InputTypeRelease)) {
|
||||||
if(item && item->callback) {
|
if(item->callback) {
|
||||||
item->callback(item->callback_context, item->index, type);
|
item->callback(item->callback_context, item->index, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -341,7 +342,7 @@ void button_menu_set_selected_item(ButtonMenu* button_menu, uint32_t index) {
|
|||||||
button_menu->view,
|
button_menu->view,
|
||||||
ButtonMenuModel * model,
|
ButtonMenuModel * model,
|
||||||
{
|
{
|
||||||
uint8_t item_position = 0;
|
size_t item_position = 0;
|
||||||
ButtonMenuItemArray_it_t it;
|
ButtonMenuItemArray_it_t it;
|
||||||
for(ButtonMenuItemArray_it(it, model->items); !ButtonMenuItemArray_end_p(it);
|
for(ButtonMenuItemArray_it(it, model->items); !ButtonMenuItemArray_end_p(it);
|
||||||
ButtonMenuItemArray_next(it), ++item_position) {
|
ButtonMenuItemArray_next(it), ++item_position) {
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ ARRAY_DEF(SubmenuItemArray, SubmenuItem, M_POD_OPLIST);
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
SubmenuItemArray_t items;
|
SubmenuItemArray_t items;
|
||||||
const char* header;
|
const char* header;
|
||||||
uint8_t position;
|
size_t position;
|
||||||
uint8_t window_position;
|
size_t window_position;
|
||||||
} SubmenuModel;
|
} SubmenuModel;
|
||||||
|
|
||||||
static void submenu_process_up(Submenu* submenu);
|
static void submenu_process_up(Submenu* submenu);
|
||||||
@@ -36,19 +36,19 @@ static void submenu_view_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
|
|
||||||
canvas_clear(canvas);
|
canvas_clear(canvas);
|
||||||
|
|
||||||
uint8_t position = 0;
|
|
||||||
SubmenuItemArray_it_t it;
|
|
||||||
|
|
||||||
if(model->header) {
|
if(model->header) {
|
||||||
canvas_set_font(canvas, FontPrimary);
|
canvas_set_font(canvas, FontPrimary);
|
||||||
canvas_draw_str(canvas, 4, 11, model->header);
|
canvas_draw_str(canvas, 4, 11, model->header);
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas_set_font(canvas, FontSecondary);
|
canvas_set_font(canvas, FontSecondary);
|
||||||
|
|
||||||
|
size_t position = 0;
|
||||||
|
SubmenuItemArray_it_t it;
|
||||||
for(SubmenuItemArray_it(it, model->items); !SubmenuItemArray_end_p(it);
|
for(SubmenuItemArray_it(it, model->items); !SubmenuItemArray_end_p(it);
|
||||||
SubmenuItemArray_next(it)) {
|
SubmenuItemArray_next(it)) {
|
||||||
uint8_t item_position = position - model->window_position;
|
const size_t item_position = position - model->window_position;
|
||||||
uint8_t items_on_screen = model->header ? 3 : 4;
|
const size_t items_on_screen = model->header ? 3 : 4;
|
||||||
uint8_t y_offset = model->header ? 16 : 0;
|
uint8_t y_offset = model->header ? 16 : 0;
|
||||||
|
|
||||||
if(item_position < items_on_screen) {
|
if(item_position < items_on_screen) {
|
||||||
@@ -198,7 +198,7 @@ void submenu_set_selected_item(Submenu* submenu, uint32_t index) {
|
|||||||
submenu->view,
|
submenu->view,
|
||||||
SubmenuModel * model,
|
SubmenuModel * model,
|
||||||
{
|
{
|
||||||
uint32_t position = 0;
|
size_t position = 0;
|
||||||
SubmenuItemArray_it_t it;
|
SubmenuItemArray_it_t it;
|
||||||
for(SubmenuItemArray_it(it, model->items); !SubmenuItemArray_end_p(it);
|
for(SubmenuItemArray_it(it, model->items); !SubmenuItemArray_end_p(it);
|
||||||
SubmenuItemArray_next(it)) {
|
SubmenuItemArray_next(it)) {
|
||||||
@@ -208,7 +208,9 @@ void submenu_set_selected_item(Submenu* submenu, uint32_t index) {
|
|||||||
position++;
|
position++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(position >= SubmenuItemArray_size(model->items)) {
|
const size_t items_size = SubmenuItemArray_size(model->items);
|
||||||
|
|
||||||
|
if(position >= items_size) {
|
||||||
position = 0;
|
position = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,16 +221,12 @@ void submenu_set_selected_item(Submenu* submenu, uint32_t index) {
|
|||||||
model->window_position -= 1;
|
model->window_position -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t items_on_screen = model->header ? 3 : 4;
|
const size_t items_on_screen = model->header ? 3 : 4;
|
||||||
|
|
||||||
if(SubmenuItemArray_size(model->items) <= items_on_screen) {
|
if(items_size <= items_on_screen) {
|
||||||
model->window_position = 0;
|
model->window_position = 0;
|
||||||
} else {
|
} else if(model->window_position >= items_size - items_on_screen) {
|
||||||
if(model->window_position >=
|
model->window_position = items_size - items_on_screen;
|
||||||
(SubmenuItemArray_size(model->items) - items_on_screen)) {
|
|
||||||
model->window_position =
|
|
||||||
(SubmenuItemArray_size(model->items) - items_on_screen);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
true);
|
true);
|
||||||
@@ -239,16 +237,18 @@ void submenu_process_up(Submenu* submenu) {
|
|||||||
submenu->view,
|
submenu->view,
|
||||||
SubmenuModel * model,
|
SubmenuModel * model,
|
||||||
{
|
{
|
||||||
uint8_t items_on_screen = model->header ? 3 : 4;
|
const size_t items_on_screen = model->header ? 3 : 4;
|
||||||
|
const size_t items_size = SubmenuItemArray_size(model->items);
|
||||||
|
|
||||||
if(model->position > 0) {
|
if(model->position > 0) {
|
||||||
model->position--;
|
model->position--;
|
||||||
if(((model->position - model->window_position) < 1) &&
|
if((model->position - model->window_position < 1) &&
|
||||||
model->window_position > 0) {
|
(model->window_position > 0)) {
|
||||||
model->window_position--;
|
model->window_position--;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
model->position = SubmenuItemArray_size(model->items) - 1;
|
model->position = items_size - 1;
|
||||||
if(model->position > (items_on_screen - 1)) {
|
if(model->position > items_on_screen - 1) {
|
||||||
model->window_position = model->position - (items_on_screen - 1);
|
model->window_position = model->position - (items_on_screen - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,12 +261,13 @@ void submenu_process_down(Submenu* submenu) {
|
|||||||
submenu->view,
|
submenu->view,
|
||||||
SubmenuModel * model,
|
SubmenuModel * model,
|
||||||
{
|
{
|
||||||
uint8_t items_on_screen = model->header ? 3 : 4;
|
const size_t items_on_screen = model->header ? 3 : 4;
|
||||||
if(model->position < (SubmenuItemArray_size(model->items) - 1)) {
|
const size_t items_size = SubmenuItemArray_size(model->items);
|
||||||
|
|
||||||
|
if(model->position < items_size - 1) {
|
||||||
model->position++;
|
model->position++;
|
||||||
if((model->position - model->window_position) > (items_on_screen - 2) &&
|
if((model->position - model->window_position > items_on_screen - 2) &&
|
||||||
model->window_position <
|
(model->window_position < items_size - items_on_screen)) {
|
||||||
(SubmenuItemArray_size(model->items) - items_on_screen)) {
|
|
||||||
model->window_position++;
|
model->window_position++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -284,7 +285,8 @@ void submenu_process_ok(Submenu* submenu) {
|
|||||||
submenu->view,
|
submenu->view,
|
||||||
SubmenuModel * model,
|
SubmenuModel * model,
|
||||||
{
|
{
|
||||||
if(model->position < (SubmenuItemArray_size(model->items))) {
|
const size_t items_size = SubmenuItemArray_size(model->items);
|
||||||
|
if(model->position < items_size) {
|
||||||
item = SubmenuItemArray_get(model->items, model->position);
|
item = SubmenuItemArray_get(model->items, model->position);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -81,7 +81,6 @@ FIRMWARE_APPS = {
|
|||||||
"basic_services",
|
"basic_services",
|
||||||
"updater_app",
|
"updater_app",
|
||||||
"unit_tests",
|
"unit_tests",
|
||||||
"nfc",
|
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -376,103 +376,86 @@ static void nfc_generate_mf_classic_4k_7b_uid(NfcDeviceData* data) {
|
|||||||
static const NfcGenerator mf_ul_generator = {
|
static const NfcGenerator mf_ul_generator = {
|
||||||
.name = "Mifare Ultralight",
|
.name = "Mifare Ultralight",
|
||||||
.generator_func = nfc_generate_mf_ul_orig,
|
.generator_func = nfc_generate_mf_ul_orig,
|
||||||
.next_scene = NfcSceneMfUltralightMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator mf_ul_11_generator = {
|
static const NfcGenerator mf_ul_11_generator = {
|
||||||
.name = "Mifare Ultralight EV1 11",
|
.name = "Mifare Ultralight EV1 11",
|
||||||
.generator_func = nfc_generate_mf_ul_11,
|
.generator_func = nfc_generate_mf_ul_11,
|
||||||
.next_scene = NfcSceneMfUltralightMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator mf_ul_h11_generator = {
|
static const NfcGenerator mf_ul_h11_generator = {
|
||||||
.name = "Mifare Ultralight EV1 H11",
|
.name = "Mifare Ultralight EV1 H11",
|
||||||
.generator_func = nfc_generate_mf_ul_h11,
|
.generator_func = nfc_generate_mf_ul_h11,
|
||||||
.next_scene = NfcSceneMfUltralightMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator mf_ul_21_generator = {
|
static const NfcGenerator mf_ul_21_generator = {
|
||||||
.name = "Mifare Ultralight EV1 21",
|
.name = "Mifare Ultralight EV1 21",
|
||||||
.generator_func = nfc_generate_mf_ul_21,
|
.generator_func = nfc_generate_mf_ul_21,
|
||||||
.next_scene = NfcSceneMfUltralightMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator mf_ul_h21_generator = {
|
static const NfcGenerator mf_ul_h21_generator = {
|
||||||
.name = "Mifare Ultralight EV1 H21",
|
.name = "Mifare Ultralight EV1 H21",
|
||||||
.generator_func = nfc_generate_mf_ul_h21,
|
.generator_func = nfc_generate_mf_ul_h21,
|
||||||
.next_scene = NfcSceneMfUltralightMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator ntag203_generator = {
|
static const NfcGenerator ntag203_generator = {
|
||||||
.name = "NTAG203",
|
.name = "NTAG203",
|
||||||
.generator_func = nfc_generate_mf_ul_ntag203,
|
.generator_func = nfc_generate_mf_ul_ntag203,
|
||||||
.next_scene = NfcSceneMfUltralightMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator ntag213_generator = {
|
static const NfcGenerator ntag213_generator = {
|
||||||
.name = "NTAG213",
|
.name = "NTAG213",
|
||||||
.generator_func = nfc_generate_ntag213,
|
.generator_func = nfc_generate_ntag213,
|
||||||
.next_scene = NfcSceneMfUltralightMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator ntag215_generator = {
|
static const NfcGenerator ntag215_generator = {
|
||||||
.name = "NTAG215",
|
.name = "NTAG215",
|
||||||
.generator_func = nfc_generate_ntag215,
|
.generator_func = nfc_generate_ntag215,
|
||||||
.next_scene = NfcSceneMfUltralightMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator ntag216_generator = {
|
static const NfcGenerator ntag216_generator = {
|
||||||
.name = "NTAG216",
|
.name = "NTAG216",
|
||||||
.generator_func = nfc_generate_ntag216,
|
.generator_func = nfc_generate_ntag216,
|
||||||
.next_scene = NfcSceneMfUltralightMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator ntag_i2c_1k_generator = {
|
static const NfcGenerator ntag_i2c_1k_generator = {
|
||||||
.name = "NTAG I2C 1k",
|
.name = "NTAG I2C 1k",
|
||||||
.generator_func = nfc_generate_ntag_i2c_1k,
|
.generator_func = nfc_generate_ntag_i2c_1k,
|
||||||
.next_scene = NfcSceneMfUltralightMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator ntag_i2c_2k_generator = {
|
static const NfcGenerator ntag_i2c_2k_generator = {
|
||||||
.name = "NTAG I2C 2k",
|
.name = "NTAG I2C 2k",
|
||||||
.generator_func = nfc_generate_ntag_i2c_2k,
|
.generator_func = nfc_generate_ntag_i2c_2k,
|
||||||
.next_scene = NfcSceneMfUltralightMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator ntag_i2c_plus_1k_generator = {
|
static const NfcGenerator ntag_i2c_plus_1k_generator = {
|
||||||
.name = "NTAG I2C Plus 1k",
|
.name = "NTAG I2C Plus 1k",
|
||||||
.generator_func = nfc_generate_ntag_i2c_plus_1k,
|
.generator_func = nfc_generate_ntag_i2c_plus_1k,
|
||||||
.next_scene = NfcSceneMfUltralightMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator ntag_i2c_plus_2k_generator = {
|
static const NfcGenerator ntag_i2c_plus_2k_generator = {
|
||||||
.name = "NTAG I2C Plus 2k",
|
.name = "NTAG I2C Plus 2k",
|
||||||
.generator_func = nfc_generate_ntag_i2c_plus_2k,
|
.generator_func = nfc_generate_ntag_i2c_plus_2k,
|
||||||
.next_scene = NfcSceneMfUltralightMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator mifare_classic_1k_4b_uid_generator = {
|
static const NfcGenerator mifare_classic_1k_4b_uid_generator = {
|
||||||
.name = "Mifare Classic 1k 4byte UID",
|
.name = "Mifare Classic 1k 4byte UID",
|
||||||
.generator_func = nfc_generate_mf_classic_1k_4b_uid,
|
.generator_func = nfc_generate_mf_classic_1k_4b_uid,
|
||||||
.next_scene = NfcSceneMfClassicMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator mifare_classic_1k_7b_uid_generator = {
|
static const NfcGenerator mifare_classic_1k_7b_uid_generator = {
|
||||||
.name = "Mifare Classic 1k 7byte UID",
|
.name = "Mifare Classic 1k 7byte UID",
|
||||||
.generator_func = nfc_generate_mf_classic_1k_7b_uid,
|
.generator_func = nfc_generate_mf_classic_1k_7b_uid,
|
||||||
.next_scene = NfcSceneMfClassicMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator mifare_classic_4k_4b_uid_generator = {
|
static const NfcGenerator mifare_classic_4k_4b_uid_generator = {
|
||||||
.name = "Mifare Classic 4k 4byte UID",
|
.name = "Mifare Classic 4k 4byte UID",
|
||||||
.generator_func = nfc_generate_mf_classic_4k_4b_uid,
|
.generator_func = nfc_generate_mf_classic_4k_4b_uid,
|
||||||
.next_scene = NfcSceneMfClassicMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const NfcGenerator mifare_classic_4k_7b_uid_generator = {
|
static const NfcGenerator mifare_classic_4k_7b_uid_generator = {
|
||||||
.name = "Mifare Classic 4k 7byte UID",
|
.name = "Mifare Classic 4k 7byte UID",
|
||||||
.generator_func = nfc_generate_mf_classic_4k_7b_uid,
|
.generator_func = nfc_generate_mf_classic_4k_7b_uid,
|
||||||
.next_scene = NfcSceneMfClassicMenu,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const NfcGenerator* const nfc_generators[] = {
|
const NfcGenerator* const nfc_generators[] = {
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../nfc_i.h"
|
#include "../nfc_device.h"
|
||||||
|
|
||||||
typedef void (*NfcGeneratorFunc)(NfcDeviceData* data);
|
typedef void (*NfcGeneratorFunc)(NfcDeviceData* data);
|
||||||
|
|
||||||
struct NfcGenerator {
|
typedef struct {
|
||||||
const char* name;
|
const char* name;
|
||||||
NfcGeneratorFunc generator_func;
|
NfcGeneratorFunc generator_func;
|
||||||
NfcScene next_scene;
|
} NfcGenerator;
|
||||||
};
|
|
||||||
|
|
||||||
extern const NfcGenerator* const nfc_generators[];
|
extern const NfcGenerator* const nfc_generators[];
|
||||||
|
|
||||||
@@ -77,28 +77,38 @@ def add_env(name, value, file):
|
|||||||
print(f"{delimeter}", file=file)
|
print(f"{delimeter}", file=file)
|
||||||
|
|
||||||
|
|
||||||
def add_envs(data, env_file, args):
|
def add_set_output_var(name, value, file):
|
||||||
add_env("COMMIT_MSG", data["commit_comment"], env_file)
|
print(f"{name}={value}", file=file)
|
||||||
add_env("COMMIT_HASH", data["commit_hash"], env_file)
|
|
||||||
add_env("COMMIT_SHA", data["commit_sha"], env_file)
|
|
||||||
add_env("SUFFIX", data["suffix"], env_file)
|
def add_envs(data, gh_env_file, gh_out_file, args):
|
||||||
add_env("BRANCH_NAME", data["branch_name"], env_file)
|
add_env("COMMIT_MSG", data["commit_comment"], gh_env_file)
|
||||||
add_env("DIST_SUFFIX", data["suffix"], env_file)
|
add_env("COMMIT_HASH", data["commit_hash"], gh_env_file)
|
||||||
add_env("WORKFLOW_BRANCH_OR_TAG", data["branch_name"], env_file)
|
add_env("COMMIT_SHA", data["commit_sha"], gh_env_file)
|
||||||
|
add_env("SUFFIX", data["suffix"], gh_env_file)
|
||||||
|
add_env("BRANCH_NAME", data["branch_name"], gh_env_file)
|
||||||
|
add_env("DIST_SUFFIX", data["suffix"], gh_env_file)
|
||||||
|
add_env("WORKFLOW_BRANCH_OR_TAG", data["branch_name"], gh_env_file)
|
||||||
|
add_set_output_var("branch_name", data["branch_name"], gh_out_file)
|
||||||
|
add_set_output_var("commit_sha", data["commit_sha"], gh_out_file)
|
||||||
|
add_set_output_var("default_target", os.getenv("DEFAULT_TARGET"), gh_out_file)
|
||||||
|
add_set_output_var("suffix", data["suffix"], gh_out_file)
|
||||||
if args.type == "pull":
|
if args.type == "pull":
|
||||||
add_env("PULL_ID", data["pull_id"], env_file)
|
add_env("PULL_ID", data["pull_id"], gh_env_file)
|
||||||
add_env("PULL_NAME", data["pull_name"], env_file)
|
add_env("PULL_NAME", data["pull_name"], gh_env_file)
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
args = parse_args()
|
args = parse_args()
|
||||||
event_file = open(args.event_file)
|
event_file = open(args.event_file, "r")
|
||||||
event = json.load(event_file)
|
event = json.load(event_file)
|
||||||
env_file = open(os.environ["GITHUB_ENV"], "a")
|
gh_env_file = open(os.environ["GITHUB_ENV"], "a")
|
||||||
|
gh_out_file = open(os.environ["GITHUB_OUTPUT"], "a")
|
||||||
data = get_details(event, args)
|
data = get_details(event, args)
|
||||||
add_envs(data, env_file, args)
|
add_envs(data, gh_env_file, gh_out_file, args)
|
||||||
event_file.close()
|
event_file.close()
|
||||||
env_file.close()
|
gh_env_file.close()
|
||||||
|
gh_out_file.close()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
53
scripts/merge_report_qa.py
Executable file
53
scripts/merge_report_qa.py
Executable file
@@ -0,0 +1,53 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
from slack_sdk import WebClient
|
||||||
|
from slack_sdk.errors import SlackApiError
|
||||||
|
|
||||||
|
|
||||||
|
def parse_args():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument("slack_token")
|
||||||
|
parser.add_argument("slack_channel")
|
||||||
|
args = parser.parse_args()
|
||||||
|
return args
|
||||||
|
|
||||||
|
|
||||||
|
def checkCommitMessage(msg):
|
||||||
|
regex = re.compile(r"^'?\[FL-\d+\]")
|
||||||
|
if regex.match(msg):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def reportSlack(commit_hash, slack_token, slack_channel, message):
|
||||||
|
client = WebClient(token=slack_token)
|
||||||
|
try:
|
||||||
|
client.chat_postMessage(channel="#" + slack_channel, text=message)
|
||||||
|
except SlackApiError as e:
|
||||||
|
print(e)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
args = parse_args()
|
||||||
|
commit_msg = os.getenv("COMMIT_MSG")
|
||||||
|
commit_hash = os.getenv("COMMIT_HASH")
|
||||||
|
commit_sha = os.getenv("COMMIT_SHA")
|
||||||
|
commit_link = (
|
||||||
|
"<https://github.com/flipperdevices/flipperzero-firmware/commit/"
|
||||||
|
+ commit_hash
|
||||||
|
+ "|"
|
||||||
|
+ commit_sha
|
||||||
|
+ ">"
|
||||||
|
)
|
||||||
|
message = "Commit " + commit_link + " merged to dev without 'FL' ticket!"
|
||||||
|
if not checkCommitMessage(commit_msg):
|
||||||
|
reportSlack(commit_hash, args.slack_token, args.slack_channel, message)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Reference in New Issue
Block a user