mirror of
https://github.com/meshcore-dev/MeshCore.git
synced 2026-04-20 22:13:47 +00:00
Merge 'dev' into 'feature/rp2040_picow_dev'.
This commit is contained in:
commit
b1c8963e1e
47 changed files with 1635 additions and 77 deletions
|
|
@ -43,6 +43,10 @@ void UITask::begin(DisplayDriver* display, const char* node_name, const char* bu
|
|||
*dash = 0;
|
||||
}
|
||||
|
||||
#ifdef PIN_USER_BTN
|
||||
pinMode(PIN_USER_BTN, INPUT);
|
||||
#endif
|
||||
|
||||
// v1.2.3 (1 Jan 2025)
|
||||
sprintf(_version_info, "%s (%s)", version, build_date);
|
||||
}
|
||||
|
|
@ -57,6 +61,7 @@ void UITask::msgRead(int msgcount) {
|
|||
void UITask::clearMsgPreview() {
|
||||
_origin[0] = 0;
|
||||
_msg[0] = 0;
|
||||
_need_refresh = true;
|
||||
}
|
||||
|
||||
void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, int msgcount) {
|
||||
|
|
@ -72,6 +77,7 @@ void UITask::newMsg(uint8_t path_len, const char* from_name, const char* text, i
|
|||
if (_display != NULL) {
|
||||
if (!_display->isOn()) _display->turnOn();
|
||||
_auto_off = millis() + AUTO_OFF_MILLIS; // extend the auto-off timer
|
||||
_need_refresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -83,22 +89,29 @@ void UITask::renderCurrScreen() {
|
|||
// render message preview
|
||||
_display->setCursor(0, 0);
|
||||
_display->setTextSize(1);
|
||||
_display->setColor(DisplayDriver::GREEN);
|
||||
_display->print(_node_name);
|
||||
|
||||
_display->setCursor(0, 12);
|
||||
_display->setColor(DisplayDriver::YELLOW);
|
||||
_display->print(_origin);
|
||||
_display->setCursor(0, 24);
|
||||
_display->setColor(DisplayDriver::LIGHT);
|
||||
_display->print(_msg);
|
||||
|
||||
_display->setCursor(100, 9);
|
||||
_display->setCursor(_display->width() - 28, 9);
|
||||
_display->setTextSize(2);
|
||||
_display->setColor(DisplayDriver::ORANGE);
|
||||
sprintf(tmp, "%d", _msgcount);
|
||||
_display->print(tmp);
|
||||
} else {
|
||||
// render 'home' screen
|
||||
_display->setColor(DisplayDriver::BLUE);
|
||||
_display->drawXbm(0, 0, meshcore_logo, 128, 13);
|
||||
_display->setCursor(0, 20);
|
||||
_display->setTextSize(1);
|
||||
|
||||
_display->setColor(DisplayDriver::LIGHT);
|
||||
_display->print(_node_name);
|
||||
|
||||
_display->setCursor(0, 32);
|
||||
|
|
@ -108,12 +121,14 @@ void UITask::renderCurrScreen() {
|
|||
//_display->printf("freq : %03.2f sf %d\n", _prefs.freq, _prefs.sf);
|
||||
//_display->printf("bw : %03.2f cr %d\n", _prefs.bw, _prefs.cr);
|
||||
} else if (_pin_code != 0) {
|
||||
_display->setColor(DisplayDriver::RED);
|
||||
_display->setTextSize(2);
|
||||
_display->setCursor(0, 43);
|
||||
sprintf(tmp, "Pin:%d", _pin_code);
|
||||
_display->print(tmp);
|
||||
}
|
||||
}
|
||||
_need_refresh = false;
|
||||
}
|
||||
|
||||
void UITask::userLedHandler() {
|
||||
|
|
@ -157,6 +172,7 @@ void UITask::buttonHandler() {
|
|||
clearMsgPreview();
|
||||
} else {
|
||||
_display->turnOn();
|
||||
_need_refresh = true;
|
||||
}
|
||||
_auto_off = cur_time + AUTO_OFF_MILLIS; // extend auto-off timer
|
||||
}
|
||||
|
|
@ -182,7 +198,7 @@ void UITask::loop() {
|
|||
userLedHandler();
|
||||
|
||||
if (_display != NULL && _display->isOn()) {
|
||||
if (millis() >= _next_refresh) {
|
||||
if (millis() >= _next_refresh && _need_refresh) {
|
||||
_display->startFrame();
|
||||
renderCurrScreen();
|
||||
_display->endFrame();
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ class UITask {
|
|||
char _origin[62];
|
||||
char _msg[80];
|
||||
int _msgcount;
|
||||
bool _need_refresh = true;
|
||||
|
||||
void renderCurrScreen();
|
||||
void buttonHandler();
|
||||
|
|
|
|||
|
|
@ -61,9 +61,14 @@
|
|||
|
||||
#ifdef DISPLAY_CLASS
|
||||
#include "UITask.h"
|
||||
#include <helpers/ui/SSD1306Display.h>
|
||||
|
||||
static DISPLAY_CLASS display;
|
||||
#ifdef ST7789
|
||||
#include <helpers/ui/ST7789Display.h>
|
||||
#elif defined(HAS_GxEPD)
|
||||
#include <helpers/ui/GxEPDDisplay.h>
|
||||
#else
|
||||
#include <helpers/ui/SSD1306Display.h>
|
||||
#endif
|
||||
static DISPLAY_CLASS display;
|
||||
#define HAS_UI
|
||||
#endif
|
||||
|
||||
|
|
@ -85,14 +90,14 @@ static uint32_t _atoi(const char* sp) {
|
|||
|
||||
/*------------ Frame Protocol --------------*/
|
||||
|
||||
#define FIRMWARE_VER_CODE 3
|
||||
#define FIRMWARE_VER_CODE 4
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
#define FIRMWARE_BUILD_DATE "7 Apr 2025"
|
||||
#define FIRMWARE_BUILD_DATE "21 Apr 2025"
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "v1.4.3"
|
||||
#define FIRMWARE_VERSION "v1.5.1"
|
||||
#endif
|
||||
|
||||
#define CMD_APP_START 1
|
||||
|
|
@ -132,6 +137,7 @@ static uint32_t _atoi(const char* sp) {
|
|||
#define CMD_SIGN_FINISH 35
|
||||
#define CMD_SEND_TRACE_PATH 36
|
||||
#define CMD_SET_DEVICE_PIN 37
|
||||
#define CMD_SET_OTHER_PARAMS 38
|
||||
|
||||
#define RESP_CODE_OK 0
|
||||
#define RESP_CODE_ERR 1
|
||||
|
|
@ -166,6 +172,7 @@ static uint32_t _atoi(const char* sp) {
|
|||
#define PUSH_CODE_STATUS_RESPONSE 0x87
|
||||
#define PUSH_CODE_LOG_RX_DATA 0x88
|
||||
#define PUSH_CODE_TRACE_DATA 0x89
|
||||
#define PUSH_CODE_NEW_ADVERT 0x8A
|
||||
|
||||
#define ERR_CODE_UNSUPPORTED_CMD 1
|
||||
#define ERR_CODE_NOT_FOUND 2
|
||||
|
|
@ -186,7 +193,7 @@ struct NodePrefs { // persisted to file
|
|||
uint8_t sf;
|
||||
uint8_t cr;
|
||||
uint8_t reserved1;
|
||||
uint8_t reserved2;
|
||||
uint8_t manual_add_contacts;
|
||||
float bw;
|
||||
uint8_t tx_power_dbm;
|
||||
uint8_t unused[3];
|
||||
|
|
@ -519,11 +526,19 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
bool isAutoAddEnabled() const override {
|
||||
return (_prefs.manual_add_contacts & 1) == 0;
|
||||
}
|
||||
|
||||
void onDiscoveredContact(ContactInfo& contact, bool is_new) override {
|
||||
if (_serial->isConnected()) {
|
||||
out_frame[0] = PUSH_CODE_ADVERT;
|
||||
memcpy(&out_frame[1], contact.id.pub_key, PUB_KEY_SIZE);
|
||||
_serial->writeFrame(out_frame, 1 + PUB_KEY_SIZE);
|
||||
if (!isAutoAddEnabled() && is_new) {
|
||||
writeContactRespFrame(PUSH_CODE_NEW_ADVERT, contact);
|
||||
} else {
|
||||
out_frame[0] = PUSH_CODE_ADVERT;
|
||||
memcpy(&out_frame[1], contact.id.pub_key, PUB_KEY_SIZE);
|
||||
_serial->writeFrame(out_frame, 1 + PUB_KEY_SIZE);
|
||||
}
|
||||
} else {
|
||||
soundBuzzer();
|
||||
}
|
||||
|
|
@ -683,6 +698,10 @@ protected:
|
|||
}
|
||||
|
||||
void onRawDataRecv(mesh::Packet* packet) override {
|
||||
if (packet->payload_len + 4 > sizeof(out_frame)) {
|
||||
MESH_DEBUG_PRINTLN("onRawDataRecv(), payload_len too long: %d", packet->payload_len);
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
out_frame[i++] = PUSH_CODE_RAW_DATA;
|
||||
out_frame[i++] = (int8_t)(_radio->getLastSNR() * 4);
|
||||
|
|
@ -770,7 +789,7 @@ public:
|
|||
file.read((uint8_t *) &_prefs.sf, sizeof(_prefs.sf)); // 60
|
||||
file.read((uint8_t *) &_prefs.cr, sizeof(_prefs.cr)); // 61
|
||||
file.read((uint8_t *) &_prefs.reserved1, sizeof(_prefs.reserved1)); // 62
|
||||
file.read((uint8_t *) &_prefs.reserved2, sizeof(_prefs.reserved2)); // 63
|
||||
file.read((uint8_t *) &_prefs.manual_add_contacts, sizeof(_prefs.manual_add_contacts)); // 63
|
||||
file.read((uint8_t *) &_prefs.bw, sizeof(_prefs.bw)); // 64
|
||||
file.read((uint8_t *) &_prefs.tx_power_dbm, sizeof(_prefs.tx_power_dbm)); // 68
|
||||
file.read((uint8_t *) _prefs.unused, sizeof(_prefs.unused)); // 69
|
||||
|
|
@ -873,7 +892,7 @@ public:
|
|||
file.write((uint8_t *) &_prefs.sf, sizeof(_prefs.sf)); // 60
|
||||
file.write((uint8_t *) &_prefs.cr, sizeof(_prefs.cr)); // 61
|
||||
file.write((uint8_t *) &_prefs.reserved1, sizeof(_prefs.reserved1)); // 62
|
||||
file.write((uint8_t *) &_prefs.reserved2, sizeof(_prefs.reserved2)); // 63
|
||||
file.write((uint8_t *) &_prefs.manual_add_contacts, sizeof(_prefs.manual_add_contacts)); // 63
|
||||
file.write((uint8_t *) &_prefs.bw, sizeof(_prefs.bw)); // 64
|
||||
file.write((uint8_t *) &_prefs.tx_power_dbm, sizeof(_prefs.tx_power_dbm)); // 68
|
||||
file.write((uint8_t *) _prefs.unused, sizeof(_prefs.unused)); // 69
|
||||
|
|
@ -914,12 +933,15 @@ public:
|
|||
out_frame[i++] = MAX_LORA_TX_POWER;
|
||||
memcpy(&out_frame[i], self_id.pub_key, PUB_KEY_SIZE); i += PUB_KEY_SIZE;
|
||||
|
||||
int32_t lat, lon, alt = 0;
|
||||
int32_t lat, lon;
|
||||
lat = (_prefs.node_lat * 1000000.0);
|
||||
lon = (_prefs.node_lon * 1000000.0);
|
||||
memcpy(&out_frame[i], &lat, 4); i += 4;
|
||||
memcpy(&out_frame[i], &lon, 4); i += 4;
|
||||
memcpy(&out_frame[i], &alt, 4); i += 4;
|
||||
out_frame[i++] = 0; // reserved
|
||||
out_frame[i++] = 0; // reserved
|
||||
out_frame[i++] = 0; // reserved
|
||||
out_frame[i++] = _prefs.manual_add_contacts;
|
||||
|
||||
uint32_t freq = _prefs.freq * 1000;
|
||||
memcpy(&out_frame[i], &freq, 4); i += 4;
|
||||
|
|
@ -1126,6 +1148,8 @@ public:
|
|||
// export SELF
|
||||
auto pkt = createSelfAdvert(_prefs.node_name, _prefs.node_lat, _prefs.node_lon);
|
||||
if (pkt) {
|
||||
pkt->header |= ROUTE_TYPE_FLOOD; // would normally be sent in this mode
|
||||
|
||||
out_frame[0] = RESP_CODE_EXPORT_CONTACT;
|
||||
uint8_t out_len = pkt->writeTo(&out_frame[1]);
|
||||
releasePacket(pkt); // undo the obtainNewPacket()
|
||||
|
|
@ -1203,6 +1227,10 @@ public:
|
|||
_prefs.airtime_factor = ((float)af) / 1000.0f;
|
||||
savePrefs();
|
||||
writeOKFrame();
|
||||
} else if (cmd_frame[0] == CMD_SET_OTHER_PARAMS) {
|
||||
_prefs.manual_add_contacts = cmd_frame[1];
|
||||
savePrefs();
|
||||
writeOKFrame();
|
||||
} else if (cmd_frame[0] == CMD_REBOOT && memcmp(&cmd_frame[1], "reboot", 6) == 0) {
|
||||
board.reboot();
|
||||
} else if (cmd_frame[0] == CMD_GET_BATTERY_VOLTAGE) {
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@
|
|||
/* ------------------------------ Config -------------------------------- */
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
#define FIRMWARE_BUILD_DATE "7 Apr 2025"
|
||||
#define FIRMWARE_BUILD_DATE "21 Apr 2025"
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "v1.4.3"
|
||||
#define FIRMWARE_VERSION "v1.5.1"
|
||||
#endif
|
||||
|
||||
#ifndef LORA_FREQ
|
||||
|
|
|
|||
|
|
@ -22,11 +22,11 @@
|
|||
/* ------------------------------ Config -------------------------------- */
|
||||
|
||||
#ifndef FIRMWARE_BUILD_DATE
|
||||
#define FIRMWARE_BUILD_DATE "7 Apr 2025"
|
||||
#define FIRMWARE_BUILD_DATE "21 Apr 2025"
|
||||
#endif
|
||||
|
||||
#ifndef FIRMWARE_VERSION
|
||||
#define FIRMWARE_VERSION "v1.4.3"
|
||||
#define FIRMWARE_VERSION "v1.5.1"
|
||||
#endif
|
||||
|
||||
#ifndef LORA_FREQ
|
||||
|
|
@ -234,6 +234,17 @@ class MyMesh : public mesh::Mesh, public CommonCLICallbacks {
|
|||
}
|
||||
}
|
||||
|
||||
uint8_t getUnsyncedCount(ClientInfo* client) {
|
||||
uint8_t count = 0;
|
||||
for (int k = 0; k < MAX_UNSYNCED_POSTS; k++) {
|
||||
if (posts[k].post_timestamp > client->sync_since // is new post for this Client?
|
||||
&& !posts[k].author.matches(client->id)) { // don't push posts to the author
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bool processAck(const uint8_t *data) {
|
||||
for (int i = 0; i < num_clients; i++) {
|
||||
auto client = &known_clients[i];
|
||||
|
|
@ -402,7 +413,7 @@ protected:
|
|||
reply_data[4] = RESP_SERVER_LOGIN_OK;
|
||||
reply_data[5] = (CLIENT_KEEP_ALIVE_SECS >> 4); // NEW: recommended keep-alive interval (secs / 16)
|
||||
reply_data[6] = (perm == RoomPermission::ADMIN ? 1 : (perm == RoomPermission::GUEST ? 0 : 2));
|
||||
reply_data[7] = 0; // FUTURE: reserved
|
||||
reply_data[7] = getUnsyncedCount(client); // NEW
|
||||
memcpy(&reply_data[8], "OK", 2); // REVISIT: not really needed
|
||||
|
||||
next_push = futureMillis(PUSH_NOTIFY_DELAY_MILLIS); // delay next push, give RESPONSE packet time to arrive first
|
||||
|
|
@ -576,6 +587,7 @@ protected:
|
|||
|
||||
auto reply = createAck(ack_hash);
|
||||
if (reply) {
|
||||
reply->payload[reply->payload_len++] = getUnsyncedCount(client); // NEW: add unsynced counter to end of ACK packet
|
||||
sendDirect(reply, client->out_path, client->out_path_len);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue