8 Commits

Author SHA1 Message Date
pe1hvh da3a868ec6 fix(bot): per-sender cooldown + empty-channel fallback (v1.20.1)
- Replace global _last_reply float with _last_reply_per_sender dict.
  A reply to one node no longer blocks all other senders for 5 s.
  LRU eviction keeps the dict bounded at 200 entries.

- _get_active_channels() now falls back to BotConfig defaults when
  the stored channel set is empty (user never saved a selection).
  Bot was silently deaf on first run despite the panel showing all
  channels pre-checked.

Closes: bot only replies to first sender in multi-node #test session.
2026-04-16 07:07:50 +02:00
pe1hvh 4a58a95cf0 fix: channel attribution, dedup, cache bugs + channel edit/move (v1.19.0)
fix(packet_decoder): brute-force channel resolution when hash lookup fails

ChannelCrypto.calculate_channel_hash() and the MeshCore firmware compute
different channel identifiers for the same secret, causing _hash_to_idx to
return None for all hashtag-channel messages. Fallback: try each registered
key individually via a single-key keystore. First valid decryption wins.
Result cached in _hash_to_idx for O(1) resolution on subsequent packets.

fix(events): channel-agnostic sentinel prevents cross-channel duplicates

on_rx_log now marks '*' in DualDeduplicator after storing a message.
on_channel_msg checks this sentinel and suppresses storage regardless of
channel_idx or message_hash differences between the two library systems.
Fixes #mc-radar messages appearing in #weather and vice versa.

fix(events): secondary path-cache keyed by content for hash-mismatch

_path_cache keyed by meshcoredecoder hash; CHANNEL_MSG_RECV carries meshcore
hash (different value). Added _path_cache_by_content ("sender:text[:100]")
as fallback so path_hashes are recovered when the two hashes disagree.

fix(commands,cache): remove stale channel key after del_channel reindex

Cache entry for old_idx not removed after slot move, causing same channel
to appear twice. New DeviceCache.remove_channel_key(idx) called after each
move. asyncio.sleep(0.5) added before re-discovery to let device settle.

feat(channel_panel,commands,dashboard): channel edit — move/reindex support

First channel-edit capability in the GUI. New '↕️ Move / Reindex' mode in
Channel Manager dialog. Source channel selected from dropdown, target index
in number field. ↕ button inline with 🗑 in Messages and Archive submenus.
_cmd_move_channel reads secret from cache or device, writes new slot, clears
old slot, updates cache atomically, triggers re-discovery with settle delay.
2026-04-06 10:23:24 +02:00
pe1hvh 8080bcc203 fix: Multibyte path hash support
### FIXED
- **Multibyte path hash support** (`ble/events.py`, `core/shared_data.py`):
  corrected docstrings in both `_resolve_path_names` methods that incorrectly
  described path hashes as "2-char hex strings". The actual contact lookup
  uses `startswith` matching, which is hash-size agnostic and correctly
  handles 1-byte (2 hex chars), 2-byte (4 hex chars) and 3-byte (6 hex chars)
  path hashes as introduced in MeshCore firmware v1.14.0. No functional code
  was changed — only the documentation was incorrect.
- **MariaDB schema** (`meshcore_schema.sql`): `meshcore_messages.path_hashes`
  column widened from `VARCHAR(128)` to `VARCHAR(255)`. The old limit caused
  silent truncation for paths longer than ~40 hops in 1-byte mode or ~25 hops
  in 2-byte mode. Migration is backward-compatible; existing data is unchanged.

### CHANGED
- `config.py`: version bump `1.17.0 → 1.17.1`.

### RATIONALE
- MeshCore firmware v1.14.0 (2026-03-06) introduced configurable path hash
  sizes (1-, 2- or 3-byte per repeater). Verification confirmed that
  `meshcoredecoder 0.3.2` already returns correctly sized hex strings via
  `_decode_path_len_byte`. The GUI path-resolution logic was already
  forward-compatible; only the docstrings and the MariaDB column width required
  correction.

### IMPACT
- No BLE handler, GUI panel, service or API endpoint modified.
- `meshcoredecoder` library unchanged; no pip update required.
- MariaDB migration: single `ALTER TABLE` statement, no downtime, no data loss.
2026-04-04 22:59:44 +02:00
pe1hvh a62b8d1733 feat(channels): add hashtag and private channel management dialog
WHAT: New + Add Channel button in the Messages submenu opens a dialog
supporting three modes — Hashtag (key derived from name), Private New
(random key + QR export), Private Existing (paste hex key).

WHY: Channels could only be added via firmware/external tools. The new
dialog covers all user scenarios without changing the BLE worker or
existing panels.

NOTES: Requires `qrcode[pil]` for QR rendering (graceful degradation if
absent). Channel re-discovery is triggered automatically on success.
2026-04-04 11:40:14 +02:00
pe1hvh 00d1739378 feat(bot): extract bot to dedicated panel with channel assignment and private mode(#v1.15.0)
WHAT: New BotPanel replaces the BOT checkbox in ActionsPanel. Interactive
channel checkboxes (from live device channel list) replace the hardcoded
BOT_CHANNELS constant. Private mode restricts replies to pinned contacts only.
BotConfigStore persists settings per device to ~/.meshcore-gui/bot/.

WHY: Bot configuration was scattered (toggle in Actions, channels in code).
A dedicated panel and config store aligns with the BBS panel/BbsConfigStore
pattern and enables private mode without architectural changes.

NOTES: ActionsPanel.__init__ signature simplified (set_bot_enabled removed).
create_worker accepts pin_store kwarg (backwards compatible, defaults to None).
2026-03-16 16:48:16 +01:00
pe1hvh 8836d9dd6e fix(bbs_service): resolve NameError in _abbrev_table that crashed !h and !help(#v1.14.1)
_abbrev_table used a list comprehension inline inside a generator
expression filter. In Python 3, list comprehensions have their own
scope, so the loop variable 'cu' was not visible to the outer 'if'
condition — causing a NameError on every !h / !help DM command.

Extract the comprehension to a local variable 'cats_upper' so both
the iteration and the filter operate on the same pre-built list.
2026-03-16 11:20:55 +01:00
pe1hvh 2963e1c855 feat(bbs): DM-based BBS with channel-based access, multi-channel whitelist, short syntax 2026-03-14 20:58:56 +01:00
pe1hvh d8a7947c6b Initial clean code 2026-03-09 17:53:29 +01:00