You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Two interacting bugs caused this:
Bug A (primary, blocks ID-based / scan-tap join entirely):
The v1.5.4+306 audit added a hard null-guard on device.sessionId in
session_join_card.dart that showed a 'host did not broadcast its
session id' snackbar and aborted the join when sessionId was null.
Combined with the v1.5.4+308 SIGABRT hotfix that removed
CBAdvertisementDataServiceDataKey from iOS advertisements (Apple
crashes when 3rd-party apps try to set it), iOS hosts no longer
broadcast their sessionId via BLE — so iPhone joiners ALWAYS hit
the snackbar and could never join an iPad host. v1.5.2 worked
precisely because it didn't have this guard. Fix: fall back to
device.id when sessionId is null. SyncEngine doesn't gate by
sessionId, so a mismatched local-DB session label is cosmetic, not
a sync break.
Bug B (secondary, broke iPad→iPhone direction even after a successful
QR-based join):
BleTransport.broadcast()'s peripheral-mode path passed the entire
SyncPayload to pm.updateValue(...) in one call with no MTU-aware
chunking. iOS silently truncates anything past
central.maximumUpdateValueLength. A 150-250 byte position payload
became 20 bytes of garbled JSON on the iPhone, SyncPayload.fromBytes
threw, the message was dropped — iPad showed 1/8 connected, iPhone
showed 0/8.
Fix: chunk via the existing 0x01/0x02/0x03 protocol; surface
central.maximumUpdateValueLength from
BleAdvertiserChannel.swift didSubscribeTo so Dart knows the per-
central limit; use the MIN across subscribed centrals so a single
chunked stream is compatible with every subscriber; retry up to 3x
with 25ms delay on pm.updateValue=false (transmit-queue-full).
Plus three MPC bug fixes flagged by the parallel audit but not
the primary bug:
- Info.plist NSBonjourServices was missing _red-grid-link._udp;
iOS 14+ silently rejects MPC service registration without both
_tcp and _udp. Added _udp.
- IosP2pTransport._handlePeerFound now extracts sessionId from
discoveryInfo['sessionId'] (the native side already packs it,
but Dart was discarding it). Without this, MPC-discovered iPads
also fell into Bug A's null-guard.
- IosP2pTransport now wires the 'onError' event so MPC advertiser/
browser failures surface on the transport state stream instead
of being silently swallowed (which masked Bug B for weeks).
0 commit comments