# Lab 002 — LixelGO/iPhone local K1 protocol observation

- Date: 2026-07-16
- Device scope: one owner-controlled LixelKity K1, exact firmware `3.0.2`
- Application scope: owner-operated LixelGO on a trusted iPhone
- Capture path: iPhone `pcapd` over USB to the Mac
- Result: **GO for protocol-backed camera discovery and start/stop mapping;
  PAUSE for Mission Core command emission and save-state semantics**

This report contains no device identifier, address, SSID, credential, project
name, room image, or raw packet payload. The sensitive source captures remain
under ignored `sessions/` with mode `0600`.

## Experiment boundary

The operator performed one clean LixelGO lifecycle and one control/stop window:

1. K1 was powered to steady-green standby without a physical scan gesture.
2. LixelGO established Bluetooth control and requested the K1 Wi-Fi network.
3. The operator accepted the iOS Wi-Fi join request.
4. LixelGO entered its scan workspace; this navigation alone caused no K1 state
   transition.
5. The operator supplied a private project name and confirmed start.
6. K1 performed static initialization and exposed point cloud, pose and camera
   preview.
7. The operator selected left and right camera views.
8. The operator opened the stop confirmation and then confirmed it.
9. K1 stopped the LiDAR, displayed its saving state and returned to steady-green
   standby without any physical K1 button press.

Bluetooth HCI was not captured. The BLE stage is supported by the operator's
screen/physical observation, while all protocol findings below start at the
iPhone IP stack.

## Evidence integrity

The two principal network sessions contain `108,188` and `207,123` packets.
Their raw PCAPNG and compatible classic PCAP hashes match the capture manifests,
and packet timestamps/order are equivalent across the two representations.

The original manifests and captures were left byte-for-byte unchanged. A
separate private integrity inventory re-hashes the manifests, packet files and
late operator-event JSONL. Operator events record sequence, not precise action
latency: several were narrated after the corresponding wire event.

## Network and privacy result

LixelGO accounted for more than `99.5%` of bytes in each principal capture and
communicated with exactly two private local endpoints. No LixelGO flow to a
public/WAN address was observed in either window. The first window contained a
very small amount of unrelated public traffic from other iPhone processes; the
second contained no public traffic at all.

This is bounded negative evidence for these sessions, not a permanent claim
about every application mode or future LixelGO release.

Observed K1 transports:

| Transport | Purpose | Result |
| --- | --- | --- |
| MQTT 3.1.1 over plaintext TCP `1883` | control, status, point cloud, pose | observed |
| RTSP 1.0 over TCP `8554` | left/right camera session control | observed |
| interleaved RTP/TCP, H.264 PT96, 90 kHz | camera preview media | observed |
| HTTP over TCP `80` | three empty project-related setup responses | ancillary only |

No LixelGO UDP flow was observed.

The retained clean-cycle control connection was subsequently re-audited without
capturing new traffic. MQTT CONNECT used protocol level 4 / MQTT 3.1.1,
`clean_session=false` and keepalive 60. Control and point-cloud subscriptions
used separate 19-byte client IDs; their values remain private. The control
client issued three ordered subscription groups containing 9, 5 and 42 topics
before issuing requests. The separate point-cloud client then issued groups of
1 and 1 topic; their values are the already documented legacy/current point
channels. The control group order, topic names and requested QoS values are now
locked by public synthetic regression without exposing client IDs or payloads.
The modeling acknowledgement topic is
`lixel/application/response/modeling`; request QoS was 2 while the K1 delivered
the observed application response PUBLISH packets at QoS 0. These redacted
facts bound the acceptance transport but do not authorize it.

## Start and static initialization

The application start transaction is now physical wire evidence rather than
static-analysis evidence:

- QoS 2 PUBLISH topic: `lixel/application/request/modeling`;
- bounded protobuf top-level action field: `1`;
- correlated device response: about `1.5 ms` after the request, with the same
  action and a success result;
- first pose: about `23.1 s` after the request;
- first modeling/point-cloud reports: about `24.1 s` after the request;
- first camera RTSP PLAY: about `25.1 s` after the request.

The observed 144-byte START protobuf has this bounded top-level wire shape
(private strings remain redacted):

```text
f1/wire2 = 130-byte private header/session string
f2/wire0 = 1
f3/wire2 = 3-byte private string
f4/wire0 = 2
f5/wire0 = 1
```

`f4` is the decoded value `2`; the occasionally noted `1` describes only the
one-byte varint encoding length and is not the field value. The successful
response repeats the private 130-byte field, reports `f2=1`, and includes an
observed success block in `f15/wire2` (15 bytes). These observations describe
the capture but do not establish safe construction rules for a new request.

The 23–25 second interval matches the operator-observed static initialization.
The captured request contains additional private header/settings context. Its
complete construction and validation rules remain unresolved and are not
committed as a reusable command fixture.

## Live data plane

The existing repository decoder successfully decoded distributed samples of
both live spatial channels:

- point cloud: `lixel/application/report/lio_pcl`, about `9.4 Hz`, roughly
  `2,500–2,650` points per sampled frame;
- pose: `lixel/application/report/lio_pose`, about `10 Hz`, finite decoded
  position/orientation fields.

During active scanning the aggregate K1-to-phone data plane averaged roughly
`1.11 MB/s`, split approximately into `0.25 MB/s` MQTT and `0.86 MB/s` camera
RTSP/RTP. The observed peak was about `1.89 MB/s`.

## Camera preview

The K1 exposes two independent path-labelled RTSP preview endpoints:

```text
rtsp://{confirmed-device-private-ipv4}:8554/live/chn_left_main
rtsp://{confirmed-device-private-ipv4}:8554/live/chn_right_main
```

Each session follows `OPTIONS`, `DESCRIBE`, `SETUP`, `PLAY`; media is H.264 in
interleaved RTP over TCP. The observed preview rate was approximately `10 fps`
and `6.45–6.59 Mbit/s`.

Camera selection is not an MQTT command. LixelGO tears down the current RTSP
session and opens the other endpoint. In the controlled left-to-right switch,
the new RTSP connection began about `0.8 s` after the preceding stream's last
packet. RTP arrived immediately after PLAY, but the first new SPS/PPS/IDR group
arrived about `0.79 s` later. This explains most of the operator-observed visual
delay; exact tap-to-display latency was not measurable from retrospective event
markers.

The capture proves a compressed preview path, not full-resolution raw camera
frames, camera calibration, stitched panorama geometry, or optical left/right
identity beyond the endpoint labels and operator-selected views.

## Stop and post-stop boundary

The remote stop transaction is also verified inside the packet capture:

- QoS 2 PUBLISH on the same modeling-request topic;
- bounded protobuf top-level action field: `2`;
- correlated success response after about `33 ms`;
- final point-cloud PUBLISH after about `36.4 ms`;
- final pose PUBLISH after about `40.8 ms`;
- final interleaved video packet after about `54.1 ms`;
- point-cloud UNSUBSCRIBE and RTSP TEARDOWN at about `0.95 s`;
- status/modeling reports for about another `9 s`;
- control MQTT and heartbeat remained reachable for about `31 s` without a
  recurrence of high-rate point, pose, or video traffic.

The raw modeling-state value changed immediately after stop. Its enum name is
not decoded. The capture does not contain an independently verified
`save-complete`/`project-closed` response or the previously observed standby
state code. Completed saving and final steady-green standby are therefore
operator-corroborated, not packet-semantically proven.

## Decision

- **GO:** retain MQTT point cloud and pose as the current live spatial plane.
- **GO:** implement a read-only left/right RTSP/H.264 preview receiver behind
  the XGRIDS plugin boundary.
- **GO:** promote start=`1` and stop=`2` from static hints to observed,
  physical-correlated vendor mappings.
- **PAUSE:** keep all Mission Core vendor writes disabled until request headers,
  settings, acknowledgements, timeout, save completion and rollback are modeled
  and regression-tested.
- **PAUSE:** do not name the post-stop enum or claim durable project persistence
  from this capture.
- **PAUSE:** BLE automation remains governed by the separately reviewed Wi-Fi
  provisioning profile; no BLE/HCI inference is added here.

The next smallest implementation step is an offline/then-live read-only camera
adapter with bounded buffering, H.264 metadata, explicit left/right selection
and no acquisition command publisher.
