You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
432 lines
15 KiB
432 lines
15 KiB
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://adn.systems/schemas/report-v2.json",
|
|
"title": "ADN Monitor Report Protocol v2",
|
|
"description": "JSON payloads for the TCP report channel (netstring-framed). Legacy v1 uses pickle CONFIG_SND/BRIDGE_SND and CSV BRDG_EVENT; v2 replaces those with typed JSON. Wire opcodes are defined in docs/en/server/protocols/report-v2.md.",
|
|
"type": "object",
|
|
"required": ["type"],
|
|
"oneOf": [
|
|
{ "$ref": "#/$defs/hello" },
|
|
{ "$ref": "#/$defs/dashboard_state" },
|
|
{ "$ref": "#/$defs/topology" },
|
|
{ "$ref": "#/$defs/routing_table" },
|
|
{ "$ref": "#/$defs/voice_event" },
|
|
{ "$ref": "#/$defs/delta" }
|
|
],
|
|
"$defs": {
|
|
"dmr_id": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 16777215,
|
|
"description": "DMR radio ID or talkgroup (24-bit)."
|
|
},
|
|
"stream_id": {
|
|
"type": "integer",
|
|
"minimum": 0,
|
|
"maximum": 4294967295,
|
|
"description": "HBP stream identifier (32-bit, unsigned)."
|
|
},
|
|
"slot": {
|
|
"type": "integer",
|
|
"enum": [1, 2]
|
|
},
|
|
"system_mode": {
|
|
"type": "string",
|
|
"enum": ["MASTER", "PEER", "OPENBRIDGE"]
|
|
},
|
|
"to_type": {
|
|
"type": "string",
|
|
"enum": ["ON", "OFF", "STAT", "NONE"],
|
|
"description": "Legacy BRIDGES TO_TYPE semantics until subscription model (Phase 2)."
|
|
},
|
|
"hello": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["type", "server", "version", "report_protocol", "features"],
|
|
"properties": {
|
|
"type": { "const": "hello" },
|
|
"server": { "type": "string", "minLength": 1 },
|
|
"version": { "type": "string", "minLength": 1, "description": "adn-server package version." },
|
|
"report_protocol": {
|
|
"type": "integer",
|
|
"const": 2,
|
|
"description": "Report payload schema version (distinct from legacy HELLO protocol field value 1)."
|
|
},
|
|
"features": {
|
|
"type": "array",
|
|
"items": { "type": "string" },
|
|
"uniqueItems": true,
|
|
"description": "Capability tokens. v1: INGRESS, END_TX_FORWARD, PUSH_ON_CONNECT. v2 adds REPORT_V2, ROUTING_TABLE_JSON, VOICE_EVENT_JSON, DELTA_UPDATES. TCP monitor uses dashboard_state (STATE_SND), not topology."
|
|
},
|
|
"systems": {
|
|
"type": "array",
|
|
"items": { "type": "string" },
|
|
"description": "Optional hint: enabled system names with at least one connected peer or upstream link. Omitted when none. Full topology (all systems) follows in the topology message."
|
|
}
|
|
}
|
|
},
|
|
"dashboard_peer": {
|
|
"type": "object",
|
|
"additionalProperties": true,
|
|
"required": ["id", "connected"],
|
|
"properties": {
|
|
"id": { "$ref": "#/$defs/dmr_id" },
|
|
"connected": { "type": "boolean" },
|
|
"ip": { "type": "string" },
|
|
"port": { "type": "integer", "minimum": 0, "maximum": 65535 },
|
|
"callsign": { "type": "string" },
|
|
"connected_at": { "type": "integer" },
|
|
"options": { "type": "string" },
|
|
"ts1_static": {
|
|
"type": "array",
|
|
"items": { "type": "string" }
|
|
},
|
|
"ts2_static": {
|
|
"type": "array",
|
|
"items": { "type": "string" }
|
|
},
|
|
"single_mode": { "type": "boolean" },
|
|
"ua_timer_min": { "type": "number", "minimum": 0 },
|
|
"ua_sessions": {
|
|
"type": "object",
|
|
"additionalProperties": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["tgid", "expires_at"],
|
|
"properties": {
|
|
"tgid": { "$ref": "#/$defs/dmr_id" },
|
|
"expires_at": { "type": "number" }
|
|
}
|
|
}
|
|
},
|
|
"ua_multi_tgs": {
|
|
"type": "object",
|
|
"additionalProperties": {
|
|
"type": "array",
|
|
"items": { "type": "string" }
|
|
}
|
|
},
|
|
"rf_mode": {
|
|
"type": "string",
|
|
"enum": ["simplex", "duplex"]
|
|
}
|
|
}
|
|
},
|
|
"dashboard_master": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["mode", "peers"],
|
|
"properties": {
|
|
"mode": { "const": "MASTER" },
|
|
"peers": {
|
|
"type": "object",
|
|
"additionalProperties": { "$ref": "#/$defs/dashboard_peer" }
|
|
},
|
|
"single_mode": { "type": "boolean" },
|
|
"default_ua_timer": { "type": "number", "minimum": 0 },
|
|
"ip": { "type": "string" },
|
|
"port": { "type": "integer", "minimum": 0, "maximum": 65535 }
|
|
}
|
|
},
|
|
"dashboard_upstream_peer": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["mode", "connected"],
|
|
"properties": {
|
|
"mode": { "type": "string", "enum": ["PEER", "XLXPEER"] },
|
|
"connected": { "type": "boolean" },
|
|
"callsign": { "type": "string" },
|
|
"location": { "type": "string" },
|
|
"description": { "type": "string" },
|
|
"url": { "type": "string" },
|
|
"master_ip": { "type": "string" },
|
|
"master_port": { "type": "integer", "minimum": 0, "maximum": 65535 },
|
|
"radio_id": { "$ref": "#/$defs/dmr_id" },
|
|
"connected_at": { "type": "integer" }
|
|
}
|
|
},
|
|
"dashboard_openbridge": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["mode", "streams"],
|
|
"properties": {
|
|
"mode": { "const": "OPENBRIDGE" },
|
|
"streams": { "type": "object" },
|
|
"network_id": { "$ref": "#/$defs/dmr_id" },
|
|
"ip": { "type": "string" },
|
|
"port": { "type": "integer", "minimum": 0, "maximum": 65535 },
|
|
"enhanced_obp": { "type": "boolean" },
|
|
"connected": {
|
|
"type": "boolean",
|
|
"description": "ENHANCED_OBP BCKA keepalive OK (peer answered within 60s). Omitted when ENHANCED_OBP is false."
|
|
}
|
|
}
|
|
},
|
|
"dashboard_ctable": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["MASTERS", "PEERS", "OPENBRIDGES"],
|
|
"properties": {
|
|
"MASTERS": {
|
|
"type": "object",
|
|
"additionalProperties": { "$ref": "#/$defs/dashboard_master" }
|
|
},
|
|
"PEERS": {
|
|
"type": "object",
|
|
"additionalProperties": { "$ref": "#/$defs/dashboard_upstream_peer" }
|
|
},
|
|
"OPENBRIDGES": {
|
|
"type": "object",
|
|
"additionalProperties": { "$ref": "#/$defs/dashboard_openbridge" }
|
|
}
|
|
}
|
|
},
|
|
"dashboard_state": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["type", "ts", "ctable"],
|
|
"properties": {
|
|
"type": { "const": "dashboard_state" },
|
|
"ts": { "type": "number", "description": "Unix epoch seconds (fractional allowed)." },
|
|
"server_id": {
|
|
"type": "string",
|
|
"description": "GLOBAL.SERVER_ID when present (MQTT retained state)."
|
|
},
|
|
"ctable": { "$ref": "#/$defs/dashboard_ctable" }
|
|
}
|
|
},
|
|
"topology_system": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["name", "mode", "enabled"],
|
|
"properties": {
|
|
"name": { "type": "string" },
|
|
"mode": { "$ref": "#/$defs/system_mode" },
|
|
"enabled": { "type": "boolean" },
|
|
"ip": { "type": "string" },
|
|
"port": { "type": "integer", "minimum": 0, "maximum": 65535 },
|
|
"repeat": { "type": "boolean" },
|
|
"enhanced_obp": { "type": "boolean" },
|
|
"network_id": {
|
|
"$ref": "#/$defs/dmr_id",
|
|
"description": "OPENBRIDGE NETWORK_ID (legacy CONFIG bytes_4 value as integer)."
|
|
},
|
|
"ts1_static": {
|
|
"type": "array",
|
|
"items": { "type": "string" },
|
|
"description": "MASTER slot-1 static talkgroups (from YAML and peer RPTO OPTIONS)."
|
|
},
|
|
"ts2_static": {
|
|
"type": "array",
|
|
"items": { "type": "string" },
|
|
"description": "MASTER slot-2 static talkgroups (from YAML and peer RPTO OPTIONS)."
|
|
},
|
|
"peers": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["id", "connected"],
|
|
"properties": {
|
|
"id": { "$ref": "#/$defs/dmr_id" },
|
|
"connected": { "type": "boolean" },
|
|
"ip": { "type": "string" },
|
|
"port": { "type": "integer", "minimum": 0, "maximum": 65535 },
|
|
"callsign": { "type": "string" },
|
|
"rx_freq": { "type": "string", "description": "RX frequency digits or formatted string from HBP config." },
|
|
"tx_freq": { "type": "string" },
|
|
"location": { "type": "string" },
|
|
"description": { "type": "string" },
|
|
"url": { "type": "string" },
|
|
"slots": { "type": "string" },
|
|
"package_id": { "type": "string" },
|
|
"software_id": { "type": "string" },
|
|
"colorcode": { "type": "string" },
|
|
"tx_power": { "type": "string" },
|
|
"latitude": { "type": "string", "description": "Latitude as sent by the peer in RPTC (decimal degrees)." },
|
|
"longitude": { "type": "string", "description": "Longitude as sent by the peer in RPTC (decimal degrees)." },
|
|
"height": { "type": "string", "description": "Antenna height above ground as sent by the peer in RPTC (metres)." },
|
|
"ts1_static": {
|
|
"type": "array",
|
|
"items": { "type": "string" },
|
|
"description": "Slot-1 static TGs from this peer's RPTO OPTIONS."
|
|
},
|
|
"ts2_static": {
|
|
"type": "array",
|
|
"items": { "type": "string" },
|
|
"description": "Slot-2 static TGs from this peer's RPTO OPTIONS."
|
|
},
|
|
"single_mode": {
|
|
"type": "boolean",
|
|
"description": "Resolved SINGLE=1 from peer OPTIONS, else YAML SINGLE_MODE."
|
|
},
|
|
"ua_timer_min": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"description": "Resolved TIMER from peer OPTIONS (minutes), else YAML DEFAULT_UA_TIMER."
|
|
},
|
|
"ua_sessions": {
|
|
"type": "object",
|
|
"description": "Active SINGLE sessions per slot from server runtime (empty when none).",
|
|
"additionalProperties": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["tgid", "expires_at"],
|
|
"properties": {
|
|
"tgid": { "$ref": "#/$defs/dmr_id" },
|
|
"expires_at": { "type": "number" }
|
|
}
|
|
}
|
|
},
|
|
"ua_multi_tgs": {
|
|
"type": "object",
|
|
"description": "SINGLE=0 dynamic TGs keyed by slot (empty when none).",
|
|
"additionalProperties": {
|
|
"type": "array",
|
|
"items": { "type": "string" }
|
|
}
|
|
},
|
|
"rf_mode": {
|
|
"type": "string",
|
|
"enum": ["simplex", "duplex"],
|
|
"description": "Hotspot RF mode derived from RPTC SLOTS / RX-TX frequencies."
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"topology": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["type", "seq", "ts", "systems"],
|
|
"properties": {
|
|
"type": { "const": "topology" },
|
|
"seq": { "type": "integer", "minimum": 0 },
|
|
"ts": { "type": "number", "description": "Unix epoch seconds (fractional allowed)." },
|
|
"systems": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/$defs/topology_system" }
|
|
}
|
|
}
|
|
},
|
|
"routing_leg": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["system", "ts", "tgid", "active", "to_type"],
|
|
"properties": {
|
|
"system": { "type": "string" },
|
|
"ts": { "$ref": "#/$defs/slot" },
|
|
"tgid": { "$ref": "#/$defs/dmr_id" },
|
|
"active": { "type": "boolean" },
|
|
"to_type": { "$ref": "#/$defs/to_type" },
|
|
"timer_expires_at": {
|
|
"type": "number",
|
|
"description": "Unix time when rule_timer deactivates leg (legacy TIMER field)."
|
|
}
|
|
}
|
|
},
|
|
"routing_table": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["type", "seq", "ts", "routes"],
|
|
"properties": {
|
|
"type": { "const": "routing_table" },
|
|
"seq": { "type": "integer", "minimum": 0 },
|
|
"ts": { "type": "number" },
|
|
"routes": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["relay_table_key", "legs"],
|
|
"properties": {
|
|
"relay_table_key": {
|
|
"type": "string",
|
|
"description": "Talkgroup id string or reflector key (#xxx)."
|
|
},
|
|
"legs": {
|
|
"type": "array",
|
|
"items": { "$ref": "#/$defs/routing_leg" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"voice_event": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"type",
|
|
"ts",
|
|
"call_family",
|
|
"phase",
|
|
"direction",
|
|
"system",
|
|
"stream_id",
|
|
"peer_id",
|
|
"src_id",
|
|
"slot",
|
|
"dst_id",
|
|
"is_announcement"
|
|
],
|
|
"properties": {
|
|
"type": { "const": "voice_event" },
|
|
"ts": { "type": "number" },
|
|
"call_family": {
|
|
"type": "string",
|
|
"enum": ["GROUP", "PRIVATE", "UNIT", "VCSSBK"],
|
|
"description": "Replaces BRDG_EVENT prefix (e.g. GROUP VOICE)."
|
|
},
|
|
"phase": {
|
|
"type": "string",
|
|
"enum": ["INGRESS", "START", "END", "DATA"],
|
|
"description": "DATA is used for UNIT DATA events (legacy BRDG_EVENT CSV)."
|
|
},
|
|
"direction": {
|
|
"type": "string",
|
|
"enum": ["RX", "TX"]
|
|
},
|
|
"system": { "type": "string" },
|
|
"stream_id": { "$ref": "#/$defs/stream_id" },
|
|
"peer_id": { "$ref": "#/$defs/dmr_id" },
|
|
"src_id": { "$ref": "#/$defs/dmr_id" },
|
|
"slot": { "$ref": "#/$defs/slot" },
|
|
"dst_id": { "$ref": "#/$defs/dmr_id" },
|
|
"duration_s": {
|
|
"type": ["number", "null"],
|
|
"minimum": 0,
|
|
"description": "Present on END events."
|
|
},
|
|
"is_announcement": {
|
|
"type": "boolean",
|
|
"description": "True when the call originated from the announcement/TTS synthetic PTT path, not a real connected peer."
|
|
}
|
|
}
|
|
},
|
|
"delta": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["type", "seq", "ts", "since_seq", "patch"],
|
|
"properties": {
|
|
"type": { "const": "delta" },
|
|
"seq": { "type": "integer", "minimum": 1 },
|
|
"ts": { "type": "number" },
|
|
"since_seq": {
|
|
"type": "integer",
|
|
"minimum": 0,
|
|
"description": "Client last applied seq; server sends changes after this."
|
|
},
|
|
"patch": {
|
|
"description": "Partial topology or routing_table payload (same shape, may omit unchanged branches).",
|
|
"oneOf": [
|
|
{ "$ref": "#/$defs/topology" },
|
|
{ "$ref": "#/$defs/routing_table" }
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|