mirror of
https://github.com/liquidraver/ZephCore.git
synced 2026-11-04 09:27:23 +00:00
sync with arduino/dev
This commit is contained in:
1 parent
e2f13e2292
commit
8dd6f149f8
8 files changed
+159
-22
No files matched your search
@@ -73,6 +73,7 @@ LOG_MODULE_REGISTER(zephcore_companion, CONFIG_ZEPHCORE_MAIN_LOG_LEVEL);
|
||||
#define CMD_GET_AUTOADD_CONFIG 0x3B
|
||||
#define CMD_GET_ALLOWED_REPEAT_FREQ 0x3C
|
||||
#define CMD_SET_PATH_HASH_MODE 0x3D
|
||||
#define CMD_SEND_CHANNEL_DATA 0x3E
|
||||
|
||||
/* Response packet types */
|
||||
#define PACKET_OK 0x00
|
||||
@@ -102,6 +103,9 @@ LOG_MODULE_REGISTER(zephcore_companion, CONFIG_ZEPHCORE_MAIN_LOG_LEVEL);
|
||||
#define PACKET_STATS 0x18
|
||||
#define PACKET_AUTOADD_CONFIG 0x19
|
||||
#define PACKET_ALLOWED_REPEAT_FREQ 0x1A
|
||||
#define PACKET_CHANNEL_DATA_RECV 0x1B
|
||||
|
||||
#define MAX_CHANNEL_DATA_LENGTH (MAX_FRAME_SIZE - 9)
|
||||
|
||||
#define MAX_SIGN_DATA_LEN (8 * 1024)
|
||||
|
||||
@@ -355,8 +359,8 @@ size_t CompanionMesh::serializeContact(uint8_t *buf, const ContactInfo &c, uint8
|
||||
|
||||
static bool isChannelMessage(const uint8_t *buf)
|
||||
{
|
||||
// Channel messages have PACKET_CHANNEL_MSG_V3 (0x11) or PACKET_CHANNEL_MSG_RECV (0x08)
|
||||
return buf[0] == PACKET_CHANNEL_MSG_V3 || buf[0] == PACKET_CHANNEL_MSG_RECV;
|
||||
// Channel messages have PACKET_CHANNEL_MSG_V3 (0x11) or PACKET_CHANNEL_MSG_RECV (0x08) or PACKET_CHANNEL_DATA_RECV (0x1B)
|
||||
return buf[0] == PACKET_CHANNEL_MSG_V3 || buf[0] == PACKET_CHANNEL_MSG_RECV || buf[0] == PACKET_CHANNEL_DATA_RECV;
|
||||
}
|
||||
|
||||
void CompanionMesh::queueOfflineMessage(const uint8_t *data, size_t len)
|
||||
@@ -745,6 +749,41 @@ void CompanionMesh::onChannelMessageRecv(const mesh::GroupChannel &channel, mesh
|
||||
sendPush(PUSH_CODE_MSG_WAITING);
|
||||
}
|
||||
|
||||
void CompanionMesh::onChannelDataRecv(const mesh::GroupChannel &channel, mesh::Packet *pkt,
|
||||
uint16_t data_type, const uint8_t *data, size_t data_len)
|
||||
{
|
||||
if (data_len > MAX_CHANNEL_DATA_LENGTH) {
|
||||
LOG_WRN("onChannelDataRecv: dropping payload_len=%d exceeds frame limit=%d",
|
||||
(int)data_len, (int)MAX_CHANNEL_DATA_LENGTH);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t frame[MAX_FRAME_SIZE];
|
||||
int i = 0;
|
||||
frame[i++] = PACKET_CHANNEL_DATA_RECV;
|
||||
frame[i++] = pkt ? (int8_t)(pkt->getSNR() * 4) : 0;
|
||||
frame[i++] = 0; // reserved1
|
||||
frame[i++] = 0; // reserved2
|
||||
|
||||
uint8_t channel_idx = findChannelIdx(channel);
|
||||
frame[i++] = channel_idx;
|
||||
frame[i++] = (pkt && pkt->isRouteFlood()) ? pkt->path_len : 0xFF;
|
||||
frame[i++] = (uint8_t)(data_type & 0xFF);
|
||||
frame[i++] = (uint8_t)(data_type >> 8);
|
||||
frame[i++] = (uint8_t)data_len;
|
||||
|
||||
int copy_len = (int)data_len;
|
||||
if (copy_len > 0) {
|
||||
memcpy(&frame[i], data, copy_len);
|
||||
i += copy_len;
|
||||
}
|
||||
|
||||
LOG_INF("onChannelDataRecv: frame_len=%d channel_idx=%d data_type=%d",
|
||||
i, channel_idx, (int)data_type);
|
||||
queueOfflineMessage(frame, i);
|
||||
sendPush(PUSH_CODE_MSG_WAITING);
|
||||
}
|
||||
|
||||
uint8_t CompanionMesh::onContactRequest(const ContactInfo &contact, uint32_t sender_timestamp,
|
||||
const uint8_t *data, uint8_t len, uint8_t *reply)
|
||||
{
|
||||
@@ -1772,7 +1811,7 @@ bool CompanionMesh::handleProtocolFrame(const uint8_t *data, size_t len)
|
||||
// If repeat requested, validate frequency against allowed bands
|
||||
if (repeat && !isValidClientRepeatFreq(freq)) {
|
||||
sendPacketError(ERR_ILLEGAL_ARG);
|
||||
} else if (freq >= 300000 && freq <= 2500000 &&
|
||||
} else if (freq >= 150000 && freq <= 2500000 &&
|
||||
bw >= 7000 && bw <= 500000 &&
|
||||
sf >= 5 && sf <= 12 &&
|
||||
cr >= 5 && cr <= 8) {
|
||||
@@ -1874,7 +1913,7 @@ bool CompanionMesh::handleProtocolFrame(const uint8_t *data, size_t len)
|
||||
#endif
|
||||
static const uint8_t fw_build[12] = FIRMWARE_BUILD_DATE;
|
||||
static const uint8_t model[40] = CONFIG_ZEPHCORE_BOARD_NAME;
|
||||
static const uint8_t version[20] = "v1.14.0-zephyr";
|
||||
static const uint8_t version[20] = "v1.14.1-zephyr";
|
||||
uint8_t rsp[82];
|
||||
rsp[0] = PACKET_DEVICE_INFO;
|
||||
rsp[1] = 10; // FIRMWARE_VER_CODE - v10 = path_hash_mode support
|
||||
@@ -2606,6 +2645,47 @@ bool CompanionMesh::handleProtocolFrame(const uint8_t *data, size_t len)
|
||||
}
|
||||
return true;
|
||||
|
||||
case CMD_SEND_CHANNEL_DATA: {
|
||||
if (len < 4) {
|
||||
sendPacketError(ERR_ILLEGAL_ARG);
|
||||
return true;
|
||||
}
|
||||
int i = 1;
|
||||
uint8_t channel_idx = data[i++];
|
||||
uint8_t path_len = data[i++];
|
||||
|
||||
if (!mesh::Packet::isValidPathLen(path_len) && path_len != OUT_PATH_UNKNOWN) {
|
||||
LOG_WRN("CMD_SEND_CHANNEL_DATA invalid path size: %d", path_len);
|
||||
sendPacketError(ERR_ILLEGAL_ARG);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t path[MAX_PATH_SIZE];
|
||||
if (path_len != OUT_PATH_UNKNOWN) {
|
||||
i += mesh::Packet::writePath(path, &data[i], path_len);
|
||||
}
|
||||
|
||||
uint16_t data_type = ((uint16_t)data[i]) | (((uint16_t)data[i + 1]) << 8);
|
||||
i += 2;
|
||||
const uint8_t *payload = &data[i];
|
||||
int payload_len = (len > (size_t)i) ? (int)(len - i) : 0;
|
||||
|
||||
ChannelDetails channel;
|
||||
if (!getChannel(channel_idx, channel)) {
|
||||
sendPacketError(ERR_NOT_FOUND);
|
||||
} else if (data_type == DATA_TYPE_RESERVED) {
|
||||
sendPacketError(ERR_ILLEGAL_ARG);
|
||||
} else if (payload_len > MAX_CHANNEL_DATA_LENGTH) {
|
||||
LOG_WRN("CMD_SEND_CHANNEL_DATA payload too long: %d > %d", payload_len, MAX_CHANNEL_DATA_LENGTH);
|
||||
sendPacketError(ERR_ILLEGAL_ARG);
|
||||
} else if (sendGroupData(channel.channel, path, path_len, data_type, payload, payload_len)) {
|
||||
sendPacketOk();
|
||||
} else {
|
||||
sendPacketError(ERR_TABLE_FULL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
case CMD_SEND_ANON_REQ:
|
||||
if (len >= 1 + PUB_KEY_SIZE + 1) {
|
||||
ContactInfo *contact = lookupContactByPubKey(&data[1], PUB_KEY_SIZE);
|
||||
|
||||
@@ -230,6 +230,8 @@ protected:
|
||||
uint32_t calcDirectTimeoutMillisFor(uint32_t pkt_airtime_millis, uint8_t path_len) const override;
|
||||
void onSendTimeout() override;
|
||||
void onChannelMessageRecv(const mesh::GroupChannel &channel, mesh::Packet *pkt, uint32_t timestamp, const char *text) override;
|
||||
void onChannelDataRecv(const mesh::GroupChannel &channel, mesh::Packet *pkt, uint16_t data_type,
|
||||
const uint8_t *data, size_t data_len) override;
|
||||
uint8_t onContactRequest(const ContactInfo &contact, uint32_t sender_timestamp, const uint8_t *data, uint8_t len, uint8_t *reply) override;
|
||||
void onContactResponse(const ContactInfo &contact, const uint8_t *data, uint8_t len) override;
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "RepeaterDataStore.h"
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "v1.14.0-zephyr"
|
||||
#define FIRMWARE_VERSION "v1.14.1-zephyr"
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
|
||||
@@ -388,12 +388,28 @@ int BaseChatMesh::searchChannelsByHash(const uint8_t *hash, mesh::GroupChannel d
|
||||
void BaseChatMesh::onGroupDataRecv(mesh::Packet *packet, uint8_t type, const mesh::GroupChannel &channel,
|
||||
uint8_t *data, size_t len)
|
||||
{
|
||||
uint8_t txt_type = data[4];
|
||||
if (type == PAYLOAD_TYPE_GRP_TXT && len > 5 && (txt_type >> 2) == 0) {
|
||||
uint32_t timestamp;
|
||||
memcpy(×tamp, data, 4);
|
||||
data[len] = 0;
|
||||
onChannelMessageRecv(channel, packet, timestamp, (const char *)&data[5]);
|
||||
if (type == PAYLOAD_TYPE_GRP_TXT) {
|
||||
uint8_t txt_type = data[4];
|
||||
if (len > 5 && (txt_type >> 2) == 0) {
|
||||
uint32_t timestamp;
|
||||
memcpy(×tamp, data, 4);
|
||||
data[len] = 0;
|
||||
onChannelMessageRecv(channel, packet, timestamp, (const char *)&data[5]);
|
||||
}
|
||||
} else if (type == PAYLOAD_TYPE_GRP_DATA) {
|
||||
if (len < 3) {
|
||||
LOG_DBG("onGroupDataRecv: dropping short group data payload len=%d", (int)len);
|
||||
return;
|
||||
}
|
||||
uint16_t data_type = ((uint16_t)data[0]) | (((uint16_t)data[1]) << 8);
|
||||
uint8_t data_len = data[2];
|
||||
size_t available_len = len - 3;
|
||||
if (data_len > available_len) {
|
||||
LOG_DBG("onGroupDataRecv: dropping malformed group data type=%d len=%d available=%d",
|
||||
(int)data_type, (int)data_len, (int)available_len);
|
||||
return;
|
||||
}
|
||||
onChannelDataRecv(channel, packet, data_type, &data[3], data_len);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -505,6 +521,38 @@ bool BaseChatMesh::sendGroupMessage(uint32_t timestamp, mesh::GroupChannel &chan
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BaseChatMesh::sendGroupData(mesh::GroupChannel &channel, uint8_t *path, uint8_t path_len,
|
||||
uint16_t data_type, const uint8_t *data, int data_len)
|
||||
{
|
||||
if (data_len < 0) {
|
||||
LOG_DBG("sendGroupData: invalid negative data_len=%d", data_len);
|
||||
return false;
|
||||
}
|
||||
if (data_len > MAX_GROUP_DATA_LENGTH) {
|
||||
LOG_DBG("sendGroupData: data_len=%d exceeds max=%d", data_len, MAX_GROUP_DATA_LENGTH);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t temp[3 + MAX_GROUP_DATA_LENGTH];
|
||||
temp[0] = (uint8_t)(data_type & 0xFF);
|
||||
temp[1] = (uint8_t)(data_type >> 8);
|
||||
temp[2] = (uint8_t)data_len;
|
||||
if (data_len > 0) memcpy(&temp[3], data, data_len);
|
||||
|
||||
mesh::Packet *pkt = createGroupDatagram(PAYLOAD_TYPE_GRP_DATA, channel, temp, 3 + data_len);
|
||||
if (pkt == nullptr) {
|
||||
LOG_DBG("sendGroupData: unable to create group datagram, data_len=%d", data_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (path_len == OUT_PATH_UNKNOWN) {
|
||||
sendFloodScoped(channel, pkt);
|
||||
} else {
|
||||
sendDirect(pkt, path, path_len);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BaseChatMesh::shareContactZeroHop(const ContactInfo &contact)
|
||||
{
|
||||
int plen = getBlobByKey(contact.id.pub_key, PUB_KEY_SIZE, temp_buf);
|
||||
|
||||
@@ -133,6 +133,8 @@ protected:
|
||||
virtual uint32_t calcDirectTimeoutMillisFor(uint32_t pkt_airtime_millis, uint8_t path_len) const = 0;
|
||||
virtual void onSendTimeout() = 0;
|
||||
virtual void onChannelMessageRecv(const mesh::GroupChannel &channel, mesh::Packet *pkt, uint32_t timestamp, const char *text) = 0;
|
||||
virtual void onChannelDataRecv(const mesh::GroupChannel &channel, mesh::Packet *pkt, uint16_t data_type,
|
||||
const uint8_t *data, size_t data_len) {}
|
||||
virtual uint8_t onContactRequest(const ContactInfo &contact, uint32_t sender_timestamp,
|
||||
const uint8_t *data, uint8_t len, uint8_t *reply) = 0;
|
||||
virtual void onContactResponse(const ContactInfo &contact, const uint8_t *data, uint8_t len) = 0;
|
||||
@@ -168,6 +170,8 @@ public:
|
||||
uint32_t &est_timeout);
|
||||
bool sendGroupMessage(uint32_t timestamp, mesh::GroupChannel &channel, const char *sender_name,
|
||||
const char *text, int text_len);
|
||||
bool sendGroupData(mesh::GroupChannel &channel, uint8_t *path, uint8_t path_len,
|
||||
uint16_t data_type, const uint8_t *data, int data_len);
|
||||
int sendLogin(const ContactInfo &recipient, const char *password, uint32_t &est_timeout);
|
||||
int sendAnonReq(const ContactInfo &recipient, const uint8_t *data, uint8_t len, uint32_t &tag, uint32_t &est_timeout);
|
||||
int sendRequest(const ContactInfo &recipient, uint8_t req_type, uint32_t &tag, uint32_t &est_timeout);
|
||||
|
||||
@@ -137,7 +137,7 @@ void CommonCLI::loadPrefs(const char* path) {
|
||||
_prefs->airtime_factor *= 10.0f;
|
||||
}
|
||||
_prefs->airtime_factor = constrain(_prefs->airtime_factor, 0.0f, 99.0f);
|
||||
_prefs->freq = constrain(_prefs->freq, 400.0f, 2500.0f);
|
||||
_prefs->freq = constrain(_prefs->freq, 150.0f, 2500.0f);
|
||||
_prefs->bw = constrain(_prefs->bw, 7.8f, 500.0f);
|
||||
_prefs->sf = constrain(_prefs->sf, (uint8_t)5, (uint8_t)12);
|
||||
_prefs->cr = constrain(_prefs->cr, (uint8_t)5, (uint8_t)8);
|
||||
@@ -377,12 +377,12 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
uint8_t sf = num > 2 ? atoi(parts[2]) : 0;
|
||||
uint8_t cr = num > 3 ? atoi(parts[3]) : 0;
|
||||
int temp_timeout_mins = num > 4 ? atoi(parts[4]) : 0;
|
||||
if (freq >= 300.0f && freq <= 2500.0f && sf >= 5 && sf <= 12 &&
|
||||
if (freq >= 150.0f && freq <= 2500.0f && sf >= 5 && sf <= 12 &&
|
||||
cr >= 5 && cr <= 8 && bw >= 7.0f && bw <= 500.0f && temp_timeout_mins > 0) {
|
||||
_callbacks->applyTempRadioParams(freq, bw, sf, cr, temp_timeout_mins);
|
||||
snprintf(reply, CLI_REPLY_SIZE, "OK - temp params for %d mins", temp_timeout_mins);
|
||||
} else {
|
||||
strcpy(reply, "Error: freq 300-2500, bw 7-500, sf 5-12, cr 5-8, timeout>0");
|
||||
strcpy(reply, "Error: freq 150-2500, bw 7-500, sf 5-12, cr 5-8, timeout>0");
|
||||
}
|
||||
} else if (memcmp(command, "password ", 9) == 0) {
|
||||
StrHelper::strncpy(_prefs->password, &command[9], sizeof(_prefs->password));
|
||||
@@ -499,7 +499,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
} else {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %.3f", (double)adc_mult);
|
||||
}
|
||||
} else if (memcmp(config, "rxboost", 7) == 0) {
|
||||
} else if (memcmp(config, "radio.rxgain", 12) == 0) {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %d", (int)_prefs->rx_boost);
|
||||
} else if (memcmp(config, "rxduty", 6) == 0) {
|
||||
snprintf(reply, CLI_REPLY_SIZE, "> %d", (int)_prefs->rx_duty_cycle);
|
||||
@@ -617,7 +617,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
float bw = num > 1 ? strtof(parts[1], nullptr) : 0.0f;
|
||||
uint8_t sf = num > 2 ? atoi(parts[2]) : 0;
|
||||
uint8_t cr = num > 3 ? atoi(parts[3]) : 0;
|
||||
if (freq >= 300.0f && freq <= 2500.0f && sf >= 5 && sf <= 12 &&
|
||||
if (freq >= 150.0f && freq <= 2500.0f && sf >= 5 && sf <= 12 &&
|
||||
cr >= 5 && cr <= 8 && bw >= 7.0f && bw <= 500.0f) {
|
||||
_prefs->sf = sf;
|
||||
_prefs->cr = cr;
|
||||
@@ -626,7 +626,7 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
_callbacks->savePrefs();
|
||||
strcpy(reply, "OK - reboot to apply");
|
||||
} else {
|
||||
strcpy(reply, "Error: freq 300-2500, bw 7-500, sf 5-12, cr 5-8");
|
||||
strcpy(reply, "Error: freq 150-2500, bw 7-500, sf 5-12, cr 5-8");
|
||||
}
|
||||
} else if (memcmp(config, "lat ", 4) == 0) {
|
||||
_prefs->node_lat = atof(&config[4]);
|
||||
@@ -744,12 +744,12 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
}
|
||||
} else if (sender_timestamp == 0 && memcmp(config, "freq ", 5) == 0) {
|
||||
float f = atof(&config[5]);
|
||||
if (f >= 400.0f && f <= 2500.0f) {
|
||||
if (f >= 150.0f && f <= 2500.0f) {
|
||||
_prefs->freq = f;
|
||||
savePrefs();
|
||||
strcpy(reply, "OK - reboot to apply");
|
||||
} else {
|
||||
strcpy(reply, "Error: range 400-2500 MHz");
|
||||
strcpy(reply, "Error: range 150-2500 MHz");
|
||||
}
|
||||
} else if (memcmp(config, "adc.multiplier ", 15) == 0) {
|
||||
_prefs->adc_multiplier = atof(&config[15]);
|
||||
@@ -764,12 +764,12 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, const char* command, ch
|
||||
_prefs->adc_multiplier = 0.0f;
|
||||
strcpy(reply, "Error: unsupported by this board");
|
||||
}
|
||||
} else if (memcmp(config, "rxboost ", 8) == 0) {
|
||||
int val = atoi(&config[8]);
|
||||
} else if (memcmp(config, "radio.rxgain ", 13) == 0) {
|
||||
int val = atoi(&config[13]);
|
||||
if (val == 0 || val == 1) {
|
||||
_prefs->rx_boost = (uint8_t)val;
|
||||
savePrefs();
|
||||
snprintf(reply, CLI_REPLY_SIZE, "OK - rxboost=%d (reboot to apply)", _prefs->rx_boost);
|
||||
snprintf(reply, CLI_REPLY_SIZE, "OK - radio.rxgain=%d (reboot to apply)", _prefs->rx_boost);
|
||||
} else {
|
||||
strcpy(reply, "Error: must be 0 or 1");
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#define TXT_TYPE_PLAIN 0 // a plain text message
|
||||
#define TXT_TYPE_CLI_DATA 1 // a CLI command
|
||||
#define TXT_TYPE_SIGNED_PLAIN 2 // plain text, signed by sender
|
||||
#define DATA_TYPE_RESERVED 0x0000 // reserved for future use
|
||||
#define DATA_TYPE_DEV 0xFFFF // developer namespace for experimenting with group/channel datagrams
|
||||
|
||||
class StrHelper {
|
||||
public:
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define MAX_PACKET_PAYLOAD 184
|
||||
#define MAX_PATH_SIZE 64
|
||||
#define MAX_TRANS_UNIT 255
|
||||
#define MAX_GROUP_DATA_LENGTH (MAX_PACKET_PAYLOAD - CIPHER_BLOCK_SIZE - 3)
|
||||
|
||||
#define MESH_DEBUG_PRINT(...)
|
||||
#define MESH_DEBUG_PRINTLN(...)
|
||||
|
||||
Reference in new issue
Block a user