XEdDSA packet signing UI (BaseUI) (#10841)
* XEdDSA packet signing UI (BaseUI) * Move Pixels around for TFT
This commit is contained in:
@@ -183,6 +183,10 @@ const StoredMessage &MessageStore::addFromPacket(const meshtastic_MeshPacket &pa
|
|||||||
sm.type = isDM ? MessageType::DM_TO_US : MessageType::BROADCAST;
|
sm.type = isDM ? MessageType::DM_TO_US : MessageType::BROADCAST;
|
||||||
sm.ackStatus = (packet.from == 0) ? AckStatus::NONE : AckStatus::ACKED;
|
sm.ackStatus = (packet.from == 0) ? AckStatus::NONE : AckStatus::ACKED;
|
||||||
|
|
||||||
|
#if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN || MESHTASTIC_EXCLUDE_PKI)
|
||||||
|
sm.xeddsaSigned = packet.xeddsa_signed;
|
||||||
|
#endif
|
||||||
|
|
||||||
addLiveMessage(sm);
|
addLiveMessage(sm);
|
||||||
|
|
||||||
#if ENABLE_MESSAGE_PERSISTENCE
|
#if ENABLE_MESSAGE_PERSISTENCE
|
||||||
@@ -230,6 +234,7 @@ struct __attribute__((packed)) StoredMessageRecord {
|
|||||||
uint8_t isBootRelative;
|
uint8_t isBootRelative;
|
||||||
uint8_t ackStatus; // static_cast<uint8_t>(AckStatus)
|
uint8_t ackStatus; // static_cast<uint8_t>(AckStatus)
|
||||||
uint8_t type; // static_cast<uint8_t>(MessageType)
|
uint8_t type; // static_cast<uint8_t>(MessageType)
|
||||||
|
uint8_t xeddsaSigned; // 1 if packet carried a verified XEdDSA signature
|
||||||
uint16_t textLength; // message length
|
uint16_t textLength; // message length
|
||||||
char text[MAX_MESSAGE_SIZE]; // store actual text here
|
char text[MAX_MESSAGE_SIZE]; // store actual text here
|
||||||
};
|
};
|
||||||
@@ -245,6 +250,7 @@ static inline void writeMessageRecord(SafeFile &f, const StoredMessage &m)
|
|||||||
rec.isBootRelative = m.isBootRelative;
|
rec.isBootRelative = m.isBootRelative;
|
||||||
rec.ackStatus = static_cast<uint8_t>(m.ackStatus);
|
rec.ackStatus = static_cast<uint8_t>(m.ackStatus);
|
||||||
rec.type = static_cast<uint8_t>(m.type);
|
rec.type = static_cast<uint8_t>(m.type);
|
||||||
|
rec.xeddsaSigned = m.xeddsaSigned ? 1 : 0;
|
||||||
rec.textLength = m.textLength;
|
rec.textLength = m.textLength;
|
||||||
|
|
||||||
// Copy the actual text into the record from RAM pool
|
// Copy the actual text into the record from RAM pool
|
||||||
@@ -269,6 +275,7 @@ static inline bool readMessageRecord(File &f, StoredMessage &m)
|
|||||||
m.isBootRelative = rec.isBootRelative;
|
m.isBootRelative = rec.isBootRelative;
|
||||||
m.ackStatus = static_cast<AckStatus>(rec.ackStatus);
|
m.ackStatus = static_cast<AckStatus>(rec.ackStatus);
|
||||||
m.type = static_cast<MessageType>(rec.type);
|
m.type = static_cast<MessageType>(rec.type);
|
||||||
|
m.xeddsaSigned = rec.xeddsaSigned != 0;
|
||||||
m.textLength = rec.textLength;
|
m.textLength = rec.textLength;
|
||||||
|
|
||||||
// 💡 Re-store text into pool and update offset
|
// 💡 Re-store text into pool and update offset
|
||||||
|
|||||||
+3
-1
@@ -72,10 +72,12 @@ struct StoredMessage {
|
|||||||
uint16_t textOffset; // Offset into global text pool (valid only after loadFromFlash())
|
uint16_t textOffset; // Offset into global text pool (valid only after loadFromFlash())
|
||||||
uint16_t textLength; // Length of text in bytes
|
uint16_t textLength; // Length of text in bytes
|
||||||
|
|
||||||
|
bool xeddsaSigned; // true if packet carried a verified XEdDSA signature
|
||||||
|
|
||||||
// Default constructor initializes all fields safely
|
// Default constructor initializes all fields safely
|
||||||
StoredMessage()
|
StoredMessage()
|
||||||
: timestamp(0), sender(0), channelIndex(0), dest(0xffffffff), type(MessageType::BROADCAST), isBootRelative(false),
|
: timestamp(0), sender(0), channelIndex(0), dest(0xffffffff), type(MessageType::BROADCAST), isBootRelative(false),
|
||||||
ackStatus(AckStatus::NONE), textOffset(0), textLength(0)
|
ackStatus(AckStatus::NONE), textOffset(0), textLength(0), xeddsaSigned(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -615,12 +615,22 @@ void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
|
|
||||||
// Shrink Sender name if needed
|
// Shrink Sender name if needed
|
||||||
int availWidth = (mine ? rightTextWidth : leftTextWidth) - display->getStringWidth(timeBuf) -
|
int availWidth = (mine ? rightTextWidth : leftTextWidth) - display->getStringWidth(timeBuf) -
|
||||||
display->getStringWidth(chanType) - graphics::UIRenderer::measureStringWithEmotes(display, " @...");
|
display->getStringWidth(chanType) - graphics::UIRenderer::measureStringWithEmotes(display, " *@...");
|
||||||
if (availWidth < 0)
|
if (availWidth < 0)
|
||||||
availWidth = 0;
|
availWidth = 0;
|
||||||
char truncatedSender[64];
|
char truncatedSender[64];
|
||||||
graphics::UIRenderer::truncateStringWithEmotes(display, senderName, truncatedSender, sizeof(truncatedSender), availWidth);
|
graphics::UIRenderer::truncateStringWithEmotes(display, senderName, truncatedSender, sizeof(truncatedSender), availWidth);
|
||||||
|
|
||||||
|
// Determine signed-message prefix before building the header line, since it needs to go
|
||||||
|
// at the front of headerStr rather than appended after (strncat only appends at the end).
|
||||||
|
const char *signPrefix = "";
|
||||||
|
#if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN || MESHTASTIC_EXCLUDE_PKI)
|
||||||
|
bool is_xeddsa_signed = m.xeddsaSigned;
|
||||||
|
if (is_xeddsa_signed) {
|
||||||
|
signPrefix = "*";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Final header line
|
// Final header line
|
||||||
char headerStr[128];
|
char headerStr[128];
|
||||||
if (mine) {
|
if (mine) {
|
||||||
@@ -634,7 +644,8 @@ void drawTextMessageFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
|||||||
snprintf(headerStr, sizeof(headerStr), "%s", timeBuf);
|
snprintf(headerStr, sizeof(headerStr), "%s", timeBuf);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
snprintf(headerStr, sizeof(headerStr), chanType[0] ? "%s @%s %s" : "%s @%s", timeBuf, truncatedSender, chanType);
|
snprintf(headerStr, sizeof(headerStr), chanType[0] ? "%s %s@%s %s" : "%s %s@%s", timeBuf, signPrefix, truncatedSender,
|
||||||
|
chanType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push header line
|
// Push header line
|
||||||
|
|||||||
@@ -788,12 +788,34 @@ void UIRenderer::drawFavoriteNode(OLEDDisplay *display, OLEDDisplayUiState *stat
|
|||||||
|
|
||||||
// Print node's long name (e.g. "Backpack Node")
|
// Print node's long name (e.g. "Backpack Node")
|
||||||
if (username) {
|
if (username) {
|
||||||
|
int username_buffer = 0;
|
||||||
|
#if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN || MESHTASTIC_EXCLUDE_PKI)
|
||||||
|
if (nodeInfoLiteHasXeddsaSigned(node)) {
|
||||||
|
if (currentResolution == ScreenResolution::High) {
|
||||||
|
graphics::NodeListRenderer::drawScaledXBitmap16x16(x + 2, getTextPositions(display)[line] + 1,
|
||||||
|
xeddsa_shield_width, xeddsa_shield_height, xeddsa_shield,
|
||||||
|
display);
|
||||||
|
username_buffer = (xeddsa_shield_width * 2) + 4;
|
||||||
|
} else {
|
||||||
|
display->drawXbm(x, getTextPositions(display)[line] + 3, xeddsa_shield_width, xeddsa_shield_height,
|
||||||
|
xeddsa_shield);
|
||||||
|
username_buffer = xeddsa_shield_width + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#if GRAPHICS_TFT_COLORING_ENABLED
|
#if GRAPHICS_TFT_COLORING_ENABLED
|
||||||
const int usernameWidth = UIRenderer::measureStringWithEmotes(display, username);
|
const int usernameWidth = UIRenderer::measureStringWithEmotes(display, username);
|
||||||
|
#if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN || MESHTASTIC_EXCLUDE_PKI)
|
||||||
|
if (nodeInfoLiteHasXeddsaSigned(node)) {
|
||||||
|
setAndRegisterTFTColorRole(TFTColorRole::FavoriteNodeBGHighlight, TFTPalette::Yellow, TFTPalette::Black,
|
||||||
|
x + usernameWidth, getTextPositions(display)[line], username_buffer, FONT_HEIGHT_SMALL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
setAndRegisterTFTColorRole(TFTColorRole::FavoriteNodeBGHighlight, TFTPalette::Yellow, TFTPalette::Black, x,
|
setAndRegisterTFTColorRole(TFTColorRole::FavoriteNodeBGHighlight, TFTPalette::Yellow, TFTPalette::Black, x,
|
||||||
getTextPositions(display)[line], usernameWidth, FONT_HEIGHT_SMALL);
|
getTextPositions(display)[line], usernameWidth, FONT_HEIGHT_SMALL);
|
||||||
#endif
|
#endif
|
||||||
UIRenderer::drawStringWithEmotes(display, x, getTextPositions(display)[line++], username, FONT_HEIGHT_SMALL, 1, false);
|
UIRenderer::drawStringWithEmotes(display, x + username_buffer, getTextPositions(display)[line++], username,
|
||||||
|
FONT_HEIGHT_SMALL, 1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !MESHTASTIC_EXCLUDE_STATUS && !MESHTASTIC_EXCLUDE_STATUSDB
|
#if !MESHTASTIC_EXCLUDE_STATUS && !MESHTASTIC_EXCLUDE_STATUSDB
|
||||||
|
|||||||
@@ -291,6 +291,10 @@ const uint8_t digital_icon_clock[] PROGMEM = {0b00111100, 0b01000010, 0b10000101
|
|||||||
const uint8_t analog_icon_clock[] PROGMEM = {0b11111111, 0b01000010, 0b00100100, 0b00011000,
|
const uint8_t analog_icon_clock[] PROGMEM = {0b11111111, 0b01000010, 0b00100100, 0b00011000,
|
||||||
0b00100100, 0b01000010, 0b01000010, 0b11111111};
|
0b00100100, 0b01000010, 0b01000010, 0b11111111};
|
||||||
|
|
||||||
|
#define xeddsa_shield_width 8
|
||||||
|
#define xeddsa_shield_height 8
|
||||||
|
const uint8_t xeddsa_shield[] PROGMEM = {0x7E, 0x8F, 0x8F, 0x8F, 0xF1, 0xF1, 0x72, 0x3C};
|
||||||
|
|
||||||
#define chirpy_width 38
|
#define chirpy_width 38
|
||||||
#define chirpy_height 50
|
#define chirpy_height 50
|
||||||
const uint8_t chirpy[] = {
|
const uint8_t chirpy[] = {
|
||||||
|
|||||||
Reference in New Issue
Block a user