mirror of
https://github.com/pelgraine/Meck.git
synced 2026-05-07 22:04:49 +02:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e40d9ced4a | |||
| b8de2d0d16 | |||
| 9fbc3202f6 | |||
| 9d91f48797 | |||
| 21eb385763 | |||
| 4b81e596d2 |
@@ -541,6 +541,46 @@ void MyMesh::onChannelMessageRecv(const mesh::GroupChannel &channel, mesh::Packe
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MyMesh::queueSentChannelMessage(uint8_t channel_idx, uint32_t timestamp, const char* sender, const char* text) {
|
||||||
|
// Format message the same way as onChannelMessageRecv for BLE app sync
|
||||||
|
// This allows sent messages from device keyboard to appear in the app
|
||||||
|
int i = 0;
|
||||||
|
if (app_target_ver >= 3) {
|
||||||
|
out_frame[i++] = RESP_CODE_CHANNEL_MSG_RECV_V3;
|
||||||
|
out_frame[i++] = 0; // SNR not applicable for sent messages
|
||||||
|
out_frame[i++] = 0; // reserved1
|
||||||
|
out_frame[i++] = 0; // reserved2
|
||||||
|
} else {
|
||||||
|
out_frame[i++] = RESP_CODE_CHANNEL_MSG_RECV;
|
||||||
|
}
|
||||||
|
|
||||||
|
out_frame[i++] = channel_idx;
|
||||||
|
out_frame[i++] = 0; // path_len = 0 indicates local/sent message
|
||||||
|
|
||||||
|
out_frame[i++] = TXT_TYPE_PLAIN;
|
||||||
|
memcpy(&out_frame[i], ×tamp, 4);
|
||||||
|
i += 4;
|
||||||
|
|
||||||
|
// Format as "sender: text" like the app expects
|
||||||
|
char formatted[MAX_FRAME_SIZE];
|
||||||
|
snprintf(formatted, sizeof(formatted), "%s: %s", sender, text);
|
||||||
|
int tlen = strlen(formatted);
|
||||||
|
if (i + tlen > MAX_FRAME_SIZE) {
|
||||||
|
tlen = MAX_FRAME_SIZE - i;
|
||||||
|
}
|
||||||
|
memcpy(&out_frame[i], formatted, tlen);
|
||||||
|
i += tlen;
|
||||||
|
|
||||||
|
addToOfflineQueue(out_frame, i);
|
||||||
|
|
||||||
|
// If app is connected, send push notification
|
||||||
|
if (_serial->isConnected()) {
|
||||||
|
uint8_t frame[1];
|
||||||
|
frame[0] = PUSH_CODE_MSG_WAITING;
|
||||||
|
_serial->writeFrame(frame, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t MyMesh::onContactRequest(const ContactInfo &contact, uint32_t sender_timestamp, const uint8_t *data,
|
uint8_t MyMesh::onContactRequest(const ContactInfo &contact, uint32_t sender_timestamp, const uint8_t *data,
|
||||||
uint8_t len, uint8_t *reply) {
|
uint8_t len, uint8_t *reply) {
|
||||||
if (data[0] == REQ_TYPE_GET_TELEMETRY_DATA) {
|
if (data[0] == REQ_TYPE_GET_TELEMETRY_DATA) {
|
||||||
@@ -1979,4 +2019,4 @@ bool MyMesh::advert() {
|
|||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,11 +8,11 @@
|
|||||||
#define FIRMWARE_VER_CODE 8
|
#define FIRMWARE_VER_CODE 8
|
||||||
|
|
||||||
#ifndef FIRMWARE_BUILD_DATE
|
#ifndef FIRMWARE_BUILD_DATE
|
||||||
#define FIRMWARE_BUILD_DATE "1 Feb 2026"
|
#define FIRMWARE_BUILD_DATE "4 Feb 2026"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FIRMWARE_VERSION
|
#ifndef FIRMWARE_VERSION
|
||||||
#define FIRMWARE_VERSION "Meck v0.6"
|
#define FIRMWARE_VERSION "Meck v0.6.2"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
|
#if defined(NRF52_PLATFORM) || defined(STM32_PLATFORM)
|
||||||
@@ -101,6 +101,9 @@ public:
|
|||||||
void enterCLIRescue();
|
void enterCLIRescue();
|
||||||
|
|
||||||
int getRecentlyHeard(AdvertPath dest[], int max_num);
|
int getRecentlyHeard(AdvertPath dest[], int max_num);
|
||||||
|
|
||||||
|
// Queue a sent channel message for BLE app sync
|
||||||
|
void queueSentChannelMessage(uint8_t channel_idx, uint32_t timestamp, const char* sender, const char* text);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float getAirtimeBudgetFactor() const override;
|
float getAirtimeBudgetFactor() const override;
|
||||||
@@ -230,4 +233,4 @@ private:
|
|||||||
AdvertPath advert_paths[ADVERT_PATH_TABLE_SIZE]; // circular table
|
AdvertPath advert_paths[ADVERT_PATH_TABLE_SIZE]; // circular table
|
||||||
};
|
};
|
||||||
|
|
||||||
extern MyMesh the_mesh;
|
extern MyMesh the_mesh;
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
static uint8_t composeChannelIdx = 0; // Which channel to send to
|
static uint8_t composeChannelIdx = 0; // Which channel to send to
|
||||||
static unsigned long lastComposeRefresh = 0;
|
static unsigned long lastComposeRefresh = 0;
|
||||||
static bool composeNeedsRefresh = false;
|
static bool composeNeedsRefresh = false;
|
||||||
#define COMPOSE_REFRESH_INTERVAL 250 // ms between e-ink refreshes while typing
|
#define COMPOSE_REFRESH_INTERVAL 600 // ms between e-ink refreshes while typing (refresh takes ~650ms)
|
||||||
|
|
||||||
void initKeyboard();
|
void initKeyboard();
|
||||||
void handleKeyboardInput();
|
void handleKeyboardInput();
|
||||||
@@ -646,8 +646,6 @@ void drawComposeScreen() {
|
|||||||
void sendComposedMessage() {
|
void sendComposedMessage() {
|
||||||
if (composePos == 0) return;
|
if (composePos == 0) return;
|
||||||
|
|
||||||
MESH_DEBUG_PRINTLN("Sending message to channel %d: %s", composeChannelIdx, composeBuffer);
|
|
||||||
|
|
||||||
// Get the selected channel
|
// Get the selected channel
|
||||||
ChannelDetails channel;
|
ChannelDetails channel;
|
||||||
if (the_mesh.getChannel(composeChannelIdx, channel)) {
|
if (the_mesh.getChannel(composeChannelIdx, channel)) {
|
||||||
@@ -657,20 +655,21 @@ void sendComposedMessage() {
|
|||||||
if (the_mesh.sendGroupMessage(timestamp, channel.channel,
|
if (the_mesh.sendGroupMessage(timestamp, channel.channel,
|
||||||
the_mesh.getNodePrefs()->node_name,
|
the_mesh.getNodePrefs()->node_name,
|
||||||
composeBuffer, composePos)) {
|
composeBuffer, composePos)) {
|
||||||
MESH_DEBUG_PRINTLN("Message sent to channel %s", channel.name);
|
|
||||||
|
|
||||||
// Add the sent message to local channel history so we can see what we sent
|
// Add the sent message to local channel history so we can see what we sent
|
||||||
ui_task.addSentChannelMessage(composeChannelIdx,
|
ui_task.addSentChannelMessage(composeChannelIdx,
|
||||||
the_mesh.getNodePrefs()->node_name,
|
the_mesh.getNodePrefs()->node_name,
|
||||||
composeBuffer);
|
composeBuffer);
|
||||||
|
|
||||||
|
// Queue message for BLE app sync (so sent messages appear in companion app)
|
||||||
|
the_mesh.queueSentChannelMessage(composeChannelIdx, timestamp,
|
||||||
|
the_mesh.getNodePrefs()->node_name,
|
||||||
|
composeBuffer);
|
||||||
|
|
||||||
ui_task.showAlert("Sent!", 1500);
|
ui_task.showAlert("Sent!", 1500);
|
||||||
} else {
|
} else {
|
||||||
MESH_DEBUG_PRINTLN("Failed to send message");
|
|
||||||
ui_task.showAlert("Send failed!", 1500);
|
ui_task.showAlert("Send failed!", 1500);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
MESH_DEBUG_PRINTLN("Could not get channel %d", composeChannelIdx);
|
|
||||||
ui_task.showAlert("No channel!", 1500);
|
ui_task.showAlert("No channel!", 1500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,6 +46,14 @@ void TDeckBoard::begin() {
|
|||||||
MESH_DEBUG_PRINTLN("TDeckBoard::begin() - GPS Serial2 initialized at %d baud", GPS_BAUDRATE);
|
MESH_DEBUG_PRINTLN("TDeckBoard::begin() - GPS Serial2 initialized at %d baud", GPS_BAUDRATE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Disable 4G modem power (only present on 4G version, not audio version)
|
||||||
|
// This turns off the red status LED on the modem module
|
||||||
|
#ifdef MODEM_POWER_EN
|
||||||
|
pinMode(MODEM_POWER_EN, OUTPUT);
|
||||||
|
digitalWrite(MODEM_POWER_EN, LOW); // Cut power to modem
|
||||||
|
MESH_DEBUG_PRINTLN("TDeckBoard::begin() - 4G modem power disabled");
|
||||||
|
#endif
|
||||||
|
|
||||||
// Configure user button
|
// Configure user button
|
||||||
pinMode(PIN_USER_BTN, INPUT);
|
pinMode(PIN_USER_BTN, INPUT);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user