1use crate::draft16::message::ControlMessage;
2use crate::fields::{FieldMap as Map, FieldValue as Value};
3use crate::kvp::{KeyValuePair, KvpValue};
4use crate::types::*;
5use crate::varint::VarInt;
6
7fn vi(v: u64) -> Value {
8 Value::Uint(v)
9}
10
11fn ns_to_json(ns: &TrackNamespace) -> Value {
12 Value::Array(
13 ns.0.iter().map(|e| Value::Text(String::from_utf8_lossy(e).into_owned())).collect(),
14 )
15}
16
17fn d16_setup_param_name(key: u64) -> Option<&'static str> {
18 match key {
19 0x01 => Some("path"),
20 0x02 => Some("max_request_id"),
21 0x03 => Some("authorization_token"),
22 0x04 => Some("max_auth_token_cache_size"),
23 0x05 => Some("authority"),
24 0x07 => Some("moqt_implementation"),
25 _ => None,
26 }
27}
28
29fn d16_msg_param_name(key: u64) -> Option<&'static str> {
30 match key {
31 0x02 => Some("delivery_timeout"),
32 0x03 => Some("authorization_token"),
33 0x04 => Some("max_cache_duration"),
34 0x08 => Some("expires"),
35 0x09 => Some("largest_object"),
36 0x0e => Some("publisher_priority"),
37 0x10 => Some("forward"),
38 0x20 => Some("subscriber_priority"),
39 0x21 => Some("subscription_filter"),
40 0x22 => Some("group_order"),
41 0x30 => Some("dynamic_groups"),
42 0x32 => Some("new_group_request"),
43 _ => None,
44 }
45}
46
47fn auth_token_to_json_d16(bytes: &[u8]) -> Value {
48 let mut buf = bytes;
49 let alias_type = match VarInt::decode(&mut buf) {
50 Ok(v) => v,
51 Err(_) => return Value::Bytes(bytes.to_vec()),
52 };
53 let at = alias_type.into_inner();
54 let mut o = Map::new();
55 o.insert("alias_type".into(), vi(at));
56 match at {
57 0 | 2 => {
58 if let Ok(ta) = VarInt::decode(&mut buf) {
59 o.insert("token_alias".into(), vi(ta.into_inner()));
60 }
61 }
62 1 => {
63 if let Ok(ta) = VarInt::decode(&mut buf) {
64 o.insert("token_alias".into(), vi(ta.into_inner()));
65 }
66 if let Ok(tt) = VarInt::decode(&mut buf) {
67 o.insert("token_type".into(), vi(tt.into_inner()));
68 }
69 o.insert("token_value".into(), Value::Bytes(buf.to_vec()));
70 }
71 _ => {
72 if let Ok(tt) = VarInt::decode(&mut buf) {
73 o.insert("token_type".into(), vi(tt.into_inner()));
74 }
75 o.insert("token_value".into(), Value::Bytes(buf.to_vec()));
76 }
77 }
78 Value::Map(o)
79}
80
81fn decode_subscription_filter(bytes: &[u8]) -> Value {
82 let mut buf = bytes;
83 let filter_type = VarInt::decode(&mut buf).unwrap().into_inner();
84 let mut obj = Map::new();
85 obj.insert("filter_type".into(), vi(filter_type));
86 match filter_type {
87 3 => {
88 let start_group = VarInt::decode(&mut buf).unwrap().into_inner();
89 let start_object = VarInt::decode(&mut buf).unwrap().into_inner();
90 obj.insert("start_group".into(), vi(start_group));
91 obj.insert("start_object".into(), vi(start_object));
92 }
93 4 => {
94 let start_group = VarInt::decode(&mut buf).unwrap().into_inner();
95 let start_object = VarInt::decode(&mut buf).unwrap().into_inner();
96 let end_group = VarInt::decode(&mut buf).unwrap().into_inner();
97 obj.insert("start_group".into(), vi(start_group));
98 obj.insert("start_object".into(), vi(start_object));
99 obj.insert("end_group".into(), vi(end_group));
100 }
101 _ => {}
102 }
103 Value::Map(obj)
104}
105
106fn decode_largest_object(bytes: &[u8]) -> Value {
132 let mut buf = bytes;
133 let Ok(group) = VarInt::decode(&mut buf) else {
134 return Value::Bytes(bytes.to_vec());
135 };
136 let Ok(object) = VarInt::decode(&mut buf) else {
137 return Value::Bytes(bytes.to_vec());
138 };
139 let mut obj = Map::new();
140 obj.insert("group".into(), vi(group.into_inner()));
141 obj.insert("object".into(), vi(object.into_inner()));
142 Value::Map(obj)
143}
144
145fn kvp_to_json_d16_inner(
146 params: &[KeyValuePair],
147 name_fn: fn(u64) -> Option<&'static str>,
148) -> Value {
149 let mut obj = Map::new();
150 let mut unknown = Vec::new();
151
152 for p in params {
153 let key = p.key.into_inner();
154 if let Some(name) = name_fn(key) {
155 match (&p.value, key) {
156 (KvpValue::Bytes(b), 0x21) => {
157 obj.insert(name.to_string(), decode_subscription_filter(b));
158 }
159 (KvpValue::Bytes(b), 0x09) => {
160 obj.insert(name.to_string(), decode_largest_object(b));
161 }
162 (KvpValue::Bytes(b), _) if name == "authorization_token" => {
163 obj.insert(name.to_string(), auth_token_to_json_d16(b));
164 }
165 (KvpValue::Varint(v), _) => {
166 obj.insert(name.to_string(), vi(v.into_inner()));
167 }
168 (KvpValue::Bytes(b), _) => {
169 obj.insert(
170 name.to_string(),
171 Value::Text(String::from_utf8_lossy(b).into_owned()),
172 );
173 }
174 }
175 } else {
176 let mut entry = Map::new();
177 entry.insert("id".to_string(), Value::Text(format!("0x{:x}", key)));
178 match &p.value {
179 KvpValue::Varint(v) => {
180 entry.insert("length".to_string(), vi(v.into_inner()));
181 }
182 KvpValue::Bytes(b) => {
183 entry.insert("length".to_string(), vi(b.len() as u64));
184 entry.insert("raw_hex".to_string(), Value::Bytes(b.to_vec()));
185 }
186 }
187 unknown.push(Value::Map(entry));
188 }
189 }
190
191 if !unknown.is_empty() {
192 obj.insert("unknown".to_string(), Value::Array(unknown));
193 }
194
195 Value::Map(obj)
196}
197
198fn kvp_to_json_d16(params: &[KeyValuePair]) -> Value {
199 kvp_to_json_d16_inner(params, d16_msg_param_name)
200}
201
202fn kvp_to_json_d16_setup(params: &[KeyValuePair]) -> Value {
203 kvp_to_json_d16_inner(params, d16_setup_param_name)
204}
205
206fn d16_track_ext_name(key: u64) -> Option<&'static str> {
210 match key {
211 0x02 => Some("delivery_timeout"),
212 0x04 => Some("max_cache_duration"),
213 0x0e => Some("default_publisher_priority"),
214 _ => None,
215 }
216}
217
218fn kvp_to_json_d16_track_ext(params: &[KeyValuePair]) -> Value {
219 kvp_to_json_d16_inner(params, d16_track_ext_name)
220}
221
222pub fn message_fields(msg: &ControlMessage) -> Map {
228 let obj = match msg {
229 ControlMessage::ClientSetup(m) => {
230 let mut o = Map::new();
231 o.insert("parameters".into(), kvp_to_json_d16_setup(&m.parameters));
232 o
233 }
234 ControlMessage::ServerSetup(m) => {
235 let mut o = Map::new();
236 o.insert("parameters".into(), kvp_to_json_d16_setup(&m.parameters));
237 o
238 }
239 ControlMessage::GoAway(m) => {
240 let mut o = Map::new();
241 o.insert(
242 "new_session_uri".into(),
243 Value::Text(String::from_utf8_lossy(&m.new_session_uri).into_owned()),
244 );
245 o
246 }
247 ControlMessage::MaxRequestId(m) => {
248 let mut o = Map::new();
249 o.insert("max_request_id".into(), vi(m.request_id.into_inner()));
250 o
251 }
252 ControlMessage::RequestsBlocked(m) => {
253 let mut o = Map::new();
254 o.insert("maximum_request_id".into(), vi(m.maximum_request_id.into_inner()));
255 o
256 }
257 ControlMessage::RequestOk(m) => {
258 let mut o = Map::new();
259 o.insert("request_id".into(), vi(m.request_id.into_inner()));
260 o.insert("parameters".into(), kvp_to_json_d16(&m.parameters));
261 o
262 }
263 ControlMessage::RequestError(m) => {
264 let mut o = Map::new();
265 o.insert("request_id".into(), vi(m.request_id.into_inner()));
266 o.insert("error_code".into(), vi(m.error_code.into_inner()));
267 o.insert("retry_interval".into(), vi(m.retry_interval.into_inner()));
268 o.insert(
269 "reason_phrase".into(),
270 Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
271 );
272 o
273 }
274 ControlMessage::Subscribe(m) => {
275 let mut o = Map::new();
276 o.insert("request_id".into(), vi(m.request_id.into_inner()));
277 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
278 o.insert(
279 "track_name".into(),
280 Value::Text(String::from_utf8_lossy(&m.track_name).into_owned()),
281 );
282 o.insert("parameters".into(), kvp_to_json_d16(&m.parameters));
283 o
284 }
285 ControlMessage::SubscribeOk(m) => {
286 let mut o = Map::new();
287 o.insert("request_id".into(), vi(m.request_id.into_inner()));
288 o.insert("track_alias".into(), vi(m.track_alias.into_inner()));
289 o.insert("parameters".into(), kvp_to_json_d16(&m.parameters));
290 if !m.track_extensions.is_empty() {
291 o.insert("track_extensions".into(), kvp_to_json_d16_track_ext(&m.track_extensions));
292 }
293 o
294 }
295 ControlMessage::RequestUpdate(m) => {
296 let mut o = Map::new();
297 o.insert("request_id".into(), vi(m.request_id.into_inner()));
298 o.insert("existing_request_id".into(), vi(m.existing_request_id.into_inner()));
299 o.insert("parameters".into(), kvp_to_json_d16(&m.parameters));
300 o
301 }
302 ControlMessage::Unsubscribe(m) => {
303 let mut o = Map::new();
304 o.insert("request_id".into(), vi(m.request_id.into_inner()));
305 o
306 }
307 ControlMessage::Publish(m) => {
308 let mut o = Map::new();
309 o.insert("request_id".into(), vi(m.request_id.into_inner()));
310 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
311 o.insert(
312 "track_name".into(),
313 Value::Text(String::from_utf8_lossy(&m.track_name).into_owned()),
314 );
315 o.insert("track_alias".into(), vi(m.track_alias.into_inner()));
316 o.insert("parameters".into(), kvp_to_json_d16(&m.parameters));
317 if !m.track_extensions.is_empty() {
318 o.insert("track_extensions".into(), kvp_to_json_d16_track_ext(&m.track_extensions));
319 }
320 o
321 }
322 ControlMessage::PublishOk(m) => {
323 let mut o = Map::new();
324 o.insert("request_id".into(), vi(m.request_id.into_inner()));
325 o.insert("parameters".into(), kvp_to_json_d16(&m.parameters));
326 o
327 }
328 ControlMessage::PublishDone(m) => {
329 let mut o = Map::new();
330 o.insert("request_id".into(), vi(m.request_id.into_inner()));
331 o.insert("status_code".into(), vi(m.status_code.into_inner()));
332 o.insert("stream_count".into(), vi(m.stream_count.into_inner()));
333 o.insert(
334 "reason_phrase".into(),
335 Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
336 );
337 o
338 }
339 ControlMessage::PublishNamespace(m) => {
340 let mut o = Map::new();
341 o.insert("request_id".into(), vi(m.request_id.into_inner()));
342 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
343 o.insert("parameters".into(), kvp_to_json_d16(&m.parameters));
344 o
345 }
346 ControlMessage::PublishNamespaceDone(m) => {
347 let mut o = Map::new();
348 o.insert("request_id".into(), vi(m.request_id.into_inner()));
349 o
350 }
351 ControlMessage::PublishNamespaceCancel(m) => {
352 let mut o = Map::new();
353 o.insert("request_id".into(), vi(m.request_id.into_inner()));
354 o.insert("error_code".into(), vi(m.error_code.into_inner()));
355 o.insert(
356 "reason_phrase".into(),
357 Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
358 );
359 o
360 }
361 ControlMessage::Namespace(m) => {
362 let mut o = Map::new();
363 o.insert("namespace_suffix".into(), ns_to_json(&m.namespace_suffix));
364 o
365 }
366 ControlMessage::NamespaceDone(m) => {
367 let mut o = Map::new();
368 o.insert("namespace_suffix".into(), ns_to_json(&m.namespace_suffix));
369 o
370 }
371 ControlMessage::SubscribeNamespace(m) => {
372 let mut o = Map::new();
373 o.insert("request_id".into(), vi(m.request_id.into_inner()));
374 o.insert("namespace_prefix".into(), ns_to_json(&m.namespace_prefix));
375 o.insert("subscribe_options".into(), vi(m.subscribe_options.into_inner()));
376 o.insert("parameters".into(), kvp_to_json_d16(&m.parameters));
377 o
378 }
379 ControlMessage::TrackStatus(m) => {
380 let mut o = Map::new();
381 o.insert("request_id".into(), vi(m.request_id.into_inner()));
382 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
383 o.insert(
384 "track_name".into(),
385 Value::Text(String::from_utf8_lossy(&m.track_name).into_owned()),
386 );
387 o.insert("parameters".into(), kvp_to_json_d16(&m.parameters));
388 o
389 }
390 ControlMessage::Fetch(m) => {
391 let mut o = Map::new();
392 o.insert("request_id".into(), vi(m.request_id.into_inner()));
393 o.insert("fetch_type".into(), vi(m.fetch_type as u64));
394 match &m.fetch_payload {
395 crate::draft16::message::FetchPayload::Standalone {
396 track_namespace,
397 track_name,
398 start_group,
399 start_object,
400 end_group,
401 end_object,
402 } => {
403 o.insert("track_namespace".into(), ns_to_json(track_namespace));
404 o.insert(
405 "track_name".into(),
406 Value::Text(String::from_utf8_lossy(track_name).into_owned()),
407 );
408 o.insert("start_group".into(), vi(start_group.into_inner()));
409 o.insert("start_object".into(), vi(start_object.into_inner()));
410 o.insert("end_group".into(), vi(end_group.into_inner()));
411 o.insert("end_object".into(), vi(end_object.into_inner()));
412 }
413 crate::draft16::message::FetchPayload::Joining {
414 joining_request_id,
415 joining_start,
416 } => {
417 o.insert("joining_request_id".into(), vi(joining_request_id.into_inner()));
418 o.insert("joining_start".into(), vi(joining_start.into_inner()));
419 }
420 }
421 o.insert("parameters".into(), kvp_to_json_d16(&m.parameters));
422 o
423 }
424 ControlMessage::FetchOk(m) => {
425 let mut o = Map::new();
426 o.insert("request_id".into(), vi(m.request_id.into_inner()));
427 o.insert("end_of_track".into(), vi(m.end_of_track as u64));
428 o.insert("end_group".into(), vi(m.end_group.into_inner()));
429 o.insert("end_object".into(), vi(m.end_object.into_inner()));
430 o.insert("parameters".into(), kvp_to_json_d16(&m.parameters));
431 if !m.track_extensions.is_empty() {
432 o.insert("track_extensions".into(), kvp_to_json_d16_track_ext(&m.track_extensions));
433 }
434 o
435 }
436 ControlMessage::FetchCancel(m) => {
437 let mut o = Map::new();
438 o.insert("request_id".into(), vi(m.request_id.into_inner()));
439 o
440 }
441 };
442 obj
443}