mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-03-30 10:39:59 +00:00
Merge pull request #890 from fdlamotte/CommonCLI--gps-management
CommonCLI: gps management commands
This commit is contained in:
@@ -289,8 +289,16 @@ mesh::Packet *MyMesh::createSelfAdvert() {
|
||||
uint8_t app_data[MAX_ADVERT_DATA_SIZE];
|
||||
uint8_t app_data_len;
|
||||
{
|
||||
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name, _prefs.node_lat, _prefs.node_lon);
|
||||
app_data_len = builder.encodeTo(app_data);
|
||||
if (_prefs.advert_loc_policy == ADVERT_LOC_NONE) {
|
||||
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name);
|
||||
app_data_len = builder.encodeTo(app_data);
|
||||
} else if (_prefs.advert_loc_policy == ADVERT_LOC_SHARE) {
|
||||
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name, sensors.node_lat, sensors.node_lon);
|
||||
app_data_len = builder.encodeTo(app_data);
|
||||
} else {
|
||||
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name, _prefs.node_lat, _prefs.node_lon);
|
||||
app_data_len = builder.encodeTo(app_data);
|
||||
}
|
||||
}
|
||||
|
||||
return createAdvert(self_id, app_data, app_data_len);
|
||||
@@ -631,7 +639,12 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
||||
_prefs.bridge_pkt_src = 0; // logTx
|
||||
_prefs.bridge_baud = 115200; // baud rate
|
||||
_prefs.bridge_channel = 1; // channel 1
|
||||
|
||||
StrHelper::strncpy(_prefs.bridge_secret, "LVSITANOS", sizeof(_prefs.bridge_secret));
|
||||
|
||||
// GPS defaults
|
||||
_prefs.gps_enabled = 0;
|
||||
_prefs.gps_interval = 0;
|
||||
}
|
||||
|
||||
void MyMesh::begin(FILESYSTEM *fs) {
|
||||
@@ -653,6 +666,10 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
||||
|
||||
updateAdvertTimer();
|
||||
updateFloodAdvertTimer();
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
applyGpsPrefs();
|
||||
#endif
|
||||
}
|
||||
|
||||
void MyMesh::applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) {
|
||||
|
||||
@@ -135,6 +135,12 @@ protected:
|
||||
return _prefs.multi_acks;
|
||||
}
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
void applyGpsPrefs() {
|
||||
sensors.setSettingByKey("gps", _prefs.gps_enabled?"1":"0");
|
||||
}
|
||||
#endif
|
||||
|
||||
void onAnonDataRecv(mesh::Packet* packet, const uint8_t* secret, const mesh::Identity& sender, uint8_t* data, size_t len) override;
|
||||
int searchPeersByHash(const uint8_t* hash) override;
|
||||
void getPeerSharedSecret(uint8_t* dest_secret, int peer_idx) override;
|
||||
|
||||
@@ -116,8 +116,16 @@ mesh::Packet *MyMesh::createSelfAdvert() {
|
||||
uint8_t app_data[MAX_ADVERT_DATA_SIZE];
|
||||
uint8_t app_data_len;
|
||||
{
|
||||
AdvertDataBuilder builder(ADV_TYPE_ROOM, _prefs.node_name, _prefs.node_lat, _prefs.node_lon);
|
||||
app_data_len = builder.encodeTo(app_data);
|
||||
if (_prefs.advert_loc_policy == ADVERT_LOC_NONE) {
|
||||
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name);
|
||||
app_data_len = builder.encodeTo(app_data);
|
||||
} else if (_prefs.advert_loc_policy == ADVERT_LOC_SHARE) {
|
||||
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name, sensors.node_lat, sensors.node_lon);
|
||||
app_data_len = builder.encodeTo(app_data);
|
||||
} else {
|
||||
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name, _prefs.node_lat, _prefs.node_lon);
|
||||
app_data_len = builder.encodeTo(app_data);
|
||||
}
|
||||
}
|
||||
|
||||
return createAdvert(self_id, app_data, app_data_len);
|
||||
@@ -632,6 +640,10 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
||||
|
||||
updateAdvertTimer();
|
||||
updateFloodAdvertTimer();
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
applyGpsPrefs();
|
||||
#endif
|
||||
}
|
||||
|
||||
void MyMesh::applyTempRadioParams(float freq, float bw, uint8_t sf, uint8_t cr, int timeout_mins) {
|
||||
|
||||
@@ -149,6 +149,12 @@ protected:
|
||||
bool onPeerPathRecv(mesh::Packet* packet, int sender_idx, const uint8_t* secret, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override;
|
||||
void onAckRecv(mesh::Packet* packet, uint32_t ack_crc) override;
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
void applyGpsPrefs() {
|
||||
sensors.setSettingByKey("gps", _prefs.gps_enabled?"1":"0");
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
MyMesh(mesh::MainBoard& board, mesh::Radio& radio, mesh::MillisecondClock& ms, mesh::RNG& rng, mesh::RTCClock& rtc, mesh::MeshTables& tables);
|
||||
|
||||
|
||||
@@ -241,8 +241,16 @@ mesh::Packet* SensorMesh::createSelfAdvert() {
|
||||
uint8_t app_data[MAX_ADVERT_DATA_SIZE];
|
||||
uint8_t app_data_len;
|
||||
{
|
||||
AdvertDataBuilder builder(ADV_TYPE_SENSOR, _prefs.node_name, _prefs.node_lat, _prefs.node_lon);
|
||||
app_data_len = builder.encodeTo(app_data);
|
||||
if (_prefs.advert_loc_policy == ADVERT_LOC_NONE) {
|
||||
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name);
|
||||
app_data_len = builder.encodeTo(app_data);
|
||||
} else if (_prefs.advert_loc_policy == ADVERT_LOC_SHARE) {
|
||||
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name, sensors.node_lat, sensors.node_lon);
|
||||
app_data_len = builder.encodeTo(app_data);
|
||||
} else {
|
||||
AdvertDataBuilder builder(ADV_TYPE_REPEATER, _prefs.node_name, _prefs.node_lat, _prefs.node_lon);
|
||||
app_data_len = builder.encodeTo(app_data);
|
||||
}
|
||||
}
|
||||
|
||||
return createAdvert(self_id, app_data, app_data_len);
|
||||
@@ -697,6 +705,10 @@ void SensorMesh::begin(FILESYSTEM* fs) {
|
||||
|
||||
updateAdvertTimer();
|
||||
updateFloodAdvertTimer();
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
applyGpsPrefs();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool SensorMesh::formatFileSystem() {
|
||||
|
||||
@@ -149,4 +149,9 @@ private:
|
||||
|
||||
void sendAlert(const ClientInfo* c, Trigger* t);
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
void applyGpsPrefs() {
|
||||
sensors.setSettingByKey("gps", _prefs.gps_enabled?"1":"0");
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -62,8 +62,15 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
file.read((uint8_t *)&_prefs->bridge_delay, sizeof(_prefs->bridge_delay)); // 128
|
||||
file.read((uint8_t *)&_prefs->bridge_pkt_src, sizeof(_prefs->bridge_pkt_src)); // 130
|
||||
file.read((uint8_t *)&_prefs->bridge_baud, sizeof(_prefs->bridge_baud)); // 131
|
||||
file.read((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 132
|
||||
file.read((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 133
|
||||
file.read((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 135
|
||||
file.read((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 136
|
||||
file.read(pad, 4); // 152
|
||||
file.read((uint8_t *)&_prefs->gps_enabled, sizeof(_prefs->gps_enabled)); // 156
|
||||
file.read((uint8_t *)&_prefs->gps_interval, sizeof(_prefs->gps_interval)); // 157
|
||||
if (file.read((uint8_t *)&_prefs->advert_loc_policy, sizeof (_prefs->advert_loc_policy)) == -1) {
|
||||
_prefs->advert_loc_policy = ADVERT_LOC_PREFS; // default value
|
||||
} // 161
|
||||
// 162
|
||||
|
||||
// sanitise bad pref values
|
||||
_prefs->rx_delay_base = constrain(_prefs->rx_delay_base, 0, 20.0f);
|
||||
@@ -84,6 +91,9 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
_prefs->bridge_baud = constrain(_prefs->bridge_baud, 9600, 115200);
|
||||
_prefs->bridge_channel = constrain(_prefs->bridge_channel, 0, 14);
|
||||
|
||||
_prefs->gps_enabled = constrain(_prefs->gps_enabled, 0, 1);
|
||||
_prefs->advert_loc_policy = constrain(_prefs->advert_loc_policy, 0, 2);
|
||||
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
@@ -131,8 +141,13 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
|
||||
file.write((uint8_t *)&_prefs->bridge_delay, sizeof(_prefs->bridge_delay)); // 128
|
||||
file.write((uint8_t *)&_prefs->bridge_pkt_src, sizeof(_prefs->bridge_pkt_src)); // 130
|
||||
file.write((uint8_t *)&_prefs->bridge_baud, sizeof(_prefs->bridge_baud)); // 131
|
||||
file.write((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 132
|
||||
file.write((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 133
|
||||
file.write((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 135
|
||||
file.write((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 136
|
||||
file.write(pad, 4); // 152
|
||||
file.write((uint8_t *)&_prefs->gps_enabled, sizeof(_prefs->gps_enabled)); // 156
|
||||
file.write((uint8_t *)&_prefs->gps_interval, sizeof(_prefs->gps_interval)); // 157
|
||||
file.write((uint8_t *)&_prefs->advert_loc_policy, sizeof(_prefs->advert_loc_policy)); // 161
|
||||
// 162
|
||||
|
||||
file.close();
|
||||
}
|
||||
@@ -504,6 +519,126 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
sprintf(reply, "%s (Build: %s)", _callbacks->getFirmwareVer(), _callbacks->getBuildDate());
|
||||
} else if (memcmp(command, "board", 5) == 0) {
|
||||
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) {
|
||||
sprintf(reply, "> %s", val);
|
||||
} else {
|
||||
strcpy(reply, "null");
|
||||
}
|
||||
} else if (memcmp(command, "sensor set ", 11) == 0) {
|
||||
strcpy(tmp, &command[11]);
|
||||
const char *parts[2];
|
||||
int num = mesh::Utils::parseTextParts(tmp, parts, 2, ' ');
|
||||
const char *key = (num > 0) ? parts[0] : "";
|
||||
const char *value = (num > 1) ? parts[1] : "null";
|
||||
if (sensors.setSettingByKey(key, value)) {
|
||||
strcpy(reply, "ok");
|
||||
} else {
|
||||
strcpy(reply, "can't find custom var");
|
||||
}
|
||||
} else if (memcmp(command, "sensor list", 11) == 0) {
|
||||
char* dp = reply;
|
||||
int start = 0;
|
||||
int end = sensors.getNumSettings();
|
||||
if (strlen(command) > 11) {
|
||||
start = _atoi(command+12);
|
||||
}
|
||||
if (start >= end) {
|
||||
strcpy(reply, "no custom var");
|
||||
} else {
|
||||
sprintf(dp, "%d vars\n", end);
|
||||
dp = strchr(dp, 0);
|
||||
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);
|
||||
}
|
||||
if (i < end) {
|
||||
sprintf(dp, "... next:%d", i);
|
||||
} else {
|
||||
*(dp-1) = 0; // remove last CR
|
||||
}
|
||||
}
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
} else if (memcmp(command, "gps on", 6) == 0) {
|
||||
if (sensors.setSettingByKey("gps", "1")) {
|
||||
_prefs->gps_enabled = 1;
|
||||
savePrefs();
|
||||
strcpy(reply, "ok");
|
||||
} else {
|
||||
strcpy(reply, "gps toggle not found");
|
||||
}
|
||||
} else if (memcmp(command, "gps off", 7) == 0) {
|
||||
if (sensors.setSettingByKey("gps", "0")) {
|
||||
_prefs->gps_enabled = 0;
|
||||
savePrefs();
|
||||
strcpy(reply, "ok");
|
||||
} else {
|
||||
strcpy(reply, "gps toggle not found");
|
||||
}
|
||||
} else if (memcmp(command, "gps sync", 8) == 0) {
|
||||
LocationProvider * l = sensors.getLocationProvider();
|
||||
if (l != NULL) {
|
||||
l->syncTime();
|
||||
}
|
||||
} else if (memcmp(command, "gps setloc", 10) == 0) {
|
||||
_prefs->node_lat = sensors.node_lat;
|
||||
_prefs->node_lon = sensors.node_lon;
|
||||
savePrefs();
|
||||
strcpy(reply, "ok");
|
||||
} else if (memcmp(command, "gps advert", 10) == 0) {
|
||||
if (strlen(command) == 10) {
|
||||
switch (_prefs->advert_loc_policy) {
|
||||
case ADVERT_LOC_NONE:
|
||||
strcpy(reply, "> none");
|
||||
break;
|
||||
case ADVERT_LOC_PREFS:
|
||||
strcpy(reply, "> prefs");
|
||||
break;
|
||||
case ADVERT_LOC_SHARE:
|
||||
strcpy(reply, "> share");
|
||||
break;
|
||||
default:
|
||||
strcpy(reply, "error");
|
||||
}
|
||||
} else if (memcmp(command+11, "none", 4) == 0) {
|
||||
_prefs->advert_loc_policy = ADVERT_LOC_NONE;
|
||||
savePrefs();
|
||||
strcpy(reply, "ok");
|
||||
} else if (memcmp(command+11, "share", 5) == 0) {
|
||||
_prefs->advert_loc_policy = ADVERT_LOC_SHARE;
|
||||
savePrefs();
|
||||
strcpy(reply, "ok");
|
||||
} else if (memcmp(command+11, "prefs", 4) == 0) {
|
||||
_prefs->advert_loc_policy = ADVERT_LOC_PREFS;
|
||||
savePrefs();
|
||||
strcpy(reply, "ok");
|
||||
} else {
|
||||
strcpy(reply, "error");
|
||||
}
|
||||
} else if (memcmp(command, "gps", 3) == 0) {
|
||||
LocationProvider * l = sensors.getLocationProvider();
|
||||
if (l != NULL) {
|
||||
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");
|
||||
if (enabled) {
|
||||
sprintf(reply, "on, %s, %s, %d sats",
|
||||
active?"active":"deactivated",
|
||||
fix?"fix":"no fix",
|
||||
sats);
|
||||
} else {
|
||||
strcpy(reply, "off");
|
||||
}
|
||||
} else {
|
||||
strcpy(reply, "Can't find GPS");
|
||||
}
|
||||
#endif
|
||||
} else if (memcmp(command, "log start", 9) == 0) {
|
||||
_callbacks->setLoggingOn(true);
|
||||
strcpy(reply, " logging on");
|
||||
|
||||
@@ -2,11 +2,16 @@
|
||||
|
||||
#include "Mesh.h"
|
||||
#include <helpers/IdentityStore.h>
|
||||
#include <target.h>
|
||||
|
||||
#if defined(WITH_RS232_BRIDGE) || defined(WITH_ESPNOW_BRIDGE)
|
||||
#define WITH_BRIDGE
|
||||
#endif
|
||||
|
||||
#define ADVERT_LOC_NONE 0
|
||||
#define ADVERT_LOC_SHARE 1
|
||||
#define ADVERT_LOC_PREFS 2
|
||||
|
||||
struct NodePrefs { // persisted to file
|
||||
float airtime_factor;
|
||||
char node_name[32];
|
||||
@@ -37,6 +42,10 @@ struct NodePrefs { // persisted to file
|
||||
uint32_t bridge_baud; // 9600, 19200, 38400, 57600, 115200 (default 115200)
|
||||
uint8_t bridge_channel; // 1-14 (ESP-NOW only)
|
||||
char bridge_secret[16]; // for XOR encryption of bridge packets (ESP-NOW only)
|
||||
// Gps settings
|
||||
uint8_t gps_enabled;
|
||||
uint32_t gps_interval; // in seconds
|
||||
uint8_t advert_loc_policy;
|
||||
};
|
||||
|
||||
class CommonCLICallbacks {
|
||||
|
||||
@@ -23,4 +23,25 @@ public:
|
||||
virtual const char* getSettingValue(int i) const { return NULL; }
|
||||
virtual bool setSettingValue(const char* name, const char* value) { return false; }
|
||||
virtual LocationProvider* getLocationProvider() { return NULL; }
|
||||
|
||||
// Helper functions to manage setting by keys (useful in many places ...)
|
||||
const char* getSettingByKey(const char* key) {
|
||||
int num = getNumSettings();
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (strcmp(getSettingName(i), key) == 0) {
|
||||
return getSettingValue(i);
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool setSettingByKey(const char* key, const char* value) {
|
||||
int num = getNumSettings();
|
||||
for (int i = 0; i < num; i++) {
|
||||
if (strcmp(getSettingName(i), key) == 0) {
|
||||
return setSettingValue(key, value);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -387,27 +387,34 @@ bool EnvironmentSensorManager::querySensors(uint8_t requester_permissions, Cayen
|
||||
|
||||
|
||||
int EnvironmentSensorManager::getNumSettings() const {
|
||||
int settings = 0;
|
||||
#if ENV_INCLUDE_GPS
|
||||
return gps_detected ? 1 : 0; // only show GPS setting if GPS is detected
|
||||
#else
|
||||
return 0;
|
||||
if (gps_detected) settings++; // only show GPS setting if GPS is detected
|
||||
#endif
|
||||
return settings;
|
||||
}
|
||||
|
||||
const char* EnvironmentSensorManager::getSettingName(int i) const {
|
||||
int settings = 0;
|
||||
#if ENV_INCLUDE_GPS
|
||||
return (gps_detected && i == 0) ? "gps" : NULL;
|
||||
#else
|
||||
return NULL;
|
||||
if (gps_detected && i == settings++) {
|
||||
return "gps";
|
||||
}
|
||||
#endif
|
||||
// convenient way to add params (needed for some tests)
|
||||
// if (i == settings++) return "param.2";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char* EnvironmentSensorManager::getSettingValue(int i) const {
|
||||
int settings = 0;
|
||||
#if ENV_INCLUDE_GPS
|
||||
if (gps_detected && i == 0) {
|
||||
return gps_active ? "1" : "0";
|
||||
}
|
||||
if (gps_detected && i == settings++) {
|
||||
return gps_active ? "1" : "0";
|
||||
}
|
||||
#endif
|
||||
// convenient way to add params ...
|
||||
// if (i == settings++) return "2";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,4 +21,5 @@ public:
|
||||
virtual void begin() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual void loop() = 0;
|
||||
virtual bool isEnabled() = 0;
|
||||
};
|
||||
|
||||
@@ -78,6 +78,16 @@ public :
|
||||
}
|
||||
}
|
||||
|
||||
bool isEnabled() override {
|
||||
// directly read the enable pin if present as gps can be
|
||||
// activated/deactivated outside of here ...
|
||||
if (_pin_en != -1) {
|
||||
return digitalRead(_pin_en) == PIN_GPS_EN_ACTIVE;
|
||||
} else {
|
||||
return true; // no enable so must be active
|
||||
}
|
||||
}
|
||||
|
||||
void syncTime() override { nmea.clear(); LocationProvider::syncTime(); }
|
||||
long getLatitude() override { return nmea.getLatitude(); }
|
||||
long getLongitude() override { return nmea.getLongitude(); }
|
||||
|
||||
Reference in New Issue
Block a user