mirror of
https://github.com/vicliu624/trail-mate.git
synced 2026-10-22 21:22:14 +00:00
WIP: rescue misbranched LXMF and RNode work
This commit is contained in:
1 parent
86f71bf705
commit
d636eb6398
29 files changed
+6048
-50
No files matched your search
@@ -7,6 +7,7 @@
|
||||
#include "app/app_config.h"
|
||||
#include "app/app_facade_access.h"
|
||||
#include "chat/infra/mesh_protocol_utils.h"
|
||||
#include "chat/ports/i_mesh_adapter.h"
|
||||
#include "chat/usecase/contact_service.h"
|
||||
#include "platform/ui/gps_runtime.h"
|
||||
#include "platform/ui/screen_runtime.h"
|
||||
@@ -130,6 +131,36 @@ std::string base_conversation_name(const chat::ConversationId& conv)
|
||||
return buf;
|
||||
}
|
||||
|
||||
chat::MeshCapabilities active_mesh_capabilities()
|
||||
{
|
||||
chat::IMeshAdapter* adapter = app::messagingFacade().getMeshAdapter();
|
||||
return adapter ? adapter->getCapabilities() : chat::MeshCapabilities{};
|
||||
}
|
||||
|
||||
bool supports_local_text_chat()
|
||||
{
|
||||
return active_mesh_capabilities().supports_unicast_text;
|
||||
}
|
||||
|
||||
bool supports_team_chat()
|
||||
{
|
||||
return active_mesh_capabilities().supports_unicast_appdata;
|
||||
}
|
||||
|
||||
const char* local_text_chat_unavailable_message()
|
||||
{
|
||||
return (active_mesh_protocol() == chat::MeshProtocol::RNode)
|
||||
? "RNode text chat runs on host"
|
||||
: "Text chat unavailable";
|
||||
}
|
||||
|
||||
const char* team_chat_unavailable_message()
|
||||
{
|
||||
return (active_mesh_protocol() == chat::MeshProtocol::RNode)
|
||||
? "Team chat unavailable in RNode mode"
|
||||
: "Team chat unavailable";
|
||||
}
|
||||
|
||||
chat::ConversationId teamConversationId()
|
||||
{
|
||||
return chat::ConversationId(kTeamChatChannel, 0, active_mesh_protocol());
|
||||
@@ -597,7 +628,9 @@ void UiController::switchToConversation(chat::ConversationId conv)
|
||||
conversation_->setActionCallback(handle_conversation_action, this);
|
||||
conversation_->setBackCallback(handle_conversation_back, this);
|
||||
}
|
||||
const bool can_reply = team_conv_active_ || (conv.protocol == active_mesh_protocol());
|
||||
const bool can_reply = team_conv_active_
|
||||
? supports_team_chat()
|
||||
: (conv.protocol == active_mesh_protocol() && supports_local_text_chat());
|
||||
conversation_->setReplyEnabled(can_reply);
|
||||
|
||||
if (team_conv_active_)
|
||||
@@ -668,6 +701,16 @@ void UiController::switchToCompose(chat::ConversationId conv)
|
||||
::ui::SystemNotification::show("Conversation protocol mismatch", 2000);
|
||||
return;
|
||||
}
|
||||
if (!is_team_conv && !supports_local_text_chat())
|
||||
{
|
||||
::ui::SystemNotification::show(local_text_chat_unavailable_message(), 2200);
|
||||
return;
|
||||
}
|
||||
if (is_team_conv && !supports_team_chat())
|
||||
{
|
||||
::ui::SystemNotification::show(team_chat_unavailable_message(), 2200);
|
||||
return;
|
||||
}
|
||||
|
||||
state_ = State::Compose;
|
||||
current_channel_ = conv.channel;
|
||||
@@ -788,6 +831,11 @@ void UiController::handleSendMessage(const std::string& text)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (!supports_local_text_chat())
|
||||
{
|
||||
::ui::SystemNotification::show(local_text_chat_unavailable_message(), 2200);
|
||||
return;
|
||||
}
|
||||
service_.sendText(current_channel_, text, current_conv_.peer);
|
||||
}
|
||||
|
||||
@@ -1873,6 +1921,16 @@ void UiController::handleConversationAction(ChatConversationScreen::ActionIntent
|
||||
::ui::SystemNotification::show("Reply disabled for this protocol", 2000);
|
||||
return;
|
||||
}
|
||||
if (!team_conv_active_ && !supports_local_text_chat())
|
||||
{
|
||||
::ui::SystemNotification::show(local_text_chat_unavailable_message(), 2200);
|
||||
return;
|
||||
}
|
||||
if (team_conv_active_ && !supports_team_chat())
|
||||
{
|
||||
::ui::SystemNotification::show(team_chat_unavailable_message(), 2200);
|
||||
return;
|
||||
}
|
||||
switchToCompose(current_conv_);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,6 +316,10 @@ static const char* node_protocol_short_label(chat::contacts::NodeProtocolType pr
|
||||
{
|
||||
switch (protocol)
|
||||
{
|
||||
case chat::contacts::NodeProtocolType::LXMF:
|
||||
return "LX";
|
||||
case chat::contacts::NodeProtocolType::RNode:
|
||||
return "RN";
|
||||
case chat::contacts::NodeProtocolType::MeshCore:
|
||||
return "MC";
|
||||
case chat::contacts::NodeProtocolType::Meshtastic:
|
||||
@@ -333,6 +337,12 @@ static bool node_protocol_to_mesh(chat::contacts::NodeProtocolType protocol, cha
|
||||
}
|
||||
switch (protocol)
|
||||
{
|
||||
case chat::contacts::NodeProtocolType::LXMF:
|
||||
*out = chat::MeshProtocol::LXMF;
|
||||
return true;
|
||||
case chat::contacts::NodeProtocolType::RNode:
|
||||
*out = chat::MeshProtocol::RNode;
|
||||
return true;
|
||||
case chat::contacts::NodeProtocolType::MeshCore:
|
||||
*out = chat::MeshProtocol::MeshCore;
|
||||
return true;
|
||||
@@ -375,9 +385,62 @@ static constexpr DiscoveryActionSpec kDiscoveryActionSpecs[] = {
|
||||
{"Cancel", "Back", DiscoveryActionCommand::Cancel},
|
||||
};
|
||||
|
||||
static chat::MeshCapabilities active_mesh_capabilities()
|
||||
{
|
||||
chat::IMeshAdapter* adapter = app::messagingFacade().getMeshAdapter();
|
||||
return adapter ? adapter->getCapabilities() : chat::MeshCapabilities{};
|
||||
}
|
||||
|
||||
static bool supports_local_text_chat()
|
||||
{
|
||||
return active_mesh_capabilities().supports_unicast_text;
|
||||
}
|
||||
|
||||
static bool supports_team_chat()
|
||||
{
|
||||
return active_mesh_capabilities().supports_unicast_appdata;
|
||||
}
|
||||
|
||||
static const char* local_text_chat_unavailable_message()
|
||||
{
|
||||
return (active_mesh_protocol() == chat::MeshProtocol::RNode)
|
||||
? "RNode text chat runs on host"
|
||||
: "Text chat unavailable";
|
||||
}
|
||||
|
||||
static const char* team_chat_unavailable_message()
|
||||
{
|
||||
return (active_mesh_protocol() == chat::MeshProtocol::RNode)
|
||||
? "Team chat unavailable in RNode mode"
|
||||
: "Team chat unavailable";
|
||||
}
|
||||
|
||||
static const char* broadcast_chat_unavailable_message(const BroadcastTargetSpec& spec)
|
||||
{
|
||||
if (spec.protocol == chat::MeshProtocol::Meshtastic)
|
||||
{
|
||||
return "MT send uses slot 0/1 only";
|
||||
}
|
||||
if (spec.protocol == chat::MeshProtocol::RNode)
|
||||
{
|
||||
return "RNode text chat runs on host";
|
||||
}
|
||||
return "Chat unavailable";
|
||||
}
|
||||
|
||||
static size_t get_broadcast_target_count()
|
||||
{
|
||||
return (active_mesh_protocol() == chat::MeshProtocol::Meshtastic) ? 8U : 2U;
|
||||
switch (active_mesh_protocol())
|
||||
{
|
||||
case chat::MeshProtocol::Meshtastic:
|
||||
return 8U;
|
||||
case chat::MeshProtocol::MeshCore:
|
||||
return 2U;
|
||||
case chat::MeshProtocol::RNode:
|
||||
return 1U;
|
||||
default:
|
||||
return 0U;
|
||||
}
|
||||
}
|
||||
|
||||
static bool get_broadcast_target_spec(int index, BroadcastTargetSpec* out)
|
||||
@@ -403,6 +466,20 @@ static bool get_broadcast_target_spec(int index, BroadcastTargetSpec* out)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (active_mesh_protocol() == chat::MeshProtocol::RNode)
|
||||
{
|
||||
if (index != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
out->protocol = chat::MeshProtocol::RNode;
|
||||
out->channel = chat::ChannelId::PRIMARY;
|
||||
out->channel_index = 0;
|
||||
out->enabled = true;
|
||||
out->chat_supported = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
@@ -432,6 +509,10 @@ static std::string format_broadcast_target_label(const BroadcastTargetSpec& spec
|
||||
snprintf(buf, sizeof(buf), "[MT] Slot %u", static_cast<unsigned>(spec.channel_index));
|
||||
return std::string(buf);
|
||||
}
|
||||
if (spec.protocol == chat::MeshProtocol::RNode)
|
||||
{
|
||||
return "[RN] Modem Bridge";
|
||||
}
|
||||
return (spec.channel == chat::ChannelId::SECONDARY) ? "[MC] Secondary" : "[MC] Primary";
|
||||
}
|
||||
|
||||
@@ -453,6 +534,10 @@ static std::string format_broadcast_target_status(const BroadcastTargetSpec& spe
|
||||
}
|
||||
return spec.chat_supported ? "Ready" : "Slot";
|
||||
}
|
||||
if (spec.protocol == chat::MeshProtocol::RNode)
|
||||
{
|
||||
return "Host bridge";
|
||||
}
|
||||
return "Ready";
|
||||
}
|
||||
|
||||
@@ -736,7 +821,7 @@ static void on_list_item_clicked(lv_event_t* e)
|
||||
BroadcastTargetSpec spec{};
|
||||
if (get_selected_broadcast_target(&spec, nullptr) && !spec.chat_supported)
|
||||
{
|
||||
::ui::SystemNotification::show("MT send uses slot 0/1 only", 2200);
|
||||
::ui::SystemNotification::show(broadcast_chat_unavailable_message(spec), 2200);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1225,7 +1310,7 @@ static void open_chat_compose()
|
||||
}
|
||||
if (!target_spec.chat_supported)
|
||||
{
|
||||
::ui::SystemNotification::show("MT send uses slot 0/1 only", 2200);
|
||||
::ui::SystemNotification::show(broadcast_chat_unavailable_message(target_spec), 2200);
|
||||
return;
|
||||
}
|
||||
protocol = target_spec.protocol;
|
||||
@@ -1235,6 +1320,11 @@ static void open_chat_compose()
|
||||
}
|
||||
else if (g_contacts_state.current_mode == ContactsMode::Team)
|
||||
{
|
||||
if (!supports_team_chat())
|
||||
{
|
||||
::ui::SystemNotification::show(team_chat_unavailable_message(), 2200);
|
||||
return;
|
||||
}
|
||||
channel = chat::ChannelId::PRIMARY;
|
||||
peer_id = 0;
|
||||
title = team::ui::g_team_state.team_name.empty()
|
||||
@@ -1243,6 +1333,11 @@ static void open_chat_compose()
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!supports_local_text_chat())
|
||||
{
|
||||
::ui::SystemNotification::show(local_text_chat_unavailable_message(), 2200);
|
||||
return;
|
||||
}
|
||||
channel = chat::ChannelId::PRIMARY;
|
||||
peer_id = node->node_id;
|
||||
chat::MeshProtocol node_protocol = protocol;
|
||||
@@ -1251,7 +1346,7 @@ static void open_chat_compose()
|
||||
{
|
||||
char buf[64];
|
||||
snprintf(buf, sizeof(buf), "Switch to %s to chat",
|
||||
(node_protocol == chat::MeshProtocol::MeshCore) ? "MeshCore" : "Meshtastic");
|
||||
chat::infra::meshProtocolName(node_protocol));
|
||||
::ui::SystemNotification::show(buf, 2200);
|
||||
return;
|
||||
}
|
||||
@@ -1531,6 +1626,13 @@ static void on_compose_action(chat::ui::ChatComposeScreen::ActionIntent intent,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!supports_local_text_chat())
|
||||
{
|
||||
::ui::SystemNotification::show(local_text_chat_unavailable_message(), 2200);
|
||||
close_chat_compose();
|
||||
return;
|
||||
}
|
||||
|
||||
std::string text = g_contacts_state.compose_screen->getText();
|
||||
if (!text.empty())
|
||||
{
|
||||
@@ -2155,7 +2257,9 @@ static void open_action_menu_modal()
|
||||
(g_contacts_state.current_mode == ContactsMode::Contacts ||
|
||||
g_contacts_state.current_mode == ContactsMode::Nearby);
|
||||
|
||||
int action_count = 2; // Chat + Cancel
|
||||
const bool allow_chat_action =
|
||||
(g_contacts_state.current_mode == ContactsMode::Team) ? supports_team_chat() : supports_local_text_chat();
|
||||
int action_count = allow_chat_action ? 2 : 1; // Chat + Cancel
|
||||
if (g_contacts_state.current_mode == ContactsMode::Contacts)
|
||||
{
|
||||
action_count += 3; // Edit/Delete/Info
|
||||
@@ -2255,7 +2359,10 @@ static void open_action_menu_modal()
|
||||
}
|
||||
};
|
||||
|
||||
add_action(ActionMenuCommand::Chat, "Chat");
|
||||
if (allow_chat_action)
|
||||
{
|
||||
add_action(ActionMenuCommand::Chat, "Chat");
|
||||
}
|
||||
if (g_contacts_state.current_mode == ContactsMode::Contacts)
|
||||
{
|
||||
add_action(ActionMenuCommand::Edit, "Edit");
|
||||
@@ -2324,7 +2431,7 @@ void refresh_ui()
|
||||
lv_obj_clear_flag(g_contacts_state.sub_container, LV_OBJ_FLAG_SCROLLABLE);
|
||||
}
|
||||
|
||||
bool team_available = is_team_available();
|
||||
bool team_available = is_team_available() && supports_team_chat();
|
||||
const bool meshcore_mode = (active_mesh_protocol() == chat::MeshProtocol::MeshCore);
|
||||
if (g_contacts_state.team_btn)
|
||||
{
|
||||
@@ -2450,7 +2557,11 @@ void refresh_ui()
|
||||
target.display_name = format_broadcast_target_label(spec);
|
||||
target.protocol = (spec.protocol == chat::MeshProtocol::MeshCore)
|
||||
? chat::contacts::NodeProtocolType::MeshCore
|
||||
: chat::contacts::NodeProtocolType::Meshtastic;
|
||||
: ((spec.protocol == chat::MeshProtocol::LXMF)
|
||||
? chat::contacts::NodeProtocolType::LXMF
|
||||
: ((spec.protocol == chat::MeshProtocol::RNode)
|
||||
? chat::contacts::NodeProtocolType::RNode
|
||||
: chat::contacts::NodeProtocolType::Meshtastic));
|
||||
target.channel = spec.channel_index;
|
||||
broadcast_list.push_back(target);
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "app/app_config.h"
|
||||
#include "app/app_facade_access.h"
|
||||
#include "chat/domain/chat_types.h"
|
||||
#include "chat/infra/mesh_protocol_utils.h"
|
||||
#include "chat/infra/meshtastic/mt_region.h"
|
||||
#include "ui/components/info_card.h"
|
||||
#include "ui/components/two_pane_layout.h"
|
||||
@@ -51,7 +52,33 @@ void format_contacts_title(char* out, size_t out_len)
|
||||
snprintf(out, out_len, "Contacts (MeshCore)");
|
||||
return;
|
||||
}
|
||||
snprintf(out, out_len, "Contacts");
|
||||
if (protocol == chat::MeshProtocol::RNode)
|
||||
{
|
||||
const chat::MeshConfig& rnode = app_ctx.getConfig().rnode_config;
|
||||
if (rnode.override_frequency_mhz > 0.0f)
|
||||
{
|
||||
snprintf(out, out_len, "Contacts (RNode - %.3fMHz)", rnode.override_frequency_mhz);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(out, out_len, "Contacts (RNode)");
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (protocol == chat::MeshProtocol::LXMF)
|
||||
{
|
||||
const chat::MeshConfig& lxmf = app_ctx.getConfig().rnode_config;
|
||||
if (lxmf.override_frequency_mhz > 0.0f)
|
||||
{
|
||||
snprintf(out, out_len, "Contacts (LXMF - %.3fMHz)", lxmf.override_frequency_mhz);
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(out, out_len, "Contacts (LXMF)");
|
||||
}
|
||||
return;
|
||||
}
|
||||
snprintf(out, out_len, "Contacts (%s)", chat::infra::meshProtocolName(protocol));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#if defined(ARDUINO) || defined(ESP_PLATFORM)
|
||||
|
||||
#include "app/app_config.h"
|
||||
#include "app/app_facade_access.h"
|
||||
#include "platform/ui/hostlink_runtime.h"
|
||||
#include "ui/app_runtime.h"
|
||||
#include "ui/assets/fonts/fonts.h"
|
||||
@@ -37,8 +39,42 @@ void request_exit()
|
||||
ui_request_exit_to_menu();
|
||||
}
|
||||
|
||||
bool use_rnode_bridge()
|
||||
{
|
||||
return app::appFacade().getConfig().mesh_protocol == chat::MeshProtocol::RNode;
|
||||
}
|
||||
|
||||
const char* page_title()
|
||||
{
|
||||
return use_rnode_bridge() ? "RNode Bridge" : "Data Exchange";
|
||||
}
|
||||
|
||||
const char* page_subtitle()
|
||||
{
|
||||
return use_rnode_bridge() ? "USB CDC KISS modem for Reticulum" : "Data Exchange";
|
||||
}
|
||||
|
||||
const char* status_text(platform::ui::hostlink::LinkState state)
|
||||
{
|
||||
if (use_rnode_bridge())
|
||||
{
|
||||
switch (state)
|
||||
{
|
||||
case platform::ui::hostlink::LinkState::Stopped:
|
||||
case platform::ui::hostlink::LinkState::Waiting:
|
||||
return "Waiting for Reticulum host...";
|
||||
case platform::ui::hostlink::LinkState::Connected:
|
||||
case platform::ui::hostlink::LinkState::Handshaking:
|
||||
return "Host connected, probing modem...";
|
||||
case platform::ui::hostlink::LinkState::Ready:
|
||||
return "RNode modem ready";
|
||||
case platform::ui::hostlink::LinkState::Error:
|
||||
return "Bridge error";
|
||||
default:
|
||||
return "Waiting for Reticulum host...";
|
||||
}
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case platform::ui::hostlink::LinkState::Stopped:
|
||||
@@ -133,7 +169,7 @@ void enter(const shell::Host* host, lv_obj_t* parent)
|
||||
lv_obj_add_event_cb(s_root, root_key_event_cb, LV_EVENT_KEY, nullptr);
|
||||
|
||||
::ui::widgets::top_bar_init(s_top_bar, s_root);
|
||||
::ui::widgets::top_bar_set_title(s_top_bar, "Data Exchange");
|
||||
::ui::widgets::top_bar_set_title(s_top_bar, page_title());
|
||||
::ui::widgets::top_bar_set_back_callback(s_top_bar, on_back, nullptr);
|
||||
if (s_top_bar.back_btn)
|
||||
{
|
||||
@@ -173,7 +209,7 @@ void enter(const shell::Host* host, lv_obj_t* parent)
|
||||
lv_obj_center(stack);
|
||||
|
||||
lv_obj_t* title = lv_label_create(stack);
|
||||
lv_label_set_text(title, "Data Exchange");
|
||||
lv_label_set_text(title, page_subtitle());
|
||||
lv_obj_set_style_text_font(title, &lv_font_montserrat_18, 0);
|
||||
|
||||
s_status_label = lv_label_create(stack);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "app/app_facade_access.h"
|
||||
#include "board/BoardBase.h"
|
||||
#include "chat/domain/chat_types.h"
|
||||
#include "chat/infra/mesh_protocol_utils.h"
|
||||
#include "chat/infra/meshcore/mc_region_presets.h"
|
||||
#include "chat/infra/meshtastic/mt_region.h"
|
||||
#include "meshtastic/config.pb.h"
|
||||
@@ -399,12 +400,31 @@ static bool parse_float_text(const char* text, float* out_value)
|
||||
return true;
|
||||
}
|
||||
|
||||
static chat::MeshProtocol selected_protocol()
|
||||
{
|
||||
return static_cast<chat::MeshProtocol>(g_settings.chat_protocol);
|
||||
}
|
||||
|
||||
static bool is_meshcore_protocol_selected()
|
||||
{
|
||||
return selected_protocol() == chat::MeshProtocol::MeshCore;
|
||||
}
|
||||
|
||||
static bool is_rnode_protocol_selected()
|
||||
{
|
||||
return selected_protocol() == chat::MeshProtocol::RNode ||
|
||||
selected_protocol() == chat::MeshProtocol::LXMF;
|
||||
}
|
||||
|
||||
static void reset_mesh_settings()
|
||||
{
|
||||
app::IAppFacade& app_ctx = app::appFacade();
|
||||
app_ctx.getConfig().meshtastic_config = chat::MeshConfig();
|
||||
app_ctx.getConfig().meshtastic_config.region = app::AppConfig::kDefaultRegionCode;
|
||||
app_ctx.getConfig().meshcore_config = chat::MeshConfig();
|
||||
app_ctx.getConfig().applyMeshCoreFactoryDefaults();
|
||||
app_ctx.getConfig().rnode_config = chat::MeshConfig();
|
||||
app_ctx.getConfig().applyRNodeFactoryDefaults();
|
||||
strncpy(app_ctx.getConfig().meshcore_config.meshcore_channel_name, "Public",
|
||||
sizeof(app_ctx.getConfig().meshcore_config.meshcore_channel_name) - 1);
|
||||
app_ctx.getConfig().meshcore_config.meshcore_channel_name[sizeof(app_ctx.getConfig().meshcore_config.meshcore_channel_name) - 1] = '\0';
|
||||
@@ -417,12 +437,9 @@ static void reset_mesh_settings()
|
||||
g_settings.chat_psk[0] = '\0';
|
||||
g_settings.net_use_preset = app_ctx.getConfig().meshtastic_config.use_preset;
|
||||
g_settings.net_modem_preset = app_ctx.getConfig().meshtastic_config.modem_preset;
|
||||
g_settings.net_tx_power = app_ctx.getConfig().meshtastic_config.tx_power;
|
||||
g_settings.net_tx_power = app_ctx.getConfig().activeMeshConfig().tx_power;
|
||||
g_settings.net_hop_limit = app_ctx.getConfig().meshtastic_config.hop_limit;
|
||||
const chat::MeshConfig& active_cfg =
|
||||
(app_ctx.getConfig().mesh_protocol == chat::MeshProtocol::MeshCore)
|
||||
? app_ctx.getConfig().meshcore_config
|
||||
: app_ctx.getConfig().meshtastic_config;
|
||||
const chat::MeshConfig& active_cfg = app_ctx.getConfig().activeMeshConfig();
|
||||
g_settings.net_tx_enabled = active_cfg.tx_enabled;
|
||||
g_settings.net_relay = app_ctx.getConfig().meshtastic_config.enable_relay;
|
||||
g_settings.net_duty_cycle = true;
|
||||
@@ -576,12 +593,20 @@ static void settings_load()
|
||||
const app::AppConfig& cfg = app_ctx.getConfig();
|
||||
const chat::MeshConfig& mt_cfg = cfg.meshtastic_config;
|
||||
const chat::MeshConfig& mc_cfg = cfg.meshcore_config;
|
||||
const chat::MeshConfig& rn_cfg = cfg.rnode_config;
|
||||
|
||||
g_settings.chat_region = mt_cfg.region;
|
||||
g_settings.chat_channel = cfg.chat_channel;
|
||||
const uint8_t* active_psk =
|
||||
(cfg.mesh_protocol == chat::MeshProtocol::MeshCore) ? mc_cfg.secondary_key : mt_cfg.secondary_key;
|
||||
if (is_zero_key(active_psk, sizeof(mt_cfg.secondary_key)))
|
||||
const uint8_t* active_psk = nullptr;
|
||||
if (cfg.mesh_protocol == chat::MeshProtocol::MeshCore)
|
||||
{
|
||||
active_psk = mc_cfg.secondary_key;
|
||||
}
|
||||
else if (cfg.mesh_protocol == chat::MeshProtocol::Meshtastic)
|
||||
{
|
||||
active_psk = mt_cfg.secondary_key;
|
||||
}
|
||||
if (!active_psk || is_zero_key(active_psk, sizeof(mt_cfg.secondary_key)))
|
||||
{
|
||||
g_settings.chat_psk[0] = '\0';
|
||||
}
|
||||
@@ -593,24 +618,38 @@ static void settings_load()
|
||||
sizeof(g_settings.chat_psk));
|
||||
}
|
||||
|
||||
g_settings.net_use_preset = mt_cfg.use_preset;
|
||||
g_settings.net_modem_preset = mt_cfg.modem_preset;
|
||||
g_settings.net_manual_bw = static_cast<int>(std::lround(mt_cfg.bandwidth_khz));
|
||||
g_settings.net_manual_sf = mt_cfg.spread_factor;
|
||||
g_settings.net_manual_cr = mt_cfg.coding_rate;
|
||||
int tx_power = mt_cfg.tx_power;
|
||||
if (cfg.mesh_protocol == chat::MeshProtocol::RNode ||
|
||||
cfg.mesh_protocol == chat::MeshProtocol::LXMF)
|
||||
{
|
||||
g_settings.net_use_preset = 0;
|
||||
g_settings.net_modem_preset = 0;
|
||||
g_settings.net_manual_bw = static_cast<int>(std::lround(rn_cfg.bandwidth_khz));
|
||||
g_settings.net_manual_sf = rn_cfg.spread_factor;
|
||||
g_settings.net_manual_cr = rn_cfg.coding_rate;
|
||||
float_to_text(rn_cfg.override_frequency_mhz, g_settings.net_override_freq,
|
||||
sizeof(g_settings.net_override_freq), 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_settings.net_use_preset = mt_cfg.use_preset;
|
||||
g_settings.net_modem_preset = mt_cfg.modem_preset;
|
||||
g_settings.net_manual_bw = static_cast<int>(std::lround(mt_cfg.bandwidth_khz));
|
||||
g_settings.net_manual_sf = mt_cfg.spread_factor;
|
||||
g_settings.net_manual_cr = mt_cfg.coding_rate;
|
||||
float_to_text(mt_cfg.override_frequency_mhz, g_settings.net_override_freq,
|
||||
sizeof(g_settings.net_override_freq), 3);
|
||||
}
|
||||
|
||||
int tx_power = cfg.activeMeshConfig().tx_power;
|
||||
if (tx_power < kNetTxPowerMin) tx_power = kNetTxPowerMin;
|
||||
if (tx_power > kNetTxPowerMax) tx_power = kNetTxPowerMax;
|
||||
g_settings.net_tx_power = tx_power;
|
||||
g_settings.net_hop_limit = mt_cfg.hop_limit;
|
||||
g_settings.net_tx_enabled = (cfg.mesh_protocol == chat::MeshProtocol::MeshCore)
|
||||
? mc_cfg.tx_enabled
|
||||
: mt_cfg.tx_enabled;
|
||||
g_settings.net_tx_enabled = cfg.activeMeshConfig().tx_enabled;
|
||||
g_settings.net_override_duty_cycle = mt_cfg.override_duty_cycle;
|
||||
g_settings.net_channel_num = mt_cfg.channel_num;
|
||||
g_settings.net_relay = mt_cfg.enable_relay;
|
||||
float_to_text(mt_cfg.frequency_offset_mhz, g_settings.net_freq_offset, sizeof(g_settings.net_freq_offset), 3);
|
||||
float_to_text(mt_cfg.override_frequency_mhz, g_settings.net_override_freq, sizeof(g_settings.net_override_freq), 3);
|
||||
g_settings.net_duty_cycle = cfg.net_duty_cycle;
|
||||
g_settings.net_channel_util = cfg.net_channel_util;
|
||||
|
||||
@@ -900,7 +939,15 @@ static void on_text_save_clicked(lv_event_t* e)
|
||||
modal_close();
|
||||
return;
|
||||
}
|
||||
app_ctx.getConfig().meshtastic_config.override_frequency_mhz = value;
|
||||
if (app_ctx.getConfig().mesh_protocol == chat::MeshProtocol::RNode ||
|
||||
app_ctx.getConfig().mesh_protocol == chat::MeshProtocol::LXMF)
|
||||
{
|
||||
app_ctx.getConfig().rnode_config.override_frequency_mhz = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
app_ctx.getConfig().meshtastic_config.override_frequency_mhz = value;
|
||||
}
|
||||
app_ctx.saveConfig();
|
||||
app_ctx.applyMeshConfig();
|
||||
}
|
||||
@@ -1169,10 +1216,18 @@ static void on_option_clicked(lv_event_t* e)
|
||||
if (payload->item->pref_key && strcmp(payload->item->pref_key, "net_bw") == 0)
|
||||
{
|
||||
app::IAppFacade& app_ctx = app::appFacade();
|
||||
app_ctx.getConfig().meshtastic_config.bandwidth_khz = static_cast<float>(payload->value);
|
||||
app_ctx.getConfig().meshtastic_config.use_preset = false;
|
||||
g_settings.net_use_preset = false;
|
||||
prefs_put_int("net_use_preset", 0);
|
||||
if (app_ctx.getConfig().mesh_protocol == chat::MeshProtocol::RNode ||
|
||||
app_ctx.getConfig().mesh_protocol == chat::MeshProtocol::LXMF)
|
||||
{
|
||||
app_ctx.getConfig().rnode_config.bandwidth_khz = static_cast<float>(payload->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
app_ctx.getConfig().meshtastic_config.bandwidth_khz = static_cast<float>(payload->value);
|
||||
app_ctx.getConfig().meshtastic_config.use_preset = false;
|
||||
g_settings.net_use_preset = false;
|
||||
prefs_put_int("net_use_preset", 0);
|
||||
}
|
||||
app_ctx.saveConfig();
|
||||
app_ctx.applyMeshConfig();
|
||||
rebuild_list = true;
|
||||
@@ -1180,10 +1235,18 @@ static void on_option_clicked(lv_event_t* e)
|
||||
if (payload->item->pref_key && strcmp(payload->item->pref_key, "net_sf") == 0)
|
||||
{
|
||||
app::IAppFacade& app_ctx = app::appFacade();
|
||||
app_ctx.getConfig().meshtastic_config.spread_factor = static_cast<uint8_t>(payload->value);
|
||||
app_ctx.getConfig().meshtastic_config.use_preset = false;
|
||||
g_settings.net_use_preset = false;
|
||||
prefs_put_int("net_use_preset", 0);
|
||||
if (app_ctx.getConfig().mesh_protocol == chat::MeshProtocol::RNode ||
|
||||
app_ctx.getConfig().mesh_protocol == chat::MeshProtocol::LXMF)
|
||||
{
|
||||
app_ctx.getConfig().rnode_config.spread_factor = static_cast<uint8_t>(payload->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
app_ctx.getConfig().meshtastic_config.spread_factor = static_cast<uint8_t>(payload->value);
|
||||
app_ctx.getConfig().meshtastic_config.use_preset = false;
|
||||
g_settings.net_use_preset = false;
|
||||
prefs_put_int("net_use_preset", 0);
|
||||
}
|
||||
app_ctx.saveConfig();
|
||||
app_ctx.applyMeshConfig();
|
||||
rebuild_list = true;
|
||||
@@ -1191,10 +1254,18 @@ static void on_option_clicked(lv_event_t* e)
|
||||
if (payload->item->pref_key && strcmp(payload->item->pref_key, "net_cr") == 0)
|
||||
{
|
||||
app::IAppFacade& app_ctx = app::appFacade();
|
||||
app_ctx.getConfig().meshtastic_config.coding_rate = static_cast<uint8_t>(payload->value);
|
||||
app_ctx.getConfig().meshtastic_config.use_preset = false;
|
||||
g_settings.net_use_preset = false;
|
||||
prefs_put_int("net_use_preset", 0);
|
||||
if (app_ctx.getConfig().mesh_protocol == chat::MeshProtocol::RNode ||
|
||||
app_ctx.getConfig().mesh_protocol == chat::MeshProtocol::LXMF)
|
||||
{
|
||||
app_ctx.getConfig().rnode_config.coding_rate = static_cast<uint8_t>(payload->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
app_ctx.getConfig().meshtastic_config.coding_rate = static_cast<uint8_t>(payload->value);
|
||||
app_ctx.getConfig().meshtastic_config.use_preset = false;
|
||||
g_settings.net_use_preset = false;
|
||||
prefs_put_int("net_use_preset", 0);
|
||||
}
|
||||
app_ctx.saveConfig();
|
||||
app_ctx.applyMeshConfig();
|
||||
rebuild_list = true;
|
||||
@@ -1322,7 +1393,15 @@ static void on_option_clicked(lv_event_t* e)
|
||||
if (payload->item->pref_key && strcmp(payload->item->pref_key, "net_tx_power") == 0)
|
||||
{
|
||||
app::IAppFacade& app_ctx = app::appFacade();
|
||||
app_ctx.getConfig().meshtastic_config.tx_power = static_cast<int8_t>(payload->value);
|
||||
if (app_ctx.getConfig().mesh_protocol == chat::MeshProtocol::RNode ||
|
||||
app_ctx.getConfig().mesh_protocol == chat::MeshProtocol::LXMF)
|
||||
{
|
||||
app_ctx.getConfig().rnode_config.tx_power = static_cast<int8_t>(payload->value);
|
||||
}
|
||||
else
|
||||
{
|
||||
app_ctx.getConfig().meshtastic_config.tx_power = static_cast<int8_t>(payload->value);
|
||||
}
|
||||
app_ctx.saveConfig();
|
||||
app_ctx.applyMeshConfig();
|
||||
}
|
||||
@@ -1607,6 +1686,8 @@ static const settings::ui::SettingOption kChatChannelOptions[] = {
|
||||
static const settings::ui::SettingOption kChatProtocolOptions[] = {
|
||||
{"Meshtastic", static_cast<int>(chat::MeshProtocol::Meshtastic)},
|
||||
{"MeshCore", static_cast<int>(chat::MeshProtocol::MeshCore)},
|
||||
{"LXMF", static_cast<int>(chat::MeshProtocol::LXMF)},
|
||||
{"RNode Bridge", static_cast<int>(chat::MeshProtocol::RNode)},
|
||||
};
|
||||
|
||||
static const settings::ui::SettingOption kNetPresetOptions[] = {
|
||||
@@ -1801,7 +1882,7 @@ static settings::ui::SettingItem kMapItems[] = {
|
||||
static settings::ui::SettingItem kChatItems[] = {
|
||||
{"User Name", settings::ui::SettingType::Text, nullptr, 0, nullptr, nullptr, g_settings.user_name, sizeof(g_settings.user_name), false, "chat_user"},
|
||||
{"Short Name", settings::ui::SettingType::Text, nullptr, 0, nullptr, nullptr, g_settings.short_name, sizeof(g_settings.short_name), false, "chat_short"},
|
||||
{"Protocol", settings::ui::SettingType::Enum, kChatProtocolOptions, 2, &g_settings.chat_protocol, nullptr, nullptr, 0, false, "mesh_protocol"},
|
||||
{"Protocol", settings::ui::SettingType::Enum, kChatProtocolOptions, 4, &g_settings.chat_protocol, nullptr, nullptr, 0, false, "mesh_protocol"},
|
||||
{"Region", settings::ui::SettingType::Enum, kChatRegionOptions, 0, &g_settings.chat_region, nullptr, nullptr, 0, false, "chat_region"},
|
||||
{"Channel", settings::ui::SettingType::Enum, kChatChannelOptions, 2, &g_settings.chat_channel, nullptr, nullptr, 0, false, "chat_channel"},
|
||||
{"Channel Key / PSK", settings::ui::SettingType::Text, nullptr, 0, nullptr, nullptr, g_settings.chat_psk, sizeof(g_settings.chat_psk), true, "chat_psk"},
|
||||
@@ -1954,7 +2035,8 @@ static bool should_show_item(const settings::ui::SettingItem& item)
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool meshcore = (g_settings.chat_protocol == static_cast<int>(chat::MeshProtocol::MeshCore));
|
||||
const bool meshcore = is_meshcore_protocol_selected();
|
||||
const bool rnode = is_rnode_protocol_selected();
|
||||
|
||||
// Relay is currently not implemented as real forwarding in Meshtastic path.
|
||||
if (has_pref_key(item, "net_relay"))
|
||||
@@ -1986,6 +2068,38 @@ static bool should_show_item(const settings::ui::SettingItem& item)
|
||||
if (has_pref_key(item, "net_freq_offset")) return false;
|
||||
if (has_pref_key(item, "net_override_freq")) return false;
|
||||
}
|
||||
else if (rnode)
|
||||
{
|
||||
if (has_pref_key(item, "chat_region")) return false;
|
||||
if (has_pref_key(item, "chat_channel")) return false;
|
||||
if (has_pref_key(item, "chat_psk")) return false;
|
||||
if (has_pref_key(item, "privacy_encrypt")) return false;
|
||||
if (has_pref_key(item, "privacy_pki")) return false;
|
||||
|
||||
if (has_pref_key(item, "net_use_preset")) return false;
|
||||
if (has_pref_key(item, "net_preset")) return false;
|
||||
if (has_pref_key(item, "net_hop_limit")) return false;
|
||||
if (has_pref_key(item, "net_override_duty")) return false;
|
||||
if (has_pref_key(item, "net_channel_num")) return false;
|
||||
if (has_pref_key(item, "net_freq_offset")) return false;
|
||||
if (has_pref_key(item, "net_duty_cycle")) return false;
|
||||
if (has_pref_key(item, "net_util")) return false;
|
||||
|
||||
if (has_pref_key(item, "mc_region_preset")) return false;
|
||||
if (has_pref_key(item, "mc_freq")) return false;
|
||||
if (has_pref_key(item, "mc_bw")) return false;
|
||||
if (has_pref_key(item, "mc_sf")) return false;
|
||||
if (has_pref_key(item, "mc_cr")) return false;
|
||||
if (has_pref_key(item, "mc_tx_power")) return false;
|
||||
if (has_pref_key(item, "mc_repeat")) return false;
|
||||
if (has_pref_key(item, "mc_rx_delay")) return false;
|
||||
if (has_pref_key(item, "mc_airtime")) return false;
|
||||
if (has_pref_key(item, "mc_flood_max")) return false;
|
||||
if (has_pref_key(item, "mc_multi_acks")) return false;
|
||||
if (has_pref_key(item, "mc_channel_slot")) return false;
|
||||
if (has_pref_key(item, "mc_channel_name")) return false;
|
||||
if (has_pref_key(item, "mc_channel_key")) return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (has_pref_key(item, "mc_region_preset")) return false;
|
||||
@@ -2149,6 +2263,11 @@ static bool activate_item_widget(settings::ui::ItemWidget& widget)
|
||||
{
|
||||
app_ctx.getConfig().meshcore_config.tx_enabled = *item.bool_value;
|
||||
}
|
||||
else if (app_ctx.getConfig().mesh_protocol == chat::MeshProtocol::RNode ||
|
||||
app_ctx.getConfig().mesh_protocol == chat::MeshProtocol::LXMF)
|
||||
{
|
||||
app_ctx.getConfig().rnode_config.tx_enabled = *item.bool_value;
|
||||
}
|
||||
else
|
||||
{
|
||||
app_ctx.getConfig().meshtastic_config.tx_enabled = *item.bool_value;
|
||||
|
||||
Reference in new issue
Block a user