mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-04-20 22:13:47 +00:00
Merge branch 'ripplebiz:dev' into dev
This commit is contained in:
commit
a6c8dc4866
10 changed files with 168 additions and 69 deletions
|
|
@ -46,6 +46,9 @@
|
|||
#define CMD_SET_CUSTOM_VAR 41
|
||||
#define CMD_GET_ADVERT_PATH 42
|
||||
#define CMD_GET_TUNING_PARAMS 43
|
||||
// NOTE: CMD range 44..49 parked, potentially for WiFi operations
|
||||
#define CMD_SEND_BINARY_REQ 50
|
||||
#define CMD_FACTORY_RESET 51
|
||||
|
||||
#define RESP_CODE_OK 0
|
||||
#define RESP_CODE_ERR 1
|
||||
|
|
@ -93,6 +96,7 @@
|
|||
#define PUSH_CODE_TRACE_DATA 0x89
|
||||
#define PUSH_CODE_NEW_ADVERT 0x8A
|
||||
#define PUSH_CODE_TELEMETRY_RESPONSE 0x8B
|
||||
#define PUSH_CODE_BINARY_RESPONSE 0x8C
|
||||
|
||||
#define ERR_CODE_UNSUPPORTED_CMD 1
|
||||
#define ERR_CODE_NOT_FOUND 2
|
||||
|
|
@ -468,6 +472,7 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
|
|||
i += 6; // pub_key_prefix
|
||||
memcpy(&out_frame[i], &tag, 4);
|
||||
i += 4; // NEW: include server timestamp
|
||||
out_frame[i++] = data[7]; // NEW (v7): ACL permissions
|
||||
} else {
|
||||
out_frame[i++] = PUSH_CODE_LOGIN_FAIL;
|
||||
out_frame[i++] = 0; // reserved
|
||||
|
|
@ -490,7 +495,7 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
|
|||
memcpy(&out_frame[i], &data[4], len - 4);
|
||||
i += (len - 4);
|
||||
_serial->writeFrame(out_frame, i);
|
||||
} else if (len > 4 && tag == pending_telemetry) { // check for telemetry response
|
||||
} else if (len > 4 && tag == pending_telemetry) { // check for matching response tag
|
||||
pending_telemetry = 0;
|
||||
|
||||
int i = 0;
|
||||
|
|
@ -501,6 +506,17 @@ void MyMesh::onContactResponse(const ContactInfo &contact, const uint8_t *data,
|
|||
memcpy(&out_frame[i], &data[4], len - 4);
|
||||
i += (len - 4);
|
||||
_serial->writeFrame(out_frame, i);
|
||||
} else if (len > 4 && tag == pending_req) { // check for matching response tag
|
||||
pending_req = 0;
|
||||
|
||||
int i = 0;
|
||||
out_frame[i++] = PUSH_CODE_BINARY_RESPONSE;
|
||||
out_frame[i++] = 0; // reserved
|
||||
memcpy(&out_frame[i], &tag, 4); // app needs to match this to RESP_CODE_SENT.tag
|
||||
i += 4;
|
||||
memcpy(&out_frame[i], &data[4], len - 4);
|
||||
i += (len - 4);
|
||||
_serial->writeFrame(out_frame, i);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -566,7 +582,7 @@ MyMesh::MyMesh(mesh::Radio &radio, mesh::RNG &rng, mesh::RTCClock &rtc, SimpleMe
|
|||
_cli_rescue = false;
|
||||
offline_queue_len = 0;
|
||||
app_target_ver = 0;
|
||||
pending_login = pending_status = pending_telemetry = 0;
|
||||
pending_login = pending_status = pending_telemetry = pending_req = 0;
|
||||
next_ack_idx = 0;
|
||||
sign_data = NULL;
|
||||
dirty_contacts_expiry = 0;
|
||||
|
|
@ -1103,7 +1119,7 @@ void MyMesh::handleCmdFrame(size_t len) {
|
|||
if (result == MSG_SEND_FAILED) {
|
||||
writeErrFrame(ERR_CODE_TABLE_FULL);
|
||||
} else {
|
||||
pending_telemetry = pending_status = 0;
|
||||
pending_req = pending_telemetry = pending_status = 0;
|
||||
memcpy(&pending_login, recipient->id.pub_key, 4); // match this to onContactResponse()
|
||||
out_frame[0] = RESP_CODE_SENT;
|
||||
out_frame[1] = (result == MSG_SEND_SENT_FLOOD) ? 1 : 0;
|
||||
|
|
@ -1123,7 +1139,7 @@ void MyMesh::handleCmdFrame(size_t len) {
|
|||
if (result == MSG_SEND_FAILED) {
|
||||
writeErrFrame(ERR_CODE_TABLE_FULL);
|
||||
} else {
|
||||
pending_telemetry = pending_login = 0;
|
||||
pending_req = pending_telemetry = pending_login = 0;
|
||||
// FUTURE: pending_status = tag; // match this in onContactResponse()
|
||||
memcpy(&pending_status, recipient->id.pub_key, 4); // legacy matching scheme
|
||||
out_frame[0] = RESP_CODE_SENT;
|
||||
|
|
@ -1135,7 +1151,7 @@ void MyMesh::handleCmdFrame(size_t len) {
|
|||
} else {
|
||||
writeErrFrame(ERR_CODE_NOT_FOUND); // contact not found
|
||||
}
|
||||
} else if (cmd_frame[0] == CMD_SEND_TELEMETRY_REQ && len >= 4 + PUB_KEY_SIZE) {
|
||||
} else if (cmd_frame[0] == CMD_SEND_TELEMETRY_REQ && len >= 4 + PUB_KEY_SIZE) { // can deprecate, in favour of CMD_SEND_BINARY_REQ
|
||||
uint8_t *pub_key = &cmd_frame[4];
|
||||
ContactInfo *recipient = lookupContactByPubKey(pub_key, PUB_KEY_SIZE);
|
||||
if (recipient) {
|
||||
|
|
@ -1144,7 +1160,7 @@ void MyMesh::handleCmdFrame(size_t len) {
|
|||
if (result == MSG_SEND_FAILED) {
|
||||
writeErrFrame(ERR_CODE_TABLE_FULL);
|
||||
} else {
|
||||
pending_status = pending_login = 0;
|
||||
pending_status = pending_login = pending_req = 0;
|
||||
pending_telemetry = tag; // match this in onContactResponse()
|
||||
out_frame[0] = RESP_CODE_SENT;
|
||||
out_frame[1] = (result == MSG_SEND_SENT_FLOOD) ? 1 : 0;
|
||||
|
|
@ -1170,6 +1186,27 @@ void MyMesh::handleCmdFrame(size_t len) {
|
|||
memcpy(&out_frame[i], telemetry.getBuffer(), tlen);
|
||||
i += tlen;
|
||||
_serial->writeFrame(out_frame, i);
|
||||
} else if (cmd_frame[0] == CMD_SEND_BINARY_REQ && len >= 2 + PUB_KEY_SIZE) {
|
||||
uint8_t *pub_key = &cmd_frame[1];
|
||||
ContactInfo *recipient = lookupContactByPubKey(pub_key, PUB_KEY_SIZE);
|
||||
if (recipient) {
|
||||
uint8_t *req_data = &cmd_frame[1 + PUB_KEY_SIZE];
|
||||
uint32_t tag, est_timeout;
|
||||
int result = sendRequest(*recipient, req_data, len - (1 + PUB_KEY_SIZE), tag, est_timeout);
|
||||
if (result == MSG_SEND_FAILED) {
|
||||
writeErrFrame(ERR_CODE_TABLE_FULL);
|
||||
} else {
|
||||
pending_status = pending_login = pending_telemetry = 0;
|
||||
pending_req = tag; // match this in onContactResponse()
|
||||
out_frame[0] = RESP_CODE_SENT;
|
||||
out_frame[1] = (result == MSG_SEND_SENT_FLOOD) ? 1 : 0;
|
||||
memcpy(&out_frame[2], &tag, 4);
|
||||
memcpy(&out_frame[6], &est_timeout, 4);
|
||||
_serial->writeFrame(out_frame, 10);
|
||||
}
|
||||
} else {
|
||||
writeErrFrame(ERR_CODE_NOT_FOUND); // contact not found
|
||||
}
|
||||
} else if (cmd_frame[0] == CMD_HAS_CONNECTION && len >= 1 + PUB_KEY_SIZE) {
|
||||
uint8_t *pub_key = &cmd_frame[1];
|
||||
if (hasConnectionTo(pub_key)) {
|
||||
|
|
@ -1325,6 +1362,15 @@ void MyMesh::handleCmdFrame(size_t len) {
|
|||
} else {
|
||||
writeErrFrame(ERR_CODE_NOT_FOUND);
|
||||
}
|
||||
} else if (cmd_frame[0] == CMD_FACTORY_RESET && memcmp(&cmd_frame[1], "reset", 5) == 0) {
|
||||
bool success = _store->formatFileSystem();
|
||||
if (success) {
|
||||
writeOKFrame();
|
||||
delay(1000);
|
||||
board.reboot(); // doesn't return
|
||||
} else {
|
||||
writeErrFrame(ERR_CODE_FILE_IO_ERROR);
|
||||
}
|
||||
} else {
|
||||
writeErrFrame(ERR_CODE_UNSUPPORTED_CMD);
|
||||
MESH_DEBUG_PRINTLN("ERROR: unknown command: %02X", cmd_frame[0]);
|
||||
|
|
|
|||
|
|
@ -7,14 +7,14 @@
|
|||
#endif
|
||||
|
||||
/*------------ Frame Protocol --------------*/
|
||||
#define FIRMWARE_VER_CODE 6
|
||||
#define FIRMWARE_VER_CODE 7
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
#define FIRMWARE_BUILD_DATE "2 Jul 2025"
|
||||
#define FIRMWARE_BUILD_DATE "15 Jul 2025"
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "v1.7.2"
|
||||
#define FIRMWARE_VERSION "v1.7.3"
|
||||
#endif
|
||||
|
||||
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
|
||||
|
|
@ -160,7 +160,8 @@ private:
|
|||
NodePrefs _prefs;
|
||||
uint32_t pending_login;
|
||||
uint32_t pending_status;
|
||||
uint32_t pending_telemetry;
|
||||
uint32_t pending_telemetry; // pending _TELEMETRY_REQ
|
||||
uint32_t pending_req; // pending _BINARY_REQ
|
||||
BaseSerialInterface *_serial;
|
||||
|
||||
ContactsIterator _iter;
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@
|
|||
/* ------------------------------ Config -------------------------------- */
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
#define FIRMWARE_BUILD_DATE "2 Jul 2025"
|
||||
#define FIRMWARE_BUILD_DATE "15 Jul 2025"
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "v1.7.2"
|
||||
#define FIRMWARE_VERSION "v1.7.3"
|
||||
#endif
|
||||
|
||||
#ifndef LORA_FREQ
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@
|
|||
/* ------------------------------ Config -------------------------------- */
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
#define FIRMWARE_BUILD_DATE "2 Jul 2025"
|
||||
#define FIRMWARE_BUILD_DATE "15 Jul 2025"
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "v1.7.2"
|
||||
#define FIRMWARE_VERSION "v1.7.3"
|
||||
#endif
|
||||
|
||||
#ifndef LORA_FREQ
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@
|
|||
|
||||
#define LAZY_CONTACTS_WRITE_DELAY 5000
|
||||
|
||||
#define ALERT_ACK_EXPIRY_MILLIS 6000 // wait 6 secs for ACKs to alert messages
|
||||
#define ALERT_ACK_EXPIRY_MILLIS 8000 // wait 8 secs for ACKs to alert messages
|
||||
|
||||
static File openAppend(FILESYSTEM* _fs, const char* fname) {
|
||||
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
|
||||
|
|
@ -95,11 +95,11 @@ void SensorMesh::loadContacts() {
|
|||
while (!full) {
|
||||
ContactInfo c;
|
||||
uint8_t pub_key[32];
|
||||
uint8_t unused[5];
|
||||
uint8_t unused[6];
|
||||
|
||||
bool success = (file.read(pub_key, 32) == 32);
|
||||
success = success && (file.read((uint8_t *) &c.permissions, 2) == 2);
|
||||
success = success && (file.read(unused, 5) == 5);
|
||||
success = success && (file.read((uint8_t *) &c.permissions, 1) == 1);
|
||||
success = success && (file.read(unused, 6) == 6);
|
||||
success = success && (file.read((uint8_t *)&c.out_path_len, 1) == 1);
|
||||
success = success && (file.read(c.out_path, 64) == 64);
|
||||
success = success && (file.read(c.shared_secret, PUB_KEY_SIZE) == PUB_KEY_SIZE);
|
||||
|
|
@ -131,8 +131,8 @@ void SensorMesh::saveContacts() {
|
|||
if (c->permissions == 0) continue; // skip deleted entries
|
||||
|
||||
bool success = (file.write(c->id.pub_key, 32) == 32);
|
||||
success = success && (file.write((uint8_t *) &c->permissions, 2) == 2);
|
||||
success = success && (file.write(unused, 5) == 5);
|
||||
success = success && (file.write((uint8_t *) &c->permissions, 1) == 1);
|
||||
success = success && (file.write(unused, 6) == 6);
|
||||
success = success && (file.write((uint8_t *)&c->out_path_len, 1) == 1);
|
||||
success = success && (file.write(c->out_path, 64) == 64);
|
||||
success = success && (file.write(c->shared_secret, PUB_KEY_SIZE) == PUB_KEY_SIZE);
|
||||
|
|
@ -240,7 +240,7 @@ static uint8_t putFloat(uint8_t * dest, float value, uint8_t size, uint32_t mult
|
|||
return size;
|
||||
}
|
||||
|
||||
uint8_t SensorMesh::handleRequest(uint16_t perms, uint32_t sender_timestamp, uint8_t req_type, uint8_t* payload, size_t payload_len) {
|
||||
uint8_t SensorMesh::handleRequest(uint8_t perms, uint32_t sender_timestamp, uint8_t req_type, uint8_t* payload, size_t payload_len) {
|
||||
memcpy(reply_data, &sender_timestamp, 4); // reflect sender_timestamp back in response packet (kind of like a 'tag')
|
||||
|
||||
if (req_type == REQ_TYPE_GET_TELEMETRY_DATA && (perms & PERM_GET_TELEMETRY) != 0) {
|
||||
|
|
@ -248,12 +248,13 @@ uint8_t SensorMesh::handleRequest(uint16_t perms, uint32_t sender_timestamp, uin
|
|||
telemetry.addVoltage(TELEM_CHANNEL_SELF, (float)board.getBattMilliVolts() / 1000.0f);
|
||||
// query other sensors -- target specific
|
||||
sensors.querySensors(0xFF, telemetry); // allow all telemetry permissions for admin or guest
|
||||
// TODO: let requester know permissions they have: telemetry.addPresence(TELEM_CHANNEL_SELF, perms);
|
||||
|
||||
uint8_t tlen = telemetry.getSize();
|
||||
memcpy(&reply_data[4], telemetry.getBuffer(), tlen);
|
||||
return 4 + tlen; // reply_len
|
||||
}
|
||||
if (req_type == REQ_TYPE_GET_AVG_MIN_MAX && (perms & PERM_GET_MIN_MAX_AVG) != 0) {
|
||||
if (req_type == REQ_TYPE_GET_AVG_MIN_MAX && (perms & PERM_GET_OTHER_STATS) != 0) {
|
||||
uint32_t start_secs_ago, end_secs_ago;
|
||||
memcpy(&start_secs_ago, &payload[0], 4);
|
||||
memcpy(&end_secs_ago, &payload[4], 4);
|
||||
|
|
@ -287,15 +288,15 @@ uint8_t SensorMesh::handleRequest(uint16_t perms, uint32_t sender_timestamp, uin
|
|||
}
|
||||
return ofs;
|
||||
}
|
||||
if (req_type == REQ_TYPE_GET_ACCESS_LIST && (perms & PERM_IS_ADMIN) != 0) {
|
||||
if (req_type == REQ_TYPE_GET_ACCESS_LIST && (perms & PERM_ACL_ROLE_MASK) == PERM_ACL_LEVEL3) {
|
||||
uint8_t res1 = payload[0]; // reserved for future (extra query params)
|
||||
uint8_t res2 = payload[1];
|
||||
if (res1 == 0 && res2 == 0) {
|
||||
uint8_t ofs = 4;
|
||||
for (int i = 0; i < num_contacts && ofs + 8 <= sizeof(reply_data) - 4; i++) {
|
||||
for (int i = 0; i < num_contacts && ofs + 7 <= sizeof(reply_data) - 4; i++) {
|
||||
auto c = &contacts[i];
|
||||
memcpy(&reply_data[ofs], c->id.pub_key, 6); ofs += 6; // just 6-byte pub_key prefix
|
||||
memcpy(&reply_data[ofs], &c->permissions, 2); ofs += 2;
|
||||
reply_data[ofs++] = c->permissions;
|
||||
}
|
||||
return ofs;
|
||||
}
|
||||
|
|
@ -337,11 +338,11 @@ ContactInfo* SensorMesh::putContact(const mesh::Identity& id) {
|
|||
return c;
|
||||
}
|
||||
|
||||
void SensorMesh::applyContactPermissions(const uint8_t* pubkey, uint16_t perms) {
|
||||
void SensorMesh::applyContactPermissions(const uint8_t* pubkey, uint8_t perms) {
|
||||
mesh::Identity id(pubkey);
|
||||
auto c = putContact(id);
|
||||
|
||||
if (perms == 0) { // no permissions, remove from contacts
|
||||
if ((perms & PERM_ACL_ROLE_MASK) == PERM_ACL_GUEST) { // guest role is not persisted in contacts
|
||||
memset(c, 0, sizeof(*c));
|
||||
} else {
|
||||
c->permissions = perms; // update their permissions
|
||||
|
|
@ -449,7 +450,7 @@ uint8_t SensorMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t*
|
|||
MESH_DEBUG_PRINTLN("Login success!");
|
||||
client->last_timestamp = sender_timestamp;
|
||||
client->last_activity = getRTCClock()->getCurrentTime();
|
||||
client->permissions = PERM_IS_ADMIN | PERM_RECV_ALERTS_HI | PERM_RECV_ALERTS_LO; // initially opt-in to receive alerts (can opt out)
|
||||
client->permissions = PERM_ACL_LEVEL3 | PERM_RECV_ALERTS_HI | PERM_RECV_ALERTS_LO; // initially opt-in to receive alerts (can opt out)
|
||||
memcpy(client->shared_secret, secret, PUB_KEY_SIZE);
|
||||
|
||||
dirty_contacts_expiry = futureMillis(LAZY_CONTACTS_WRITE_DELAY);
|
||||
|
|
@ -459,7 +460,7 @@ uint8_t SensorMesh::handleLoginReq(const mesh::Identity& sender, const uint8_t*
|
|||
reply_data[4] = RESP_SERVER_LOGIN_OK;
|
||||
reply_data[5] = 0; // NEW: recommended keep-alive interval (secs / 16)
|
||||
reply_data[6] = 1; // 1 = is admin
|
||||
reply_data[7] = 0; // FUTURE: reserved
|
||||
reply_data[7] = client->permissions;
|
||||
getRNG()->random(&reply_data[8], 4); // random blob to help packet-hash uniqueness
|
||||
|
||||
return 12; // reply length
|
||||
|
|
@ -480,7 +481,7 @@ void SensorMesh::handleCommand(uint32_t sender_timestamp, char* command, char* r
|
|||
}
|
||||
|
||||
// handle sensor-specific CLI commands
|
||||
if (memcmp(command, "setperm ", 8) == 0) { // format: setperm {pubkey-hex} {permissions-int16}
|
||||
if (memcmp(command, "setperm ", 8) == 0) { // format: setperm {pubkey-hex} {permissions-int8}
|
||||
char* hex = &command[8];
|
||||
char* sp = strchr(hex, ' '); // look for separator char
|
||||
if (sp == NULL || sp - hex != PUB_KEY_SIZE*2) {
|
||||
|
|
@ -490,20 +491,21 @@ void SensorMesh::handleCommand(uint32_t sender_timestamp, char* command, char* r
|
|||
|
||||
uint8_t pubkey[PUB_KEY_SIZE];
|
||||
if (mesh::Utils::fromHex(pubkey, PUB_KEY_SIZE, hex)) {
|
||||
uint16_t perms = atoi(sp);
|
||||
uint8_t perms = atoi(sp);
|
||||
applyContactPermissions(pubkey, perms);
|
||||
strcpy(reply, "OK");
|
||||
} else {
|
||||
strcpy(reply, "Err - bad pubkey");
|
||||
}
|
||||
}
|
||||
} else if (sender_timestamp == 0 && strcmp(command, "getperm") == 0) {
|
||||
Serial.println("Permissions:");
|
||||
} else if (sender_timestamp == 0 && strcmp(command, "get acl") == 0) {
|
||||
Serial.println("ACL:");
|
||||
for (int i = 0; i < num_contacts; i++) {
|
||||
auto c = &contacts[i];
|
||||
|
||||
Serial.printf("%02X ", c->permissions);
|
||||
mesh::Utils::printHex(Serial, c->id.pub_key, PUB_KEY_SIZE);
|
||||
Serial.printf(" %04X\n", c->permissions);
|
||||
Serial.printf("\n");
|
||||
}
|
||||
reply[0] = 0;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -23,22 +23,29 @@
|
|||
#include <RTClib.h>
|
||||
#include <target.h>
|
||||
|
||||
#define PERM_IS_ADMIN 0x8000
|
||||
#define PERM_GET_TELEMETRY 0x0001
|
||||
#define PERM_GET_MIN_MAX_AVG 0x0002
|
||||
#define PERM_RECV_ALERTS_LO 0x0100 // low priority alerts
|
||||
#define PERM_RECV_ALERTS_HI 0x0200 // high priority alerts
|
||||
#define PERM_ACL_ROLE_MASK 3 // lower 2 bits
|
||||
#define PERM_ACL_GUEST 0
|
||||
#define PERM_ACL_LEVEL1 1
|
||||
#define PERM_ACL_LEVEL2 2
|
||||
#define PERM_ACL_LEVEL3 3 // admin
|
||||
|
||||
#define PERM_GET_TELEMETRY (1 << 2)
|
||||
#define PERM_GET_OTHER_STATS (1 << 3)
|
||||
#define PERM_RESERVED1 (1 << 4)
|
||||
#define PERM_RESERVED2 (1 << 5)
|
||||
#define PERM_RECV_ALERTS_LO (1 << 6) // low priority alerts
|
||||
#define PERM_RECV_ALERTS_HI (1 << 7) // high priority alerts
|
||||
|
||||
struct ContactInfo {
|
||||
mesh::Identity id;
|
||||
uint16_t permissions;
|
||||
uint8_t permissions;
|
||||
int8_t out_path_len;
|
||||
uint8_t out_path[MAX_PATH_SIZE];
|
||||
uint8_t shared_secret[PUB_KEY_SIZE];
|
||||
uint32_t last_timestamp; // by THEIR clock (transient)
|
||||
uint32_t last_activity; // by OUR clock (transient)
|
||||
|
||||
bool isAdmin() const { return (permissions & PERM_IS_ADMIN) != 0; }
|
||||
bool isAdmin() const { return (permissions & PERM_ACL_ROLE_MASK) == PERM_ACL_LEVEL3; }
|
||||
};
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
|
|
@ -151,10 +158,10 @@ private:
|
|||
void loadContacts();
|
||||
void saveContacts();
|
||||
uint8_t handleLoginReq(const mesh::Identity& sender, const uint8_t* secret, uint32_t sender_timestamp, const uint8_t* data);
|
||||
uint8_t handleRequest(uint16_t perms, uint32_t sender_timestamp, uint8_t req_type, uint8_t* payload, size_t payload_len);
|
||||
uint8_t handleRequest(uint8_t perms, uint32_t sender_timestamp, uint8_t req_type, uint8_t* payload, size_t payload_len);
|
||||
mesh::Packet* createSelfAdvert();
|
||||
ContactInfo* putContact(const mesh::Identity& id);
|
||||
void applyContactPermissions(const uint8_t* pubkey, uint16_t perms);
|
||||
void applyContactPermissions(const uint8_t* pubkey, uint8_t perms);
|
||||
|
||||
void sendAlert(ContactInfo* c, Trigger* t);
|
||||
|
||||
|
|
|
|||
|
|
@ -403,22 +403,52 @@ bool BaseChatMesh::importContact(const uint8_t src_buf[], uint8_t len) {
|
|||
}
|
||||
|
||||
int BaseChatMesh::sendLogin(const ContactInfo& recipient, const char* password, uint32_t& est_timeout) {
|
||||
int tlen;
|
||||
uint8_t temp[24];
|
||||
uint32_t now = getRTCClock()->getCurrentTimeUnique();
|
||||
memcpy(temp, &now, 4); // mostly an extra blob to help make packet_hash unique
|
||||
if (recipient.type == ADV_TYPE_ROOM) {
|
||||
memcpy(&temp[4], &recipient.sync_since, 4);
|
||||
int len = strlen(password); if (len > 15) len = 15; // max 15 chars currently
|
||||
memcpy(&temp[8], password, len);
|
||||
tlen = 8 + len;
|
||||
} else {
|
||||
int len = strlen(password); if (len > 15) len = 15; // max 15 chars currently
|
||||
memcpy(&temp[4], password, len);
|
||||
tlen = 4 + len;
|
||||
}
|
||||
mesh::Packet* pkt;
|
||||
{
|
||||
int tlen;
|
||||
uint8_t temp[24];
|
||||
uint32_t now = getRTCClock()->getCurrentTimeUnique();
|
||||
memcpy(temp, &now, 4); // mostly an extra blob to help make packet_hash unique
|
||||
if (recipient.type == ADV_TYPE_ROOM) {
|
||||
memcpy(&temp[4], &recipient.sync_since, 4);
|
||||
int len = strlen(password); if (len > 15) len = 15; // max 15 chars currently
|
||||
memcpy(&temp[8], password, len);
|
||||
tlen = 8 + len;
|
||||
} else {
|
||||
int len = strlen(password); if (len > 15) len = 15; // max 15 chars currently
|
||||
memcpy(&temp[4], password, len);
|
||||
tlen = 4 + len;
|
||||
}
|
||||
|
||||
auto pkt = createAnonDatagram(PAYLOAD_TYPE_ANON_REQ, self_id, recipient.id, recipient.shared_secret, temp, tlen);
|
||||
pkt = createAnonDatagram(PAYLOAD_TYPE_ANON_REQ, self_id, recipient.id, recipient.shared_secret, temp, tlen);
|
||||
}
|
||||
if (pkt) {
|
||||
uint32_t t = _radio->getEstAirtimeFor(pkt->getRawLength());
|
||||
if (recipient.out_path_len < 0) {
|
||||
sendFlood(pkt);
|
||||
est_timeout = calcFloodTimeoutMillisFor(t);
|
||||
return MSG_SEND_SENT_FLOOD;
|
||||
} else {
|
||||
sendDirect(pkt, recipient.out_path, recipient.out_path_len);
|
||||
est_timeout = calcDirectTimeoutMillisFor(t, recipient.out_path_len);
|
||||
return MSG_SEND_SENT_DIRECT;
|
||||
}
|
||||
}
|
||||
return MSG_SEND_FAILED;
|
||||
}
|
||||
|
||||
int BaseChatMesh::sendRequest(const ContactInfo& recipient, const uint8_t* req_data, uint8_t data_len, uint32_t& tag, uint32_t& est_timeout) {
|
||||
if (data_len > MAX_PACKET_PAYLOAD - 16) return MSG_SEND_FAILED;
|
||||
|
||||
mesh::Packet* pkt;
|
||||
{
|
||||
uint8_t temp[MAX_PACKET_PAYLOAD];
|
||||
tag = getRTCClock()->getCurrentTimeUnique();
|
||||
memcpy(temp, &tag, 4); // mostly an extra blob to help make packet_hash unique
|
||||
memcpy(&temp[4], req_data, data_len);
|
||||
|
||||
pkt = createDatagram(PAYLOAD_TYPE_REQ, recipient.id, recipient.shared_secret, temp, 4 + data_len);
|
||||
}
|
||||
if (pkt) {
|
||||
uint32_t t = _radio->getEstAirtimeFor(pkt->getRawLength());
|
||||
if (recipient.out_path_len < 0) {
|
||||
|
|
@ -435,14 +465,17 @@ int BaseChatMesh::sendLogin(const ContactInfo& recipient, const char* password,
|
|||
}
|
||||
|
||||
int BaseChatMesh::sendRequest(const ContactInfo& recipient, uint8_t req_type, uint32_t& tag, uint32_t& est_timeout) {
|
||||
uint8_t temp[13];
|
||||
tag = getRTCClock()->getCurrentTimeUnique();
|
||||
memcpy(temp, &tag, 4); // mostly an extra blob to help make packet_hash unique
|
||||
temp[4] = req_type;
|
||||
memset(&temp[5], 0, 4); // reserved (possibly for 'since' param)
|
||||
getRNG()->random(&temp[9], 4); // random blob to help make packet-hash unique
|
||||
mesh::Packet* pkt;
|
||||
{
|
||||
uint8_t temp[13];
|
||||
tag = getRTCClock()->getCurrentTimeUnique();
|
||||
memcpy(temp, &tag, 4); // mostly an extra blob to help make packet_hash unique
|
||||
temp[4] = req_type;
|
||||
memset(&temp[5], 0, 4); // reserved (possibly for 'since' param)
|
||||
getRNG()->random(&temp[9], 4); // random blob to help make packet-hash unique
|
||||
|
||||
auto pkt = createDatagram(PAYLOAD_TYPE_REQ, recipient.id, recipient.shared_secret, temp, sizeof(temp));
|
||||
pkt = createDatagram(PAYLOAD_TYPE_REQ, recipient.id, recipient.shared_secret, temp, sizeof(temp));
|
||||
}
|
||||
if (pkt) {
|
||||
uint32_t t = _radio->getEstAirtimeFor(pkt->getRawLength());
|
||||
if (recipient.out_path_len < 0) {
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ public:
|
|||
bool sendGroupMessage(uint32_t timestamp, mesh::GroupChannel& channel, const char* sender_name, const char* text, int text_len);
|
||||
int sendLogin(const ContactInfo& recipient, const char* password, uint32_t& est_timeout);
|
||||
int sendRequest(const ContactInfo& recipient, uint8_t req_type, uint32_t& tag, uint32_t& est_timeout);
|
||||
int sendRequest(const ContactInfo& recipient, const uint8_t* req_data, uint8_t data_len, uint32_t& tag, uint32_t& est_timeout);
|
||||
bool shareContactZeroHop(const ContactInfo& contact);
|
||||
uint8_t exportContact(const ContactInfo& contact, uint8_t dest_buf[]);
|
||||
bool importContact(const uint8_t src_buf[], uint8_t len);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,14 @@
|
|||
#include "target.h"
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
HeltecV3Board board;
|
||||
|
||||
static SPIClass spi;
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi);
|
||||
#if defined(P_LORA_SCLK)
|
||||
static SPIClass spi;
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY, spi);
|
||||
#else
|
||||
RADIO_CLASS radio = new Module(P_LORA_NSS, P_LORA_DIO_1, P_LORA_RESET, P_LORA_BUSY);
|
||||
#endif
|
||||
|
||||
WRAPPER_CLASS radio_driver(radio, board);
|
||||
|
||||
|
|
@ -21,7 +24,11 @@ DISPLAY_CLASS display;
|
|||
bool radio_init() {
|
||||
fallback_clock.begin();
|
||||
rtc_clock.begin(Wire);
|
||||
#if defined(P_LORA_SCLK)
|
||||
return radio.std_init(&spi);
|
||||
#else
|
||||
return radio.std_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t radio_get_rng_seed() {
|
||||
|
|
@ -42,4 +49,4 @@ void radio_set_tx_power(uint8_t dbm) {
|
|||
mesh::LocalIdentity radio_new_identity() {
|
||||
RadioNoiseListener rng(radio);
|
||||
return mesh::LocalIdentity(&rng); // create new random identity
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ void initVariant() {
|
|||
pinMode(LED_BLUE, OUTPUT);
|
||||
digitalWrite(LED_BLUE, LOW);
|
||||
|
||||
/* disable gps until we actually support it.
|
||||
pinMode(GPS_EN, OUTPUT);
|
||||
digitalWrite(GPS_EN, HIGH);
|
||||
*/
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue