Skip to content
Draft
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
14 changes: 5 additions & 9 deletions examples/companion_radio/MyMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1775,15 +1775,11 @@ void MyMesh::handleCmdFrame(size_t len) {
} else if (cmd_frame[0] == CMD_GET_CUSTOM_VARS) {
out_frame[0] = RESP_CODE_CUSTOM_VARS;
char *dp = (char *)&out_frame[1];
for (int i = 0; i < sensors.getNumSettings() && dp - (char *)&out_frame[1] < 140; i++) {
if (i > 0) {
*dp++ = ',';
}
strcpy(dp, sensors.getSettingName(i));
dp = strchr(dp, 0);
*dp++ = ':';
strcpy(dp, sensors.getSettingValue(i));
dp = strchr(dp, 0);
char *end = (char *)out_frame + sizeof(out_frame);
for (int i = 0; i < sensors.getNumSettings(); i++) {
if (i > 0) *dp++ = ',';
dp += snprintf(dp, end - dp, "%s:", sensors.getSettingName(i));
dp += sensors.getSettingValue(i, dp, end - dp);
}
_serial->writeFrame(out_frame, dp - (char *)out_frame);
} else if (cmd_frame[0] == CMD_SET_CUSTOM_VAR && len >= 4) {
Expand Down
8 changes: 6 additions & 2 deletions examples/companion_radio/ui-new/UITask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -884,7 +884,9 @@ bool UITask::getGPSState() {
int num = _sensors->getNumSettings();
for (int i = 0; i < num; i++) {
if (strcmp(_sensors->getSettingName(i), "gps") == 0) {
return !strcmp(_sensors->getSettingValue(i), "1");
char val[4];
_sensors->getSettingValue(i, val, sizeof(val));
return !strcmp(val, "1");
}
}
}
Expand All @@ -897,7 +899,9 @@ void UITask::toggleGPS() {
int num = _sensors->getNumSettings();
for (int i = 0; i < num; i++) {
if (strcmp(_sensors->getSettingName(i), "gps") == 0) {
if (strcmp(_sensors->getSettingValue(i), "1") == 0) {
char val[4];
_sensors->getSettingValue(i, val, sizeof(val));
if (strcmp(val, "1") == 0) {
_sensors->setSettingValue("gps", "0");
_node_prefs->gps_enabled = 0;
notify(UIEventType::ack);
Expand Down
4 changes: 3 additions & 1 deletion examples/companion_radio/ui-orig/UITask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,9 @@ void UITask::handleButtonQuadruplePress() {
int num = _sensors->getNumSettings();
for (int i = 0; i < num; i++) {
if (strcmp(_sensors->getSettingName(i), "gps") == 0) {
if (strcmp(_sensors->getSettingValue(i), "1") == 0) {
char val[4];
_sensors->getSettingValue(i, val, sizeof(val));
if (strcmp(val, "1") == 0) {
_sensors->setSettingValue("gps", "0");
notify(UIEventType::ack);
sprintf(_alert, "GPS: Disabled");
Expand Down
6 changes: 1 addition & 5 deletions examples/simple_repeater/MyMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,7 @@ uint8_t MyMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t* secr
if (data[0] == 0) { // blank password, just check if sender is in ACL
client = acl.getClient(sender.pub_key, PUB_KEY_SIZE);
if (client == NULL) {
#if MESH_DEBUG
MESH_DEBUG_PRINTLN("Login, sender not in ACL");
#endif
}
}
if (client == NULL) {
Expand All @@ -104,9 +102,7 @@ uint8_t MyMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t* secr
} else if (strcmp((char *)data, _prefs.guest_password) == 0) { // check guest password
perms = PERM_ACL_GUEST;
} else {
#if MESH_DEBUG
MESH_DEBUG_PRINTLN("Invalid password: %s", data);
#endif
return 0;
}

Expand Down Expand Up @@ -1165,7 +1161,7 @@ void MyMesh::clearStats() {
((SimpleMeshTables *)getTables())->resetStats();
}

void MyMesh::handleCommand(uint32_t sender_timestamp, char *command, char *reply) {
void MyMesh::handleCommand(uint32_t sender_timestamp, char *command, char reply[MAX_CLI_REPLY_LEN]) {
if (region_load_active) {
if (StrHelper::isBlank(command)) { // empty/blank line, signal to terminate 'load' operation
region_map = temp_map; // copy over the temp instance as new current map
Expand Down
3 changes: 1 addition & 2 deletions examples/simple_repeater/MyMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,7 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {

void saveIdentity(const mesh::LocalIdentity& new_id) override;
void clearStats() override;

void handleCommand(uint32_t sender_timestamp, char* command, char* reply);
void handleCommand(uint32_t sender_timestamp, char* command, char reply[MAX_CLI_REPLY_LEN]);
void loop();

#if defined(WITH_BRIDGE)
Expand Down
4 changes: 2 additions & 2 deletions examples/simple_repeater/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void setup() {

command[0] = 0;

sensors.begin();
sensors.begin(fs);

the_mesh.begin(fs);

Expand Down Expand Up @@ -125,7 +125,7 @@ void loop() {
if (len > 0 && command[len - 1] == '\r') { // received complete line
Serial.print('\n');
command[len - 1] = 0; // replace newline with C string null terminator
char reply[160];
char reply[MAX_CLI_REPLY_LEN];
the_mesh.handleCommand(0, command, reply); // NOTE: there is no sender_timestamp via serial!
if (reply[0]) {
Serial.print(" -> "); Serial.println(reply);
Expand Down
4 changes: 1 addition & 3 deletions examples/simple_room_server/MyMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,9 +317,7 @@ void MyMesh::onAnonDataRecv(mesh::Packet *packet, const uint8_t *secret, const m
if (data[8] == 0) { // blank password, just check if sender is in ACL
client = acl.getClient(sender.pub_key, PUB_KEY_SIZE);
if (client == NULL) {
#if MESH_DEBUG
MESH_DEBUG_PRINTLN("Login, sender not in ACL");
#endif
}
}
if (client == NULL) {
Expand Down Expand Up @@ -850,7 +848,7 @@ void MyMesh::formatPacketStatsReply(char *reply) {
getNumRecvFlood(), getNumRecvDirect());
}

void MyMesh::handleCommand(uint32_t sender_timestamp, char *command, char *reply) {
void MyMesh::handleCommand(uint32_t sender_timestamp, char *command, char reply[MAX_CLI_REPLY_LEN]) {
if (region_load_active) {
if (StrHelper::isBlank(command)) { // empty/blank line, signal to terminate 'load' operation
region_map = temp_map; // copy over the temp instance as new current map
Expand Down
2 changes: 1 addition & 1 deletion examples/simple_room_server/MyMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,6 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {

void saveIdentity(const mesh::LocalIdentity& new_id) override;
void clearStats() override;
void handleCommand(uint32_t sender_timestamp, char* command, char* reply);
void handleCommand(uint32_t sender_timestamp, char* command, char reply[MAX_CLI_REPLY_LEN]);
void loop();
};
2 changes: 1 addition & 1 deletion examples/simple_room_server/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ void loop() {

if (len > 0 && command[len - 1] == '\r') { // received complete line
command[len - 1] = 0; // replace newline with C string null terminator
char reply[160];
char reply[MAX_CLI_REPLY_LEN];
the_mesh.handleCommand(0, command, reply); // NOTE: there is no sender_timestamp via serial!
if (reply[0]) {
Serial.print(" -> "); Serial.println(reply);
Expand Down
12 changes: 3 additions & 9 deletions examples/simple_sensor/SensorMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -332,16 +332,12 @@ uint8_t SensorMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t*
if (data[0] == 0) { // blank password, just check if sender is in ACL
client = acl.getClient(sender.pub_key, PUB_KEY_SIZE);
if (client == NULL) {
#if MESH_DEBUG
MESH_DEBUG_PRINTLN("Login, sender not in ACL");
#endif
return 0;
}
} else {
if (strcmp((char *) data, _prefs.password) != 0) { // check for valid admin password
#if MESH_DEBUG
MESH_DEBUG_PRINTLN("Invalid password: %s", &data[4]);
#endif
return 0;
}

Expand Down Expand Up @@ -376,7 +372,7 @@ uint8_t SensorMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t*
return 13; // reply length
}

void SensorMesh::handleCommand(uint32_t sender_timestamp, char* command, char* reply) {
void SensorMesh::handleCommand(uint32_t sender_timestamp, char* command, char reply[MAX_CLI_REPLY_LEN]) {
while (*command == ' ') command++; // skip leading spaces

if (strlen(command) > 4 && command[2] == '|') { // optional prefix (for companion radio CLI)
Expand Down Expand Up @@ -615,10 +611,8 @@ void SensorMesh::onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_i

bool SensorMesh::handleIncomingMsg(ClientInfo& from, uint32_t timestamp, uint8_t* data, uint8_t flags, size_t len) {
MESH_DEBUG_PRINT("handleIncomingMsg: unhandled msg from ");
#ifdef MESH_DEBUG
mesh::Utils::printHex(Serial, from.id.pub_key, PUB_KEY_SIZE);
Serial.printf(": %s\n", data);
#endif
MESH_DEBUG_PRINT_HEX(from.id.pub_key, PUB_KEY_SIZE);
MESH_DEBUG_PRINT_RAW(": %s\n", data);
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion examples/simple_sensor/SensorMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class SensorMesh : public mesh::Mesh, public CommonCLICallbacks {
SensorMesh(mesh::MainBoard& board, mesh::Radio& radio, mesh::MillisecondClock& ms, mesh::RNG& rng, mesh::RTCClock& rtc, mesh::MeshTables& tables);
void begin(FILESYSTEM* fs);
void loop();
void handleCommand(uint32_t sender_timestamp, char* command, char* reply);
void handleCommand(uint32_t sender_timestamp, char* command, char reply[MAX_CLI_REPLY_LEN]);

// CommonCLI callbacks
const char* getFirmwareVer() override { return FIRMWARE_VERSION; }
Expand Down
2 changes: 1 addition & 1 deletion examples/simple_sensor/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ void loop() {

if (len > 0 && command[len - 1] == '\r') { // received complete line
command[len - 1] = 0; // replace newline with C string null terminator
char reply[160];
char reply[MAX_CLI_REPLY_LEN];
the_mesh.handleCommand(0, command, reply); // NOTE: there is no sender_timestamp via serial!
if (reply[0]) {
Serial.print(" -> "); Serial.println(reply);
Expand Down
50 changes: 50 additions & 0 deletions src/EndianTypes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#pragma once

#include <stdint.h>

/**
* @brief Endianness-safe integer types for network/protocol communication
*
* These types automatically handle byte order conversion between wire format
* and host format, preventing endianness bugs in protocol implementations.
*/

// Big-endian 32-bit unsigned integer
struct be_uint32_t {
uint32_t wireBytes;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
operator uint32_t() const { return __builtin_bswap32(wireBytes); }
#else
operator uint32_t() const { return wireBytes; }
#endif
} __attribute__((packed));

// Big-endian 16-bit unsigned integer
struct be_uint16_t {
uint16_t wireBytes;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
operator uint16_t() const { return __builtin_bswap16(wireBytes); }
#else
operator uint16_t() const { return wireBytes; }
#endif
} __attribute__((packed));

// Little-endian 16-bit unsigned integer
struct le_uint16_t {
uint16_t wireBytes;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
operator uint16_t() const { return wireBytes; }
#else
operator uint16_t() const { return __builtin_bswap16(wireBytes); }
#endif
} __attribute__((packed));

// Little-endian 32-bit unsigned integer
struct le_uint32_t {
uint32_t wireBytes;
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
operator uint32_t() const { return wireBytes; }
#else
operator uint32_t() const { return __builtin_bswap32(wireBytes); }
#endif
} __attribute__((packed));
4 changes: 4 additions & 0 deletions src/MeshCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,13 @@
#include <Arduino.h>
#define MESH_DEBUG_PRINT(F, ...) Serial.printf("DEBUG: " F, ##__VA_ARGS__)
#define MESH_DEBUG_PRINTLN(F, ...) Serial.printf("DEBUG: " F "\n", ##__VA_ARGS__)
#define MESH_DEBUG_PRINT_RAW(F, ...) Serial.printf(F, ##__VA_ARGS__)
#define MESH_DEBUG_PRINT_HEX(src,len) mesh::Utils::printHex(Serial, src, len)
#else
#define MESH_DEBUG_PRINT(...) {}
#define MESH_DEBUG_PRINTLN(...) {}
#define MESH_DEBUG_PRINT_RAW(F, ...) {}
#define MESH_DEBUG_PRINT_HEX(src,len) {}
#endif

#if BRIDGE_DEBUG && ARDUINO
Expand Down
34 changes: 17 additions & 17 deletions src/helpers/CommonCLI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ uint8_t CommonCLI::buildAdvertData(uint8_t node_type, uint8_t* app_data) {
}
}

void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* reply) {
void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char reply[MAX_CLI_REPLY_LEN]) {
char *reply_end= reply + MAX_CLI_REPLY_LEN;
if (memcmp(command, "poweroff", 8) == 0 || memcmp(command, "shutdown", 8) == 0) {
_board->powerOff(); // doesn't return
} else if (memcmp(command, "reboot", 6) == 0) {
Expand Down Expand Up @@ -304,8 +305,8 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re
sprintf(reply, "%s", _board->getManufacturerName());
} else if (memcmp(command, "sensor get ", 11) == 0) {
const char* key = command + 11;
const char* val = _sensors->getSettingByKey(key);
if (val != NULL) {
char val[MAX_SETTING_BUF_LEN];
if (_sensors->getSettingByKey(key, val, sizeof(val)) > 0) {
sprintf(reply, "> %s", val);
} else {
strcpy(reply, "null");
Expand All @@ -328,22 +329,20 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re
if (strlen(command) > 11) {
start = _atoi(command+12);
}
const char *continue_fmt = "... next:%d";
if (start >= end) {
strcpy(reply, "no custom var");
strlcpy(reply, "no custom var", reply_end - reply);
} else {
sprintf(dp, "%d vars\n", end);
dp = strchr(dp, 0);
const char *vars_end = reply_end - strlen(continue_fmt) - 1; // leave space for continue message if needed
dp += snprintf(dp, vars_end - dp, "%d vars\n", end);
int i;
for (i = start; i < end && (dp-reply < 134); i++) {
sprintf(dp, "%s=%s\n",
_sensors->getSettingName(i),
_sensors->getSettingValue(i));
dp = strchr(dp, 0);
for (i = start; i < end && dp < vars_end; i++) {
dp += snprintf(dp, vars_end - dp, "%s=", _sensors->getSettingName(i));
dp += _sensors->getSettingValue(i, dp, vars_end - dp);
dp += snprintf(dp, vars_end - dp, "\n");
}
if (i < end) {
sprintf(dp, "... next:%d", i);
} else {
*(dp-1) = 0; // remove last CR
snprintf(dp, reply_end - dp, continue_fmt, i);
}
}
} else if (memcmp(command, "region", 6) == 0) {
Expand Down Expand Up @@ -414,7 +413,8 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re
bool enabled = l->isEnabled(); // is EN pin on ?
bool fix = l->isValid(); // has fix ?
int sats = l->satellitesCount();
bool active = !strcmp(_sensors->getSettingByKey("gps"), "1");
char gpsVal[4];
bool active = _sensors->getSettingByKey("gps", gpsVal, sizeof(gpsVal)) > 0 && !strcmp(gpsVal, "1");
if (enabled) {
sprintf(reply, "on, %s, %s, %d sats",
active?"active":"deactivated",
Expand Down Expand Up @@ -464,7 +464,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re
}
}

void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* reply) {
void CommonCLI::handleSetCmd(uint32_t sender_timestamp, const char* command, char* reply) {
const char* config = &command[4];
if (memcmp(config, "dutycycle ", 10) == 0) {
float dc = atof(&config[10]);
Expand Down Expand Up @@ -733,7 +733,7 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep
}
}

void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* reply) {
void CommonCLI::handleGetCmd(uint32_t sender_timestamp, const char* command, char* reply) {
const char* config = &command[4];
if (memcmp(config, "dutycycle", 9) == 0) {
float dc = 100.0f / (_prefs->airtime_factor + 1.0f);
Expand Down
8 changes: 5 additions & 3 deletions src/helpers/CommonCLI.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#include <helpers/ClientACL.h>
#include <helpers/RegionMap.h>

#define MAX_CLI_REPLY_LEN 160

#if defined(WITH_RS232_BRIDGE) || defined(WITH_ESPNOW_BRIDGE)
#define WITH_BRIDGE
#endif
Expand Down Expand Up @@ -127,15 +129,15 @@ class CommonCLI {
void loadPrefsInt(FILESYSTEM* _fs, const char* filename);

void handleRegionCmd(char* command, char* reply);
void handleGetCmd(uint32_t sender_timestamp, char* command, char* reply);
void handleSetCmd(uint32_t sender_timestamp, char* command, char* reply);
void handleGetCmd(uint32_t sender_timestamp, const char* command, char* reply);
void handleSetCmd(uint32_t sender_timestamp, const char* command, char* reply);

public:
CommonCLI(mesh::MainBoard& board, mesh::RTCClock& rtc, SensorManager& sensors, RegionMap& region_map, ClientACL& acl, NodePrefs* prefs, CommonCLICallbacks* callbacks)
: _board(&board), _rtc(&rtc), _sensors(&sensors), _region_map(&region_map), _acl(&acl), _prefs(prefs), _callbacks(callbacks) { }

void loadPrefs(FILESYSTEM* _fs);
void savePrefs(FILESYSTEM* _fs);
void handleCommand(uint32_t sender_timestamp, char* command, char* reply);
void handleCommand(uint32_t sender_timestamp, char* command, char reply[MAX_CLI_REPLY_LEN]);
uint8_t buildAdvertData(uint8_t node_type, uint8_t* app_data);
};
Loading