Keep GPIO command scopes and cover room text limits and existing UI dispatch

This commit is contained in:
mikecarper committed 2026-09-30 03:54:27 -07:00
1 parent 5404885495
commit c76278c1c7
8 files changed
+15 -13

No files matched your search

+4 -1
View File
@@ -75,7 +75,10 @@
for (const name of ["vibration", "sound", "led", "screen"]) if (config[name] !== "inherit") parts.push(name + "=" + config[name]);
for (const name of ["repeat", "gap"]) parts.push(name + "=" + config[name]);
const text = "!notify " + parts.join(" ");
if (text.length > 159) throw new Error("Notification text exceeds 159 characters. Shorten the patterns or melody.");
// Room forwarding reserves an author prefix and currently stores 150 text
// characters. Reject before a truncated post could lose a field's value.
const maximum = config.kind === "room" ? 150 : 159;
if (text.length > maximum) throw new Error("Notification text exceeds " + maximum + " characters for " + (config.kind === "room" ? "a room post" : "a DM") + ". Shorten the patterns or melody.");
return text;
}
function level(pattern, elapsed) {
+1 -1
View File
@@ -84,7 +84,7 @@ stop policy. USB testing uses Binary Companion mode at 115200 baud.
<pre><code data-role="dm"></code></pre>
<p>The recipient must first grant your contact or room permission. Send the string
as an ordinary DM or room post; it contains no GPIO action. Long patterns may need
shortening to fit a 159-character message.</p>
shortening to fit 159 characters for a DM, or 150 for a room post.</p>
</section>
<section class="notification-card">
<h2>Try it on your device</h2>
+1 -1
View File
@@ -2413,7 +2413,7 @@ void MyMesh::begin(bool has_display, bool radio_available) {
notification_settings = mesh::notify::Settings();
}
#endif
#endif
// load persisted prefs
const bool prefs_ready =
-1
View File
@@ -185,7 +185,6 @@ build_flags = ${arduino_base.build_flags}
; PendSV reaches this FreeRTOS function from assembly, outside the LTO graph.
-Wl,--undefined=vTaskSwitchContext
-D NRF52_PLATFORM
-D USER_GPIO_CONTROL=1
-D LFS_NO_ASSERT=1
-D EXTRAFS=1
-D MESH_NRF52_LOOP_STACK_WORDS=2048
+2 -9
View File
@@ -5,9 +5,7 @@
#include "Nrf52BootloaderVersion.h"
#include "nrf52/SoftDeviceState.h"
#include <target.h>
#ifdef USER_GPIO_CONTROL
#include "UserGpioPinPolicy.h"
#endif
#include <bluefruit.h>
#include "ble_gap.h"
@@ -52,7 +50,6 @@ static void format_ota_reply(char reply[]) {
mac_addr[2], mac_addr[1], mac_addr[0]);
}
#ifdef USER_GPIO_CONTROL
namespace {
bool isExposedNrf52UserGpio(uint8_t pin) {
@@ -86,10 +83,10 @@ bool isExposedNrf52UserGpio(uint8_t pin) {
}
} // namespace
#endif
bool NRF52Board::isUserGpioAvailable(uint8_t pin) const {
#ifdef USER_GPIO_CONTROL
// This board approval query also serves Companion alert outputs. CommonCLI's
// separate USER_GPIO_CONTROL flag still controls its GPIO command exposure.
if (pin >= PINS_COUNT || digitalPinToPinName(pin) == 0xFF) return false;
#if defined(RAK_3401) || defined(RAK_4631)
// Sensor startup can toggle these WisBlock slot pins while detecting GPS,
@@ -97,10 +94,6 @@ bool NRF52Board::isUserGpioAvailable(uint8_t pin) const {
if (pin == WB_IO2 || pin == WB_IO4 || pin == WB_IO5) return false;
#endif
return isExposedNrf52UserGpio(pin) && !UserGpioPinPolicy::isFirmwareReserved(pin);
#else
(void)pin;
return false;
#endif
}
bool NRF52Board::rebootToUf2Bootloader() {
+3
View File
@@ -143,6 +143,9 @@ struct MyMesh {
bool hasOutbound(){return false;}
void markConnectionActive(const ContactInfo&){}
void queueMessage(const ContactInfo&,int,mesh::Packet*,uint32_t,const void*,int,const char*){}
// This harness exercises radio/local identity dispatch. Notification parsing
// and permissions run against the real controller in their native suite.
bool handleNotificationCommand(const char*,char*,size_t){return false;}
};
'''
+1
View File
@@ -46,6 +46,7 @@ struct StrHelper {
};
struct ChannelDetails { char name[32]; };
struct Mesh {
bool notificationButton() { return false; }
bool dual_radio_active=false;
bool isDualRadioActive() const { return dual_radio_active; }
bool getChannel(int channel,ChannelDetails& details) const {
+3
View File
@@ -22,6 +22,9 @@ const vip = {...builder.EXAMPLES.vip, id: "01".repeat(32), remote: "on"};
assert.ok(builder.commands(vip).includes("set notify.remote contact:" + vip.id + " on"));
const room = {...vip, kind: "room"};
assert.ok(builder.commands(room).includes("set notify.remote room:" + room.id + " on"));
const longPost = {...vip, led: Array(9).fill("60000").join(","), repeat: "65535"};
assert.equal(builder.notificationText(longPost).length, 151);
assert.throws(() => builder.notificationText({...longPost, kind: "room"}), /150 characters for a room post/);
assert.throws(() => builder.commands({...builder.EXAMPLES.food, remote: "on"}));
assert.throws(() => builder.commands({...vip, id: "1234"}));
const encoded = builder.encodeCommand("notify.stop", "A7");