rustmeter_beacon_core/protocol/
event_payload.rs1use crate::{
2 buffer::{BufferReader, BufferWriter},
3 protocol::{MonitorValuePayload, TypeDefinitionPayload},
4 tracing::ReadTracingError,
5};
6use arbitrary_int::{traits::Integer, u3, u5};
7
8#[derive(Debug, Clone, PartialEq)]
9pub enum EventPayload {
10 EmbassyTaskReady { task_id: u16, executor_id: u3 },
13 EmbassyTaskExecBegin { task_id: u16, executor_id: u3 },
16 EmbassyTaskExecEnd { executor_id: u3 },
19 EmbassyExecutorPollStart { executor_id: u3 },
22 EmbassyExecutorIdle { executor_id: u3 },
25 MonitorStart { monitor_id: u8 },
28 MonitorEnd,
31 MonitorValue {
35 value_id: u8,
36 value: MonitorValuePayload,
37 },
38 TypeDefinition(TypeDefinitionPayload),
40 DataLossEvent { dropped_events: u32 },
42 DefmtData {
43 len: u8,
44 #[cfg(not(feature = "std"))]
45 data: *const u8,
46 #[cfg(feature = "std")]
47 data: Vec<u8>,
48 },
49}
50
51impl EventPayload {
52 pub const fn event_id(&self) -> u5 {
53 use crate::protocol::raw_writers::event_ids::*;
54 let id = match self {
55 EventPayload::EmbassyTaskReady { .. } => EMBASSY_TASK_READY,
56 EventPayload::EmbassyTaskExecBegin { .. } => EMBASSY_TASK_EXEC_BEGIN,
57 EventPayload::EmbassyTaskExecEnd { .. } => EMBASSY_TASK_EXEC_END,
58 EventPayload::EmbassyExecutorPollStart { .. } => EMBASSY_EXECUTOR_POLL_START,
59 EventPayload::EmbassyExecutorIdle { .. } => EMBASSY_EXECUTOR_IDLE,
60 EventPayload::MonitorStart { .. } => MONITOR_START,
61 EventPayload::MonitorEnd => MONITOR_END,
62 EventPayload::MonitorValue { .. } => MONITOR_VALUE,
63 EventPayload::TypeDefinition(_) => TYPE_DEFINITION,
64 EventPayload::DataLossEvent { .. } => DATA_LOSS_EVENT,
65 EventPayload::DefmtData { .. } => DEFMT_DATA_EVENT,
66 };
67
68 u5::new(id)
69 }
70
71 pub const fn get_executor_id(&self) -> Option<u3> {
73 match self {
74 EventPayload::EmbassyTaskReady { executor_id, .. } => Some(*executor_id),
75 EventPayload::EmbassyTaskExecBegin { executor_id, .. } => Some(*executor_id),
76 EventPayload::EmbassyTaskExecEnd { executor_id, .. } => Some(*executor_id),
77 EventPayload::EmbassyExecutorPollStart { executor_id, .. } => Some(*executor_id),
78 EventPayload::EmbassyExecutorIdle { executor_id, .. } => Some(*executor_id),
79 _ => None,
80 }
81 }
82
83 pub const fn get_monitor_value_type_id(&self) -> Option<u3> {
85 match self {
86 EventPayload::MonitorValue { value, .. } => Some(value.type_id()),
87 _ => None,
88 }
89 }
90
91 pub const fn get_sub_id(&self) -> Option<u3> {
93 if let Some(executor_id) = self.get_executor_id() {
95 return Some(executor_id);
96 }
97 if let Some(type_id) = self.get_monitor_value_type_id() {
99 return Some(type_id);
100 }
101
102 None
103 }
104
105 pub fn write_bytes(&self, writer: &mut BufferWriter) {
106 let sub_id = self.get_sub_id().unwrap_or(u3::new(0));
108 let event_type = u8::from(self.event_id()) << 3 | sub_id.as_u8();
109 writer.write_byte(event_type);
110
111 match self {
113 EventPayload::EmbassyTaskReady {
114 task_id,
115 executor_id: _,
116 } => {
117 writer.write_bytes(&task_id.to_le_bytes());
118 }
119 EventPayload::EmbassyTaskExecBegin {
120 task_id,
121 executor_id: _,
122 } => {
123 writer.write_bytes(&task_id.to_le_bytes());
124 }
125 EventPayload::EmbassyTaskExecEnd { executor_id: _ } => {}
126 EventPayload::EmbassyExecutorPollStart { executor_id: _ } => {}
127 EventPayload::EmbassyExecutorIdle { executor_id: _ } => {}
128 EventPayload::MonitorStart { monitor_id } => {
129 writer.write_byte(*monitor_id);
130 }
131 EventPayload::MonitorEnd => {}
132 EventPayload::MonitorValue { value_id, value } => {
133 writer.write_byte(*value_id);
134 value.write_bytes(writer);
135 }
136 EventPayload::TypeDefinition(def) => {
137 def.write_bytes(writer);
138 }
139 EventPayload::DataLossEvent { dropped_events } => {
140 writer.write_bytes(&dropped_events.to_le_bytes());
141 }
142 EventPayload::DefmtData { data, len } => {
143 writer.write_byte(*len);
144 #[cfg(not(feature = "std"))]
145 unsafe {
146 writer.write_bytes(core::slice::from_raw_parts(*data, *len as usize));
147 }
148 #[cfg(feature = "std")]
149 {
150 writer.write_bytes(&data[..*len as usize]);
151 }
152 }
153 }
154 }
155
156 pub fn from_bytes(
160 event_type: u8,
161 buffer: &mut BufferReader,
162 ) -> Result<EventPayload, ReadTracingError> {
163 let event_id = u5::new(event_type >> 3);
164 let sub_id = u3::new(event_type & 0x07);
165
166 use crate::protocol::raw_writers::event_ids::*;
167 match event_id.as_u8() {
168 EMBASSY_TASK_READY => {
170 let task_id = buffer.read_u16()?;
171 Ok(EventPayload::EmbassyTaskReady {
172 task_id,
173 executor_id: sub_id,
174 })
175 }
176 EMBASSY_TASK_EXEC_BEGIN => {
178 let task_id = buffer.read_u16()?;
179 Ok(EventPayload::EmbassyTaskExecBegin {
180 task_id,
181 executor_id: sub_id,
182 })
183 }
184 EMBASSY_TASK_EXEC_END => Ok(EventPayload::EmbassyTaskExecEnd {
186 executor_id: sub_id,
187 }),
188 EMBASSY_EXECUTOR_POLL_START => Ok(EventPayload::EmbassyExecutorPollStart {
190 executor_id: sub_id,
191 }),
192 EMBASSY_EXECUTOR_IDLE => Ok(EventPayload::EmbassyExecutorIdle {
194 executor_id: sub_id,
195 }),
196 MONITOR_START => {
198 let monitor_id = buffer.read_byte()?;
199 Ok(EventPayload::MonitorStart { monitor_id })
200 }
201 MONITOR_END => Ok(EventPayload::MonitorEnd),
203 MONITOR_VALUE => {
205 let value_id = buffer.read_byte()?;
206 let value = MonitorValuePayload::from_bytes(sub_id, buffer)?;
207
208 Ok(EventPayload::MonitorValue { value_id, value })
209 }
210 TYPE_DEFINITION => {
212 let typedef_it = buffer.read_byte()?;
213 let def = TypeDefinitionPayload::from_bytes(typedef_it, buffer)?;
214 Ok(EventPayload::TypeDefinition(def))
215 }
216 DATA_LOSS_EVENT => {
218 let dropped_events = buffer.read_u32()?;
219 Ok(EventPayload::DataLossEvent { dropped_events })
220 }
221 DEFMT_DATA_EVENT => {
223 #[cfg(not(feature = "std"))]
224 {
225 panic!("DefmtDataEvent decoding requires the 'std' feature to be enabled.");
226 }
227 #[cfg(feature = "std")]
228 {
229 let len = buffer.read_byte()?;
230 let data = buffer.read_bytes(len as usize)?.to_vec();
231 Ok(EventPayload::DefmtData { len, data })
232 }
233 }
234 _ => return Err(ReadTracingError::InvalidEventType),
235 }
236 }
237}
238
239#[cfg(test)]
240#[cfg(feature = "std")]
241mod tests {
242 use super::*;
243 use crate::buffer::{BufferReader, BufferWriter};
244
245 #[test]
246 fn test_event_payload_write_and_read() {
247 let events = vec![
248 EventPayload::EmbassyTaskReady {
249 task_id: 42,
250 executor_id: u3::new(5),
251 },
252 EventPayload::EmbassyTaskExecBegin {
253 task_id: 44,
254 executor_id: u3::new(6),
255 },
256 EventPayload::EmbassyTaskExecEnd {
257 executor_id: u3::new(1),
258 },
259 EventPayload::EmbassyExecutorPollStart {
260 executor_id: u3::new(3),
261 },
262 EventPayload::EmbassyExecutorIdle {
263 executor_id: u3::new(4),
264 },
265 EventPayload::MonitorStart { monitor_id: 5 },
266 EventPayload::MonitorEnd,
267 EventPayload::MonitorValue {
268 value_id: 7,
269 value: 456u16.into(),
270 },
271 EventPayload::TypeDefinition(TypeDefinitionPayload::ScopeMonitor {
272 monitor_id: 8,
273 name: "test_scope".to_string(),
274 }),
275 EventPayload::DataLossEvent { dropped_events: 10 },
276 EventPayload::DefmtData {
277 len: 4,
278 data: vec![1, 2, 3, 4],
279 },
280 ];
281
282 for event in events {
283 let mut writer = BufferWriter::new();
285 event.write_bytes(&mut writer);
286 let bytes = writer.as_slice();
287
288 let mut reader = BufferReader::new(bytes);
290 let read_event =
291 EventPayload::from_bytes(reader.read_byte().unwrap(), &mut reader).unwrap();
292
293 assert_eq!(event, read_event);
294 }
295 }
296}