Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add mavlink port set config options for tx backpack #167

Merged
merged 3 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions html/scan.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ function _(el) {

function init() {
initAat();
initMavLink();

// sends XMLHttpRequest, so do it last
initOptions();
Expand All @@ -25,6 +26,27 @@ function initAat() {
);
}

function initMavLink() {
// Fetch initial MavLink configuration
const xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
const data = JSON.parse(this.responseText);
updateMavLinkConfig(data);

// Start periodic updates of MavLink stats
updateMavLinkStats();
setInterval(updateMavLinkStats, 1000);

const resetButton = _('mavlink_reset_defaults');
if (resetButton) {
resetButton.addEventListener('click', resetMavLinkDefaults);
}
}
};
xmlhttp.open('GET', '/mavlink', true);
xmlhttp.send();
}
function initOptions() {
const xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
Expand All @@ -38,6 +60,63 @@ function initOptions() {
xmlhttp.send();
}

function updateMavLinkConfig(data) {
_('mavlink_listen_port').value = data.ports.listen;
_('mavlink_send_port').value = data.ports.send;
}

function updateMavLinkStats() {
const xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
const data = JSON.parse(this.responseText);

// Update Stats
_('mavlink_gcs_ip').textContent = data.ip.gcs;
_('mavlink_packets_down').textContent = data.counters.packets_down;
_('mavlink_packets_up').textContent = data.counters.packets_up;
_('mavlink_drops_down').textContent = data.counters.drops_down;
_('mavlink_overflows_down').textContent = data.counters.overflows_down;
}
};
xmlhttp.open('GET', '/mavlink', true);
xmlhttp.send();
}

function resetMavLinkDefaults() {
const defaultSendPort = 14550;
const defaultListenPort = 14555;

// Update the input fields
_('mavlink_listen_port').value = defaultListenPort;
_('mavlink_send_port').value = defaultSendPort;

// Send the new values to the server
const xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4) {
if (this.status == 200) {
cuteAlert({
type: "success",
title: "Default Settings Applied",
message: "MavLink ports have been reset to default values."
});
// Refresh the MavLink stats to reflect the changes
updateMavLinkStats();
} else {
cuteAlert({
type: "error",
title: "Error",
message: "Failed to apply default settings. Please try again."
});
}
}
};
xmlhttp.open('POST', '/setmavlink', true);
xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xmlhttp.send(`listen=${defaultListenPort}&send=${defaultSendPort}`);
}

function updateConfig(data) {
let config = data.config;
if (config.mode==="STA") {
Expand Down
49 changes: 49 additions & 0 deletions html/txbp_index.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ <h1><b>ExpressLRS</b></h1>
<li id="tx_tab" class="mui--is-active"><a data-mui-toggle="tab" data-mui-controls="pane-justified-1">TX</a></li>
<li><a data-mui-toggle="tab" data-mui-controls="pane-justified-2">Backpack</a></li>
<li><a data-mui-toggle="tab" data-mui-controls="pane-justified-3">Network</a></li>
<li><a data-mui-toggle="tab" data-mui-controls="pane-justified-4">MavLink</a></li>
</ul>

<div class="mui-tabs__pane mui--is-active" id="pane-justified-1">
Expand Down Expand Up @@ -97,6 +98,54 @@ <h2>Home Network: <span id="ssid"></span></h2>
<a id="access" href="#" class="mui-btn mui-btn--primary">Disconnect</a>
</div>
</div>

<div class="mui-tabs__pane" id="pane-justified-4">
<h2>MavLink Configuration</h2>
<form action="/setmavlink" id="mavlink_form" method="POST" autocomplete="off" class="mui-form">
<div class="mui-textfield">
Send Port
<input type="number" id="mavlink_send_port" name="send" placeholder="Send Port">
</div>
<div class="mui-textfield">
Listen Port
<input type="number" id="mavlink_listen_port" name="listen" placeholder="Listen Port">
</div>
<!-- I wanted to avoid adding css -->
<table>
<tr>
<td>
<input type="submit" value="Save Configuration" class="mui-btn mui-btn--primary">
</td>
<td>
<button id="mavlink_reset_defaults" class="mui-btn mui-btn--primary">Reset Defaults</button>
</td>
</tr>
</table>
</form>
<h3>MavLink Statistics</h3>
<table class="mui-table">
<tr>
<td>Packets Downlink:</td>
<td id="mavlink_packets_down"></td>
</tr>
<tr>
<td>Packets Uplink:</td>
<td id="mavlink_packets_up"></td>
</tr>
<tr>
<td>Drops Downlink:</td>
<td id="mavlink_drops_down"></td>
</tr>
<tr>
<td>Overflows Downlink:</td>
<td id="mavlink_overflows_down"></td>
</tr>
<tr>
<td>GCS IP Adresses</Address>:</td>
<td id="mavlink_gcs_ip"></td>
</tr>
</table>
</div>
</div>
</div>
<footer>
Expand Down
4 changes: 0 additions & 4 deletions lib/MAVLink/MAVLink.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
#if defined(MAVLINK_ENABLED)
#include "common/mavlink.h"

// This is the port that we will listen for mavlink packets on
constexpr uint16_t MAVLINK_PORT_LISTEN = 14555;
// This is the port that we will send mavlink packets to
constexpr uint16_t MAVLINK_PORT_SEND = 14550;
// Size of the buffer that we will use to store mavlink packets in units of mavlink_message_t
constexpr size_t MAVLINK_BUF_SIZE = 16;
// Threshold at which we will flush the buffer
Expand Down
60 changes: 50 additions & 10 deletions lib/WIFI/devWIFI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,28 +228,33 @@ static void WebUpdateSendNetworks(AsyncWebServerRequest *request)
}
}

static void sendResponse(AsyncWebServerRequest *request, const String &msg, WiFiMode_t mode) {
AsyncWebServerResponse *response = request->beginResponse(200, "text/plain", msg);
static void sendResponse(AsyncWebServerRequest *request, const String &msg, const String &type = "text/plain") {
AsyncWebServerResponse *response = request->beginResponse(200, type, msg);
response->addHeader("Connection", "close");
request->send(response);
request->client()->close();
changeTime = millis();
}

static void changeWifiMode(WiFiMode_t mode){
changeMode = mode;
}

static void WebUpdateAccessPoint(AsyncWebServerRequest *request)
{
DBGLN("Starting Access Point");
String msg = String("Access Point starting, please connect to access point '") + wifi_ap_ssid + "' with password '" + wifi_ap_password + "'";
sendResponse(request, msg, WIFI_AP);
sendResponse(request, msg);
changeWifiMode(WIFI_AP);
}

static void WebUpdateConnect(AsyncWebServerRequest *request)
{
DBGLN("Connecting to home network");
String msg = String("Connecting to network '") + station_ssid + "', connect to http://" +
myHostname + ".local from a browser on that network";
sendResponse(request, msg, WIFI_STA);
sendResponse(request, msg);
changeWifiMode(WIFI_STA);
}

static void WebUpdateSetHome(AsyncWebServerRequest *request)
Expand Down Expand Up @@ -280,13 +285,16 @@ static void WebUpdateForget(AsyncWebServerRequest *request)
strcpy(station_ssid, firmwareOptions.home_wifi_ssid);
strcpy(station_password, firmwareOptions.home_wifi_password);
String msg = String("Temporary network forgotten, attempting to connect to network '") + station_ssid + "'";
sendResponse(request, msg, WIFI_STA);
sendResponse(request, msg);
changeWifiMode(WIFI_STA);

}
else {
station_ssid[0] = 0;
station_password[0] = 0;
String msg = String("Home network forgotten, please connect to access point '") + wifi_ap_ssid + "' with password '" + wifi_ap_password + "'";
sendResponse(request, msg, WIFI_AP);
sendResponse(request, msg);
changeWifiMode(WIFI_AP);
}
}

Expand Down Expand Up @@ -465,8 +473,8 @@ static void WebMAVLinkHandler(AsyncWebServerRequest *request)
json["counters"]["packets_up"] = stats->packets_uplink;
json["counters"]["drops_down"] = stats->drops_downlink;
json["counters"]["overflows_down"] = stats->overflows_downlink;
json["ports"]["listen"] = MAVLINK_PORT_LISTEN;
json["ports"]["send"] = MAVLINK_PORT_SEND;
json["ports"]["listen"] = config.GetMavlinkListenPort();
json["ports"]["send"] = config.GetMavlinkSendPort();
if (gcsIPSet) {
json["ip"]["gcs"] = gcsIP.toString();
} else {
Expand All @@ -478,6 +486,35 @@ static void WebMAVLinkHandler(AsyncWebServerRequest *request)
serializeJson(json, *response);
request->send(response);
}

static void WebUpdateSetMavLink(AsyncWebServerRequest *request)
{
uint16_t listen_port = request->arg("listen").toInt();
uint16_t send_port = request->arg("send").toInt();

DBGLN("Setting MavLink configuration: listen=%d, send=%d", listen_port, send_port);

config.SetMavlinkListenPort(listen_port);
config.SetMavlinkSendPort(send_port);
config.SetWiFiService(WIFI_SERVICE_MAVLINK_TX);
config.Commit();

// Restart MavLink UDP service
mavlinkUDP.stop();
mavlinkUDP.begin(config.GetMavlinkListenPort());

String response = F(
"<html><head>"
"<meta http-equiv='refresh' content='2;url=/'>"
"<title>MavLink Settings Updated</title>"
"</head><body>"
"<h1>MavLink Settings Updated Successfully</h1>"
"<p>Redirecting back to the main page in 2 seconds...</p>"
"</body></html>"
);

sendResponse(request, response, "text/html");
}
#endif

static void wifiOff()
Expand Down Expand Up @@ -600,6 +637,9 @@ static void startServices()
server.on("/config", HTTP_GET, GetConfiguration);
server.on("/networks.json", WebUpdateSendNetworks);
server.on("/sethome", WebUpdateSetHome);
#if defined(MAVLINK_ENABLED)
server.on("/setmavlink", WebUpdateSetMavLink);
#endif
server.on("/forget", WebUpdateForget);
server.on("/connect", WebUpdateConnect);
server.on("/access", WebUpdateAccessPoint);
Expand Down Expand Up @@ -632,7 +672,7 @@ static void startServices()

startMDNS();
#if defined(MAVLINK_ENABLED)
mavlinkUDP.begin(MAVLINK_PORT_LISTEN);
mavlinkUDP.begin(config.GetMavlinkListenPort());
#endif

servicesStarted = true;
Expand Down Expand Up @@ -748,7 +788,7 @@ static void HandleWebUpdate()
remote = WiFi.broadcastIP();
}

mavlinkUDP.beginPacket(remote, MAVLINK_PORT_SEND);
mavlinkUDP.beginPacket(remote, config.GetMavlinkSendPort());
mavlink_message_t* msgQueue = mavlink.GetQueuedMsgs();
for (uint8_t i = 0; i < mavlink.GetQueuedMsgCount(); i++)
{
Expand Down
16 changes: 16 additions & 0 deletions lib/config/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ TxBackpackConfig::SetDefaults()
m_config.password[0] = 0;
memset(m_config.address, 0, 6);
m_config.wifiService = WIFI_SERVICE_UPDATE;
m_config.mavlinkListenPort = 14555; // Default MavLink listen port
m_config.mavlinkSendPort = 14550; // Default MavLink send port
m_modified = true;
Commit();
}
Expand Down Expand Up @@ -97,6 +99,19 @@ TxBackpackConfig::SetTelemMode(telem_mode_t mode)
m_config.telemMode = mode;
m_modified = true;
}
void
TxBackpackConfig::SetMavlinkListenPort(uint16_t port)
{
m_config.mavlinkListenPort = port;
m_modified = true;
}

void
TxBackpackConfig::SetMavlinkSendPort(uint16_t port)
{
m_config.mavlinkSendPort = port;
m_modified = true;
}
#endif

/////////////////////////////////////////////////////
Expand Down Expand Up @@ -297,6 +312,7 @@ TimerBackpackConfig::Commit()
if (!m_modified)
{
// No changes
DBGLN("No Config Changes Detected")
return;
}
// Write the struct to eeprom
Expand Down
8 changes: 7 additions & 1 deletion lib/config/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#define VRX_BACKPACK_CONFIG_MAGIC (0b10 << 30)
#define TIMER_BACKPACK_CONFIG_MAGIC (0b11 << 30)

#define TX_BACKPACK_CONFIG_VERSION 3
#define TX_BACKPACK_CONFIG_VERSION 4
#define VRX_BACKPACK_CONFIG_VERSION 3
#define TIMER_BACKPACK_CONFIG_VERSION 3

Expand All @@ -34,6 +34,8 @@ typedef struct {
uint8_t address[6];
wifi_service_t wifiService;
telem_mode_t telemMode;
uint16_t mavlinkListenPort;
uint16_t mavlinkSendPort;
} tx_backpack_config_t;

class TxBackpackConfig
Expand All @@ -50,6 +52,8 @@ class TxBackpackConfig
uint8_t *GetGroupAddress() { return m_config.address; }
wifi_service_t GetWiFiService() { return m_config.wifiService; }
telem_mode_t GetTelemMode() { return m_config.telemMode; }
uint16_t GetMavlinkListenPort() const { return m_config.mavlinkListenPort; }
uint16_t GetMavlinkSendPort() const { return m_config.mavlinkSendPort; }

// Setters
void SetStorageProvider(ELRS_EEPROM *eeprom);
Expand All @@ -60,6 +64,8 @@ class TxBackpackConfig
void SetGroupAddress(const uint8_t address[6]);
void SetWiFiService(wifi_service_t service);
void SetTelemMode(telem_mode_t mode);
void SetMavlinkListenPort(uint16_t port);
void SetMavlinkSendPort(uint16_t port);

private:
tx_backpack_config_t m_config;
Expand Down