ChangelogLink to the section Changelog
On this page
All notable changes to the UNIVIP specification and its machine-readable artifacts are recorded here. The format follows Keep a Changelog; the project follows semantic versioning as described in GOVERNANCE.md.
[Unreleased] — reference implementationsLink to the section [Unreleased] — reference implementations
Portal illustrations — 2026-10-16Link to the section Portal illustrations — 2026-10-16
- Added ImageGen concept scenes for deployment alternatives, the alarm-inspection walkthrough and camera ground footprints. Labels and captions remain editable HTML, and scene panels stack on narrow screens.
- Documentation images are published from
docs/images/with local link checking, descriptive alternative text, explicit dimensions and lazy loading. Generation prompts are retained undersite/artwork/.
Software and emulator hardening — 2026-10-16Link to the section Software and emulator hardening — 2026-10-16
- Unconfirmable DJI cancellation returns
command-not-cancellableon REST or rejectsvehicle.cancelwithBUSY; inability to stop after lease loss reportsFAILED. - Both gateways reject a false ground cancellation while takeoff is pending. DJI shutdown retains the requested video id so it can stop a push before its start reply has been applied.
- New movement requests are refused while failsafe control is active; hosted video ownership survives session reconnection. Both gaps have regression coverage.
- .NET hosted proxies enforce video-view ownership between authenticated callers. Both gateways combine WHEP and session views in a per-client quota; Python INTERNAL signaling errors omit exception details.
- Wheels and source distributions include the canonical schemas; a clean-install check builds from the extracted sdist outside the checkout.
- Browser STUN/TURN configuration, relay-only recorded demonstrations, seeded native UDP faults, recording clock-error and frame-counter checks, and extended opt-in autopilot SITL cases.
- One-command software validation with retained reports and recordings. Operator hold now cancels queued simulator patrols. macOS TLS test skips are explicit; Linux continues to require TLS 1.3.
- Verified at
e1ff3d8: 593 local software tests passed, two macOS TLS skips; all 142 Linux gateway tests passed; 10 PX4 and 10 ArduCopter SITL cases passed. The documentation records the GPS coverage boundary. - The portal publishes problem registry rows with multiple rejection reasons and checks that every registered error has a page, including
command-not-cancellable.
AddedLink to the section Added
gateway/(Python reference gateway, implementing spec 0.2.0-draft): Profiles S, C and N with device-initiated session channel, session proxy, device-hosted REST, telemetry, events with replay, leases, camera and vehicle commands with every Part 11 precondition, audit trail, TLS 1.3 only, H.264 over WebRTC with a machine-readable timecode. Adapters: kinematic simulator, MAVLink (PX4, ArduPilot) with a fake PX4 vehicle, and the DJI Cloud API (dji_cloud: DJI Dock / Dock 2 over MQTT, optionaldjiextra) with a fake dock and a minimal MQTT broker. Development client endpoint that validates every message and can forward REST requests over the session.gateway/client tools:univip-recorder(video as received in MPEG-TS with one MISB ST 0601 Local Set per frame as synchronous KLV, plus telemetry, events and the RTCP time map) andunivip-replay(flight path from either source, GeoJSON, per-frame CSV and a self-contained replay page); the Phase 1 recording test.dotnet/: .NET 10 client SDK (Univip.Protocol,Univip.Client), the gateway ported to ASP.NET Core (Univip.Gateway), andUnivip.Viewer.Web, a standalone viewer (WebRTC video relayed as WHEP or signalled over the session, Leaflet map with track, home and geofence, telemetry overlay with stale indication, events with active conditions, optional leased camera control and hold / return home) with Playwright browser tests.media.encoder/media.encoder_devicefor the .NET gateway (libx264,libopenh264,h264_vaapi,h264_nvenc,h264_qsv); the Python gateway accepts and ignores them.docs/sitl-validation.md: the MAVLink adapter validated against PX4 1.17.0 and ArduCopter 4.7.2 SITL, with 19 adapter bugs fixed (among them PX4 relative-altitude goto, hold not stopping a goto, ArduCopter hold descending, failsafe returns shown as emergencies, Copter 4.7 RTL parameter names, gimbal control on both autopilots, and the take-off pilot-override race); opt-in SITL tests (gateway/tests/test_sitl.py), build scripts (tools/sitl/) and a manualsitlworkflow.- Docs: implementation findings F10–F21 and I–V (SITL, viewer, DJI, recording, media security, and the review of the 0.2 text while implementing it) with their resolutions;
docs/recording-test.md;docs/security/webrtc-review-2026-10.md;THIRD_PARTY_NOTICES.md. - CI:
gateway(with ffmpeg and thedjiextra) anddotnet(with the browser tests in Google Chrome).
SecurityLink to the section Security
- .NET gateway, internal review of the WebRTC stack: fixed SDP parsing that could stall the gateway loop, unbounded SCTP state, media redirection (RFC 7675 consent checks added), WHEP DELETE by other viewers (creator only, random ids), STUN reflection and replay, SRTCP replay, CBC DTLS suites and the long-lived DTLS certificate. The software follow-up addresses WR-18 and WR-19; WR-20 to WR-22 remain residual items.
- Python gateway: unguessable WHEP view ids, creator-only teardown, 64 KiB offer cap; command limits fail closed when they cannot be evaluated (a missing home position no longer skips the distance and altitude checks).
- .NET SDK: the REST token is no longer sent to a WHEP resource URL outside the device's REST origin.
ChangedLink to the section Changed
- Website (ADR-0009, superseding ADR-0008 decision 4):
site/is now a Vite and TypeScript project that builds a static site intosite/dist/for Cloudflare Workers (site/wrangler.jsonc) or Cloudflare Pages, replacing MkDocs and the GitHub Pages deployment. The build fails on broken links and heading anchors, on pages missing from the navigation and on schemas whose$idis not their published URL. Page URLs have no.htmlor trailing slash, so problem type URIs resolve without a redirect;_headersadds cross-origin access to schemas, examples and the API description, a content security policy and caching. The site adds search, light and dark themes, and a home page chart drawn from a telemetry example. Thesiteworkflow builds, type-checks and tests it, and keepssite/dist/as an artifact; it no longer deploys.tools/build_site.py,site/mkdocs.ymlandsite/requirements.txtare removed.
DocumentationLink to the section Documentation
docs/community-and-membership.mdand a dated note on ADR-0008 give the 0.2 website URLs (/spec/0.2/,/schemas/v0.2/) instead of the 0.1 ones.THIRD_PARTY_NOTICES.mdcovers the website: two OFL fonts and MiniSearch are served with it, and the build publishes their licence texts.- The PyAV wheel used by the Python gateway's
mediaextra bundles GPL libx264 and libx265.Univip.Protocolpins JsonSchema.Net 8.0.5 (with JsonPointer.Net 6.0.1 and Json.More.Net 2.2.0), the last versions whose NuGet packages are plain MIT; 9.x binaries carry a maintenance-fee agreement. SeeTHIRD_PARTY_NOTICES.md.
[0.2.0-draft] — 2026-10-15Link to the section [0.2.0-draft] — 2026-10-15
Resolves the 60 implementation findings A–H recorded against 0.1, and most of those from the viewer, the DJI adapter, the recording test and the WebRTC review (I–S); docs/implementation-findings.md maps each finding to its resolution and lists the ones left for 0.3. These are the editor's resolutions, open to review by the Technical Working Group. Messages valid under 0.1 remain valid under the 0.2 schemas (examples/compat/); a device that declares 0.2 without its own REST listener must support the session proxy.
AddedLink to the section Added
- Session proxy (Part 05 §5.5.1):
requestandresponseenvelopes carry REST calls over the session channel, so a client can reach a device that accepts no inbound connections.transports.rest.session_proxy; REQUIRED whendevice_hostedis false. Proxied scopes are limited to those the operator allowed for the endpoint. - Verified client identity (Part 05 §5.3.1): the device takes the client's identity from its configuration of the endpoint and refuses a
welcomenaming anotherclient_id; command status and lease envelopes are routed by it. - Problem-type registry (Part 05 §5.5.2) with a page per type on univip.org (
/problems/<slug>/), including types for a client-hosted endpoint whose device is unavailable, times out or fails. - Payloads for
welcome,ping/pongandsignalin the envelope schema; signalkind: "close",webrtc_session_id(several views per session),constraints, andref_msg_idon answers; error codesPROTOCOL_VIOLATION,UNKNOWN_STREAM,CODEC_UNSUPPORTED,BUSY. - Capability members
telemetry.applied_rate_hz,transports.rest.insecure,media.webrtc.ice(FULL/LITE),payloads[].lease(camera lease TTL and heartbeat),vehicle.limits.altitude_agl_basis. - Telemetry
age_msonposition,motion,powerand payload entries; enumerated reasons fordevice.offlineandcamera.stream.stopped. - WebRTC baseline (Part 09 §9.3): full ICE (ICE-lite only where host candidates are reachable, and declared), DTLS 1.2+ with ECDHE and a P-256 certificate,
SRTP_AES128_CM_HMAC_SHA1_80, PLI/FIR answered within 1 s, key frame at least every 2 s, client-created telemetry data channel that may drop under backpressure, views ending with their session.DELETEof a WHEP view in the OpenAPI, creator only. - Timecode strip specified as the Part 14 alignment pattern; SAN URI binding of
device_idfor mTLS; TLS policy for OAuth token endpoints. - Media security (Part 09 §9.3): ICE consent freshness (RFC 7675) on every device, views released within 30 s of consent loss, SHA-256-or-stronger fingerprints, per-peer certificates, 64 KiB offer cap, unguessable view ids deletable only by their creator, same-origin
Location, device-to-client telemetry channel, optional per-client view limits. - Optional VP8 and AV1 beside the mandatory H.264; condition keys for stateful events; client staleness guidance; a HOLDING dwell for every device; return-home reasons
WEATHER,TRAFFIC,OBSTACLE,FAULT. - Annex A.4: DJI Cloud API ↔ UNIVIP (informative).
ChangedLink to the section Changed
- Profile N requires Profile S only (was C), so a vehicle without a controllable payload can be tasked.
- Limits fail closed: a command whose limits cannot be evaluated (for example, home unknown) is rejected
OUT_OF_LIMITS. Take-off is also allowed fromDOCKED; protocol-limited sources may declare a telemetry rate below 2 Hz. - KLV in MPEG-TS is carried as synchronous metadata (stream type 0x15), one Local Set per frame; the frame-time target is defined as the error of the frame's device time, with telemetry interpolated to it; a TS copy replaces telemetry only for the members ST 0601 carries; the recording time map is anchored to the segment.
- Annex A.2 (MAVLink) revised against PX4 and ArduPilot SITL:
MAV_STATE_CRITICALis a failsafe, not an emergency; PX4 repositions are AMSL; hold is PX4 pause or ArduCopter BRAKE; holding over home after a no-land return; gimbal-manager control; ArduCopter 4.7 RTL parameter names. - Annex A.3 (ST 0601) corrected: tag numbers 72, 75, 67/68, 74, 90–92, sensor-relative angles through the full platform attitude, corner and edition rules.
- Enumerations are open unless marked
x-univip-closed(command and lease states), and the schemas matchschemamembers by pattern, so receivers tolerate unknown values and other 0.x MINORs (Part 01 §1.4–1.5, Part 13 §13.6). Schema$ids moved tohttps://univip.org/schemas/v0.2/. poweris no longer required once the source has stopped; repeated values carryage_ms. The requested telemetry rate is an upper bound.- HTTP 403 means only a missing scope; lease, limit and safety refusals are 422 rejections. The synchronous command answer reflects the controller's acknowledgment (up to 10 s).
expires_atbounds the start of execution. A future-datedissued_atisINVALID_PARAMETERS. - Session establishment: one
welcomeperhellocarrying itsdevice_id; per-device refusal without dropping the session, re-offer at most every 60 s; ping and unanswered-ping rules; which messages may precedecapabilities. - Event replay restated as one guarantee (disconnects up to 15 minutes and 500 events); still-active conditions re-sent with their original
event_id. - Lease envelopes only to the holder;
GET /leasesshows a caller its own leases; session loss starts the lease expiry clock;vehicle.holdon the ground completes at once. - Gimbal
BODYandEARTHframes defined;move_relativedeltas apply in the requested frame;rate_degpsis a slew limit a device may ignore. - Annex A.2 (MAVLink):
RECOVEREDandLANDINGrows, hold and manual modes per autopilot, ellipsoid height from fused MSL plus geoid separation, RTL parameter restoration,COMMAND_ACKtiming and results 7/8, and the gateway's choice oftelemetry.staleoverlink.lost.
RemovedLink to the section Removed
WEBRTC_DEVICE_OFFER(the device-offer signalling mode was never defined in enough detail to implement).
[0.1.0-draft] — 2026-10-14Link to the section [0.1.0-draft] — 2026-10-14
ChangedLink to the section Changed
- Completed the ODIP→UNIVIP rename where it had been missed: OAuth scope
univip.aircraftis nowunivip.vehicle(Part 13, OpenAPI, ONVIF comparison); standard event topics beginvehicle.(Parts 03 and 08); Annex A refers tovehicle.operation.*. - ADR-0001 through ADR-0006 moved from Proposed to Accepted on sponsor confirmation (2026-10-14); all decisions in the 0.1 draft are now Accepted.
- Schema
$ids moved fromurn:univip:schema:v0.1:<kind>to canonicalhttps://univip.org/schemas/v0.1/<kind>.schema.json(ADR-0008); domain purchased 2026-10-14. Website build added undersite/. - Website build fixed: the
site/configuration (mkdocs.yml,requirements.txt,README.md) is now committed (it had been excluded by.gitignore); the site workflow builds on every push and pull request with broken links failing the build, and deploys from the default branch whatever its name. - Renamed the project from ODIP (Open Drone Interoperability Protocol) to UNIVIP (Universal Vehicle Interoperability Protocol);
univip.orgreserved. Schema identifiers are nowunivip.<kind>.vX.Y, URNsurn:univip:…, REST base/univip/v1, scopesunivip.view|camera|vehicle|config|admin, DNS-SD_univip._tcp. - Domain-neutral vocabulary (ADR-0007, Option 2):
aircraft.*commands are nowvehicle.*; the telemetryaircraftobject isvehiclewithvehicle_state(core statesOFF, IDLE, PREDEPLOY, DEPLOYING, OPERATING, HOLDING, RETURNING, RECOVERING, RECOVERED, DOCKED, EMERGENCY, UNKNOWN) and informativedomain_state;flight_time_sisoperation_time_s;remaining_flight_time_sisremaining_endurance_s; event topics moved fromdrone.*tovehicle.*withflight.*→operation.*andgnss.degraded→positioning.degraded; lease scopeaircraft→vehicle. - Added
device.domain(AIR,UNDERWATER,SURFACE,GROUND,MULTI),position.depth_m,position.altitude_above_seabed_m,position.source, link transportsACOUSTIC/OPTICAL, limitsmax_depth_m/min_altitude_above_seabed_m, missionaltitude_reference: DEPTH, reserved commandsvehicle.dive_to/vehicle.surface, eventvehicle.depth.limit, and an underwater ROV telemetry example. Aerial remains the only domain with conformance test groups in 0.1.
AddedLink to the section Added
- ADR-0007 (multi-domain scope) and cross-domain naming shortlist; ADR-0005 records the sponsor decision that MQTT is not mandatory.
- Initial repository: white paper, prior-art review, roadmap and governance.
- ONVIF comparison (architecture, transport stack, security), transport-baseline validation, community/membership/website plan and naming proposal.
- Architecture decision records ADR-0001 through ADR-0006 recording the foundational decisions and their proposed defaults.
- Specification parts 01–14 (scope, terminology, architecture, profiles, identity and connection, capabilities, telemetry, events, media, camera and payload control, flight control, geospatial extension, security, conformance testing).
- JSON Schema 2020-12 definitions for the common types, telemetry, events, capabilities, commands, command status and the geospatial extension.
- OpenAPI 3.1 description of the ODIP v1 REST interface.
- Worked examples for telemetry, events, capabilities and commands.
tools/validate.pyand a CI workflow that runs it.