Skip to content

Protocol differences in Link Controller v2.2.1 (newer app versions) #3

Description

@csmarshall

While building a CLI tool against the documented protocol, I found several breaking differences in Insta360 Link Controller v2.2.1 (macOS). Documenting here for anyone hitting the same issues.


  1. Process name changed

The macOS process is no longer named Insta360 Link Controller. It now runs as Webcam-desktop inside the app bundle:

/Applications/Insta360 Link Controller.app/Contents/MacOS/Webcam-desktop

This matters if you're using pgrep or lsof to find the process — filtering by process name won't work. Filter by PID instead:

pgrep -f "Insta360 Link Controller" # matches the full path, still works
lsof -i -a -n -P -p # note: requires -a to AND the filters on macOS


  1. Port is ephemeral, not fixed

The WebSocket server no longer listens on a predictable port (7878, 9090, etc.). In testing it bound to 49924, which is in the ephemeral range. Discovery via lsof -p is the reliable approach.


  1. Token is required — in the URL and the controlRequest

The WebSocket connection now requires a token, passed in two places:

ws://localhost:/?token=

AND in the controlRequest protobuf message:

controlRequest { token: "" }

Connecting without the token (or with a wrong one) results in controlResponse { success: false, reason: TOKEN_INVALID }.

The token is generated by the app when it displays the QR code for the mobile web remote. Previously-accepted tokens are cached in:

~/Library/Application Support/Insta360 Link Controller/startup.ini

under a [Token] section, with Unix timestamps as values (so you can pick the most recent):

[Token]
3cAKW91uM3JxnlDCOzY9b55PnYHlWh=1773071792
JUW5b7Nf7NjxR9jpfuJxAxs1HUwmXN=1773071791

Note: configparser lowercases keys by default — read the file manually to preserve case, as the token is case-sensitive.


  1. DeviceInfoNotification field layout changed

The field assignments in DeviceInfoNotification are swapped compared to the proto:

Field Proto (v1.4.1 doc) Actual v2.2.1
1 string curDeviceSerialNum DeviceInfo device (embedded msg)
2 repeated DeviceInfo devices string curDeviceSerialNum

So curDeviceSerialNum is now at field 2, and field 1 holds a single DeviceInfo message directly.


  1. DeviceInfo.zoom moved from field 3 to field 5

Within DeviceInfo, the ZoomInfo zoom message moved:

Field Proto (v1.4.1 doc) Actual v2.2.1
3 ZoomInfo zoom int32 (varint)
5 bool mirror ZoomInfo zoom

The ZoomInfo content itself is unchanged (curValue, minValue, maxValue).


Raw hex capture

Full deviceInfoNotify response frame from a live session (serial redacted):

080152b2020a9f020a0b4c696e6b2d58585858585858120e5858585858585858585858585858
180020002a070864106418900338ffffffffffffffffff014000480052e301080110012001
2801300048016032683270327832880101900100980100a00100a80101b001fc2ad8010090
0202980200a80201b00200c00200d00201d80201e00200e80200f00200f80200800301880300
900301980300a2030a686f72697a6f6e74616cad0300000000b00300b80300c00300ca032c
08ffffffffffffffffff0110ffffffffffffffffff0118ffffffffffffffffff0120ffffffff
ffffffffffffffffff01d2031608ffffffffffffffffff0110ffffffffffffffffff01da0313
0800120723303066663030184d2009280a3032e00300e80301f00300f8035a800400880401
120e5858585858585858585858585858

Tested on: Link Controller 2.2.1 (build 24), macOS 26.3.1, Insta360 Link (original).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions