mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-03-30 14:55:46 +00:00
* Refactor: new AdvertDataHelpers.h
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <helpers/StaticPoolPacketManager.h>
|
||||
#include <helpers/SimpleMeshTables.h>
|
||||
#include <helpers/IdentityStore.h>
|
||||
#include <helpers/AdvertDataHelpers.h>
|
||||
#include <RTClib.h>
|
||||
|
||||
/* ------------------------------ Config -------------------------------- */
|
||||
@@ -345,34 +346,14 @@ public:
|
||||
num_clients = 0;
|
||||
}
|
||||
|
||||
#define ADV_TYPE_NONE 0 // unknown
|
||||
#define ADV_TYPE_CHAT 1
|
||||
#define ADV_TYPE_REPEATER 2
|
||||
//FUTURE: 3..15
|
||||
|
||||
#define ADV_LATLON_MASK 0x10
|
||||
#define ADV_BATTERY_MASK 0x20
|
||||
#define ADV_TEMPERATURE_MASK 0x40
|
||||
#define ADV_NAME_MASK 0x80
|
||||
|
||||
void sendSelfAdvertisement() {
|
||||
uint8_t app_data[MAX_ADVERT_DATA_SIZE+32];
|
||||
app_data[0] = ADV_TYPE_REPEATER | ADV_NAME_MASK;
|
||||
int i = 1;
|
||||
int32_t lat = ADVERT_LAT * 1E6;
|
||||
int32_t lon = ADVERT_LON * 1E6;
|
||||
if (!(lat == 0 && lon == 0)) {
|
||||
app_data[0] |= ADV_LATLON_MASK;
|
||||
memcpy(&app_data[i], &lat, 4); i += 4;
|
||||
memcpy(&app_data[i], &lon, 4); i += 4;
|
||||
uint8_t app_data[MAX_ADVERT_DATA_SIZE];
|
||||
uint8_t app_data_len;
|
||||
{
|
||||
AdvertDataBuilder builder(ADV_TYPE_REPEATER, ADVERT_NAME, ADVERT_LAT, ADVERT_LON);
|
||||
app_data_len = builder.encodeTo(app_data);
|
||||
}
|
||||
strcpy((char *)&app_data[i], ADVERT_NAME);
|
||||
int app_data_len = i + strlen(ADVERT_NAME);
|
||||
if (app_data_len > MAX_ADVERT_DATA_SIZE) {
|
||||
app_data_len = MAX_ADVERT_DATA_SIZE;
|
||||
app_data[MAX_ADVERT_DATA_SIZE - 1] = 0; // truncate the ADVERT_NAME
|
||||
}
|
||||
|
||||
|
||||
mesh::Packet* pkt = createAdvert(self_id, app_data, app_data_len);
|
||||
if (pkt) {
|
||||
sendFlood(pkt, 800); // add slight delay
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <helpers/StaticPoolPacketManager.h>
|
||||
#include <helpers/SimpleMeshTables.h>
|
||||
#include <helpers/IdentityStore.h>
|
||||
#include <helpers/AdvertDataHelpers.h>
|
||||
#include <RTClib.h>
|
||||
|
||||
/* ------------------------------ Config -------------------------------- */
|
||||
@@ -422,35 +423,14 @@ public:
|
||||
memset(posts, 0, sizeof(posts));
|
||||
}
|
||||
|
||||
#define ADV_TYPE_NONE 0 // unknown
|
||||
#define ADV_TYPE_CHAT 1
|
||||
#define ADV_TYPE_REPEATER 2
|
||||
#define ADV_TYPE_ROOM 3 // New kid on the block!
|
||||
//FUTURE: 4..15
|
||||
|
||||
#define ADV_LATLON_MASK 0x10
|
||||
#define ADV_BATTERY_MASK 0x20
|
||||
#define ADV_TEMPERATURE_MASK 0x40
|
||||
#define ADV_NAME_MASK 0x80
|
||||
|
||||
void sendSelfAdvertisement() {
|
||||
uint8_t app_data[MAX_ADVERT_DATA_SIZE+32];
|
||||
app_data[0] = ADV_TYPE_ROOM | ADV_NAME_MASK;
|
||||
int i = 1;
|
||||
int32_t lat = ADVERT_LAT * 1E6;
|
||||
int32_t lon = ADVERT_LON * 1E6;
|
||||
if (!(lat == 0 && lon == 0)) {
|
||||
app_data[0] |= ADV_LATLON_MASK;
|
||||
memcpy(&app_data[i], &lat, 4); i += 4;
|
||||
memcpy(&app_data[i], &lon, 4); i += 4;
|
||||
uint8_t app_data[MAX_ADVERT_DATA_SIZE];
|
||||
uint8_t app_data_len;
|
||||
{
|
||||
AdvertDataBuilder builder(ADV_TYPE_ROOM, ADVERT_NAME, ADVERT_LAT, ADVERT_LON);
|
||||
app_data_len = builder.encodeTo(app_data);
|
||||
}
|
||||
strcpy((char *)&app_data[i], ADVERT_NAME);
|
||||
int app_data_len = i + strlen(ADVERT_NAME);
|
||||
if (app_data_len > MAX_ADVERT_DATA_SIZE) {
|
||||
app_data_len = MAX_ADVERT_DATA_SIZE;
|
||||
app_data[MAX_ADVERT_DATA_SIZE - 1] = 0; // truncate the ADVERT_NAME
|
||||
}
|
||||
|
||||
|
||||
mesh::Packet* pkt = createAdvert(self_id, app_data, app_data_len);
|
||||
if (pkt) {
|
||||
sendFlood(pkt, 1200); // add slight delay
|
||||
@@ -504,6 +484,7 @@ public:
|
||||
if (c->pending_ack && millisHasNowPassed(c->ack_timeout)) {
|
||||
c->push_failures++;
|
||||
c->pending_ack = 0; // reset (TODO: keep prev expected_ack's in a list, incase they arrive LATER, after we retry)
|
||||
MESH_DEBUG_PRINTLN("pending ACK timed out: push_failures: %d", (uint32_t)c->push_failures);
|
||||
|
||||
if (c->push_failures >= 3) {
|
||||
evict(c);
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <helpers/ArduinoHelpers.h>
|
||||
#include <helpers/StaticPoolPacketManager.h>
|
||||
#include <helpers/SimpleMeshTables.h>
|
||||
#include <helpers/AdvertDataHelpers.h>
|
||||
|
||||
/* ---------------------------------- CONFIGURATION ------------------------------------- */
|
||||
|
||||
@@ -132,14 +133,11 @@ protected:
|
||||
}
|
||||
}
|
||||
// unknown node
|
||||
if (app_data_len > 0 && app_data[0] == (ADV_TYPE_CHAT | ADV_NAME_MASK)) { // is it a 'Chat' node (with a name)?
|
||||
AdvertDataParser parser(app_data, app_data_len);
|
||||
if (parser.getType() == ADV_TYPE_CHAT && parser.hasName()) { // is it a 'Chat' node (with a name)?
|
||||
// automatically add to our contacts
|
||||
char name[32];
|
||||
memcpy(name, &app_data[1], app_data_len - 1);
|
||||
name[app_data_len - 1] = 0; // need null terminator
|
||||
|
||||
addContact(name, id);
|
||||
Serial.printf(" ADDED contact: %s\n", name);
|
||||
addContact(parser.getName(), id);
|
||||
Serial.printf(" ADDED contact: %s\n", parser.getName());
|
||||
} else {
|
||||
Serial.printf(" Unknown app_data type: %02X, len=%d\n", app_data[0], app_data_len);
|
||||
}
|
||||
@@ -268,10 +266,12 @@ public:
|
||||
}
|
||||
|
||||
void sendSelfAdvert() {
|
||||
uint8_t app_data[32];
|
||||
app_data[0] = ADV_TYPE_CHAT | ADV_NAME_MASK;
|
||||
strcpy((char *)&app_data[1], USER_NAME);
|
||||
int app_data_len = 1 + strlen(USER_NAME);
|
||||
uint8_t app_data[MAX_ADVERT_DATA_SIZE];
|
||||
uint8_t app_data_len;
|
||||
{
|
||||
AdvertDataBuilder builder(ADV_TYPE_CHAT, USER_NAME);
|
||||
app_data_len = builder.encodeTo(app_data);
|
||||
}
|
||||
|
||||
mesh::Packet* adv = createAdvert(self_id, app_data, app_data_len);
|
||||
if (adv) {
|
||||
|
||||
101
src/helpers/AdvertDataHelpers.h
Normal file
101
src/helpers/AdvertDataHelpers.h
Normal file
@@ -0,0 +1,101 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define ADV_TYPE_NONE 0 // unknown
|
||||
#define ADV_TYPE_CHAT 1
|
||||
#define ADV_TYPE_REPEATER 2
|
||||
#define ADV_TYPE_ROOM 3 // New kid on the block!
|
||||
//FUTURE: 4..15
|
||||
|
||||
#define ADV_LATLON_MASK 0x10
|
||||
#define ADV_BATTERY_MASK 0x20
|
||||
#define ADV_TEMPERATURE_MASK 0x40
|
||||
#define ADV_NAME_MASK 0x80
|
||||
|
||||
class AdvertDataBuilder {
|
||||
uint8_t _type;
|
||||
const char* _name;
|
||||
int32_t _lat, _lon;
|
||||
public:
|
||||
AdvertDataBuilder(uint8_t adv_type) : _type(adv_type), _name(NULL), _lat(0), _lon(0) { }
|
||||
AdvertDataBuilder(uint8_t adv_type, const char* name) : _type(adv_type), _name(name), _lat(0), _lon(0) { }
|
||||
AdvertDataBuilder(uint8_t adv_type, const char* name, double lat, double lon) :
|
||||
_type(adv_type), _name(name), _lat(lat * 1E6), _lon(lon * 1E6) { }
|
||||
|
||||
/**
|
||||
* \brief encode the given advertisement data.
|
||||
* \param app_data dest array, must be MAX_ADVERT_DATA_SIZE
|
||||
* \returns the encoded length in bytes
|
||||
*/
|
||||
uint8_t encodeTo(uint8_t app_data[]) {
|
||||
app_data[0] = _type;
|
||||
int i = 1;
|
||||
if (!(_lat == 0 && _lon == 0)) {
|
||||
app_data[0] |= ADV_LATLON_MASK;
|
||||
memcpy(&app_data[i], &_lat, 4); i += 4;
|
||||
memcpy(&app_data[i], &_lon, 4); i += 4;
|
||||
}
|
||||
// TODO: BATTERY encoding
|
||||
// TODO: TEMPERATURE encoding
|
||||
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++;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
};
|
||||
|
||||
class AdvertDataParser {
|
||||
uint8_t _flags;
|
||||
bool _valid;
|
||||
char _name[MAX_ADVERT_DATA_SIZE];
|
||||
int32_t _lat, _lon;
|
||||
public:
|
||||
AdvertDataParser(const uint8_t app_data[], uint8_t app_data_len) {
|
||||
_name[0] = 0;
|
||||
_lat = _lon = 0;
|
||||
_flags = app_data[0];
|
||||
_valid = false;
|
||||
|
||||
int i = 1;
|
||||
if (_flags & ADV_LATLON_MASK) {
|
||||
memcpy(&_lat, &app_data[i], 4); i += 4;
|
||||
memcpy(&_lon, &app_data[i], 4); i += 4;
|
||||
}
|
||||
if (_flags & ADV_BATTERY_MASK) {
|
||||
/* TODO: somewhere to store battery volts? */ i += 2;
|
||||
}
|
||||
if (_flags & ADV_TEMPERATURE_MASK) {
|
||||
/* TODO: somewhere to store temperature? */ i += 2;
|
||||
}
|
||||
|
||||
if (app_data_len >= i) {
|
||||
int nlen = 0;
|
||||
if (_flags & ADV_NAME_MASK) {
|
||||
nlen = app_data_len - i; // remainder of app_data
|
||||
}
|
||||
if (nlen > 0) {
|
||||
memcpy(_name, &app_data[i], nlen);
|
||||
_name[nlen] = 0; // set null terminator
|
||||
}
|
||||
_valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool isValid() const { return _valid; }
|
||||
uint8_t getType() const { return _flags & 0x0F; }
|
||||
|
||||
bool hasName() const { _name[0] != 0; }
|
||||
const char* getName() const { return _name; }
|
||||
|
||||
bool hasLatLon() const { return !(_lat == 0 && _lon == 0); }
|
||||
int32_t getIntLat() const { return _lat; }
|
||||
int32_t getIntLon() const { return _lon; }
|
||||
double getLat() const { return ((double)_lat) / 1000000.0; }
|
||||
double getLon() const { return ((double)_lon) / 1000000.0; }
|
||||
};
|
||||
Reference in New Issue
Block a user