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}) diff --git a/Development/nmos-cpp-node/config.json b/Development/nmos-cpp-node/config.json index c529de695..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": ["v", "a"], - //"receivers": [], + //"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/jxsv", + // 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, @@ -198,6 +199,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": "", diff --git a/Development/nmos-cpp-node/node_implementation.cpp b/Development/nmos-cpp-node/node_implementation.cpp index 1e074fe23..aba7fd005 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); @@ -154,13 +157,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{ @@ -400,13 +412,18 @@ 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 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)); 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 +545,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 +690,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 +921,168 @@ 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, mxl_domain_id, flow_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); + 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); + + 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(); + } + } + // example channelmapping resources demonstrating a range of input/output capabilities // see https://github.com/sony/nmos-cpp/issues/111#issuecomment-740613137 @@ -1545,7 +1725,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; @@ -1883,19 +2064,25 @@ 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); + 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](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 @@ -1930,6 +2117,16 @@ 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::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))); }); + } }; } @@ -2263,6 +2460,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; diff --git a/Development/nmos/connection_api.cpp b/Development/nmos/connection_api.cpp index eb63bcafb..aa9994a84 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 } } }; @@ -240,13 +243,46 @@ namespace nmos return auto_constraints; } + 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 + { + { + nmos::types::sender, + { + nmos::fields::mxl_domain_id, + nmos::fields::mxl_flow_id + } + }, + { + nmos::types::receiver, + { + nmos::fields::mxl_domain_id + } + } + }; + 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(); - static const std::map> no_auto_constraints; + static const std::map> no_auto_constraints + { + { + nmos::types::sender, {} + }, + { + nmos::types::receiver, {} + } + }; return no_auto_constraints; } @@ -483,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. @@ -543,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/connection_resources.cpp b/Development/nmos/connection_resources.cpp index 79d81a7e9..55ddd4885 100644 --- a/Development/nmos/connection_resources.cpp +++ b/Development/nmos/connection_resources.cpp @@ -612,4 +612,108 @@ 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(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_domain_id, mxl_domain_id.empty() ? unconstrained : value_of({ + { nmos::fields::constraint_enum, value_of({ + mxl_domain_id + }) } + }) }, + { nmos::fields::mxl_flow_id, mxl_flow_id.empty() ? unconstrained : value_of({ + { nmos::fields::constraint_enum, value_of({ + mxl_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::mxl_domain_id, U("auto") }, + { nmos::fields::mxl_flow_id, U("auto") } + }); + } + + 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::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 } + }); + } + + 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::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_domain_id, const nmos::id& mxl_flow_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(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); + + 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 + + return{ is05_versions::v1_2, types::sender, std::move(data), false }; + } + + nmos::resource make_connection_mxl_receiver(const nmos::id& id, const nmos::id& mxl_domain_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(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(); + 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..2f757a728 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, 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); } #endif diff --git a/Development/nmos/is05_schemas/is05_schemas.h b/Development/nmos/is05_schemas/is05_schemas.h index 4550dbe77..2c3db393a 100644 --- a/Development/nmos/is05_schemas/is05_schemas.h +++ b/Development/nmos/is05_schemas/is05_schemas.h @@ -7,6 +7,28 @@ 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_mxl; + 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_mxl; + 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_fields.h b/Development/nmos/json_fields.h index 0ff9921db..e195e61ae 100644 --- a/Development/nmos/json_fields.h +++ b/Development/nmos/json_fields.h @@ -172,6 +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 (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"), {} }; // senders: UUID, auto, or null; receivers: UUID or null (BCP-007-03) // IS-07 Event & Tally diff --git a/Development/nmos/json_schema.cpp b/Development/nmos/json_schema.cpp index 3860509ca..e6491e7f0 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,25 @@ 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_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) }, { make_schema_uri(v1_1::tag, _XPLATSTR("receiver-stage-schema.json")), make_schema(v1_1::receiver_stage_schema) }, @@ -487,12 +516,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; } 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." 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..b6c9aa6dc --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params.json @@ -0,0 +1,36 @@ +{ + "$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" + } + }, + { + "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_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_mxl.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json new file mode 100644 index 000000000..c1153be59 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/receiver_transport_params_mxl.json @@ -0,0 +1,45 @@ +{ + "$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": { + "mxl_domain_id": { + "type": [ + "string", + "null" + ], + "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. 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}$" + }, + { + "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/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..c8d0d7586 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params.json @@ -0,0 +1,36 @@ +{ + "$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" + } + }, + { + "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_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_mxl.json b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json new file mode 100644 index 000000000..527b1c908 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/sender_transport_params_mxl.json @@ -0,0 +1,48 @@ +{ + "$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": { + "mxl_domain_id": { + "type": [ + "string", + "null" + ], + "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}$" + }, + { + "pattern": "^auto$" + }, + { + "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/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..6a3f1a346 --- /dev/null +++ b/Development/third_party/is-05/v1.2.x/APIs/schemas/transporttype-response-schema.json @@ -0,0 +1,18 @@ +{ + "$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", + "urn:x-nmos:transport:mxl" + ] + } + ], + "format": "uri" +}