mirror of
https://github.com/pelgraine/Meck.git
synced 2026-10-30 19:52:01 +01:00
MeshCore v1.18 batch 3: path length checks, trace offset, GPS clock wrap, UTF-8 advert names, BLE receive queue, search results 24, trace timeout
This commit is contained in:
1 parent
46f46035ba
commit
7ea461e443
9 files changed
+104
-38
No files matched your search
@@ -2495,7 +2495,8 @@ void MyMesh::handleCmdFrame(size_t len) {
|
||||
} else if (cmd_frame[0] == CMD_SEND_RAW_DATA && len >= 6) {
|
||||
int i = 1;
|
||||
uint8_t path_len = cmd_frame[i++];
|
||||
if (path_len != OUT_PATH_UNKNOWN && i + mesh::Packet::getPathByteLenFor(path_len) + 4 <= len) { // minimum 4 byte payload
|
||||
if (path_len != OUT_PATH_UNKNOWN && mesh::Packet::isValidPathLen(path_len)
|
||||
&& i + mesh::Packet::getPathByteLenFor(path_len) + 4 <= len) { // minimum 4 byte payload
|
||||
uint8_t *path = &cmd_frame[i];
|
||||
i += mesh::Packet::getPathByteLenFor(path_len);
|
||||
auto pkt = createRawData(&cmd_frame[i], len - i);
|
||||
@@ -2762,7 +2763,7 @@ void MyMesh::handleCmdFrame(size_t len) {
|
||||
sendDirect(pkt, &cmd_frame[10], path_len);
|
||||
|
||||
uint32_t t = _radio->getEstAirtimeFor(pkt->payload_len + pkt->path_len + 2);
|
||||
uint32_t est_timeout = calcDirectTimeoutMillisFor(t, path_len);
|
||||
uint32_t est_timeout = calcDirectTimeoutMillisFor(t, path_len >> path_sz);
|
||||
|
||||
out_frame[0] = RESP_CODE_SENT;
|
||||
out_frame[1] = 0;
|
||||
|
||||
+7
-1
@@ -55,7 +55,9 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
||||
uint8_t path_sz = flags & 0x03; // NEW v1.11+: lower 2 bits is path hash size
|
||||
|
||||
uint8_t len = pkt->payload_len - i;
|
||||
uint8_t offset = pkt->path_len << path_sz;
|
||||
// path_len*entry_size can exceed 255 (path_len up to 63, entry_size up to 8);
|
||||
// a uint8_t offset would wrap and steer the isHashMatch() read to the wrong place.
|
||||
uint16_t offset = (uint16_t)pkt->path_len << path_sz;
|
||||
if (offset >= len) { // TRACE has reached end of given path
|
||||
onTraceRecv(pkt, trace_tag, auth_code, flags, pkt->path, &pkt->payload[i], len);
|
||||
} else if (self_id.isHashMatch(&pkt->payload[i + offset], 1 << path_sz) && allowPacketForward(pkt) && !_tables->hasSeen(pkt)) {
|
||||
@@ -160,6 +162,10 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
|
||||
if (pkt->getPayloadType() == PAYLOAD_TYPE_PATH) {
|
||||
int k = 0;
|
||||
uint8_t path_len = data[k++];
|
||||
if (!Packet::isValidPathLen(path_len)) {
|
||||
MESH_DEBUG_PRINTLN("%s PAYLOAD_TYPE_PATH, bad path_len: %u", getLogDateTime(), (uint32_t)path_len);
|
||||
break; // reject bad encoding
|
||||
}
|
||||
uint8_t* path = &data[k]; k += Packet::getPathByteLenFor(path_len);
|
||||
uint8_t extra_type = data[k++] & 0x0F; // upper 4 bits reserved for future use
|
||||
uint8_t* extra = &data[k];
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <helpers/AdvertDataHelpers.h>
|
||||
#include <helpers/UTF8Helpers.h>
|
||||
|
||||
uint8_t AdvertDataBuilder::encodeTo(uint8_t app_data[]) {
|
||||
app_data[0] = _type;
|
||||
@@ -16,11 +17,12 @@
|
||||
app_data[0] |= ADV_FEAT2_MASK;
|
||||
memcpy(&app_data[i], &_extra2, 2); i += 2;
|
||||
}
|
||||
if (_name && *_name != 0) {
|
||||
app_data[0] |= ADV_NAME_MASK;
|
||||
const char* sp = _name;
|
||||
while (*sp && i < MAX_ADVERT_DATA_SIZE) {
|
||||
app_data[i++] = *sp++;
|
||||
if (_name && *_name != 0) {
|
||||
size_t name_len = mesh::validUtf8PrefixLength(_name, MAX_ADVERT_DATA_SIZE - i);
|
||||
if (name_len > 0) {
|
||||
app_data[0] |= ADV_NAME_MASK;
|
||||
memcpy(&app_data[i], _name, name_len);
|
||||
i += name_len;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "ContactInfo.h"
|
||||
|
||||
#define MAX_SEARCH_RESULTS 8
|
||||
#define MAX_SEARCH_RESULTS 24
|
||||
|
||||
#define MSG_SEND_FAILED 0
|
||||
#define MSG_SEND_SENT_FLOOD 1
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace mesh {
|
||||
|
||||
inline bool isUtf8Continuation(uint8_t byte) {
|
||||
return (byte & 0xC0) == 0x80;
|
||||
}
|
||||
|
||||
inline size_t validUtf8PrefixLength(const char* text, size_t max_bytes) {
|
||||
if (text == nullptr) return 0;
|
||||
|
||||
size_t offset = 0;
|
||||
while (text[offset] != '\0') {
|
||||
const uint8_t first = static_cast<uint8_t>(text[offset]);
|
||||
size_t sequence_length = 0;
|
||||
|
||||
if (first <= 0x7F) {
|
||||
sequence_length = 1;
|
||||
} else if (first >= 0xC2 && first <= 0xDF) {
|
||||
sequence_length = 2;
|
||||
} else if (first >= 0xE0 && first <= 0xEF) {
|
||||
sequence_length = 3;
|
||||
} else if (first >= 0xF0 && first <= 0xF4) {
|
||||
sequence_length = 4;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
if (offset + sequence_length > max_bytes) break;
|
||||
|
||||
bool complete = true;
|
||||
for (size_t i = 1; i < sequence_length; i++) {
|
||||
if (text[offset + i] == '\0' || !isUtf8Continuation(static_cast<uint8_t>(text[offset + i]))) {
|
||||
complete = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!complete) break;
|
||||
|
||||
if (sequence_length == 3) {
|
||||
const uint8_t second = static_cast<uint8_t>(text[offset + 1]);
|
||||
if ((first == 0xE0 && second < 0xA0) || (first == 0xED && second > 0x9F)) break;
|
||||
} else if (sequence_length == 4) {
|
||||
const uint8_t second = static_cast<uint8_t>(text[offset + 1]);
|
||||
if ((first == 0xF0 && second < 0x90) || (first == 0xF4 && second > 0x8F)) break;
|
||||
}
|
||||
|
||||
offset += sequence_length;
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
} // namespace mesh
|
||||
@@ -228,11 +228,10 @@ void SerialBLEInterface::onWrite(BLECharacteristic* pCharacteristic, esp_ble_gat
|
||||
memcpy(&_rx_buf[_rx_len], rxValue + 2, n);
|
||||
_rx_len += n;
|
||||
if (tag == SLICE_TAG_LAST || tag == SLICE_TAG_SINGLE) {
|
||||
if (recv_queue_len < FRAME_QUEUE_SIZE) {
|
||||
recv_queue[recv_queue_len].len = _rx_len;
|
||||
memcpy(recv_queue[recv_queue_len].buf, _rx_buf, _rx_len);
|
||||
recv_queue_len++;
|
||||
} else {
|
||||
Frame frame;
|
||||
frame.len = _rx_len;
|
||||
memcpy(frame.buf, _rx_buf, _rx_len);
|
||||
if (xQueueSend(recv_queue, &frame, 0) != pdTRUE) {
|
||||
BLE_DEBUG_PRINTLN("ERROR: onWrite(), recv_queue is full! (sliced)");
|
||||
}
|
||||
_rx_len = -1;
|
||||
@@ -242,12 +241,14 @@ void SerialBLEInterface::onWrite(BLECharacteristic* pCharacteristic, esp_ble_gat
|
||||
#endif
|
||||
if (len > MAX_FRAME_SIZE) {
|
||||
BLE_DEBUG_PRINTLN("ERROR: onWrite(), frame too big, len=%d", len);
|
||||
} else if (recv_queue_len >= FRAME_QUEUE_SIZE) {
|
||||
BLE_DEBUG_PRINTLN("ERROR: onWrite(), recv_queue is full!");
|
||||
} else {
|
||||
recv_queue[recv_queue_len].len = len;
|
||||
memcpy(recv_queue[recv_queue_len].buf, rxValue, len);
|
||||
recv_queue_len++;
|
||||
Frame frame;
|
||||
frame.len = len;
|
||||
memcpy(frame.buf, rxValue, len);
|
||||
|
||||
if (xQueueSend(recv_queue, &frame, 0) != pdTRUE) {
|
||||
BLE_DEBUG_PRINTLN("ERROR: onWrite(), recv_queue is full!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,17 +378,11 @@ size_t SerialBLEInterface::checkRecvFrame(uint8_t dest[]) {
|
||||
#endif
|
||||
}
|
||||
|
||||
if (recv_queue_len > 0) { // check recv queue
|
||||
size_t len = recv_queue[0].len; // take from top of queue
|
||||
memcpy(dest, recv_queue[0].buf, len);
|
||||
|
||||
BLE_DEBUG_PRINTLN("readBytes: sz=%d, hdr=%d", len, (uint32_t) dest[0]);
|
||||
|
||||
recv_queue_len--;
|
||||
if (recv_queue_len > 0) {
|
||||
memmove(&recv_queue[0], &recv_queue[1], recv_queue_len * sizeof(Frame));
|
||||
}
|
||||
return len;
|
||||
Frame frame;
|
||||
if (xQueueReceive(recv_queue, &frame, 0) == pdTRUE) { // check recv queue
|
||||
memcpy(dest, frame.buf, frame.len);
|
||||
BLE_DEBUG_PRINTLN("readBytes: sz=%d, hdr=%d", (uint32_t) frame.len, (uint32_t) dest[0]);
|
||||
return frame.len;
|
||||
}
|
||||
|
||||
if (pServer->getConnectedCount() == 0) {
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <BLEServer.h>
|
||||
#include <BLEUtils.h>
|
||||
#include <BLE2902.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/queue.h>
|
||||
|
||||
class SerialBLEInterface : public BaseSerialInterface, BLESecurityCallbacks, BLEServerCallbacks, BLECharacteristicCallbacks {
|
||||
BLEServer *pServer;
|
||||
@@ -36,13 +38,14 @@ class SerialBLEInterface : public BaseSerialInterface, BLESecurityCallbacks, BLE
|
||||
};
|
||||
|
||||
#define FRAME_QUEUE_SIZE 16
|
||||
int recv_queue_len;
|
||||
Frame recv_queue[FRAME_QUEUE_SIZE];
|
||||
StaticQueue_t recv_queue_state;
|
||||
uint8_t recv_queue_storage[FRAME_QUEUE_SIZE * sizeof(Frame)];
|
||||
QueueHandle_t recv_queue; // filled by the BLE stack task (onWrite), drained by loop()
|
||||
int send_queue_len;
|
||||
Frame send_queue[FRAME_QUEUE_SIZE];
|
||||
|
||||
void clearBuffers() {
|
||||
recv_queue_len = 0; send_queue_len = 0;
|
||||
xQueueReset(recv_queue); send_queue_len = 0;
|
||||
#ifdef MECK_BLE_SMALL_MTU_SPLIT
|
||||
_tx_off = 0; _rx_len = -1;
|
||||
#endif
|
||||
@@ -83,7 +86,10 @@ public:
|
||||
_last_write = 0;
|
||||
last_conn_id = 0;
|
||||
memset(_remote_bda, 0, 6);
|
||||
send_queue_len = recv_queue_len = 0;
|
||||
recv_queue = xQueueCreateStatic(
|
||||
FRAME_QUEUE_SIZE, sizeof(Frame), recv_queue_storage, &recv_queue_state
|
||||
);
|
||||
send_queue_len = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -698,11 +698,11 @@ void EnvironmentSensorManager::stop_gps() {
|
||||
}
|
||||
|
||||
void EnvironmentSensorManager::loop() {
|
||||
static long next_gps_update = 0;
|
||||
static unsigned long next_gps_update = 0;
|
||||
|
||||
#if ENV_INCLUDE_GPS
|
||||
_location->loop();
|
||||
if (millis() > next_gps_update) {
|
||||
if ((long)(millis() - next_gps_update) > 0) {
|
||||
|
||||
if(gps_active){
|
||||
#ifdef RAK_WISBLOCK_GPS
|
||||
|
||||
@@ -41,7 +41,7 @@ class MicroNMEALocationProvider : public LocationProvider {
|
||||
RefCountedDigitalPin* _peripher_power;
|
||||
int _pin_reset;
|
||||
int _pin_en;
|
||||
long next_check = 0;
|
||||
unsigned long next_check = 0;
|
||||
long time_valid = 0;
|
||||
|
||||
public :
|
||||
@@ -124,7 +124,7 @@ public :
|
||||
|
||||
if (!isValid()) time_valid = 0;
|
||||
|
||||
if (millis() > next_check) {
|
||||
if ((long)(millis() - next_check) > 0) {
|
||||
next_check = millis() + 1000;
|
||||
if (_time_sync_needed && time_valid > 2) {
|
||||
if (_clock != NULL) {
|
||||
|
||||
Reference in new issue
Block a user