mirror of
https://github.com/meshtastic/firmware.git
synced 2026-01-29 13:12:04 +00:00
Merge branch 'develop' into InkHUD-Improvements
This commit is contained in:
@@ -438,7 +438,7 @@ void drawLoRaFocused(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x,
|
|||||||
if (currentResolution == ScreenResolution::UltraLow) {
|
if (currentResolution == ScreenResolution::UltraLow) {
|
||||||
snprintf(frequencyslot, sizeof(frequencyslot), "%sMHz (%d)", freqStr, config.lora.channel_num);
|
snprintf(frequencyslot, sizeof(frequencyslot), "%sMHz (%d)", freqStr, config.lora.channel_num);
|
||||||
} else {
|
} else {
|
||||||
snprintf(frequencyslot, sizeof(frequencyslot), "Freq/Ch: %sMHz (%d)", freqStr, config.lora.channel_num);
|
snprintf(frequencyslot, sizeof(frequencyslot), "Freq: %sMHz (%d)", freqStr, config.lora.channel_num);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size_t len = strlen(frequencyslot);
|
size_t len = strlen(frequencyslot);
|
||||||
|
|||||||
@@ -65,12 +65,12 @@ uint8_t test_count = 0;
|
|||||||
|
|
||||||
void menuHandler::loraMenu()
|
void menuHandler::loraMenu()
|
||||||
{
|
{
|
||||||
static const char *optionsArray[] = {"Back", "Device Role", "Radio Preset", "LoRa Region"};
|
static const char *optionsArray[] = {"Back", "Device Role", "Radio Preset", "Frequency Slot", "LoRa Region"};
|
||||||
enum optionsNumbers { Back = 0, device_role_picker = 1, radio_preset_picker = 2, lora_picker = 3 };
|
enum optionsNumbers { Back = 0, device_role_picker = 1, radio_preset_picker = 2, frequency_slot = 3, lora_picker = 4 };
|
||||||
BannerOverlayOptions bannerOptions;
|
BannerOverlayOptions bannerOptions;
|
||||||
bannerOptions.message = "LoRa Actions";
|
bannerOptions.message = "LoRa Actions";
|
||||||
bannerOptions.optionsArrayPtr = optionsArray;
|
bannerOptions.optionsArrayPtr = optionsArray;
|
||||||
bannerOptions.optionsCount = 4;
|
bannerOptions.optionsCount = 5;
|
||||||
bannerOptions.bannerCallback = [](int selected) -> void {
|
bannerOptions.bannerCallback = [](int selected) -> void {
|
||||||
if (selected == Back) {
|
if (selected == Back) {
|
||||||
// No action
|
// No action
|
||||||
@@ -78,6 +78,8 @@ void menuHandler::loraMenu()
|
|||||||
menuHandler::menuQueue = menuHandler::device_role_picker;
|
menuHandler::menuQueue = menuHandler::device_role_picker;
|
||||||
} else if (selected == radio_preset_picker) {
|
} else if (selected == radio_preset_picker) {
|
||||||
menuHandler::menuQueue = menuHandler::radio_preset_picker;
|
menuHandler::menuQueue = menuHandler::radio_preset_picker;
|
||||||
|
} else if (selected == frequency_slot) {
|
||||||
|
menuHandler::menuQueue = menuHandler::frequency_slot;
|
||||||
} else if (selected == lora_picker) {
|
} else if (selected == lora_picker) {
|
||||||
menuHandler::menuQueue = menuHandler::lora_picker;
|
menuHandler::menuQueue = menuHandler::lora_picker;
|
||||||
}
|
}
|
||||||
@@ -248,6 +250,113 @@ void menuHandler::DeviceRolePicker()
|
|||||||
screen->showOverlayBanner(bannerOptions);
|
screen->showOverlayBanner(bannerOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void menuHandler::FrequencySlotPicker()
|
||||||
|
{
|
||||||
|
|
||||||
|
enum ReplyOptions : int { Back = -1 };
|
||||||
|
constexpr int MAX_CHANNEL_OPTIONS = 202;
|
||||||
|
static const char *optionsArray[MAX_CHANNEL_OPTIONS];
|
||||||
|
static int optionsEnumArray[MAX_CHANNEL_OPTIONS];
|
||||||
|
static char channelText[MAX_CHANNEL_OPTIONS - 1][12];
|
||||||
|
int options = 0;
|
||||||
|
optionsArray[options] = "Back";
|
||||||
|
optionsEnumArray[options++] = Back;
|
||||||
|
optionsArray[options] = "Slot 0 (Auto)";
|
||||||
|
optionsEnumArray[options++] = 0;
|
||||||
|
|
||||||
|
// Calculate number of channels (copied from RadioInterface::applyModemConfig())
|
||||||
|
meshtastic_Config_LoRaConfig &loraConfig = config.lora;
|
||||||
|
double bw = loraConfig.bandwidth;
|
||||||
|
if (loraConfig.use_preset) {
|
||||||
|
switch (loraConfig.modem_preset) {
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO:
|
||||||
|
bw = (myRegion->wideLora) ? 1625.0 : 500;
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_FAST:
|
||||||
|
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_SLOW:
|
||||||
|
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_FAST:
|
||||||
|
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_MEDIUM_SLOW:
|
||||||
|
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_TURBO:
|
||||||
|
bw = (myRegion->wideLora) ? 1625.0 : 500;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
bw = (myRegion->wideLora) ? 812.5 : 250;
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_MODERATE:
|
||||||
|
bw = (myRegion->wideLora) ? 406.25 : 125;
|
||||||
|
break;
|
||||||
|
case meshtastic_Config_LoRaConfig_ModemPreset_LONG_SLOW:
|
||||||
|
bw = (myRegion->wideLora) ? 406.25 : 125;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bw = loraConfig.bandwidth;
|
||||||
|
if (bw == 31) // This parameter is not an integer
|
||||||
|
bw = 31.25;
|
||||||
|
if (bw == 62) // Fix for 62.5Khz bandwidth
|
||||||
|
bw = 62.5;
|
||||||
|
if (bw == 200)
|
||||||
|
bw = 203.125;
|
||||||
|
if (bw == 400)
|
||||||
|
bw = 406.25;
|
||||||
|
if (bw == 800)
|
||||||
|
bw = 812.5;
|
||||||
|
if (bw == 1600)
|
||||||
|
bw = 1625.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t numChannels = 0;
|
||||||
|
if (myRegion) {
|
||||||
|
numChannels = (uint32_t)floor((myRegion->freqEnd - myRegion->freqStart) / (myRegion->spacing + (bw / 1000.0)));
|
||||||
|
} else {
|
||||||
|
LOG_WARN("Region not set, cannot calculate number of channels");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numChannels > (uint32_t)(MAX_CHANNEL_OPTIONS - 2))
|
||||||
|
numChannels = (uint32_t)(MAX_CHANNEL_OPTIONS - 2);
|
||||||
|
|
||||||
|
for (uint32_t ch = 1; ch <= numChannels; ch++) {
|
||||||
|
snprintf(channelText[ch - 1], sizeof(channelText[ch - 1]), "Slot %lu", (unsigned long)ch);
|
||||||
|
optionsArray[options] = channelText[ch - 1];
|
||||||
|
optionsEnumArray[options++] = (int)ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
BannerOverlayOptions bannerOptions;
|
||||||
|
bannerOptions.message = "Frequency Slot";
|
||||||
|
bannerOptions.optionsArrayPtr = optionsArray;
|
||||||
|
bannerOptions.optionsEnumPtr = optionsEnumArray;
|
||||||
|
bannerOptions.optionsCount = options;
|
||||||
|
|
||||||
|
// Start highlight on current channel if possible, otherwise on "1"
|
||||||
|
int initial = (int)config.lora.channel_num + 1;
|
||||||
|
if (initial < 2 || initial > (int)numChannels + 1)
|
||||||
|
initial = 1;
|
||||||
|
bannerOptions.InitialSelected = initial;
|
||||||
|
|
||||||
|
bannerOptions.bannerCallback = [](int selected) -> void {
|
||||||
|
if (selected == Back) {
|
||||||
|
menuHandler::menuQueue = menuHandler::lora_Menu;
|
||||||
|
screen->runNow();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
config.lora.channel_num = selected;
|
||||||
|
service->reloadConfig(SEGMENT_CONFIG);
|
||||||
|
rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
screen->showOverlayBanner(bannerOptions);
|
||||||
|
}
|
||||||
|
|
||||||
void menuHandler::RadioPresetPicker()
|
void menuHandler::RadioPresetPicker()
|
||||||
{
|
{
|
||||||
static const RadioPresetOption presetOptions[] = {
|
static const RadioPresetOption presetOptions[] = {
|
||||||
@@ -278,6 +387,8 @@ void menuHandler::RadioPresetPicker()
|
|||||||
}
|
}
|
||||||
|
|
||||||
config.lora.modem_preset = option.value;
|
config.lora.modem_preset = option.value;
|
||||||
|
config.lora.channel_num = 0; // Reset to default channel for the preset
|
||||||
|
config.lora.override_frequency = 0; // Clear any custom frequency
|
||||||
service->reloadConfig(SEGMENT_CONFIG);
|
service->reloadConfig(SEGMENT_CONFIG);
|
||||||
rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000);
|
rebootAtMsec = (millis() + DEFAULT_REBOOT_SECONDS * 1000);
|
||||||
});
|
});
|
||||||
@@ -2551,6 +2662,9 @@ void menuHandler::handleMenuSwitch(OLEDDisplay *display)
|
|||||||
case radio_preset_picker:
|
case radio_preset_picker:
|
||||||
RadioPresetPicker();
|
RadioPresetPicker();
|
||||||
break;
|
break;
|
||||||
|
case frequency_slot:
|
||||||
|
FrequencySlotPicker();
|
||||||
|
break;
|
||||||
case no_timeout_lora_picker:
|
case no_timeout_lora_picker:
|
||||||
LoraRegionPicker(0);
|
LoraRegionPicker(0);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class menuHandler
|
|||||||
lora_picker,
|
lora_picker,
|
||||||
device_role_picker,
|
device_role_picker,
|
||||||
radio_preset_picker,
|
radio_preset_picker,
|
||||||
|
frequency_slot,
|
||||||
no_timeout_lora_picker,
|
no_timeout_lora_picker,
|
||||||
TZ_picker,
|
TZ_picker,
|
||||||
twelve_hour_picker,
|
twelve_hour_picker,
|
||||||
@@ -63,6 +64,7 @@ class menuHandler
|
|||||||
static void loraMenu();
|
static void loraMenu();
|
||||||
static void DeviceRolePicker();
|
static void DeviceRolePicker();
|
||||||
static void RadioPresetPicker();
|
static void RadioPresetPicker();
|
||||||
|
static void FrequencySlotPicker();
|
||||||
static void handleMenuSwitch(OLEDDisplay *display);
|
static void handleMenuSwitch(OLEDDisplay *display);
|
||||||
static void showConfirmationBanner(const char *message, std::function<void()> onConfirm);
|
static void showConfirmationBanner(const char *message, std::function<void()> onConfirm);
|
||||||
static void clockMenu();
|
static void clockMenu();
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ void handleAPIv1FromRadio(HTTPRequest *req, HTTPResponse *res)
|
|||||||
|
|
||||||
if (req->getMethod() == "OPTIONS") {
|
if (req->getMethod() == "OPTIONS") {
|
||||||
res->setStatusCode(204); // Success with no content
|
res->setStatusCode(204); // Success with no content
|
||||||
// res->print(""); @todo remove
|
res->print("");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,7 +223,7 @@ void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res)
|
|||||||
|
|
||||||
if (req->getMethod() == "OPTIONS") {
|
if (req->getMethod() == "OPTIONS") {
|
||||||
res->setStatusCode(204); // Success with no content
|
res->setStatusCode(204); // Success with no content
|
||||||
// res->print(""); @todo remove
|
res->print("");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -460,12 +460,15 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
|||||||
}
|
}
|
||||||
|
|
||||||
meshtastic_NodeInfoLite *sender = nodeDB->getMeshNode(mp.from);
|
meshtastic_NodeInfoLite *sender = nodeDB->getMeshNode(mp.from);
|
||||||
bool mutedNode = false;
|
|
||||||
if (sender) {
|
|
||||||
mutedNode = (sender->bitfield & NODEINFO_BITFIELD_IS_MUTED_MASK);
|
|
||||||
}
|
|
||||||
meshtastic_Channel ch = channels.getByIndex(mp.channel ? mp.channel : channels.getPrimaryIndex());
|
meshtastic_Channel ch = channels.getByIndex(mp.channel ? mp.channel : channels.getPrimaryIndex());
|
||||||
|
|
||||||
|
// If we receive a broadcast message, apply channel mute setting
|
||||||
|
// If we receive a direct message and the receipent is us, apply DM mute setting
|
||||||
|
// Else we just handle it as not muted.
|
||||||
|
const bool directToUs = !isBroadcast(mp.to) && isToUs(&mp);
|
||||||
|
bool is_muted = directToUs ? (sender && ((sender->bitfield & NODEINFO_BITFIELD_IS_MUTED_MASK) != 0))
|
||||||
|
: (ch.settings.has_module_settings && ch.settings.module_settings.is_muted);
|
||||||
|
|
||||||
if (moduleConfig.external_notification.alert_bell) {
|
if (moduleConfig.external_notification.alert_bell) {
|
||||||
if (containsBell) {
|
if (containsBell) {
|
||||||
LOG_INFO("externalNotificationModule - Notification Bell");
|
LOG_INFO("externalNotificationModule - Notification Bell");
|
||||||
@@ -516,8 +519,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (moduleConfig.external_notification.alert_message && !mutedNode &&
|
if (moduleConfig.external_notification.alert_message && !is_muted) {
|
||||||
(!ch.settings.has_module_settings || !ch.settings.module_settings.is_muted)) {
|
|
||||||
LOG_INFO("externalNotificationModule - Notification Module");
|
LOG_INFO("externalNotificationModule - Notification Module");
|
||||||
isNagging = true;
|
isNagging = true;
|
||||||
setExternalState(0, true);
|
setExternalState(0, true);
|
||||||
@@ -528,8 +530,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (moduleConfig.external_notification.alert_message_vibra && !mutedNode &&
|
if (moduleConfig.external_notification.alert_message_vibra && !is_muted) {
|
||||||
(!ch.settings.has_module_settings || !ch.settings.module_settings.is_muted)) {
|
|
||||||
LOG_INFO("externalNotificationModule - Notification Module (Vibra)");
|
LOG_INFO("externalNotificationModule - Notification Module (Vibra)");
|
||||||
isNagging = true;
|
isNagging = true;
|
||||||
setExternalState(1, true);
|
setExternalState(1, true);
|
||||||
@@ -540,8 +541,7 @@ ProcessMessage ExternalNotificationModule::handleReceived(const meshtastic_MeshP
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (moduleConfig.external_notification.alert_message_buzzer && !mutedNode &&
|
if (moduleConfig.external_notification.alert_message_buzzer && !is_muted) {
|
||||||
(!ch.settings.has_module_settings || !ch.settings.module_settings.is_muted)) {
|
|
||||||
LOG_INFO("externalNotificationModule - Notification Module (Buzzer)");
|
LOG_INFO("externalNotificationModule - Notification Module (Buzzer)");
|
||||||
if (config.device.buzzer_mode != meshtastic_Config_DeviceConfig_BuzzerMode_DIRECT_MSG_ONLY ||
|
if (config.device.buzzer_mode != meshtastic_Config_DeviceConfig_BuzzerMode_DIRECT_MSG_ONLY ||
|
||||||
(!isBroadcast(mp.to) && isToUs(&mp))) {
|
(!isBroadcast(mp.to) && isToUs(&mp))) {
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ void cpuDeepSleep(uint32_t msecs)
|
|||||||
void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel");
|
void updateBatteryLevel(uint8_t level) NOT_IMPLEMENTED("updateBatteryLevel");
|
||||||
|
|
||||||
int TCPPort = SERVER_API_DEFAULT_PORT;
|
int TCPPort = SERVER_API_DEFAULT_PORT;
|
||||||
|
bool checkConfigPort = true;
|
||||||
|
|
||||||
static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||||
{
|
{
|
||||||
@@ -63,6 +64,7 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state)
|
|||||||
if (sscanf(arg, "%d", &TCPPort) < 1)
|
if (sscanf(arg, "%d", &TCPPort) < 1)
|
||||||
return ARGP_ERR_UNKNOWN;
|
return ARGP_ERR_UNKNOWN;
|
||||||
else
|
else
|
||||||
|
checkConfigPort = false;
|
||||||
printf("Using config file %d\n", TCPPort);
|
printf("Using config file %d\n", TCPPort);
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
@@ -870,6 +872,14 @@ bool loadConfig(const char *configPath)
|
|||||||
std::cout << "Cannot set both MACAddress and MACAddressSource!" << std::endl;
|
std::cout << "Cannot set both MACAddress and MACAddressSource!" << std::endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
if (checkConfigPort) {
|
||||||
|
portduino_config.api_port = (yamlConfig["General"]["APIPort"]).as<int>(-1);
|
||||||
|
if (portduino_config.api_port != -1 &&
|
||||||
|
portduino_config.api_port > 1023 &&
|
||||||
|
portduino_config.api_port < 65536) {
|
||||||
|
TCPPort = (portduino_config.api_port);
|
||||||
|
}
|
||||||
|
}
|
||||||
portduino_config.mac_address = (yamlConfig["General"]["MACAddress"]).as<std::string>("");
|
portduino_config.mac_address = (yamlConfig["General"]["MACAddress"]).as<std::string>("");
|
||||||
if (portduino_config.mac_address != "") {
|
if (portduino_config.mac_address != "") {
|
||||||
portduino_config.mac_address_explicit = true;
|
portduino_config.mac_address_explicit = true;
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ extern struct portduino_config_struct {
|
|||||||
std::string mac_address = "";
|
std::string mac_address = "";
|
||||||
bool mac_address_explicit = false;
|
bool mac_address_explicit = false;
|
||||||
std::string mac_address_source = "";
|
std::string mac_address_source = "";
|
||||||
|
int api_port = -1;
|
||||||
std::string config_directory = "";
|
std::string config_directory = "";
|
||||||
std::string available_directory = "/etc/meshtasticd/available.d/";
|
std::string available_directory = "/etc/meshtasticd/available.d/";
|
||||||
int maxtophone = 100;
|
int maxtophone = 100;
|
||||||
@@ -508,6 +509,8 @@ extern struct portduino_config_struct {
|
|||||||
out << YAML::Key << "General" << YAML::Value << YAML::BeginMap;
|
out << YAML::Key << "General" << YAML::Value << YAML::BeginMap;
|
||||||
if (config_directory != "")
|
if (config_directory != "")
|
||||||
out << YAML::Key << "ConfigDirectory" << YAML::Value << config_directory;
|
out << YAML::Key << "ConfigDirectory" << YAML::Value << config_directory;
|
||||||
|
if (api_port != -1)
|
||||||
|
out << YAML::Key << "TCPPort" << YAML::Value << api_port;
|
||||||
if (mac_address_explicit)
|
if (mac_address_explicit)
|
||||||
out << YAML::Key << "MACAddress" << YAML::Value << mac_address;
|
out << YAML::Key << "MACAddress" << YAML::Value << mac_address;
|
||||||
if (mac_address_source != "")
|
if (mac_address_source != "")
|
||||||
@@ -519,4 +522,4 @@ extern struct portduino_config_struct {
|
|||||||
out << YAML::EndMap; // General
|
out << YAML::EndMap; // General
|
||||||
return out.c_str();
|
return out.c_str();
|
||||||
}
|
}
|
||||||
} portduino_config;
|
} portduino_config;
|
||||||
|
|||||||
Reference in New Issue
Block a user