diff --git a/examples/companion_radio/ui-new/UITask.cpp b/examples/companion_radio/ui-new/UITask.cpp index 547eb07d..1aa32e94 100644 --- a/examples/companion_radio/ui-new/UITask.cpp +++ b/examples/companion_radio/ui-new/UITask.cpp @@ -2191,6 +2191,22 @@ extern "C" EMSCRIPTEN_KEEPALIVE int sim_buzzer_freq_hz() { extern "C" EMSCRIPTEN_KEEPALIVE int sim_buzzer_get_volume() { return g_sim_ui_task_for_js ? (int)g_sim_ui_task_for_js->buzzerVolume() : 0; } + +// Write side: a host page's own mute control (a button next to the d-pad, +// say) calling this fires UITask::toggleBuzzer() -- the literal function +// the real on-device Settings > Buzzer mute toggle calls, not a +// re-implementation of it. That single call already does everything the +// real toggle does: buzzer.quiet(), writes NodePrefs.buzzer_quiet, clears +// buzzer_auto (manual mute always wins over auto-mute-on-BT-connect, +// same as pressing it on the device would), the_mesh.savePrefs(), and +// the real on-screen "Buzzer: ON/OFF" alert -- so muting from the host +// page's button is visibly the same event as muting from the keypad. +extern "C" EMSCRIPTEN_KEEPALIVE void sim_buzzer_toggle_quiet() { + if (g_sim_ui_task_for_js) g_sim_ui_task_for_js->toggleBuzzer(); +} +extern "C" EMSCRIPTEN_KEEPALIVE int sim_buzzer_get_quiet() { + return (g_sim_ui_task_for_js && g_sim_ui_task_for_js->isBuzzerQuiet()) ? 1 : 0; +} #endif #endif diff --git a/examples/simple_repeater/MyMesh.cpp b/examples/simple_repeater/MyMesh.cpp index a88de9f2..ac0965bd 100644 --- a/examples/simple_repeater/MyMesh.cpp +++ b/examples/simple_repeater/MyMesh.cpp @@ -891,7 +891,27 @@ MyMesh::MyMesh(mesh::MainBoard &board, mesh::Radio &radio, mesh::MillisecondCloc _prefs.rx_delay_base = 0.0f; // turn off by default, was 10.0; _prefs.tx_delay_factor = 0.5f; // was 0.25f _prefs.direct_tx_delay_factor = 0.3f; // was 0.2 +#if defined(SIM_PLATFORM) && defined(__EMSCRIPTEN__) + // Every visitor's own local repeater otherwise advertises the exact same + // literal ADVERT_NAME ("repeater") -- across meshcore-solo-site's + // cross-visitor relay bridge (every visitor's R shares one virtual + // channel) that means every hop in every path/relay list is an + // indistinguishable wall of "repeater"s, confirmed live. Real repeaters + // are near-universally named after the geographic feature they sit on + // (an actual, common ham-radio convention) -- a random " " + // pair both fixes the indistinguishability and reads as a plausible + // real name instead of an obviously synthetic one. + // sim_instance_entropy() (SimInstance.h) is the same real + // crypto.getRandomValues()-sourced entropy already mixed into this + // instance's RNG seed (see SimRNG.h) -- genuinely different per visitor, + // not a fixed per-tag value repeatable across boots. + static const char* RPT_ADJ[] = { "Cedar","Copper","Ember","Foggy","Granite","Iron","Misty","Rusty","Silver","Windy","Amber","Frost","Golden","Stone","Lunar","Quiet" }; + static const char* RPT_FEAT[] = { "Ridge","Summit","Hollow","Peak","Creek","Grove","Meadow","Bluff","Hilltop","Overlook","Pines","Notch","Crossing","Basin","Knoll","Ledge" }; + uint32_t rn = sim_instance_entropy(); + snprintf(_prefs.node_name, sizeof(_prefs.node_name), "%s %s", RPT_ADJ[(rn >> 4) & 15], RPT_FEAT[rn & 15]); +#else StrHelper::strncpy(_prefs.node_name, ADVERT_NAME, sizeof(_prefs.node_name)); +#endif _prefs.node_lat = ADVERT_LAT; _prefs.node_lon = ADVERT_LON; StrHelper::strncpy(_prefs.password, ADMIN_PASSWORD, sizeof(_prefs.password)); diff --git a/examples/simple_repeater/main.cpp b/examples/simple_repeater/main.cpp index b31abcc6..374e2a84 100644 --- a/examples/simple_repeater/main.cpp +++ b/examples/simple_repeater/main.cpp @@ -41,6 +41,18 @@ extern "C" EMSCRIPTEN_KEEPALIVE uint32_t sim_repeater_get_relay_count() { return the_mesh.getNumForwarded(); } +// This instance's own advertised name (NodePrefs.node_name via +// MyMesh::getNodeName()) -- randomized per-visitor at first boot (see the +// SIM_PLATFORM/__EMSCRIPTEN__ branch in MyMesh's constructor) so every +// hop in a cross-visitor path/relay list isn't just an indistinguishable +// wall of the literal "repeater". Returns a pointer straight into +// NodePrefs's own fixed buffer -- valid for the process's whole lifetime, +// same as every other read-only getter here, no ownership handoff needed +// (ccall(..., 'string', ...) on the JS side copies it out immediately). +extern "C" EMSCRIPTEN_KEEPALIVE const char* sim_repeater_get_name() { + return the_mesh.getNodeName(); +} + // Same "has setup() actually finished" readiness flag as // examples/companion_radio/main.cpp -- see that file's comment for why // this is needed instead of a fixed post-ready delay.