mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-04-20 22:13:47 +00:00
Merge branch 'dev' into ext-trace
This commit is contained in:
commit
cdbeacdc4d
12 changed files with 475 additions and 44 deletions
|
|
@ -52,6 +52,12 @@
|
|||
#define CMD_SEND_PATH_DISCOVERY_REQ 52
|
||||
#define CMD_SET_FLOOD_SCOPE 54 // v8+
|
||||
#define CMD_SEND_CONTROL_DATA 55 // v8+
|
||||
#define CMD_GET_STATS 56 // v8+, second byte is stats type
|
||||
|
||||
// Stats sub-types for CMD_GET_STATS
|
||||
#define STATS_TYPE_CORE 0
|
||||
#define STATS_TYPE_RADIO 1
|
||||
#define STATS_TYPE_PACKETS 2
|
||||
|
||||
#define RESP_CODE_OK 0
|
||||
#define RESP_CODE_ERR 1
|
||||
|
|
@ -77,6 +83,7 @@
|
|||
#define RESP_CODE_CUSTOM_VARS 21
|
||||
#define RESP_CODE_ADVERT_PATH 22
|
||||
#define RESP_CODE_TUNING_PARAMS 23
|
||||
#define RESP_CODE_STATS 24 // v8+, second byte is stats type
|
||||
|
||||
#define SEND_TIMEOUT_BASE_MILLIS 500
|
||||
#define FLOOD_SEND_TIMEOUT_FACTOR 16.0f
|
||||
|
|
@ -1541,6 +1548,55 @@ void MyMesh::handleCmdFrame(size_t len) {
|
|||
} else {
|
||||
writeErrFrame(ERR_CODE_NOT_FOUND);
|
||||
}
|
||||
} else if (cmd_frame[0] == CMD_GET_STATS && len >= 2) {
|
||||
uint8_t stats_type = cmd_frame[1];
|
||||
if (stats_type == STATS_TYPE_CORE) {
|
||||
int i = 0;
|
||||
out_frame[i++] = RESP_CODE_STATS;
|
||||
out_frame[i++] = STATS_TYPE_CORE;
|
||||
uint16_t battery_mv = board.getBattMilliVolts();
|
||||
uint32_t uptime_secs = _ms->getMillis() / 1000;
|
||||
uint8_t queue_len = (uint8_t)_mgr->getOutboundCount(0xFFFFFFFF);
|
||||
memcpy(&out_frame[i], &battery_mv, 2); i += 2;
|
||||
memcpy(&out_frame[i], &uptime_secs, 4); i += 4;
|
||||
memcpy(&out_frame[i], &_err_flags, 2); i += 2;
|
||||
out_frame[i++] = queue_len;
|
||||
_serial->writeFrame(out_frame, i);
|
||||
} else if (stats_type == STATS_TYPE_RADIO) {
|
||||
int i = 0;
|
||||
out_frame[i++] = RESP_CODE_STATS;
|
||||
out_frame[i++] = STATS_TYPE_RADIO;
|
||||
int16_t noise_floor = (int16_t)_radio->getNoiseFloor();
|
||||
int8_t last_rssi = (int8_t)radio_driver.getLastRSSI();
|
||||
int8_t last_snr = (int8_t)(radio_driver.getLastSNR() * 4); // scaled by 4 for 0.25 dB precision
|
||||
uint32_t tx_air_secs = getTotalAirTime() / 1000;
|
||||
uint32_t rx_air_secs = getReceiveAirTime() / 1000;
|
||||
memcpy(&out_frame[i], &noise_floor, 2); i += 2;
|
||||
out_frame[i++] = last_rssi;
|
||||
out_frame[i++] = last_snr;
|
||||
memcpy(&out_frame[i], &tx_air_secs, 4); i += 4;
|
||||
memcpy(&out_frame[i], &rx_air_secs, 4); i += 4;
|
||||
_serial->writeFrame(out_frame, i);
|
||||
} else if (stats_type == STATS_TYPE_PACKETS) {
|
||||
int i = 0;
|
||||
out_frame[i++] = RESP_CODE_STATS;
|
||||
out_frame[i++] = STATS_TYPE_PACKETS;
|
||||
uint32_t recv = radio_driver.getPacketsRecv();
|
||||
uint32_t sent = radio_driver.getPacketsSent();
|
||||
uint32_t n_sent_flood = getNumSentFlood();
|
||||
uint32_t n_sent_direct = getNumSentDirect();
|
||||
uint32_t n_recv_flood = getNumRecvFlood();
|
||||
uint32_t n_recv_direct = getNumRecvDirect();
|
||||
memcpy(&out_frame[i], &recv, 4); i += 4;
|
||||
memcpy(&out_frame[i], &sent, 4); i += 4;
|
||||
memcpy(&out_frame[i], &n_sent_flood, 4); i += 4;
|
||||
memcpy(&out_frame[i], &n_sent_direct, 4); i += 4;
|
||||
memcpy(&out_frame[i], &n_recv_flood, 4); i += 4;
|
||||
memcpy(&out_frame[i], &n_recv_direct, 4); i += 4;
|
||||
_serial->writeFrame(out_frame, i);
|
||||
} else {
|
||||
writeErrFrame(ERR_CODE_ILLEGAL_ARG); // invalid stats sub-type
|
||||
}
|
||||
} else if (cmd_frame[0] == CMD_FACTORY_RESET && memcmp(&cmd_frame[1], "reset", 5) == 0) {
|
||||
bool success = _store->formatFileSystem();
|
||||
if (success) {
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ void MyMesh::putNeighbour(const mesh::Identity &id, uint32_t timestamp, float sn
|
|||
#endif
|
||||
}
|
||||
|
||||
uint8_t MyMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t* secret, uint32_t sender_timestamp, const uint8_t* data) {
|
||||
uint8_t MyMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t* secret, uint32_t sender_timestamp, const uint8_t* data, bool is_flood) {
|
||||
ClientInfo* client = NULL;
|
||||
if (data[0] == 0) { // blank password, just check if sender is in ACL
|
||||
client = acl.getClient(sender.pub_key, PUB_KEY_SIZE);
|
||||
|
|
@ -123,6 +123,10 @@ uint8_t MyMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t* secr
|
|||
}
|
||||
}
|
||||
|
||||
if (is_flood) {
|
||||
client->out_path_len = -1; // need to rediscover out_path
|
||||
}
|
||||
|
||||
uint32_t now = getRTCClock()->getCurrentTimeUnique();
|
||||
memcpy(reply_data, &now, 4); // response packets always prefixed with timestamp
|
||||
reply_data[4] = RESP_SERVER_LOGIN_OK;
|
||||
|
|
@ -438,7 +442,7 @@ void MyMesh::onAnonDataRecv(mesh::Packet *packet, const uint8_t *secret, const m
|
|||
data[len] = 0; // ensure null terminator
|
||||
uint8_t reply_len;
|
||||
if (data[4] == 0 || data[4] >= ' ') { // is password, ie. a login request
|
||||
reply_len = handleLoginReq(sender, secret, timestamp, &data[4]);
|
||||
reply_len = handleLoginReq(sender, secret, timestamp, &data[4], packet->isRouteFlood());
|
||||
//} else if (data[4] == ANON_REQ_TYPE_*) { // future type codes
|
||||
// TODO
|
||||
} else {
|
||||
|
|
@ -710,6 +714,8 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc
|
|||
_prefs.gps_enabled = 0;
|
||||
_prefs.gps_interval = 0;
|
||||
_prefs.advert_loc_policy = ADVERT_LOC_PREFS;
|
||||
|
||||
_prefs.adc_multiplier = 0.0f; // 0.0f means use default board multiplier
|
||||
}
|
||||
|
||||
void MyMesh::begin(FILESYSTEM *fs) {
|
||||
|
|
@ -733,6 +739,8 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
|||
updateAdvertTimer();
|
||||
updateFloodAdvertTimer();
|
||||
|
||||
board.setAdcMultiplier(_prefs.adc_multiplier);
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
applyGpsPrefs();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
|
|||
#endif
|
||||
|
||||
void putNeighbour(const mesh::Identity& id, uint32_t timestamp, float snr);
|
||||
uint8_t handleLoginReq(const mesh::Identity& sender, const uint8_t* secret, uint32_t sender_timestamp, const uint8_t* data);
|
||||
uint8_t handleLoginReq(const mesh::Identity& sender, const uint8_t* secret, uint32_t sender_timestamp, const uint8_t* data, bool is_flood);
|
||||
int handleRequest(ClientInfo* sender, uint32_t sender_timestamp, uint8_t* payload, size_t payload_len);
|
||||
mesh::Packet* createSelfAdvert();
|
||||
|
||||
|
|
|
|||
|
|
@ -332,6 +332,10 @@ void MyMesh::onAnonDataRecv(mesh::Packet *packet, const uint8_t *secret, const m
|
|||
dirty_contacts_expiry = futureMillis(LAZY_CONTACTS_WRITE_DELAY);
|
||||
}
|
||||
|
||||
if (packet->isRouteFlood()) {
|
||||
client->out_path_len = -1; // need to rediscover out_path
|
||||
}
|
||||
|
||||
uint32_t now = getRTCClock()->getCurrentTimeUnique();
|
||||
memcpy(reply_data, &now, 4); // response packets always prefixed with timestamp
|
||||
// TODO: maybe reply with count of messages waiting to be synced for THIS client?
|
||||
|
|
@ -641,6 +645,8 @@ void MyMesh::begin(FILESYSTEM *fs) {
|
|||
updateAdvertTimer();
|
||||
updateFloodAdvertTimer();
|
||||
|
||||
board.setAdcMultiplier(_prefs.adc_multiplier);
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
applyGpsPrefs();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -326,7 +326,7 @@ int SensorMesh::getAGCResetInterval() const {
|
|||
return ((int)_prefs.agc_reset_interval) * 4000; // milliseconds
|
||||
}
|
||||
|
||||
uint8_t SensorMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t* secret, uint32_t sender_timestamp, const uint8_t* data) {
|
||||
uint8_t SensorMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t* secret, uint32_t sender_timestamp, const uint8_t* data, bool is_flood) {
|
||||
ClientInfo* client;
|
||||
if (data[0] == 0) { // blank password, just check if sender is in ACL
|
||||
client = acl.getClient(sender.pub_key, PUB_KEY_SIZE);
|
||||
|
|
@ -359,6 +359,10 @@ uint8_t SensorMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t*
|
|||
dirty_contacts_expiry = futureMillis(LAZY_CONTACTS_WRITE_DELAY);
|
||||
}
|
||||
|
||||
if (is_flood) {
|
||||
client->out_path_len = -1; // need to rediscover out_path
|
||||
}
|
||||
|
||||
uint32_t now = getRTCClock()->getCurrentTimeUnique();
|
||||
memcpy(reply_data, &now, 4); // response packets always prefixed with timestamp
|
||||
reply_data[4] = RESP_SERVER_LOGIN_OK;
|
||||
|
|
@ -451,7 +455,7 @@ void SensorMesh::onAnonDataRecv(mesh::Packet* packet, const uint8_t* secret, con
|
|||
data[len] = 0; // ensure null terminator
|
||||
uint8_t reply_len;
|
||||
if (data[4] == 0 || data[4] >= ' ') { // is password, ie. a login request
|
||||
reply_len = handleLoginReq(sender, secret, timestamp, &data[4]);
|
||||
reply_len = handleLoginReq(sender, secret, timestamp, &data[4], packet->isRouteFlood());
|
||||
//} else if (data[4] == ANON_REQ_TYPE_*) { // future type codes
|
||||
// TODO
|
||||
} else {
|
||||
|
|
@ -740,6 +744,8 @@ void SensorMesh::begin(FILESYSTEM* fs) {
|
|||
updateAdvertTimer();
|
||||
updateFloodAdvertTimer();
|
||||
|
||||
board.setAdcMultiplier(_prefs.adc_multiplier);
|
||||
|
||||
#if ENV_INCLUDE_GPS == 1
|
||||
applyGpsPrefs();
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ private:
|
|||
uint8_t pending_sf;
|
||||
uint8_t pending_cr;
|
||||
|
||||
uint8_t handleLoginReq(const mesh::Identity& sender, const uint8_t* secret, uint32_t sender_timestamp, const uint8_t* data);
|
||||
uint8_t handleLoginReq(const mesh::Identity& sender, const uint8_t* secret, uint32_t sender_timestamp, const uint8_t* data, bool is_flood);
|
||||
uint8_t handleRequest(uint8_t perms, uint32_t sender_timestamp, uint8_t req_type, uint8_t* payload, size_t payload_len);
|
||||
mesh::Packet* createSelfAdvert();
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue