diff --git a/applications/external/4inrow/4inrow.c b/applications/external/4inrow/4inrow.c
index 09ae94376..da2d5a4cb 100644
--- a/applications/external/4inrow/4inrow.c
+++ b/applications/external/4inrow/4inrow.c
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
static int matrix[6][7] = {0};
static int cursorx = 3;
@@ -234,6 +235,8 @@ int32_t four_in_row_app(void* p) {
return 255;
}
+ dolphin_deed(DolphinDeedPluginGameStart);
+
// Создаем новый view port
ViewPort* view_port = view_port_alloc();
// Создаем callback отрисовки, без контекста
diff --git a/applications/external/4inrow/application.fam b/applications/external/4inrow/application.fam
index 9d0db09ca..67a133992 100644
--- a/applications/external/4inrow/application.fam
+++ b/applications/external/4inrow/application.fam
@@ -7,7 +7,6 @@ App(
"gui",
],
stack_size=1 * 1024,
- order=90,
fap_icon="4inrow_10px.png",
fap_category="Games",
fap_author="leo-need-more-coffee",
diff --git a/applications/external/airmouse/application.fam b/applications/external/airmouse/application.fam
index dfb88da1e..b5498b8ce 100644
--- a/applications/external/airmouse/application.fam
+++ b/applications/external/airmouse/application.fam
@@ -6,6 +6,6 @@ App(
stack_size=10 * 1024,
fap_category="GPIO",
fap_icon="mouse_10px.png",
- fap_version="0.6",
+ fap_version="0.8",
sources=["*.c", "*.cc"],
)
diff --git a/applications/external/airmouse/tracking/main_loop.cc b/applications/external/airmouse/tracking/main_loop.cc
index 2caffb717..a9aca0aab 100644
--- a/applications/external/airmouse/tracking/main_loop.cc
+++ b/applications/external/airmouse/tracking/main_loop.cc
@@ -12,178 +12,219 @@
static const float CURSOR_SPEED = 1024.0 / (M_PI / 4);
static const float STABILIZE_BIAS = 16.0;
-float g_yaw = 0;
-float g_pitch = 0;
-float g_dYaw = 0;
-float g_dPitch = 0;
-bool firstRead = true;
-bool stabilize = true;
-CalibrationData calibration;
-cardboard::OrientationTracker tracker(10000000l); // 10 ms / 100 Hz
-uint64_t ippms, ippms2;
+class TrackingState {
+private:
+ float yaw;
+ float pitch;
+ float dYaw;
+ float dPitch;
+ bool firstRead;
+ bool stabilize;
+ CalibrationData calibration;
+ cardboard::OrientationTracker tracker;
+ uint64_t ippus, ippus2;
-static inline float clamp(float val)
-{
- while (val <= -M_PI) {
- val += 2 * M_PI;
- }
- while (val >= M_PI) {
- val -= 2 * M_PI;
- }
- return val;
-}
-
-static inline float highpass(float oldVal, float newVal)
-{
- if (!stabilize) {
- return newVal;
- }
- float delta = clamp(oldVal - newVal);
- float alpha = (float) std::max(0.0, 1 - std::pow(std::fabs(delta) * CURSOR_SPEED / STABILIZE_BIAS, 3.0));
- return newVal + alpha * delta;
-}
-
-void sendCurrentState(MouseMoveCallback mouse_move, void *context)
-{
- float dX = g_dYaw * CURSOR_SPEED;
- float dY = g_dPitch * CURSOR_SPEED;
-
- // Scale the shift down to fit the protocol.
- if (dX > 127) {
- dY *= 127.0 / dX;
- dX = 127;
- }
- if (dX < -127) {
- dY *= -127.0 / dX;
- dX = -127;
- }
- if (dY > 127) {
- dX *= 127.0 / dY;
- dY = 127;
- }
- if (dY < -127) {
- dX *= -127.0 / dY;
- dY = -127;
+private:
+ float clamp(float val) {
+ while (val <= -M_PI) {
+ val += 2 * M_PI;
+ }
+ while (val >= M_PI) {
+ val -= 2 * M_PI;
+ }
+ return val;
}
- const int8_t x = (int8_t)std::floor(dX + 0.5);
- const int8_t y = (int8_t)std::floor(dY + 0.5);
-
- mouse_move(x, y, context);
-
- // Only subtract the part of the error that was already sent.
- if (x != 0) {
- g_dYaw -= x / CURSOR_SPEED;
- }
- if (y != 0) {
- g_dPitch -= y / CURSOR_SPEED;
- }
-}
-
-void onOrientation(cardboard::Vector4& quaternion)
-{
- float q1 = quaternion[0]; // X * sin(T/2)
- float q2 = quaternion[1]; // Y * sin(T/2)
- float q3 = quaternion[2]; // Z * sin(T/2)
- float q0 = quaternion[3]; // cos(T/2)
-
- float yaw = std::atan2(2 * (q0 * q3 - q1 * q2), (1 - 2 * (q1 * q1 + q3 * q3)));
- float pitch = std::asin(2 * (q0 * q1 + q2 * q3));
- // float roll = std::atan2(2 * (q0 * q2 - q1 * q3), (1 - 2 * (q1 * q1 + q2 * q2)));
-
- if (yaw == NAN || pitch == NAN) {
- // NaN case, skip it
- return;
+ float highpass(float oldVal, float newVal) {
+ if (!stabilize) {
+ return newVal;
+ }
+ float delta = clamp(oldVal - newVal);
+ float alpha = (float) std::max(0.0, 1 - std::pow(std::fabs(delta) * CURSOR_SPEED / STABILIZE_BIAS, 3.0));
+ return newVal + alpha * delta;
}
- if (firstRead) {
- g_yaw = yaw;
- g_pitch = pitch;
- firstRead = false;
- } else {
- const float newYaw = highpass(g_yaw, yaw);
- const float newPitch = highpass(g_pitch, pitch);
+ void sendCurrentState(MouseMoveCallback mouse_move, void *context) {
+ float dX = dYaw * CURSOR_SPEED;
+ float dY = dPitch * CURSOR_SPEED;
- float dYaw = clamp(g_yaw - newYaw);
- float dPitch = g_pitch - newPitch;
- g_yaw = newYaw;
- g_pitch = newPitch;
+ // Scale the shift down to fit the protocol.
+ if (dX > 127) {
+ dY *= 127.0 / dX;
+ dX = 127;
+ }
+ if (dX < -127) {
+ dY *= -127.0 / dX;
+ dX = -127;
+ }
+ if (dY > 127) {
+ dX *= 127.0 / dY;
+ dY = 127;
+ }
+ if (dY < -127) {
+ dX *= -127.0 / dY;
+ dY = -127;
+ }
- // Accumulate the error locally.
- g_dYaw += dYaw;
- g_dPitch += dPitch;
+ const int8_t x = (int8_t)std::floor(dX + 0.5);
+ const int8_t y = (int8_t)std::floor(dY + 0.5);
+
+ mouse_move(x, y, context);
+
+ // Only subtract the part of the error that was already sent.
+ if (x != 0) {
+ dYaw -= x / CURSOR_SPEED;
+ }
+ if (y != 0) {
+ dPitch -= y / CURSOR_SPEED;
+ }
}
-}
+
+ void onOrientation(cardboard::Vector4& quaternion) {
+ float q1 = quaternion[0]; // X * sin(T/2)
+ float q2 = quaternion[1]; // Y * sin(T/2)
+ float q3 = quaternion[2]; // Z * sin(T/2)
+ float q0 = quaternion[3]; // cos(T/2)
+
+ float yaw = std::atan2(2 * (q0 * q3 - q1 * q2), (1 - 2 * (q1 * q1 + q3 * q3)));
+ float pitch = std::asin(2 * (q0 * q1 + q2 * q3));
+ // float roll = std::atan2(2 * (q0 * q2 - q1 * q3), (1 - 2 * (q1 * q1 + q2 * q2)));
+
+ if (yaw == NAN || pitch == NAN) {
+ // NaN case, skip it
+ return;
+ }
+
+ if (firstRead) {
+ this->yaw = yaw;
+ this->pitch = pitch;
+ firstRead = false;
+ } else {
+ const float newYaw = highpass(this->yaw, yaw);
+ const float newPitch = highpass(this->pitch, pitch);
+
+ float dYaw = clamp(this->yaw - newYaw);
+ float dPitch = this->pitch - newPitch;
+ this->yaw = newYaw;
+ this->pitch = newPitch;
+
+ // Accumulate the error locally.
+ this->dYaw += dYaw;
+ this->dPitch += dPitch;
+ }
+ }
+
+public:
+ TrackingState()
+ : yaw(0)
+ , pitch(0)
+ , dYaw(0)
+ , dPitch(0)
+ , firstRead(true)
+ , stabilize(true)
+ , tracker(10000000l) { // 10 ms / 100 Hz
+ ippus = furi_hal_cortex_instructions_per_microsecond();
+ ippus2 = ippus / 2;
+ }
+
+ void beginCalibration() {
+ calibration.reset();
+ }
+
+ bool stepCalibration() {
+ if (calibration.isComplete())
+ return true;
+
+ double vec[6];
+ if (imu_read(vec) & GYR_DATA_READY) {
+ cardboard::Vector3 data(vec[3], vec[4], vec[5]);
+ furi_delay_ms(9); // Artificially limit to ~100Hz
+ return calibration.add(data);
+ }
+
+ return false;
+ }
+
+ void saveCalibration() {
+ CalibrationMedian store;
+ cardboard::Vector3 median = calibration.getMedian();
+ store.x = median[0];
+ store.y = median[1];
+ store.z = median[2];
+ CALIBRATION_DATA_SAVE(&store);
+ }
+
+ void loadCalibration() {
+ CalibrationMedian store;
+ cardboard::Vector3 median = calibration.getMedian();
+ if (CALIBRATION_DATA_LOAD(&store)) {
+ median[0] = store.x;
+ median[1] = store.y;
+ median[2] = store.z;
+ }
+
+ tracker.SetCalibration(median);
+ }
+
+ void beginTracking() {
+ loadCalibration();
+ tracker.Resume();
+ }
+
+ void stepTracking(MouseMoveCallback mouse_move, void *context) {
+ double vec[6];
+ int ret = imu_read(vec);
+ if (ret != 0) {
+ uint64_t t = (DWT->CYCCNT * 1000llu + ippus2) / ippus;
+ if (ret & ACC_DATA_READY) {
+ cardboard::AccelerometerData adata
+ = { .system_timestamp = t, .sensor_timestamp_ns = t,
+ .data = cardboard::Vector3(vec[0], vec[1], vec[2]) };
+ tracker.OnAccelerometerData(adata);
+ }
+ if (ret & GYR_DATA_READY) {
+ cardboard::GyroscopeData gdata
+ = { .system_timestamp = t, .sensor_timestamp_ns = t,
+ .data = cardboard::Vector3(vec[3], vec[4], vec[5]) };
+ cardboard::Vector4 pose = tracker.OnGyroscopeData(gdata);
+ onOrientation(pose);
+ sendCurrentState(mouse_move, context);
+ }
+ }
+ }
+
+ void stopTracking() {
+ tracker.Pause();
+ }
+};
+
+static TrackingState g_state;
extern "C" {
void calibration_begin() {
- calibration.reset();
+ g_state.beginCalibration();
FURI_LOG_I(TAG, "Calibrating");
}
bool calibration_step() {
- if (calibration.isComplete())
- return true;
-
- double vec[6];
- if (imu_read(vec) & GYR_DATA_READY) {
- cardboard::Vector3 data(vec[3], vec[4], vec[5]);
- furi_delay_ms(9); // Artificially limit to ~100Hz
- return calibration.add(data);
- }
-
- return false;
+ return g_state.stepCalibration();
}
void calibration_end() {
- CalibrationMedian store;
- cardboard::Vector3 median = calibration.getMedian();
- store.x = median[0];
- store.y = median[1];
- store.z = median[2];
- CALIBRATION_DATA_SAVE(&store);
+ g_state.saveCalibration();
}
void tracking_begin() {
- CalibrationMedian store;
- cardboard::Vector3 median = calibration.getMedian();
- if (CALIBRATION_DATA_LOAD(&store)) {
- median[0] = store.x;
- median[1] = store.y;
- median[2] = store.z;
- }
-
- ippms = furi_hal_cortex_instructions_per_microsecond();
- ippms2 = ippms / 2;
- tracker.SetCalibration(median);
- tracker.Resume();
+ g_state.beginTracking();
}
void tracking_step(MouseMoveCallback mouse_move, void *context) {
- double vec[6];
- int ret = imu_read(vec);
- if (ret != 0) {
- uint64_t t = (DWT->CYCCNT * 1000llu + ippms2) / ippms;
- if (ret & ACC_DATA_READY) {
- cardboard::AccelerometerData adata
- = { .system_timestamp = t, .sensor_timestamp_ns = t,
- .data = cardboard::Vector3(vec[0], vec[1], vec[2]) };
- tracker.OnAccelerometerData(adata);
- }
- if (ret & GYR_DATA_READY) {
- cardboard::GyroscopeData gdata
- = { .system_timestamp = t, .sensor_timestamp_ns = t,
- .data = cardboard::Vector3(vec[3], vec[4], vec[5]) };
- cardboard::Vector4 pose = tracker.OnGyroscopeData(gdata);
- onOrientation(pose);
- sendCurrentState(mouse_move, context);
- }
- }
+ g_state.stepTracking(mouse_move, context);
}
void tracking_end() {
- tracker.Pause();
+ g_state.stopTracking();
}
}
diff --git a/applications/external/airmouse/tracking/orientation_tracker.cc b/applications/external/airmouse/tracking/orientation_tracker.cc
index ac20e9672..4f381c895 100644
--- a/applications/external/airmouse/tracking/orientation_tracker.cc
+++ b/applications/external/airmouse/tracking/orientation_tracker.cc
@@ -89,7 +89,7 @@ Vector4 OrientationTracker::OnGyroscopeData(const GyroscopeData& event)
sensor_fusion_->ProcessGyroscopeSample(data);
- return OrientationTracker::GetPose(data.sensor_timestamp_ns + sampling_period_ns_);
+ return GetPose(data.sensor_timestamp_ns + sampling_period_ns_);
}
} // namespace cardboard
diff --git a/applications/external/airmouse/tracking/sensors/sensor_fusion_ekf.cc b/applications/external/airmouse/tracking/sensors/sensor_fusion_ekf.cc
index 575dde6f0..dabd788ef 100644
--- a/applications/external/airmouse/tracking/sensors/sensor_fusion_ekf.cc
+++ b/applications/external/airmouse/tracking/sensors/sensor_fusion_ekf.cc
@@ -59,13 +59,14 @@ namespace {
// angle = norm(a)
// axis = a.normalized()
// If norm(a) == 0, it returns an identity rotation.
- static inline Rotation RotationFromVector(const Vector3& a)
+ static inline void RotationFromVector(const Vector3& a, Rotation& r)
{
const double norm_a = Length(a);
if (norm_a < kEpsilon) {
- return Rotation::Identity();
+ r = Rotation::Identity();
+ return;
}
- return Rotation::FromAxisAndAngle(a / norm_a, norm_a);
+ r = Rotation::FromAxisAndAngle(a / norm_a, norm_a);
}
} // namespace
@@ -199,7 +200,8 @@ void SensorFusionEkf::ComputeMeasurementJacobian()
Vector3 delta = Vector3::Zero();
delta[dof] = kFiniteDifferencingEpsilon;
- const Rotation epsilon_rotation = RotationFromVector(delta);
+ Rotation epsilon_rotation;
+ RotationFromVector(delta, epsilon_rotation);
const Vector3 delta_rotation
= ComputeInnovation(epsilon_rotation * current_state_.sensor_from_start_rotation);
@@ -263,7 +265,8 @@ void SensorFusionEkf::ProcessAccelerometerSample(const AccelerometerData& sample
* state_covariance_;
// Updates pose and associate covariance matrix.
- const Rotation rotation_from_state_update = RotationFromVector(state_update_);
+ Rotation rotation_from_state_update;
+ RotationFromVector(state_update_, rotation_from_state_update);
current_state_.sensor_from_start_rotation
= rotation_from_state_update * current_state_.sensor_from_start_rotation;
diff --git a/applications/external/airmouse/views/bt_mouse.c b/applications/external/airmouse/views/bt_mouse.c
index 7d9c0e6db..664b25bfd 100644
--- a/applications/external/airmouse/views/bt_mouse.c
+++ b/applications/external/airmouse/views/bt_mouse.c
@@ -132,6 +132,11 @@ void bt_mouse_connection_status_changed_callback(BtStatus status, void* context)
BtMouse* bt_mouse = context;
bt_mouse->connected = (status == BtStatusConnected);
+ if(!bt_mouse->notifications) {
+ tracking_end();
+ return;
+ }
+
if(bt_mouse->connected) {
notification_internal_message(bt_mouse->notifications, &sequence_set_blue_255);
tracking_begin();
@@ -140,9 +145,6 @@ void bt_mouse_connection_status_changed_callback(BtStatus status, void* context)
tracking_end();
notification_internal_message(bt_mouse->notifications, &sequence_reset_blue);
}
-
- //with_view_model(
- // bt_mouse->view, void * model, { model->connected = connected; }, true);
}
bool bt_mouse_move(int8_t dx, int8_t dy, void* context) {
@@ -160,46 +162,6 @@ bool bt_mouse_move(int8_t dx, int8_t dy, void* context) {
return true;
}
-void bt_mouse_enter_callback(void* context) {
- furi_assert(context);
- BtMouse* bt_mouse = context;
-
- bt_mouse->bt = furi_record_open(RECORD_BT);
- bt_mouse->notifications = furi_record_open(RECORD_NOTIFICATION);
- bt_set_status_changed_callback(
- bt_mouse->bt, bt_mouse_connection_status_changed_callback, bt_mouse);
- furi_assert(bt_set_profile(bt_mouse->bt, BtProfileHidKeyboard));
- furi_hal_bt_start_advertising();
-}
-
-bool bt_mouse_custom_callback(uint32_t event, void* context) {
- UNUSED(event);
- furi_assert(context);
- BtMouse* bt_mouse = context;
-
- tracking_step(bt_mouse_move, context);
- furi_delay_ms(3); // Magic! Removing this will break the buttons
-
- view_dispatcher_send_custom_event(bt_mouse->view_dispatcher, 0);
- return true;
-}
-
-void bt_mouse_exit_callback(void* context) {
- furi_assert(context);
- BtMouse* bt_mouse = context;
-
- tracking_end();
- notification_internal_message(bt_mouse->notifications, &sequence_reset_blue);
-
- furi_hal_bt_stop_advertising();
- bt_set_profile(bt_mouse->bt, BtProfileSerial);
-
- furi_record_close(RECORD_NOTIFICATION);
- bt_mouse->notifications = NULL;
- furi_record_close(RECORD_BT);
- bt_mouse->bt = NULL;
-}
-
static int8_t clamp(int t) {
if(t < -128) {
return -128;
@@ -279,6 +241,50 @@ void bt_mouse_thread_stop(BtMouse* bt_mouse) {
furi_thread_join(bt_mouse->thread);
furi_thread_free(bt_mouse->thread);
furi_mutex_free(bt_mouse->mutex);
+ bt_mouse->mutex = NULL;
+ bt_mouse->thread = NULL;
+}
+
+void bt_mouse_enter_callback(void* context) {
+ furi_assert(context);
+ BtMouse* bt_mouse = context;
+
+ bt_mouse->bt = furi_record_open(RECORD_BT);
+ bt_mouse->notifications = furi_record_open(RECORD_NOTIFICATION);
+ bt_set_status_changed_callback(
+ bt_mouse->bt, bt_mouse_connection_status_changed_callback, bt_mouse);
+ furi_assert(bt_set_profile(bt_mouse->bt, BtProfileHidKeyboard));
+ furi_hal_bt_start_advertising();
+ bt_mouse_thread_start(bt_mouse);
+}
+
+bool bt_mouse_custom_callback(uint32_t event, void* context) {
+ UNUSED(event);
+ furi_assert(context);
+ BtMouse* bt_mouse = context;
+
+ tracking_step(bt_mouse_move, context);
+ furi_delay_ms(3); // Magic! Removing this will break the buttons
+
+ view_dispatcher_send_custom_event(bt_mouse->view_dispatcher, 0);
+ return true;
+}
+
+void bt_mouse_exit_callback(void* context) {
+ furi_assert(context);
+ BtMouse* bt_mouse = context;
+
+ bt_mouse_thread_stop(bt_mouse);
+ tracking_end();
+ notification_internal_message(bt_mouse->notifications, &sequence_reset_blue);
+
+ furi_hal_bt_stop_advertising();
+ bt_set_profile(bt_mouse->bt, BtProfileSerial);
+
+ furi_record_close(RECORD_NOTIFICATION);
+ bt_mouse->notifications = NULL;
+ furi_record_close(RECORD_BT);
+ bt_mouse->bt = NULL;
}
BtMouse* bt_mouse_alloc(ViewDispatcher* view_dispatcher) {
@@ -293,13 +299,11 @@ BtMouse* bt_mouse_alloc(ViewDispatcher* view_dispatcher) {
view_set_enter_callback(bt_mouse->view, bt_mouse_enter_callback);
view_set_custom_callback(bt_mouse->view, bt_mouse_custom_callback);
view_set_exit_callback(bt_mouse->view, bt_mouse_exit_callback);
- bt_mouse_thread_start(bt_mouse);
return bt_mouse;
}
void bt_mouse_free(BtMouse* bt_mouse) {
furi_assert(bt_mouse);
- bt_mouse_thread_stop(bt_mouse);
view_free(bt_mouse->view);
free(bt_mouse);
}
diff --git a/applications/external/arkanoid/application.fam b/applications/external/arkanoid/application.fam
index b33b9acae..19e851514 100644
--- a/applications/external/arkanoid/application.fam
+++ b/applications/external/arkanoid/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="arkanoid_game_app",
requires=["gui"],
stack_size=1 * 1024,
- order=20,
fap_icon="arkanoid_10px.png",
fap_category="Games",
fap_author="@xMasterX & @gotnull",
diff --git a/applications/external/arkanoid/arkanoid_game.c b/applications/external/arkanoid/arkanoid_game.c
index f6d8c1a3d..2adf2e30b 100644
--- a/applications/external/arkanoid/arkanoid_game.c
+++ b/applications/external/arkanoid/arkanoid_game.c
@@ -5,6 +5,7 @@
#include
#include
#include
+#include
#define TAG "Arkanoid"
@@ -397,6 +398,9 @@ int32_t arkanoid_game_app(void* p) {
Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
+ // Call dolphin deed on game start
+ dolphin_deed(DolphinDeedPluginGameStart);
+
GameEvent event;
for(bool processing = true; processing;) {
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
diff --git a/applications/external/asteroids/application.fam b/applications/external/asteroids/application.fam
index ca5f5d175..608809c02 100644
--- a/applications/external/asteroids/application.fam
+++ b/applications/external/asteroids/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_ASTEROIDS"],
requires=["gui"],
stack_size=8 * 1024,
- order=50,
fap_icon="appicon.png",
fap_icon_assets="assets",
fap_category="Games",
diff --git a/applications/external/avr_isp_programmer/application.fam b/applications/external/avr_isp_programmer/application.fam
index 5f3b17037..f355cfcb5 100644
--- a/applications/external/avr_isp_programmer/application.fam
+++ b/applications/external/avr_isp_programmer/application.fam
@@ -5,7 +5,8 @@ App(
entry_point="avr_isp_app",
requires=["gui"],
stack_size=4 * 1024,
- order=20,
+ fap_description="Application for flashing AVR microcontrollers",
+ fap_version="1.0",
fap_icon="avr_app_icon_10x10.png",
fap_category="GPIO",
fap_icon_assets="images",
diff --git a/applications/external/avr_isp_programmer/avr_isp_app_i.h b/applications/external/avr_isp_programmer/avr_isp_app_i.h
index 819e3f45f..8a7dbc4b8 100644
--- a/applications/external/avr_isp_programmer/avr_isp_app_i.h
+++ b/applications/external/avr_isp_programmer/avr_isp_app_i.h
@@ -1,7 +1,8 @@
#pragma once
#include "helpers/avr_isp_types.h"
-#include
+#include "avr_isp_icons.h"
+#include
#include "scenes/avr_isp_scene.h"
#include
@@ -41,4 +42,4 @@ typedef struct {
AvrIspError error;
} AvrIspApp;
-bool avr_isp_load_from_file(AvrIspApp* app);
+bool avr_isp_load_from_file(AvrIspApp* app);
\ No newline at end of file
diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp.c b/applications/external/avr_isp_programmer/helpers/avr_isp.c
index 1b9e2fd1f..283c17bfd 100644
--- a/applications/external/avr_isp_programmer/helpers/avr_isp.c
+++ b/applications/external/avr_isp_programmer/helpers/avr_isp.c
@@ -174,7 +174,7 @@ static void avr_isp_commit(AvrIsp* instance, uint16_t addr, uint8_t data) {
while((furi_get_tick() - starttime) < 30) {
if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FLASH_HI(addr)) != 0xFF) {
break;
- }
+ };
}
}
}
@@ -357,7 +357,7 @@ uint8_t avr_isp_read_lock_byte(AvrIsp* instance) {
data = avr_isp_spi_transaction(instance, AVR_ISP_READ_LOCK_BYTE);
if(avr_isp_spi_transaction(instance, AVR_ISP_READ_LOCK_BYTE) == data) {
break;
- }
+ };
data = 0x00;
}
return data;
@@ -377,7 +377,7 @@ bool avr_isp_write_lock_byte(AvrIsp* instance, uint8_t lock) {
if(avr_isp_spi_transaction(instance, AVR_ISP_READ_LOCK_BYTE) == lock) {
ret = true;
break;
- }
+ };
}
}
return ret;
@@ -392,7 +392,7 @@ uint8_t avr_isp_read_fuse_low(AvrIsp* instance) {
data = avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_LOW);
if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_LOW) == data) {
break;
- }
+ };
data = 0x00;
}
return data;
@@ -412,7 +412,7 @@ bool avr_isp_write_fuse_low(AvrIsp* instance, uint8_t lfuse) {
if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_LOW) == lfuse) {
ret = true;
break;
- }
+ };
}
}
return ret;
@@ -427,7 +427,7 @@ uint8_t avr_isp_read_fuse_high(AvrIsp* instance) {
data = avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_HIGH);
if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_HIGH) == data) {
break;
- }
+ };
data = 0x00;
}
return data;
@@ -447,7 +447,7 @@ bool avr_isp_write_fuse_high(AvrIsp* instance, uint8_t hfuse) {
if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_HIGH) == hfuse) {
ret = true;
break;
- }
+ };
}
}
return ret;
@@ -462,7 +462,7 @@ uint8_t avr_isp_read_fuse_extended(AvrIsp* instance) {
data = avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_EXTENDED);
if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_EXTENDED) == data) {
break;
- }
+ };
data = 0x00;
}
return data;
@@ -482,7 +482,7 @@ bool avr_isp_write_fuse_extended(AvrIsp* instance, uint8_t efuse) {
if(avr_isp_spi_transaction(instance, AVR_ISP_READ_FUSE_EXTENDED) == efuse) {
ret = true;
break;
- }
+ };
}
}
return ret;
diff --git a/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c b/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c
index 121f08565..b4c12cbc3 100644
--- a/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c
+++ b/applications/external/avr_isp_programmer/helpers/avr_isp_worker_rw.c
@@ -350,12 +350,12 @@ static void avr_isp_worker_rw_get_dump_flash(AvrIspWorkerRW* instance, const cha
sizeof(data));
flipper_i32hex_file_bin_to_i32hex_set_data(
flipper_hex_flash, data, avr_isp_chip_arr[instance->chip_arr_ind].pagesize);
- //FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_flash));
+ FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_flash));
instance->progress_flash =
(float)(i) / ((float)avr_isp_chip_arr[instance->chip_arr_ind].flashsize / 2.0f);
}
flipper_i32hex_file_bin_to_i32hex_set_end_line(flipper_hex_flash);
- //FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_flash));
+ FURI_LOG_D(TAG, "%s", flipper_i32hex_file_get_string(flipper_hex_flash));
flipper_i32hex_file_close(flipper_hex_flash);
instance->progress_flash = 1.0f;
}
diff --git a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c b/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c
index 051d97e9c..bbb6d4739 100644
--- a/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c
+++ b/applications/external/avr_isp_programmer/lib/driver/avr_isp_prog.c
@@ -111,7 +111,7 @@ static uint8_t avr_isp_prog_getch(AvrIspProg* instance) {
uint8_t data[1] = {0};
while(furi_stream_buffer_receive(instance->stream_rx, &data, sizeof(int8_t), 30) == 0) {
if(instance->exit) break;
- }
+ };
return data[0];
}
@@ -196,7 +196,7 @@ static void avr_isp_prog_set_cfg(AvrIspProg* instance) {
instance->cfg->lockbytes = instance->buff[6];
instance->cfg->fusebytes = instance->buff[7];
instance->cfg->flashpoll = instance->buff[8];
- // ignore (instance->buff[9] == instance->buff[8]) //FLASH polling value. Same as �flashpoll�
+ // ignore (instance->buff[9] == instance->buff[8]) //FLASH polling value. Same as flashpoll
instance->cfg->eeprompoll = instance->buff[10] << 8 | instance->buff[11];
instance->cfg->pagesize = instance->buff[12] << 8 | instance->buff[13];
instance->cfg->eepromsize = instance->buff[14] << 8 | instance->buff[15];
@@ -348,7 +348,7 @@ static void avr_isp_prog_commit(AvrIspProg* instance, uint16_t addr, uint8_t dat
while((furi_get_tick() - starttime) < 30) {
if(avr_isp_prog_spi_transaction(instance, AVR_ISP_READ_FLASH_HI(addr)) != 0xFF) {
break;
- }
+ };
}
}
}
diff --git a/applications/external/avr_isp_programmer/views/avr_isp_view_chip_detect.c b/applications/external/avr_isp_programmer/views/avr_isp_view_chip_detect.c
index fdcf71c36..b30d4e916 100644
--- a/applications/external/avr_isp_programmer/views/avr_isp_view_chip_detect.c
+++ b/applications/external/avr_isp_programmer/views/avr_isp_view_chip_detect.c
@@ -1,5 +1,6 @@
#include "avr_isp_view_chip_detect.h"
-#include
+#include "avr_isp_icons.h"
+#include
#include
#include "../helpers/avr_isp_worker_rw.h"
diff --git a/applications/external/avr_isp_programmer/views/avr_isp_view_programmer.c b/applications/external/avr_isp_programmer/views/avr_isp_view_programmer.c
index 34e18770b..38b7394d6 100644
--- a/applications/external/avr_isp_programmer/views/avr_isp_view_programmer.c
+++ b/applications/external/avr_isp_programmer/views/avr_isp_view_programmer.c
@@ -1,5 +1,6 @@
#include "avr_isp_view_programmer.h"
-#include
+#include "avr_isp_icons.h"
+#include
#include "../helpers/avr_isp_worker.h"
#include
diff --git a/applications/external/barcode_gen/barcode_app.c b/applications/external/barcode_gen/barcode_app.c
index 99e5769d2..aff437f2e 100644
--- a/applications/external/barcode_gen/barcode_app.c
+++ b/applications/external/barcode_gen/barcode_app.c
@@ -1,6 +1,7 @@
#include "barcode_app.h"
#include "barcode_app_icons.h"
+#include
/**
* Opens a file browser dialog and returns the filepath of the selected file
diff --git a/applications/external/blackjack/application.fam b/applications/external/blackjack/application.fam
index 83b3c83a8..504989116 100644
--- a/applications/external/blackjack/application.fam
+++ b/applications/external/blackjack/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="blackjack_app",
requires=["gui", "storage", "canvas"],
stack_size=2 * 1024,
- order=30,
fap_icon="blackjack_10px.png",
fap_category="Games",
fap_icon_assets="assets",
diff --git a/applications/external/blackjack/blackjack.c b/applications/external/blackjack/blackjack.c
index ee5e35415..8cf698d85 100644
--- a/applications/external/blackjack/blackjack.c
+++ b/applications/external/blackjack/blackjack.c
@@ -1,6 +1,7 @@
#include
#include
+#include
#include
#include
@@ -14,6 +15,7 @@
#include "ui.h"
#include "blackjack_icons.h"
+#include
#define DEALER_MAX 17
@@ -275,6 +277,7 @@ void dealer_tick(GameState* game_state) {
if(dealer_score >= DEALER_MAX) {
if(dealer_score > 21 || dealer_score < player_score) {
+ dolphin_deed(DolphinDeedPluginGameWin);
enqueue(
&(game_state->queue_state),
game_state,
@@ -568,6 +571,9 @@ int32_t blackjack_app(void* p) {
AppEvent event;
+ // Call dolphin deed on game start
+ dolphin_deed(DolphinDeedPluginGameStart);
+
for(bool processing = true; processing;) {
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
furi_mutex_acquire(game_state->mutex, FuriWaitForever);
@@ -625,4 +631,4 @@ free_and_exit:
furi_message_queue_free(event_queue);
return return_code;
-}
+}
\ No newline at end of file
diff --git a/applications/external/bomberduck/application.fam b/applications/external/bomberduck/application.fam
index 39c680693..958ac7c02 100644
--- a/applications/external/bomberduck/application.fam
+++ b/applications/external/bomberduck/application.fam
@@ -7,7 +7,6 @@ App(
"gui",
],
stack_size=1 * 1024,
- order=90,
fap_icon="bomb.png",
fap_category="Games",
fap_icon_assets="assets",
diff --git a/applications/external/bomberduck/bomberduck.c b/applications/external/bomberduck/bomberduck.c
index d81515371..eddec089f 100644
--- a/applications/external/bomberduck/bomberduck.c
+++ b/applications/external/bomberduck/bomberduck.c
@@ -6,6 +6,8 @@
#include
#include
#include "bomberduck_icons.h"
+#include
+#include
int max(int a, int b) {
return (a > b) ? a : b;
@@ -381,6 +383,7 @@ int32_t bomberduck_app(void* p) {
return 255;
}
+ dolphin_deed(DolphinDeedPluginGameStart);
// Создаем новый view port
ViewPort* view_port = view_port_alloc();
// Создаем callback отрисовки, без контекста
@@ -454,8 +457,9 @@ int32_t bomberduck_app(void* p) {
notification_message(notification, &end);
world.running = 0;
world.level += 1;
- // if(world.level % 5 == 0) {
- // }
+ if(world.level % 5 == 0) {
+ dolphin_deed(DolphinDeedPluginGameWin);
+ }
}
for(int i = 0; i < world.bombs_count; i++) {
if(furi_get_tick() - world.bombs[i].planted >
diff --git a/applications/external/bpmtapper/application.fam b/applications/external/bpmtapper/application.fam
index bf3f3c895..b25f61af3 100644
--- a/applications/external/bpmtapper/application.fam
+++ b/applications/external/bpmtapper/application.fam
@@ -9,7 +9,6 @@ App(
fap_icon="bpm_10px.png",
fap_category="Media",
fap_icon_assets="icons",
- order=15,
fap_author="@panki27",
fap_weburl="https://github.com/panki27/bpm-tapper",
fap_version="1.0",
diff --git a/applications/external/caesarcipher/application.fam b/applications/external/caesarcipher/application.fam
index fdb1052b0..985487986 100644
--- a/applications/external/caesarcipher/application.fam
+++ b/applications/external/caesarcipher/application.fam
@@ -10,7 +10,6 @@ App(
stack_size=2 * 1024,
fap_icon="caesar_cipher_icon.png",
fap_category="Tools",
- order=20,
fap_author="@panki27",
fap_weburl="https://github.com/panki27/caesar-cipher",
fap_version="1.0",
diff --git a/applications/external/calculator/application.fam b/applications/external/calculator/application.fam
index cba45e49b..cfd183ec3 100644
--- a/applications/external/calculator/application.fam
+++ b/applications/external/calculator/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_CALCULATOR"],
requires=["gui"],
stack_size=1 * 1024,
- order=45,
fap_icon="calcIcon.png",
fap_category="Tools",
fap_author="@n-o-T-I-n-s-a-n-e",
diff --git a/applications/external/camera_suite/application.fam b/applications/external/camera_suite/application.fam
index d3ddde2c1..1c9f0cc6f 100644
--- a/applications/external/camera_suite/application.fam
+++ b/applications/external/camera_suite/application.fam
@@ -9,7 +9,6 @@ App(
fap_icon="icons/camera_suite.png",
fap_weburl="https://github.com/CodyTolene/Flipper-Zero-Cam",
name="[ESP32] Camera Suite",
- order=1,
requires=["gui", "storage"],
stack_size=8 * 1024,
)
diff --git a/applications/external/camera_suite/views/camera_suite_view_camera.c b/applications/external/camera_suite/views/camera_suite_view_camera.c
index 77850b425..94b8a8639 100644
--- a/applications/external/camera_suite/views/camera_suite_view_camera.c
+++ b/applications/external/camera_suite/views/camera_suite_view_camera.c
@@ -3,6 +3,7 @@
#include
#include
#include
+#include
#include "../helpers/camera_suite_haptic.h"
#include "../helpers/camera_suite_speaker.h"
#include "../helpers/camera_suite_led.h"
diff --git a/applications/external/camera_suite/views/camera_suite_view_guide.c b/applications/external/camera_suite/views/camera_suite_view_guide.c
index b32b0dd8f..479f8d4d1 100644
--- a/applications/external/camera_suite/views/camera_suite_view_guide.c
+++ b/applications/external/camera_suite/views/camera_suite_view_guide.c
@@ -3,6 +3,7 @@
#include
#include
#include
+#include
struct CameraSuiteViewGuide {
View* view;
diff --git a/applications/external/chess/application.fam b/applications/external/chess/application.fam
index e0479c380..6f3d3321c 100644
--- a/applications/external/chess/application.fam
+++ b/applications/external/chess/application.fam
@@ -7,7 +7,6 @@ App(
"gui",
],
stack_size=4 * 1024,
- order=10,
fap_icon="flipchess_10px.png",
fap_icon_assets="icons",
fap_icon_assets_symbol="flipchess",
diff --git a/applications/external/chess/icons/Background_128x11.png b/applications/external/chess/icons/Background_128x11.png
deleted file mode 100644
index 149780f0c..000000000
Binary files a/applications/external/chess/icons/Background_128x11.png and /dev/null differ
diff --git a/applications/external/chess/views/flipchess_startscreen.c b/applications/external/chess/views/flipchess_startscreen.c
index d25bbe2cc..9a146674e 100644
--- a/applications/external/chess/views/flipchess_startscreen.c
+++ b/applications/external/chess/views/flipchess_startscreen.c
@@ -4,6 +4,7 @@
#include
#include
#include "flipchess_icons.h"
+#include
struct FlipChessStartscreen {
View* view;
diff --git a/applications/external/cntdown_timer/application.fam b/applications/external/cntdown_timer/application.fam
index 054833eeb..79a08423e 100644
--- a/applications/external/cntdown_timer/application.fam
+++ b/applications/external/cntdown_timer/application.fam
@@ -10,7 +10,6 @@ App(
"gui",
],
stack_size=2 * 1024,
- order=20,
fap_icon="cntdown_timer.png",
fap_category="Tools",
fap_author="@0w0mewo",
diff --git a/applications/external/dap_link/application.fam b/applications/external/dap_link/application.fam
index e05a7e01f..8f25bef83 100644
--- a/applications/external/dap_link/application.fam
+++ b/applications/external/dap_link/application.fam
@@ -8,7 +8,8 @@ App(
"dialogs",
],
stack_size=4 * 1024,
- order=20,
+ fap_description="Enables use of Flipper as a debug probe for ARM devices, implements the CMSIS-DAP protocol",
+ fap_version="1.0",
fap_icon="dap_link.png",
fap_category="GPIO",
fap_private_libs=[
diff --git a/applications/external/dap_link/dap_link.c b/applications/external/dap_link/dap_link.c
index 52d222138..487c63c44 100644
--- a/applications/external/dap_link/dap_link.c
+++ b/applications/external/dap_link/dap_link.c
@@ -15,7 +15,7 @@
#include "usb/dap_v2_usb.h"
#include
#include "dap_link_icons.h"
-#include "assets_icons.h"
+#include
/***************************************************************************/
/****************************** DAP COMMON *********************************/
@@ -525,4 +525,4 @@ int32_t dap_link_app(void* p) {
dap_app_free(app);
return 0;
-}
+}
\ No newline at end of file
diff --git a/applications/external/dap_link/gui/views/dap_main_view.c b/applications/external/dap_link/gui/views/dap_main_view.c
index f54c5e3d5..15f285698 100644
--- a/applications/external/dap_link/gui/views/dap_main_view.c
+++ b/applications/external/dap_link/gui/views/dap_main_view.c
@@ -1,5 +1,6 @@
#include "dap_main_view.h"
#include "dap_link_icons.h"
+#include
#include
// extern const Icon I_ArrowDownEmpty_12x18;
diff --git a/applications/external/doom/.gitignore b/applications/external/doom/.gitignore
deleted file mode 100644
index e2a15a10a..000000000
--- a/applications/external/doom/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-dist/*
-.vscode
-.clang-format
-.editorconfig
\ No newline at end of file
diff --git a/applications/external/doom/application.fam b/applications/external/doom/application.fam
index 5ff6878ee..995286d74 100644
--- a/applications/external/doom/application.fam
+++ b/applications/external/doom/application.fam
@@ -8,7 +8,6 @@ App(
"music_player",
],
stack_size=4 * 1024,
- order=75,
fap_icon="doom_10px.png",
fap_category="Games",
fap_icon_assets="assets",
diff --git a/applications/external/doom/display.h b/applications/external/doom/display.h
index 89f821867..a949b14fa 100644
--- a/applications/external/doom/display.h
+++ b/applications/external/doom/display.h
@@ -1,7 +1,8 @@
#include
#include
#include "constants.h"
-#include
+#include "doom_icons.h"
+#include
#include "assets.h"
#define CHECK_BIT(var, pos) ((var) & (1 << (pos)))
diff --git a/applications/external/doom/doom.c b/applications/external/doom/doom.c
index dfe37d094..c2d9a6bf0 100644
--- a/applications/external/doom/doom.c
+++ b/applications/external/doom/doom.c
@@ -13,6 +13,7 @@
#include "level.h"
#include
#include
+#include
#define SOUND
@@ -156,9 +157,6 @@ void spawnEntity(uint8_t type, uint8_t x, uint8_t y, PluginState* const plugin_s
plugin_state->entity[plugin_state->num_entities] = create_medikit(x, y);
plugin_state->num_entities++;
break;
-
- default:
- break;
}
}
@@ -462,9 +460,6 @@ void updateEntities(const uint8_t level[], Canvas* const canvas, PluginState* co
}
break;
}
-
- default:
- break;
}
i++;
@@ -993,6 +988,9 @@ int32_t doom_app() {
music_player_worker_load_rtttl_from_string(plugin_state->music_instance->worker, dsintro);
music_player_worker_start(plugin_state->music_instance->worker);
#endif
+ // Call dolphin deed on game start
+ dolphin_deed(DolphinDeedPluginGameStart);
+
for(bool processing = true; processing;) {
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
furi_mutex_acquire(plugin_state->mutex, FuriWaitForever);
diff --git a/applications/external/doom/doom_music_player_worker.c b/applications/external/doom/doom_music_player_worker.c
index c8b9bb9db..e81549625 100644
--- a/applications/external/doom/doom_music_player_worker.c
+++ b/applications/external/doom/doom_music_player_worker.c
@@ -393,7 +393,7 @@ bool music_player_worker_load_rtttl_from_file(MusicPlayerWorker* instance, const
if(!storage_file_open(file, file_path, FSAM_READ, FSOM_OPEN_EXISTING)) {
FURI_LOG_E(TAG, "Unable to open file");
break;
- }
+ };
uint16_t ret = 0;
do {
diff --git a/applications/external/dtmf_dolphin/application.fam b/applications/external/dtmf_dolphin/application.fam
index 5f01bc9a0..11a72df12 100644
--- a/applications/external/dtmf_dolphin/application.fam
+++ b/applications/external/dtmf_dolphin/application.fam
@@ -10,9 +10,8 @@ App(
],
fap_icon="phone.png",
stack_size=8 * 1024,
- order=20,
fap_category="Tools",
fap_author="@litui & @xMasterX",
- fap_version="1.0",
+ fap_version="1.1",
fap_description="DTMF (Dual-Tone Multi-Frequency) dialer, Bluebox, and Redbox.",
)
diff --git a/applications/external/dtmf_dolphin/dtmf_dolphin.c b/applications/external/dtmf_dolphin/dtmf_dolphin.c
index 698b23540..c1b10defa 100644
--- a/applications/external/dtmf_dolphin/dtmf_dolphin.c
+++ b/applications/external/dtmf_dolphin/dtmf_dolphin.c
@@ -86,4 +86,4 @@ int32_t dtmf_dolphin_app(void* p) {
app_free(app);
return 0;
-}
+}
\ No newline at end of file
diff --git a/applications/external/dtmf_dolphin/phone.png b/applications/external/dtmf_dolphin/phone.png
index 443f847c3..9c4d04c02 100644
Binary files a/applications/external/dtmf_dolphin/phone.png and b/applications/external/dtmf_dolphin/phone.png differ
diff --git a/applications/external/esp32cam_camera/application.fam b/applications/external/esp32cam_camera/application.fam
index a0e0ede4c..e8d5c7158 100644
--- a/applications/external/esp32cam_camera/application.fam
+++ b/applications/external/esp32cam_camera/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_CAMERA"],
requires=["gui"],
stack_size=8 * 1024,
- order=1,
fap_icon="icon.png",
fap_category="GPIO",
fap_description="ESP32-CAM live feed and photo capture, use left/right for orientation/mode, up/down for brightness and center for saving a screenshot. [Unplug the USB cable to test with Mayhem]",
diff --git a/applications/external/esp32cam_evilportal/application.fam b/applications/external/esp32cam_evilportal/application.fam
index 190ae711a..d842ddc79 100644
--- a/applications/external/esp32cam_evilportal/application.fam
+++ b/applications/external/esp32cam_evilportal/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_EVIL_PORTAL"],
requires=["gui"],
stack_size=1 * 1024,
- order=90,
fap_icon="icons/evil_portal_10px.png",
fap_category="GPIO",
fap_description="ESP32-CAM evil portal. When users try to connect to this access point they will be served a fake login screen. User credentials are sent to the Flipper and logged on the SD card. [Unplug the USB cable to test with Mayhem]",
diff --git a/applications/external/esp32cam_marauder_companion/application.fam b/applications/external/esp32cam_marauder_companion/application.fam
index 800cb92be..891c0859d 100644
--- a/applications/external/esp32cam_marauder_companion/application.fam
+++ b/applications/external/esp32cam_marauder_companion/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_WIFI_MARAUDER"],
requires=["gui"],
stack_size=4 * 1024,
- order=2,
fap_icon="wifi_10px.png",
fap_category="GPIO",
fap_description="ESP32-CAM version of Marauder. Includes all functionality from the original plus some options to trigger the camera and flashlight. [Unplug the USB cable to test with Mayhem]",
diff --git a/applications/external/esp32cam_morseflasher/application.fam b/applications/external/esp32cam_morseflasher/application.fam
index 037e63c81..4c40e19a9 100644
--- a/applications/external/esp32cam_morseflasher/application.fam
+++ b/applications/external/esp32cam_morseflasher/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_UART_TERMINAL"],
requires=["gui"],
stack_size=1 * 1024,
- order=90,
fap_icon_assets="assets",
fap_icon="icon.png",
fap_category="GPIO",
diff --git a/applications/external/esp32cam_motion_detection/application.fam b/applications/external/esp32cam_motion_detection/application.fam
index 57a5396c5..b2fa8a467 100644
--- a/applications/external/esp32cam_motion_detection/application.fam
+++ b/applications/external/esp32cam_motion_detection/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_QRCODE"],
requires=["gui"],
stack_size=8 * 1024,
- order=1,
fap_icon="icon.png",
fap_category="GPIO",
fap_description="ESP32-CAM Motion detection. It generates a beep when motion is detected. Can be extended to trigger more stuff in the code. [Unplug the USB cable to test with Mayhem]",
diff --git a/applications/external/esp32cam_nannycam/application.fam b/applications/external/esp32cam_nannycam/application.fam
index 75f2be783..bbb7022d1 100644
--- a/applications/external/esp32cam_nannycam/application.fam
+++ b/applications/external/esp32cam_nannycam/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_QRCODE"],
requires=["gui"],
stack_size=8 * 1024,
- order=1,
fap_icon="icon.png",
fap_category="GPIO",
fap_description="ESP32-CAM simple app to start a remote camera. [Unplug the USB cable to test with Mayhem]",
diff --git a/applications/external/esp32cam_qrcode/application.fam b/applications/external/esp32cam_qrcode/application.fam
index 73c418510..b96942e9e 100644
--- a/applications/external/esp32cam_qrcode/application.fam
+++ b/applications/external/esp32cam_qrcode/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_QRCODE"],
requires=["gui"],
stack_size=8 * 1024,
- order=1,
fap_icon="icon.png",
fap_category="GPIO",
fap_description="ESP32-CAM simple app to show a payload from QR codes. Can be extended to trigger more stuff in the code. [Unplug the USB cable to test with Mayhem]",
diff --git a/applications/external/esp8266_deauth/application.fam b/applications/external/esp8266_deauth/application.fam
index 9b176a3dd..f36d85d18 100644
--- a/applications/external/esp8266_deauth/application.fam
+++ b/applications/external/esp8266_deauth/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="esp8266_deauth_app",
requires=["gui"],
stack_size=2 * 1024,
- order=100,
fap_icon="wifi_10px.png",
fap_category="WiFi",
fap_author="@SequoiaSan & @xMasterX",
diff --git a/applications/external/esp_flasher/application.fam b/applications/external/esp_flasher/application.fam
index 2a3085511..1fd1c6e7a 100644
--- a/applications/external/esp_flasher/application.fam
+++ b/applications/external/esp_flasher/application.fam
@@ -6,7 +6,6 @@ App(
entry_point="esp_flasher_app",
requires=["gui"],
stack_size=4 * 1024,
- order=90,
fap_icon="update_10px.png",
fap_category="GPIO",
fap_private_libs=[
diff --git a/applications/external/esubghz_chat/assets/Nfc_14px.png b/applications/external/esubghz_chat/assets/Nfc_14px.png
new file mode 100644
index 000000000..9e43a3291
Binary files /dev/null and b/applications/external/esubghz_chat/assets/Nfc_14px.png differ
diff --git a/applications/external/esubghz_chat/assets/chat_14px.png b/applications/external/esubghz_chat/assets/chat_14px.png
new file mode 100644
index 000000000..f949d0a79
Binary files /dev/null and b/applications/external/esubghz_chat/assets/chat_14px.png differ
diff --git a/applications/external/esubghz_chat/assets/hex_10px.png b/applications/external/esubghz_chat/assets/hex_10px.png
deleted file mode 100644
index 582e288c6..000000000
Binary files a/applications/external/esubghz_chat/assets/hex_10px.png and /dev/null differ
diff --git a/applications/external/esubghz_chat/assets/hex_14px.png b/applications/external/esubghz_chat/assets/hex_14px.png
new file mode 100644
index 000000000..b2af9e204
Binary files /dev/null and b/applications/external/esubghz_chat/assets/hex_14px.png differ
diff --git a/applications/external/esubghz_chat/assets/keyboard_14px.png b/applications/external/esubghz_chat/assets/keyboard_14px.png
new file mode 100644
index 000000000..b84309c5a
Binary files /dev/null and b/applications/external/esubghz_chat/assets/keyboard_14px.png differ
diff --git a/applications/external/esubghz_chat/assets/u2f_14px.png b/applications/external/esubghz_chat/assets/u2f_14px.png
new file mode 100644
index 000000000..d65bacea9
Binary files /dev/null and b/applications/external/esubghz_chat/assets/u2f_14px.png differ
diff --git a/applications/external/esubghz_chat/crypto_wrapper.c b/applications/external/esubghz_chat/crypto_wrapper.c
index e9074bdce..5d72bd843 100644
--- a/applications/external/esubghz_chat/crypto_wrapper.c
+++ b/applications/external/esubghz_chat/crypto_wrapper.c
@@ -192,10 +192,46 @@ bool crypto_ctx_encrypt(ESubGhzChatCryptoCtx* ctx, uint8_t* in, size_t in_len, u
TAG_BYTES) == 0);
#endif /* FURI_HAL_CRYPTO_ADVANCED_AVAIL */
- // increase internal counter
+ // update replay dict and increase internal counter
if(ret) {
+ ESubGhzChatReplayDict_set_at(ctx->replay_dict, ctx->run_id, ctx->counter);
ctx->counter++;
}
return ret;
}
+
+size_t crypto_ctx_dump_replay_dict(
+ ESubGhzChatCryptoCtx* ctx,
+ CryptoCtxReplayDictWriter writer,
+ void* writer_ctx) {
+ size_t ret = 0;
+ ESubGhzChatReplayDict_it_t i;
+
+ for(ESubGhzChatReplayDict_it(i, ctx->replay_dict); !ESubGhzChatReplayDict_end_p(i);
+ ESubGhzChatReplayDict_next(i), ret++) {
+ ESubGhzChatReplayDict_itref_t* ref = ESubGhzChatReplayDict_ref(i);
+ if(!writer(ref->key, ref->value, writer_ctx)) {
+ break;
+ }
+ }
+
+ return ret;
+}
+
+size_t crypto_ctx_read_replay_dict(
+ ESubGhzChatCryptoCtx* ctx,
+ CryptoCtxReplayDictReader reader,
+ void* reader_ctx) {
+ size_t ret = 0;
+
+ uint64_t run_id;
+ uint32_t counter;
+
+ while(reader(&run_id, &counter, reader_ctx)) {
+ ESubGhzChatReplayDict_set_at(ctx->replay_dict, run_id, counter);
+ ret++;
+ }
+
+ return ret;
+}
diff --git a/applications/external/esubghz_chat/crypto_wrapper.h b/applications/external/esubghz_chat/crypto_wrapper.h
index 4a3dcf8e5..080a604d1 100644
--- a/applications/external/esubghz_chat/crypto_wrapper.h
+++ b/applications/external/esubghz_chat/crypto_wrapper.h
@@ -34,6 +34,18 @@ void crypto_ctx_get_key(ESubGhzChatCryptoCtx* ctx, uint8_t* key);
bool crypto_ctx_decrypt(ESubGhzChatCryptoCtx* ctx, uint8_t* in, size_t in_len, uint8_t* out);
bool crypto_ctx_encrypt(ESubGhzChatCryptoCtx* ctx, uint8_t* in, size_t in_len, uint8_t* out);
+typedef bool (*CryptoCtxReplayDictWriter)(uint64_t run_id, uint32_t counter, void* context);
+typedef bool (*CryptoCtxReplayDictReader)(uint64_t* run_id, uint32_t* counter, void* context);
+
+size_t crypto_ctx_dump_replay_dict(
+ ESubGhzChatCryptoCtx* ctx,
+ CryptoCtxReplayDictWriter writer,
+ void* writer_ctx);
+size_t crypto_ctx_read_replay_dict(
+ ESubGhzChatCryptoCtx* ctx,
+ CryptoCtxReplayDictReader reader,
+ void* reader_ctx);
+
#ifdef __cplusplus
}
#endif
diff --git a/applications/external/esubghz_chat/esubghz_chat.c b/applications/external/esubghz_chat/esubghz_chat.c
index 342f244ed..6a5778fd0 100644
--- a/applications/external/esubghz_chat/esubghz_chat.c
+++ b/applications/external/esubghz_chat/esubghz_chat.c
@@ -1,14 +1,13 @@
#include
#include
#include
-#include
+#include "helpers/radio_device_loader.h"
#include "esubghz_chat_i.h"
#define CHAT_LEAVE_DELAY 10
#define TICK_INTERVAL 50
#define MESSAGE_COMPLETION_TIMEOUT 500
-#define TIMEOUT_BETWEEN_MESSAGES 500
#define KBD_UNLOCK_CNT 3
#define KBD_UNLOCK_TIMEOUT 1000
@@ -125,15 +124,23 @@ void tx_msg_input(ESubGhzChatState* state) {
subghz_tx_rx_worker_write(state->subghz_worker, state->tx_buffer, tx_size);
}
-/* Displays whether or not encryption has been enabled in the text box. Also
- * clears the text input buffer to remove the password and starts the Sub-GHz
- * worker. After starting the worker a join message is transmitted. */
+/* Displays information on frequency, encryption and radio type in the text
+ * box. Also clears the text input buffer to remove the password and starts the
+ * Sub-GHz worker. After starting the worker a join message is transmitted. */
void enter_chat(ESubGhzChatState* state) {
+ furi_string_cat_printf(state->chat_box_store, "Frequency: %lu", state->frequency);
+
furi_string_cat_printf(
state->chat_box_store, "\nEncrypted: %s", (state->encrypted ? "yes" : "no"));
subghz_tx_rx_worker_start(state->subghz_worker, state->subghz_device, state->frequency);
+ if(strcmp(state->subghz_device->name, "cc1101_ext") == 0) {
+ furi_string_cat_printf(state->chat_box_store, "\nRadio: External");
+ } else {
+ furi_string_cat_printf(state->chat_box_store, "\nRadio: Internal");
+ }
+
/* concatenate the name prefix and join message */
furi_string_set(state->msg_input, state->name_prefix);
furi_string_cat_str(state->msg_input, " joined chat.");
@@ -523,6 +530,9 @@ int32_t esubghz_chat(void) {
goto err_alloc_crypto;
}
+ /* set the default frequency */
+ state->frequency = DEFAULT_FREQ;
+
/* set the have_read callback of the Sub-GHz worker */
subghz_tx_rx_worker_set_callback_have_read(state->subghz_worker, have_read_cb, state);
@@ -531,7 +541,12 @@ int32_t esubghz_chat(void) {
/* init internal device */
subghz_devices_init();
- state->subghz_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
+
+ state->subghz_device =
+ radio_device_loader_set(state->subghz_device, SubGhzRadioDeviceTypeExternalCC1101);
+
+ subghz_devices_reset(state->subghz_device);
+ subghz_devices_idle(state->subghz_device);
/* set chat name prefix */
furi_string_printf(state->name_prefix, "%s", furi_hal_version_get_name_ptr());
@@ -582,8 +597,8 @@ int32_t esubghz_chat(void) {
Gui* gui = furi_record_open(RECORD_GUI);
view_dispatcher_attach_to_gui(state->view_dispatcher, gui, ViewDispatcherTypeFullscreen);
- /* switch to the frequency input scene */
- scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput);
+ /* switch to the key menu scene */
+ scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_KeyMenu);
/* run the view dispatcher, this call only returns when we close the
* application */
@@ -627,6 +642,8 @@ int32_t esubghz_chat(void) {
crypto_explicit_bzero(state->nfc_dev_data, sizeof(NfcDeviceData));
/* deinit devices */
+ radio_device_loader_end(state->subghz_device);
+
subghz_devices_deinit();
/* exit suppress charge mode */
diff --git a/applications/external/esubghz_chat/esubghz_chat_i.h b/applications/external/esubghz_chat/esubghz_chat_i.h
index b29e6292d..4c6458cec 100644
--- a/applications/external/esubghz_chat/esubghz_chat_i.h
+++ b/applications/external/esubghz_chat/esubghz_chat_i.h
@@ -18,8 +18,8 @@
#include "crypto_wrapper.h"
#include "scenes/esubghz_chat_scene.h"
-#include
#include "esubghz_chat_icons.h"
+#include
#define APPLICATION_NAME "ESubGhzChat"
diff --git a/applications/external/esubghz_chat/helpers/nfc_helpers.h b/applications/external/esubghz_chat/helpers/nfc_helpers.h
new file mode 100644
index 000000000..5e507e335
--- /dev/null
+++ b/applications/external/esubghz_chat/helpers/nfc_helpers.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NFC_MAX_BYTES 256
+#define NFC_CONFIG_PAGES 4
+
+struct FreqNfcEntry {
+ uint32_t frequency;
+ uint32_t unused1;
+ uint32_t unused2;
+ uint32_t unused3;
+} __attribute__((packed));
+
+struct ReplayDictNfcEntry {
+ uint64_t run_id;
+ uint32_t counter;
+ uint32_t unused;
+} __attribute__((packed));
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/applications/external/esubghz_chat/helpers/radio_device_loader.c b/applications/external/esubghz_chat/helpers/radio_device_loader.c
new file mode 100644
index 000000000..91f006a44
--- /dev/null
+++ b/applications/external/esubghz_chat/helpers/radio_device_loader.c
@@ -0,0 +1,65 @@
+#include "radio_device_loader.h"
+
+#include
+#include
+
+static void radio_device_loader_power_on() {
+ uint8_t attempts = 0;
+ while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
+ furi_hal_power_enable_otg();
+ //CC1101 power-up time
+ furi_delay_ms(10);
+ }
+}
+
+static void radio_device_loader_power_off() {
+ if(furi_hal_power_is_otg_enabled()) furi_hal_power_disable_otg();
+}
+
+bool radio_device_loader_is_connect_external(const char* name) {
+ bool is_connect = false;
+ bool is_otg_enabled = furi_hal_power_is_otg_enabled();
+
+ if(!is_otg_enabled) {
+ radio_device_loader_power_on();
+ }
+
+ const SubGhzDevice* device = subghz_devices_get_by_name(name);
+ if(device) {
+ is_connect = subghz_devices_is_connect(device);
+ }
+
+ if(!is_otg_enabled) {
+ radio_device_loader_power_off();
+ }
+ return is_connect;
+}
+
+const SubGhzDevice* radio_device_loader_set(
+ const SubGhzDevice* current_radio_device,
+ SubGhzRadioDeviceType radio_device_type) {
+ const SubGhzDevice* radio_device;
+
+ if(radio_device_type == SubGhzRadioDeviceTypeExternalCC1101 &&
+ radio_device_loader_is_connect_external(SUBGHZ_DEVICE_CC1101_EXT_NAME)) {
+ radio_device_loader_power_on();
+ radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_EXT_NAME);
+ subghz_devices_begin(radio_device);
+ } else if(current_radio_device == NULL) {
+ radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
+ } else {
+ radio_device_loader_end(current_radio_device);
+ radio_device = subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME);
+ }
+
+ return radio_device;
+}
+
+void radio_device_loader_end(const SubGhzDevice* radio_device) {
+ furi_assert(radio_device);
+ radio_device_loader_power_off();
+ // Code below is not used (and will cause crash) since its called from tx_rx worker end!
+ //if(radio_device != subghz_devices_get_by_name(SUBGHZ_DEVICE_CC1101_INT_NAME)) {
+ // subghz_devices_end(radio_device);
+ //}
+}
\ No newline at end of file
diff --git a/applications/external/esubghz_chat/helpers/radio_device_loader.h b/applications/external/esubghz_chat/helpers/radio_device_loader.h
new file mode 100644
index 000000000..bee4e2c36
--- /dev/null
+++ b/applications/external/esubghz_chat/helpers/radio_device_loader.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include
+
+/** SubGhzRadioDeviceType */
+typedef enum {
+ SubGhzRadioDeviceTypeInternal,
+ SubGhzRadioDeviceTypeExternalCC1101,
+} SubGhzRadioDeviceType;
+
+const SubGhzDevice* radio_device_loader_set(
+ const SubGhzDevice* current_radio_device,
+ SubGhzRadioDeviceType radio_device_type);
+
+void radio_device_loader_end(const SubGhzDevice* radio_device);
\ No newline at end of file
diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_freq_input.c b/applications/external/esubghz_chat/scenes/esubghz_chat_freq_input.c
index ccce26418..3c74caec3 100644
--- a/applications/external/esubghz_chat/scenes/esubghz_chat_freq_input.c
+++ b/applications/external/esubghz_chat/scenes/esubghz_chat_freq_input.c
@@ -1,12 +1,11 @@
#include "../esubghz_chat_i.h"
-/* Sends FreqEntered event to scene manager and displays the frequency in the
- * text box. */
+/* Sends FreqEntered event to scene manager and enters the chat. */
static void freq_input_cb(void* context) {
furi_assert(context);
ESubGhzChatState* state = context;
- furi_string_cat_printf(state->chat_box_store, "Frequency: %lu", state->frequency);
+ enter_chat(state);
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_FreqEntered);
}
@@ -49,7 +48,7 @@ void scene_on_enter_freq_input(void* context) {
furi_assert(context);
ESubGhzChatState* state = context;
- snprintf(state->text_input_store, TEXT_INPUT_STORE_SIZE, "%lu", (uint32_t)DEFAULT_FREQ);
+ snprintf(state->text_input_store, TEXT_INPUT_STORE_SIZE, "%lu", state->frequency);
text_input_reset(state->text_input);
text_input_set_result_callback(
state->text_input,
@@ -76,9 +75,9 @@ bool scene_on_event_freq_input(void* context, SceneManagerEvent event) {
switch(event.type) {
case SceneManagerEventTypeCustom:
switch(event.event) {
- /* switch to password input scene */
+ /* switch to message input scene */
case ESubGhzChatEvent_FreqEntered:
- scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_KeyMenu);
+ scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatInput);
consumed = true;
break;
}
diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_hex_key_input.c b/applications/external/esubghz_chat/scenes/esubghz_chat_hex_key_input.c
index 564bfde8f..00d9e70f3 100644
--- a/applications/external/esubghz_chat/scenes/esubghz_chat_hex_key_input.c
+++ b/applications/external/esubghz_chat/scenes/esubghz_chat_hex_key_input.c
@@ -1,7 +1,7 @@
#include "../esubghz_chat_i.h"
-/* Sets the entered bytes as the key, enters the chat and sends a HexKeyEntered
- * event to the scene manager. */
+/* Sets the entered bytes as the key and sends a HexKeyEntered event to the
+ * scene manager. */
static void hex_key_input_cb(void* context) {
furi_assert(context);
ESubGhzChatState* state = context;
@@ -20,8 +20,6 @@ static void hex_key_input_cb(void* context) {
state->encrypted = true;
- enter_chat(state);
-
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_HexKeyEntered);
}
@@ -55,9 +53,9 @@ bool scene_on_event_hex_key_input(void* context, SceneManagerEvent event) {
switch(event.type) {
case SceneManagerEventTypeCustom:
switch(event.event) {
- /* switch to message input scene */
+ /* switch to frequency input scene */
case ESubGhzChatEvent_HexKeyEntered:
- scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatInput);
+ scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput);
consumed = true;
break;
}
diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_key_menu.c b/applications/external/esubghz_chat/scenes/esubghz_chat_key_menu.c
index 13483bf53..cd1269ee1 100644
--- a/applications/external/esubghz_chat/scenes/esubghz_chat_key_menu.c
+++ b/applications/external/esubghz_chat/scenes/esubghz_chat_key_menu.c
@@ -17,7 +17,6 @@ static void key_menu_cb(void* context, uint32_t index) {
switch(index) {
case ESubGhzChatKeyMenuItems_NoEncryption:
state->encrypted = false;
- enter_chat(state);
view_dispatcher_send_custom_event(
state->view_dispatcher, ESubGhzChatEvent_KeyMenuNoEncryption);
@@ -49,7 +48,6 @@ static void key_menu_cb(void* context, uint32_t index) {
/* set encrypted flag and enter the chat */
state->encrypted = true;
- enter_chat(state);
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_KeyMenuGenKey);
break;
@@ -73,33 +71,37 @@ void scene_on_enter_key_menu(void* context) {
menu_reset(state->menu);
+ /* clear the crypto CTX in case we got back from password or hex key
+ * input */
+ crypto_ctx_clear(state->crypto_ctx);
+
menu_add_item(
state->menu,
"No encryption",
- &I_chat_10px,
+ &I_chat_14px,
ESubGhzChatKeyMenuItems_NoEncryption,
key_menu_cb,
state);
menu_add_item(
state->menu,
"Password",
- &I_keyboard_10px,
+ &I_keyboard_14px,
ESubGhzChatKeyMenuItems_Password,
key_menu_cb,
state);
menu_add_item(
- state->menu, "Hex Key", &I_hex_10px, ESubGhzChatKeyMenuItems_HexKey, key_menu_cb, state);
+ state->menu, "Hex Key", &I_hex_14px, ESubGhzChatKeyMenuItems_HexKey, key_menu_cb, state);
menu_add_item(
state->menu,
"Generate Key",
- &I_u2f_10px,
+ &I_u2f_14px,
ESubGhzChatKeyMenuItems_GenKey,
key_menu_cb,
state);
menu_add_item(
state->menu,
"Read Key from NFC",
- &I_Nfc_10px,
+ &I_Nfc_14px,
ESubGhzChatKeyMenuItems_ReadKeyFromNfc,
key_menu_cb,
state);
@@ -119,10 +121,10 @@ bool scene_on_event_key_menu(void* context, SceneManagerEvent event) {
switch(event.type) {
case SceneManagerEventTypeCustom:
switch(event.event) {
- /* switch to message input scene */
+ /* switch to frequency input scene */
case ESubGhzChatEvent_KeyMenuNoEncryption:
case ESubGhzChatEvent_KeyMenuGenKey:
- scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatInput);
+ scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput);
consumed = true;
break;
diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_key_read_popup.c b/applications/external/esubghz_chat/scenes/esubghz_chat_key_read_popup.c
index 4d5904406..db1f75491 100644
--- a/applications/external/esubghz_chat/scenes/esubghz_chat_key_read_popup.c
+++ b/applications/external/esubghz_chat/scenes/esubghz_chat_key_read_popup.c
@@ -1,4 +1,5 @@
#include "../esubghz_chat_i.h"
+#include "../helpers/nfc_helpers.h"
typedef enum {
KeyReadPopupState_Idle,
@@ -28,18 +29,46 @@ static void key_read_popup_timeout_cb(void* context) {
if(cur_state == KeyReadPopupState_Fail) {
view_dispatcher_send_custom_event(
state->view_dispatcher, ESubGhzChatEvent_KeyReadPopupFailed);
- /* done displaying our success, enter chat */
+ /* done displaying our success */
} else if(cur_state == KeyReadPopupState_Success) {
- enter_chat(state);
view_dispatcher_send_custom_event(
state->view_dispatcher, ESubGhzChatEvent_KeyReadPopupSucceeded);
}
}
+struct ReplayDictNfcReaderContext {
+ uint8_t* cur;
+ uint8_t* max;
+};
+
+static bool replay_dict_nfc_reader(uint64_t* run_id, uint32_t* counter, void* context) {
+ struct ReplayDictNfcReaderContext* ctx = (struct ReplayDictNfcReaderContext*)context;
+
+ if(ctx->cur + sizeof(struct ReplayDictNfcEntry) > ctx->max) {
+ return false;
+ }
+
+ struct ReplayDictNfcEntry* entry = (struct ReplayDictNfcEntry*)ctx->cur;
+ *run_id = entry->run_id;
+ *counter = __ntohl(entry->counter);
+
+ ctx->cur += sizeof(struct ReplayDictNfcEntry);
+
+ return true;
+}
+
static bool key_read_popup_handle_key_read(ESubGhzChatState* state) {
NfcDeviceData* dev_data = state->nfc_dev_data;
- if(dev_data->mf_ul_data.data_read < KEY_BITS / 8) {
+ /* check for config pages */
+ if(dev_data->mf_ul_data.data_read < NFC_CONFIG_PAGES * 4) {
+ return false;
+ }
+
+ size_t data_read = dev_data->mf_ul_data.data_read - (NFC_CONFIG_PAGES * 4);
+
+ /* check if key was transmitted */
+ if(data_read < KEY_BITS / 8) {
return false;
}
@@ -55,6 +84,21 @@ static bool key_read_popup_handle_key_read(ESubGhzChatState* state) {
return false;
}
+ /* read the frequency */
+ if(data_read >= (KEY_BITS / 8) + sizeof(struct FreqNfcEntry)) {
+ struct FreqNfcEntry* freq_entry =
+ (struct FreqNfcEntry*)(dev_data->mf_ul_data.data + (KEY_BITS / 8));
+ state->frequency = __ntohl(freq_entry->frequency);
+ }
+
+ /* read the replay dict */
+ struct ReplayDictNfcReaderContext rd_ctx = {
+ .cur = dev_data->mf_ul_data.data + (KEY_BITS / 8) + sizeof(struct FreqNfcEntry),
+ .max =
+ dev_data->mf_ul_data.data + (data_read < NFC_MAX_BYTES ? data_read : NFC_MAX_BYTES)};
+
+ crypto_ctx_read_replay_dict(state->crypto_ctx, replay_dict_nfc_reader, &rd_ctx);
+
/* set encrypted flag */
state->encrypted = true;
@@ -183,9 +227,9 @@ bool scene_on_event_key_read_popup(void* context, SceneManagerEvent event) {
consumed = true;
break;
- /* success, go to chat input */
+ /* success, go to frequency input */
case ESubGhzChatEvent_KeyReadPopupSucceeded:
- scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatInput);
+ scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput);
consumed = true;
break;
diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_key_share_popup.c b/applications/external/esubghz_chat/scenes/esubghz_chat_key_share_popup.c
index a3230049c..07d85cb33 100644
--- a/applications/external/esubghz_chat/scenes/esubghz_chat_key_share_popup.c
+++ b/applications/external/esubghz_chat/scenes/esubghz_chat_key_share_popup.c
@@ -1,4 +1,25 @@
#include "../esubghz_chat_i.h"
+#include "../helpers/nfc_helpers.h"
+
+struct ReplayDictNfcWriterContext {
+ uint8_t* cur;
+ uint8_t* max;
+};
+
+static bool replay_dict_nfc_writer(uint64_t run_id, uint32_t counter, void* context) {
+ struct ReplayDictNfcWriterContext* ctx = (struct ReplayDictNfcWriterContext*)context;
+
+ struct ReplayDictNfcEntry entry = {.run_id = run_id, .counter = __htonl(counter), .unused = 0};
+
+ if(ctx->cur + sizeof(entry) > ctx->max) {
+ return false;
+ }
+
+ memcpy(ctx->cur, &entry, sizeof(entry));
+ ctx->cur += sizeof(entry);
+
+ return true;
+}
static void prepare_nfc_dev_data(ESubGhzChatState* state) {
NfcDeviceData* dev_data = state->nfc_dev_data;
@@ -20,9 +41,32 @@ static void prepare_nfc_dev_data(ESubGhzChatState* state) {
dev_data->mf_ul_data.version.storage_size = 0x11;
dev_data->mf_ul_data.version.protocol_type = 0x03;
- /* Add 16 to the size for config pages */
- dev_data->mf_ul_data.data_size = (KEY_BITS / 8) + 16;
+ size_t data_written = 0;
+
+ /* write key */
crypto_ctx_get_key(state->crypto_ctx, dev_data->mf_ul_data.data);
+ data_written += (KEY_BITS / 8);
+
+ /* write frequency */
+ struct FreqNfcEntry* freq_entry =
+ (struct FreqNfcEntry*)(dev_data->mf_ul_data.data + data_written);
+ freq_entry->frequency = __htonl(state->frequency);
+ freq_entry->unused1 = 0;
+ freq_entry->unused2 = 0;
+ freq_entry->unused3 = 0;
+ data_written += sizeof(struct FreqNfcEntry);
+
+ /* write the replay dict */
+ struct ReplayDictNfcWriterContext wr_ctx = {
+ .cur = dev_data->mf_ul_data.data + data_written,
+ .max = dev_data->mf_ul_data.data + NFC_MAX_BYTES};
+
+ size_t n_entries =
+ crypto_ctx_dump_replay_dict(state->crypto_ctx, replay_dict_nfc_writer, &wr_ctx);
+ data_written += n_entries * sizeof(struct ReplayDictNfcEntry);
+
+ /* calculate size of data, add 16 for config pages */
+ dev_data->mf_ul_data.data_size = data_written + (NFC_CONFIG_PAGES * 4);
}
/* Prepares the key share popup scene. */
diff --git a/applications/external/esubghz_chat/scenes/esubghz_chat_pass_input.c b/applications/external/esubghz_chat/scenes/esubghz_chat_pass_input.c
index cb40fc7fd..f1cf4bfa7 100644
--- a/applications/external/esubghz_chat/scenes/esubghz_chat_pass_input.c
+++ b/applications/external/esubghz_chat/scenes/esubghz_chat_pass_input.c
@@ -1,14 +1,12 @@
#include "../esubghz_chat_i.h"
-/* Sends PassEntered event to scene manager and enters the chat. */
+/* Sends PassEntered event to scene manager. */
static void pass_input_cb(void* context) {
furi_assert(context);
ESubGhzChatState* state = context;
crypto_explicit_bzero(state->text_input_store, sizeof(state->text_input_store));
- enter_chat(state);
-
view_dispatcher_send_custom_event(state->view_dispatcher, ESubGhzChatEvent_PassEntered);
}
@@ -83,9 +81,9 @@ bool scene_on_event_pass_input(void* context, SceneManagerEvent event) {
switch(event.type) {
case SceneManagerEventTypeCustom:
switch(event.event) {
- /* switch to message input scene */
+ /* switch to frequency input scene */
case ESubGhzChatEvent_PassEntered:
- scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_ChatInput);
+ scene_manager_next_scene(state->scene_manager, ESubGhzChatScene_FreqInput);
consumed = true;
break;
}
diff --git a/applications/external/etch_a_sketch/application.fam b/applications/external/etch_a_sketch/application.fam
index db1add1ab..2f6cd9136 100644
--- a/applications/external/etch_a_sketch/application.fam
+++ b/applications/external/etch_a_sketch/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_ETCH_A_SKETCH"],
requires=["gui"],
stack_size=2 * 1024,
- order=175,
fap_icon="etch-a-sketch-icon.png",
fap_category="Media",
fap_icon_assets="assets",
diff --git a/applications/external/evil_portal/LICENSE.txt b/applications/external/evil_portal/LICENSE.txt
new file mode 100644
index 000000000..2ae63a7f6
--- /dev/null
+++ b/applications/external/evil_portal/LICENSE.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 bigbrodude6119
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/applications/external/evil_portal/application.fam b/applications/external/evil_portal/application.fam
index 58c7d426c..6af0546c4 100644
--- a/applications/external/evil_portal/application.fam
+++ b/applications/external/evil_portal/application.fam
@@ -6,7 +6,9 @@ App(
cdefines=["APP_EVIL_PORTAL"],
requires=["gui"],
stack_size=1 * 1024,
- order=90,
+ fap_author="bigbrodude6119",
+ fap_description="Create an evil captive portal Wi-Fi access point",
+ fap_icon_assets="icons",
fap_icon="icons/evil_portal_10px.png",
fap_category="WiFi",
)
diff --git a/applications/external/evil_portal/evil_portal_app.c b/applications/external/evil_portal/evil_portal_app.c
index ef3131f46..8e091da40 100644
--- a/applications/external/evil_portal/evil_portal_app.c
+++ b/applications/external/evil_portal/evil_portal_app.c
@@ -32,10 +32,15 @@ Evil_PortalApp* evil_portal_app_alloc() {
app->command_index = 0;
app->portal_logs = furi_string_alloc();
- app->gui = furi_record_open(RECORD_GUI);
app->dialogs = furi_record_open(RECORD_DIALOGS);
+ app->file_path = furi_string_alloc();
+
+ app->gui = furi_record_open(RECORD_GUI);
app->view_dispatcher = view_dispatcher_alloc();
+
+ app->loading = loading_alloc();
+
app->scene_manager = scene_manager_alloc(&evil_portal_scene_handlers, app);
view_dispatcher_enable_queue(app->view_dispatcher);
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
@@ -49,12 +54,18 @@ Evil_PortalApp* evil_portal_app_alloc() {
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
+ app->view_stack = view_stack_alloc();
+
app->var_item_list = variable_item_list_alloc();
view_dispatcher_add_view(
app->view_dispatcher,
Evil_PortalAppViewVarItemList,
variable_item_list_get_view(app->var_item_list));
+ app->text_input = text_input_alloc();
+ view_dispatcher_add_view(
+ app->view_dispatcher, Evil_PortalAppViewTextInput, text_input_get_view(app->text_input));
+
for(int i = 0; i < NUM_MENU_ITEMS; ++i) {
app->selected_option_index[i] = 0;
}
@@ -89,6 +100,10 @@ void evil_portal_app_free(Evil_PortalApp* app) {
text_box_free(app->text_box);
furi_string_free(app->text_box_store);
+ text_input_free(app->text_input);
+
+ view_stack_free(app->view_stack);
+ loading_free(app->loading);
// View dispatcher
view_dispatcher_free(app->view_dispatcher);
@@ -98,36 +113,32 @@ void evil_portal_app_free(Evil_PortalApp* app) {
// Close records
furi_record_close(RECORD_GUI);
+
furi_record_close(RECORD_DIALOGS);
+ furi_string_free(app->file_path);
free(app);
}
int32_t evil_portal_app(void* p) {
UNUSED(p);
+ Evil_PortalApp* evil_portal_app = evil_portal_app_alloc();
- // turn off 5v, so it gets reset on startup
- if(furi_hal_power_is_otg_enabled()) {
- furi_hal_power_disable_otg();
- }
-
- // Enable 5v on startup
uint8_t attempts = 0;
+ bool otg_was_enabled = furi_hal_power_is_otg_enabled();
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
furi_hal_power_enable_otg();
furi_delay_ms(10);
}
furi_delay_ms(200);
- Evil_PortalApp* evil_portal_app = evil_portal_app_alloc();
-
evil_portal_app->uart = evil_portal_uart_init(evil_portal_app);
view_dispatcher_run(evil_portal_app->view_dispatcher);
evil_portal_app_free(evil_portal_app);
- if(furi_hal_power_is_otg_enabled()) {
+ if(furi_hal_power_is_otg_enabled() && !otg_was_enabled) {
furi_hal_power_disable_otg();
}
diff --git a/applications/external/evil_portal/evil_portal_app.h b/applications/external/evil_portal/evil_portal_app.h
index 65c047ea5..bb663ec22 100644
--- a/applications/external/evil_portal/evil_portal_app.h
+++ b/applications/external/evil_portal/evil_portal_app.h
@@ -8,4 +8,4 @@ typedef struct Evil_PortalApp Evil_PortalApp;
#ifdef __cplusplus
}
-#endif
+#endif
\ No newline at end of file
diff --git a/applications/external/evil_portal/evil_portal_app_i.h b/applications/external/evil_portal/evil_portal_app_i.h
index af36d8eb9..bbe82cbd8 100644
--- a/applications/external/evil_portal/evil_portal_app_i.h
+++ b/applications/external/evil_portal/evil_portal_app_i.h
@@ -4,19 +4,22 @@
#include "evil_portal_custom_event.h"
#include "evil_portal_uart.h"
#include "scenes/evil_portal_scene.h"
+#include "evil_portal_icons.h"
+#include
#include
+#include
#include
+#include
#include
#include
#include
-
-#include
+#include
#include
#include
-#define NUM_MENU_ITEMS (4)
+#define NUM_MENU_ITEMS (6)
#define EVIL_PORTAL_TEXT_BOX_STORE_SIZE (4096)
#define UART_CH \
@@ -27,14 +30,13 @@
#define SET_AP_CMD "setap"
#define RESET_CMD "reset"
-#define EVIL_PORTAL_INDEX_EXTENSION ".html"
-#define EVIL_PORTAL_BASE_FOLDER STORAGE_APP_DATA_PATH_PREFIX
+#define HTML_EXTENSION ".html"
+#define HTML_FOLDER APP_DATA_PATH("html")
struct Evil_PortalApp {
Gui* gui;
ViewDispatcher* view_dispatcher;
SceneManager* scene_manager;
- DialogsApp* dialogs;
FuriString* portal_logs;
const char* command_queue[1];
@@ -47,6 +49,11 @@ struct Evil_PortalApp {
VariableItemList* var_item_list;
Evil_PortalUart* uart;
+ TextInput* text_input;
+ DialogsApp* dialogs;
+ FuriString* file_path;
+ Loading* loading;
+ ViewStack* view_stack;
int selected_menu_index;
int selected_option_index[NUM_MENU_ITEMS];
@@ -59,6 +66,7 @@ struct Evil_PortalApp {
bool sent_html;
bool sent_reset;
int BAUDRATE;
+ char text_store[2][128 + 1];
uint8_t* index_html;
uint8_t* ap_name;
@@ -68,4 +76,5 @@ typedef enum {
Evil_PortalAppViewVarItemList,
Evil_PortalAppViewConsoleOutput,
Evil_PortalAppViewStartPortal,
+ Evil_PortalAppViewTextInput,
} Evil_PortalAppView;
diff --git a/applications/external/evil_portal/evil_portal_custom_event.h b/applications/external/evil_portal/evil_portal_custom_event.h
index a566ca62e..a4609e00a 100644
--- a/applications/external/evil_portal/evil_portal_custom_event.h
+++ b/applications/external/evil_portal/evil_portal_custom_event.h
@@ -5,4 +5,5 @@ typedef enum {
Evil_PortalEventStartConsole,
Evil_PortalEventStartKeyboard,
Evil_PortalEventStartPortal,
+ Evil_PortalEventTextInput,
} Evil_PortalCustomEvent;
diff --git a/applications/external/evil_portal/helpers/evil_portal_storage.c b/applications/external/evil_portal/helpers/evil_portal_storage.c
index aa9a50493..22dd11dfb 100644
--- a/applications/external/evil_portal/helpers/evil_portal_storage.c
+++ b/applications/external/evil_portal/helpers/evil_portal_storage.c
@@ -8,31 +8,21 @@ static void evil_portal_close_storage() {
furi_record_close(RECORD_STORAGE);
}
-bool evil_portal_read_index_html(void* context) {
- FuriString* file_path = furi_string_alloc_set(EVIL_PORTAL_BASE_FOLDER);
-
- DialogsFileBrowserOptions browser_options;
- dialog_file_browser_set_basic_options(
- &browser_options,
- EVIL_PORTAL_INDEX_EXTENSION,
- NULL); // TODO configure icon
- browser_options.base_path = EVIL_PORTAL_BASE_FOLDER;
-
+void evil_portal_read_index_html(void* context) {
Evil_PortalApp* app = context;
- bool res = dialog_file_browser_show(app->dialogs, file_path, file_path, &browser_options);
-
- if(!res) {
- furi_string_free(file_path);
- return false;
- }
-
Storage* storage = evil_portal_open_storage();
FileInfo fi;
- if(storage_common_stat(storage, furi_string_get_cstr(file_path), &fi) == FSE_OK) {
+ if(!storage_common_exists(storage, EVIL_PORTAL_INDEX_SAVE_PATH)) {
+ FuriString* tmp = furi_string_alloc_set(EVIL_PORTAL_INDEX_DEFAULT_PATH);
+ evil_portal_replace_index_html(tmp);
+ furi_string_free(tmp);
+ }
+
+ if(storage_common_stat(storage, EVIL_PORTAL_INDEX_SAVE_PATH, &fi) == FSE_OK) {
File* index_html = storage_file_alloc(storage);
if(storage_file_open(
- index_html, furi_string_get_cstr(file_path), FSAM_READ, FSOM_OPEN_EXISTING)) {
+ index_html, EVIL_PORTAL_INDEX_SAVE_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) {
app->index_html = malloc((size_t)fi.size);
uint8_t* buf_ptr = app->index_html;
size_t read = 0;
@@ -45,7 +35,6 @@ bool evil_portal_read_index_html(void* context) {
}
free(buf_ptr);
}
- furi_string_free(file_path);
storage_file_close(index_html);
storage_file_free(index_html);
} else {
@@ -57,7 +46,33 @@ bool evil_portal_read_index_html(void* context) {
}
evil_portal_close_storage();
- return true;
+}
+
+void evil_portal_replace_index_html(FuriString* path) {
+ Storage* storage = evil_portal_open_storage();
+ FS_Error error;
+ error = storage_common_remove(storage, EVIL_PORTAL_INDEX_SAVE_PATH);
+ if(error != FSE_OK) {
+ FURI_LOG_D("EVIL PORTAL", "Error removing file");
+ } else {
+ FURI_LOG_D("EVIL PORTAL", "Error removed file");
+ }
+ error = storage_common_copy(storage, furi_string_get_cstr(path), EVIL_PORTAL_INDEX_SAVE_PATH);
+ if(error != FSE_OK) {
+ FURI_LOG_D("EVIL PORTAL", "Error copying file");
+ }
+ evil_portal_close_storage();
+}
+
+void evil_portal_create_html_folder_if_not_exists() {
+ Storage* storage = evil_portal_open_storage();
+ if(storage_common_stat(storage, HTML_FOLDER, NULL) == FSE_NOT_EXIST) {
+ FURI_LOG_D("Evil Portal", "Directory %s doesn't exist. Will create new.", HTML_FOLDER);
+ if(!storage_simply_mkdir(storage, HTML_FOLDER)) {
+ FURI_LOG_E("Evil Portal", "Error creating directory %s", HTML_FOLDER);
+ }
+ }
+ evil_portal_close_storage();
}
void evil_portal_read_ap_name(void* context) {
@@ -89,6 +104,19 @@ void evil_portal_read_ap_name(void* context) {
evil_portal_close_storage();
}
+void evil_portal_write_ap_name(void* context) {
+ Evil_PortalApp* app = context;
+ Storage* storage = evil_portal_open_storage();
+
+ File* ap_name = storage_file_alloc(storage);
+ if(storage_file_open(ap_name, EVIL_PORTAL_AP_SAVE_PATH, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
+ storage_file_write(ap_name, app->text_store[0], strlen(app->text_store[0]));
+ }
+ storage_file_close(ap_name);
+ storage_file_free(ap_name);
+ evil_portal_close_storage();
+}
+
char* sequential_file_resolve_path(
Storage* storage,
const char* dir,
diff --git a/applications/external/evil_portal/helpers/evil_portal_storage.h b/applications/external/evil_portal/helpers/evil_portal_storage.h
index d4ad33e1d..ad0b8a392 100644
--- a/applications/external/evil_portal/helpers/evil_portal_storage.h
+++ b/applications/external/evil_portal/helpers/evil_portal_storage.h
@@ -1,5 +1,4 @@
#include "../evil_portal_app_i.h"
-#include
#include
#include
#include
@@ -8,11 +7,15 @@
#define PORTAL_FILE_DIRECTORY_PATH EXT_PATH("apps_data/evil_portal")
#define EVIL_PORTAL_INDEX_SAVE_PATH PORTAL_FILE_DIRECTORY_PATH "/index.html"
+#define EVIL_PORTAL_INDEX_DEFAULT_PATH PORTAL_FILE_DIRECTORY_PATH "/html/xtreme.html"
#define EVIL_PORTAL_AP_SAVE_PATH PORTAL_FILE_DIRECTORY_PATH "/ap.config.txt"
#define EVIL_PORTAL_LOG_SAVE_PATH PORTAL_FILE_DIRECTORY_PATH "/logs"
-bool evil_portal_read_index_html(void* context);
+void evil_portal_read_index_html(void* context);
void evil_portal_read_ap_name(void* context);
+void evil_portal_write_ap_name(void* context);
+void evil_portal_replace_index_html(FuriString* path);
+void evil_portal_create_html_folder_if_not_exists();
void write_logs(FuriString* portal_logs);
char* sequential_file_resolve_path(
Storage* storage,
diff --git a/applications/external/evil_portal/scenes/evil_portal_scene_config.h b/applications/external/evil_portal/scenes/evil_portal_scene_config.h
index 94b09ae46..ffb958487 100644
--- a/applications/external/evil_portal/scenes/evil_portal_scene_config.h
+++ b/applications/external/evil_portal/scenes/evil_portal_scene_config.h
@@ -1,2 +1,4 @@
ADD_SCENE(evil_portal, start, Start)
ADD_SCENE(evil_portal, console_output, ConsoleOutput)
+ADD_SCENE(evil_portal, rename, Rename)
+ADD_SCENE(evil_portal, select_html, SelectHtml)
diff --git a/applications/external/evil_portal/scenes/evil_portal_scene_console_output.c b/applications/external/evil_portal/scenes/evil_portal_scene_console_output.c
index 94f2cef4f..19b076845 100644
--- a/applications/external/evil_portal/scenes/evil_portal_scene_console_output.c
+++ b/applications/external/evil_portal/scenes/evil_portal_scene_console_output.c
@@ -22,8 +22,6 @@ void evil_portal_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, void
void evil_portal_scene_console_output_on_enter(void* context) {
Evil_PortalApp* app = context;
- bool portal_file_set = false;
-
TextBox* text_box = app->text_box;
text_box_reset(app->text_box);
text_box_set_font(text_box, TextBoxFontText);
@@ -64,25 +62,24 @@ void evil_portal_scene_console_output_on_enter(void* context) {
}
}
- if(0 == strncmp(SET_HTML_CMD, app->selected_tx_string, strlen(SET_HTML_CMD))) {
- portal_file_set = evil_portal_read_index_html(context);
+ if(0 == strncmp("setapname", app->selected_tx_string, strlen("setapname"))) {
+ scene_manager_next_scene(app->scene_manager, Evil_PortalSceneRename);
+ return;
+ }
- if(portal_file_set) {
- app->command_queue[0] = SET_AP_CMD;
- app->has_command_queue = true;
- app->command_index = 0;
- if(app->show_stopscan_tip) {
- const char* msg = "Starting portal\nIf no response press\nBACK to return\n";
- furi_string_cat_str(app->text_box_store, msg);
- app->text_box_store_strlen += strlen(msg);
- }
- } else {
- if(app->show_stopscan_tip) {
- const char* msg = "No portal selected\nShowing current logs\nPress "
- "BACK to return\n";
- furi_string_cat_str(app->text_box_store, msg);
- app->text_box_store_strlen += strlen(msg);
- }
+ if(0 == strncmp("selecthtml", app->selected_tx_string, strlen("selecthtml"))) {
+ scene_manager_next_scene(app->scene_manager, Evil_PortalSceneSelectHtml);
+ return;
+ }
+
+ if(0 == strncmp(SET_HTML_CMD, app->selected_tx_string, strlen(SET_HTML_CMD))) {
+ app->command_queue[0] = SET_AP_CMD;
+ app->has_command_queue = true;
+ app->command_index = 0;
+ if(app->show_stopscan_tip) {
+ const char* msg = "Starting portal\nIf no response press\nBACK to return\n";
+ furi_string_cat_str(app->text_box_store, msg);
+ app->text_box_store_strlen += strlen(msg);
}
}
@@ -107,13 +104,7 @@ void evil_portal_scene_console_output_on_enter(void* context) {
if(app->is_command && app->selected_tx_string) {
if(0 == strncmp(SET_HTML_CMD, app->selected_tx_string, strlen(SET_HTML_CMD))) {
- if(!portal_file_set) {
- scene_manager_set_scene_state(
- app->scene_manager, Evil_PortalSceneConsoleOutput, 0);
- view_dispatcher_switch_to_view(
- app->view_dispatcher, Evil_PortalAppViewConsoleOutput);
- return;
- }
+ evil_portal_read_index_html(context);
FuriString* data = furi_string_alloc();
furi_string_cat(data, "sethtml=");
diff --git a/applications/external/evil_portal/scenes/evil_portal_scene_rename.c b/applications/external/evil_portal/scenes/evil_portal_scene_rename.c
new file mode 100644
index 000000000..72f3ef18c
--- /dev/null
+++ b/applications/external/evil_portal/scenes/evil_portal_scene_rename.c
@@ -0,0 +1,42 @@
+#include "../evil_portal_app_i.h"
+#include "../helpers/evil_portal_storage.h"
+
+void evil_portal_text_input_callback(void* context) {
+ furi_assert(context);
+ Evil_PortalApp* app = context;
+ view_dispatcher_send_custom_event(app->view_dispatcher, Evil_PortalEventTextInput);
+}
+
+void evil_portal_scene_rename_on_enter(void* context) {
+ Evil_PortalApp* app = context;
+ TextInput* text_input = app->text_input;
+ size_t enter_name_length = 25;
+ evil_portal_read_ap_name(app);
+ text_input_set_header_text(text_input, "AP Name/SSID");
+ strncpy(app->text_store[0], (char*)app->ap_name, enter_name_length);
+ text_input_set_result_callback(
+ text_input,
+ evil_portal_text_input_callback,
+ context,
+ app->text_store[0],
+ enter_name_length,
+ false);
+ view_dispatcher_switch_to_view(app->view_dispatcher, Evil_PortalAppViewTextInput);
+}
+
+bool evil_portal_scene_rename_on_event(void* context, SceneManagerEvent event) {
+ Evil_PortalApp* app = context;
+ SceneManager* scene_manager = app->scene_manager;
+ bool consumed = false;
+ if(event.type == SceneManagerEventTypeCustom) {
+ evil_portal_write_ap_name(app);
+ scene_manager_search_and_switch_to_previous_scene(scene_manager, Evil_PortalSceneStart);
+ consumed = true;
+ }
+ return consumed;
+}
+
+void evil_portal_scene_rename_on_exit(void* context) {
+ Evil_PortalApp* app = context;
+ variable_item_list_reset(app->var_item_list);
+}
diff --git a/applications/external/evil_portal/scenes/evil_portal_scene_select_html.c b/applications/external/evil_portal/scenes/evil_portal_scene_select_html.c
new file mode 100644
index 000000000..1dbcdd54d
--- /dev/null
+++ b/applications/external/evil_portal/scenes/evil_portal_scene_select_html.c
@@ -0,0 +1,54 @@
+#include "../evil_portal_app_i.h"
+#include "../helpers/evil_portal_storage.h"
+
+void evil_portal_show_loading_popup(Evil_PortalApp* app, bool show) {
+ TaskHandle_t timer_task = xTaskGetHandle(configTIMER_SERVICE_TASK_NAME);
+ ViewStack* view_stack = app->view_stack;
+ Loading* loading = app->loading;
+ if(show) {
+ // Raise timer priority so that animations can play
+ vTaskPrioritySet(timer_task, configMAX_PRIORITIES - 1);
+ view_stack_add_view(view_stack, loading_get_view(loading));
+ } else {
+ view_stack_remove_view(view_stack, loading_get_view(loading));
+ // Restore default timer priority
+ vTaskPrioritySet(timer_task, configTIMER_TASK_PRIORITY);
+ }
+}
+
+void evil_portal_scene_select_html_on_enter(void* context) {
+ Evil_PortalApp* app = context;
+ DialogsFileBrowserOptions browser_options;
+ evil_portal_create_html_folder_if_not_exists();
+
+ dialog_file_browser_set_basic_options(&browser_options, HTML_EXTENSION, &I_evil_portal_10px);
+ browser_options.base_path = HTML_FOLDER;
+
+ FuriString* path;
+ path = furi_string_alloc();
+
+ furi_string_set(path, HTML_FOLDER);
+
+ bool success = dialog_file_browser_show(app->dialogs, app->file_path, path, &browser_options);
+ furi_string_free(path);
+
+ if(success) {
+ //Replace HTML File
+ evil_portal_show_loading_popup(app, true);
+ evil_portal_replace_index_html(app->file_path);
+ evil_portal_show_loading_popup(app, false);
+ }
+
+ scene_manager_search_and_switch_to_previous_scene(app->scene_manager, Evil_PortalSceneStart);
+}
+
+bool evil_portal_scene_select_html_on_event(void* context, SceneManagerEvent event) {
+ UNUSED(context);
+ UNUSED(event);
+ bool consumed = true;
+ return consumed;
+}
+
+void evil_portal_scene_select_html_on_exit(void* context) {
+ UNUSED(context);
+}
diff --git a/applications/external/evil_portal/scenes/evil_portal_scene_start.c b/applications/external/evil_portal/scenes/evil_portal_scene_start.c
index 7f7200fcb..b06aedc51 100644
--- a/applications/external/evil_portal/scenes/evil_portal_scene_start.c
+++ b/applications/external/evil_portal/scenes/evil_portal_scene_start.c
@@ -33,6 +33,12 @@ const Evil_PortalItem items[NUM_MENU_ITEMS] = {
// console
{"Save logs", {""}, 1, {"savelogs"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
+ // set AP name
+ {"Set AP name", {""}, 1, {"setapname"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
+
+ // select HTML Portal File
+ {"Select HTML", {""}, 1, {"selecthtml"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
+
// help
{"Help", {""}, 1, {"help"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
};
diff --git a/applications/external/flappy_bird/application.fam b/applications/external/flappy_bird/application.fam
index ad18e57e1..625c5f66c 100644
--- a/applications/external/flappy_bird/application.fam
+++ b/applications/external/flappy_bird/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="flappy_game_app",
requires=["gui"],
stack_size=4 * 1024,
- order=100,
fap_icon="flappy_10px.png",
fap_category="Games",
fap_icon_assets="assets",
diff --git a/applications/external/flappy_bird/flappy_bird.c b/applications/external/flappy_bird/flappy_bird.c
index 3100b7c6b..496ffcf56 100644
--- a/applications/external/flappy_bird/flappy_bird.c
+++ b/applications/external/flappy_bird/flappy_bird.c
@@ -1,9 +1,11 @@
#include
-#include
+#include "flappy_bird_icons.h"
+#include
#include
#include
#include
+#include
#define TAG "Flappy"
#define DEBUG false
@@ -311,6 +313,9 @@ int32_t flappy_game_app(void* p) {
Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
+ // Call dolphin deed on game start
+ dolphin_deed(DolphinDeedPluginGameStart);
+
GameEvent event;
for(bool processing = true; processing;) {
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
diff --git a/applications/external/flashlight/application.fam b/applications/external/flashlight/application.fam
index a71258013..4ad9b6101 100644
--- a/applications/external/flashlight/application.fam
+++ b/applications/external/flashlight/application.fam
@@ -8,7 +8,6 @@ App(
"gui",
],
stack_size=2 * 1024,
- order=20,
fap_icon="flash10px.png",
fap_category="GPIO",
fap_author="@xMasterX",
diff --git a/applications/external/flipbip/application.fam b/applications/external/flipbip/application.fam
index bae1c0fb6..0831ff432 100644
--- a/applications/external/flipbip/application.fam
+++ b/applications/external/flipbip/application.fam
@@ -7,7 +7,6 @@ App(
"gui",
],
stack_size=3 * 1024,
- order=10,
fap_icon="flipbip_10px.png",
fap_private_libs=[
Lib(
diff --git a/applications/external/flipbip/icons/ButtonDown_10x5.png b/applications/external/flipbip/icons/ButtonDown_10x5.png
new file mode 100644
index 000000000..b492b926c
Binary files /dev/null and b/applications/external/flipbip/icons/ButtonDown_10x5.png differ
diff --git a/applications/external/flipbip/icons/ButtonUp_10x5.png b/applications/external/flipbip/icons/ButtonUp_10x5.png
new file mode 100644
index 000000000..5da99d01e
Binary files /dev/null and b/applications/external/flipbip/icons/ButtonUp_10x5.png differ
diff --git a/applications/external/flipper_i2ctools/application.fam b/applications/external/flipper_i2ctools/application.fam
index 128f609a1..5ed100750 100644
--- a/applications/external/flipper_i2ctools/application.fam
+++ b/applications/external/flipper_i2ctools/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="i2ctools_app",
requires=["gui"],
stack_size=2 * 1024,
- order=175,
fap_icon="i2ctools.png",
fap_category="GPIO",
fap_icon_assets="images",
diff --git a/applications/external/flipper_i2ctools/images/Voltage_16x16.png b/applications/external/flipper_i2ctools/images/Voltage_16x16.png
deleted file mode 100644
index 94e796872..000000000
Binary files a/applications/external/flipper_i2ctools/images/Voltage_16x16.png and /dev/null differ
diff --git a/applications/external/flipper_i2ctools/views/infos_view.h b/applications/external/flipper_i2ctools/views/infos_view.h
index 11b388c02..db7330483 100644
--- a/applications/external/flipper_i2ctools/views/infos_view.h
+++ b/applications/external/flipper_i2ctools/views/infos_view.h
@@ -1,7 +1,8 @@
#include
#include
#include
-#include
+#include "i2ctools_icons.h"
+#include
#define INFOS_TEXT "INFOS"
diff --git a/applications/external/flipper_i2ctools/views/main_view.h b/applications/external/flipper_i2ctools/views/main_view.h
index 6e476c6dd..878c3b2ea 100644
--- a/applications/external/flipper_i2ctools/views/main_view.h
+++ b/applications/external/flipper_i2ctools/views/main_view.h
@@ -1,7 +1,7 @@
#include
#include
#include
-#include
+#include "i2ctools_icons.h"
#include
#define APP_NAME "I2C Tools"
@@ -41,4 +41,4 @@ typedef struct {
void draw_main_view(Canvas* canvas, i2cMainView* main_view);
i2cMainView* i2c_main_view_alloc();
-void i2c_main_view_free(i2cMainView* main_view);
+void i2c_main_view_free(i2cMainView* main_view);
\ No newline at end of file
diff --git a/applications/external/flipper_i2ctools/views/scanner_view.h b/applications/external/flipper_i2ctools/views/scanner_view.h
index 9b571ed9b..0ce780d5e 100644
--- a/applications/external/flipper_i2ctools/views/scanner_view.h
+++ b/applications/external/flipper_i2ctools/views/scanner_view.h
@@ -1,10 +1,10 @@
#include
#include
#include
-#include
+#include "i2ctools_icons.h"
#include
#include "../i2cscanner.h"
#define SCAN_TEXT "SCAN"
-void draw_scanner_view(Canvas* canvas, i2cScanner* i2c_scanner);
+void draw_scanner_view(Canvas* canvas, i2cScanner* i2c_scanner);
\ No newline at end of file
diff --git a/applications/external/flipper_i2ctools/views/sender_view.h b/applications/external/flipper_i2ctools/views/sender_view.h
index 3c2000703..a1148e1f8 100644
--- a/applications/external/flipper_i2ctools/views/sender_view.h
+++ b/applications/external/flipper_i2ctools/views/sender_view.h
@@ -1,10 +1,10 @@
#include
#include
#include
-#include
+#include "i2ctools_icons.h"
#include
#include "../i2csender.h"
#define SEND_TEXT "SEND"
-void draw_sender_view(Canvas* canvas, i2cSender* i2c_sender);
+void draw_sender_view(Canvas* canvas, i2cSender* i2c_sender);
\ No newline at end of file
diff --git a/applications/external/flipper_i2ctools/views/sniffer_view.h b/applications/external/flipper_i2ctools/views/sniffer_view.h
index 1b586d568..fdb817ec3 100644
--- a/applications/external/flipper_i2ctools/views/sniffer_view.h
+++ b/applications/external/flipper_i2ctools/views/sniffer_view.h
@@ -1,10 +1,10 @@
#include
#include
#include
-#include
+#include "i2ctools_icons.h"
#include
#include "../i2csniffer.h"
#define SNIFF_TEXT "SNIFF"
-void draw_sniffer_view(Canvas* canvas, i2cSniffer* i2c_sniffer);
+void draw_sniffer_view(Canvas* canvas, i2cSniffer* i2c_sniffer);
\ No newline at end of file
diff --git a/applications/external/flizzer_tracker/application.fam b/applications/external/flizzer_tracker/application.fam
index c5b2d2cee..481e41c40 100644
--- a/applications/external/flizzer_tracker/application.fam
+++ b/applications/external/flizzer_tracker/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="flizzer_tracker_app",
cdefines=["APP_FLIZZER_TRACKER"],
stack_size=2 * 1024,
- order=90,
fap_version=(0, 2),
fap_description="An advanced Flipper Zero chiptune tracker with 4 channels",
fap_author="LTVA",
diff --git a/applications/external/flizzer_tracker/flizzer_tracker.c b/applications/external/flizzer_tracker/flizzer_tracker.c
index 2c0729a43..63f22e32a 100644
--- a/applications/external/flizzer_tracker/flizzer_tracker.c
+++ b/applications/external/flizzer_tracker/flizzer_tracker.c
@@ -7,7 +7,8 @@
#include "view/pattern_editor.h"
#include "font.h"
-#include
+#include "flizzer_tracker_icons.h"
+#include
void draw_callback(Canvas* canvas, void* ctx) {
TrackerViewModel* model = (TrackerViewModel*)ctx;
diff --git a/applications/external/flizzer_tracker/view/instrument_editor.c b/applications/external/flizzer_tracker/view/instrument_editor.c
index b931a5de5..4d5463118 100644
--- a/applications/external/flizzer_tracker/view/instrument_editor.c
+++ b/applications/external/flizzer_tracker/view/instrument_editor.c
@@ -4,7 +4,8 @@
#include "../macros.h"
#include "opcode_description.h"
-#include
+#include "flizzer_tracker_icons.h"
+#include
void draw_inst_flag(
FlizzerTrackerApp* tracker,
diff --git a/applications/external/flizzer_tracker/view/pattern_editor.c b/applications/external/flizzer_tracker/view/pattern_editor.c
index 19c62d9f9..c4effed56 100644
--- a/applications/external/flizzer_tracker/view/pattern_editor.c
+++ b/applications/external/flizzer_tracker/view/pattern_editor.c
@@ -1,7 +1,8 @@
#include "pattern_editor.h"
#include "../macros.h"
-#include
+#include "flizzer_tracker_icons.h"
+#include
#define PATTERN_EDITOR_Y ((tracker->focus == EDIT_PATTERN) ? 4 : (64 - (6 * 5) - 1))
diff --git a/applications/external/game15/application.fam b/applications/external/game15/application.fam
index d6b1e10a0..36efe4d26 100644
--- a/applications/external/game15/application.fam
+++ b/applications/external/game15/application.fam
@@ -6,7 +6,6 @@ App(
requires=["gui"],
stack_size=1 * 1024,
fap_icon="game15_10px.png",
- order=30,
fap_category="Games",
fap_author="@x27",
fap_version="1.0",
diff --git a/applications/external/game15/game15.c b/applications/external/game15/game15.c
index d5d9a3bec..3a8750d75 100644
--- a/applications/external/game15/game15.c
+++ b/applications/external/game15/game15.c
@@ -3,6 +3,7 @@
#include
#include
#include
+#include
#include "sandbox.h"
@@ -118,6 +119,7 @@ static bool storage_game_state_load() {
storage_common_migrate(storage, EXT_PATH("apps/Games/game15.save"), SAVING_FILENAME);
File* file = storage_file_alloc(storage);
+
uint16_t bytes_readed = 0;
if(storage_file_open(file, SAVING_FILENAME, FSAM_READ, FSOM_OPEN_EXISTING))
bytes_readed = storage_file_read(file, &game_state, sizeof(game_state_t));
@@ -456,6 +458,9 @@ int32_t game15_app() {
sandbox_init(
FPS, (SandboxRenderCallback)render_callback, (SandboxEventHandler)game_event_handler);
+ // Call dolphin deed on game start
+ dolphin_deed(DolphinDeedPluginGameStart);
+
sandbox_loop();
sandbox_free();
game_free();
diff --git a/applications/external/game_2048/application.fam b/applications/external/game_2048/application.fam
index 6be28fafd..d78cdfd27 100644
--- a/applications/external/game_2048/application.fam
+++ b/applications/external/game_2048/application.fam
@@ -1,4 +1,3 @@
-# PLUGIN BY eugene-kirzhanov
App(
appid="game_2048",
name="2048",
@@ -8,10 +7,9 @@ App(
"gui",
],
stack_size=1 * 1024,
- order=90,
fap_icon="game_2048.png",
fap_category="Games",
fap_author="@eugene-kirzhanov",
- fap_version="1.0",
- fap_description="2048 Game",
+ fap_version="1.1",
+ fap_description="Play the port of the 2048 game on Flipper Zero.",
)
diff --git a/applications/external/game_2048/game_2048.c b/applications/external/game_2048/game_2048.c
index 2376f6fcc..48d0200ec 100644
--- a/applications/external/game_2048/game_2048.c
+++ b/applications/external/game_2048/game_2048.c
@@ -13,6 +13,7 @@
#include
#include
#include
+#include
#include "digits.h"
#include "array_utils.h"
@@ -393,6 +394,9 @@ int32_t game_2048_app() {
Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
+ // Call dolphin deed on game start
+ dolphin_deed(DolphinDeedPluginGameStart);
+
bool is_finished = false;
while(!is_finished) {
FuriStatus event_status = furi_message_queue_get(event_queue, &input, FuriWaitForever);
diff --git a/applications/external/game_of_life/application.fam b/applications/external/game_of_life/application.fam
index 0037dbe4e..a4de9ff40 100644
--- a/applications/external/game_of_life/application.fam
+++ b/applications/external/game_of_life/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_GAMEOFLIFE_GAME"],
requires=["gui"],
stack_size=2 * 1024,
- order=110,
fap_icon="golIcon.png",
fap_category="Games",
fap_author="@tgxn (original by @itsyourbedtime)",
diff --git a/applications/external/geiger/flipper_geiger.c b/applications/external/geiger/flipper_geiger.c
index a9101a277..58ab08b0e 100644
--- a/applications/external/geiger/flipper_geiger.c
+++ b/applications/external/geiger/flipper_geiger.c
@@ -10,6 +10,7 @@
#include
#include
#include
+
#include
#include
@@ -35,48 +36,118 @@ typedef struct {
typedef struct {
FuriMutex* mutex;
uint32_t cps, cpm;
- uint32_t line[SCREEN_SIZE_X / 2];
+ uint32_t line[SCREEN_SIZE_X];
float coef;
uint8_t data;
+ uint8_t zoom;
+ uint8_t newLinePosition;
+ uint8_t version;
} mutexStruct;
static void draw_callback(Canvas* canvas, void* ctx) {
furi_assert(ctx);
- mutexStruct displayStruct;
- mutexStruct* geigerMutex = ctx;
- furi_mutex_acquire(geigerMutex->mutex, FuriWaitForever);
- memcpy(&displayStruct, geigerMutex, sizeof(mutexStruct));
- furi_mutex_release(geigerMutex->mutex);
+ mutexStruct* mutexVal = ctx;
+ mutexStruct mutexDraw;
+ furi_mutex_acquire(mutexVal->mutex, FuriWaitForever);
+ memcpy(&mutexDraw, mutexVal, sizeof(mutexStruct));
+ furi_mutex_release(mutexVal->mutex);
- char buffer[32];
- if(displayStruct.data == 0)
- snprintf(
- buffer, sizeof(buffer), "%ld cps - %ld cpm", displayStruct.cps, displayStruct.cpm);
- else if(displayStruct.data == 1)
- snprintf(
- buffer,
- sizeof(buffer),
- "%ld cps - %.2f uSv/h",
- displayStruct.cps,
- ((double)displayStruct.cpm * (double)CONVERSION_FACTOR));
- else
- snprintf(
- buffer,
- sizeof(buffer),
- "%ld cps - %.2f mSv/y",
- displayStruct.cps,
- (((double)displayStruct.cpm * (double)CONVERSION_FACTOR)) * (double)8.76);
+ if(mutexDraw.version == 0) {
+ char buffer[32];
+ if(mutexDraw.data == 0)
+ snprintf(buffer, sizeof(buffer), "%ld cps - %ld cpm", mutexDraw.cps, mutexDraw.cpm);
+ else if(mutexDraw.data == 1)
+ snprintf(
+ buffer,
+ sizeof(buffer),
+ "%ld cps - %.2f uSv/h",
+ mutexDraw.cps,
+ ((double)mutexDraw.cpm * (double)CONVERSION_FACTOR));
+ else if(mutexDraw.data == 2)
+ snprintf(
+ buffer,
+ sizeof(buffer),
+ "%ld cps - %.2f mSv/y",
+ mutexDraw.cps,
+ (((double)mutexDraw.cpm * (double)CONVERSION_FACTOR)) * (double)8.76);
+ else if(mutexDraw.data == 3)
+ snprintf(
+ buffer,
+ sizeof(buffer),
+ "%ld cps - %.4f Rad/h",
+ mutexDraw.cps,
+ ((double)mutexDraw.cpm * (double)CONVERSION_FACTOR) / (double)10000);
+ else if(mutexDraw.data == 4)
+ snprintf(
+ buffer,
+ sizeof(buffer),
+ "%ld cps - %.2f mR/h",
+ mutexDraw.cps,
+ ((double)mutexDraw.cpm * (double)CONVERSION_FACTOR) / (double)10);
+ else
+ snprintf(
+ buffer,
+ sizeof(buffer),
+ "%ld cps - %.2f uR/h",
+ mutexDraw.cps,
+ ((double)mutexDraw.cpm * (double)CONVERSION_FACTOR) * (double)100);
- for(int i = 0; i < SCREEN_SIZE_X; i += 2) {
- float Y = SCREEN_SIZE_Y - (displayStruct.line[i / 2] * displayStruct.coef);
+ canvas_set_font(canvas, FontPrimary);
+ canvas_draw_str_aligned(canvas, 64, 10, AlignCenter, AlignBottom, buffer);
- canvas_draw_line(canvas, i, Y, i, SCREEN_SIZE_Y);
- canvas_draw_line(canvas, i + 1, Y, i + 1, SCREEN_SIZE_Y);
+ uint8_t linePosition = mutexDraw.newLinePosition;
+
+ if(mutexDraw.zoom == 0) {
+ for(int i = 0; i < SCREEN_SIZE_X; i += 8) {
+ if(linePosition != 0)
+ linePosition--;
+ else
+ linePosition = SCREEN_SIZE_X - 1;
+
+ float Y = SCREEN_SIZE_Y - (mutexDraw.line[linePosition] * mutexDraw.coef);
+ for(int j = 0; j < 8; j++)
+ canvas_draw_line(canvas, i + j, Y, i + j, SCREEN_SIZE_Y);
+ }
+ } else if(mutexDraw.zoom == 1) {
+ for(int i = 0; i < SCREEN_SIZE_X; i += 4) {
+ if(linePosition != 0)
+ linePosition--;
+ else
+ linePosition = SCREEN_SIZE_X - 1;
+
+ float Y = SCREEN_SIZE_Y - (mutexDraw.line[linePosition] * mutexDraw.coef);
+ for(int j = 0; j < 4; j++)
+ canvas_draw_line(canvas, i + j, Y, i + j, SCREEN_SIZE_Y);
+ }
+ } else if(mutexDraw.zoom == 2) {
+ for(int i = 0; i < SCREEN_SIZE_X; i += 2) {
+ if(linePosition != 0)
+ linePosition--;
+ else
+ linePosition = SCREEN_SIZE_X - 1;
+
+ float Y = SCREEN_SIZE_Y - (mutexDraw.line[linePosition] * mutexDraw.coef);
+ for(int j = 0; j < 2; j++)
+ canvas_draw_line(canvas, i + j, Y, i + j, SCREEN_SIZE_Y);
+ }
+ } else if(mutexDraw.zoom == 3) {
+ for(int i = 0; i < SCREEN_SIZE_X; i++) {
+ if(linePosition != 0)
+ linePosition--;
+ else
+ linePosition = SCREEN_SIZE_X - 1;
+
+ float Y = SCREEN_SIZE_Y - (mutexDraw.line[linePosition] * mutexDraw.coef);
+ canvas_draw_line(canvas, i, Y, i, SCREEN_SIZE_Y);
+ }
+ }
+ } else {
+ canvas_set_font(canvas, FontPrimary);
+ canvas_draw_str_aligned(canvas, 64, 10, AlignCenter, AlignBottom, "Geiger Counter");
+ canvas_draw_str_aligned(canvas, 64, 20, AlignCenter, AlignBottom, "Version 20230806");
+ canvas_draw_str_aligned(canvas, 64, 40, AlignCenter, AlignBottom, "github.com/nmrr");
}
-
- canvas_set_font(canvas, FontPrimary);
- canvas_draw_str_aligned(canvas, 64, 10, AlignCenter, AlignBottom, buffer);
}
static void input_callback(InputEvent* input_event, void* ctx) {
@@ -107,8 +178,7 @@ static void gpiocallback(void* ctx) {
furi_message_queue_put(queue, &event, 0);
}
-int32_t flipper_geiger_app(void* p) {
- UNUSED(p);
+int32_t flipper_geiger_app() {
EventApp event;
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(EventApp));
@@ -118,9 +188,12 @@ int32_t flipper_geiger_app(void* p) {
mutexStruct mutexVal;
mutexVal.cps = 0;
mutexVal.cpm = 0;
- for(int i = 0; i < SCREEN_SIZE_X / 2; i++) mutexVal.line[i] = 0;
+ for(int i = 0; i < SCREEN_SIZE_X; i++) mutexVal.line[i] = 0;
mutexVal.coef = 1;
mutexVal.data = 0;
+ mutexVal.zoom = 2;
+ mutexVal.newLinePosition = 0;
+ mutexVal.version = 0;
uint32_t counter = 0;
@@ -131,7 +204,7 @@ int32_t flipper_geiger_app(void* p) {
}
ViewPort* view_port = view_port_alloc();
- view_port_draw_callback_set(view_port, draw_callback, &mutexVal);
+ view_port_draw_callback_set(view_port, draw_callback, &mutexVal.mutex);
view_port_input_callback_set(view_port, input_callback, event_queue);
furi_hal_gpio_add_int_callback(&gpio_ext_pa7, gpiocallback, event_queue);
@@ -166,15 +239,16 @@ int32_t flipper_geiger_app(void* p) {
if(event_status == FuriStatusOk) {
if(event.type == EventTypeInput) {
- if(event.input.key == InputKeyBack) {
+ if(event.input.key == InputKeyBack && event.input.type == InputTypeLong) {
break;
- } else if(event.input.key == InputKeyOk && event.input.type == InputTypeShort) {
+ } else if(event.input.key == InputKeyOk && event.input.type == InputTypeLong) {
counter = 0;
furi_mutex_acquire(mutexVal.mutex, FuriWaitForever);
mutexVal.cps = 0;
mutexVal.cpm = 0;
- for(int i = 0; i < SCREEN_SIZE_X / 2; i++) mutexVal.line[i] = 0;
+ for(uint8_t i = 0; i < SCREEN_SIZE_X; i++) mutexVal.line[i] = 0;
+ mutexVal.newLinePosition = 0;
screenRefresh = 1;
furi_mutex_release(mutexVal.mutex);
@@ -215,7 +289,7 @@ int32_t flipper_geiger_app(void* p) {
if(mutexVal.data != 0)
mutexVal.data--;
else
- mutexVal.data = 2;
+ mutexVal.data = 5;
screenRefresh = 1;
furi_mutex_release(mutexVal.mutex);
@@ -223,35 +297,61 @@ int32_t flipper_geiger_app(void* p) {
event.input.type == InputTypeShort)) {
furi_mutex_acquire(mutexVal.mutex, FuriWaitForever);
- if(mutexVal.data != 2)
+ if(mutexVal.data != 5)
mutexVal.data++;
else
mutexVal.data = 0;
+ screenRefresh = 1;
+ furi_mutex_release(mutexVal.mutex);
+ } else if((event.input.key == InputKeyUp && event.input.type == InputTypeShort)) {
+ furi_mutex_acquire(mutexVal.mutex, FuriWaitForever);
+ if(mutexVal.zoom != 0) mutexVal.zoom--;
+
+ screenRefresh = 1;
+ furi_mutex_release(mutexVal.mutex);
+
+ } else if((event.input.key == InputKeyDown &&
+ event.input.type == InputTypeShort)) {
+ furi_mutex_acquire(mutexVal.mutex, FuriWaitForever);
+ if(mutexVal.zoom != 3) mutexVal.zoom++;
+
+ screenRefresh = 1;
+ furi_mutex_release(mutexVal.mutex);
+ } else if((event.input.key == InputKeyDown && event.input.type == InputTypeLong)) {
+ furi_mutex_acquire(mutexVal.mutex, FuriWaitForever);
+ if(mutexVal.version == 0)
+ mutexVal.version = 1;
+ else
+ mutexVal.version = 0;
+
screenRefresh = 1;
furi_mutex_release(mutexVal.mutex);
}
} else if(event.type == ClockEventTypeTick) {
- furi_mutex_acquire(mutexVal.mutex, FuriWaitForever);
-
if(recordData == 1) {
furi_string_printf(dataString, "%lu,%lu\n", epoch++, counter);
stream_write_string(file_stream, dataString);
}
- for(int i = 0; i < SCREEN_SIZE_X / 2 - 1; i++)
- mutexVal.line[SCREEN_SIZE_X / 2 - 1 - i] =
- mutexVal.line[SCREEN_SIZE_X / 2 - 2 - i];
+ furi_mutex_acquire(mutexVal.mutex, FuriWaitForever);
- mutexVal.line[0] = counter;
+ mutexVal.line[mutexVal.newLinePosition] = counter;
mutexVal.cps = counter;
counter = 0;
- mutexVal.cpm = mutexVal.line[0];
- uint32_t max = mutexVal.line[0];
- for(int i = 1; i < SCREEN_SIZE_X / 2; i++) {
- if(i < 60) mutexVal.cpm += mutexVal.line[i];
- if(mutexVal.line[i] > max) max = mutexVal.line[i];
+ mutexVal.cpm = mutexVal.line[mutexVal.newLinePosition];
+ uint32_t max = mutexVal.line[mutexVal.newLinePosition];
+ uint8_t linePosition = mutexVal.newLinePosition;
+
+ for(int i = 1; i < SCREEN_SIZE_X; i++) {
+ if(linePosition != 0)
+ linePosition--;
+ else
+ linePosition = SCREEN_SIZE_X - 1;
+
+ if(i < 60) mutexVal.cpm += mutexVal.line[linePosition];
+ if(mutexVal.line[linePosition] > max) max = mutexVal.line[linePosition];
}
if(max > 0)
@@ -259,6 +359,11 @@ int32_t flipper_geiger_app(void* p) {
else
mutexVal.coef = 1;
+ if(mutexVal.newLinePosition != SCREEN_SIZE_X - 1)
+ mutexVal.newLinePosition++;
+ else
+ mutexVal.newLinePosition = 0;
+
screenRefresh = 1;
furi_mutex_release(mutexVal.mutex);
} else if(event.type == EventGPIO) {
diff --git a/applications/external/gpioreader_b/application.fam b/applications/external/gpioreader_b/application.fam
index 29fe701b6..3e38301ba 100644
--- a/applications/external/gpioreader_b/application.fam
+++ b/applications/external/gpioreader_b/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="gpio_app",
requires=["gui"],
stack_size=1 * 1024,
- order=50,
fap_category="GPIO",
fap_icon="icon.png",
fap_icon_assets="icons",
diff --git a/applications/external/gps_nmea_uart/application.fam b/applications/external/gps_nmea_uart/application.fam
index c3897e38a..1bc46d535 100644
--- a/applications/external/gps_nmea_uart/application.fam
+++ b/applications/external/gps_nmea_uart/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="gps_app",
requires=["gui"],
stack_size=1 * 1024,
- order=35,
fap_icon="gps_10px.png",
fap_category="GPIO",
fap_author="@ezod & @xMasterX",
diff --git a/applications/external/hc_sr04/application.fam b/applications/external/hc_sr04/application.fam
index 7bbbaa5be..cbe135194 100644
--- a/applications/external/hc_sr04/application.fam
+++ b/applications/external/hc_sr04/application.fam
@@ -7,7 +7,6 @@ App(
"gui",
],
stack_size=2 * 1024,
- order=20,
fap_icon="dist_sensor10px.png",
fap_category="GPIO",
fap_author="@xMasterX (first implementation by @Sanqui)",
diff --git a/applications/external/heap_defence_game/heap_defence.c b/applications/external/heap_defence_game/heap_defence.c
index daf910404..111c22dce 100644
--- a/applications/external/heap_defence_game/heap_defence.c
+++ b/applications/external/heap_defence_game/heap_defence.c
@@ -14,6 +14,7 @@
#include
#include
#include
+#include
#define Y_FIELD_SIZE 6
#define Y_LAST (Y_FIELD_SIZE - 1)
@@ -532,6 +533,9 @@ int32_t heap_defence_app(void* p) {
game->game_status = 0;
game->animation = AnimationPause;
+ // Call dolphin deed on game start
+ dolphin_deed(DolphinDeedPluginGameStart);
+
GameEvent event = {0};
while(event.input.key != InputKeyBack) {
if(furi_message_queue_get(event_queue, &event, 100) != FuriStatusOk) {
diff --git a/applications/external/hex_editor/application.fam b/applications/external/hex_editor/application.fam
index fa7c3f13e..8f8d8c26e 100644
--- a/applications/external/hex_editor/application.fam
+++ b/applications/external/hex_editor/application.fam
@@ -9,7 +9,6 @@ App(
"dialogs",
],
stack_size=2 * 1024,
- order=20,
fap_icon="icons/edit_10px.png",
fap_category="Tools",
fap_icon_assets="icons",
diff --git a/applications/external/hex_viewer/application.fam b/applications/external/hex_viewer/application.fam
index be8a7a0dd..821eead69 100644
--- a/applications/external/hex_viewer/application.fam
+++ b/applications/external/hex_viewer/application.fam
@@ -8,11 +8,10 @@ App(
"dialogs",
],
stack_size=2 * 1024,
- order=20,
fap_icon="icons/hex_10px.png",
fap_category="Tools",
fap_icon_assets="icons",
fap_author="@QtRoS",
- fap_version="1.0",
+ fap_version="1.1",
fap_description="App allows to view various files as HEX.",
)
diff --git a/applications/external/hex_viewer/hex_viewer.c b/applications/external/hex_viewer/hex_viewer.c
index 58fedb341..b98f2d867 100644
--- a/applications/external/hex_viewer/hex_viewer.c
+++ b/applications/external/hex_viewer/hex_viewer.c
@@ -1,7 +1,8 @@
#include
#include
-#include
+#include "hex_viewer_icons.h"
+#include
#include
#include
#include
@@ -163,7 +164,7 @@ static bool hex_viewer_open_file(HexViewer* hex_viewer, const char* file_path) {
FURI_LOG_E(TAG, "Unable to open stream: %s", file_path);
isOk = false;
break;
- }
+ };
hex_viewer->model->file_size = stream_size(hex_viewer->model->stream);
} while(false);
diff --git a/applications/external/hid_app/hid.h b/applications/external/hid_app/hid.h
index 2b5a8059b..c21d3e265 100644
--- a/applications/external/hid_app/hid.h
+++ b/applications/external/hid_app/hid.h
@@ -25,9 +25,6 @@
#include "views/hid_tikshorts.h"
#include "views/hid_mouse_clicker.h"
-#include "hid_icons.h"
-#include
-
#include "hid_path.h"
typedef enum {
diff --git a/applications/external/hid_app/views/hid_keyboard.c b/applications/external/hid_app/views/hid_keyboard.c
index 1c1525ec9..c41c53797 100644
--- a/applications/external/hid_app/views/hid_keyboard.c
+++ b/applications/external/hid_app/views/hid_keyboard.c
@@ -3,6 +3,8 @@
#include
#include
#include "../hid.h"
+#include "hid_icons.h"
+#include
#define TAG "HidKeyboard"
diff --git a/applications/external/hid_app/views/hid_keynote.c b/applications/external/hid_app/views/hid_keynote.c
index e3d5f7a99..ce21bc56b 100644
--- a/applications/external/hid_app/views/hid_keynote.c
+++ b/applications/external/hid_app/views/hid_keynote.c
@@ -2,6 +2,9 @@
#include
#include "../hid.h"
+#include "hid_icons.h"
+#include
+
#define TAG "HidKeynote"
struct HidKeynote {
diff --git a/applications/external/hid_app/views/hid_media.c b/applications/external/hid_app/views/hid_media.c
index caf854eb1..037f251fe 100644
--- a/applications/external/hid_app/views/hid_media.c
+++ b/applications/external/hid_app/views/hid_media.c
@@ -5,6 +5,9 @@
#include
#include "../hid.h"
+#include "hid_icons.h"
+#include
+
#define TAG "HidMedia"
struct HidMedia {
diff --git a/applications/external/hid_app/views/hid_mouse.c b/applications/external/hid_app/views/hid_mouse.c
index 4c4737155..3fd364ef9 100644
--- a/applications/external/hid_app/views/hid_mouse.c
+++ b/applications/external/hid_app/views/hid_mouse.c
@@ -2,6 +2,9 @@
#include
#include "../hid.h"
+#include "hid_icons.h"
+#include
+
#define TAG "HidMouse"
struct HidMouse {
diff --git a/applications/external/hid_app/views/hid_mouse_clicker.c b/applications/external/hid_app/views/hid_mouse_clicker.c
index 6777034ff..b0269738e 100644
--- a/applications/external/hid_app/views/hid_mouse_clicker.c
+++ b/applications/external/hid_app/views/hid_mouse_clicker.c
@@ -2,6 +2,9 @@
#include
#include "../hid.h"
+#include "hid_icons.h"
+#include
+
#define TAG "HidMouseClicker"
#define DEFAULT_CLICK_RATE 1
#define MAXIMUM_CLICK_RATE 60
diff --git a/applications/external/hid_app/views/hid_mouse_jiggler.c b/applications/external/hid_app/views/hid_mouse_jiggler.c
index c2ff93f60..bc71b7da6 100644
--- a/applications/external/hid_app/views/hid_mouse_jiggler.c
+++ b/applications/external/hid_app/views/hid_mouse_jiggler.c
@@ -2,6 +2,9 @@
#include
#include "../hid.h"
+#include "hid_icons.h"
+#include
+
#define TAG "HidMouseJiggler"
struct HidMouseJiggler {
diff --git a/applications/external/hid_app/views/hid_numpad.c b/applications/external/hid_app/views/hid_numpad.c
index b342bb38d..1d0c62769 100644
--- a/applications/external/hid_app/views/hid_numpad.c
+++ b/applications/external/hid_app/views/hid_numpad.c
@@ -3,6 +3,8 @@
#include
#include
#include "../hid.h"
+#include "hid_icons.h"
+#include
#define TAG "HidNumpad"
diff --git a/applications/external/hid_app/views/hid_tikshorts.c b/applications/external/hid_app/views/hid_tikshorts.c
index 78e7488f3..6796b3ca6 100644
--- a/applications/external/hid_app/views/hid_tikshorts.c
+++ b/applications/external/hid_app/views/hid_tikshorts.c
@@ -2,6 +2,9 @@
#include "../hid.h"
#include
+#include "hid_icons.h"
+#include
+
#define TAG "HidTikShorts"
struct HidTikShorts {
diff --git a/applications/external/ifttt/application.fam b/applications/external/ifttt/application.fam
index 1a86000a4..2f8871e03 100644
--- a/applications/external/ifttt/application.fam
+++ b/applications/external/ifttt/application.fam
@@ -8,7 +8,6 @@ App(
"gui",
],
stack_size=2 * 1024,
- order=20,
fap_icon="icon.png",
fap_category="WiFi",
)
diff --git a/applications/external/ir_scope/application.fam b/applications/external/ir_scope/application.fam
index 00e161d97..ceaa629f7 100644
--- a/applications/external/ir_scope/application.fam
+++ b/applications/external/ir_scope/application.fam
@@ -3,12 +3,11 @@ App(
name="IR Scope",
apptype=FlipperAppType.EXTERNAL,
entry_point="ir_scope_app",
- cdefines=["APP_IR_SCOPE"],
requires=["gui"],
stack_size=2 * 1024,
fap_icon="ir_scope.png",
fap_category="Infrared",
fap_author="@kallanreed",
- fap_version="1.0",
+ fap_version="1.2",
fap_description="App allows to see incoming IR signals.",
)
diff --git a/applications/external/jetpack_joyride/application.fam b/applications/external/jetpack_joyride/application.fam
index 1b98e11ce..bb4eaa8fb 100644
--- a/applications/external/jetpack_joyride/application.fam
+++ b/applications/external/jetpack_joyride/application.fam
@@ -8,7 +8,6 @@ App(
cdefines=["APP_JETPACK_GAME"],
requires=["gui"],
stack_size=4 * 1024,
- order=100,
fap_icon="icon.png",
fap_category="Games",
fap_icon_assets="assets",
diff --git a/applications/external/jetpack_joyride/includes/background_assets.h b/applications/external/jetpack_joyride/includes/background_assets.h
index d42fcfd71..21721f03c 100644
--- a/applications/external/jetpack_joyride/includes/background_assets.h
+++ b/applications/external/jetpack_joyride/includes/background_assets.h
@@ -9,7 +9,8 @@
#include "point.h"
#include "states.h"
#include "game_sprites.h"
-#include
+#include "jetpack_joyride_icons.h"
+#include
#define BG_ASSETS_MAX 3
diff --git a/applications/external/jetpack_joyride/includes/coin.c b/applications/external/jetpack_joyride/includes/coin.c
index 7a3811a8c..485e55f1b 100644
--- a/applications/external/jetpack_joyride/includes/coin.c
+++ b/applications/external/jetpack_joyride/includes/coin.c
@@ -1,7 +1,8 @@
#include
#include
-#include
+#include "jetpack_joyride_icons.h"
+#include
#include
#include "coin.h"
diff --git a/applications/external/jetpack_joyride/includes/missile.c b/applications/external/jetpack_joyride/includes/missile.c
index af47e8478..8302973a5 100644
--- a/applications/external/jetpack_joyride/includes/missile.c
+++ b/applications/external/jetpack_joyride/includes/missile.c
@@ -1,7 +1,8 @@
#include
#include
-#include
+#include "jetpack_joyride_icons.h"
+#include
#include
#include "states.h"
diff --git a/applications/external/jetpack_joyride/includes/scientist.c b/applications/external/jetpack_joyride/includes/scientist.c
index b1a8a14c0..d831b78db 100644
--- a/applications/external/jetpack_joyride/includes/scientist.c
+++ b/applications/external/jetpack_joyride/includes/scientist.c
@@ -1,7 +1,8 @@
#include "scientist.h"
#include "game_sprites.h"
-#include
+#include "jetpack_joyride_icons.h"
+#include
#include
void scientist_tick(SCIENTIST* const scientists) {
diff --git a/applications/external/jetpack_joyride/jetpack.c b/applications/external/jetpack_joyride/jetpack.c
index 7969300bd..37443ee90 100644
--- a/applications/external/jetpack_joyride/jetpack.c
+++ b/applications/external/jetpack_joyride/jetpack.c
@@ -1,6 +1,7 @@
#include
-#include
+#include "jetpack_joyride_icons.h"
+#include
#include
#include
#include
@@ -370,4 +371,4 @@ free_and_exit:
furi_message_queue_free(event_queue);
return return_code;
-}
+}
\ No newline at end of file
diff --git a/applications/external/lightmeter/application.fam b/applications/external/lightmeter/application.fam
index a1ad9fd0e..83e14b543 100644
--- a/applications/external/lightmeter/application.fam
+++ b/applications/external/lightmeter/application.fam
@@ -7,7 +7,6 @@ App(
"gui",
],
stack_size=4 * 1024,
- order=90,
fap_version=(1, 2),
fap_icon="lightmeter.png",
fap_category="GPIO",
diff --git a/applications/external/lightmeter/docs/README.md b/applications/external/lightmeter/docs/README.md
deleted file mode 100644
index e90630c03..000000000
--- a/applications/external/lightmeter/docs/README.md
+++ /dev/null
@@ -1,17 +0,0 @@
-## Lightmeter app for photography
-
-An application that suggests settings for your manual camera based on the reading of the ambient light sensor. Can also be used in a pure lux meter mode.
-
-## Supported sensors
-
-- BH1750
-- MAX44009
-
-## Wiring
-
-| Sensor | Flipper Zero |
-| ------ | ------------ |
-| VCC | 3.3V |
-| GND | GND |
-| SCL | C0 |
-| SDA | C1 |
diff --git a/applications/external/magspoof/application.fam b/applications/external/magspoof/application.fam
index 7a9ad7c60..dd764c584 100644
--- a/applications/external/magspoof/application.fam
+++ b/applications/external/magspoof/application.fam
@@ -10,12 +10,11 @@ App(
"dialogs",
],
stack_size=6 * 1024,
- order=64, # keep it at the bottom of the list while still WIP
fap_icon="icons/mag_10px.png",
fap_category="GPIO",
fap_icon_assets="icons",
fap_version=(0, 5), # major, minor
fap_description="WIP MagSpoof port using the RFID subsystem",
fap_author="Zachary Weiss",
- fap_weburl="https://github.com/hummusec/magspoof_flipper", # Original by zacharyweiss
+ fap_weburl="https://github.com/zacharyweiss/magspoof_flipper",
)
diff --git a/applications/external/magspoof/helpers/mag_helpers.c b/applications/external/magspoof/helpers/mag_helpers.c
index 1f7c2ae20..89c451f62 100644
--- a/applications/external/magspoof/helpers/mag_helpers.c
+++ b/applications/external/magspoof/helpers/mag_helpers.c
@@ -153,7 +153,6 @@ void tx_deinit_rfid() {
furi_hal_gpio_write(RFID_PIN_OUT, 0);
furi_hal_rfid_pins_reset();
- furi_hal_power_disable_otg();
}
void tx_init_rf(int hz) {
@@ -187,7 +186,6 @@ bool tx_init(MagSetting* setting) {
tx_init_rfid();
break;
case MagTxStateGPIO:
- furi_hal_power_enable_otg();
// gpio_item_configure_all_pins(GpioModeOutputPushPull);
furi_hal_gpio_init(GPIO_PIN_A, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_init(GPIO_PIN_B, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
@@ -238,7 +236,6 @@ bool tx_deinit(MagSetting* setting) {
furi_hal_gpio_init(GPIO_PIN_ENABLE, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
//gpio_item_configure_all_pins(GpioModeAnalog);
- furi_hal_power_disable_otg();
break;
case MagTxStatePiezo:
tx_deinit_piezo();
diff --git a/applications/external/magspoof/mag.c b/applications/external/magspoof/mag.c
index 6d8bfa3c3..8c821b994 100644
--- a/applications/external/magspoof/mag.c
+++ b/applications/external/magspoof/mag.c
@@ -168,16 +168,39 @@ int32_t mag_app(void* p) {
Mag* mag = mag_alloc();
UNUSED(p);
+ mag_make_app_folder(mag);
+
+ // Enable 5v power, multiple attempts to avoid issues with power chip protection false triggering
+ uint8_t attempts = 0;
+ bool otg_was_enabled = furi_hal_power_is_otg_enabled();
+ while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
+ furi_hal_power_enable_otg();
+ furi_delay_ms(10);
+ }
+
view_dispatcher_attach_to_gui(mag->view_dispatcher, mag->gui, ViewDispatcherTypeFullscreen);
scene_manager_next_scene(mag->scene_manager, MagSceneStart);
view_dispatcher_run(mag->view_dispatcher);
+ // Disable 5v power
+ if(furi_hal_power_is_otg_enabled() && !otg_was_enabled) {
+ furi_hal_power_disable_otg();
+ }
+
mag_free(mag);
return 0;
}
+void mag_make_app_folder(Mag* mag) {
+ furi_assert(mag);
+
+ if(!storage_simply_mkdir(mag->storage, MAG_APP_FOLDER)) {
+ dialog_message_show_storage_error(mag->dialogs, "Cannot create\napp folder");
+ }
+}
+
void mag_text_store_set(Mag* mag, const char* text, ...) {
furi_assert(mag);
va_list args;
diff --git a/applications/external/magspoof/mag_device.c b/applications/external/magspoof/mag_device.c
index 77e8c2e83..f3be3a5ff 100644
--- a/applications/external/magspoof/mag_device.c
+++ b/applications/external/magspoof/mag_device.c
@@ -76,6 +76,8 @@ static bool mag_device_save_file(
// Make path to file to be saved
furi_string_cat_printf(temp_str, "/%s%s", dev_name, extension);
} else {
+ // Create mag directory if necessary
+ if(!storage_simply_mkdir((mag_dev->storage), MAG_APP_FOLDER)) break;
// First remove mag device file if it was saved
furi_string_printf(temp_str, "%s/%s%s", folder, dev_name, extension);
}
diff --git a/applications/external/magspoof/mag_i.h b/applications/external/magspoof/mag_i.h
index af6735cca..a57c26e15 100644
--- a/applications/external/magspoof/mag_i.h
+++ b/applications/external/magspoof/mag_i.h
@@ -92,6 +92,8 @@ void mag_text_store_clear(Mag* mag);
void mag_show_loading_popup(void* context, bool show);
+void mag_make_app_folder(Mag* mag);
+
void mag_popup_timeout_callback(void* context);
void mag_widget_callback(GuiButtonType result, InputType type, void* context);
diff --git a/applications/external/mandelbrot/application.fam b/applications/external/mandelbrot/application.fam
index b5a3f4ccc..7c476ced8 100644
--- a/applications/external/mandelbrot/application.fam
+++ b/applications/external/mandelbrot/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_MANDELBROT_GAME"],
requires=["gui"],
stack_size=1 * 1024,
- order=130,
fap_icon="Mandelbrot.png",
fap_category="Media",
fap_author="@Possibly-Matt",
diff --git a/applications/external/mass_storage/application.fam b/applications/external/mass_storage/application.fam
index 96cd28aec..66d18422c 100644
--- a/applications/external/mass_storage/application.fam
+++ b/applications/external/mass_storage/application.fam
@@ -9,6 +9,7 @@ App(
],
stack_size=2 * 1024,
fap_description="Implements a mass storage device over USB for disk images",
+ fap_version="1.2",
fap_icon="assets/mass_storage_10px.png",
fap_icon_assets="assets",
fap_category="USB",
diff --git a/applications/external/metronome/application.fam b/applications/external/metronome/application.fam
index e6439db7b..b5a87a236 100644
--- a/applications/external/metronome/application.fam
+++ b/applications/external/metronome/application.fam
@@ -8,8 +8,8 @@ App(
],
fap_icon="metronome_icon.png",
fap_category="Media",
+ fap_icon_assets="images",
stack_size=2 * 1024,
- order=20,
fap_author="@panki27 & @xMasterX",
fap_version="1.0",
fap_description="Metronome app",
diff --git a/applications/external/metronome/gui_extensions.c b/applications/external/metronome/gui_extensions.c
index 18494098e..4c7ad2252 100644
--- a/applications/external/metronome/gui_extensions.c
+++ b/applications/external/metronome/gui_extensions.c
@@ -1,5 +1,6 @@
#include
#include
+#include "metronome_icons.h"
#include
//lib can only do bottom left/right
diff --git a/applications/external/metronome/metronome.c b/applications/external/metronome/metronome.c
index 46231d66d..a01f4418d 100644
--- a/applications/external/metronome/metronome.c
+++ b/applications/external/metronome/metronome.c
@@ -178,7 +178,7 @@ static void timer_callback(void* ctx) {
case Silent:
break;
}
- }
+ };
// this is a bit of a kludge... if we are on vibro and unpronounced, stop vibro after half the usual duration
switch(metronome_state->output_mode) {
diff --git a/applications/external/mfkey32/application.fam b/applications/external/mfkey32/application.fam
index 33d932ce9..4d8b3b062 100644
--- a/applications/external/mfkey32/application.fam
+++ b/applications/external/mfkey32/application.fam
@@ -9,9 +9,11 @@ App(
"storage",
],
stack_size=1 * 1024,
- fap_icon="images/mfkey.png",
+ fap_description="Mf Classic key finder",
+ fap_version="1.0",
+ fap_icon="mfkey.png",
fap_category="NFC",
- fap_author="noproto",
+ fap_author="@noproto",
fap_icon_assets="images",
fap_weburl="https://github.com/noproto/FlipperMfkey",
)
diff --git a/applications/external/mfkey32/mfkey.png b/applications/external/mfkey32/mfkey.png
new file mode 100644
index 000000000..52ab29efb
Binary files /dev/null and b/applications/external/mfkey32/mfkey.png differ
diff --git a/applications/external/mfkey32/mfkey32.c b/applications/external/mfkey32/mfkey32.c
index 5e790b01f..fc4c9db26 100644
--- a/applications/external/mfkey32/mfkey32.c
+++ b/applications/external/mfkey32/mfkey32.c
@@ -13,6 +13,7 @@
#include
#include
#include "mfkey32_icons.h"
+#include
#include
#include
#include
diff --git a/applications/external/mifare_fuzzer/application.fam b/applications/external/mifare_fuzzer/application.fam
index c90212286..5d02b9235 100644
--- a/applications/external/mifare_fuzzer/application.fam
+++ b/applications/external/mifare_fuzzer/application.fam
@@ -8,7 +8,6 @@ App(
"gui",
],
stack_size=4 * 1024,
- order=30,
fap_icon="images/mifare_fuzzer_10px.png",
fap_category="NFC",
fap_icon_assets="images",
diff --git a/applications/external/mifare_nested/application.fam b/applications/external/mifare_nested/application.fam
index b8e2aa0dd..a06f7d7ec 100644
--- a/applications/external/mifare_nested/application.fam
+++ b/applications/external/mifare_nested/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="mifare_nested_app",
requires=["storage", "gui", "nfc"],
stack_size=4 * 1024,
- order=30,
fap_icon="assets/icon.png",
fap_category="NFC",
fap_private_libs=[Lib(name="nested"), Lib(name="parity"), Lib(name="crypto1")],
diff --git a/applications/external/mifare_nested/mifare_nested_i.h b/applications/external/mifare_nested/mifare_nested_i.h
index b13a6c098..324328b44 100644
--- a/applications/external/mifare_nested/mifare_nested_i.h
+++ b/applications/external/mifare_nested/mifare_nested_i.h
@@ -20,6 +20,7 @@
#include
#include
#include "mifare_nested_icons.h"
+#include
#define NESTED_VERSION_APP "1.5.2"
#define NESTED_GITHUB_LINK "https://github.com/AloneLiberty/FlipperNested"
diff --git a/applications/external/minesweeper/application.fam b/applications/external/minesweeper/application.fam
index 07b3e97bb..891bd7801 100644
--- a/applications/external/minesweeper/application.fam
+++ b/applications/external/minesweeper/application.fam
@@ -7,7 +7,6 @@ App(
stack_size=8 * 1024,
fap_category="Games",
fap_icon="minesweeper_icon.png",
- order=35,
fap_author="@panki27 & @xMasterX",
fap_version="1.0",
fap_description="Minesweeper Game",
diff --git a/applications/external/minesweeper/minesweeper.c b/applications/external/minesweeper/minesweeper.c
index 41fca2b0a..4e92fba33 100644
--- a/applications/external/minesweeper/minesweeper.c
+++ b/applications/external/minesweeper/minesweeper.c
@@ -7,6 +7,8 @@
#include
#include
+#include
+
#include "assets.h"
#define PLAYFIELD_WIDTH 16
@@ -236,6 +238,9 @@ static bool game_won(Minesweeper* minesweeper_state) {
message, furi_string_get_cstr(tempStr), 64, 32, AlignCenter, AlignCenter);
dialog_message_set_buttons(message, NULL, "Play again", NULL);
+ // Call dolphin deed when we win the game
+ dolphin_deed(DolphinDeedPluginGameWin);
+
DialogMessageButton choice = dialog_message_show(minesweeper_state->dialogs, message);
dialog_message_free(message);
furi_string_free(tempStr);
@@ -390,6 +395,9 @@ int32_t minesweeper_app(void* p) {
Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
+ // Call dolphin deed on game start
+ dolphin_deed(DolphinDeedPluginGameStart);
+
PluginEvent event;
for(bool processing = true; processing;) {
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
diff --git a/applications/external/morse_code/application.fam b/applications/external/morse_code/application.fam
index d46b34628..d39f4738c 100644
--- a/applications/external/morse_code/application.fam
+++ b/applications/external/morse_code/application.fam
@@ -7,7 +7,6 @@ App(
"gui",
],
stack_size=1 * 1024,
- order=20,
fap_icon="morse_code_10px.png",
fap_category="Media",
fap_author="@wh00hw & @xMasterX",
diff --git a/applications/external/multi_converter/application.fam b/applications/external/multi_converter/application.fam
index 6844c73b3..51d1c0798 100644
--- a/applications/external/multi_converter/application.fam
+++ b/applications/external/multi_converter/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="multi_converter_app",
requires=["gui"],
stack_size=1 * 1024,
- order=160,
fap_icon="converter_10px.png",
fap_category="Tools",
fap_author="@theisolinearchip",
diff --git a/applications/external/multi_dice/application.fam b/applications/external/multi_dice/application.fam
index 15f5fe820..6bca3167a 100644
--- a/applications/external/multi_dice/application.fam
+++ b/applications/external/multi_dice/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_DICE"],
requires=["gui"],
stack_size=2 * 1024,
- order=70,
fap_icon="dice.png",
fap_category="Games",
)
diff --git a/applications/external/music_beeper/application.fam b/applications/external/music_beeper/application.fam
index a15af7e32..24a592c4a 100644
--- a/applications/external/music_beeper/application.fam
+++ b/applications/external/music_beeper/application.fam
@@ -3,14 +3,11 @@ App(
name="Music Beeper",
apptype=FlipperAppType.EXTERNAL,
entry_point="music_beeper_app",
- cdefines=["APP_MUSIC_BEEPER"],
requires=[
"gui",
"dialogs",
],
- provides=["music_beeper_start"],
stack_size=2 * 1024,
- order=45,
fap_icon="music_10px.png",
fap_icon_assets="icons",
fap_category="Media",
diff --git a/applications/external/music_player/application.fam b/applications/external/music_player/application.fam
index 4d0858494..24ccb9a70 100644
--- a/applications/external/music_player/application.fam
+++ b/applications/external/music_player/application.fam
@@ -8,8 +8,8 @@ App(
"dialogs",
],
stack_size=2 * 1024,
- order=45,
fap_icon="music_10px.png",
fap_category="Media",
+ fap_icon_assets="icons",
fap_libs=["music_worker"],
)
diff --git a/applications/external/music_player/music_player.c b/applications/external/music_player/music_player.c
index 181eb60d6..aaec81346 100644
--- a/applications/external/music_player/music_player.c
+++ b/applications/external/music_player/music_player.c
@@ -3,6 +3,7 @@
#include
#include
+#include "music_player_icons.h"
#include
#include
#include
diff --git a/applications/external/music_tracker/application.fam b/applications/external/music_tracker/application.fam
index 6c78a9bf6..5aba35cd3 100644
--- a/applications/external/music_tracker/application.fam
+++ b/applications/external/music_tracker/application.fam
@@ -7,7 +7,6 @@ App(
"gui",
],
stack_size=4 * 1024,
- order=20,
fap_icon="zero_tracker.png",
fap_category="Media",
fap_author="@DrZlo13",
diff --git a/applications/external/nfc_magic/application.fam b/applications/external/nfc_magic/application.fam
index 83a148f21..01c6dfaa8 100644
--- a/applications/external/nfc_magic/application.fam
+++ b/applications/external/nfc_magic/application.fam
@@ -9,7 +9,6 @@ App(
"gui",
],
stack_size=4 * 1024,
- order=30,
fap_icon="Nfc_10px.png",
fap_category="NFC",
fap_private_libs=[
diff --git a/applications/external/nfc_rfid_detector/application.fam b/applications/external/nfc_rfid_detector/application.fam
index 70c91bc84..ffed6967a 100644
--- a/applications/external/nfc_rfid_detector/application.fam
+++ b/applications/external/nfc_rfid_detector/application.fam
@@ -6,8 +6,10 @@ App(
entry_point="nfc_rfid_detector_app",
requires=["gui"],
stack_size=4 * 1024,
- order=50,
+ fap_description="Identify the reader type: NFC (13 MHz) and/or RFID (125 KHz).",
+ fap_version="1.0",
fap_icon="nfc_rfid_detector_10px.png",
fap_category="Tools",
fap_icon_assets="images",
+ fap_author="SkorP",
)
diff --git a/applications/external/nfc_rfid_detector/views/nfc_rfid_detector_view_field_presence.c b/applications/external/nfc_rfid_detector/views/nfc_rfid_detector_view_field_presence.c
index faf253977..cf8ca936c 100644
--- a/applications/external/nfc_rfid_detector/views/nfc_rfid_detector_view_field_presence.c
+++ b/applications/external/nfc_rfid_detector/views/nfc_rfid_detector_view_field_presence.c
@@ -1,6 +1,6 @@
#include "nfc_rfid_detector_view_field_presence.h"
#include "../nfc_rfid_detector_app_i.h"
-#include
+#include "nfc_rfid_detector_icons.h"
#include
#include
diff --git a/applications/external/nightstand/application.fam b/applications/external/nightstand/application.fam
index e94e24cf2..380c34b16 100644
--- a/applications/external/nightstand/application.fam
+++ b/applications/external/nightstand/application.fam
@@ -7,7 +7,6 @@ App(
stack_size=2 * 1024,
fap_icon="clock.png",
fap_category="Tools",
- order=81,
fap_author="@nymda & @Willy-JL",
fap_weburl="https://github.com/nymda/FlipperNightStand",
fap_version="1.0",
diff --git a/applications/external/nrf24batch/application.fam b/applications/external/nrf24batch/application.fam
index ff8e5546e..aff3ffd30 100644
--- a/applications/external/nrf24batch/application.fam
+++ b/applications/external/nrf24batch/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_NRF24BATCH"],
requires=["gui"],
stack_size=2 * 1024,
- order=60,
fap_icon="nrf24batch_10px.png",
fap_category="GPIO",
fap_private_libs=[
diff --git a/applications/external/nrf24batch/lib/nrf24/nrf24.c b/applications/external/nrf24batch/lib/nrf24/nrf24.c
index be1b6ddc0..e074860ed 100644
--- a/applications/external/nrf24batch/lib/nrf24/nrf24.c
+++ b/applications/external/nrf24batch/lib/nrf24/nrf24.c
@@ -381,4 +381,4 @@ uint8_t nrf24_set_mac(uint8_t mac_addr, uint8_t* mac, uint8_t mlen) {
uint8_t addr[5];
for(int i = 0; i < mlen; i++) addr[i] = mac[mlen - i - 1];
return nrf24_write_buf_reg(nrf24_HANDLE, mac_addr, addr, mlen);
-}
\ No newline at end of file
+}
diff --git a/applications/external/nrf24batch/lib/nrf24/nrf24.h b/applications/external/nrf24batch/lib/nrf24/nrf24.h
index 5e6657caf..605513d4b 100644
--- a/applications/external/nrf24batch/lib/nrf24/nrf24.h
+++ b/applications/external/nrf24batch/lib/nrf24/nrf24.h
@@ -389,4 +389,4 @@ uint32_t bytes_to_int32(uint8_t* bytes, bool bigendian);
#ifdef __cplusplus
}
-#endif
\ No newline at end of file
+#endif
diff --git a/applications/external/nrf24batch/nrf24batch.c b/applications/external/nrf24batch/nrf24batch.c
index 81225fd2b..1eb90c3c2 100644
--- a/applications/external/nrf24batch/nrf24batch.c
+++ b/applications/external/nrf24batch/nrf24batch.c
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include
#include
diff --git a/applications/external/nrf24channelscanner/application.fam b/applications/external/nrf24channelscanner/application.fam
index af773a1f0..3a7e9bf8c 100644
--- a/applications/external/nrf24channelscanner/application.fam
+++ b/applications/external/nrf24channelscanner/application.fam
@@ -1,6 +1,6 @@
App(
appid="nrf24channelscanner",
- name="[NRF24] Channel scanner",
+ name="[NRF24] Channel Scanner",
apptype=FlipperAppType.EXTERNAL,
entry_point="nrf24channelscanner_main",
stack_size=2 * 1024,
diff --git a/applications/external/nrf24channelscanner/images/Ok_btn_9x9.png b/applications/external/nrf24channelscanner/images/Ok_btn_9x9.png
deleted file mode 100644
index 978ec1e83..000000000
Binary files a/applications/external/nrf24channelscanner/images/Ok_btn_9x9.png and /dev/null differ
diff --git a/applications/external/nrf24channelscanner/images/Pin_back_arrow_10x8.png b/applications/external/nrf24channelscanner/images/Pin_back_arrow_10x8.png
deleted file mode 100644
index e46cc5834..000000000
Binary files a/applications/external/nrf24channelscanner/images/Pin_back_arrow_10x8.png and /dev/null differ
diff --git a/applications/external/nrf24channelscanner/lib/nrf24/nrf24.c b/applications/external/nrf24channelscanner/lib/nrf24/nrf24.c
index 611a5dbda..2307d6daf 100644
--- a/applications/external/nrf24channelscanner/lib/nrf24/nrf24.c
+++ b/applications/external/nrf24channelscanner/lib/nrf24/nrf24.c
@@ -114,4 +114,4 @@ bool nrf24_check_connected(FuriHalSpiBusHandle* handle) {
} else {
return false;
}
-}
\ No newline at end of file
+}
diff --git a/applications/external/nrf24channelscanner/lib/nrf24/nrf24.h b/applications/external/nrf24channelscanner/lib/nrf24/nrf24.h
index cd1bab2f1..fdbdb0e3f 100644
--- a/applications/external/nrf24channelscanner/lib/nrf24/nrf24.h
+++ b/applications/external/nrf24channelscanner/lib/nrf24/nrf24.h
@@ -126,4 +126,4 @@ bool nrf24_check_connected(FuriHalSpiBusHandle* handle);
#ifdef __cplusplus
}
-#endif
\ No newline at end of file
+#endif
diff --git a/applications/external/nrf24channelscanner/nrf24channelscanner.c b/applications/external/nrf24channelscanner/nrf24channelscanner.c
index 39749e77a..cfe64bd32 100644
--- a/applications/external/nrf24channelscanner/nrf24channelscanner.c
+++ b/applications/external/nrf24channelscanner/nrf24channelscanner.c
@@ -7,6 +7,7 @@
#include
#include
#include "nrf24channelscanner_icons.h"
+#include
const uint8_t num_channels = 128;
static uint8_t nrf24values[128] = {0}; //to store channel data
diff --git a/applications/external/nrf24mousejacker/application.fam b/applications/external/nrf24mousejacker/application.fam
index f5a9b9dbc..30de60b5d 100644
--- a/applications/external/nrf24mousejacker/application.fam
+++ b/applications/external/nrf24mousejacker/application.fam
@@ -8,12 +8,12 @@ App(
"dialogs",
],
stack_size=2 * 1024,
- order=60,
fap_icon="mouse_10px.png",
fap_category="GPIO",
fap_author="@mothball187 & @xMasterX",
fap_version="1.0",
fap_description="App works with NRF24 Sniffer app to perform mousejack attacks",
+ fap_icon_assets="images",
fap_private_libs=[
Lib(
name="nrf24",
diff --git a/applications/external/nrf24mousejacker/lib/nrf24/nrf24.h b/applications/external/nrf24mousejacker/lib/nrf24/nrf24.h
index c61aafffb..58dbad0c8 100644
--- a/applications/external/nrf24mousejacker/lib/nrf24/nrf24.h
+++ b/applications/external/nrf24mousejacker/lib/nrf24/nrf24.h
@@ -373,4 +373,4 @@ bool nrf24_check_connected(FuriHalSpiBusHandle* handle);
#ifdef __cplusplus
}
-#endif
\ No newline at end of file
+#endif
diff --git a/applications/external/nrf24mousejacker/mousejacker.c b/applications/external/nrf24mousejacker/mousejacker.c
index 8f2914c62..02d91f788 100644
--- a/applications/external/nrf24mousejacker/mousejacker.c
+++ b/applications/external/nrf24mousejacker/mousejacker.c
@@ -11,6 +11,7 @@
#include
#include
#include "mousejacker_ducky.h"
+#include "nrf24mousejacker_icons.h"
#include
#define TAG "mousejacker"
diff --git a/applications/external/nrf24scan/application.fam b/applications/external/nrf24scan/application.fam
index 1be252f7c..5ad617ad4 100644
--- a/applications/external/nrf24scan/application.fam
+++ b/applications/external/nrf24scan/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_NRF24SCAN"],
requires=["gui"],
stack_size=2 * 1024,
- order=60,
fap_icon="nrf24scan_10px.png",
fap_category="GPIO",
fap_private_libs=[
diff --git a/applications/external/nrf24scan/lib/nrf24/nrf24.c b/applications/external/nrf24scan/lib/nrf24/nrf24.c
index 284541426..acd0130c7 100644
--- a/applications/external/nrf24scan/lib/nrf24/nrf24.c
+++ b/applications/external/nrf24scan/lib/nrf24/nrf24.c
@@ -553,4 +553,4 @@ uint8_t nrf24_set_mac(uint8_t mac_addr, uint8_t* mac, uint8_t mlen) {
uint8_t addr[5];
for(int i = 0; i < mlen; i++) addr[i] = mac[mlen - i - 1];
return nrf24_write_buf_reg(nrf24_HANDLE, mac_addr, addr, mlen);
-}
\ No newline at end of file
+}
diff --git a/applications/external/nrf24scan/lib/nrf24/nrf24.h b/applications/external/nrf24scan/lib/nrf24/nrf24.h
index d077f1da3..d5fdced3b 100644
--- a/applications/external/nrf24scan/lib/nrf24/nrf24.h
+++ b/applications/external/nrf24scan/lib/nrf24/nrf24.h
@@ -384,4 +384,4 @@ uint32_t bytes_to_int32(uint8_t* bytes, bool bigendian);
#ifdef __cplusplus
}
-#endif
\ No newline at end of file
+#endif
diff --git a/applications/external/nrf24scan/nrf24scan.c b/applications/external/nrf24scan/nrf24scan.c
index d56ee332e..1a60ce36d 100644
--- a/applications/external/nrf24scan/nrf24scan.c
+++ b/applications/external/nrf24scan/nrf24scan.c
@@ -9,6 +9,7 @@
#include
#include
#include
+#include
#include
#include
diff --git a/applications/external/nrf24sniff/application.fam b/applications/external/nrf24sniff/application.fam
index 244677e38..98be7d06e 100644
--- a/applications/external/nrf24sniff/application.fam
+++ b/applications/external/nrf24sniff/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="nrfsniff_app",
requires=["gui"],
stack_size=2 * 1024,
- order=60,
fap_icon="nrfsniff_10px.png",
fap_category="GPIO",
fap_author="@mothball187 & @xMasterX",
diff --git a/applications/external/nrf24sniff/lib/nrf24/nrf24.c b/applications/external/nrf24sniff/lib/nrf24/nrf24.c
index d85196e86..8b39cf5eb 100644
--- a/applications/external/nrf24sniff/lib/nrf24/nrf24.c
+++ b/applications/external/nrf24sniff/lib/nrf24/nrf24.c
@@ -543,4 +543,4 @@ bool nrf24_check_connected(FuriHalSpiBusHandle* handle) {
} else {
return false;
}
-}
\ No newline at end of file
+}
diff --git a/applications/external/nrf24sniff/lib/nrf24/nrf24.h b/applications/external/nrf24sniff/lib/nrf24/nrf24.h
index c61aafffb..58dbad0c8 100644
--- a/applications/external/nrf24sniff/lib/nrf24/nrf24.h
+++ b/applications/external/nrf24sniff/lib/nrf24/nrf24.h
@@ -373,4 +373,4 @@ bool nrf24_check_connected(FuriHalSpiBusHandle* handle);
#ifdef __cplusplus
}
-#endif
\ No newline at end of file
+#endif
diff --git a/applications/external/nrf24sniff/nrfsniff.c b/applications/external/nrf24sniff/nrfsniff.c
index 1b761aacb..bc58602ff 100644
--- a/applications/external/nrf24sniff/nrfsniff.c
+++ b/applications/external/nrf24sniff/nrfsniff.c
@@ -10,7 +10,7 @@
#define LOGITECH_MAX_CHANNEL 85
#define COUNT_THRESHOLD 2
-#define DEFAULT_SAMPLE_TIME 4000
+#define DEFAULT_SAMPLE_TIME 8000
#define MAX_ADDRS 100
#define MAX_CONFIRMED 32
@@ -350,10 +350,6 @@ int32_t nrfsniff_app(void* p) {
storage_common_migrate(storage, EXT_PATH("nrfsniff"), NRFSNIFF_APP_PATH_FOLDER);
storage_common_mkdir(storage, NRFSNIFF_APP_PATH_FOLDER);
- while(!furi_hal_speaker_acquire(100)) {
- furi_delay_ms(100);
- }
-
PluginEvent event;
for(bool processing = true; processing;) {
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
@@ -459,7 +455,6 @@ int32_t nrfsniff_app(void* p) {
target_rate = 8; // rate can be either 8 (2Mbps) or 0 (1Mbps)
sniffing_state = false;
nrf24_deinit();
- furi_hal_speaker_release();
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
furi_record_close(RECORD_GUI);
diff --git a/applications/external/ocarina/application.fam b/applications/external/ocarina/application.fam
index 552adfdeb..572aa1679 100644
--- a/applications/external/ocarina/application.fam
+++ b/applications/external/ocarina/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_OCARINA"],
requires=["gui"],
stack_size=1 * 1024,
- order=30,
fap_icon="music_10px.png",
fap_category="Media",
fap_icon_assets="icons",
diff --git a/applications/external/orgasmotron/application.fam b/applications/external/orgasmotron/application.fam
index b4c191a8a..f58a4a734 100644
--- a/applications/external/orgasmotron/application.fam
+++ b/applications/external/orgasmotron/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["ORGASMOTRON"],
requires=["gui"],
stack_size=1 * 1024,
- order=20,
fap_icon="orgasmotron_10px.png",
fap_category="Tools",
)
diff --git a/applications/external/paint/application.fam b/applications/external/paint/application.fam
index a6f154bac..e5dec6040 100644
--- a/applications/external/paint/application.fam
+++ b/applications/external/paint/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_PAINT"],
requires=["gui"],
stack_size=2 * 1024,
- order=175,
fap_icon="paintIcon.png",
fap_category="Media",
fap_author="@n-o-T-I-n-s-a-n-e",
diff --git a/applications/external/picopass/application.fam b/applications/external/picopass/application.fam
index b14427f2e..896d3cf74 100644
--- a/applications/external/picopass/application.fam
+++ b/applications/external/picopass/application.fam
@@ -1,6 +1,6 @@
App(
appid="picopass",
- name="PicoPass",
+ name="[iClass] PicoPass",
apptype=FlipperAppType.EXTERNAL,
targets=["f7"],
entry_point="picopass_app",
@@ -9,7 +9,8 @@ App(
"gui",
],
stack_size=4 * 1024,
- order=30,
+ fap_description="App to communicate with NFC tags using the PicoPass(iClass) format",
+ fap_version="1.2",
fap_icon="125_10px.png",
fap_category="NFC",
fap_libs=["mbedtls"],
@@ -18,4 +19,6 @@ App(
name="loclass",
),
],
+ fap_icon_assets="icons",
+ fap_file_assets="files",
)
diff --git a/applications/external/picopass/files/iclass_elite_dict.txt b/applications/external/picopass/files/iclass_elite_dict.txt
new file mode 100644
index 000000000..908889aec
--- /dev/null
+++ b/applications/external/picopass/files/iclass_elite_dict.txt
@@ -0,0 +1,41 @@
+
+## From https://github.com/RfidResearchGroup/proxmark3/blob/master/client/dictionaries/iclass_default_keys.dic
+
+# key1/Kc from PicoPass 2k documentation
+7665544332211000
+# SAGEM
+0123456789ABCDEF
+# PicoPass Default Exchange Key
+5CBCF1DA45D5FB4F
+# From HID multiclassSE reader
+31ad7ebd2f282168
+# From pastebin: https://pastebin.com/uHqpjiuU
+6EFD46EFCBB3C875
+E033CA419AEE43F9
+
+# default picopass KD / Page 0 / Book 1
+FDCB5A52EA8F3090
+237FF9079863DF44
+5ADC25FB27181D32
+83B881F2936B2E49
+43644E61EE866BA5
+897034143D016080
+82D17B44C0122963
+4895CA7DE65E2025
+DADAD4C57BE271B7
+E41E9EDEF5719ABF
+293D275EC3AF9C7F
+C3C169251B8A70FB
+F41DAF58B20C8B91
+28877A609EC0DD2B
+66584C91EE80D5E5
+C1B74D7478053AE2
+
+# default iCLASS RFIDeas
+6B65797374726B72
+
+# CTF key
+5C100DF7042EAE64
+
+# iCopy-X DRM key (iCE product)
+2020666666668888
diff --git a/applications/external/picopass/files/iclass_standard_dict.txt b/applications/external/picopass/files/iclass_standard_dict.txt
new file mode 100644
index 000000000..46808ef60
--- /dev/null
+++ b/applications/external/picopass/files/iclass_standard_dict.txt
@@ -0,0 +1,47 @@
+
+## From https://github.com/RfidResearchGroup/proxmark3/blob/master/client/dictionaries/iclass_default_keys.dic
+
+# AA1
+AEA684A6DAB23278
+# key1/Kc from PicoPass 2k documentation
+7665544332211000
+# SAGEM
+0123456789ABCDEF
+# from loclass demo file.
+5b7c62c491c11b39
+# Kd from PicoPass 2k documentation
+F0E1D2C3B4A59687
+# PicoPass Default Exchange Key
+5CBCF1DA45D5FB4F
+# From HID multiclassSE reader
+31ad7ebd2f282168
+# From pastebin: https://pastebin.com/uHqpjiuU
+6EFD46EFCBB3C875
+E033CA419AEE43F9
+
+# iCopy-x DRM keys
+# iCL tags
+2020666666668888
+# iCS tags reversed from the SOs
+6666202066668888
+
+# default picopass KD / Page 0 / Book 1
+FDCB5A52EA8F3090
+237FF9079863DF44
+5ADC25FB27181D32
+83B881F2936B2E49
+43644E61EE866BA5
+897034143D016080
+82D17B44C0122963
+4895CA7DE65E2025
+DADAD4C57BE271B7
+E41E9EDEF5719ABF
+293D275EC3AF9C7F
+C3C169251B8A70FB
+F41DAF58B20C8B91
+28877A609EC0DD2B
+66584C91EE80D5E5
+C1B74D7478053AE2
+
+# default iCLASS RFIDeas
+6B65797374726B72
diff --git a/applications/external/picopass/helpers/iclass_elite_dict.c b/applications/external/picopass/helpers/iclass_elite_dict.c
index f92dce0aa..5f0f41f85 100644
--- a/applications/external/picopass/helpers/iclass_elite_dict.c
+++ b/applications/external/picopass/helpers/iclass_elite_dict.c
@@ -3,9 +3,9 @@
#include
#include
-#define ICLASS_ELITE_DICT_FLIPPER_NAME APP_DATA_PATH("assets/iclass_elite_dict.txt")
+#define ICLASS_ELITE_DICT_FLIPPER_NAME APP_ASSETS_PATH("iclass_elite_dict.txt")
+#define ICLASS_STANDARD_DICT_FLIPPER_NAME APP_ASSETS_PATH("iclass_standard_dict.txt")
#define ICLASS_ELITE_DICT_USER_NAME APP_DATA_PATH("assets/iclass_elite_dict_user.txt")
-#define ICLASS_STANDARD_DICT_FLIPPER_NAME APP_DATA_PATH("assets/iclass_standard_dict.txt")
#define TAG "IclassEliteDict"
diff --git a/applications/external/picopass/picopass.c b/applications/external/picopass/picopass.c
index 8b55342ed..13f6ae5fb 100644
--- a/applications/external/picopass/picopass.c
+++ b/applications/external/picopass/picopass.c
@@ -68,6 +68,13 @@ Picopass* picopass_alloc() {
PicopassViewTextInput,
text_input_get_view(picopass->text_input));
+ // Byte Input
+ picopass->byte_input = byte_input_alloc();
+ view_dispatcher_add_view(
+ picopass->view_dispatcher,
+ PicopassViewByteInput,
+ byte_input_get_view(picopass->byte_input));
+
// Custom Widget
picopass->widget = widget_alloc();
view_dispatcher_add_view(
@@ -109,6 +116,10 @@ void picopass_free(Picopass* picopass) {
view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewTextInput);
text_input_free(picopass->text_input);
+ // ByteInput
+ view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewByteInput);
+ byte_input_free(picopass->byte_input);
+
// Custom Widget
view_dispatcher_remove_view(picopass->view_dispatcher, PicopassViewWidget);
widget_free(picopass->widget);
diff --git a/applications/external/picopass/picopass_device.c b/applications/external/picopass/picopass_device.c
index 3502f253e..dbb9b9e1b 100644
--- a/applications/external/picopass/picopass_device.c
+++ b/applications/external/picopass/picopass_device.c
@@ -2,6 +2,7 @@
#include
#include
+#include "picopass_icons.h"
#include
#define TAG "PicopassDevice"
@@ -356,8 +357,8 @@ ReturnCode picopass_device_parse_credential(PicopassBlock* AA1, PicopassPacs* pa
return ERR_NONE;
}
-ReturnCode picopass_device_parse_wiegand(uint8_t* data, PicopassWiegandRecord* record) {
- uint32_t* halves = (uint32_t*)data;
+ReturnCode picopass_device_parse_wiegand(uint8_t* credential, PicopassWiegandRecord* record) {
+ uint32_t* halves = (uint32_t*)credential;
if(halves[0] == 0) {
uint8_t leading0s = __builtin_clz(REVERSE_BYTES_U32(halves[1]));
record->bitLength = 31 - leading0s;
@@ -367,8 +368,16 @@ ReturnCode picopass_device_parse_wiegand(uint8_t* data, PicopassWiegandRecord* r
}
FURI_LOG_D(TAG, "bitLength: %d", record->bitLength);
+ // Remove sentinel bit from credential. Byteswapping to handle array of bytes vs 64bit value
+ uint64_t sentinel = __builtin_bswap64(1ULL << record->bitLength);
+ uint64_t swapped = 0;
+ memcpy(&swapped, credential, sizeof(uint64_t));
+ swapped = swapped ^ sentinel;
+ memcpy(credential, &swapped, sizeof(uint64_t));
+ FURI_LOG_D(TAG, "PACS: (%d) %016llx", record->bitLength, swapped);
+
if(record->bitLength == 26) {
- uint8_t* v4 = data + 4;
+ uint8_t* v4 = credential + 4;
uint32_t bot = v4[3] | (v4[2] << 8) | (v4[1] << 16) | (v4[0] << 24);
record->CardNumber = (bot >> 1) & 0xFFFF;
diff --git a/applications/external/picopass/picopass_i.h b/applications/external/picopass/picopass_i.h
index 88c2140ee..0fc928610 100644
--- a/applications/external/picopass/picopass_i.h
+++ b/applications/external/picopass/picopass_i.h
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
#include
#include
@@ -26,6 +27,7 @@
#include
#include
+#include "picopass_icons.h"
#include
#define PICOPASS_TEXT_STORE_SIZE 128
@@ -60,12 +62,14 @@ struct Picopass {
char text_store[PICOPASS_TEXT_STORE_SIZE + 1];
FuriString* text_box_store;
+ uint8_t byte_input_store[RFAL_PICOPASS_BLOCK_LEN];
// Common Views
Submenu* submenu;
Popup* popup;
Loading* loading;
TextInput* text_input;
+ ByteInput* byte_input;
Widget* widget;
DictAttack* dict_attack;
Loclass* loclass;
@@ -76,6 +80,7 @@ typedef enum {
PicopassViewPopup,
PicopassViewLoading,
PicopassViewTextInput,
+ PicopassViewByteInput,
PicopassViewWidget,
PicopassViewDictAttack,
PicopassViewLoclass,
diff --git a/applications/external/picopass/picopass_worker.c b/applications/external/picopass/picopass_worker.c
index 25ba7ebba..a0aac6231 100644
--- a/applications/external/picopass/picopass_worker.c
+++ b/applications/external/picopass/picopass_worker.c
@@ -21,8 +21,8 @@ static const uint8_t loclass_csns[LOCLASS_NUM_CSNS][RFAL_PICOPASS_BLOCK_LEN] = {
};
static void picopass_worker_enable_field() {
- furi_hal_nfc_ll_txrx_on();
furi_hal_nfc_exit_sleep();
+ furi_hal_nfc_ll_txrx_on();
furi_hal_nfc_ll_poll();
}
@@ -130,7 +130,7 @@ ReturnCode picopass_detect_card(int timeout) {
err = rfalPicoPassPollerCheckPresence();
if(err != ERR_RF_COLLISION) {
- //FURI_LOG_E(TAG, "rfalPicoPassPollerCheckPresence error %d", err);
+ FURI_LOG_E(TAG, "rfalPicoPassPollerCheckPresence error %d", err);
return err;
}
@@ -1057,7 +1057,9 @@ static void picopass_emu_handle_packet(
if(memcmp(nfcv_data->frame + 5, rmac, 4)) {
// Bad MAC from reader, do not send a response.
FURI_LOG_I(TAG, "Got bad MAC from reader");
+#ifndef PICOPASS_DEBUG_IGNORE_BAD_RMAC
return;
+#endif
}
// CHIPRESPONSE(4)
@@ -1196,6 +1198,8 @@ static void picopass_emu_handle_packet(
}
void picopass_worker_emulate(PicopassWorker* picopass_worker, bool loclass_mode) {
+ furi_hal_nfc_exit_sleep();
+
FuriHalNfcTxRxContext tx_rx = {};
PicopassEmulatorCtx emu_ctx = {
.state = PicopassEmulatorStateIdle,
diff --git a/applications/external/picopass/rfal_picopass.c b/applications/external/picopass/rfal_picopass.c
index 983a11eab..1d45a48dc 100644
--- a/applications/external/picopass/rfal_picopass.c
+++ b/applications/external/picopass/rfal_picopass.c
@@ -47,7 +47,7 @@ FuriHalNfcReturn rfalPicoPassPollerInitialize(void) {
FuriHalNfcModePollPicopass, FuriHalNfcBitrate26p48, FuriHalNfcBitrate26p48);
if(ret != FuriHalNfcReturnOk) {
return ret;
- }
+ };
furi_hal_nfc_ll_set_error_handling(FuriHalNfcErrorHandlingNfc);
furi_hal_nfc_ll_set_guard_time(FURI_HAL_NFC_LL_GT_PICOPASS);
diff --git a/applications/external/picopass/scenes/picopass_scene_card_menu.c b/applications/external/picopass/scenes/picopass_scene_card_menu.c
index fe63f7c86..fa4515db3 100644
--- a/applications/external/picopass/scenes/picopass_scene_card_menu.c
+++ b/applications/external/picopass/scenes/picopass_scene_card_menu.c
@@ -4,6 +4,8 @@ enum SubmenuIndex {
SubmenuIndexSave,
SubmenuIndexSaveAsLF,
SubmenuIndexChangeKey,
+ SubmenuIndexWrite,
+ SubmenuIndexEmulate,
};
void picopass_scene_card_menu_submenu_callback(void* context, uint32_t index) {
@@ -26,6 +28,14 @@ void picopass_scene_card_menu_on_enter(void* context) {
picopass_scene_card_menu_submenu_callback,
picopass);
}
+ submenu_add_item(
+ submenu, "Write", SubmenuIndexWrite, picopass_scene_card_menu_submenu_callback, picopass);
+ submenu_add_item(
+ submenu,
+ "Emulate",
+ SubmenuIndexEmulate,
+ picopass_scene_card_menu_submenu_callback,
+ picopass);
submenu_add_item(
submenu,
"Change Key",
@@ -57,6 +67,12 @@ bool picopass_scene_card_menu_on_event(void* context, SceneManagerEvent event) {
picopass->dev->format = PicopassDeviceSaveFormatLF;
scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName);
consumed = true;
+ } else if(event.event == SubmenuIndexWrite) {
+ scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteCard);
+ consumed = true;
+ } else if(event.event == SubmenuIndexEmulate) {
+ scene_manager_next_scene(picopass->scene_manager, PicopassSceneEmulate);
+ consumed = true;
} else if(event.event == SubmenuIndexChangeKey) {
scene_manager_set_scene_state(
picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexChangeKey);
diff --git a/applications/external/picopass/scenes/picopass_scene_config.h b/applications/external/picopass/scenes/picopass_scene_config.h
index 6156ed689..3241c2344 100644
--- a/applications/external/picopass/scenes/picopass_scene_config.h
+++ b/applications/external/picopass/scenes/picopass_scene_config.h
@@ -11,9 +11,11 @@ ADD_SCENE(picopass, delete, Delete)
ADD_SCENE(picopass, delete_success, DeleteSuccess)
ADD_SCENE(picopass, write_card, WriteCard)
ADD_SCENE(picopass, write_card_success, WriteCardSuccess)
+ADD_SCENE(picopass, write_card_failure, WriteCardFailure)
ADD_SCENE(picopass, read_factory_success, ReadFactorySuccess)
ADD_SCENE(picopass, write_key, WriteKey)
ADD_SCENE(picopass, key_menu, KeyMenu)
ADD_SCENE(picopass, elite_dict_attack, EliteDictAttack)
ADD_SCENE(picopass, emulate, Emulate)
ADD_SCENE(picopass, loclass, Loclass)
+ADD_SCENE(picopass, key_input, KeyInput)
diff --git a/applications/external/picopass/scenes/picopass_scene_device_info.c b/applications/external/picopass/scenes/picopass_scene_device_info.c
index 41d0bad81..60ed6ed94 100644
--- a/applications/external/picopass/scenes/picopass_scene_device_info.c
+++ b/applications/external/picopass/scenes/picopass_scene_device_info.c
@@ -17,7 +17,6 @@ void picopass_scene_device_info_on_enter(void* context) {
FuriString* csn_str = furi_string_alloc_set("CSN:");
FuriString* credential_str = furi_string_alloc();
FuriString* wiegand_str = furi_string_alloc();
- FuriString* sio_str = furi_string_alloc();
dolphin_deed(DolphinDeedNfcReadSuccess);
@@ -43,7 +42,7 @@ void picopass_scene_device_info_on_enter(void* context) {
}
furi_string_set(credential_str, "");
for(uint8_t i = RFAL_PICOPASS_BLOCK_LEN - bytesLength; i < RFAL_PICOPASS_BLOCK_LEN; i++) {
- furi_string_cat_printf(credential_str, " %02X", pacs->credential[i]);
+ furi_string_cat_printf(credential_str, "%02X", pacs->credential[i]);
}
if(pacs->record.valid) {
@@ -54,7 +53,7 @@ void picopass_scene_device_info_on_enter(void* context) {
}
if(pacs->sio) {
- furi_string_cat_printf(sio_str, "+SIO");
+ furi_string_cat_printf(credential_str, " +SIO");
}
}
@@ -70,13 +69,10 @@ void picopass_scene_device_info_on_enter(void* context) {
AlignCenter,
FontSecondary,
furi_string_get_cstr(credential_str));
- widget_add_string_element(
- widget, 64, 46, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(sio_str));
furi_string_free(csn_str);
furi_string_free(credential_str);
furi_string_free(wiegand_str);
- furi_string_free(sio_str);
widget_add_button_element(
picopass->widget,
diff --git a/applications/external/picopass/scenes/picopass_scene_key_input.c b/applications/external/picopass/scenes/picopass_scene_key_input.c
new file mode 100644
index 000000000..97db46653
--- /dev/null
+++ b/applications/external/picopass/scenes/picopass_scene_key_input.c
@@ -0,0 +1,48 @@
+#include "../picopass_i.h"
+#include
+#include
+#include
+
+void picopass_scene_key_input_text_input_callback(void* context) {
+ Picopass* picopass = context;
+
+ picopass->dev->dev_data.pacs.elite_kdf = true;
+ memcpy(picopass->dev->dev_data.pacs.key, picopass->byte_input_store, RFAL_PICOPASS_BLOCK_LEN);
+ view_dispatcher_send_custom_event(picopass->view_dispatcher, PicopassCustomEventByteInputDone);
+}
+
+void picopass_scene_key_input_on_enter(void* context) {
+ Picopass* picopass = context;
+
+ ByteInput* byte_input = picopass->byte_input;
+ byte_input_set_header_text(byte_input, "Enter The Key In Hex");
+ byte_input_set_result_callback(
+ byte_input,
+ picopass_scene_key_input_text_input_callback,
+ NULL,
+ picopass,
+ picopass->byte_input_store,
+ RFAL_PICOPASS_BLOCK_LEN);
+ view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewByteInput);
+}
+
+bool picopass_scene_key_input_on_event(void* context, SceneManagerEvent event) {
+ Picopass* picopass = context;
+ bool consumed = false;
+
+ if(event.type == SceneManagerEventTypeCustom) {
+ if(event.event == PicopassCustomEventByteInputDone) {
+ scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteKey);
+ consumed = true;
+ }
+ }
+ return consumed;
+}
+
+void picopass_scene_key_input_on_exit(void* context) {
+ Picopass* picopass = context;
+
+ // Clear view
+ byte_input_set_result_callback(picopass->byte_input, NULL, NULL, NULL, NULL, 0);
+ byte_input_set_header_text(picopass->byte_input, "");
+}
diff --git a/applications/external/picopass/scenes/picopass_scene_key_menu.c b/applications/external/picopass/scenes/picopass_scene_key_menu.c
index 08adffed2..21d8a526d 100644
--- a/applications/external/picopass/scenes/picopass_scene_key_menu.c
+++ b/applications/external/picopass/scenes/picopass_scene_key_menu.c
@@ -6,7 +6,7 @@ enum SubmenuIndex {
SubmenuIndexWriteiCE,
SubmenuIndexWriteiCL,
SubmenuIndexWriteiCS,
- SubmenuIndexWriteCustom, //TODO: user input of key
+ SubmenuIndexWriteCustom,
};
void picopass_scene_key_menu_submenu_callback(void* context, uint32_t index) {
@@ -43,6 +43,12 @@ void picopass_scene_key_menu_on_enter(void* context) {
SubmenuIndexWriteiCS,
picopass_scene_key_menu_submenu_callback,
picopass);
+ submenu_add_item(
+ submenu,
+ "Write Elite",
+ SubmenuIndexWriteCustom,
+ picopass_scene_key_menu_submenu_callback,
+ picopass);
submenu_set_selected_item(
picopass->submenu,
@@ -84,6 +90,12 @@ bool picopass_scene_key_menu_on_event(void* context, SceneManagerEvent event) {
picopass->dev->dev_data.pacs.elite_kdf = false;
scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteKey);
consumed = true;
+ } else if(event.event == SubmenuIndexWriteCustom) {
+ scene_manager_set_scene_state(
+ picopass->scene_manager, PicopassSceneKeyMenu, SubmenuIndexWriteCustom);
+ // Key and elite_kdf = true are both set in key_input scene
+ scene_manager_next_scene(picopass->scene_manager, PicopassSceneKeyInput);
+ consumed = true;
}
} else if(event.type == SceneManagerEventTypeBack) {
consumed = scene_manager_search_and_switch_to_previous_scene(
diff --git a/applications/external/picopass/scenes/picopass_scene_read_card_success.c b/applications/external/picopass/scenes/picopass_scene_read_card_success.c
index 2f80cd7b9..adcdaded3 100644
--- a/applications/external/picopass/scenes/picopass_scene_read_card_success.c
+++ b/applications/external/picopass/scenes/picopass_scene_read_card_success.c
@@ -19,7 +19,7 @@ void picopass_scene_read_card_success_on_enter(void* context) {
FuriString* csn_str = furi_string_alloc_set("CSN:");
FuriString* credential_str = furi_string_alloc();
FuriString* wiegand_str = furi_string_alloc();
- FuriString* sio_str = furi_string_alloc();
+ FuriString* key_str = furi_string_alloc();
dolphin_deed(DolphinDeedNfcReadSuccess);
@@ -79,7 +79,7 @@ void picopass_scene_read_card_success_on_enter(void* context) {
size_t bytesLength = 1 + pacs->record.bitLength / 8;
furi_string_set(credential_str, "");
for(uint8_t i = RFAL_PICOPASS_BLOCK_LEN - bytesLength; i < RFAL_PICOPASS_BLOCK_LEN; i++) {
- furi_string_cat_printf(credential_str, " %02X", pacs->credential[i]);
+ furi_string_cat_printf(credential_str, "%02X", pacs->credential[i]);
}
if(pacs->record.valid) {
@@ -90,19 +90,16 @@ void picopass_scene_read_card_success_on_enter(void* context) {
}
if(pacs->sio) {
- furi_string_cat_printf(sio_str, "+SIO");
+ furi_string_cat_printf(credential_str, " +SIO");
}
if(pacs->key) {
- if(pacs->sio) {
- furi_string_cat_printf(sio_str, " ");
- }
- furi_string_cat_printf(sio_str, "Key: ");
+ furi_string_cat_printf(key_str, "Key: ");
uint8_t key[RFAL_PICOPASS_BLOCK_LEN];
memcpy(key, &pacs->key, RFAL_PICOPASS_BLOCK_LEN);
for(uint8_t i = 0; i < RFAL_PICOPASS_BLOCK_LEN; i++) {
- furi_string_cat_printf(sio_str, "%02X", key[i]);
+ furi_string_cat_printf(key_str, "%02X", key[i]);
}
}
@@ -134,12 +131,12 @@ void picopass_scene_read_card_success_on_enter(void* context) {
FontSecondary,
furi_string_get_cstr(credential_str));
widget_add_string_element(
- widget, 64, 46, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(sio_str));
+ widget, 64, 46, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(key_str));
furi_string_free(csn_str);
furi_string_free(credential_str);
furi_string_free(wiegand_str);
- furi_string_free(sio_str);
+ furi_string_free(key_str);
view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget);
}
diff --git a/applications/external/picopass/scenes/picopass_scene_save_name.c b/applications/external/picopass/scenes/picopass_scene_save_name.c
index baf882b80..a80932f08 100644
--- a/applications/external/picopass/scenes/picopass_scene_save_name.c
+++ b/applications/external/picopass/scenes/picopass_scene_save_name.c
@@ -52,8 +52,9 @@ bool picopass_scene_save_name_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == PicopassCustomEventTextInputDone) {
+ // Delete old file if renaming
if(strcmp(picopass->dev->dev_name, "") != 0) {
- // picopass_device_delete(picopass->dev, true);
+ picopass_device_delete(picopass->dev, true);
}
strlcpy(
picopass->dev->dev_name, picopass->text_store, strlen(picopass->text_store) + 1);
diff --git a/applications/external/picopass/scenes/picopass_scene_saved_menu.c b/applications/external/picopass/scenes/picopass_scene_saved_menu.c
index 401f43f9b..0283906f2 100644
--- a/applications/external/picopass/scenes/picopass_scene_saved_menu.c
+++ b/applications/external/picopass/scenes/picopass_scene_saved_menu.c
@@ -5,6 +5,7 @@ enum SubmenuIndex {
SubmenuIndexInfo,
SubmenuIndexWrite,
SubmenuIndexEmulate,
+ SubmenuIndexRename,
};
void picopass_scene_saved_menu_submenu_callback(void* context, uint32_t index) {
@@ -17,12 +18,6 @@ void picopass_scene_saved_menu_on_enter(void* context) {
Picopass* picopass = context;
Submenu* submenu = picopass->submenu;
- submenu_add_item(
- submenu,
- "Delete",
- SubmenuIndexDelete,
- picopass_scene_saved_menu_submenu_callback,
- picopass);
submenu_add_item(
submenu, "Info", SubmenuIndexInfo, picopass_scene_saved_menu_submenu_callback, picopass);
submenu_add_item(
@@ -33,6 +28,18 @@ void picopass_scene_saved_menu_on_enter(void* context) {
SubmenuIndexEmulate,
picopass_scene_saved_menu_submenu_callback,
picopass);
+ submenu_add_item(
+ submenu,
+ "Rename",
+ SubmenuIndexRename,
+ picopass_scene_saved_menu_submenu_callback,
+ picopass);
+ submenu_add_item(
+ submenu,
+ "Delete",
+ SubmenuIndexDelete,
+ picopass_scene_saved_menu_submenu_callback,
+ picopass);
submenu_set_selected_item(
picopass->submenu,
@@ -61,6 +68,9 @@ bool picopass_scene_saved_menu_on_event(void* context, SceneManagerEvent event)
} else if(event.event == SubmenuIndexEmulate) {
scene_manager_next_scene(picopass->scene_manager, PicopassSceneEmulate);
consumed = true;
+ } else if(event.event == SubmenuIndexRename) {
+ scene_manager_next_scene(picopass->scene_manager, PicopassSceneSaveName);
+ consumed = true;
}
}
diff --git a/applications/external/picopass/scenes/picopass_scene_start.c b/applications/external/picopass/scenes/picopass_scene_start.c
index cfd758ed5..d6b394b3f 100644
--- a/applications/external/picopass/scenes/picopass_scene_start.c
+++ b/applications/external/picopass/scenes/picopass_scene_start.c
@@ -58,7 +58,7 @@ bool picopass_scene_start_on_event(void* context, SceneManagerEvent event) {
consumed = true;
} else if(event.event == SubmenuIndexLoclass) {
scene_manager_set_scene_state(
- picopass->scene_manager, PicopassSceneLoclass, PicopassSceneLoclass);
+ picopass->scene_manager, PicopassSceneStart, PicopassSceneLoclass);
scene_manager_next_scene(picopass->scene_manager, PicopassSceneLoclass);
consumed = true;
}
diff --git a/applications/external/picopass/scenes/picopass_scene_write_card.c b/applications/external/picopass/scenes/picopass_scene_write_card.c
index ce396fc10..3c6eae296 100644
--- a/applications/external/picopass/scenes/picopass_scene_write_card.c
+++ b/applications/external/picopass/scenes/picopass_scene_write_card.c
@@ -4,7 +4,7 @@
void picopass_write_card_worker_callback(PicopassWorkerEvent event, void* context) {
UNUSED(event);
Picopass* picopass = context;
- view_dispatcher_send_custom_event(picopass->view_dispatcher, PicopassCustomEventWorkerExit);
+ view_dispatcher_send_custom_event(picopass->view_dispatcher, event);
}
void picopass_scene_write_card_on_enter(void* context) {
@@ -33,7 +33,10 @@ bool picopass_scene_write_card_on_event(void* context, SceneManagerEvent event)
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
- if(event.event == PicopassCustomEventWorkerExit) {
+ if(event.event == PicopassWorkerEventFail) {
+ scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteCardFailure);
+ consumed = true;
+ } else if(event.event == PicopassWorkerEventSuccess) {
scene_manager_next_scene(picopass->scene_manager, PicopassSceneWriteCardSuccess);
consumed = true;
}
diff --git a/applications/external/picopass/scenes/picopass_scene_write_card_failure.c b/applications/external/picopass/scenes/picopass_scene_write_card_failure.c
new file mode 100644
index 000000000..4aae21996
--- /dev/null
+++ b/applications/external/picopass/scenes/picopass_scene_write_card_failure.c
@@ -0,0 +1,65 @@
+#include "../picopass_i.h"
+#include
+
+void picopass_scene_write_card_failure_widget_callback(
+ GuiButtonType result,
+ InputType type,
+ void* context) {
+ furi_assert(context);
+ Picopass* picopass = context;
+
+ if(type == InputTypeShort) {
+ view_dispatcher_send_custom_event(picopass->view_dispatcher, result);
+ }
+}
+
+void picopass_scene_write_card_failure_on_enter(void* context) {
+ Picopass* picopass = context;
+ Widget* widget = picopass->widget;
+ FuriString* str = furi_string_alloc_set("Write Failure!");
+
+ widget_add_button_element(
+ widget,
+ GuiButtonTypeLeft,
+ "Retry",
+ picopass_scene_write_card_failure_widget_callback,
+ picopass);
+
+ widget_add_button_element(
+ widget,
+ GuiButtonTypeRight,
+ "Menu",
+ picopass_scene_write_card_failure_widget_callback,
+ picopass);
+
+ widget_add_string_element(
+ widget, 64, 5, AlignCenter, AlignCenter, FontSecondary, furi_string_get_cstr(str));
+
+ furi_string_free(str);
+
+ view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget);
+}
+
+bool picopass_scene_write_card_failure_on_event(void* context, SceneManagerEvent event) {
+ Picopass* picopass = context;
+ bool consumed = false;
+
+ if(event.type == SceneManagerEventTypeCustom) {
+ if(event.event == GuiButtonTypeLeft) {
+ consumed = scene_manager_previous_scene(picopass->scene_manager);
+ } else if(event.event == GuiButtonTypeRight) {
+ // Clear device name
+ picopass_device_set_name(picopass->dev, "");
+ consumed = scene_manager_search_and_switch_to_previous_scene(
+ picopass->scene_manager, PicopassSceneStart);
+ }
+ }
+ return consumed;
+}
+
+void picopass_scene_write_card_failure_on_exit(void* context) {
+ Picopass* picopass = context;
+
+ // Clear view
+ widget_reset(picopass->widget);
+}
diff --git a/applications/external/picopass/scenes/picopass_scene_write_card_success.c b/applications/external/picopass/scenes/picopass_scene_write_card_success.c
index cd760272f..52b403cfe 100644
--- a/applications/external/picopass/scenes/picopass_scene_write_card_success.c
+++ b/applications/external/picopass/scenes/picopass_scene_write_card_success.c
@@ -55,8 +55,8 @@ bool picopass_scene_write_card_success_on_event(void* context, SceneManagerEvent
} else if(event.event == GuiButtonTypeRight) {
// Clear device name
picopass_device_set_name(picopass->dev, "");
- scene_manager_next_scene(picopass->scene_manager, PicopassSceneCardMenu);
- consumed = true;
+ consumed = scene_manager_search_and_switch_to_previous_scene(
+ picopass->scene_manager, PicopassSceneStart);
}
}
return consumed;
diff --git a/applications/external/pocsag_pager/application.fam b/applications/external/pocsag_pager/application.fam
index cb893f66f..04634c81f 100644
--- a/applications/external/pocsag_pager/application.fam
+++ b/applications/external/pocsag_pager/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="pocsag_pager_app",
requires=["gui"],
stack_size=4 * 1024,
- order=50,
fap_icon="pocsag_pager_10px.png",
fap_category="Sub-GHz",
fap_icon_assets="images",
diff --git a/applications/external/pocsag_pager/pocsag_pager_app_i.c b/applications/external/pocsag_pager/pocsag_pager_app_i.c
index 88c3a8c30..8dda1d8b6 100644
--- a/applications/external/pocsag_pager/pocsag_pager_app_i.c
+++ b/applications/external/pocsag_pager/pocsag_pager_app_i.c
@@ -136,7 +136,7 @@ void pcsg_hopper_update(POCSAGPagerApp* app) {
if(app->txrx->txrx_state == PCSGTxRxStateRx) {
pcsg_rx_end(app);
- }
+ };
if(app->txrx->txrx_state == PCSGTxRxStateIDLE) {
subghz_receiver_reset(app->txrx->receiver);
app->txrx->preset->frequency =
diff --git a/applications/external/pocsag_pager/scenes/pocsag_pager_receiver.c b/applications/external/pocsag_pager/scenes/pocsag_pager_receiver.c
index 58af9a64a..cc2abd7e0 100644
--- a/applications/external/pocsag_pager/scenes/pocsag_pager_receiver.c
+++ b/applications/external/pocsag_pager/scenes/pocsag_pager_receiver.c
@@ -135,7 +135,7 @@ void pocsag_pager_scene_receiver_on_enter(void* context) {
if(app->txrx->txrx_state == PCSGTxRxStateRx) {
pcsg_rx_end(app);
- }
+ };
if((app->txrx->txrx_state == PCSGTxRxStateIDLE) ||
(app->txrx->txrx_state == PCSGTxRxStateSleep)) {
// Start RX
@@ -161,7 +161,7 @@ bool pocsag_pager_scene_receiver_on_event(void* context, SceneManagerEvent event
if(app->txrx->txrx_state == PCSGTxRxStateRx) {
pcsg_rx_end(app);
pcsg_idle(app);
- }
+ };
app->txrx->hopper_state = PCSGHopperStateOFF;
app->txrx->idx_menu_chosen = 0;
subghz_receiver_set_rx_callback(app->txrx->receiver, NULL, app);
diff --git a/applications/external/pocsag_pager/views/pocsag_pager_receiver.c b/applications/external/pocsag_pager/views/pocsag_pager_receiver.c
index 755102682..629c3894e 100644
--- a/applications/external/pocsag_pager/views/pocsag_pager_receiver.c
+++ b/applications/external/pocsag_pager/views/pocsag_pager_receiver.c
@@ -1,6 +1,6 @@
#include "pocsag_pager_receiver.h"
#include "../pocsag_pager_app_i.h"
-#include
+#include "pocsag_pager_icons.h"
#include
#include
diff --git a/applications/external/pomodoro/flipp_pomodoro_app.c b/applications/external/pomodoro/flipp_pomodoro_app.c
index c49952c87..c91edc93c 100644
--- a/applications/external/pomodoro/flipp_pomodoro_app.c
+++ b/applications/external/pomodoro/flipp_pomodoro_app.c
@@ -32,6 +32,10 @@ static bool flipp_pomodoro_app_custom_event_callback(void* ctx, uint32_t event)
return CustomEventConsumed;
case FlippPomodoroAppCustomEventStageComplete:
if(flipp_pomodoro__get_stage(app->state) == FlippPomodoroStageFocus) {
+ // REGISTER a deed on work stage complete to get an acheivement
+ dolphin_deed(DolphinDeedPluginGameWin);
+ FURI_LOG_I(TAG, "Focus stage reward added");
+
flipp_pomodoro_statistics__increase_focus_stages_completed(app->statistics);
};
@@ -106,9 +110,12 @@ int32_t flipp_pomodoro_app(void* p) {
FURI_LOG_I(TAG, "Initial");
FlippPomodoroApp* app = flipp_pomodoro_app_alloc();
+ FURI_LOG_I(TAG, "Run deed added");
+ dolphin_deed(DolphinDeedPluginGameStart);
+
view_dispatcher_run(app->view_dispatcher);
flipp_pomodoro_app_free(app);
return 0;
-};
+};
\ No newline at end of file
diff --git a/applications/external/pomodoro/flipp_pomodoro_app_i.h b/applications/external/pomodoro/flipp_pomodoro_app_i.h
index 56d8a6133..8b8650776 100644
--- a/applications/external/pomodoro/flipp_pomodoro_app_i.h
+++ b/applications/external/pomodoro/flipp_pomodoro_app_i.h
@@ -15,6 +15,7 @@
#include
#include
#include
+#include
#include
// App resource imports
diff --git a/applications/external/protoview/application.fam b/applications/external/protoview/application.fam
index 7dbb7ea31..75084b852 100644
--- a/applications/external/protoview/application.fam
+++ b/applications/external/protoview/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="protoview_app_entry",
requires=["gui"],
stack_size=8 * 1024,
- order=50,
fap_icon="appicon.png",
fap_category="Sub-GHz",
fap_author="@antirez & (fixes by @xMasterX)",
diff --git a/applications/external/protoview/signal_file.c b/applications/external/protoview/signal_file.c
index e7934d04b..8f325ab52 100644
--- a/applications/external/protoview/signal_file.c
+++ b/applications/external/protoview/signal_file.c
@@ -45,14 +45,21 @@ bool save_signal(ProtoViewApp* app, const char* filename) {
custom,
"Custom_preset_module: CC1101\n"
"Custom_preset_data: ");
- for(int j = 0; regs[j]; j += 2) {
+
+ /* We will know the size of the preset data once we reach the end
+ * of the registers (null address). For now it's INT_MAX. */
+ int preset_data_size = INT_MAX;
+ bool patable_reached = false;
+ for(int j = 0; j <= preset_data_size; j += 2) {
+ // End reached, set the size to write the remaining 8 bytes (PATABLE)
+ if(!patable_reached && regs[j] == 0) {
+ preset_data_size = j + 8;
+ patable_reached = true;
+ }
furi_string_cat_printf(custom, "%02X %02X ", (int)regs[j], (int)regs[j + 1]);
}
- // Add patable
- furi_string_cat(custom, "00 00 C0 00 00 00 00 00 00 00 ");
- //size_t len = furi_string_size(file_content);
- //furi_string_set_char(custom, len - 1, '\n');
- furi_string_cat(custom, "\n");
+ size_t len = furi_string_size(custom);
+ furi_string_set_char(custom, len - 1, '\n');
furi_string_cat(file_content, custom);
furi_string_free(custom);
}
diff --git a/applications/external/rc2014_coleco/application.fam b/applications/external/rc2014_coleco/application.fam
index fe3ee028b..d9b3aa727 100644
--- a/applications/external/rc2014_coleco/application.fam
+++ b/applications/external/rc2014_coleco/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_COLECO"],
requires=["gui"],
stack_size=1 * 1024,
- order=35,
fap_icon="coleco_10px.png",
fap_icon_assets="icons",
fap_category="GPIO",
diff --git a/applications/external/reversi/application.fam b/applications/external/reversi/application.fam
index 25a087c0c..87091e91a 100644
--- a/applications/external/reversi/application.fam
+++ b/applications/external/reversi/application.fam
@@ -8,7 +8,6 @@ App(
"gui",
],
stack_size=1 * 1024,
- order=90,
fap_icon="game_reversi.png",
fap_category="Games",
fap_icon_assets_symbol="game_reversi",
diff --git a/applications/external/rootoflife/application.fam b/applications/external/rootoflife/application.fam
index aa3d68211..c335f77aa 100644
--- a/applications/external/rootoflife/application.fam
+++ b/applications/external/rootoflife/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_ROOTS_OF_LIFE_GAME"],
requires=["gui"],
stack_size=1 * 1024,
- order=30,
fap_icon="roots_of_life_10px.png",
fap_category="Games",
fap_icon_assets="images",
diff --git a/applications/external/sam/application.fam b/applications/external/sam/application.fam
index 8a6d70c07..e123f455b 100644
--- a/applications/external/sam/application.fam
+++ b/applications/external/sam/application.fam
@@ -8,7 +8,6 @@ App(
"dialogs",
],
stack_size=4 * 1024,
- order=20,
fap_icon="music_10px.png",
fap_category="Media",
)
@@ -22,7 +21,6 @@ App(
"dialogs",
],
stack_size=4 * 1024,
- order=20,
fap_icon="music_10px.png",
fap_category="Media",
)
@@ -36,7 +34,6 @@ App(
"dialogs",
],
stack_size=4 * 1024,
- order=20,
fap_icon="music_10px.png",
fap_category="Media",
)
@@ -50,7 +47,6 @@ App(
"dialogs",
],
stack_size=4 * 1024,
- order=20,
fap_icon="music_10px.png",
fap_category="Media",
)
diff --git a/applications/external/scorched_tanks/application.fam b/applications/external/scorched_tanks/application.fam
index 4d74c5ced..6256a3c47 100644
--- a/applications/external/scorched_tanks/application.fam
+++ b/applications/external/scorched_tanks/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_SCORCHED_TANKS_GAME"],
requires=["gui"],
stack_size=1 * 1024,
- order=100,
fap_icon="scorchedTanks_10px.png",
fap_category="Games",
fap_author="@jasniec",
diff --git a/applications/external/sentry_safe/application.fam b/applications/external/sentry_safe/application.fam
index 73264cf01..7f17ca5f6 100644
--- a/applications/external/sentry_safe/application.fam
+++ b/applications/external/sentry_safe/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="sentry_safe_app",
requires=["gui"],
stack_size=1 * 1024,
- order=40,
fap_icon="safe_10px.png",
fap_category="GPIO",
fap_author="@H4ckd4ddy & @xMasterX (ported to latest firmware)",
diff --git a/applications/external/sentry_safe/sentry_safe.c b/applications/external/sentry_safe/sentry_safe.c
index d9c75d1ea..789b43f2c 100644
--- a/applications/external/sentry_safe/sentry_safe.c
+++ b/applications/external/sentry_safe/sentry_safe.c
@@ -166,4 +166,4 @@ int32_t sentry_safe_app(void* p) {
free(sentry_state);
return 0;
-}
+}
\ No newline at end of file
diff --git a/applications/external/signal_generator/application.fam b/applications/external/signal_generator/application.fam
index a7b93b817..4a5877a7c 100644
--- a/applications/external/signal_generator/application.fam
+++ b/applications/external/signal_generator/application.fam
@@ -5,7 +5,9 @@ App(
entry_point="signal_gen_app",
requires=["gui"],
stack_size=1 * 1024,
- order=50,
+ fap_description="Control GPIO pins to generate digital signals",
+ fap_version="1.0",
fap_icon="signal_gen_10px.png",
fap_category="GPIO",
+ fap_icon_assets="icons",
)
diff --git a/applications/external/signal_generator/views/signal_gen_pwm.c b/applications/external/signal_generator/views/signal_gen_pwm.c
index 84dc63f92..63669a937 100644
--- a/applications/external/signal_generator/views/signal_gen_pwm.c
+++ b/applications/external/signal_generator/views/signal_gen_pwm.c
@@ -1,6 +1,7 @@
#include "../signal_gen_app_i.h"
#include
#include
+#include "signal_generator_icons.h"
#include
typedef enum {
diff --git a/applications/external/slots/application.fam b/applications/external/slots/application.fam
index 190841543..9a2e244d8 100644
--- a/applications/external/slots/application.fam
+++ b/applications/external/slots/application.fam
@@ -7,7 +7,6 @@ App(
requires=["gui"],
stack_size=1 * 1024,
fap_icon="ddgame_icon.png",
- order=30,
fap_category="Games",
fap_icon_assets="assets",
fap_author="@Daniel-dev-s",
diff --git a/applications/external/snake_2/application.fam b/applications/external/snake_2/application.fam
index 287522983..f05f76441 100644
--- a/applications/external/snake_2/application.fam
+++ b/applications/external/snake_2/application.fam
@@ -6,7 +6,6 @@ App(
cdefines=["APP_SNAKE_20"],
requires=["gui"],
stack_size=1 * 1024,
- order=30,
fap_icon="snake_10px.png",
fap_category="Games",
fap_author="@Willzvul",
diff --git a/applications/external/snake_2/snake_20.c b/applications/external/snake_2/snake_20.c
index ee6ae68f3..c45c9796c 100644
--- a/applications/external/snake_2/snake_20.c
+++ b/applications/external/snake_2/snake_20.c
@@ -2,6 +2,7 @@
#include
#include
#include
+#include
#include
#include
@@ -399,6 +400,8 @@ int32_t snake_20_app(void* p) {
notification_message_block(notification, &sequence_display_backlight_enforce_on);
+ dolphin_deed(DolphinDeedPluginGameStart);
+
SnakeEvent event;
for(bool processing = true; processing;) {
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100);
@@ -522,4 +525,4 @@ int32_t snake_20_app(void* p) {
free(snake_state);
return 0;
-}
+}
\ No newline at end of file
diff --git a/applications/external/solitaire/LICENSE b/applications/external/solitaire/LICENSE
new file mode 100644
index 000000000..37558e682
--- /dev/null
+++ b/applications/external/solitaire/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2023 Tibor Tálosi
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/applications/external/solitaire/application.fam b/applications/external/solitaire/application.fam
index 99067e1b9..9394dfc8a 100644
--- a/applications/external/solitaire/application.fam
+++ b/applications/external/solitaire/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="solitaire_app",
requires=["gui", "storage", "canvas"],
stack_size=2 * 1024,
- order=30,
fap_icon="solitaire_10px.png",
fap_category="Games",
fap_icon_assets="assets",
diff --git a/applications/external/solitaire/defines.h b/applications/external/solitaire/defines.h
index 8734395e8..a225b7c83 100644
--- a/applications/external/solitaire/defines.h
+++ b/applications/external/solitaire/defines.h
@@ -44,6 +44,7 @@ typedef struct {
InputKey input;
bool started;
+ bool had_change;
bool processing;
bool longPress;
PlayState state;
diff --git a/applications/external/solitaire/solitaire.c b/applications/external/solitaire/solitaire.c
index 82506384e..9b9c8ce74 100644
--- a/applications/external/solitaire/solitaire.c
+++ b/applications/external/solitaire/solitaire.c
@@ -1,12 +1,15 @@
#include
+#include
#include
#include
#include "defines.h"
#include "common/ui.h"
#include "solitaire_icons.h"
+#include
#include
#include
void init(GameState* game_state);
+
const NotificationSequence sequence_fail = {
&message_vibro_on,
&message_note_c4,
@@ -33,13 +36,6 @@ int8_t columns[7][3] = {
};
bool can_place_card(Card where, Card what) {
- FURI_LOG_D(
- APP_NAME,
- "TESTING pip %i, letter %i with pip %i, letter %i",
- where.pip,
- where.character,
- what.pip,
- what.character);
bool a_black = where.pip == 0 || where.pip == 3;
bool b_black = what.pip == 0 || what.pip == 3;
if(a_black == b_black) return false;
@@ -53,86 +49,97 @@ bool can_place_card(Card where, Card what) {
}
static void draw_scene(Canvas* const canvas, const GameState* game_state) {
- int deckIndex = game_state->deck.index;
- if(game_state->dragging_deck) deckIndex--;
+ if(game_state->had_change) {
+ int deckIndex = game_state->deck.index;
+ if(game_state->dragging_deck) deckIndex--;
- if((game_state->deck.index < (game_state->deck.card_count - 1) ||
- game_state->deck.index == -1) &&
- game_state->deck.card_count > 0) {
- draw_card_back_at(columns[0][0], columns[0][1], canvas);
- if(game_state->selectRow == 0 && game_state->selectColumn == 0) {
- draw_rounded_box(
- canvas,
- columns[0][0] + 1,
- columns[0][1] + 1,
- CARD_WIDTH - 2,
- CARD_HEIGHT - 2,
- Inverse);
- }
- } else
- draw_card_space(
- columns[0][0],
- columns[0][1],
- game_state->selectRow == 0 && game_state->selectColumn == 0,
- canvas);
- //deck side
- if(deckIndex >= 0) {
- Card c = game_state->deck.cards[deckIndex];
- draw_card_at_colored(
- columns[1][0],
- columns[1][1],
- c.pip,
- c.character,
- game_state->selectRow == 0 && game_state->selectColumn == 1,
- canvas);
- } else
- draw_card_space(
- columns[1][0],
- columns[1][1],
- game_state->selectRow == 0 && game_state->selectColumn == 1,
- canvas);
-
- for(uint8_t i = 0; i < 4; i++) {
- Card current = game_state->top_cards[i];
- bool selected = game_state->selectRow == 0 && game_state->selectColumn == (i + 3);
- if(current.disabled) {
- draw_card_space(columns[i + 3][0], columns[i + 3][1], selected, canvas);
- } else {
- draw_card_at(
- columns[i + 3][0], columns[i + 3][1], current.pip, current.character, canvas);
- if(selected) {
+ if((game_state->deck.index < (game_state->deck.card_count - 1) ||
+ game_state->deck.index == -1) &&
+ game_state->deck.card_count > 0) {
+ draw_card_back_at(columns[0][0], columns[0][1], canvas);
+ if(game_state->selectRow == 0 && game_state->selectColumn == 0) {
draw_rounded_box(
- canvas, columns[i + 3][0], columns[i + 3][1], CARD_WIDTH, CARD_HEIGHT, Inverse);
+ canvas,
+ columns[0][0] + 1,
+ columns[0][1] + 1,
+ CARD_WIDTH - 2,
+ CARD_HEIGHT - 2,
+ Inverse);
+ }
+ } else
+ draw_card_space(
+ columns[0][0],
+ columns[0][1],
+ game_state->selectRow == 0 && game_state->selectColumn == 0,
+ canvas);
+ //deck side
+ if(deckIndex >= 0) {
+ Card c = game_state->deck.cards[deckIndex];
+ draw_card_at_colored(
+ columns[1][0],
+ columns[1][1],
+ c.pip,
+ c.character,
+ game_state->selectRow == 0 && game_state->selectColumn == 1,
+ canvas);
+ } else
+ draw_card_space(
+ columns[1][0],
+ columns[1][1],
+ game_state->selectRow == 0 && game_state->selectColumn == 1,
+ canvas);
+
+ for(uint8_t i = 0; i < 4; i++) {
+ Card current = game_state->top_cards[i];
+ bool selected = game_state->selectRow == 0 && game_state->selectColumn == (i + 3);
+ if(current.disabled) {
+ draw_card_space(columns[i + 3][0], columns[i + 3][1], selected, canvas);
+ } else {
+ draw_card_at(
+ columns[i + 3][0], columns[i + 3][1], current.pip, current.character, canvas);
+ if(selected) {
+ draw_rounded_box(
+ canvas,
+ columns[i + 3][0],
+ columns[i + 3][1],
+ CARD_WIDTH,
+ CARD_HEIGHT,
+ Inverse);
+ }
}
}
- }
- for(uint8_t i = 0; i < 7; i++) {
- bool selected = game_state->selectRow == 1 && game_state->selectColumn == i;
- int8_t index = (game_state->bottom_columns[i].index - 1 - game_state->selected_card);
- if(index < 0) index = 0;
- draw_hand_column(
- game_state->bottom_columns[i],
- columns[i][0],
- columns[i][2],
- selected ? index : -1,
- canvas);
- }
+ for(uint8_t i = 0; i < 7; i++) {
+ bool selected = game_state->selectRow == 1 && game_state->selectColumn == i;
+ int8_t index = (game_state->bottom_columns[i].index - 1 - game_state->selected_card);
+ if(index < 0) index = 0;
+ draw_hand_column(
+ game_state->bottom_columns[i],
+ columns[i][0],
+ columns[i][2],
+ selected ? index : -1,
+ canvas);
+ }
- int8_t pos[2] = {
- columns[game_state->selectColumn][0],
- columns[game_state->selectColumn][game_state->selectRow + 1]};
+ int8_t pos[2] = {
+ columns[game_state->selectColumn][0],
+ columns[game_state->selectColumn][game_state->selectRow + 1]};
- /* draw_icon_clip(canvas, &I_card_graphics, pos[0] + CARD_HALF_WIDTH, pos[1] + CARD_HALF_HEIGHT, 30, 5, 5, 5,
- Filled);*/
+ /* draw_icon_clip(canvas, &I_card_graphics, pos[0] + CARD_HALF_WIDTH, pos[1] + CARD_HALF_HEIGHT, 30, 5, 5, 5,
+ Filled);*/
- if(game_state->dragging_hand.index > 0) {
- draw_hand_column(
- game_state->dragging_hand,
- pos[0] + CARD_HALF_WIDTH + 3,
- pos[1] + CARD_HALF_HEIGHT + 3,
- -1,
- canvas);
+ if(game_state->dragging_hand.index > 0) {
+ draw_hand_column(
+ game_state->dragging_hand,
+ pos[0] + CARD_HALF_WIDTH + 3,
+ pos[1] + CARD_HALF_HEIGHT + 3,
+ -1,
+ canvas);
+ }
+
+ clone_buffer(get_buffer(canvas), game_state->animation.buffer);
+ } else {
+ clone_buffer(game_state->animation.buffer, get_buffer(canvas));
}
}
@@ -154,9 +161,11 @@ static void draw_animation(Canvas* const canvas, const GameState* game_state) {
}
static void render_callback(Canvas* const canvas, void* ctx) {
- furi_assert(ctx);
const GameState* game_state = ctx;
- furi_mutex_acquire(game_state->mutex, FuriWaitForever);
+ furi_mutex_acquire(game_state->mutex, 25);
+ if(game_state == NULL) {
+ return;
+ }
switch(game_state->state) {
case GameStateAnimate:
@@ -253,7 +262,6 @@ bool place_on_top(Card* where, Card what) {
int8_t b_letter = (int8_t)what.character;
if(a_letter == 12) a_letter = -1;
if(b_letter == 12) b_letter = -1;
-
if(where->disabled && b_letter != -1) return false;
if((a_letter + 1) == b_letter) {
@@ -276,6 +284,9 @@ void tick(GameState* game_state, NotificationApp* notification) {
if(game_state->top_cards[0].character == 11 && game_state->top_cards[1].character == 11 &&
game_state->top_cards[2].character == 11 && game_state->top_cards[3].character == 11) {
game_state->state = GameStateAnimate;
+ game_state->had_change = true;
+ dolphin_deed(DolphinDeedPluginGameWin);
+
return;
}
}
@@ -406,6 +417,7 @@ void tick(GameState* game_state, NotificationApp* notification) {
}
void init(GameState* game_state) {
+ dolphin_deed(DolphinDeedPluginGameStart);
game_state->selectColumn = 0;
game_state->selected_card = 0;
game_state->selectRow = 0;
@@ -484,16 +496,17 @@ int32_t solitaire_app(void* p) {
FuriTimer* timer = furi_timer_alloc(update_timer_callback, FuriTimerTypePeriodic, event_queue);
furi_timer_start(timer, furi_kernel_get_tick_frequency() / 30);
- Gui* gui = furi_record_open(RECORD_GUI);
+ Gui* gui = furi_record_open("gui");
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
AppEvent event;
-
for(bool processing = true; processing;) {
FuriStatus event_status = furi_message_queue_get(event_queue, &event, 150);
furi_mutex_acquire(game_state->mutex, FuriWaitForever);
+ game_state->had_change = false;
if(event_status == FuriStatusOk) {
if(event.type == EventTypeKey) {
+ game_state->had_change = true;
if(event.input.type == InputTypeLong) {
game_state->longPress = true;
switch(event.input.key) {
@@ -540,6 +553,7 @@ int32_t solitaire_app(void* p) {
game_state->input = InputKeyMAX;
}
}
+
view_port_update(view_port);
furi_mutex_release(game_state->mutex);
}
@@ -561,5 +575,6 @@ free_and_exit:
free(game_state->deck.cards);
free(game_state);
furi_message_queue_free(event_queue);
+
return return_code;
-}
+}
\ No newline at end of file
diff --git a/applications/external/spectrum_analyzer/application.fam b/applications/external/spectrum_analyzer/application.fam
index 27cc286d9..13f5d49f9 100644
--- a/applications/external/spectrum_analyzer/application.fam
+++ b/applications/external/spectrum_analyzer/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="spectrum_analyzer_app",
requires=["gui"],
stack_size=2 * 1024,
- order=12,
fap_icon="spectrum_10px.png",
fap_category="Sub-GHz",
fap_author="@xMasterX & @theY4Kman & @ALEEF02 (original by @jolcese)",
diff --git a/applications/external/spectrum_analyzer/spectrum_analyzer.c b/applications/external/spectrum_analyzer/spectrum_analyzer.c
index ed6e86867..345dd008b 100644
--- a/applications/external/spectrum_analyzer/spectrum_analyzer.c
+++ b/applications/external/spectrum_analyzer/spectrum_analyzer.c
@@ -608,4 +608,4 @@ int32_t spectrum_analyzer_app(void* p) {
spectrum_analyzer_free(spectrum_analyzer);
return 0;
-}
+}
\ No newline at end of file
diff --git a/applications/external/spi_mem_manager/application.fam b/applications/external/spi_mem_manager/application.fam
index a21f8061d..8d1100cf9 100644
--- a/applications/external/spi_mem_manager/application.fam
+++ b/applications/external/spi_mem_manager/application.fam
@@ -5,7 +5,8 @@ App(
entry_point="spi_mem_app",
requires=["gui"],
stack_size=1 * 2048,
- order=30,
+ fap_description="Application for reading and writing 25-series SPI memory chips",
+ fap_version="1.0",
fap_icon="images/Dip8_10px.png",
fap_category="GPIO",
fap_icon_assets="images",
diff --git a/applications/external/spi_mem_manager/views/spi_mem_view_detect.c b/applications/external/spi_mem_manager/views/spi_mem_view_detect.c
index eddf36e49..473d54ae2 100644
--- a/applications/external/spi_mem_manager/views/spi_mem_view_detect.c
+++ b/applications/external/spi_mem_manager/views/spi_mem_view_detect.c
@@ -1,5 +1,6 @@
#include "spi_mem_view_detect.h"
#include "spi_mem_manager_icons.h"
+#include
#include
struct SPIMemDetectView {
diff --git a/applications/external/subghz_bruteforcer/application.fam b/applications/external/subghz_bruteforcer/application.fam
index 713520a2c..bb9cd6d24 100644
--- a/applications/external/subghz_bruteforcer/application.fam
+++ b/applications/external/subghz_bruteforcer/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="subbrute_app",
requires=["gui", "dialogs"],
stack_size=2 * 1024,
- order=11,
fap_icon="subbrute_10px.png",
fap_category="Sub-GHz",
fap_icon_assets="images",
diff --git a/applications/external/subghz_playlist/application.fam b/applications/external/subghz_playlist/application.fam
index 8fe9ccbaf..5050197f2 100644
--- a/applications/external/subghz_playlist/application.fam
+++ b/applications/external/subghz_playlist/application.fam
@@ -5,9 +5,9 @@ App(
entry_point="playlist_app",
requires=["storage", "gui", "dialogs", "subghz"],
stack_size=2 * 1024,
- order=14,
fap_icon="subplaylist_10px.png",
fap_category="Sub-GHz",
+ fap_icon_assets="images",
fap_author="@darmiel",
fap_version="1.0",
fap_description="App works with list of sub-ghz files from .txt file that contains paths to target files.",
diff --git a/applications/external/subghz_playlist/playlist.c b/applications/external/subghz_playlist/playlist.c
index fe0186e74..85b5109b8 100644
--- a/applications/external/subghz_playlist/playlist.c
+++ b/applications/external/subghz_playlist/playlist.c
@@ -6,6 +6,7 @@
#include
#include
+#include "subghz_playlist_icons.h"
#include
#include
diff --git a/applications/external/subghz_remote/application.fam b/applications/external/subghz_remote/application.fam
index 7eee1369f..1a99a2025 100644
--- a/applications/external/subghz_remote/application.fam
+++ b/applications/external/subghz_remote/application.fam
@@ -4,7 +4,6 @@ App(
apptype=FlipperAppType.EXTERNAL,
entry_point="subghz_remote_app",
stack_size=2 * 1024,
- order=11,
fap_icon="icon.png",
fap_description="SubGhz Remote, uses up to 5 .sub files",
fap_category="Sub-GHz",
diff --git a/applications/external/swd_probe/application.fam b/applications/external/swd_probe/application.fam
index 8239121b1..998dcc7b6 100644
--- a/applications/external/swd_probe/application.fam
+++ b/applications/external/swd_probe/application.fam
@@ -5,7 +5,6 @@ App(
entry_point="swd_probe_app_main",
requires=["notification", "gui", "storage", "dialogs", "cli"],
stack_size=2 * 1024,
- order=10,
fap_icon="icons/app.png",
fap_category="GPIO",
fap_icon_assets="icons",
diff --git a/applications/external/swd_probe/swd_probe_app.c b/applications/external/swd_probe/swd_probe_app.c
index ba4cbd1ee..b43b9c1c8 100644
--- a/applications/external/swd_probe/swd_probe_app.c
+++ b/applications/external/swd_probe/swd_probe_app.c
@@ -3137,6 +3137,8 @@ int32_t swd_probe_app_main(void* p) {
DBGS("swd_execute_script");
swd_execute_script(app, SWD_PATH "/startup.swd");
+ dolphin_deed(DolphinDeedPluginGameStart);
+
DBGS("processing");
for(bool processing = true; processing;) {
swd_main_loop(app);
diff --git a/applications/external/swd_probe/swd_probe_app.h b/applications/external/swd_probe/swd_probe_app.h
index b60617e98..5a45a4fd9 100644
--- a/applications/external/swd_probe/swd_probe_app.h
+++ b/applications/external/swd_probe/swd_probe_app.h
@@ -15,6 +15,7 @@
#include
#include
#include
+#include