Repository navigation
Conversation
New mirror/ directory: portable protocol core, Chat renderer, host simulator and tests, NimBLE peripheral and Mirror activity. Upstream hooks are listed in mirror/MIRROR_CHANGES.md. Verified: host tests (234 checks), pio run -e x4pro and x4pro-mirror. Not verified: hardware, X4 (C3) build. See mirror/docs/FINDINGS.md.
Authenticated pairing (disconnect unauthenticated peers), connection epoch reset, single resync per gap, render lock released before the panel refresh, layout split with empty state, scroll marker and block-aligned own messages, single-op diffs applied in place. CI builds both mirror environments with the upstream toolchain recipe and uploads the images. Adds the X4 (C3) build numbers.
Firmware buildsFirmware is not available for the latest commit of this PR ( |
…indicator Status band with dark-mode state and Confirm toggle, status/command handling in Session, BandedGfx and shared frame composition, template dump() and glob-based sources so a new template needs no common-layer change, shape fixes from review. Adds the control golden transcript.
cppcheck flagged ICONS[7] as out of bounds: the lookup loop could end at index 7. Start from a valid fallback and stop at the first match.
The custom-sdkconfig envs run an Arduino core build in a dummy project that keeps build_src_filter but drops build flags and lib_deps. Mirror sources in that phase pulled in the hal library and Rtc failed to compile (BoardConfig.h not found). mirror/build.py now sets the source filter lazily and leaves the mirror folders out during that phase. Reproduced from a pristine IDF libs cache; both mirror envs build.
…dow, protocol 3 Every characteristic and the notification subscription need an encrypted, authenticated link. LE Secure Connections only, MITM passkey, resolvable private address, generic name. Unknown phones can connect only while Pair phone is open; a bonded phone cannot re-pair outside it. Bonds from the old security model are deleted. Protocol 3 adds unlock/HID fields (unused until the keyboard lands). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
One bond serves the mirror and an opt-in HID keyboard built with authenticated characteristics only. Unlock pad sends each key immediately and keeps nothing; the phone reports only a locked boolean. Chord (default Ctrl+Alt+Shift+M) is edited on the device, validated in core/Chord, and announced to the phone. Docs list what needs hardware verification. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
|
CI status for
Generated by Claude Code |
Opening the unlock screen wakes the phone. Pattern dots send digits 0-8 as the finger touches them and Enter when it lifts; the PIN pad keeps an Enter key. The path is never drawn. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
… docs) drain keeps the reserved inbound capacity, the connection epoch changes once per link, a failed authentication deletes the bond and closes the pairing window, refused links skip connection tuning. Clearer messages, periodic full refresh on the unlock screens, no key highlight on touch boards. README trimmed. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
PlatformIO's cppcheck binary links libpcre.so.3; ubuntu-latest is now 26.04, which has no libpcre3 package. Fork only: drop this commit when sending the work upstream. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
…omments Unlock, pattern and chord screens move to MirrorScreens.cpp. Per-link state is one struct, the chord rows are a table, BLE security setup is one function, the security epoch lives with the other settings. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
The list Home cannot scroll, so with Plugins/OPDS and Sync Now the Mirror row fell below the screen. In mirror builds it now lists Library, Sync Now, Mirror and More...; File Browser, File Transfer, OPDS/Plugins and Settings open from More.... Cover-grid Home and stock builds are unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
…pairing logs The X4 Pro has no Confirm button by default, so pairing could never be started there. The Mirror screen is now a column of buttons (tap on touch boards, cursor plus Confirm elsewhere); Forget and Keyboard ask for a second tap. Chat view: side buttons or swipe scroll, tapping the top toggles dark mode. Logs for the pairing window, advertising, connections and authentication; advertising is no longer restarted while a central is connecting. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
… screen A GATT server that fails to start (for example with the keyboard service) now ends in 'Bluetooth could not start' instead of a silent non-advertising device. The Mirror screen shows whether the radio is advertising, so pairing problems are visible without a serial cable. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
…NimBLE errors With the keyboard on, advertising failed to start on hardware (serial log: 'advertising FAILED to start'). The retry drops the HID UUID and appearance from the advertisement; NimBLE error logging is on in the mirror builds so the reason code shows in the serial log. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
…ails Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
…onse Serial log from the X4 Pro: advertising with the private address fails (rc=530, HCI 0x12) and the public address works. The device name did not fit the main advertising packet. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
The device slowed its CPU and could auto-sleep while advertising for a phone to pair; only a connected phone kept it awake. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
|
CI note for Generated by Claude Code |
The pairing code disappears within a second on hardware; the log did not say who ended the link. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
Phone log: with the keyboard appearance the phone classifies the device as a keyboard (class 0x540), shows its own PIN and answers the passkey request with it, so the code on our screen never matched. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
The stack keeps the callback objects, which held a reference to the first MirrorBle. After leaving and re-entering Mirror, a connecting phone called into the destroyed instance and the mutex lock aborted the firmware (decoded backtrace: MirrorBle::onConnected line 261). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
…sing bond Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
…imeout, heap log on stop Lessons from Flowe OS's BLE service: deinit while a link is closing races the host task; heap per visit should be watched. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
…lock, long-press scroll, steadier pairing Chat schema 2: draft_cursor, SetDraftCursor, ScrollTop/ScrollBottom (regenerated, goldens updated). The draft box grows with the text and shows the cursor's line. The pattern is collected while dragging (samples interpolated) and sent when the finger lifts; opening Unlock sends Enter after the wake when the phone is locked. Holding a scroll button jumps to the oldest or newest message. The device accepts a connection whenever a bond exists, drops other bonds only during a fresh pairing, advertises while connected so the phone's companion scan can find it, and refuses a second central. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
The mirror workflow ran on push and on pull request for the same commit; it now runs on pull request (push only for develop) and cancels superseded runs. The X4 (C3) image builds on demand only. The stock CI builds only the X4 Pro instead of eight boards. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
…ding security request While a phone is linked the device advertises non-connectable (the companion scan still sees it) instead of connectable, so the phone's HID host and app are not refused and retried in a loop. The security request now waits 1.5 s and is sent only if the phone has not secured the link itself. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
Serial log: a bonded phone connected, encryption failed (MIC failure) and the failure handler deleted the bond, so the next start showed 0 bonds. Only a pairing in progress deletes a bond now. Connection tuning waits for a secure link and the device no longer sends its own security request (it preceded HCI ack timeouts and host resets). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
…ng, diff validation) A readable-NVS check before deleting bonds, a random code for a refused pairing, a pairing that outlasts the window, events of a refused link ignored, a cached bond count for the render task, Enter after the wake without blocking, buttons inactive while the passkey shows, second-tap state reset, a single-op diff validated before it is applied, UTF-8 hard breaks clamped, periodic full refresh on the status screen. Lessons and the open findings are documented. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA
Summary
ynsgnr/retink(Android app, protocol 3).mirror/directory. Upstream files touched are listed inmirror/MIRROR_CHANGES.md:platformio.ini(oneextra_configsline),HomeActivityandCoverGridHomeUi(Home menu entry), and the CI workflows. Everything is behind-DCROSSPOINT_MIRROR=1, set only by themirror(X4, C3) andx4pro-mirror(X4 Pro, S3) environments.mirror/README.md.mirror.ymlbuilds both mirror environments and uploadsfirmware-mirror.binandfirmware-x4pro-mirror.binas artifacts, runs the host tests, and checks the generated files. The last commit pins the cppcheck job toubuntu-24.04(the runner image droppedlibpcre3); it is fork-only.Scope Check
This is a personal fork feature, outside upstream CrossPoint scope (SCOPE.md), and is not intended for upstream.
freeink-sdk/,lib/hal/, bootloader, OTA or recovery code.Additional Context
pio run -e mirrorand-e x4pro-mirror, the retink Kotlin tests and APK build.mirror/docs/FINDINGS.md.firmware-handoffprocess (independent reviews, human acceptance, hardware testing) has not been done.AI Usage
Did you use AI tools to help write this code? YES (Claude Code wrote the change; a human has not reviewed it yet).
🤖 Generated with Claude Code
https://claude.ai/code/session_01Xxo1zUj9y971kfgC3syQCA