Skip to content
This repository has been archived by the owner on Jul 28, 2024. It is now read-only.

Commit

Permalink
Merge branch 'dev' into hedger/toochain_29
Browse files Browse the repository at this point in the history
  • Loading branch information
hedger authored Feb 16, 2024
2 parents d19f8f5 + 60a9d7e commit 01d937c
Show file tree
Hide file tree
Showing 91 changed files with 3,352 additions and 1,730 deletions.
11 changes: 11 additions & 0 deletions applications/examples/example_ble_beacon/application.fam
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
App(
appid="example_ble_beacon",
name="Example: BLE Beacon",
apptype=FlipperAppType.EXTERNAL,
entry_point="ble_beacon_app",
requires=["gui"],
stack_size=1 * 1024,
fap_icon="example_ble_beacon_10px.png",
fap_category="Examples",
fap_icon_assets="images",
)
149 changes: 149 additions & 0 deletions applications/examples/example_ble_beacon/ble_beacon_app.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#include "ble_beacon_app.h"

#include <extra_beacon.h>
#include <furi_hal_version.h>

#include <string.h>

#define TAG "ble_beacon_app"

static bool ble_beacon_app_custom_event_callback(void* context, uint32_t event) {
furi_assert(context);
BleBeaconApp* app = context;
return scene_manager_handle_custom_event(app->scene_manager, event);
}

static bool ble_beacon_app_back_event_callback(void* context) {
furi_assert(context);
BleBeaconApp* app = context;
return scene_manager_handle_back_event(app->scene_manager);
}

static void ble_beacon_app_tick_event_callback(void* context) {
furi_assert(context);
BleBeaconApp* app = context;
scene_manager_handle_tick_event(app->scene_manager);
}

static void ble_beacon_app_restore_beacon_state(BleBeaconApp* app) {
// Restore beacon data from service
GapExtraBeaconConfig* local_config = &app->beacon_config;
const GapExtraBeaconConfig* config = furi_hal_bt_extra_beacon_get_config();
if(config) {
// We have a config, copy it
memcpy(local_config, config, sizeof(app->beacon_config));
} else {
// No config, set up default values - they will stay until overriden or device is reset
local_config->min_adv_interval_ms = 50;
local_config->max_adv_interval_ms = 150;

local_config->adv_channel_map = GapAdvChannelMapAll;
local_config->adv_power_level = GapAdvPowerLevel_0dBm;

local_config->address_type = GapAddressTypePublic;
memcpy(
local_config->address, furi_hal_version_get_ble_mac(), sizeof(local_config->address));
// Modify MAC address to make it different from the one used by the main app
local_config->address[0] ^= 0xFF;
local_config->address[3] ^= 0xFF;

furi_check(furi_hal_bt_extra_beacon_set_config(local_config));
}

// Get beacon state
app->is_beacon_active = furi_hal_bt_extra_beacon_is_active();

// Restore last beacon data
app->beacon_data_len = furi_hal_bt_extra_beacon_get_data(app->beacon_data);
}

static BleBeaconApp* ble_beacon_app_alloc() {
BleBeaconApp* app = malloc(sizeof(BleBeaconApp));

app->gui = furi_record_open(RECORD_GUI);

app->scene_manager = scene_manager_alloc(&ble_beacon_app_scene_handlers, app);
app->view_dispatcher = view_dispatcher_alloc();

app->status_string = furi_string_alloc();

view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
view_dispatcher_set_custom_event_callback(
app->view_dispatcher, ble_beacon_app_custom_event_callback);
view_dispatcher_set_navigation_event_callback(
app->view_dispatcher, ble_beacon_app_back_event_callback);
view_dispatcher_set_tick_event_callback(
app->view_dispatcher, ble_beacon_app_tick_event_callback, 100);
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
view_dispatcher_enable_queue(app->view_dispatcher);

app->submenu = submenu_alloc();
view_dispatcher_add_view(
app->view_dispatcher, BleBeaconAppViewSubmenu, submenu_get_view(app->submenu));

app->dialog_ex = dialog_ex_alloc();
view_dispatcher_add_view(
app->view_dispatcher, BleBeaconAppViewDialog, dialog_ex_get_view(app->dialog_ex));

app->byte_input = byte_input_alloc();
view_dispatcher_add_view(
app->view_dispatcher, BleBeaconAppViewByteInput, byte_input_get_view(app->byte_input));

ble_beacon_app_restore_beacon_state(app);

return app;
}

static void ble_beacon_app_free(BleBeaconApp* app) {
view_dispatcher_remove_view(app->view_dispatcher, BleBeaconAppViewByteInput);
view_dispatcher_remove_view(app->view_dispatcher, BleBeaconAppViewSubmenu);
view_dispatcher_remove_view(app->view_dispatcher, BleBeaconAppViewDialog);

free(app->byte_input);
free(app->submenu);
free(app->dialog_ex);

free(app->scene_manager);
free(app->view_dispatcher);

free(app->status_string);

furi_record_close(RECORD_NOTIFICATION);
furi_record_close(RECORD_GUI);
app->gui = NULL;

free(app);
}

int32_t ble_beacon_app(void* args) {
UNUSED(args);

BleBeaconApp* app = ble_beacon_app_alloc();

scene_manager_next_scene(app->scene_manager, BleBeaconAppSceneRunBeacon);

view_dispatcher_run(app->view_dispatcher);

ble_beacon_app_free(app);
return 0;
}

void ble_beacon_app_update_state(BleBeaconApp* app) {
furi_hal_bt_extra_beacon_stop();

furi_check(furi_hal_bt_extra_beacon_set_config(&app->beacon_config));

app->beacon_data_len = 0;
while((app->beacon_data[app->beacon_data_len] != 0) &&
(app->beacon_data_len < sizeof(app->beacon_data))) {
app->beacon_data_len++;
}

FURI_LOG_I(TAG, "beacon_data_len: %d", app->beacon_data_len);

furi_check(furi_hal_bt_extra_beacon_set_data(app->beacon_data, app->beacon_data_len));

if(app->is_beacon_active) {
furi_check(furi_hal_bt_extra_beacon_start());
}
}
50 changes: 50 additions & 0 deletions applications/examples/example_ble_beacon/ble_beacon_app.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#pragma once

#include "extra_beacon.h"
#include <furi.h>
#include <gui/gui.h>
#include <gui/view.h>
#include <gui/scene_manager.h>
#include <gui/view_dispatcher.h>

#include <gui/modules/widget.h>
#include <gui/modules/submenu.h>
#include <gui/modules/byte_input.h>
#include <gui/modules/dialog_ex.h>

#include <rpc/rpc_app.h>
#include <notification/notification_messages.h>

#include <furi_hal_bt.h>

#include "scenes/scenes.h"
#include <stdint.h>

typedef struct {
Gui* gui;
SceneManager* scene_manager;
ViewDispatcher* view_dispatcher;

Submenu* submenu;
ByteInput* byte_input;
DialogEx* dialog_ex;

FuriString* status_string;

GapExtraBeaconConfig beacon_config;
uint8_t beacon_data[EXTRA_BEACON_MAX_DATA_SIZE];
uint8_t beacon_data_len;
bool is_beacon_active;
} BleBeaconApp;

typedef enum {
BleBeaconAppViewSubmenu,
BleBeaconAppViewByteInput,
BleBeaconAppViewDialog,
} BleBeaconAppView;

typedef enum {
BleBeaconAppCustomEventDataEditResult = 100,
} BleBeaconAppCustomEvent;

void ble_beacon_app_update_state(BleBeaconApp* app);
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ADD_SCENE(ble_beacon_app, menu, Menu)
ADD_SCENE(ble_beacon_app, input_mac_addr, InputMacAddress)
ADD_SCENE(ble_beacon_app, input_beacon_data, InputBeaconData)
ADD_SCENE(ble_beacon_app, run_beacon, RunBeacon)
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "../ble_beacon_app.h"

static void ble_beacon_app_scene_add_type_byte_input_callback(void* context) {
BleBeaconApp* ble_beacon = context;
view_dispatcher_send_custom_event(
ble_beacon->view_dispatcher, BleBeaconAppCustomEventDataEditResult);
}

void ble_beacon_app_scene_input_beacon_data_on_enter(void* context) {
BleBeaconApp* ble_beacon = context;
byte_input_set_header_text(ble_beacon->byte_input, "Enter beacon data");

byte_input_set_result_callback(
ble_beacon->byte_input,
ble_beacon_app_scene_add_type_byte_input_callback,
NULL,
context,
ble_beacon->beacon_data,
sizeof(ble_beacon->beacon_data));

view_dispatcher_switch_to_view(ble_beacon->view_dispatcher, BleBeaconAppViewByteInput);
}

bool ble_beacon_app_scene_input_beacon_data_on_event(void* context, SceneManagerEvent event) {
BleBeaconApp* ble_beacon = context;
SceneManager* scene_manager = ble_beacon->scene_manager;

if(event.type == SceneManagerEventTypeCustom) {
if(event.event == BleBeaconAppCustomEventDataEditResult) {
ble_beacon_app_update_state(ble_beacon);
scene_manager_previous_scene(scene_manager);
return true;
}
}

return false;
}

void ble_beacon_app_scene_input_beacon_data_on_exit(void* context) {
BleBeaconApp* ble_beacon = context;

byte_input_set_result_callback(ble_beacon->byte_input, NULL, NULL, NULL, NULL, 0);
byte_input_set_header_text(ble_beacon->byte_input, NULL);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "../ble_beacon_app.h"

static void ble_beacon_app_scene_add_type_byte_input_callback(void* context) {
BleBeaconApp* ble_beacon = context;
view_dispatcher_send_custom_event(
ble_beacon->view_dispatcher, BleBeaconAppCustomEventDataEditResult);
}

void ble_beacon_app_scene_input_mac_addr_on_enter(void* context) {
BleBeaconApp* ble_beacon = context;
byte_input_set_header_text(ble_beacon->byte_input, "Enter MAC (reversed)");

byte_input_set_result_callback(
ble_beacon->byte_input,
ble_beacon_app_scene_add_type_byte_input_callback,
NULL,
context,
ble_beacon->beacon_config.address,
sizeof(ble_beacon->beacon_config.address));

view_dispatcher_switch_to_view(ble_beacon->view_dispatcher, BleBeaconAppViewByteInput);
}

bool ble_beacon_app_scene_input_mac_addr_on_event(void* context, SceneManagerEvent event) {
BleBeaconApp* ble_beacon = context;
SceneManager* scene_manager = ble_beacon->scene_manager;

if(event.type == SceneManagerEventTypeCustom) {
if(event.event == BleBeaconAppCustomEventDataEditResult) {
ble_beacon_app_update_state(ble_beacon);
scene_manager_previous_scene(scene_manager);
return true;
}
}

return false;
}

void ble_beacon_app_scene_input_mac_addr_on_exit(void* context) {
BleBeaconApp* ble_beacon = context;

byte_input_set_result_callback(ble_beacon->byte_input, NULL, NULL, NULL, NULL, 0);
byte_input_set_header_text(ble_beacon->byte_input, NULL);
}
56 changes: 56 additions & 0 deletions applications/examples/example_ble_beacon/scenes/scene_menu.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include "../ble_beacon_app.h"

enum SubmenuIndex {
SubmenuIndexSetMac,
SubmenuIndexSetData,
};

static void ble_beacon_app_scene_menu_submenu_callback(void* context, uint32_t index) {
BleBeaconApp* ble_beacon = context;
view_dispatcher_send_custom_event(ble_beacon->view_dispatcher, index);
}

void ble_beacon_app_scene_menu_on_enter(void* context) {
BleBeaconApp* ble_beacon = context;
Submenu* submenu = ble_beacon->submenu;

submenu_add_item(
submenu,
"Set MAC",
SubmenuIndexSetMac,
ble_beacon_app_scene_menu_submenu_callback,
ble_beacon);
submenu_add_item(
submenu,
"Set Data",
SubmenuIndexSetData,
ble_beacon_app_scene_menu_submenu_callback,
ble_beacon);

view_dispatcher_switch_to_view(ble_beacon->view_dispatcher, BleBeaconAppViewSubmenu);
}

bool ble_beacon_app_scene_menu_on_event(void* context, SceneManagerEvent event) {
BleBeaconApp* ble_beacon = context;
SceneManager* scene_manager = ble_beacon->scene_manager;

bool consumed = false;

if(event.type == SceneManagerEventTypeCustom) {
const uint32_t submenu_index = event.event;
if(submenu_index == SubmenuIndexSetMac) {
scene_manager_next_scene(scene_manager, BleBeaconAppSceneInputMacAddress);
consumed = true;
} else if(submenu_index == SubmenuIndexSetData) {
scene_manager_next_scene(scene_manager, BleBeaconAppSceneInputBeaconData);
consumed = true;
}
}

return consumed;
}

void ble_beacon_app_scene_menu_on_exit(void* context) {
BleBeaconApp* ble_beacon = context;
submenu_reset(ble_beacon->submenu);
}
Loading

0 comments on commit 01d937c

Please sign in to comment.