|
11 | 11 | // |
12 | 12 | // TODO: Unimplemented data plane events (from draft-pardue-moq-qlog-moq-events): |
13 | 13 | // - stream_type_set (when stream type becomes known) |
14 | | -// - object_datagram_created/parsed |
15 | 14 | // - object_datagram_status_created/parsed |
16 | 15 | // - fetch_header_created/parsed |
17 | 16 | // - fetch_object_created/parsed |
@@ -61,6 +60,12 @@ pub enum EventData { |
61 | 60 | #[serde(rename = "subgroup_object_created")] |
62 | 61 | SubgroupObjectCreated(SubgroupObjectCreated), |
63 | 62 |
|
| 63 | + #[serde(rename = "object_datagram_parsed")] |
| 64 | + ObjectDatagramParsed(ObjectDatagramParsed), |
| 65 | + |
| 66 | + #[serde(rename = "object_datagram_created")] |
| 67 | + ObjectDatagramCreated(ObjectDatagramCreated), |
| 68 | + |
64 | 69 | #[serde(rename = "loglevel")] |
65 | 70 | LogLevel(LogLevelEvent), |
66 | 71 | } |
@@ -133,6 +138,28 @@ pub struct SubgroupObjectCreated { |
133 | 138 | pub object: JsonValue, |
134 | 139 | } |
135 | 140 |
|
| 141 | +/// Object Datagram parsed event (data plane) |
| 142 | +#[serde_with::skip_serializing_none] |
| 143 | +#[derive(Debug, Clone, Serialize, Deserialize)] |
| 144 | +pub struct ObjectDatagramParsed { |
| 145 | + pub stream_id: u64, |
| 146 | + |
| 147 | + /// Object-specific fields |
| 148 | + #[serde(flatten)] |
| 149 | + pub object: JsonValue, |
| 150 | +} |
| 151 | + |
| 152 | +/// Object Datagram created event (data plane) |
| 153 | +#[serde_with::skip_serializing_none] |
| 154 | +#[derive(Debug, Clone, Serialize, Deserialize)] |
| 155 | +pub struct ObjectDatagramCreated { |
| 156 | + pub stream_id: u64, |
| 157 | + |
| 158 | + /// Object-specific fields |
| 159 | + #[serde(flatten)] |
| 160 | + pub object: JsonValue, |
| 161 | +} |
| 162 | + |
136 | 163 | /// LogLevel event for flexible logging (qlog loglevel schema) |
137 | 164 | /// See: https://www.ietf.org/archive/id/draft-ietf-quic-qlog-main-schema-12.html#name-loglevel-events |
138 | 165 | #[serde_with::skip_serializing_none] |
@@ -492,10 +519,10 @@ pub fn go_away_created(time: f64, stream_id: u64, msg: &message::GoAway) -> Even |
492 | 519 | /// Helper to convert SubgroupHeader to JSON |
493 | 520 | fn subgroup_header_to_json(header: &data::SubgroupHeader) -> JsonValue { |
494 | 521 | let mut json = json!({ |
| 522 | + "header_type": format!("{:?}", header.header_type), |
495 | 523 | "track_alias": header.track_alias, |
496 | 524 | "group_id": header.group_id, |
497 | 525 | "publisher_priority": header.publisher_priority, |
498 | | - "header_type": format!("{:?}", header.header_type), |
499 | 526 | }); |
500 | 527 |
|
501 | 528 | if let Some(subgroup_id) = header.subgroup_id { |
@@ -540,7 +567,7 @@ fn subgroup_object_to_json( |
540 | 567 | "group_id": group_id, |
541 | 568 | "subgroup_id": subgroup_id, |
542 | 569 | "object_id": object_id, |
543 | | - "extension_headers_length": 0, |
| 570 | + // TODO send object_playload itself |
544 | 571 | "object_payload_length": object.payload_length, |
545 | 572 | }); |
546 | 573 |
|
@@ -596,12 +623,12 @@ fn subgroup_object_ext_to_json( |
596 | 623 | object_id: u64, |
597 | 624 | object: &data::SubgroupObjectExt, |
598 | 625 | ) -> JsonValue { |
599 | | - // TODO encode extension headers |
600 | 626 | let mut object_data = json!({ |
601 | 627 | "group_id": group_id, |
602 | 628 | "subgroup_id": subgroup_id, |
603 | 629 | "object_id": object_id, |
604 | | - "extension_headers_length": object.extension_headers.0.len(), |
| 630 | + "extension_headers": key_value_pairs_to_vec(&object.extension_headers), |
| 631 | + // TODO send object_playload itself |
605 | 632 | "object_payload_length": object.payload_length, |
606 | 633 | }); |
607 | 634 |
|
@@ -650,6 +677,53 @@ pub fn subgroup_object_ext_created( |
650 | 677 | } |
651 | 678 | } |
652 | 679 |
|
| 680 | +/// Helper to convert Datagram to JSON |
| 681 | +fn object_datagram_to_json(datagram: &data::Datagram) -> JsonValue { |
| 682 | + let mut json = json!({ |
| 683 | + "datagram_type": format!("{:?}", datagram.datagram_type), |
| 684 | + "track_alias": datagram.track_alias, |
| 685 | + "group_id": datagram.group_id, |
| 686 | + "object_id": datagram.object_id.unwrap_or(0), |
| 687 | + "publisher_priority": datagram.publisher_priority, |
| 688 | + // TODO send object_playload |
| 689 | + "payload_length": datagram.payload.as_ref().map_or(0, |p| p.len()), |
| 690 | + }); |
| 691 | + |
| 692 | + if let Some(extension_headers) = &datagram.extension_headers { |
| 693 | + json["extension_headers"] = json!(key_value_pairs_to_vec(extension_headers)); |
| 694 | + } |
| 695 | + |
| 696 | + if let Some(status) = datagram.status { |
| 697 | + json["object_status"] = json!(format!("{:?}", status)); |
| 698 | + } |
| 699 | + |
| 700 | + json |
| 701 | +} |
| 702 | + |
| 703 | +/// Create a object_datagram_parsed event |
| 704 | +pub fn object_datagram_parsed(time: f64, stream_id: u64, datagram: &data::Datagram) -> Event { |
| 705 | + Event { |
| 706 | + time, |
| 707 | + name: "moqt:object_datagram_parsed".to_string(), |
| 708 | + data: EventData::ObjectDatagramParsed(ObjectDatagramParsed { |
| 709 | + stream_id, |
| 710 | + object: object_datagram_to_json(datagram), |
| 711 | + }), |
| 712 | + } |
| 713 | +} |
| 714 | + |
| 715 | +/// Create a object_datagram_created event |
| 716 | +pub fn object_datagram_created(time: f64, stream_id: u64, datagram: &data::Datagram) -> Event { |
| 717 | + Event { |
| 718 | + time, |
| 719 | + name: "moqt:object_datagram_created".to_string(), |
| 720 | + data: EventData::ObjectDatagramCreated(ObjectDatagramCreated { |
| 721 | + stream_id, |
| 722 | + object: object_datagram_to_json(datagram), |
| 723 | + }), |
| 724 | + } |
| 725 | +} |
| 726 | + |
653 | 727 | // LogLevel events (generic logging) |
654 | 728 |
|
655 | 729 | /// Log levels for qlog loglevel events |
|
0 commit comments