Frontend:
- trace empty-state now shows connection status + capture mode (boxed,
colored) in the center, updated live via checkConnection
- capture-mode uses amber warning style (gsmtap/disabled), green for direct
- stopCapture clears currentSessionId
Server:
- gsmtap read_packet catches OSError on socket close (no more EBADF
traceback on stop)
- stop_session joins the loop and discards a session with zero messages;
/api/capture/stop reports discarded
- startup prints server version
Tests: 122 (gsmtap close, empty/non-empty capture lifecycle).
- pcap.py: _parse_tsresol now pads options to a 32-bit boundary
((-length) % 4) and uses 2** for the MSB-set (power-of-2) case, so
nanosecond if_tsresol is read correctly (was defaulting to µs and
scaling timestamps 1000x)
- database/server: set imported session started/ended from the first/last
packet timestamps (falling back to wall-clock for synthetic SPB)
- frontend: formatDuration renders hours
- tests: tsresol (ns after padded option, default µs, ns round-trip) and
session-window/fallback (119 total)