Connection spine
OpenZCine speaks standard PTP to Nikon Z bodies: PTP-IP over Wi-Fi, or PTP over the USB-C cable. There is no Bluetooth step and no vendor SDK. Every control, live-view frame and media byte rides the same serialized PTP session. Order of operations on Wi-Fi:
discover → TCP :15740 Init_Command → Init_Event → OpenSession → GetDeviceInfo → pair (first time) → app-control mode → live view → media- Reach the camera. Join the camera’s own access point, share a
router with it, or let it join the phone’s hotspot. Discovery browses
Bonjour
_ptp._tcpand probes the local subnet. - Init handshake. Command socket first
(
Init_Command_Request/Init_Command_Ack), then the event socket with the connection number the camera assigned. Both on TCP port 15740. - OpenSession. Transaction ID 0, then
GetDeviceInfo. The operations the body advertises decide every later step, not the model name. - Pairing (first time only). Gen-3 bodies show a four-digit code; the
operator confirms it on both screens (
GetPairingInfo,ConfirmPairing). USB-C and original Z 5 / Z 6 / Z 7 / Z 50 bodies have no pairing step: the cable, or joining the camera’s own network, is the trust boundary. - App-control mode.
ChangeApplicationModeon Gen-2 and Gen-3 bodies, a write ofApplicationMode(0xD1F0) on Gen 1. Over USB the ZR also needsChangeCameraModeremote mode. - Vendor discovery.
GetVendorCodes(orGetVendorPropCodeson older bodies) lists the vendor properties the body can report, which gates polling. - Live view and media run as ordinary transactions on the same command channel.
A saved camera skips pairing: the app runs a quiet profile probe, and if the app-control switch answers OK the session continues. A refusal or a hangup is treated as the camera’s word, and the app falls back to one fresh pairing.
Disconnects send CloseSession before closing the sockets, and a reconnect
waits a short settle so the camera can release its single session slot. A body
that never sees the old session end can refuse or wedge on a fast re-Init.
Implementation lives in Sources/OpenZCineCore/ (packets, handshake, policies)
and the platform transports (OpenCine Sources/OpenCineNikon/PTPIPTransport.swift
and USBCameraTransport.swift for iOS, OpenCine Sources/OpenCineNikonAndroid/ for Android).
Platform shells own sockets, permissions and the Wi-Fi join. Body generations
and per-model differences are in Nikon Z Devices.