From 33c9902cc4a83e7f165311a9c28d6e845004b686 Mon Sep 17 00:00:00 2001 From: Gareth Sylvester-Bradley Date: Wed, 25 Feb 2026 10:08:12 +0000 Subject: [PATCH 01/20] Start with v1.1.x schemas --- .../schemas/activation-response-schema.json | 44 ++++ .../APIs/schemas/activation-schema.json | 35 ++++ .../schemas/bulk-receiver-post-schema.json | 24 +++ .../APIs/schemas/bulk-response-schema.json | 36 ++++ .../APIs/schemas/bulk-sender-post-schema.json | 24 +++ .../APIs/schemas/connectionapi-base.json | 16 ++ .../APIs/schemas/connectionapi-bulk.json | 16 ++ .../APIs/schemas/connectionapi-receiver.json | 18 ++ .../APIs/schemas/connectionapi-sender.json | 19 ++ .../APIs/schemas/connectionapi-single.json | 16 ++ .../APIs/schemas/constraint-schema.json | 62 ++++++ .../APIs/schemas/constraints-schema-mqtt.json | 43 ++++ .../APIs/schemas/constraints-schema-rtp.json | 81 ++++++++ .../schemas/constraints-schema-websocket.json | 23 +++ .../APIs/schemas/constraints-schema.json | 24 +++ .../is-05/v1.2.x/APIs/schemas/error.json | 27 +++ .../schemas/receiver-response-schema.json | 37 ++++ .../APIs/schemas/receiver-stage-schema.json | 30 +++ .../APIs/schemas/receiver-transport-file.json | 27 +++ .../schemas/receiver_transport_params.json | 30 +++ .../receiver_transport_params_dash.json | 3 + .../receiver_transport_params_ext.json | 11 + .../receiver_transport_params_mqtt.json | 83 ++++++++ .../receiver_transport_params_rtp.json | 152 ++++++++++++++ .../receiver_transport_params_websocket.json | 42 ++++ .../APIs/schemas/sender-receiver-base.json | 11 + .../APIs/schemas/sender-response-schema.json | 33 +++ .../APIs/schemas/sender-stage-schema.json | 27 +++ .../APIs/schemas/sender_transport_params.json | 30 +++ .../schemas/sender_transport_params_dash.json | 3 + .../schemas/sender_transport_params_ext.json | 11 + .../schemas/sender_transport_params_mqtt.json | 83 ++++++++ .../schemas/sender_transport_params_rtp.json | 191 ++++++++++++++++++ .../sender_transport_params_websocket.json | 45 +++++ .../transporttype-response-schema.json | 17 ++ 35 files changed, 1374 insertions(+) create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/activation-response-schema.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/activation-schema.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-receiver-post-schema.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-response-schema.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-sender-post-schema.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-base.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-bulk.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-receiver.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-sender.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-single.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/constraint-schema.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-mqtt.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-rtp.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-websocket.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/error.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-response-schema.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-stage-schema.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-transport-file.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_dash.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_ext.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mqtt.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_rtp.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_websocket.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/sender-receiver-base.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/sender-response-schema.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/sender-stage-schema.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_dash.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_ext.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mqtt.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_rtp.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_websocket.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/transporttype-response-schema.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/activation-response-schema.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/activation-response-schema.json new file mode 100644 index 000000000..5bb0f4f74 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/activation-response-schema.json @@ -0,0 +1,44 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Parameters concerned with activation of the transport parameters", + "type": "object", + "additionalProperties": false, + "required": [ + "mode", + "requested_time", + "activation_time" + ], + "properties": { + "mode": { + "description": "Mode of activation: immediate (on message receipt), scheduled_absolute (when internal clock >= requested_time), scheduled_relative (when internal clock >= time of message receipt + requested_time), or null (no activation scheduled). This parameter returns to null on the staged endpoint once an activation is completed or when it is explicitly set to null. For immediate activations, in the response to the PATCH request this field will be set to 'activate_immediate', but will be null in response to any subsequent GET requests.", + "anyOf": [{ + "type": "string", + "enum": [ + "activate_immediate", + "activate_scheduled_absolute", + "activate_scheduled_relative" + ] + }, { + "type": "null" + }] + }, + "requested_time": { + "description": "String formatted TAI timestamp (:) indicating time (absolute or relative) for activation requested. This field returns to null once the activation is completed on the staged endpoint or when the resource is unlocked by setting the activation mode to null. For an immediate activation this field will always be null on the staged endpoint, even in the response to the PATCH request.", + "anyOf": [{ + "type": "string", + "pattern": "^[0-9]+:[0-9]+$" + }, { + "type": "null" + }] + }, + "activation_time": { + "description": "String formatted TAI timestamp (:) indicating the absolute time the sender or receiver will or did actually activate for scheduled activations, or the time activation occurred for immediate activations. On the staged endpoint this field returns to null once the activation is completed or when the resource is unlocked by setting the activation mode to null. For immediate activations on the staged endpoint this property will be the time the activation actually occurred in the response to the PATCH request, but null in response to any GET requests thereafter.", + "anyOf": [{ + "type": "string", + "pattern": "^[0-9]+:[0-9]+$" + }, { + "type": "null" + }] + } + } +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/activation-schema.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/activation-schema.json new file mode 100644 index 000000000..27cefb795 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/activation-schema.json @@ -0,0 +1,35 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "title": "Activation resource", + "description": "Parameters concerned with activation of the transport parameters", + "type": "object", + "additionalProperties": false, + "required": [ + "mode" + ], + "properties": { + "mode": { + "description": "Mode of activation: immediate (on message receipt), scheduled_absolute (when internal clock >= requested_time), scheduled_relative (when internal clock >= time of message receipt + requested_time), or null (no activation scheduled)", + "anyOf": [{ + "type": "string", + "enum": [ + "activate_immediate", + "activate_scheduled_absolute", + "activate_scheduled_relative" + ] + }, { + "type": "null" + }] + }, + "requested_time": { + "description": "String formatted TAI timestamp (:) indicating time (absolute or relative) for activation. Should be null or not present if 'mode' is null.", + "anyOf": [{ + "type": "string", + "pattern": "^[0-9]+:[0-9]+$" + }, { + "type": "null" + }] + } + } +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-receiver-post-schema.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-receiver-post-schema.json new file mode 100644 index 000000000..4b9be73a2 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-receiver-post-schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "array", + "description": "Describes a bulk receiver update resource", + "title": "Bulk receiver resource", + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "params" + ], + "properties": { + "id": { + "description": "ID of the target receiver to apply parameters to", + "type": "string", + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + "params": { + "$ref": "receiver-stage-schema.json" + } + } + } +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-response-schema.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-response-schema.json new file mode 100644 index 000000000..46ab6d531 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-response-schema.json @@ -0,0 +1,36 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Describes a response to a bulk activation request", + "title": "Bulk activation response", + "type": "array", + "items": { + "type": "object", + "required": [ + "id", + "code" + ], + "properties": { + "id": { + "description": "ID of a device to be activated", + "type": "string", + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + "code": { + "description": "HTTP status code that would have resulted from an individual activation on this device", + "type": "integer", + "anyOf": [ + { "minimum": 200, "maximum": 299 }, + { "minimum": 400, "maximum": 599 } + ] + }, + "error": { + "description": "Human readable message which is suitable for user interface display, and helpful to the user. Only included if 'code' indicates an error state", + "type": "string" + }, + "debug": { + "description": "Debug information which may assist a programmer working with the API. Only included if 'code' indicates an error state", + "type": ["null", "string"] + } + } + } +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-sender-post-schema.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-sender-post-schema.json new file mode 100644 index 000000000..b5fb0dca0 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-sender-post-schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "array", + "description": "Describes a bulk sender update resource", + "title": "Bulk sender resource", + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "params" + ], + "properties": { + "id": { + "description": "ID of the target sender to apply parameters to", + "type": "string", + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + "params": { + "$ref": "sender-stage-schema.json" + } + } + } +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-base.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-base.json new file mode 100644 index 000000000..400106144 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-base.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "array", + "description": "Describes the Connection API base resource", + "title": "Connection API base resource", + "items": { + "type": "string", + "enum": [ + "bulk/", + "single/" + ] + }, + "minItems": 2, + "maxItems": 2, + "uniqueItems": true +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-bulk.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-bulk.json new file mode 100644 index 000000000..03fc8f778 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-bulk.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "array", + "description": "Describes the Connection API /bulk base resource", + "title": "Connection API /bulk base resource", + "items": { + "type": "string", + "enum": [ + "senders/", + "receivers/" + ] + }, + "minItems": 2, + "maxItems": 2, + "uniqueItems": true +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-receiver.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-receiver.json new file mode 100644 index 000000000..99cd2d347 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-receiver.json @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "array", + "description": "Describes the Connection API /single/receivers/{receiverId} base resource", + "title": "Connection API /single/receivers/{receiverId} base resource", + "items": { + "type": "string", + "enum": [ + "constraints/", + "staged/", + "active/", + "transporttype/" + ] + }, + "minItems": 4, + "maxItems": 4, + "uniqueItems": true +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-sender.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-sender.json new file mode 100644 index 000000000..8d072dbb7 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-sender.json @@ -0,0 +1,19 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "array", + "description": "Describes the Connection API /single/senders/{senderId} base resource", + "title": "Connection API /single/senders/{senderId} base resource", + "items": { + "type": "string", + "enum": [ + "constraints/", + "staged/", + "active/", + "transportfile/", + "transporttype/" + ] + }, + "minItems": 5, + "maxItems": 5, + "uniqueItems": true +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-single.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-single.json new file mode 100644 index 000000000..0d36e835f --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-single.json @@ -0,0 +1,16 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "array", + "description": "Describes the Connection API /single base resource", + "title": "Connection API /single base resource", + "items": { + "type": "string", + "enum": [ + "senders/", + "receivers/" + ] + }, + "minItems": 2, + "maxItems": 2, + "uniqueItems": true +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/constraint-schema.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/constraint-schema.json new file mode 100644 index 000000000..fb9631173 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/constraint-schema.json @@ -0,0 +1,62 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Definition of a single constraint record", + "title": "Constraint", + "definitions": { + "constraint": { + "type": "object", + "description": "The constraints for a single transport parameter", + "properties": { + "maximum": { + "description": "The inclusive maximum value the parameter can be set to", + "type": [ + "integer", + "number" + ] + }, + "minimum": { + "description": "The inclusive minimum value the parameter can be set to", + "type": [ + "integer", + "number" + ] + }, + "enum": { + "description": "An array of allowed values", + "type": "array", + "minItems": 1, + "uniqueItems": true, + "items": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "integer" + }, + { + "type": "null" + }, + { + "type": "number" + }, + { + "type": "string" + } + ] + } + }, + "pattern": { + "description": "A regex pattern that must be satisfied for this parameter", + "type": "string", + "format": "regex" + }, + "description": { + "description": "A human readable string describing the constraint (optional)", + "type": "string" + } + }, + "additionalProperties": false + } + } +} \ No newline at end of file diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-mqtt.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-mqtt.json new file mode 100644 index 000000000..1219dc19e --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-mqtt.json @@ -0,0 +1,43 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "description": "Used to express the dynamic constraints on MQTT transport parameters. These constraints may be set and changed at run time. Every transport parameter must have an entry, even if it is only an empty object.", + "required": [ + "broker_topic", + "broker_protocol", + "broker_authorization", + "connection_status_broker_topic" + ], + "additionalProperties": false, + "patternProperties": { + "^ext_[a-zA-Z0-9_]+$":{ + "$ref": "constraint-schema.json#/definitions/constraint" + } + }, + "properties": { + "destination_host": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "source_host": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "broker_topic": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "broker_protocol": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "broker_authorization": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "connection_status_broker_topic": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "source_port": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "destination_port": { + "$ref": "constraint-schema.json#/definitions/constraint" + } + } +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-rtp.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-rtp.json new file mode 100644 index 000000000..a20613be6 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-rtp.json @@ -0,0 +1,81 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "description": "Used to express the dynamic constraints on RTP transport parameters. These constraints may be set and changed at run time. Every transport parameter must have an entry, even if it is only an empty object.", + "required": [ + "source_ip", + "destination_port", + "rtp_enabled" + ], + "additionalProperties": false, + "patternProperties": { + "^ext_[a-zA-Z0-9_]+$":{ + "$ref": "constraint-schema.json#/definitions/constraint" + } + }, + "properties": { + "multicast_ip": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "destination_ip": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "destination_port": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "source_ip": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "interface_ip": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "source_port": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "fec_enabled": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "fec_destination_ip": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "fec_mode": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "fec_type": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "fec_block_width": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "fec_block_height": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "fec1D_destination_port": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "fec2D_destination_port": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "fec1D_source_port": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "fec2D_source_port": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "rtcp_enabled": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "rtcp_destination_ip": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "rtcp_destination_port": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "rtcp_source_port": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "rtp_enabled": { + "$ref": "constraint-schema.json#/definitions/constraint" + } + } +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-websocket.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-websocket.json new file mode 100644 index 000000000..cf3215eb8 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-websocket.json @@ -0,0 +1,23 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "description": "Used to express the dynamic constraints on WebSocket transport parameters. These constraints may be set and changed at run time. Every transport parameter must have an entry, even if it is only an empty object.", + "required": [ + "connection_uri", + "connection_authorization" + ], + "additionalProperties": false, + "patternProperties": { + "^ext_[a-zA-Z0-9_]+$":{ + "$ref": "constraint-schema.json#/definitions/constraint" + } + }, + "properties": { + "connection_uri": { + "$ref": "constraint-schema.json#/definitions/constraint" + }, + "connection_authorization": { + "$ref": "constraint-schema.json#/definitions/constraint" + } + } +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema.json new file mode 100644 index 000000000..d43a11db4 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Used to express the dynamic constraints on transport parameters. These constraints may be set and changed at run time. Parameters must also conform with constraints inferred from the specification. Every transport parameter must have an entry, even if it is only an empty object.", + "title": "Constraints", + "anyOf": [{ + "type": "array", + "items": { + "$ref": "constraints-schema-rtp.json" + } + }, + { + "type": "array", + "items": { + "$ref": "constraints-schema-websocket.json" + } + }, + { + "type": "array", + "items": { + "$ref": "constraints-schema-mqtt.json" + } + } + ] +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/error.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/error.json new file mode 100644 index 000000000..402147b52 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/error.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "description": "Describes the standard error response which is returned with HTTP codes 400 and above", + "title": "Error response", + "required": [ + "code", + "error", + "debug" + ], + "properties": { + "code": { + "description": "HTTP error code", + "type": "integer", + "minimum": 400, + "maximum": 599 + }, + "error": { + "description": "Human readable message which is suitable for user interface display, and helpful to the user", + "type": "string" + }, + "debug": { + "description": "Debug information which may assist a programmer working with the API", + "type": ["null", "string"] + } + } +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-response-schema.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-response-schema.json new file mode 100644 index 000000000..df3343fcf --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-response-schema.json @@ -0,0 +1,37 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "description": "Describes a receiver", + "title": "Receiver resource", + "additionalProperties": false, + "required": [ + "sender_id", + "master_enable", + "activation", + "transport_file", + "transport_params" + ], + "properties": { + "sender_id": { + "description": "ID of the Sender subscribed to by this Receiver. This will be null if the receiver has not been configured to receive anything, or if it is receiving from a non-NMOS sender.", + "type": [ + "string", + "null" + ], + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + "master_enable": { + "description": "Master on/off control for receiver", + "type": "boolean" + }, + "activation": { + "$ref": "activation-response-schema.json" + }, + "transport_file": { + "$ref": "receiver-transport-file.json" + }, + "transport_params": { + "$ref": "receiver_transport_params.json" + } + } +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-stage-schema.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-stage-schema.json new file mode 100644 index 000000000..301719123 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-stage-schema.json @@ -0,0 +1,30 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "description": "Describes a receiver", + "title": "Receiver resource", + "additionalProperties": false, + "properties": { + "sender_id": { + "description": "ID of the Sender subscribed to by this Receiver. This will be null if the receiver has not been configured to receive anything, or if it is receiving from a non-NMOS sender.", + "type": [ + "string", + "null" + ], + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + "master_enable": { + "description": "Master on/off control for receiver", + "type": "boolean" + }, + "activation": { + "$ref": "activation-schema.json" + }, + "transport_file": { + "$ref": "receiver-transport-file.json" + }, + "transport_params": { + "$ref": "receiver_transport_params.json" + } + } +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-transport-file.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-transport-file.json new file mode 100644 index 000000000..3c7be7c2e --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-transport-file.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "description": "Transport file parameters. 'data' and 'type' must both be strings or both be null. If 'type' is non-null 'data' is expected to contain a valid instance of the specified media type.", + "title": "Transport file", + "additionalProperties": false, + "required": [ + "data", + "type" + ], + "properties": { + "data": { + "description": "Content of the transport file", + "type": [ + "string", + "null" + ] + }, + "type": { + "description": "IANA assigned media type for file (e.g application/sdp)", + "type": [ + "string", + "null" + ] + } + } +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params.json new file mode 100644 index 000000000..3656ead3a --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params.json @@ -0,0 +1,30 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Transport-specific parameters. If this parameter is included in a client request it must include the same number of array elements (or 'legs') as specified in the constraints. If no changes are required to a specific leg it must be included as an empty object ({}).", + "title": "Receiver Transport Parameters", + "anyOf": [{ + "type": "array", + "items": { + "$ref": "receiver_transport_params_rtp.json" + } + }, + { + "type": "array", + "items": { + "$ref": "receiver_transport_params_dash.json" + } + }, + { + "type": "array", + "items": { + "$ref": "receiver_transport_params_websocket.json" + } + }, + { + "type": "array", + "items": { + "$ref": "receiver_transport_params_mqtt.json" + } + } + ] +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_dash.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_dash.json new file mode 100644 index 000000000..ca07e7fce --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_dash.json @@ -0,0 +1,3 @@ +{ + "not": {} +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_ext.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_ext.json new file mode 100644 index 000000000..9b0dbb9b5 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_ext.json @@ -0,0 +1,11 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Describes external Receiver transport parameters defined in other AMWA specifications. The constraints in this schema are minimum constraints, but may be further constrained at the constraints endpoint.", + "title": "External Receiver Transport Parameters", + "type":[ + "string", + "boolean", + "null", + "number" + ] +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mqtt.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mqtt.json new file mode 100644 index 000000000..84f6548b1 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mqtt.json @@ -0,0 +1,83 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Describes MQTT Receiver transport parameters. The constraints in this schema are minimum constraints, but may be further constrained at the constraints endpoint. MQTT Receivers must support all parameters in this schema.", + "title": "MQTT Receiver Transport Parameters", + "type": "object", + "title": "Receiver Input", + "properties": { + "source_host": { + "type": [ + "string", + "null" + ], + "description": "Hostname or IP hosting the MQTT broker. If the parameter is set to auto the Receiver should establish for itself which broker it should use, based on a discovery mechanism or its own internal configuration. A null value indicates that the Receiver has not yet been configured.", + "anyOf": [{ + "pattern": "^auto$" + }, + { + "format": "hostname" + }, + { + "format": "ipv4" + }, + { + "format": "ipv6" + }, + { + "type": "null" + } + ] + }, + "source_port": { + "type": [ + "integer", + "string" + ], + "description": "Source port for MQTT traffic. If the parameter is set to auto the Receiver should establish for itself which broker it should use, based on a discovery mechanism or its own internal configuration.", + "minimum": 1, + "maximum": 65535, + "pattern": "^auto$" + }, + "broker_protocol": { + "type": "string", + "description": "Indication of whether TLS is used for communication with the broker. 'mqtt' indicates operation without TLS, and 'secure-mqtt' indicates use of TLS. If the parameter is set to auto the Receiver should establish for itself which protocol it should use, based on a discovery mechanism or its own internal configuration.", + "enum": [ + "auto", + "mqtt", + "secure-mqtt" + ] + }, + "broker_authorization": { + "type": [ + "string", + "boolean" + ], + "description": "Indication of whether authorization is used for communication with the broker. If the parameter is set to auto the Receiver should establish for itself whether authorization should be used, based on a discovery mechanism or its own internal configuration.", + "enum": [ + "auto", + true, + false + ] + }, + "broker_topic": { + "type": [ + "string", + "null" + ], + "description": "The topic which MQTT messages will be received from via the MQTT broker. A null value indicates that the Receiver has not yet been configured." + }, + "connection_status_broker_topic": { + "type": [ + "string", + "null" + ], + "description": "The topic used for MQTT status messages such as MQTT Last Will which are received via the MQTT broker. A null value indicates that the Receiver has not yet been configured, or is not using a connection status topic." + } + }, + "patternProperties": { + "^ext_[a-zA-Z0-9_]+$": { + "$ref": "receiver_transport_params_ext.json" + } + }, + "additionalProperties": false +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_rtp.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_rtp.json new file mode 100644 index 000000000..ee119205c --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_rtp.json @@ -0,0 +1,152 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Describes RTP Receiver transport parameters. The constraints in this schema are minimum constraints, but may be further constrained at the constraints endpoint. Receivers must support at least the `source_ip`, `interface_ip`, `rtp_enabled` and `destination_port` parameters, and must support the `multicast_ip` parameter if they are capable of multicast operation. Receivers supporting FEC and/or RTCP must support parameters prefixed with `fec` and `rtcp` respectively.", + "title": "RTP Receiver Transport Parameters", + "type": "object", + "title": "Receiver Input", + "properties": { + "source_ip": { + "type": [ + "string", + "null" + ], + "description": "Source IP address of RTP packets in unicast mode, source filter for source specific multicast. A null value indicates that the source IP address has not been configured in unicast mode, or the Receiver is in any-source multicast mode.", + "anyOf": [{ + "format": "ipv4" + }, + { + "format": "ipv6" + }, + { + "type": "null" + } + ] + }, + "multicast_ip": { + "type": [ + "string", + "null" + ], + "description": "IP multicast group address used in multicast operation only. Should be set to null during unicast operation. A null value indicates the parameter has not been configured, or the receiver is operating in unicast mode.", + "anyOf": [{ + "format": "ipv4" + }, + { + "format": "ipv6" + }, + { + "type": "null" + } + ] + }, + "interface_ip": { + "type": "string", + "description": "IP address of the network interface the receiver should use. The receiver should provide an enum in the constraints endpoint, which should contain the available interface addresses. If set to auto in multicast mode the receiver should determine which interface to use for itself, for example by using the routing tables. The behaviour of auto is undefined in unicast mode, and controllers should supply a specific interface address.", + "anyOf": [{ + "format": "ipv4" + }, + { + "format": "ipv6" + }, + { + "pattern": "^auto$" + } + ] + }, + "destination_port": { + "type": [ + "integer", + "string" + ], + "description": "destination port for RTP packets (auto = 5004 by default)", + "minimum": 1, + "maximum": 65535, + "pattern": "^auto$" + }, + "fec_enabled": { + "type": "boolean", + "description": "FEC on/off" + }, + "fec_destination_ip": { + "type": "string", + "description": "May be used if NAT is being used at the destination (auto = multicast_ip (multicast mode) or interface_ip (unicast mode) by default)", + "anyOf": [{ + "format": "ipv4" + }, + { + "format": "ipv6" + }, + { + "pattern": "^auto$" + } + ] + }, + "fec_mode": { + "type": "string", + "description": "forward error correction mode to apply. (auto = highest available number of dimensions by default)", + "enum": [ + "auto", + "1D", + "2D" + ] + }, + "fec1D_destination_port": { + "type": [ + "integer", + "string" + ], + "description": "destination port for RTP Column FEC packets (auto = RTP destination_port + 2 by default)", + "minimum": 1, + "maximum": 65535, + "pattern": "^auto$" + }, + "fec2D_destination_port": { + "type": [ + "integer", + "string" + ], + "description": "destination port for RTP Row FEC packets (auto = RTP destination_port + 4 by default)", + "minimum": 1, + "maximum": 65535, + "pattern": "^auto$" + }, + "rtcp_destination_ip": { + "type": "string", + "description": "Destination IP address of RTCP packets (auto = multicast_ip (multicast mode) or interface_ip (unicast mode) by default)", + "anyOf": [{ + "format": "ipv4" + }, + { + "format": "ipv6" + }, + { + "pattern": "^auto$" + } + ] + }, + "rtcp_enabled": { + "type": "boolean", + "description": "RTCP on/off" + }, + "rtcp_destination_port": { + "type": [ + "integer", + "string" + ], + "description": "destination port for RTCP packets (auto = RTP destination_port + 1 by default)", + "minimum": 1, + "maximum": 65535, + "pattern": "^auto$" + }, + "rtp_enabled": { + "type": "boolean", + "description": "RTP reception active/inactive" + } + }, + "patternProperties": { + "^ext_[a-zA-Z0-9_]+$": { + "$ref": "receiver_transport_params_ext.json" + } + }, + "additionalProperties": false +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_websocket.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_websocket.json new file mode 100644 index 000000000..38f168143 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_websocket.json @@ -0,0 +1,42 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Describes WebSocket Receiver transport parameters. The constraints in this schema are minimum constraints, but may be further constrained at the constraints endpoint. WebSocket Receivers must support all parameters in this schema.", + "title": "WebSocket Receiver Transport Parameters", + "type": "object", + "title": "Receiver Input", + "properties": { + "connection_uri": { + "type": [ + "string", + "null" + ], + "description": "URI hosting the WebSocket server as defined in RFC 6455 Section 3. A null value indicates that the receiver has not yet been configured.", + "anyOf": [{ + "format": "uri", + "pattern": "^wss?:\/\/.*" + }, + { + "type": "null" + } + ] + }, + "connection_authorization": { + "type": [ + "string", + "boolean" + ], + "description": "Indication of whether authorization is required to make a connection. If the parameter is set to auto the Receiver should establish for itself whether authorization should be used, based on its own internal configuration.", + "enum": [ + "auto", + true, + false + ] + } + }, + "patternProperties": { + "^ext_[a-zA-Z0-9_]+$": { + "$ref": "receiver_transport_params_ext.json" + } + }, + "additionalProperties": false +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender-receiver-base.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender-receiver-base.json new file mode 100644 index 000000000..942bf0d86 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender-receiver-base.json @@ -0,0 +1,11 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "array", + "description": "Describes the Connection API sender/receiver base resource", + "title": "Connection API sender/receiver base resource", + "items": { + "type": "string", + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/$" + }, + "uniqueItems": true +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender-response-schema.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender-response-schema.json new file mode 100644 index 000000000..958bc40db --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender-response-schema.json @@ -0,0 +1,33 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "description": "Describes a sender", + "title": "Sender resource", + "additionalProperties": false, + "required": [ + "receiver_id", + "master_enable", + "activation", + "transport_params" + ], + "properties": { + "receiver_id": { + "description": "ID of the target Receiver of this Sender. This will be null if the sender is operating in multicast mode, or has not been assigned a receiver in unicast mode, or is sending to a non-NMOS receiver in unicast mode.", + "type": [ + "string", + "null" + ], + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + "master_enable": { + "description": "Master on/off control for sender", + "type": "boolean" + }, + "activation": { + "$ref": "activation-response-schema.json" + }, + "transport_params": { + "$ref": "sender_transport_params.json" + } + } +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender-stage-schema.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender-stage-schema.json new file mode 100644 index 000000000..6afc2dd22 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender-stage-schema.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "description": "Describes a sender", + "title": "Sender resource", + "additionalProperties": false, + "properties": { + "receiver_id": { + "description": "ID of the target Receiver of this Sender. This will be null if the sender is operating in multicast mode, or has not been assigned a receiver in unicast mode, or is sending to a non-NMOS receiver in unicast mode.", + "type": [ + "string", + "null" + ], + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + "master_enable": { + "description": "Master on/off control for sender", + "type": "boolean" + }, + "activation": { + "$ref": "activation-schema.json" + }, + "transport_params": { + "$ref": "sender_transport_params.json" + } + } +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params.json new file mode 100644 index 000000000..226ba4b5a --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params.json @@ -0,0 +1,30 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Transport-specific parameters. If this parameter is included in a client request it must include the same number of array elements (or 'legs') as specified in the constraints. If no changes are required to a specific leg it must be included as an empty object ({}).", + "title": "Sender Transport Parameters", + "anyOf": [{ + "type": "array", + "items": { + "$ref": "sender_transport_params_rtp.json" + } + }, + { + "type": "array", + "items": { + "$ref": "sender_transport_params_dash.json" + } + }, + { + "type": "array", + "items": { + "$ref": "sender_transport_params_websocket.json" + } + }, + { + "type": "array", + "items": { + "$ref": "sender_transport_params_mqtt.json" + } + } + ] +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_dash.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_dash.json new file mode 100644 index 000000000..ca07e7fce --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_dash.json @@ -0,0 +1,3 @@ +{ + "not": {} +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_ext.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_ext.json new file mode 100644 index 000000000..8209fd754 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_ext.json @@ -0,0 +1,11 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Describes external Sender transport parameters defined in other AMWA specifications. The constraints in this schema are minimum constraints, but may be further constrained at the constraints endpoint.", + "title": "External Sender Transport Parameters", + "type":[ + "string", + "boolean", + "null", + "number" + ] +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mqtt.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mqtt.json new file mode 100644 index 000000000..a7e98074d --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mqtt.json @@ -0,0 +1,83 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Describes MQTT Sender transport parameters. The constraints in this schema are minimum constraints, but may be further constrained at the constraints endpoint. MQTT Senders must support all properties in this schema.", + "title": "MQTT Sender Transport Parameters", + "type": "object", + "title": "Sender Output", + "properties": { + "destination_host": { + "type": [ + "string", + "null" + ], + "description": "Hostname or IP hosting the MQTT broker. If the parameter is set to auto the Sender should establish for itself which broker it should use, based on a discovery mechanism or its own internal configuration. A null value indicates that the Sender has not yet been configured.", + "anyOf": [{ + "pattern": "^auto$" + }, + { + "format": "hostname" + }, + { + "format": "ipv4" + }, + { + "format": "ipv6" + }, + { + "type": "null" + } + ] + }, + "destination_port": { + "type": [ + "integer", + "string" + ], + "description": "Destination port for MQTT traffic. If the parameter is set to auto the Sender should establish for itself which broker it should use, based on a discovery mechanism or its own internal configuration.", + "minimum": 1, + "maximum": 65535, + "pattern": "^auto$" + }, + "broker_protocol": { + "type": "string", + "description": "Indication of whether TLS is used for communication with the broker. 'mqtt' indicates operation without TLS, and 'secure-mqtt' indicates use of TLS. If the parameter is set to auto the Sender should establish for itself which protocol it should use, based on a discovery mechanism or its own internal configuration.", + "enum": [ + "auto", + "mqtt", + "secure-mqtt" + ] + }, + "broker_authorization": { + "type": [ + "string", + "boolean" + ], + "description": "Indication of whether authorization is used for communication with the broker. If the parameter is set to auto the Sender should establish for itself whether authorization should be used, based on a discovery mechanism or its own internal configuration.", + "enum": [ + "auto", + true, + false + ] + }, + "broker_topic": { + "type": [ + "string", + "null" + ], + "description": "The topic which MQTT messages will be sent to on the MQTT broker. A null value indicates that the Sender has not yet been configured." + }, + "connection_status_broker_topic": { + "type": [ + "string", + "null" + ], + "description": "The topic which MQTT status messages such as MQTT Last Will are sent to on the MQTT broker. A null value indicates that the Sender has not yet been configured, or is not using a connection status topic." + } + }, + "patternProperties": { + "^ext_[a-zA-Z0-9_]+$": { + "$ref": "sender_transport_params_ext.json" + } + }, + "additionalProperties": false +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_rtp.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_rtp.json new file mode 100644 index 000000000..b849b9b7b --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_rtp.json @@ -0,0 +1,191 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Describes RTP Sender transport parameters. The constraints in this schema are minimum constraints, but may be further constrained at the constraints endpoint. As a minimum all senders must support `source_ip`, `destination_ip`, `source_port`, `rtp_enabled` and `destination_port`. Senders supporting FEC and/or RTCP must support parameters prefixed with `fec` and `rtcp` respectively.", + "title": "RTP Sender Transport Parameters", + "type": "object", + "title": "Sender Output", + "properties": { + "source_ip": { + "type": "string", + "description": "IP address from which RTP packets will be sent (IP address of interface bound to this output). The sender should provide an enum in the constraints endpoint, which should contain the available interface addresses. If the parameter is set to auto the sender should establish for itself which interface it should use, based on routing rules or its own internal configuration.", + "anyOf": [{ + "format": "ipv4" + }, + { + "format": "ipv6" + }, + { + "pattern": "^auto$" + } + ] + }, + "destination_ip": { + "type": "string", + "description": "IP address to which RTP packets will be sent. If auto is set the sender should select a multicast address to send to itself. For example it may implement MADCAP (RFC 2730), ZMAAP, or be allocated address by some other system responsible for co-ordination multicast address use.", + "anyOf": [{ + "format": "ipv4" + }, + { + "format": "ipv6" + }, + { + "pattern": "^auto$" + } + ] + }, + "source_port": { + "type": [ + "integer", + "string" + ], + "description": "source port for RTP packets (auto = 5004 by default)", + "minimum": 0, + "maximum": 65535, + "pattern": "^auto$" + }, + "destination_port": { + "type": [ + "integer", + "string" + ], + "description": "destination port for RTP packets (auto = 5004 by default)", + "minimum": 1, + "maximum": 65535, + "pattern": "^auto$" + }, + "fec_enabled": { + "type": "boolean", + "description": "FEC on/off" + }, + "fec_destination_ip": { + "type": "string", + "description": "May be used if NAT is being used at the destination (auto = destination_ip by default)", + "anyOf": [{ + "format": "ipv4" + }, + { + "format": "ipv6" + }, + { + "pattern": "^auto$" + } + ] + }, + "fec_type": { + "type": "string", + "description": "forward error correction mode to apply", + "enum": [ + "XOR", + "Reed-Solomon" + ] + }, + "fec_mode": { + "type": "string", + "description": "forward error correction mode to apply", + "enum": [ + "1D", + "2D" + ] + }, + "fec_block_width": { + "type": "integer", + "description": "width of block over which FEC is calculated in packets", + "minimum": 4, + "maximum": 200 + }, + "fec_block_height": { + "type": "integer", + "description": "height of block over which FEC is calculated in packets", + "minimum": 4, + "maximum": 200 + }, + "fec1D_destination_port": { + "type": [ + "integer", + "string" + ], + "description": "destination port for RTP Column FEC packets (auto = RTP destination_port + 2 by default)", + "minimum": 1, + "maximum": 65535, + "pattern": "^auto$" + }, + "fec2D_destination_port": { + "type": [ + "integer", + "string" + ], + "description": "destination port for RTP Row FEC packets (auto = RTP destination_port + 4 by default)", + "minimum": 1, + "maximum": 65535, + "pattern": "^auto$" + }, + "fec1D_source_port": { + "type": [ + "integer", + "string" + ], + "description": "source port for RTP FEC packets (auto = RTP source_port + 2 by default)", + "minimum": 0, + "maximum": 65535, + "pattern": "^auto$" + }, + "fec2D_source_port": { + "type": [ + "integer", + "string" + ], + "description": "source port for RTP FEC packets (auto = RTP source_port + 4 by default)", + "minimum": 0, + "maximum": 65535, + "pattern": "^auto$" + }, + "rtcp_enabled": { + "type": "boolean", + "description": "rtcp on/off" + }, + "rtcp_destination_ip": { + "type": "string", + "description": "IP address to which RTCP packets will be sent (auto = same as RTP destination_ip by default)", + "anyOf": [{ + "format": "ipv4" + }, + { + "format": "ipv6" + }, + { + "pattern": "^auto$" + } + ] + }, + "rtcp_destination_port": { + "type": [ + "integer", + "string" + ], + "description": "destination port for RTCP packets (auto = RTP destination_port + 1 by default)", + "minimum": 1, + "maximum": 65535, + "pattern": "^auto$" + }, + "rtcp_source_port": { + "type": [ + "integer", + "string" + ], + "description": "source port for RTCP packets (auto = RTP source_port + 1 by default)", + "minimum": 0, + "maximum": 65535, + "pattern": "^auto$" + }, + "rtp_enabled": { + "type": "boolean", + "description": "RTP transmission active/inactive" + } + }, + "patternProperties": { + "^ext_[a-zA-Z0-9_]+$": { + "$ref": "sender_transport_params_ext.json" + } + }, + "additionalProperties": false +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_websocket.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_websocket.json new file mode 100644 index 000000000..65c187f28 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_websocket.json @@ -0,0 +1,45 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Describes WebSocket Sender transport parameters. The constraints in this schema are minimum constraints, but may be further constrained at the constraints endpoint. WebSocket Senders must support all parameters in this schema.", + "title": "WebSocket Sender Transport Parameters", + "type": "object", + "title": "Sender Output", + "properties": { + "connection_uri": { + "type": [ + "string", + "null" + ], + "description": "URI hosting the WebSocket server as defined in RFC 6455 Section 3. The sender should provide an enum in the constraints endpoint, which should contain the available interface addresses formatted as connection URIs. If the parameter is set to auto the sender should establish for itself which interface it should use, based on routing rules or its own internal configuration. A null value indicates that the sender has not yet been configured.", + "anyOf": [{ + "pattern": "^auto$" + }, + { + "format": "uri", + "pattern": "^wss?:\/\/.*" + }, + { + "type": "null" + } + ] + }, + "connection_authorization": { + "type": [ + "string", + "boolean" + ], + "description": "Indication of whether authorization is required to make a connection. If the parameter is set to auto the Sender should establish for itself whether authorization should be used, based on its own internal configuration.", + "enum": [ + "auto", + true, + false + ] + } + }, + "patternProperties": { + "^ext_[a-zA-Z0-9_]+$": { + "$ref": "sender_transport_params_ext.json" + } + }, + "additionalProperties": false +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/transporttype-response-schema.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/transporttype-response-schema.json new file mode 100644 index 000000000..77ce38fd3 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/transporttype-response-schema.json @@ -0,0 +1,17 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Transport Type", + "description": "Transport type URN base used by the Sender or Receiver (i.e. with any subclassifications or versions removed)", + "type": "string", + "oneOf": [ + { + "enum": [ + "urn:x-nmos:transport:rtp", + "urn:x-nmos:transport:dash", + "urn:x-nmos:transport:websocket", + "urn:x-nmos:transport:mqtt" + ] + } + ], + "format": "uri" +} From 7f4d4a6a244bb3d326b222728e36404b66cfce29 Mon Sep 17 00:00:00 2001 From: Gareth Sylvester-Bradley Date: Wed, 25 Feb 2026 10:10:29 +0000 Subject: [PATCH 02/20] Add schema changes for MXL as a built-in transport --- .../schemas/receiver_transport_params.json | 6 ++++ .../receiver_transport_params_mxl.json | 29 +++++++++++++++++++ .../APIs/schemas/sender_transport_params.json | 6 ++++ .../schemas/sender_transport_params_mxl.json | 29 +++++++++++++++++++ .../transporttype-response-schema.json | 3 +- 5 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json create mode 100644 Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params.json index 3656ead3a..b6c9aa6dc 100644 --- a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params.json +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params.json @@ -25,6 +25,12 @@ "items": { "$ref": "receiver_transport_params_mqtt.json" } + }, + { + "type": "array", + "items": { + "$ref": "receiver_transport_params_mxl.json" + } } ] } diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json new file mode 100644 index 000000000..31bcda06b --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json @@ -0,0 +1,29 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Describes MXL Receiver transport parameters. The constraints in this schema are minimum constraints, but may be further constrained at the constraints endpoint.", + "title": "MXL Receiver Transport Parameters", + "type": "object", + "properties": { + "flow_id": { + "type": [ + "string", + "null" + ], + "description": "ID of the Flow to read.", + "anyOf": [{ + "type": "string", + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + { + "type": "null" + } + ] + } + }, + "patternProperties": { + "^ext_[a-zA-Z0-9_]+$": { + "$ref": "receiver_transport_params_ext.json" + } + }, + "additionalProperties": false +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params.json index 226ba4b5a..c8d0d7586 100644 --- a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params.json +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params.json @@ -25,6 +25,12 @@ "items": { "$ref": "sender_transport_params_mqtt.json" } + }, + { + "type": "array", + "items": { + "$ref": "sender_transport_params_mxl.json" + } } ] } diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json new file mode 100644 index 000000000..d059b7f3c --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json @@ -0,0 +1,29 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "description": "Describes MXL Sender transport parameters. The constraints in this schema are minimum constraints, but may be further constrained at the constraints endpoint.", + "title": "MXL Sender Transport Parameters", + "type": "object", + "properties": { + "flow_id": { + "type": [ + "string", + "null" + ], + "description": "ID of the Flow to write.", + "anyOf": [{ + "type": "string", + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + { + "type": "null" + } + ] + } + }, + "patternProperties": { + "^ext_[a-zA-Z0-9_]+$": { + "$ref": "sender_transport_params_ext.json" + } + }, + "additionalProperties": false +} diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/transporttype-response-schema.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/transporttype-response-schema.json index 77ce38fd3..6a3f1a346 100644 --- a/Development/third_party/is-05/v1.2.x/APIs/schemas/transporttype-response-schema.json +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/transporttype-response-schema.json @@ -9,7 +9,8 @@ "urn:x-nmos:transport:rtp", "urn:x-nmos:transport:dash", "urn:x-nmos:transport:websocket", - "urn:x-nmos:transport:mqtt" + "urn:x-nmos:transport:mqtt", + "urn:x-nmos:transport:mxl" ] } ], From f28ca6a0a33deec601138adf0023e36619a56944 Mon Sep 17 00:00:00 2001 From: lo-simon Date: Wed, 25 Feb 2026 11:18:23 +0000 Subject: [PATCH 03/20] Add IS-05 schema cpp generation --- Development/cmake/NmosCppLibraries.cmake | 46 +++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/Development/cmake/NmosCppLibraries.cmake b/Development/cmake/NmosCppLibraries.cmake index ca49cd857..982e000b0 100644 --- a/Development/cmake/NmosCppLibraries.cmake +++ b/Development/cmake/NmosCppLibraries.cmake @@ -407,9 +407,50 @@ set(NMOS_IS05_SCHEMAS_HEADERS nmos/is05_schemas/is05_schemas.h ) +set(NMOS_IS05_V1_2_TAG v1.2.x) set(NMOS_IS05_V1_1_TAG v1.1.x) set(NMOS_IS05_V1_0_TAG v1.0.x) +set(NMOS_IS05_V1_2_SCHEMAS_JSON + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/activation-response-schema.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/activation-schema.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/bulk-receiver-post-schema.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/bulk-response-schema.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/bulk-sender-post-schema.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/connectionapi-base.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/connectionapi-bulk.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/connectionapi-receiver.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/connectionapi-sender.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/connectionapi-single.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/constraint-schema.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/constraints-schema.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/constraints-schema-mqtt.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/constraints-schema-rtp.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/constraints-schema-websocket.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/error.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/receiver_transport_params.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/receiver_transport_params_dash.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/receiver_transport_params_ext.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/receiver_transport_params_mqtt.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/receiver_transport_params_mxl.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/receiver_transport_params_rtp.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/receiver_transport_params_websocket.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/receiver-response-schema.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/receiver-stage-schema.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/receiver-transport-file.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/sender_transport_params.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/sender_transport_params_dash.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/sender_transport_params_ext.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/sender_transport_params_mqtt.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/sender_transport_params_mxl.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/sender_transport_params_rtp.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/sender_transport_params_websocket.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/sender-receiver-base.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/sender-response-schema.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/sender-stage-schema.json + third_party/is-05/${NMOS_IS05_V1_2_TAG}/APIs/schemas/transporttype-response-schema.json + ) + set(NMOS_IS05_V1_1_SCHEMAS_JSON third_party/is-05/${NMOS_IS05_V1_1_TAG}/APIs/schemas/activation-response-schema.json third_party/is-05/${NMOS_IS05_V1_1_TAG}/APIs/schemas/activation-schema.json @@ -474,10 +515,11 @@ set(NMOS_IS05_V1_0_SCHEMAS_JSON set(NMOS_IS05_SCHEMAS_JSON_MATCH "third_party/is-05/([^/]+)/APIs/schemas/([^;]+)\\.json") set(NMOS_IS05_SCHEMAS_SOURCE_REPLACE "${CMAKE_CURRENT_BINARY_DIR_REPLACE}/nmos/is05_schemas/\\1/\\2.cpp") +string(REGEX REPLACE "${NMOS_IS05_SCHEMAS_JSON_MATCH}(;|$)" "${NMOS_IS05_SCHEMAS_SOURCE_REPLACE}\\3" NMOS_IS05_V1_2_SCHEMAS_SOURCES "${NMOS_IS05_V1_2_SCHEMAS_JSON}") string(REGEX REPLACE "${NMOS_IS05_SCHEMAS_JSON_MATCH}(;|$)" "${NMOS_IS05_SCHEMAS_SOURCE_REPLACE}\\3" NMOS_IS05_V1_1_SCHEMAS_SOURCES "${NMOS_IS05_V1_1_SCHEMAS_JSON}") string(REGEX REPLACE "${NMOS_IS05_SCHEMAS_JSON_MATCH}(;|$)" "${NMOS_IS05_SCHEMAS_SOURCE_REPLACE}\\3" NMOS_IS05_V1_0_SCHEMAS_SOURCES "${NMOS_IS05_V1_0_SCHEMAS_JSON}") -foreach(JSON ${NMOS_IS05_V1_1_SCHEMAS_JSON} ${NMOS_IS05_V1_0_SCHEMAS_JSON}) +foreach(JSON ${NMOS_IS05_V1_2_SCHEMAS_JSON} ${NMOS_IS05_V1_1_SCHEMAS_JSON} ${NMOS_IS05_V1_0_SCHEMAS_JSON}) string(REGEX REPLACE "${NMOS_IS05_SCHEMAS_JSON_MATCH}" "${NMOS_IS05_SCHEMAS_SOURCE_REPLACE}" SOURCE "${JSON}") string(REGEX REPLACE "${NMOS_IS05_SCHEMAS_JSON_MATCH}" "\\1" NS "${JSON}") string(REGEX REPLACE "${NMOS_IS05_SCHEMAS_JSON_MATCH}" "\\2" VAR "${JSON}") @@ -509,11 +551,13 @@ endforeach() add_library( nmos_is05_schemas STATIC ${NMOS_IS05_SCHEMAS_HEADERS} + ${NMOS_IS05_V1_2_SCHEMAS_SOURCES} ${NMOS_IS05_V1_1_SCHEMAS_SOURCES} ${NMOS_IS05_V1_0_SCHEMAS_SOURCES} ) source_group("nmos\\is05_schemas\\Header Files" FILES ${NMOS_IS05_SCHEMAS_HEADERS}) +source_group("nmos\\is05_schemas\\${NMOS_IS05_V1_2_TAG}\\Source Files" FILES ${NMOS_IS05_V1_2_SCHEMAS_SOURCES}) source_group("nmos\\is05_schemas\\${NMOS_IS05_V1_1_TAG}\\Source Files" FILES ${NMOS_IS05_V1_1_SCHEMAS_SOURCES}) source_group("nmos\\is05_schemas\\${NMOS_IS05_V1_0_TAG}\\Source Files" FILES ${NMOS_IS05_V1_0_SCHEMAS_SOURCES}) From d0c600e8016208aa53422f51bfe804e13207cf17 Mon Sep 17 00:00:00 2001 From: Gareth Sylvester-Bradley Date: Wed, 25 Feb 2026 11:12:38 +0000 Subject: [PATCH 04/20] Add IS-05 v1.2 as copy of IS-05 v1.1 --- Development/nmos/is05_schemas/is05_schemas.h | 20 ++++++++++++++ Development/nmos/is05_versions.h | 3 +- Development/nmos/json_schema.cpp | 29 ++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/Development/nmos/is05_schemas/is05_schemas.h b/Development/nmos/is05_schemas/is05_schemas.h index 4550dbe77..5430ede77 100644 --- a/Development/nmos/is05_schemas/is05_schemas.h +++ b/Development/nmos/is05_schemas/is05_schemas.h @@ -7,6 +7,26 @@ namespace nmos { namespace is05_schemas { + namespace v1_2_x + { + extern const char* activation_schema; + extern const char* sender_stage_schema; + extern const char* sender_transport_params; + extern const char* sender_transport_params_rtp; + extern const char* sender_transport_params_dash; + extern const char* sender_transport_params_websocket; + extern const char* sender_transport_params_mqtt; + extern const char* sender_transport_params_ext; + extern const char* receiver_stage_schema; + extern const char* receiver_transport_file; + extern const char* receiver_transport_params; + extern const char* receiver_transport_params_rtp; + extern const char* receiver_transport_params_dash; + extern const char* receiver_transport_params_websocket; + extern const char* receiver_transport_params_mqtt; + extern const char* receiver_transport_params_ext; + } + namespace v1_1_x { extern const char* activation_schema; diff --git a/Development/nmos/is05_versions.h b/Development/nmos/is05_versions.h index dfb39a527..4ed870ce9 100644 --- a/Development/nmos/is05_versions.h +++ b/Development/nmos/is05_versions.h @@ -12,8 +12,9 @@ namespace nmos { const api_version v1_0{ 1, 0 }; const api_version v1_1{ 1, 1 }; + const api_version v1_2{ 1, 2 }; - const std::set all{ nmos::is05_versions::v1_0, nmos::is05_versions::v1_1 }; + const std::set all{ nmos::is05_versions::v1_0, nmos::is05_versions::v1_1, nmos::is05_versions::v1_2 }; inline std::set from_settings(const nmos::settings& settings) { diff --git a/Development/nmos/json_schema.cpp b/Development/nmos/json_schema.cpp index 3860509ca..d08668d6a 100644 --- a/Development/nmos/json_schema.cpp +++ b/Development/nmos/json_schema.cpp @@ -77,6 +77,16 @@ namespace nmos return{ _XPLATSTR("https://github.com/AMWA-TV/is-05/raw/") + tag + _XPLATSTR("/APIs/schemas/") + ref }; } + // See https://github.com/AMWA-TV/is-05/blob/v1.2.x/APIs/schemas/ + namespace v1_2 + { + using namespace nmos::is05_schemas::v1_2_x; + const utility::string_t tag(_XPLATSTR("v1.2.x")); + + const web::uri connectionapi_sender_staged_patch_request_uri = make_schema_uri(tag, _XPLATSTR("sender-stage-schema.json")); + const web::uri connectionapi_receiver_staged_patch_request_uri = make_schema_uri(tag, _XPLATSTR("receiver-stage-schema.json")); + } + // See https://github.com/AMWA-TV/is-05/blob/v1.1.x/APIs/schemas/ namespace v1_1 { @@ -323,6 +333,23 @@ namespace nmos return { + // v1.2 + { make_schema_uri(v1_2::tag, _XPLATSTR("sender-stage-schema.json")), make_schema(v1_2::sender_stage_schema) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("receiver-stage-schema.json")), make_schema(v1_2::receiver_stage_schema) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("receiver-transport-file.json")), make_schema(v1_2::receiver_transport_file) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("activation-schema.json")), make_schema(v1_2::activation_schema) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("sender_transport_params.json")), make_schema(v1_2::sender_transport_params) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("sender_transport_params_rtp.json")), make_schema(v1_2::sender_transport_params_rtp) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("sender_transport_params_dash.json")), make_schema(v1_2::sender_transport_params_dash) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("sender_transport_params_websocket.json")), make_schema(v1_2::sender_transport_params_websocket) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("sender_transport_params_mqtt.json")), make_schema(v1_2::sender_transport_params_mqtt) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("sender_transport_params_ext.json")), make_schema(v1_2::sender_transport_params_ext) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("receiver_transport_params.json")), make_schema(v1_2::receiver_transport_params) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("receiver_transport_params_rtp.json")), make_schema(v1_2::receiver_transport_params_rtp) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("receiver_transport_params_dash.json")), make_schema(v1_2::receiver_transport_params_dash) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("receiver_transport_params_websocket.json")), make_schema(v1_2::receiver_transport_params_websocket) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("receiver_transport_params_mqtt.json")), make_schema(v1_2::receiver_transport_params_mqtt) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("receiver_transport_params_ext.json")), make_schema(v1_2::receiver_transport_params_ext) }, // v1.1 { make_schema_uri(v1_1::tag, _XPLATSTR("sender-stage-schema.json")), make_schema(v1_1::sender_stage_schema) }, { make_schema_uri(v1_1::tag, _XPLATSTR("receiver-stage-schema.json")), make_schema(v1_1::receiver_stage_schema) }, @@ -487,12 +514,14 @@ namespace nmos web::uri make_connectionapi_sender_staged_patch_request_schema_uri(const nmos::api_version& version) { + if (is05_versions::v1_2 <= version) return is05_schemas::v1_2::connectionapi_sender_staged_patch_request_uri; if (is05_versions::v1_1 <= version) return is05_schemas::v1_1::connectionapi_sender_staged_patch_request_uri; return is05_schemas::v1_0::connectionapi_sender_staged_patch_request_uri; } web::uri make_connectionapi_receiver_staged_patch_request_schema_uri(const nmos::api_version& version) { + if (is05_versions::v1_2 <= version) return is05_schemas::v1_2::connectionapi_receiver_staged_patch_request_uri; if (is05_versions::v1_1 <= version) return is05_schemas::v1_1::connectionapi_receiver_staged_patch_request_uri; return is05_schemas::v1_0::connectionapi_receiver_staged_patch_request_uri; } From 19db280004b21d517f2224bc1f791db551dd6ebd Mon Sep 17 00:00:00 2001 From: Gareth Sylvester-Bradley Date: Wed, 25 Feb 2026 11:18:23 +0000 Subject: [PATCH 05/20] Add MXL senders and receivers --- Development/nmos/connection_api.cpp | 4 + Development/nmos/connection_resources.cpp | 87 ++++++++++++++++++++ Development/nmos/connection_resources.h | 3 + Development/nmos/is05_schemas/is05_schemas.h | 2 + Development/nmos/json_fields.h | 2 + Development/nmos/json_schema.cpp | 2 + Development/nmos/transport.h | 2 + 7 files changed, 102 insertions(+) diff --git a/Development/nmos/connection_api.cpp b/Development/nmos/connection_api.cpp index eb63bcafb..83cdd641b 100644 --- a/Development/nmos/connection_api.cpp +++ b/Development/nmos/connection_api.cpp @@ -86,6 +86,9 @@ namespace nmos }, { nmos::is05_versions::v1_1, { nmos::transports::websocket, nmos::transports::mqtt } + }, + { + nmos::is05_versions::v1_2, { nmos::transports::mxl } } }; @@ -245,6 +248,7 @@ namespace nmos if (nmos::transports::rtp == transport_base) return rtp_auto_constraints(); if (nmos::transports::websocket == transport_base) return websocket_auto_constraints(); if (nmos::transports::mqtt == transport_base) return mqtt_auto_constraints(); + //if (nmos::transports::mxl == transport_base) return mxl_auto_constraints(); static const std::map> no_auto_constraints; return no_auto_constraints; diff --git a/Development/nmos/connection_resources.cpp b/Development/nmos/connection_resources.cpp index 79d81a7e9..acdee5735 100644 --- a/Development/nmos/connection_resources.cpp +++ b/Development/nmos/connection_resources.cpp @@ -612,4 +612,91 @@ namespace nmos // See https://specs.amwa.tv/is-07/releases/v1.0.1/docs/5.1._Transport_-_MQTT.html#33-connection_status_broker_topic return U("x-nmos/events/") + make_api_version(version) + U("/connections/") + connection_id; } + + namespace details + { + web::json::value make_connection_mxl_sender_core_constraints() + { + using web::json::value; + using web::json::value_of; + + const auto unconstrained = value::object(); + return value_of({ + { nmos::fields::flow_id, unconstrained } + }); + } + + web::json::value make_connection_mxl_sender_staged_core_parameter_set() + { + using web::json::value; + using web::json::value_of; + + return value_of({ + { nmos::fields::flow_id, value::null() } + }); + } + + web::json::value make_connection_mxl_receiver_core_constraints() + { + using web::json::value; + using web::json::value_of; + + const auto unconstrained = value::object(); + return value_of({ + { nmos::fields::flow_id, unconstrained } + }); + } + + web::json::value make_connection_mxl_receiver_staged_core_parameter_set() + { + using web::json::value; + using web::json::value_of; + + return value_of({ + { nmos::fields::flow_id, value::null() } + }); + } + } + + nmos::resource make_connection_mxl_sender(const nmos::id& id) + { + using web::json::value; + using web::json::value_of; + + const auto redundant = false; + + auto data = details::make_connection_resource_core(id, redundant); + + data[nmos::fields::endpoint_constraints] = details::legs_of(details::make_connection_mxl_sender_core_constraints(), redundant); + + data[nmos::fields::endpoint_staged][nmos::fields::receiver_id] = value::null(); + data[nmos::fields::endpoint_staged][nmos::fields::transport_params] = details::legs_of(details::make_connection_mxl_sender_staged_core_parameter_set(), redundant); + + data[nmos::fields::endpoint_active] = data[nmos::fields::endpoint_staged]; + + // Note that the transporttype endpoint is implemented in terms of the matching IS-04 sender + + return{ is05_versions::v1_2, types::sender, std::move(data), false }; + } + + nmos::resource make_connection_mxl_receiver(const nmos::id& id) + { + using web::json::value; + + const auto redundant = false; + + auto data = details::make_connection_resource_core(id, redundant); + + data[nmos::fields::endpoint_constraints] = details::legs_of(details::make_connection_mxl_receiver_core_constraints(), redundant); + + data[nmos::fields::endpoint_staged][nmos::fields::sender_id] = value::null(); + data[nmos::fields::endpoint_staged][nmos::fields::transport_file] = details::make_connection_receiver_staging_transport_file(); + data[nmos::fields::endpoint_staged][nmos::fields::transport_params] = details::legs_of(details::make_connection_mxl_receiver_staged_core_parameter_set(), redundant); + + data[nmos::fields::endpoint_active] = data[nmos::fields::endpoint_staged]; + + // Note that the transporttype endpoint is implemented in terms of the matching IS-04 receiver + + return{ is05_versions::v1_2, types::receiver, std::move(data), false }; + } } diff --git a/Development/nmos/connection_resources.h b/Development/nmos/connection_resources.h index adb035d34..045ed92e0 100644 --- a/Development/nmos/connection_resources.h +++ b/Development/nmos/connection_resources.h @@ -60,6 +60,9 @@ namespace nmos utility::string_t make_events_mqtt_broker_topic(const nmos::id& source_id, const nmos::settings& settings); utility::string_t make_events_mqtt_connection_status_broker_topic(const nmos::id& connection_id, const nmos::settings& settings); + + nmos::resource make_connection_mxl_sender(const nmos::id& id); + nmos::resource make_connection_mxl_receiver(const nmos::id& id); } #endif diff --git a/Development/nmos/is05_schemas/is05_schemas.h b/Development/nmos/is05_schemas/is05_schemas.h index 5430ede77..2c3db393a 100644 --- a/Development/nmos/is05_schemas/is05_schemas.h +++ b/Development/nmos/is05_schemas/is05_schemas.h @@ -16,6 +16,7 @@ namespace nmos extern const char* sender_transport_params_dash; extern const char* sender_transport_params_websocket; extern const char* sender_transport_params_mqtt; + extern const char* sender_transport_params_mxl; extern const char* sender_transport_params_ext; extern const char* receiver_stage_schema; extern const char* receiver_transport_file; @@ -24,6 +25,7 @@ namespace nmos extern const char* receiver_transport_params_dash; extern const char* receiver_transport_params_websocket; extern const char* receiver_transport_params_mqtt; + extern const char* receiver_transport_params_mxl; extern const char* receiver_transport_params_ext; } diff --git a/Development/nmos/json_fields.h b/Development/nmos/json_fields.h index 0ff9921db..5e3b4739f 100644 --- a/Development/nmos/json_fields.h +++ b/Development/nmos/json_fields.h @@ -172,6 +172,8 @@ namespace nmos const web::json::field_as_value_or broker_authorization{ U("broker_authorization"), {} }; // string or bool const web::json::field_as_value_or broker_topic{ U("broker_topic"), {} }; // string or null const web::json::field_as_value_or connection_status_broker_topic{ U("connection_status_broker_topic"), {} }; // string or null + // for urn:x-nmos:transport:mxl + //const web::json::field_as_value flow_id{ U("flow_id") }; // see nmos::id // IS-07 Event & Tally diff --git a/Development/nmos/json_schema.cpp b/Development/nmos/json_schema.cpp index d08668d6a..e6491e7f0 100644 --- a/Development/nmos/json_schema.cpp +++ b/Development/nmos/json_schema.cpp @@ -343,12 +343,14 @@ namespace nmos { make_schema_uri(v1_2::tag, _XPLATSTR("sender_transport_params_dash.json")), make_schema(v1_2::sender_transport_params_dash) }, { make_schema_uri(v1_2::tag, _XPLATSTR("sender_transport_params_websocket.json")), make_schema(v1_2::sender_transport_params_websocket) }, { make_schema_uri(v1_2::tag, _XPLATSTR("sender_transport_params_mqtt.json")), make_schema(v1_2::sender_transport_params_mqtt) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("sender_transport_params_mxl.json")), make_schema(v1_2::sender_transport_params_mxl) }, { make_schema_uri(v1_2::tag, _XPLATSTR("sender_transport_params_ext.json")), make_schema(v1_2::sender_transport_params_ext) }, { make_schema_uri(v1_2::tag, _XPLATSTR("receiver_transport_params.json")), make_schema(v1_2::receiver_transport_params) }, { make_schema_uri(v1_2::tag, _XPLATSTR("receiver_transport_params_rtp.json")), make_schema(v1_2::receiver_transport_params_rtp) }, { make_schema_uri(v1_2::tag, _XPLATSTR("receiver_transport_params_dash.json")), make_schema(v1_2::receiver_transport_params_dash) }, { make_schema_uri(v1_2::tag, _XPLATSTR("receiver_transport_params_websocket.json")), make_schema(v1_2::receiver_transport_params_websocket) }, { make_schema_uri(v1_2::tag, _XPLATSTR("receiver_transport_params_mqtt.json")), make_schema(v1_2::receiver_transport_params_mqtt) }, + { make_schema_uri(v1_2::tag, _XPLATSTR("receiver_transport_params_mxl.json")), make_schema(v1_2::receiver_transport_params_mxl) }, { make_schema_uri(v1_2::tag, _XPLATSTR("receiver_transport_params_ext.json")), make_schema(v1_2::receiver_transport_params_ext) }, // v1.1 { make_schema_uri(v1_1::tag, _XPLATSTR("sender-stage-schema.json")), make_schema(v1_1::sender_stage_schema) }, diff --git a/Development/nmos/transport.h b/Development/nmos/transport.h index 8b45279b0..3da059d08 100644 --- a/Development/nmos/transport.h +++ b/Development/nmos/transport.h @@ -21,6 +21,8 @@ namespace nmos const transport mqtt{ U("urn:x-nmos:transport:mqtt") }; const transport websocket{ U("urn:x-nmos:transport:websocket") }; + + const transport mxl{ U("urn:x-nmos:transport:mxl") }; } // "Subclassifications are defined as the portion of the URN which follows the first occurrence of a '.', but prior to any '/' character." From de4b223339e83683b5eb9e7af293f2e713eefdce Mon Sep 17 00:00:00 2001 From: garethsb Date: Wed, 25 Feb 2026 14:08:42 +0000 Subject: [PATCH 06/20] Fix no_auto_constraints --- Development/nmos/connection_api.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Development/nmos/connection_api.cpp b/Development/nmos/connection_api.cpp index 83cdd641b..1b294511a 100644 --- a/Development/nmos/connection_api.cpp +++ b/Development/nmos/connection_api.cpp @@ -250,7 +250,15 @@ namespace nmos if (nmos::transports::mqtt == transport_base) return mqtt_auto_constraints(); //if (nmos::transports::mxl == transport_base) return mxl_auto_constraints(); - static const std::map> no_auto_constraints; + static const std::map> no_auto_constraints + { + { + nmos::types::sender, {} + }, + { + nmos::types::receiver, {} + } + }; return no_auto_constraints; } From 5f8b46803bbd718ea252dc945b4bb67de98181db Mon Sep 17 00:00:00 2001 From: Gareth Sylvester-Bradley Date: Wed, 25 Feb 2026 12:23:28 +0000 Subject: [PATCH 07/20] nmos-cpp-node support for MXL senders and receivers --- .../nmos-cpp-node/node_implementation.cpp | 138 +++++++++++++++++- 1 file changed, 135 insertions(+), 3 deletions(-) diff --git a/Development/nmos-cpp-node/node_implementation.cpp b/Development/nmos-cpp-node/node_implementation.cpp index 1e074fe23..4be5b1584 100644 --- a/Development/nmos-cpp-node/node_implementation.cpp +++ b/Development/nmos-cpp-node/node_implementation.cpp @@ -154,13 +154,22 @@ namespace impl // example number/enum event const port catcall{ U("c") }; + // video/v210, video/v210a, etc. + const port mxl_video{ U("xv") }; + // audio/float32 + const port mxl_audio{ U("xa") }; + // video/smpte291 + const port mxl_data{ U("xd") }; + const std::vector rtp{ video, audio, data, mux }; const std::vector ws{ temperature, burn, nonsense, catcall }; - const std::vector all{ boost::copy_range>(boost::range::join(rtp, ws)) }; + const std::vector mxl{ mxl_video, mxl_audio, mxl_data }; + const std::vector all{ boost::copy_range>(boost::join(boost::join(rtp, ws), mxl)) }; } bool is_rtp_port(const port& port); bool is_ws_port(const port& port); + bool is_mxl_port(const port& port); std::vector parse_ports(const web::json::value& value); const std::vector channels_repeat{ @@ -404,9 +413,11 @@ void node_implementation_init(nmos::node_model& model, nmos::experimental::contr const auto sender_ports = impl::parse_ports(impl::fields::senders(model.settings)); const auto rtp_sender_ports = boost::copy_range>(sender_ports | boost::adaptors::filtered(impl::is_rtp_port)); const auto ws_sender_ports = boost::copy_range>(sender_ports | boost::adaptors::filtered(impl::is_ws_port)); + const auto mxl_sender_ports = boost::copy_range>(sender_ports | boost::adaptors::filtered(impl::is_mxl_port)); const auto receiver_ports = impl::parse_ports(impl::fields::receivers(model.settings)); const auto rtp_receiver_ports = boost::copy_range>(receiver_ports | boost::adaptors::filtered(impl::is_rtp_port)); const auto ws_receiver_ports = boost::copy_range>(receiver_ports | boost::adaptors::filtered(impl::is_ws_port)); + const auto mxl_receiver_ports = boost::copy_range>(receiver_ports | boost::adaptors::filtered(impl::is_mxl_port)); const auto frame_rate = nmos::parse_rational(impl::fields::frame_rate(model.settings)); const auto frame_width = impl::fields::frame_width(model.settings); const auto frame_height = impl::fields::frame_height(model.settings); @@ -528,13 +539,14 @@ void node_implementation_init(nmos::node_model& model, nmos::experimental::contr { auto sender_ids = impl::make_ids(seed_id, nmos::types::sender, rtp_sender_ports, how_many); if (0 <= nmos::fields::events_port(model.settings)) boost::range::push_back(sender_ids, impl::make_ids(seed_id, nmos::types::sender, ws_sender_ports, how_many)); + boost::range::push_back(sender_ids, impl::make_ids(seed_id, nmos::types::sender, mxl_sender_ports, how_many)); auto receiver_ids = impl::make_ids(seed_id, nmos::types::receiver, receiver_ports, how_many); auto device = nmos::make_device(device_id, node_id, sender_ids, receiver_ids, model.settings); device.data[nmos::fields::tags] = impl::fields::device_tags(model.settings); if (!insert_resource_after(delay_millis, model.node_resources, std::move(device), gate)) throw node_implementation_init_exception(); } - // example sources, flows and senders + // example rtp sources, flows and senders for (int index = 0; index < how_many; ++index) { for (const auto& port : rtp_sender_ports) @@ -672,7 +684,7 @@ void node_implementation_init(nmos::node_model& model, nmos::experimental::contr } } - // example receivers + // example rtp receivers for (int index = 0; index < how_many; ++index) { for (const auto& port : rtp_receiver_ports) @@ -903,6 +915,121 @@ void node_implementation_init(nmos::node_model& model, nmos::experimental::contr } } + // example mxl sources, flows and senders + for (int index = 0; index < how_many; ++index) + { + for (const auto& port : mxl_sender_ports) + { + const auto source_id = impl::make_id(seed_id, nmos::types::source, port, index); + const auto flow_id = impl::make_id(seed_id, nmos::types::flow, port, index); + const auto sender_id = impl::make_id(seed_id, nmos::types::sender, port, index); + + nmos::resource source; + if (impl::ports::mxl_video == port) + { + source = nmos::make_video_source(source_id, device_id, nmos::clock_names::clk0, frame_rate, model.settings); + } + else if (impl::ports::mxl_audio == port) + { + const auto channels = boost::copy_range>(boost::irange(0, channel_count) | boost::adaptors::transformed([&](const int& index) + { + return impl::channels_repeat[index % (int)impl::channels_repeat.size()]; + })); + + source = nmos::make_audio_source(source_id, device_id, nmos::clock_names::clk0, frame_rate, channels, model.settings); + } + else if (impl::ports::mxl_data == port) + { + source = nmos::make_data_source(source_id, device_id, nmos::clock_names::clk0, frame_rate, model.settings); + } + impl::insert_parents(source, seed_id, port, index); + impl::set_label_description(source, port, index); + + nmos::resource flow; + + if (impl::ports::mxl_video == port) + { + flow = nmos::make_coded_video_flow( + flow_id, source_id, device_id, + frame_rate, + frame_width, frame_height, interlace_mode, + colorspace, transfer_characteristic, sampling, bit_depth, + video_type, + model.settings + ); + } + else if (impl::ports::mxl_audio == port) + { + flow = nmos::make_raw_audio_flow(flow_id, source_id, device_id, 48000, 32, model.settings); + flow.data[nmos::fields::media_type] = value::string(U("audio/float32")); + // add optional grain_rate + flow.data[nmos::fields::grain_rate] = nmos::make_rational(frame_rate); + } + else if (impl::ports::mxl_data == port) + { + nmos::did_sdid timecode{ 0x60, 0x60 }; + flow = nmos::make_sdianc_data_flow(flow_id, source_id, device_id, { timecode }, model.settings); + // add optional grain_rate + flow.data[nmos::fields::grain_rate] = nmos::make_rational(frame_rate); + } + impl::insert_parents(flow, seed_id, port, index); + impl::set_label_description(flow, port, index); + + auto sender = nmos::make_sender(sender_id, flow_id, nmos::transports::mxl, device_id, {}, {}, model.settings); + impl::set_label_description(sender, port, index); + impl::insert_group_hint(sender, port, index); + + auto connection_sender = nmos::make_connection_mxl_sender(sender_id); + + if (impl::fields::activate_senders(model.settings)) + { + // initialize this sender with a scheduled activation, e.g. to enable the IS-05-01 test suite to run immediately + auto& staged = connection_sender.data[nmos::fields::endpoint_staged]; + staged[nmos::fields::master_enable] = value::boolean(true); + staged[nmos::fields::activation] = value_of({ + { nmos::fields::mode, nmos::activation_modes::activate_scheduled_relative.name }, + { nmos::fields::requested_time, U("0:0") }, + { nmos::fields::activation_time, nmos::make_version() } + }); + } + + if (!insert_resource_after(delay_millis, model.node_resources, std::move(source), gate)) throw node_implementation_init_exception(); + if (!insert_resource_after(delay_millis, model.node_resources, std::move(flow), gate)) throw node_implementation_init_exception(); + if (!insert_resource_after(delay_millis, model.node_resources, std::move(sender), gate)) throw node_implementation_init_exception(); + if (!insert_resource_after(delay_millis, model.connection_resources, std::move(connection_sender), gate)) throw node_implementation_init_exception(); + } + } + + // example mxl receivers + for (int index = 0; index < how_many; ++index) + { + for (const auto& port : mxl_receiver_ports) + { + const auto receiver_id = impl::make_id(seed_id, nmos::types::receiver, port, index); + + nmos::resource receiver; + if (impl::ports::mxl_video == port) + { + receiver = nmos::make_receiver(receiver_id, device_id, nmos::transports::mxl, {}, nmos::formats::video, { video_type }, model.settings); + } + else if (impl::ports::mxl_audio == port) + { + receiver = nmos::make_audio_receiver(receiver_id, device_id, nmos::transports::mxl, {}, {}, model.settings); + } + else if (impl::ports::mxl_data == port) + { + receiver = nmos::make_sdianc_data_receiver(receiver_id, device_id, nmos::transports::mxl, {}, model.settings); + } + impl::set_label_description(receiver, port, index); + impl::insert_group_hint(receiver, port, index); + + auto connection_receiver = nmos::make_connection_mxl_receiver(receiver_id); + + if (!insert_resource_after(delay_millis, model.node_resources, std::move(receiver), gate)) throw node_implementation_init_exception(); + if (!insert_resource_after(delay_millis, model.connection_resources, std::move(connection_receiver), gate)) throw node_implementation_init_exception(); + } + } + // example channelmapping resources demonstrating a range of input/output capabilities // see https://github.com/sony/nmos-cpp/issues/111#issuecomment-740613137 @@ -2263,6 +2390,11 @@ namespace impl return impl::ports::ws.end() != boost::range::find(impl::ports::ws, port); } + bool is_mxl_port(const impl::port& port) + { + return impl::ports::mxl.end() != boost::range::find(impl::ports::mxl, port); + } + std::vector parse_ports(const web::json::value& value) { if (value.is_null()) return impl::ports::all; From 9fa16508766a11c6cf6b1ce1a2880de212ccb9f5 Mon Sep 17 00:00:00 2001 From: jonathan-r-thorpe Date: Wed, 25 Feb 2026 14:08:42 +0000 Subject: [PATCH 08/20] Add flow_id as initial value (next, try making it a /constraints value and use "auto" in /staged) --- Development/nmos-cpp-node/node_implementation.cpp | 2 +- Development/nmos/connection_resources.cpp | 8 ++++---- Development/nmos/connection_resources.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Development/nmos-cpp-node/node_implementation.cpp b/Development/nmos-cpp-node/node_implementation.cpp index 4be5b1584..ca447f725 100644 --- a/Development/nmos-cpp-node/node_implementation.cpp +++ b/Development/nmos-cpp-node/node_implementation.cpp @@ -979,7 +979,7 @@ void node_implementation_init(nmos::node_model& model, nmos::experimental::contr impl::set_label_description(sender, port, index); impl::insert_group_hint(sender, port, index); - auto connection_sender = nmos::make_connection_mxl_sender(sender_id); + auto connection_sender = nmos::make_connection_mxl_sender(sender_id, flow_id); if (impl::fields::activate_senders(model.settings)) { diff --git a/Development/nmos/connection_resources.cpp b/Development/nmos/connection_resources.cpp index acdee5735..0526d0855 100644 --- a/Development/nmos/connection_resources.cpp +++ b/Development/nmos/connection_resources.cpp @@ -626,13 +626,13 @@ namespace nmos }); } - web::json::value make_connection_mxl_sender_staged_core_parameter_set() + web::json::value make_connection_mxl_sender_staged_core_parameter_set(const nmos::id& flow_id) { using web::json::value; using web::json::value_of; return value_of({ - { nmos::fields::flow_id, value::null() } + { nmos::fields::flow_id, flow_id.empty() ? value::null() : value::string(flow_id) } }); } @@ -658,7 +658,7 @@ namespace nmos } } - nmos::resource make_connection_mxl_sender(const nmos::id& id) + nmos::resource make_connection_mxl_sender(const nmos::id& id, const nmos::id& flow_id) { using web::json::value; using web::json::value_of; @@ -670,7 +670,7 @@ namespace nmos data[nmos::fields::endpoint_constraints] = details::legs_of(details::make_connection_mxl_sender_core_constraints(), redundant); data[nmos::fields::endpoint_staged][nmos::fields::receiver_id] = value::null(); - data[nmos::fields::endpoint_staged][nmos::fields::transport_params] = details::legs_of(details::make_connection_mxl_sender_staged_core_parameter_set(), redundant); + data[nmos::fields::endpoint_staged][nmos::fields::transport_params] = details::legs_of(details::make_connection_mxl_sender_staged_core_parameter_set(flow_id), redundant); data[nmos::fields::endpoint_active] = data[nmos::fields::endpoint_staged]; diff --git a/Development/nmos/connection_resources.h b/Development/nmos/connection_resources.h index 045ed92e0..24d03b339 100644 --- a/Development/nmos/connection_resources.h +++ b/Development/nmos/connection_resources.h @@ -61,7 +61,7 @@ namespace nmos utility::string_t make_events_mqtt_broker_topic(const nmos::id& source_id, const nmos::settings& settings); utility::string_t make_events_mqtt_connection_status_broker_topic(const nmos::id& connection_id, const nmos::settings& settings); - nmos::resource make_connection_mxl_sender(const nmos::id& id); + nmos::resource make_connection_mxl_sender(const nmos::id& id, const nmos::id& flow_id); nmos::resource make_connection_mxl_receiver(const nmos::id& id); } From 18a90974959dc86858f3bce3f1ae66e471ec2393 Mon Sep 17 00:00:00 2001 From: Gareth Sylvester-Bradley Date: Wed, 25 Feb 2026 20:40:33 +0000 Subject: [PATCH 09/20] Add support for "auto" to MXL sender flow_id transport parameter --- .../nmos-cpp-node/node_implementation.cpp | 21 +++++++++++++------ Development/nmos/connection_api.cpp | 20 +++++++++++++++++- Development/nmos/connection_resources.cpp | 17 +++++++++------ .../receiver_transport_params_mxl.json | 1 - .../schemas/sender_transport_params_mxl.json | 6 ++++-- 5 files changed, 49 insertions(+), 16 deletions(-) diff --git a/Development/nmos-cpp-node/node_implementation.cpp b/Development/nmos-cpp-node/node_implementation.cpp index ca447f725..101526b51 100644 --- a/Development/nmos-cpp-node/node_implementation.cpp +++ b/Development/nmos-cpp-node/node_implementation.cpp @@ -1672,7 +1672,8 @@ void node_implementation_run(nmos::node_model& model, nmos::experimental::contro const auto sender_ports = impl::parse_ports(impl::fields::senders(model.settings)); const auto rtp_sender_ports = boost::copy_range>(sender_ports | boost::adaptors::filtered(impl::is_rtp_port)); const auto ws_sender_ports = boost::copy_range>(sender_ports | boost::adaptors::filtered(impl::is_ws_port)); - const auto rtp_receiver_ports = boost::copy_range>(impl::parse_ports(impl::fields::receivers(model.settings)) | boost::adaptors::filtered(impl::is_rtp_port)); + const auto receiver_ports = impl::parse_ports(impl::fields::receivers(model.settings)); + const auto rtp_receiver_ports = boost::copy_range>(receiver_ports | boost::adaptors::filtered(impl::is_rtp_port)); const auto simulate_status_monitor_activity = impl::fields::simulate_status_monitor_activity(model.settings); auto& control_protocol_resources = model.control_protocol_resources; @@ -2010,19 +2011,23 @@ nmos::connection_resource_auto_resolver make_node_implementation_auto_resolver(c const auto seed_id = nmos::experimental::fields::seed_id(settings); const auto device_id = impl::make_id(seed_id, nmos::types::device); const auto how_many = impl::fields::how_many(settings); - const auto rtp_sender_ports = boost::copy_range>(impl::parse_ports(impl::fields::senders(settings)) | boost::adaptors::filtered(impl::is_rtp_port)); + const auto sender_ports = impl::parse_ports(impl::fields::senders(settings)); + const auto rtp_sender_ports = boost::copy_range>(sender_ports | boost::adaptors::filtered(impl::is_rtp_port)); const auto rtp_sender_ids = impl::make_ids(seed_id, nmos::types::sender, rtp_sender_ports, how_many); - const auto ws_sender_ports = boost::copy_range>(impl::parse_ports(impl::fields::senders(settings)) | boost::adaptors::filtered(impl::is_ws_port)); + const auto ws_sender_ports = boost::copy_range>(sender_ports | boost::adaptors::filtered(impl::is_ws_port)); const auto ws_sender_ids = impl::make_ids(seed_id, nmos::types::sender, ws_sender_ports, how_many); + const auto mxl_sender_ports = boost::copy_range>(sender_ports | boost::adaptors::filtered(impl::is_mxl_port)); + const auto mxl_sender_ids = impl::make_ids(seed_id, nmos::types::sender, mxl_sender_ports, how_many); const auto ws_sender_uri = nmos::make_events_ws_api_connection_uri(device_id, settings); - const auto rtp_receiver_ports = boost::copy_range>(impl::parse_ports(impl::fields::receivers(settings)) | boost::adaptors::filtered(impl::is_rtp_port)); + const auto receiver_ports = impl::parse_ports(impl::fields::receivers(settings)); + const auto rtp_receiver_ports = boost::copy_range>(receiver_ports | boost::adaptors::filtered(impl::is_rtp_port)); const auto rtp_receiver_ids = impl::make_ids(seed_id, nmos::types::receiver, rtp_receiver_ports, how_many); - const auto ws_receiver_ports = boost::copy_range>(impl::parse_ports(impl::fields::receivers(settings)) | boost::adaptors::filtered(impl::is_ws_port)); + const auto ws_receiver_ports = boost::copy_range>(receiver_ports | boost::adaptors::filtered(impl::is_ws_port)); const auto ws_receiver_ids = impl::make_ids(seed_id, nmos::types::receiver, ws_receiver_ports, how_many); // although which properties may need to be defaulted depends on the resource type, // the default value will almost always be different for each resource - return [rtp_sender_ids, rtp_receiver_ids, ws_sender_ids, ws_sender_uri, ws_receiver_ids](const nmos::resource& resource, const nmos::resource& connection_resource, value& transport_params) + return [rtp_sender_ids, rtp_receiver_ids, ws_sender_ids, ws_sender_uri, ws_receiver_ids, mxl_sender_ids](const nmos::resource& resource, const nmos::resource& connection_resource, value& transport_params) { const std::pair id_type{ connection_resource.id, connection_resource.type }; // this code relies on the specific constraints added by node_implementation_thread @@ -2057,6 +2062,10 @@ nmos::connection_resource_auto_resolver make_node_implementation_auto_resolver(c { nmos::details::resolve_auto(transport_params[0], nmos::fields::connection_authorization, [&] { return value::boolean(false); }); } + else if (mxl_sender_ids.end() != boost::range::find(mxl_sender_ids, id_type.first)) + { + nmos::details::resolve_auto(transport_params[0], nmos::fields::flow_id, [&] { return web::json::front(nmos::fields::constraint_enum(constraints.at(0).at(nmos::fields::flow_id))); }); + } }; } diff --git a/Development/nmos/connection_api.cpp b/Development/nmos/connection_api.cpp index 1b294511a..b6ec11478 100644 --- a/Development/nmos/connection_api.cpp +++ b/Development/nmos/connection_api.cpp @@ -243,12 +243,30 @@ namespace nmos return auto_constraints; } + static const std::map>& mxl_auto_constraints() + { + // These are the constraints that support "auto" in /staged + static const std::map> auto_constraints + { + { + nmos::types::sender, + { + nmos::fields::flow_id + } + }, + { + nmos::types::receiver, {} + } + }; + return auto_constraints; + } + static const std::map>& auto_constraints(const nmos::transport& transport_base) { if (nmos::transports::rtp == transport_base) return rtp_auto_constraints(); if (nmos::transports::websocket == transport_base) return websocket_auto_constraints(); if (nmos::transports::mqtt == transport_base) return mqtt_auto_constraints(); - //if (nmos::transports::mxl == transport_base) return mxl_auto_constraints(); + if (nmos::transports::mxl == transport_base) return mxl_auto_constraints(); static const std::map> no_auto_constraints { diff --git a/Development/nmos/connection_resources.cpp b/Development/nmos/connection_resources.cpp index 0526d0855..e6bbc82eb 100644 --- a/Development/nmos/connection_resources.cpp +++ b/Development/nmos/connection_resources.cpp @@ -615,24 +615,28 @@ namespace nmos namespace details { - web::json::value make_connection_mxl_sender_core_constraints() + web::json::value make_connection_mxl_sender_core_constraints(const nmos::id& flow_id) { using web::json::value; using web::json::value_of; const auto unconstrained = value::object(); return value_of({ - { nmos::fields::flow_id, unconstrained } + { nmos::fields::flow_id, flow_id.empty() ? unconstrained : value_of({ + { nmos::fields::constraint_enum, value_of({ + flow_id + }) } + }) } }); } - web::json::value make_connection_mxl_sender_staged_core_parameter_set(const nmos::id& flow_id) + web::json::value make_connection_mxl_sender_staged_core_parameter_set() { using web::json::value; using web::json::value_of; return value_of({ - { nmos::fields::flow_id, flow_id.empty() ? value::null() : value::string(flow_id) } + { nmos::fields::flow_id, U("auto") } }); } @@ -667,12 +671,13 @@ namespace nmos auto data = details::make_connection_resource_core(id, redundant); - data[nmos::fields::endpoint_constraints] = details::legs_of(details::make_connection_mxl_sender_core_constraints(), redundant); + data[nmos::fields::endpoint_constraints] = details::legs_of(details::make_connection_mxl_sender_core_constraints(flow_id), redundant); data[nmos::fields::endpoint_staged][nmos::fields::receiver_id] = value::null(); - data[nmos::fields::endpoint_staged][nmos::fields::transport_params] = details::legs_of(details::make_connection_mxl_sender_staged_core_parameter_set(flow_id), redundant); + data[nmos::fields::endpoint_staged][nmos::fields::transport_params] = details::legs_of(details::make_connection_mxl_sender_staged_core_parameter_set(), redundant); data[nmos::fields::endpoint_active] = data[nmos::fields::endpoint_staged]; + // The caller must resolve all instances of "auto" in the /active endpoint into the actual values that will be used! // Note that the transporttype endpoint is implemented in terms of the matching IS-04 sender diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json index 31bcda06b..58931c3be 100644 --- a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json @@ -11,7 +11,6 @@ ], "description": "ID of the Flow to read.", "anyOf": [{ - "type": "string", "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" }, { diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json index d059b7f3c..7e96974fa 100644 --- a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json @@ -9,11 +9,13 @@ "string", "null" ], - "description": "ID of the Flow to write.", + "description": "ID of the Flow to write. If the parameter is set to auto the Sender should use the Flow it is bound to. A null value indicates that the Sender has not yet been configured.", "anyOf": [{ - "type": "string", "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" }, + { + "pattern": "^auto$" + }, { "type": "null" } From e5c01057fd283b81a40ad87a05ae278693c38580 Mon Sep 17 00:00:00 2001 From: jonathan-r-thorpe Date: Thu, 26 Feb 2026 10:43:53 +0000 Subject: [PATCH 10/20] Fix audio sender --- Development/nmos-cpp-node/node_implementation.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Development/nmos-cpp-node/node_implementation.cpp b/Development/nmos-cpp-node/node_implementation.cpp index 101526b51..f48788e72 100644 --- a/Development/nmos-cpp-node/node_implementation.cpp +++ b/Development/nmos-cpp-node/node_implementation.cpp @@ -1014,7 +1014,7 @@ void node_implementation_init(nmos::node_model& model, nmos::experimental::contr } else if (impl::ports::mxl_audio == port) { - receiver = nmos::make_audio_receiver(receiver_id, device_id, nmos::transports::mxl, {}, {}, model.settings); + receiver = nmos::make_audio_receiver(receiver_id, device_id, nmos::transports::mxl, {}, std::vector{}, model.settings); } else if (impl::ports::mxl_data == port) { From a8b753589358aff11966096eac258e86dfad19a0 Mon Sep 17 00:00:00 2001 From: jonathan-r-thorpe Date: Wed, 4 Mar 2026 12:00:31 +0000 Subject: [PATCH 11/20] update config.json to include mxl ports --- Development/nmos-cpp-node/config.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Development/nmos-cpp-node/config.json b/Development/nmos-cpp-node/config.json index c529de695..1545b1081 100644 --- a/Development/nmos-cpp-node/config.json +++ b/Development/nmos-cpp-node/config.json @@ -23,8 +23,8 @@ // senders, receivers: controls which kinds of sender and receiver are instantiated by the example node // the values must be an array of unique strings identifying the kinds of 'port', like ["v", "a", "d"], see impl::ports // when omitted, all ports are instantiated - //"senders": ["v", "a"], - //"receivers": [], + "senders": ["xv", "xa", "xd"], + "receivers": ["xv", "xa", "xd"], // frame_rate: controls the grain_rate of video, audio and ancillary data sources and flows // and the equivalent parameter constraint on video receivers @@ -52,7 +52,7 @@ //"component_depth": 10, // video_type: media type of video flows, e.g. "video/raw" or "video/jxsv", see nmos::media_types - //"video_type": "video/jxsv", + "video_type": "video/v210", // channel_count: controls the number of channels in audio sources //"channel_count": 8, From cfb3726e506041d4504163385a209006ade62e8b Mon Sep 17 00:00:00 2001 From: jonathan-r-thorpe Date: Tue, 5 May 2026 15:49:20 +0100 Subject: [PATCH 12/20] Added mxl_domain_id transport parameter to MXL sender and receiver connections Renamed flow_id to mxl_flow_id in MXL sender and receiver connections --- .../nmos-cpp-node/node_implementation.cpp | 32 ++++++++++++++--- Development/nmos/connection_api.cpp | 9 +++-- Development/nmos/connection_resources.cpp | 34 +++++++++++++------ Development/nmos/connection_resources.h | 4 +-- .../receiver_transport_params_mxl.json | 24 +++++++++++-- .../schemas/sender_transport_params_mxl.json | 21 ++++++++++-- 6 files changed, 100 insertions(+), 24 deletions(-) diff --git a/Development/nmos-cpp-node/node_implementation.cpp b/Development/nmos-cpp-node/node_implementation.cpp index f48788e72..ace97122a 100644 --- a/Development/nmos-cpp-node/node_implementation.cpp +++ b/Development/nmos-cpp-node/node_implementation.cpp @@ -409,6 +409,7 @@ void node_implementation_init(nmos::node_model& model, nmos::experimental::contr const auto seed_id = nmos::experimental::fields::seed_id(model.settings); const auto node_id = impl::make_id(seed_id, nmos::types::node); const auto device_id = impl::make_id(seed_id, nmos::types::device); + const auto mxl_domain_id = nmos::make_repeatable_id(seed_id, U("/x-nmos/mxl/domain")); const auto how_many = impl::fields::how_many(model.settings); const auto sender_ports = impl::parse_ports(impl::fields::senders(model.settings)); const auto rtp_sender_ports = boost::copy_range>(sender_ports | boost::adaptors::filtered(impl::is_rtp_port)); @@ -979,7 +980,7 @@ void node_implementation_init(nmos::node_model& model, nmos::experimental::contr impl::set_label_description(sender, port, index); impl::insert_group_hint(sender, port, index); - auto connection_sender = nmos::make_connection_mxl_sender(sender_id, flow_id); + auto connection_sender = nmos::make_connection_mxl_sender(sender_id, flow_id, mxl_domain_id); if (impl::fields::activate_senders(model.settings)) { @@ -1014,7 +1015,7 @@ void node_implementation_init(nmos::node_model& model, nmos::experimental::contr } else if (impl::ports::mxl_audio == port) { - receiver = nmos::make_audio_receiver(receiver_id, device_id, nmos::transports::mxl, {}, std::vector{}, model.settings); + receiver = nmos::make_receiver(receiver_id, device_id, nmos::transports::mxl, {}, nmos::formats::audio, { nmos::media_type{ U("audio/float32") } }, model.settings); } else if (impl::ports::mxl_data == port) { @@ -1023,7 +1024,7 @@ void node_implementation_init(nmos::node_model& model, nmos::experimental::contr impl::set_label_description(receiver, port, index); impl::insert_group_hint(receiver, port, index); - auto connection_receiver = nmos::make_connection_mxl_receiver(receiver_id); + auto connection_receiver = nmos::make_connection_mxl_receiver(receiver_id, mxl_domain_id); if (!insert_resource_after(delay_millis, model.node_resources, std::move(receiver), gate)) throw node_implementation_init_exception(); if (!insert_resource_after(delay_millis, model.connection_resources, std::move(connection_receiver), gate)) throw node_implementation_init_exception(); @@ -2024,10 +2025,12 @@ nmos::connection_resource_auto_resolver make_node_implementation_auto_resolver(c const auto rtp_receiver_ids = impl::make_ids(seed_id, nmos::types::receiver, rtp_receiver_ports, how_many); const auto ws_receiver_ports = boost::copy_range>(receiver_ports | boost::adaptors::filtered(impl::is_ws_port)); const auto ws_receiver_ids = impl::make_ids(seed_id, nmos::types::receiver, ws_receiver_ports, how_many); + const auto mxl_receiver_ports = boost::copy_range>(receiver_ports | boost::adaptors::filtered(impl::is_mxl_port)); + const auto mxl_receiver_ids = impl::make_ids(seed_id, nmos::types::receiver, mxl_receiver_ports, how_many); // although which properties may need to be defaulted depends on the resource type, // the default value will almost always be different for each resource - return [rtp_sender_ids, rtp_receiver_ids, ws_sender_ids, ws_sender_uri, ws_receiver_ids, mxl_sender_ids](const nmos::resource& resource, const nmos::resource& connection_resource, value& transport_params) + return [rtp_sender_ids, rtp_receiver_ids, ws_sender_ids, ws_sender_uri, ws_receiver_ids, mxl_sender_ids, mxl_receiver_ids](const nmos::resource& resource, const nmos::resource& connection_resource, value& transport_params) { const std::pair id_type{ connection_resource.id, connection_resource.type }; // this code relies on the specific constraints added by node_implementation_thread @@ -2064,7 +2067,26 @@ nmos::connection_resource_auto_resolver make_node_implementation_auto_resolver(c } else if (mxl_sender_ids.end() != boost::range::find(mxl_sender_ids, id_type.first)) { - nmos::details::resolve_auto(transport_params[0], nmos::fields::flow_id, [&] { return web::json::front(nmos::fields::constraint_enum(constraints.at(0).at(nmos::fields::flow_id))); }); + nmos::details::resolve_auto(transport_params[0], nmos::fields::mxl_flow_id, [&] { return web::json::front(nmos::fields::constraint_enum(constraints.at(0).at(nmos::fields::mxl_flow_id))); }); + nmos::details::resolve_auto(transport_params[0], nmos::fields::mxl_domain_id, [&] { return web::json::front(nmos::fields::constraint_enum(constraints.at(0).at(nmos::fields::mxl_domain_id))); }); + } + else if (mxl_receiver_ids.end() != boost::range::find(mxl_receiver_ids, id_type.first)) + { + nmos::details::resolve_auto(transport_params[0], nmos::fields::mxl_domain_id, [&] { return web::json::front(nmos::fields::constraint_enum(constraints.at(0).at(nmos::fields::mxl_domain_id))); }); + // mxl_flow_id may be unconstrained on receivers; resolve auto only when constraints enumerate values + nmos::details::resolve_auto(transport_params[0], nmos::fields::mxl_flow_id, [&] + { + const auto& fc = constraints.at(0).at(nmos::fields::mxl_flow_id); + if (fc.is_object() && fc.has_field(nmos::fields::constraint_enum)) + { + const auto& en = nmos::fields::constraint_enum(fc); + if (en.is_array() && 0 != en.as_array().size()) + { + return web::json::front(en); + } + } + return web::json::value::null(); + }); } }; } diff --git a/Development/nmos/connection_api.cpp b/Development/nmos/connection_api.cpp index b6ec11478..864fd0bb5 100644 --- a/Development/nmos/connection_api.cpp +++ b/Development/nmos/connection_api.cpp @@ -251,11 +251,16 @@ namespace nmos { nmos::types::sender, { - nmos::fields::flow_id + nmos::fields::mxl_flow_id, + nmos::fields::mxl_domain_id } }, { - nmos::types::receiver, {} + nmos::types::receiver, + { + nmos::fields::mxl_domain_id, + nmos::fields::mxl_flow_id + } } }; return auto_constraints; diff --git a/Development/nmos/connection_resources.cpp b/Development/nmos/connection_resources.cpp index e6bbc82eb..93c4512ed 100644 --- a/Development/nmos/connection_resources.cpp +++ b/Development/nmos/connection_resources.cpp @@ -615,16 +615,21 @@ namespace nmos namespace details { - web::json::value make_connection_mxl_sender_core_constraints(const nmos::id& flow_id) + web::json::value make_connection_mxl_sender_core_constraints(const nmos::id& mxl_flow_id, const nmos::id& mxl_domain_id) { using web::json::value; using web::json::value_of; const auto unconstrained = value::object(); return value_of({ - { nmos::fields::flow_id, flow_id.empty() ? unconstrained : value_of({ + { nmos::fields::mxl_flow_id, mxl_flow_id.empty() ? unconstrained : value_of({ { nmos::fields::constraint_enum, value_of({ - flow_id + mxl_flow_id + }) } + }) }, + { nmos::fields::mxl_domain_id, mxl_domain_id.empty() ? unconstrained : value_of({ + { nmos::fields::constraint_enum, value_of({ + mxl_domain_id }) } }) } }); @@ -636,18 +641,24 @@ namespace nmos using web::json::value_of; return value_of({ - { nmos::fields::flow_id, U("auto") } + { nmos::fields::mxl_flow_id, U("auto") }, + { nmos::fields::mxl_domain_id, U("auto") } }); } - web::json::value make_connection_mxl_receiver_core_constraints() + web::json::value make_connection_mxl_receiver_core_constraints(const nmos::id& mxl_domain_id) { using web::json::value; using web::json::value_of; const auto unconstrained = value::object(); return value_of({ - { nmos::fields::flow_id, unconstrained } + { nmos::fields::mxl_flow_id, unconstrained }, + { nmos::fields::mxl_domain_id, mxl_domain_id.empty() ? unconstrained : value_of({ + { nmos::fields::constraint_enum, value_of({ + mxl_domain_id + }) } + }) } }); } @@ -657,12 +668,13 @@ namespace nmos using web::json::value_of; return value_of({ - { nmos::fields::flow_id, value::null() } + { nmos::fields::mxl_flow_id, value::null() }, + { nmos::fields::mxl_domain_id, U("auto") } }); } } - nmos::resource make_connection_mxl_sender(const nmos::id& id, const nmos::id& flow_id) + nmos::resource make_connection_mxl_sender(const nmos::id& id, const nmos::id& mxl_flow_id, const nmos::id& mxl_domain_id) { using web::json::value; using web::json::value_of; @@ -671,7 +683,7 @@ namespace nmos auto data = details::make_connection_resource_core(id, redundant); - data[nmos::fields::endpoint_constraints] = details::legs_of(details::make_connection_mxl_sender_core_constraints(flow_id), redundant); + data[nmos::fields::endpoint_constraints] = details::legs_of(details::make_connection_mxl_sender_core_constraints(mxl_flow_id, mxl_domain_id), redundant); data[nmos::fields::endpoint_staged][nmos::fields::receiver_id] = value::null(); data[nmos::fields::endpoint_staged][nmos::fields::transport_params] = details::legs_of(details::make_connection_mxl_sender_staged_core_parameter_set(), redundant); @@ -684,7 +696,7 @@ namespace nmos return{ is05_versions::v1_2, types::sender, std::move(data), false }; } - nmos::resource make_connection_mxl_receiver(const nmos::id& id) + nmos::resource make_connection_mxl_receiver(const nmos::id& id, const nmos::id& mxl_domain_id) { using web::json::value; @@ -692,7 +704,7 @@ namespace nmos auto data = details::make_connection_resource_core(id, redundant); - data[nmos::fields::endpoint_constraints] = details::legs_of(details::make_connection_mxl_receiver_core_constraints(), redundant); + data[nmos::fields::endpoint_constraints] = details::legs_of(details::make_connection_mxl_receiver_core_constraints(mxl_domain_id), redundant); data[nmos::fields::endpoint_staged][nmos::fields::sender_id] = value::null(); data[nmos::fields::endpoint_staged][nmos::fields::transport_file] = details::make_connection_receiver_staging_transport_file(); diff --git a/Development/nmos/connection_resources.h b/Development/nmos/connection_resources.h index 24d03b339..5f8b4ddc6 100644 --- a/Development/nmos/connection_resources.h +++ b/Development/nmos/connection_resources.h @@ -61,8 +61,8 @@ namespace nmos utility::string_t make_events_mqtt_broker_topic(const nmos::id& source_id, const nmos::settings& settings); utility::string_t make_events_mqtt_connection_status_broker_topic(const nmos::id& connection_id, const nmos::settings& settings); - nmos::resource make_connection_mxl_sender(const nmos::id& id, const nmos::id& flow_id); - nmos::resource make_connection_mxl_receiver(const nmos::id& id); + nmos::resource make_connection_mxl_sender(const nmos::id& id, const nmos::id& mxl_flow_id, const nmos::id& mxl_domain_id); + nmos::resource make_connection_mxl_receiver(const nmos::id& id, const nmos::id& mxl_domain_id); } #endif diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json index 58931c3be..bc20bbf5b 100644 --- a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json @@ -4,15 +4,35 @@ "title": "MXL Receiver Transport Parameters", "type": "object", "properties": { - "flow_id": { + "mxl_domain_id": { "type": [ "string", "null" ], - "description": "ID of the Flow to read.", + "description": "MXL domain identity (UUID). Use auto to select from constraints.", "anyOf": [{ "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" }, + { + "pattern": "^auto$" + }, + { + "type": "null" + } + ] + }, + "mxl_flow_id": { + "type": [ + "string", + "null" + ], + "description": "MXL flow identity for the read operation. Need not match the IS-04 Flow id. Use auto to select from constraints.", + "anyOf": [{ + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + { + "pattern": "^auto$" + }, { "type": "null" } diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json index 7e96974fa..527b1c908 100644 --- a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json @@ -4,12 +4,29 @@ "title": "MXL Sender Transport Parameters", "type": "object", "properties": { - "flow_id": { + "mxl_domain_id": { "type": [ "string", "null" ], - "description": "ID of the Flow to write. If the parameter is set to auto the Sender should use the Flow it is bound to. A null value indicates that the Sender has not yet been configured.", + "description": "MXL domain identity (UUID). Use auto to select from constraints.", + "anyOf": [{ + "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" + }, + { + "pattern": "^auto$" + }, + { + "type": "null" + } + ] + }, + "mxl_flow_id": { + "type": [ + "string", + "null" + ], + "description": "MXL flow identity for the write operation. Need not match the IS-04 Flow id. Use auto to select from constraints.", "anyOf": [{ "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" }, From 4fb707f96c0c5dca569ea6273d246bf1ecbd62f3 Mon Sep 17 00:00:00 2001 From: jonathan-r-thorpe Date: Tue, 5 May 2026 16:08:35 +0100 Subject: [PATCH 13/20] Add missing JSON fields for MXL sender and receiver connections --- Development/nmos/json_fields.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Development/nmos/json_fields.h b/Development/nmos/json_fields.h index 5e3b4739f..bc91ff896 100644 --- a/Development/nmos/json_fields.h +++ b/Development/nmos/json_fields.h @@ -172,8 +172,9 @@ namespace nmos const web::json::field_as_value_or broker_authorization{ U("broker_authorization"), {} }; // string or bool const web::json::field_as_value_or broker_topic{ U("broker_topic"), {} }; // string or null const web::json::field_as_value_or connection_status_broker_topic{ U("connection_status_broker_topic"), {} }; // string or null - // for urn:x-nmos:transport:mxl - //const web::json::field_as_value flow_id{ U("flow_id") }; // see nmos::id + // for urn:x-nmos:transport:mxl (see AMWA BCP-007-03 NMOS With MXL) + const web::json::field_as_value_or mxl_domain_id{ U("mxl_domain_id"), {} }; // UUID string, auto, or null + const web::json::field_as_value_or mxl_flow_id{ U("mxl_flow_id"), {} }; // UUID string, auto, or null // IS-07 Event & Tally From d36cf53fbb9ef5af5da403464ba9a46f985268ff Mon Sep 17 00:00:00 2001 From: jonathan-r-thorpe Date: Wed, 6 May 2026 11:46:45 +0100 Subject: [PATCH 14/20] Make mxl domain id configurable --- Development/nmos-cpp-node/node_implementation.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Development/nmos-cpp-node/node_implementation.cpp b/Development/nmos-cpp-node/node_implementation.cpp index ace97122a..9cb721fac 100644 --- a/Development/nmos-cpp-node/node_implementation.cpp +++ b/Development/nmos-cpp-node/node_implementation.cpp @@ -127,6 +127,9 @@ namespace impl // simulate_status_monitor_activity: when true status monitor statuses will change randomly after activation const web::json::field_as_bool_or simulate_status_monitor_activity{U("simulate_status_monitor_activity"), true}; + + // mxl_domain_id: optional, used to override the generated MXL domain id + const web::json::field_as_string_or mxl_domain_id{ U("mxl_domain_id"), {} }; } nmos::interlace_mode get_interlace_mode(const nmos::settings& settings); @@ -409,7 +412,9 @@ void node_implementation_init(nmos::node_model& model, nmos::experimental::contr const auto seed_id = nmos::experimental::fields::seed_id(model.settings); const auto node_id = impl::make_id(seed_id, nmos::types::node); const auto device_id = impl::make_id(seed_id, nmos::types::device); - const auto mxl_domain_id = nmos::make_repeatable_id(seed_id, U("/x-nmos/mxl/domain")); + const nmos::id mxl_domain_id = model.settings.has_field(impl::fields::mxl_domain_id) + ? impl::fields::mxl_domain_id(model.settings) + : nmos::make_repeatable_id(seed_id, U("/x-nmos/mxl/domain")); const auto how_many = impl::fields::how_many(model.settings); const auto sender_ports = impl::parse_ports(impl::fields::senders(model.settings)); const auto rtp_sender_ports = boost::copy_range>(sender_ports | boost::adaptors::filtered(impl::is_rtp_port)); From b4389a7394e1fefa08e050bcc432aaf3f119c872 Mon Sep 17 00:00:00 2001 From: jonathan-r-thorpe Date: Wed, 6 May 2026 14:06:45 +0100 Subject: [PATCH 15/20] Added mxl_domain_id to config.json --- Development/nmos-cpp-node/config.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Development/nmos-cpp-node/config.json b/Development/nmos-cpp-node/config.json index 1545b1081..dbb43d263 100644 --- a/Development/nmos-cpp-node/config.json +++ b/Development/nmos-cpp-node/config.json @@ -198,6 +198,9 @@ // seed id [registry, node]: optional, used to generate repeatable id values when running with the same configuration //"seed_id": uuid-string, + // mxl_domain_id [node]: optional, overrides the generated MXL domain id used by MXL sender/receiver transport params + //"mxl_domain_id": uuid-string, + // label [registry, node]: used in resource label field //"label": "", From d2f8dbf29e415bf233f6aa81686cde3a2002b478 Mon Sep 17 00:00:00 2001 From: jonathan-r-thorpe Date: Wed, 6 May 2026 15:28:43 +0100 Subject: [PATCH 16/20] Ensure consistent mxl_domain_id and mxl_flow_id ordering --- Development/nmos/connection_api.cpp | 4 ++-- Development/nmos/connection_resources.cpp | 26 +++++++++++------------ Development/nmos/connection_resources.h | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Development/nmos/connection_api.cpp b/Development/nmos/connection_api.cpp index 864fd0bb5..9a7b34d27 100644 --- a/Development/nmos/connection_api.cpp +++ b/Development/nmos/connection_api.cpp @@ -251,8 +251,8 @@ namespace nmos { nmos::types::sender, { - nmos::fields::mxl_flow_id, - nmos::fields::mxl_domain_id + nmos::fields::mxl_domain_id, + nmos::fields::mxl_flow_id } }, { diff --git a/Development/nmos/connection_resources.cpp b/Development/nmos/connection_resources.cpp index 93c4512ed..55ddd4885 100644 --- a/Development/nmos/connection_resources.cpp +++ b/Development/nmos/connection_resources.cpp @@ -615,21 +615,21 @@ namespace nmos namespace details { - web::json::value make_connection_mxl_sender_core_constraints(const nmos::id& mxl_flow_id, const nmos::id& mxl_domain_id) + web::json::value make_connection_mxl_sender_core_constraints(const nmos::id& mxl_domain_id, const nmos::id& mxl_flow_id) { using web::json::value; using web::json::value_of; const auto unconstrained = value::object(); return value_of({ - { nmos::fields::mxl_flow_id, mxl_flow_id.empty() ? unconstrained : value_of({ + { nmos::fields::mxl_domain_id, mxl_domain_id.empty() ? unconstrained : value_of({ { nmos::fields::constraint_enum, value_of({ - mxl_flow_id + mxl_domain_id }) } }) }, - { nmos::fields::mxl_domain_id, mxl_domain_id.empty() ? unconstrained : value_of({ + { nmos::fields::mxl_flow_id, mxl_flow_id.empty() ? unconstrained : value_of({ { nmos::fields::constraint_enum, value_of({ - mxl_domain_id + mxl_flow_id }) } }) } }); @@ -641,8 +641,8 @@ namespace nmos using web::json::value_of; return value_of({ - { nmos::fields::mxl_flow_id, U("auto") }, - { nmos::fields::mxl_domain_id, U("auto") } + { nmos::fields::mxl_domain_id, U("auto") }, + { nmos::fields::mxl_flow_id, U("auto") } }); } @@ -653,12 +653,12 @@ namespace nmos const auto unconstrained = value::object(); return value_of({ - { nmos::fields::mxl_flow_id, unconstrained }, { nmos::fields::mxl_domain_id, mxl_domain_id.empty() ? unconstrained : value_of({ { nmos::fields::constraint_enum, value_of({ mxl_domain_id }) } - }) } + }) }, + { nmos::fields::mxl_flow_id, unconstrained } }); } @@ -668,13 +668,13 @@ namespace nmos using web::json::value_of; return value_of({ - { nmos::fields::mxl_flow_id, value::null() }, - { nmos::fields::mxl_domain_id, U("auto") } + { nmos::fields::mxl_domain_id, U("auto") }, + { nmos::fields::mxl_flow_id, value::null() } }); } } - nmos::resource make_connection_mxl_sender(const nmos::id& id, const nmos::id& mxl_flow_id, const nmos::id& mxl_domain_id) + nmos::resource make_connection_mxl_sender(const nmos::id& id, const nmos::id& mxl_domain_id, const nmos::id& mxl_flow_id) { using web::json::value; using web::json::value_of; @@ -683,7 +683,7 @@ namespace nmos auto data = details::make_connection_resource_core(id, redundant); - data[nmos::fields::endpoint_constraints] = details::legs_of(details::make_connection_mxl_sender_core_constraints(mxl_flow_id, mxl_domain_id), redundant); + data[nmos::fields::endpoint_constraints] = details::legs_of(details::make_connection_mxl_sender_core_constraints(mxl_domain_id, mxl_flow_id), redundant); data[nmos::fields::endpoint_staged][nmos::fields::receiver_id] = value::null(); data[nmos::fields::endpoint_staged][nmos::fields::transport_params] = details::legs_of(details::make_connection_mxl_sender_staged_core_parameter_set(), redundant); diff --git a/Development/nmos/connection_resources.h b/Development/nmos/connection_resources.h index 5f8b4ddc6..2f757a728 100644 --- a/Development/nmos/connection_resources.h +++ b/Development/nmos/connection_resources.h @@ -61,7 +61,7 @@ namespace nmos utility::string_t make_events_mqtt_broker_topic(const nmos::id& source_id, const nmos::settings& settings); utility::string_t make_events_mqtt_connection_status_broker_topic(const nmos::id& connection_id, const nmos::settings& settings); - nmos::resource make_connection_mxl_sender(const nmos::id& id, const nmos::id& mxl_flow_id, const nmos::id& mxl_domain_id); + nmos::resource make_connection_mxl_sender(const nmos::id& id, const nmos::id& mxl_domain_id, const nmos::id& mxl_flow_id); nmos::resource make_connection_mxl_receiver(const nmos::id& id, const nmos::id& mxl_domain_id); } From 6a31cab8c819a623efa611568f732ff4f69d8fd2 Mon Sep 17 00:00:00 2001 From: jonathan-r-thorpe Date: Fri, 15 May 2026 12:17:02 +0100 Subject: [PATCH 17/20] Update MXL configuration and implementation according to latest draft of BCP-007-03 --- Development/nmos-cpp-node/config.json | 9 +-- .../nmos-cpp-node/node_implementation.cpp | 66 ++++++++++++++----- Development/nmos/connection_api.cpp | 20 +++++- Development/nmos/json_fields.h | 2 +- .../receiver_transport_params_mxl.json | 5 +- 5 files changed, 74 insertions(+), 28 deletions(-) diff --git a/Development/nmos-cpp-node/config.json b/Development/nmos-cpp-node/config.json index dbb43d263..6501951e3 100644 --- a/Development/nmos-cpp-node/config.json +++ b/Development/nmos-cpp-node/config.json @@ -22,9 +22,10 @@ // senders, receivers: controls which kinds of sender and receiver are instantiated by the example node // the values must be an array of unique strings identifying the kinds of 'port', like ["v", "a", "d"], see impl::ports + // for MXL Senders and Receivers, the values must be ["xv", "xa", "xd"] // when omitted, all ports are instantiated - "senders": ["xv", "xa", "xd"], - "receivers": ["xv", "xa", "xd"], + //"senders": ["v", "a", "d"], + //"receivers": ["v", "a", "d"], // frame_rate: controls the grain_rate of video, audio and ancillary data sources and flows // and the equivalent parameter constraint on video receivers @@ -51,8 +52,8 @@ // component_depth: controls the bits per component sample of video flows //"component_depth": 10, - // video_type: media type of video flows, e.g. "video/raw" or "video/jxsv", see nmos::media_types - "video_type": "video/v210", + // video_type: media type of video flows, e.g. "video/raw", "video/jxsv", or "video/v210" for MXL Senders and Receivers, see nmos::media_types + //"video_type": "video/raw", // channel_count: controls the number of channels in audio sources //"channel_count": 8, diff --git a/Development/nmos-cpp-node/node_implementation.cpp b/Development/nmos-cpp-node/node_implementation.cpp index 9cb721fac..aba7fd005 100644 --- a/Development/nmos-cpp-node/node_implementation.cpp +++ b/Development/nmos-cpp-node/node_implementation.cpp @@ -985,7 +985,7 @@ void node_implementation_init(nmos::node_model& model, nmos::experimental::contr impl::set_label_description(sender, port, index); impl::insert_group_hint(sender, port, index); - auto connection_sender = nmos::make_connection_mxl_sender(sender_id, flow_id, mxl_domain_id); + auto connection_sender = nmos::make_connection_mxl_sender(sender_id, mxl_domain_id, flow_id); if (impl::fields::activate_senders(model.settings)) { @@ -1017,14 +1017,61 @@ void node_implementation_init(nmos::node_model& model, nmos::experimental::contr if (impl::ports::mxl_video == port) { receiver = nmos::make_receiver(receiver_id, device_id, nmos::transports::mxl, {}, nmos::formats::video, { video_type }, model.settings); + if (nmos::media_types::video_raw == video_type) + { + const auto interlace_modes = nmos::interlace_modes::progressive != interlace_mode + ? std::vector{ nmos::interlace_modes::interlaced_bff.name, nmos::interlace_modes::interlaced_tff.name, nmos::interlace_modes::interlaced_psf.name } + : std::vector{ nmos::interlace_modes::progressive.name }; + receiver.data[nmos::fields::caps][nmos::fields::constraint_sets] = value_of({ + value_of({ + { nmos::caps::format::grain_rate, nmos::make_caps_rational_constraint({ frame_rate }) }, + { nmos::caps::format::frame_width, nmos::make_caps_integer_constraint({ frame_width }) }, + { nmos::caps::format::frame_height, nmos::make_caps_integer_constraint({ frame_height }) }, + { nmos::caps::format::interlace_mode, nmos::make_caps_string_constraint(interlace_modes) }, + { nmos::caps::format::color_sampling, nmos::make_caps_string_constraint({ sampling.name }) } + }) + }); + } + else if (nmos::media_types::video_jxsv == video_type) + { + const auto max_format_bit_rate = nmos::get_video_jxsv_bit_rate(frame_rate, frame_width, frame_height, max_bits_per_pixel); + const auto max_transport_bit_rate = uint64_t(transport_bit_rate_factor * max_format_bit_rate / 1e3 + 0.5) * 1000; + + receiver.data[nmos::fields::caps][nmos::fields::constraint_sets] = value_of({ + value_of({ + { nmos::caps::format::profile, nmos::make_caps_string_constraint({ profile.name }) }, + { nmos::caps::format::level, nmos::make_caps_string_constraint({ level.name }) }, + { nmos::caps::format::sublevel, nmos::make_caps_string_constraint({ nmos::sublevels::Sublev3bpp.name, nmos::sublevels::Sublev4bpp.name }) }, + { nmos::caps::format::bit_rate, nmos::make_caps_integer_constraint({}, nmos::no_minimum(), (int64_t)max_format_bit_rate) }, + { nmos::caps::transport::bit_rate, nmos::make_caps_integer_constraint({}, nmos::no_minimum(), (int64_t)max_transport_bit_rate) }, + { nmos::caps::transport::packet_transmission_mode, nmos::make_caps_string_constraint({ nmos::packet_transmission_modes::codestream.name }) } + }) + }); + } + receiver.data[nmos::fields::version] = receiver.data[nmos::fields::caps][nmos::fields::version] = value(nmos::make_version()); } else if (impl::ports::mxl_audio == port) { receiver = nmos::make_receiver(receiver_id, device_id, nmos::transports::mxl, {}, nmos::formats::audio, { nmos::media_type{ U("audio/float32") } }, model.settings); + receiver.data[nmos::fields::caps][nmos::fields::constraint_sets] = value_of({ + value_of({ + { nmos::caps::format::media_type, nmos::make_caps_string_constraint({ U("audio/float32") }) }, + { nmos::caps::format::channel_count, nmos::make_caps_integer_constraint({}, 1, channel_count) }, + { nmos::caps::format::sample_rate, nmos::make_caps_rational_constraint({ { 48000, 1 } }) }, + { nmos::caps::format::sample_depth, nmos::make_caps_integer_constraint({ 32 }) } + }) + }); + receiver.data[nmos::fields::version] = receiver.data[nmos::fields::caps][nmos::fields::version] = value(nmos::make_version()); } else if (impl::ports::mxl_data == port) { receiver = nmos::make_sdianc_data_receiver(receiver_id, device_id, nmos::transports::mxl, {}, model.settings); + receiver.data[nmos::fields::caps][nmos::fields::constraint_sets] = value_of({ + value_of({ + { nmos::caps::format::grain_rate, nmos::make_caps_rational_constraint({ frame_rate }) } + }) + }); + receiver.data[nmos::fields::version] = receiver.data[nmos::fields::caps][nmos::fields::version] = value(nmos::make_version()); } impl::set_label_description(receiver, port, index); impl::insert_group_hint(receiver, port, index); @@ -2072,26 +2119,13 @@ nmos::connection_resource_auto_resolver make_node_implementation_auto_resolver(c } else if (mxl_sender_ids.end() != boost::range::find(mxl_sender_ids, id_type.first)) { - nmos::details::resolve_auto(transport_params[0], nmos::fields::mxl_flow_id, [&] { return web::json::front(nmos::fields::constraint_enum(constraints.at(0).at(nmos::fields::mxl_flow_id))); }); nmos::details::resolve_auto(transport_params[0], nmos::fields::mxl_domain_id, [&] { return web::json::front(nmos::fields::constraint_enum(constraints.at(0).at(nmos::fields::mxl_domain_id))); }); + nmos::details::resolve_auto(transport_params[0], nmos::fields::mxl_flow_id, [&] { return web::json::front(nmos::fields::constraint_enum(constraints.at(0).at(nmos::fields::mxl_flow_id))); }); } else if (mxl_receiver_ids.end() != boost::range::find(mxl_receiver_ids, id_type.first)) { + // BCP-007-03: mxl_flow_id does not use "auto" on receivers (UUID or null only). nmos::details::resolve_auto(transport_params[0], nmos::fields::mxl_domain_id, [&] { return web::json::front(nmos::fields::constraint_enum(constraints.at(0).at(nmos::fields::mxl_domain_id))); }); - // mxl_flow_id may be unconstrained on receivers; resolve auto only when constraints enumerate values - nmos::details::resolve_auto(transport_params[0], nmos::fields::mxl_flow_id, [&] - { - const auto& fc = constraints.at(0).at(nmos::fields::mxl_flow_id); - if (fc.is_object() && fc.has_field(nmos::fields::constraint_enum)) - { - const auto& en = nmos::fields::constraint_enum(fc); - if (en.is_array() && 0 != en.as_array().size()) - { - return web::json::front(en); - } - } - return web::json::value::null(); - }); } }; } diff --git a/Development/nmos/connection_api.cpp b/Development/nmos/connection_api.cpp index 9a7b34d27..aa9994a84 100644 --- a/Development/nmos/connection_api.cpp +++ b/Development/nmos/connection_api.cpp @@ -246,6 +246,8 @@ namespace nmos static const std::map>& mxl_auto_constraints() { // These are the constraints that support "auto" in /staged + // BCP-007-03: MXL Receivers MUST NOT use "auto" for mxl_flow_id (domain only). + // See https://specs.amwa.tv/bcp-007-03/branches/publish-auto-null/docs/NMOS-With-MXL.html static const std::map> auto_constraints { { @@ -258,8 +260,7 @@ namespace nmos { nmos::types::receiver, { - nmos::fields::mxl_domain_id, - nmos::fields::mxl_flow_id + nmos::fields::mxl_domain_id } } }; @@ -518,6 +519,20 @@ namespace nmos throw std::logic_error("matching IS-04 and IS-05 resources not found"); } + const nmos::transport transport_subclassification(nmos::fields::transport(matching_resource->data)); + + // BCP-007-03: PATCH /staged for MXL receivers must not contain transport_file. + // See https://specs.amwa.tv/bcp-007-03/branches/publish-auto-null/docs/NMOS-With-MXL.html + if (nmos::types::receiver == id_type.second && nmos::transports::mxl == nmos::transport_base(transport_subclassification)) + { + if (patch.has_field(nmos::fields::transport_file.key)) + { + slog::log(gate, SLOG_FLF) << "Rejecting PATCH for MXL receiver with transport_file"; + + return details::make_connection_resource_patch_error_response(status_codes::BadRequest, U("transport_file must not be used with MXL receivers")); + } + } + // Merge this patch request into a *copy* of the current staged endpoint // so that the merged parameters can be validated against the constraints // before the current values are overwritten. @@ -578,7 +593,6 @@ namespace nmos slog::log(gate, SLOG_FLF) << "Validating staged transport parameters against constraints"; - const nmos::transport transport_subclassification(nmos::fields::transport(matching_resource->data)); details::validate_staged_constraints(resource->type, nmos::fields::endpoint_constraints(resource->data), nmos::transport_base(transport_subclassification), merged); // Perform any final validation diff --git a/Development/nmos/json_fields.h b/Development/nmos/json_fields.h index bc91ff896..e195e61ae 100644 --- a/Development/nmos/json_fields.h +++ b/Development/nmos/json_fields.h @@ -174,7 +174,7 @@ namespace nmos const web::json::field_as_value_or connection_status_broker_topic{ U("connection_status_broker_topic"), {} }; // string or null // for urn:x-nmos:transport:mxl (see AMWA BCP-007-03 NMOS With MXL) const web::json::field_as_value_or mxl_domain_id{ U("mxl_domain_id"), {} }; // UUID string, auto, or null - const web::json::field_as_value_or mxl_flow_id{ U("mxl_flow_id"), {} }; // UUID string, auto, or null + const web::json::field_as_value_or mxl_flow_id{ U("mxl_flow_id"), {} }; // senders: UUID, auto, or null; receivers: UUID or null (BCP-007-03) // IS-07 Event & Tally diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json index bc20bbf5b..c1153be59 100644 --- a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json @@ -26,13 +26,10 @@ "string", "null" ], - "description": "MXL flow identity for the read operation. Need not match the IS-04 Flow id. Use auto to select from constraints.", + "description": "MXL flow identity for the read operation. Need not match the IS-04 Flow id. BCP-007-03: null or UUID only; the literal auto is not used for receivers.", "anyOf": [{ "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$" }, - { - "pattern": "^auto$" - }, { "type": "null" } From c70da56f101bba83adac29f8c188ac24162afb7d Mon Sep 17 00:00:00 2001 From: jonathan-r-thorpe <64410119+jonathan-r-thorpe@users.noreply.github.com> Date: Mon, 18 May 2026 16:54:15 +0100 Subject: [PATCH 18/20] Apply suggestions from code review Co-authored-by: Gareth Sylvester-Bradley <31761158+garethsb@users.noreply.github.com> --- Development/nmos-cpp-node/config.json | 5 +++-- Development/nmos/is05_schemas/is05_schemas.h | 2 +- Development/nmos/json_schema.cpp | 6 +++--- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Development/nmos-cpp-node/config.json b/Development/nmos-cpp-node/config.json index 6501951e3..5e798bfa6 100644 --- a/Development/nmos-cpp-node/config.json +++ b/Development/nmos-cpp-node/config.json @@ -22,7 +22,7 @@ // senders, receivers: controls which kinds of sender and receiver are instantiated by the example node // the values must be an array of unique strings identifying the kinds of 'port', like ["v", "a", "d"], see impl::ports - // for MXL Senders and Receivers, the values must be ["xv", "xa", "xd"] + // for MXL senders and receivers, the values must be like ["xv", "xa", "xd"] // when omitted, all ports are instantiated //"senders": ["v", "a", "d"], //"receivers": ["v", "a", "d"], @@ -52,7 +52,8 @@ // component_depth: controls the bits per component sample of video flows //"component_depth": 10, - // video_type: media type of video flows, e.g. "video/raw", "video/jxsv", or "video/v210" for MXL Senders and Receivers, see nmos::media_types + // video_type: media type of video flows, e.g. "video/raw", "video/jxsv" for ST 2110 senders and receivers + // or "video/v210" for MXL senders and receivers, see nmos::media_types //"video_type": "video/raw", // channel_count: controls the number of channels in audio sources diff --git a/Development/nmos/is05_schemas/is05_schemas.h b/Development/nmos/is05_schemas/is05_schemas.h index 2c3db393a..7b2fecee2 100644 --- a/Development/nmos/is05_schemas/is05_schemas.h +++ b/Development/nmos/is05_schemas/is05_schemas.h @@ -7,7 +7,7 @@ namespace nmos { namespace is05_schemas { - namespace v1_2_x + namespace v1_2_dev { extern const char* activation_schema; extern const char* sender_stage_schema; diff --git a/Development/nmos/json_schema.cpp b/Development/nmos/json_schema.cpp index e6491e7f0..ab021e059 100644 --- a/Development/nmos/json_schema.cpp +++ b/Development/nmos/json_schema.cpp @@ -77,11 +77,11 @@ namespace nmos return{ _XPLATSTR("https://github.com/AMWA-TV/is-05/raw/") + tag + _XPLATSTR("/APIs/schemas/") + ref }; } - // See https://github.com/AMWA-TV/is-05/blob/v1.2.x/APIs/schemas/ + // See https://github.com/AMWA-TV/is-05/blob/v1.2-dev/APIs/schemas/ namespace v1_2 { - using namespace nmos::is05_schemas::v1_2_x; - const utility::string_t tag(_XPLATSTR("v1.2.x")); + using namespace nmos::is05_schemas::v1_2_dev; + const utility::string_t tag(_XPLATSTR("v1.2-dev")); const web::uri connectionapi_sender_staged_patch_request_uri = make_schema_uri(tag, _XPLATSTR("sender-stage-schema.json")); const web::uri connectionapi_receiver_staged_patch_request_uri = make_schema_uri(tag, _XPLATSTR("receiver-stage-schema.json")); From 255da9bd1873e5f0d69ad5530adf329be4b589a5 Mon Sep 17 00:00:00 2001 From: jonathan-r-thorpe Date: Mon, 18 May 2026 16:55:54 +0100 Subject: [PATCH 19/20] Patch to fix the build-test workflow. --- .github/workflows/build-test.yml | 2 ++ .github/workflows/src/amwa-test.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 18c0cdfa9..b3efeac6a 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -429,6 +429,8 @@ jobs: run_python="python" fi pip install -r utilities/run-test-suites/gsheetsImport/requirements.txt + # PyOpenSSL 26.2+ removed OpenSSL.crypto.X509Extension; nmos-testing still uses it for certificate tests. + $run_python -m pip install 'pyOpenSSL<26.2' if [[ "${{ runner.os }}" == "Windows" ]]; then # install certificates diff --git a/.github/workflows/src/amwa-test.yml b/.github/workflows/src/amwa-test.yml index 68f7778b1..b0f2151f8 100644 --- a/.github/workflows/src/amwa-test.yml +++ b/.github/workflows/src/amwa-test.yml @@ -76,6 +76,8 @@ run_python="python" fi pip install -r utilities/run-test-suites/gsheetsImport/requirements.txt + # PyOpenSSL 26.2+ removed OpenSSL.crypto.X509Extension; nmos-testing still uses it for certificate tests. + $run_python -m pip install 'pyOpenSSL<26.2' if [[ "${{ runner.os }}" == "Windows" ]]; then # install certificates From 9aefbc4990fe177208ad18e37d15f210e131dc9f Mon Sep 17 00:00:00 2001 From: jonathan-r-thorpe Date: Mon, 18 May 2026 17:38:10 +0100 Subject: [PATCH 20/20] Moved IS-05 v1.2.x schemas to v1.2-dev. --- Development/cmake/NmosCppLibraries.cmake | 2 +- .../APIs/schemas/activation-response-schema.json | 0 .../{v1.2.x => v1.2-dev}/APIs/schemas/activation-schema.json | 0 .../APIs/schemas/bulk-receiver-post-schema.json | 0 .../{v1.2.x => v1.2-dev}/APIs/schemas/bulk-response-schema.json | 0 .../APIs/schemas/bulk-sender-post-schema.json | 0 .../{v1.2.x => v1.2-dev}/APIs/schemas/connectionapi-base.json | 0 .../{v1.2.x => v1.2-dev}/APIs/schemas/connectionapi-bulk.json | 0 .../APIs/schemas/connectionapi-receiver.json | 0 .../{v1.2.x => v1.2-dev}/APIs/schemas/connectionapi-sender.json | 0 .../{v1.2.x => v1.2-dev}/APIs/schemas/connectionapi-single.json | 0 .../{v1.2.x => v1.2-dev}/APIs/schemas/constraint-schema.json | 0 .../APIs/schemas/constraints-schema-mqtt.json | 0 .../APIs/schemas/constraints-schema-rtp.json | 0 .../APIs/schemas/constraints-schema-websocket.json | 0 .../{v1.2.x => v1.2-dev}/APIs/schemas/constraints-schema.json | 0 .../is-05/{v1.2.x => v1.2-dev}/APIs/schemas/error.json | 0 .../APIs/schemas/receiver-response-schema.json | 0 .../APIs/schemas/receiver-stage-schema.json | 0 .../APIs/schemas/receiver-transport-file.json | 0 .../APIs/schemas/receiver_transport_params.json | 0 .../APIs/schemas/receiver_transport_params_dash.json | 0 .../APIs/schemas/receiver_transport_params_ext.json | 0 .../APIs/schemas/receiver_transport_params_mqtt.json | 0 .../APIs/schemas/receiver_transport_params_mxl.json | 0 .../APIs/schemas/receiver_transport_params_rtp.json | 0 .../APIs/schemas/receiver_transport_params_websocket.json | 0 .../{v1.2.x => v1.2-dev}/APIs/schemas/sender-receiver-base.json | 0 .../APIs/schemas/sender-response-schema.json | 0 .../{v1.2.x => v1.2-dev}/APIs/schemas/sender-stage-schema.json | 0 .../APIs/schemas/sender_transport_params.json | 0 .../APIs/schemas/sender_transport_params_dash.json | 0 .../APIs/schemas/sender_transport_params_ext.json | 0 .../APIs/schemas/sender_transport_params_mqtt.json | 0 .../APIs/schemas/sender_transport_params_mxl.json | 0 .../APIs/schemas/sender_transport_params_rtp.json | 0 .../APIs/schemas/sender_transport_params_websocket.json | 0 .../APIs/schemas/transporttype-response-schema.json | 0 38 files changed, 1 insertion(+), 1 deletion(-) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/activation-response-schema.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/activation-schema.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/bulk-receiver-post-schema.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/bulk-response-schema.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/bulk-sender-post-schema.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/connectionapi-base.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/connectionapi-bulk.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/connectionapi-receiver.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/connectionapi-sender.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/connectionapi-single.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/constraint-schema.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/constraints-schema-mqtt.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/constraints-schema-rtp.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/constraints-schema-websocket.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/constraints-schema.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/error.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/receiver-response-schema.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/receiver-stage-schema.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/receiver-transport-file.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/receiver_transport_params.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/receiver_transport_params_dash.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/receiver_transport_params_ext.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/receiver_transport_params_mqtt.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/receiver_transport_params_mxl.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/receiver_transport_params_rtp.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/receiver_transport_params_websocket.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/sender-receiver-base.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/sender-response-schema.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/sender-stage-schema.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/sender_transport_params.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/sender_transport_params_dash.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/sender_transport_params_ext.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/sender_transport_params_mqtt.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/sender_transport_params_mxl.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/sender_transport_params_rtp.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/sender_transport_params_websocket.json (100%) rename Development/third_party/is-05/{v1.2.x => v1.2-dev}/APIs/schemas/transporttype-response-schema.json (100%) diff --git a/Development/cmake/NmosCppLibraries.cmake b/Development/cmake/NmosCppLibraries.cmake index 982e000b0..ea1fe5f89 100644 --- a/Development/cmake/NmosCppLibraries.cmake +++ b/Development/cmake/NmosCppLibraries.cmake @@ -407,7 +407,7 @@ set(NMOS_IS05_SCHEMAS_HEADERS nmos/is05_schemas/is05_schemas.h ) -set(NMOS_IS05_V1_2_TAG v1.2.x) +set(NMOS_IS05_V1_2_TAG v1.2-dev) set(NMOS_IS05_V1_1_TAG v1.1.x) set(NMOS_IS05_V1_0_TAG v1.0.x) diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/activation-response-schema.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/activation-response-schema.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/activation-response-schema.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/activation-response-schema.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/activation-schema.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/activation-schema.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/activation-schema.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/activation-schema.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-receiver-post-schema.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/bulk-receiver-post-schema.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-receiver-post-schema.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/bulk-receiver-post-schema.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-response-schema.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/bulk-response-schema.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-response-schema.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/bulk-response-schema.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-sender-post-schema.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/bulk-sender-post-schema.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/bulk-sender-post-schema.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/bulk-sender-post-schema.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-base.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/connectionapi-base.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-base.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/connectionapi-base.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-bulk.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/connectionapi-bulk.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-bulk.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/connectionapi-bulk.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-receiver.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/connectionapi-receiver.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-receiver.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/connectionapi-receiver.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-sender.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/connectionapi-sender.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-sender.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/connectionapi-sender.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-single.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/connectionapi-single.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/connectionapi-single.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/connectionapi-single.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/constraint-schema.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/constraint-schema.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/constraint-schema.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/constraint-schema.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-mqtt.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/constraints-schema-mqtt.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-mqtt.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/constraints-schema-mqtt.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-rtp.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/constraints-schema-rtp.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-rtp.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/constraints-schema-rtp.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-websocket.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/constraints-schema-websocket.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema-websocket.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/constraints-schema-websocket.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/constraints-schema.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/constraints-schema.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/constraints-schema.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/error.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/error.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/error.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/error.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-response-schema.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver-response-schema.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-response-schema.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver-response-schema.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-stage-schema.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver-stage-schema.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-stage-schema.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver-stage-schema.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-transport-file.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver-transport-file.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/receiver-transport-file.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver-transport-file.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver_transport_params.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver_transport_params.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_dash.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver_transport_params_dash.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_dash.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver_transport_params_dash.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_ext.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver_transport_params_ext.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_ext.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver_transport_params_ext.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mqtt.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver_transport_params_mqtt.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mqtt.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver_transport_params_mqtt.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver_transport_params_mxl.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver_transport_params_mxl.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_rtp.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver_transport_params_rtp.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_rtp.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver_transport_params_rtp.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_websocket.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver_transport_params_websocket.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_websocket.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/receiver_transport_params_websocket.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender-receiver-base.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/sender-receiver-base.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/sender-receiver-base.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/sender-receiver-base.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender-response-schema.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/sender-response-schema.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/sender-response-schema.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/sender-response-schema.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender-stage-schema.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/sender-stage-schema.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/sender-stage-schema.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/sender-stage-schema.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/sender_transport_params.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/sender_transport_params.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_dash.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/sender_transport_params_dash.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_dash.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/sender_transport_params_dash.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_ext.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/sender_transport_params_ext.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_ext.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/sender_transport_params_ext.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mqtt.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/sender_transport_params_mqtt.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mqtt.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/sender_transport_params_mqtt.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/sender_transport_params_mxl.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/sender_transport_params_mxl.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_rtp.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/sender_transport_params_rtp.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_rtp.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/sender_transport_params_rtp.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_websocket.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/sender_transport_params_websocket.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_websocket.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/sender_transport_params_websocket.json diff --git a/Development/third_party/is-05/v1.2.x/APIs/schemas/transporttype-response-schema.json b/Development/third_party/is-05/v1.2-dev/APIs/schemas/transporttype-response-schema.json similarity index 100% rename from Development/third_party/is-05/v1.2.x/APIs/schemas/transporttype-response-schema.json rename to Development/third_party/is-05/v1.2-dev/APIs/schemas/transporttype-response-schema.json