1use crate::draft15::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 d15_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 d15_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 decode_subscription_filter(bytes: &[u8]) -> Value {
48 let mut buf = bytes;
49 let filter_type = VarInt::decode(&mut buf).unwrap().into_inner();
50 let mut obj = Map::new();
51 obj.insert("filter_type".into(), vi(filter_type));
52 match filter_type {
53 3 => {
54 let start_group = VarInt::decode(&mut buf).unwrap().into_inner();
56 let start_object = VarInt::decode(&mut buf).unwrap().into_inner();
57 obj.insert("start_group".into(), vi(start_group));
58 obj.insert("start_object".into(), vi(start_object));
59 }
60 4 => {
61 let start_group = VarInt::decode(&mut buf).unwrap().into_inner();
63 let start_object = VarInt::decode(&mut buf).unwrap().into_inner();
64 let end_group = VarInt::decode(&mut buf).unwrap().into_inner();
65 obj.insert("start_group".into(), vi(start_group));
66 obj.insert("start_object".into(), vi(start_object));
67 obj.insert("end_group".into(), vi(end_group));
68 }
69 _ => {
70 }
72 }
73 Value::Map(obj)
74}
75
76fn decode_largest_object(bytes: &[u8]) -> Value {
102 let mut buf = bytes;
103 let Ok(group) = VarInt::decode(&mut buf) else {
104 return Value::Bytes(bytes.to_vec());
105 };
106 let Ok(object) = VarInt::decode(&mut buf) else {
107 return Value::Bytes(bytes.to_vec());
108 };
109 let mut obj = Map::new();
110 obj.insert("group".into(), vi(group.into_inner()));
111 obj.insert("object".into(), vi(object.into_inner()));
112 Value::Map(obj)
113}
114
115fn auth_token_to_json_d15(bytes: &[u8]) -> Value {
117 let mut buf = bytes;
118 let alias_type = match VarInt::decode(&mut buf) {
119 Ok(v) => v,
120 Err(_) => return Value::Bytes(bytes.to_vec()),
121 };
122 let at = alias_type.into_inner();
123 let mut o = Map::new();
124 o.insert("alias_type".into(), vi(at));
125 match at {
126 0 | 2 => {
127 if let Ok(ta) = VarInt::decode(&mut buf) {
128 o.insert("token_alias".into(), vi(ta.into_inner()));
129 }
130 }
131 1 => {
132 if let Ok(ta) = VarInt::decode(&mut buf) {
133 o.insert("token_alias".into(), vi(ta.into_inner()));
134 }
135 if let Ok(tt) = VarInt::decode(&mut buf) {
136 o.insert("token_type".into(), vi(tt.into_inner()));
137 }
138 o.insert("token_value".into(), Value::Bytes(buf.to_vec()));
139 }
140 _ => {
141 if let Ok(tt) = VarInt::decode(&mut buf) {
142 o.insert("token_type".into(), vi(tt.into_inner()));
143 }
144 o.insert("token_value".into(), Value::Bytes(buf.to_vec()));
145 }
146 }
147 Value::Map(o)
148}
149
150fn kvp_to_json_d15_inner(
151 params: &[KeyValuePair],
152 name_fn: fn(u64) -> Option<&'static str>,
153) -> Value {
154 let mut obj = Map::new();
155 let mut unknown = Vec::new();
156
157 for p in params {
158 let key = p.key.into_inner();
159 if let Some(name) = name_fn(key) {
160 match (&p.value, key) {
161 (KvpValue::Bytes(b), 0x21) => {
162 obj.insert(name.to_string(), decode_subscription_filter(b));
163 }
164 (KvpValue::Bytes(b), 0x09) => {
165 obj.insert(name.to_string(), decode_largest_object(b));
166 }
167 (KvpValue::Bytes(b), _) if name == "authorization_token" => {
168 obj.insert(name.to_string(), auth_token_to_json_d15(b));
169 }
170 (KvpValue::Varint(v), _) => {
171 obj.insert(name.to_string(), vi(v.into_inner()));
172 }
173 (KvpValue::Bytes(b), _) => {
174 obj.insert(
175 name.to_string(),
176 Value::Text(String::from_utf8_lossy(b).into_owned()),
177 );
178 }
179 }
180 } else {
181 let mut entry = Map::new();
182 entry.insert("id".to_string(), Value::Text(format!("0x{:x}", key)));
183 match &p.value {
184 KvpValue::Varint(v) => {
185 entry.insert("length".to_string(), vi(v.into_inner()));
186 }
187 KvpValue::Bytes(b) => {
188 entry.insert("length".to_string(), vi(b.len() as u64));
189 entry.insert("raw_hex".to_string(), Value::Bytes(b.to_vec()));
190 }
191 }
192 unknown.push(Value::Map(entry));
193 }
194 }
195
196 if !unknown.is_empty() {
197 obj.insert("unknown".to_string(), Value::Array(unknown));
198 }
199
200 Value::Map(obj)
201}
202
203fn kvp_to_json_d15(params: &[KeyValuePair]) -> Value {
204 kvp_to_json_d15_inner(params, d15_msg_param_name)
205}
206
207fn kvp_to_json_d15_setup(params: &[KeyValuePair]) -> Value {
208 kvp_to_json_d15_inner(params, d15_setup_param_name)
209}
210
211pub fn message_fields(msg: &ControlMessage) -> Map {
217 let obj = match msg {
218 ControlMessage::ClientSetup(m) => {
219 let mut o = Map::new();
220 o.insert("parameters".into(), kvp_to_json_d15_setup(&m.parameters));
221 o
222 }
223 ControlMessage::ServerSetup(m) => {
224 let mut o = Map::new();
225 o.insert("parameters".into(), kvp_to_json_d15_setup(&m.parameters));
226 o
227 }
228 ControlMessage::GoAway(m) => {
229 let mut o = Map::new();
230 o.insert(
231 "new_session_uri".into(),
232 Value::Text(String::from_utf8_lossy(&m.new_session_uri).into_owned()),
233 );
234 o
235 }
236 ControlMessage::MaxRequestId(m) => {
237 let mut o = Map::new();
238 o.insert("max_request_id".into(), vi(m.request_id.into_inner()));
239 o
240 }
241 ControlMessage::RequestsBlocked(m) => {
242 let mut o = Map::new();
243 o.insert("maximum_request_id".into(), vi(m.maximum_request_id.into_inner()));
244 o
245 }
246 ControlMessage::RequestOk(m) => {
247 let mut o = Map::new();
248 o.insert("request_id".into(), vi(m.request_id.into_inner()));
249 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
250 o
251 }
252 ControlMessage::RequestError(m) => {
253 let mut o = Map::new();
254 o.insert("request_id".into(), vi(m.request_id.into_inner()));
255 o.insert("error_code".into(), vi(m.error_code.into_inner()));
256 o.insert(
257 "reason_phrase".into(),
258 Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
259 );
260 o
261 }
262 ControlMessage::Subscribe(m) => {
263 let mut o = Map::new();
264 o.insert("request_id".into(), vi(m.request_id.into_inner()));
265 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
266 o.insert(
267 "track_name".into(),
268 Value::Text(String::from_utf8_lossy(&m.track_name).into_owned()),
269 );
270 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
271 o
272 }
273 ControlMessage::SubscribeOk(m) => {
274 let mut o = Map::new();
275 o.insert("request_id".into(), vi(m.request_id.into_inner()));
276 o.insert("track_alias".into(), vi(m.track_alias.into_inner()));
277 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
278 o
279 }
280 ControlMessage::SubscribeUpdate(m) => {
281 let mut o = Map::new();
282 o.insert("request_id".into(), vi(m.request_id.into_inner()));
283 o.insert("subscription_request_id".into(), vi(m.subscription_request_id.into_inner()));
284 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
285 o
286 }
287 ControlMessage::Unsubscribe(m) => {
288 let mut o = Map::new();
289 o.insert("request_id".into(), vi(m.request_id.into_inner()));
290 o
291 }
292 ControlMessage::Publish(m) => {
293 let mut o = Map::new();
294 o.insert("request_id".into(), vi(m.request_id.into_inner()));
295 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
296 o.insert(
297 "track_name".into(),
298 Value::Text(String::from_utf8_lossy(&m.track_name).into_owned()),
299 );
300 o.insert("track_alias".into(), vi(m.track_alias.into_inner()));
301 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
302 o
303 }
304 ControlMessage::PublishOk(m) => {
305 let mut o = Map::new();
306 o.insert("request_id".into(), vi(m.request_id.into_inner()));
307 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
308 o
309 }
310 ControlMessage::PublishDone(m) => {
311 let mut o = Map::new();
312 o.insert("request_id".into(), vi(m.request_id.into_inner()));
313 o.insert("status_code".into(), vi(m.status_code.into_inner()));
314 o.insert("stream_count".into(), vi(m.stream_count.into_inner()));
315 o.insert(
316 "reason_phrase".into(),
317 Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
318 );
319 o
320 }
321 ControlMessage::PublishNamespace(m) => {
322 let mut o = Map::new();
323 o.insert("request_id".into(), vi(m.request_id.into_inner()));
324 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
325 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
326 o
327 }
328 ControlMessage::PublishNamespaceDone(m) => {
329 let mut o = Map::new();
330 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
331 o
332 }
333 ControlMessage::PublishNamespaceCancel(m) => {
334 let mut o = Map::new();
335 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
336 o.insert("error_code".into(), vi(m.error_code.into_inner()));
337 o.insert(
338 "reason_phrase".into(),
339 Value::Text(String::from_utf8_lossy(&m.reason_phrase).into_owned()),
340 );
341 o
342 }
343 ControlMessage::SubscribeNamespace(m) => {
344 let mut o = Map::new();
345 o.insert("request_id".into(), vi(m.request_id.into_inner()));
346 o.insert("namespace_prefix".into(), ns_to_json(&m.namespace_prefix));
347 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
348 o
349 }
350 ControlMessage::UnsubscribeNamespace(m) => {
351 let mut o = Map::new();
352 o.insert("request_id".into(), vi(m.request_id.into_inner()));
353 o
354 }
355 ControlMessage::TrackStatus(m) => {
356 let mut o = Map::new();
357 o.insert("request_id".into(), vi(m.request_id.into_inner()));
358 o.insert("track_namespace".into(), ns_to_json(&m.track_namespace));
359 o.insert(
360 "track_name".into(),
361 Value::Text(String::from_utf8_lossy(&m.track_name).into_owned()),
362 );
363 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
364 o
365 }
366 ControlMessage::Fetch(m) => {
367 let mut o = Map::new();
368 o.insert("request_id".into(), vi(m.request_id.into_inner()));
369 o.insert("fetch_type".into(), vi(m.fetch_type as u64));
370 match &m.fetch_payload {
371 crate::draft15::message::FetchPayload::Standalone {
372 track_namespace,
373 track_name,
374 start_group,
375 start_object,
376 end_group,
377 end_object,
378 } => {
379 o.insert("track_namespace".into(), ns_to_json(track_namespace));
380 o.insert(
381 "track_name".into(),
382 Value::Text(String::from_utf8_lossy(track_name).into_owned()),
383 );
384 o.insert("start_group".into(), vi(start_group.into_inner()));
385 o.insert("start_object".into(), vi(start_object.into_inner()));
386 o.insert("end_group".into(), vi(end_group.into_inner()));
387 o.insert("end_object".into(), vi(end_object.into_inner()));
388 }
389 crate::draft15::message::FetchPayload::Joining {
390 joining_request_id,
391 joining_start,
392 } => {
393 o.insert("joining_request_id".into(), vi(joining_request_id.into_inner()));
394 o.insert("joining_start".into(), vi(joining_start.into_inner()));
395 }
396 }
397 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
398 o
399 }
400 ControlMessage::FetchOk(m) => {
401 let mut o = Map::new();
402 o.insert("request_id".into(), vi(m.request_id.into_inner()));
403 o.insert("end_of_track".into(), vi(m.end_of_track as u64));
404 o.insert("end_group".into(), vi(m.end_group.into_inner()));
405 o.insert("end_object".into(), vi(m.end_object.into_inner()));
406 o.insert("parameters".into(), kvp_to_json_d15(&m.parameters));
407 o
408 }
409 ControlMessage::FetchCancel(m) => {
410 let mut o = Map::new();
411 o.insert("request_id".into(), vi(m.request_id.into_inner()));
412 o
413 }
414 };
415 obj
416}