trace_recorder_parser/streaming/event/
parser.rs

1use crate::streaming::event::*;
2use crate::streaming::{EntryTable, Error, HeaderInfo};
3use crate::time::{Frequency, Ticks};
4use crate::types::{
5    format_symbol_string, Endianness, FormatString, FormattedString, Heap, ObjectClass,
6    ObjectHandle, ObjectName, Priority, Protocol, SymbolString, TimerCounter, TrimmedString,
7    UserEventChannel,
8};
9use byteordered::ByteOrdered;
10use std::io::{self, Read};
11use tracing::error;
12
13#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
14pub struct EventParser {
15    /// Endianness of the data
16    endianness: byteordered::Endianness,
17
18    /// Initial heap from the entry table, maintained by the parser
19    heap: Heap,
20
21    /// Event ID for custom printf events, if enabled
22    custom_printf_event_id: Option<EventId>,
23
24    /// Local scratch buffer for reading strings
25    buf: Vec<u8>,
26
27    /// Local scratch buffer for reading argument data
28    arg_buf: Vec<u8>,
29}
30
31impl EventParser {
32    pub fn new(endianness: Endianness, heap: Heap) -> Self {
33        Self {
34            endianness: byteordered::Endianness::from(endianness),
35            heap,
36            custom_printf_event_id: None,
37            buf: Vec::with_capacity(256),
38            arg_buf: Vec::with_capacity(256),
39        }
40    }
41
42    pub fn set_custom_printf_event_id(&mut self, custom_printf_event_id: EventId) {
43        self.custom_printf_event_id = Some(custom_printf_event_id);
44    }
45
46    pub fn system_heap(&self) -> &Heap {
47        &self.heap
48    }
49
50    pub fn next_event<R: Read>(
51        &mut self,
52        mut r: &mut R,
53        entry_table: &mut EntryTable,
54    ) -> Result<Option<(EventCode, Event)>, Error> {
55        let first_word = {
56            let mut r = ByteOrdered::le(&mut r);
57            let word = match r.read_u32() {
58                Ok(w) => w,
59                Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => return Ok(None),
60                Err(e) => return Err(e.into()),
61            };
62            match word {
63                HeaderInfo::PSF_LITTLE_ENDIAN => {
64                    return Err(Error::TraceRestarted(Endianness::Little))
65                }
66                HeaderInfo::PSF_BIG_ENDIAN => return Err(Error::TraceRestarted(Endianness::Big)),
67                _ => word.to_le_bytes(),
68            }
69        };
70
71        let mut first_word_reader = ByteOrdered::new(first_word.as_slice(), self.endianness);
72        let mut r = ByteOrdered::new(r, self.endianness);
73
74        let event_code = match first_word_reader.read_u16() {
75            Ok(ec) => EventCode(ec),
76            Err(e) if e.kind() == io::ErrorKind::UnexpectedEof => return Ok(None),
77            Err(e) => return Err(e.into()),
78        };
79
80        let event_type = event_code.event_type();
81        let event_id = event_code.event_id();
82        let event_count = EventCount(first_word_reader.read_u16()?);
83        let timestamp = Timestamp(r.read_u32()?.into());
84        let num_params = event_code.parameter_count();
85
86        if let Some(expected_parameter_count) = event_type.expected_parameter_count() {
87            if usize::from(num_params) != expected_parameter_count {
88                return Err(Error::InvalidEventParameterCount(
89                    event_code.event_id(),
90                    expected_parameter_count,
91                    num_params,
92                ));
93            }
94        }
95
96        Ok(match event_type {
97            EventType::TraceStart => {
98                let handle = object_handle(&mut r, event_id)?;
99                let sym = entry_table
100                    .symbol(handle)
101                    .ok_or(Error::ObjectLookup(handle))?;
102                let event = TraceStartEvent {
103                    event_count,
104                    timestamp,
105                    current_task_handle: handle,
106                    current_task: sym.clone().into(),
107                };
108                Some((event_code, Event::TraceStart(event)))
109            }
110
111            EventType::TsConfig => {
112                let uses_custom_timer = match num_params.0 {
113                    4 => false,
114                    // TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_INCR || TRC_HWTC_TYPE == TRC_CUSTOM_TIMER_DECR
115                    5 => true,
116                    _ => {
117                        return Err(Error::InvalidEventParameterCount(
118                            event_code.event_id(),
119                            4, // base count
120                            num_params,
121                        ));
122                    }
123                };
124                let frequency = Frequency(r.read_u32()?);
125                let tick_rate_hz = r.read_u32()?;
126                let hwtc_type = r.read_u32()?;
127                let isr_chaining_threshold = r.read_u32()?;
128                let htc_period = if uses_custom_timer {
129                    r.read_u32()?.into()
130                } else {
131                    None
132                };
133                let event = TsConfigEvent {
134                    event_count,
135                    timestamp,
136                    frequency,
137                    tick_rate_hz,
138                    hwtc_type: TimerCounter::from_hwtc_type(hwtc_type)
139                        .ok_or(Error::InvalidTimerCounter(hwtc_type))?,
140                    isr_chaining_threshold,
141                    htc_period,
142                };
143                Some((event_code, Event::TsConfig(event)))
144            }
145
146            EventType::ObjectName => {
147                // Always expect at least a handle
148                if num_params.0 < 1 {
149                    return Err(Error::InvalidEventParameterCount(
150                        event_code.event_id(),
151                        1,
152                        num_params,
153                    ));
154                }
155                let handle = object_handle(&mut r, event_id)?;
156                let symbol: SymbolString = self
157                    .read_string(&mut r, (usize::from(num_params) - 1) * 4)?
158                    .into();
159                entry_table.entry(handle).set_symbol(symbol.clone());
160                let event = ObjectNameEvent {
161                    event_count,
162                    timestamp,
163                    handle,
164                    name: symbol,
165                };
166                Some((event_code, Event::ObjectName(event)))
167            }
168
169            EventType::TaskPriority
170            | EventType::TaskPriorityInherit
171            | EventType::TaskPriorityDisinherit => {
172                let handle = object_handle(&mut r, event_id)?;
173                let priority = Priority(r.read_u32()?);
174                let entry = entry_table.entry(handle);
175                entry.states.set_priority(priority);
176                let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
177                let event = TaskEvent {
178                    event_count,
179                    timestamp,
180                    handle,
181                    name: sym.clone().into(),
182                    priority,
183                };
184                Some((
185                    event_code,
186                    match event_type {
187                    EventType::TaskPriority => Event::TaskPriority(event),
188                    EventType::TaskPriorityInherit => Event::TaskPriorityInherit(event),
189                    _ /*EventType::TaskPriorityDisinherit*/ => Event::TaskPriorityDisinherit(event),
190                },
191                ))
192            }
193
194            EventType::DefineIsr => {
195                // Always expect at least a handle
196                if num_params.0 < 1 {
197                    return Err(Error::InvalidEventParameterCount(
198                        event_code.event_id(),
199                        1,
200                        num_params,
201                    ));
202                }
203                let handle = object_handle(&mut r, event_id)?;
204                let priority = Priority(r.read_u32()?);
205                let symbol: SymbolString = self
206                    .read_string(&mut r, (usize::from(num_params) - 2) * 4)?
207                    .into();
208                let entry = entry_table.entry(handle);
209                entry.states.set_priority(priority);
210                entry.set_symbol(symbol.clone());
211                entry.set_class(ObjectClass::Isr);
212                let event = IsrEvent {
213                    event_count,
214                    timestamp,
215                    handle,
216                    name: symbol.into(),
217                    priority,
218                };
219                Some((event_code, Event::IsrDefine(event)))
220            }
221
222            EventType::TaskCreate => {
223                let handle = object_handle(&mut r, event_id)?;
224                let priority = Priority(r.read_u32()?);
225                let entry = entry_table.entry(handle);
226                entry.states.set_priority(priority);
227                entry.set_class(ObjectClass::Task);
228                let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
229                let event = TaskEvent {
230                    event_count,
231                    timestamp,
232                    handle,
233                    name: sym.clone().into(),
234                    priority,
235                };
236                Some((event_code, Event::TaskCreate(event)))
237            }
238
239            EventType::TaskReady => {
240                let handle = object_handle(&mut r, event_id)?;
241                let entry = entry_table.entry(handle);
242                let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
243                let event = TaskEvent {
244                    event_count,
245                    timestamp,
246                    handle,
247                    name: sym.clone().into(),
248                    priority: entry.states.priority(),
249                };
250                Some((event_code, Event::TaskReady(event)))
251            }
252
253            EventType::TaskSwitchIsrBegin => {
254                let handle = object_handle(&mut r, event_id)?;
255                let entry = entry_table.entry(handle);
256                let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
257                let event = IsrEvent {
258                    event_count,
259                    timestamp,
260                    handle,
261                    name: sym.clone().into(),
262                    priority: entry.states.priority(),
263                };
264                Some((event_code, Event::IsrBegin(event)))
265            }
266
267            EventType::TaskSwitchIsrResume => {
268                let handle = object_handle(&mut r, event_id)?;
269                let entry = entry_table.entry(handle);
270                let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
271                let event = IsrEvent {
272                    event_count,
273                    timestamp,
274                    handle,
275                    name: sym.clone().into(),
276                    priority: entry.states.priority(),
277                };
278                Some((event_code, Event::IsrResume(event)))
279            }
280
281            EventType::TaskSwitchTaskResume => {
282                let handle = object_handle(&mut r, event_id)?;
283                let entry = entry_table.entry(handle);
284                let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
285                let event = TaskEvent {
286                    event_count,
287                    timestamp,
288                    handle,
289                    name: sym.clone().into(),
290                    priority: entry.states.priority(),
291                };
292                Some((event_code, Event::TaskResume(event)))
293            }
294
295            EventType::TaskActivate => {
296                if (num_params.0 != 1) && (num_params.0 != 2) {
297                    return Err(Error::InvalidEventParameterCount(
298                        event_code.event_id(),
299                        1,
300                        num_params,
301                    ));
302                }
303                let handle = object_handle(&mut r, event_id)?;
304                let entry = entry_table.entry(handle);
305
306                if num_params.0 == 2 {
307                    let priority = Priority(r.read_u32()?);
308                    entry.states.set_priority(priority);
309                }
310
311                let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
312                let event = TaskEvent {
313                    event_count,
314                    timestamp,
315                    handle,
316                    name: sym.clone().into(),
317                    priority: entry.states.priority(),
318                };
319                Some((event_code, Event::TaskActivate(event)))
320            }
321
322            EventType::TaskNotify | EventType::TaskNotifyFromIsr => {
323                let handle: ObjectHandle = object_handle(&mut r, event_id)?;
324                let entry = entry_table.entry(handle);
325                let event = TaskNotifyEvent {
326                    event_count,
327                    timestamp,
328                    handle,
329                    task_name: entry.symbol.clone().map(ObjectName::from),
330                    ticks_to_wait: None,
331                };
332                Some((
333                    event_code,
334                    match event_type {
335                            EventType::TaskNotify => Event::TaskNotify(event),
336                            _ /*EventType::TaskNotifyFromIsr*/ => Event::TaskNotifyFromIsr(event),
337                        },
338                ))
339            }
340
341            EventType::TaskNotifyWait | EventType::TaskNotifyWaitBlock => {
342                let handle: ObjectHandle = object_handle(&mut r, event_id)?;
343                let ticks_to_wait = Some(Ticks(r.read_u32()?));
344                let entry = entry_table.entry(handle);
345                let event = TaskNotifyEvent {
346                    event_count,
347                    timestamp,
348                    handle,
349                    task_name: entry.symbol.clone().map(ObjectName::from),
350                    ticks_to_wait,
351                };
352                Some((
353                    event_code,
354                    match event_type {
355                            EventType::TaskNotifyWait => Event::TaskNotifyWait(event),
356                            _ /*EventType::TaskNotifyWaitBlock*/ => Event::TaskNotifyWaitBlock(event),
357                        },
358                ))
359            }
360
361            EventType::MemoryAlloc | EventType::MemoryFree => {
362                let address = r.read_u32()?;
363                let size = r.read_u32()?;
364                if matches!(event_type, EventType::MemoryAlloc) {
365                    self.heap.handle_alloc(size);
366                } else {
367                    self.heap.handle_free(size);
368                }
369                let event = MemoryEvent {
370                    event_count,
371                    timestamp,
372                    address,
373                    size,
374                    heap: self.heap,
375                };
376                Some((
377                    event_code,
378                    if matches!(event_type, EventType::MemoryAlloc) {
379                        Event::MemoryAlloc(event)
380                    } else {
381                        Event::MemoryFree(event)
382                    },
383                ))
384            }
385
386            EventType::QueueCreate => {
387                let handle = object_handle(&mut r, event_id)?;
388                let queue_length = r.read_u32()?;
389                let entry = entry_table.entry(handle);
390                entry.set_class(ObjectClass::Queue);
391                let event = QueueCreateEvent {
392                    event_count,
393                    timestamp,
394                    handle,
395                    name: entry.symbol.clone().map(ObjectName::from),
396                    queue_length,
397                };
398                Some((event_code, Event::QueueCreate(event)))
399            }
400
401            EventType::QueueSend
402            | EventType::QueueSendBlock
403            | EventType::QueueSendFromIsr
404            | EventType::QueueReceiveFromIsr
405            | EventType::QueueSendFront
406            | EventType::QueueSendFrontBlock
407            | EventType::QueueSendFrontFromIsr => {
408                let handle: ObjectHandle = object_handle(&mut r, event_id)?;
409                let messages_waiting = r.read_u32()?;
410                let event = QueueEvent {
411                    event_count,
412                    timestamp,
413                    handle,
414                    name: entry_table.symbol(handle).cloned().map(ObjectName::from),
415                    ticks_to_wait: None,
416                    messages_waiting,
417                };
418                Some((
419                    event_code,
420                    match event_type {
421                        EventType::QueueSend => Event::QueueSend(event),
422                        EventType::QueueSendBlock => Event::QueueSendBlock(event),
423                        EventType::QueueSendFromIsr => Event::QueueSendFromIsr(event),
424                        EventType::QueueReceiveFromIsr => Event::QueueReceiveFromIsr(event),
425                        EventType::QueueSendFront => Event::QueueSendFront(event),
426                        EventType::QueueSendFrontBlock => Event::QueueSendFrontBlock(event),
427                        _ /*EventType::QueueSendFrontFromIsr*/ => Event::QueueSendFrontFromIsr(event),
428                    },
429                ))
430            }
431
432            EventType::QueueReceive
433            | EventType::QueueReceiveBlock
434            | EventType::QueuePeek
435            | EventType::QueuePeekBlock => {
436                let handle: ObjectHandle = object_handle(&mut r, event_id)?;
437                let ticks_to_wait = Some(Ticks(r.read_u32()?));
438                let messages_waiting = r.read_u32()?;
439                let event = QueueEvent {
440                    event_count,
441                    timestamp,
442                    handle,
443                    name: entry_table.symbol(handle).cloned().map(ObjectName::from),
444                    ticks_to_wait,
445                    messages_waiting,
446                };
447                Some((
448                    event_code,
449                    match event_type {
450                        EventType::QueueReceive => Event::QueueReceive(event),
451                        EventType::QueueReceiveBlock => Event::QueueReceiveBlock(event),
452                        EventType::QueuePeek => Event::QueuePeek(event),
453                        _ /*EventType::QueuePeekBlock*/ => Event::QueuePeekBlock(event),
454                    },
455                ))
456            }
457
458            EventType::MutexCreate => {
459                let handle: ObjectHandle = object_handle(&mut r, event_id)?;
460                let _unused = r.read_u32()?;
461                let entry = entry_table.entry(handle);
462                entry.set_class(ObjectClass::Mutex);
463                let event = MutexCreateEvent {
464                    event_count,
465                    timestamp,
466                    handle,
467                    name: entry.symbol.clone().map(ObjectName::from),
468                };
469                Some((event_code, Event::MutexCreate(event)))
470            }
471
472            EventType::MutexGive | EventType::MutexGiveBlock | EventType::MutexGiveRecursive => {
473                let handle: ObjectHandle = object_handle(&mut r, event_id)?;
474                let entry = entry_table.entry(handle);
475                entry.set_class(ObjectClass::Mutex);
476                let event = MutexEvent {
477                    event_count,
478                    timestamp,
479                    handle,
480                    name: entry.symbol.clone().map(ObjectName::from),
481                    ticks_to_wait: None,
482                };
483                Some((
484                    event_code,
485                    match event_type {
486                            EventType::MutexGive => Event::MutexGive(event),
487                            EventType::MutexGiveBlock => Event::MutexGiveBlock(event),
488                            _ /*EventType::MutexGiveRecursive*/ => Event::MutexGiveRecursive(event),
489                        },
490                ))
491            }
492
493            EventType::MutexTake
494            | EventType::MutexTakeBlock
495            | EventType::MutexTakeRecursive
496            | EventType::MutexTakeRecursiveBlock => {
497                let handle: ObjectHandle = object_handle(&mut r, event_id)?;
498                let ticks_to_wait = Some(Ticks(r.read_u32()?));
499                let entry = entry_table.entry(handle);
500                entry.set_class(ObjectClass::Mutex);
501                let event = MutexEvent {
502                    event_count,
503                    timestamp,
504                    handle,
505                    name: entry.symbol.clone().map(ObjectName::from),
506                    ticks_to_wait,
507                };
508                Some((
509                    event_code,
510                    match event_type {
511                            EventType::MutexTake => Event::MutexTake(event),
512                            EventType::MutexTakeBlock => Event::MutexTakeBlock(event),
513                            EventType::MutexTakeRecursive => Event::MutexTakeRecursive(event),
514                            _ /*EventType::MutexTakeRecursiveBlock*/ => Event::MutexTakeRecursiveBlock(event),
515                        },
516                ))
517            }
518
519            EventType::SemaphoreBinaryCreate => {
520                let handle: ObjectHandle = object_handle(&mut r, event_id)?;
521                let _unused = r.read_u32()?;
522                let entry = entry_table.entry(handle);
523                entry.set_class(ObjectClass::Semaphore);
524                let event = SemaphoreCreateEvent {
525                    event_count,
526                    timestamp,
527                    handle,
528                    name: entry.symbol.clone().map(ObjectName::from),
529                    count: None,
530                };
531                Some((event_code, Event::SemaphoreBinaryCreate(event)))
532            }
533
534            EventType::SemaphoreCountingCreate => {
535                let handle = object_handle(&mut r, event_id)?;
536                let count = Some(r.read_u32()?);
537                let entry = entry_table.entry(handle);
538                entry.set_class(ObjectClass::Semaphore);
539                let event = SemaphoreCreateEvent {
540                    event_count,
541                    timestamp,
542                    handle,
543                    name: entry.symbol.clone().map(ObjectName::from),
544                    count,
545                };
546                Some((event_code, Event::SemaphoreCountingCreate(event)))
547            }
548
549            EventType::SemaphoreGive
550            | EventType::SemaphoreGiveBlock
551            | EventType::SemaphoreGiveFromIsr
552            | EventType::SemaphoreTakeFromIsr => {
553                let handle: ObjectHandle = object_handle(&mut r, event_id)?;
554                let count = r.read_u32()?;
555                let event = SemaphoreEvent {
556                    event_count,
557                    timestamp,
558                    handle,
559                    name: entry_table.symbol(handle).cloned().map(ObjectName::from),
560                    ticks_to_wait: None,
561                    count,
562                };
563                Some((
564                    event_code,
565                    match event_type {
566                        EventType::SemaphoreGive => Event::SemaphoreGive(event),
567                        EventType::SemaphoreGiveBlock => Event::SemaphoreGiveBlock(event),
568                        EventType::SemaphoreGiveFromIsr => Event::SemaphoreGiveFromIsr(event),
569                        _ /*EventType::SemaphoreTakeFromIsr*/ => Event::SemaphoreTakeFromIsr(event),
570                    },
571                ))
572            }
573
574            EventType::SemaphoreTake
575            | EventType::SemaphoreTakeBlock
576            | EventType::SemaphorePeek
577            | EventType::SemaphorePeekBlock => {
578                let handle: ObjectHandle = object_handle(&mut r, event_id)?;
579                let ticks_to_wait = Some(Ticks(r.read_u32()?));
580                let count = r.read_u32()?;
581                let event = SemaphoreEvent {
582                    event_count,
583                    timestamp,
584                    handle,
585                    name: entry_table.symbol(handle).cloned().map(ObjectName::from),
586                    ticks_to_wait,
587                    count,
588                };
589                Some((
590                    event_code,
591                    match event_type {
592                        EventType::SemaphoreTake => Event::SemaphoreTake(event),
593                        EventType::SemaphoreTakeBlock => Event::SemaphoreTakeBlock(event),
594                        EventType::SemaphorePeek => Event::SemaphorePeek(event),
595                        _ /*EventType::SemaphorePeekBlock*/ => Event::SemaphorePeekBlock(event),
596                    },
597                ))
598            }
599
600            EventType::EventGroupCreate => {
601                let handle: ObjectHandle = object_handle(&mut r, event_id)?;
602                let event_bits = r.read_u32()?;
603                let entry = entry_table.entry(handle);
604                entry.set_class(ObjectClass::EventGroup);
605                let event = EventGroupCreateEvent {
606                    event_count,
607                    timestamp,
608                    handle,
609                    name: entry.symbol.clone().map(ObjectName::from),
610                    event_bits,
611                };
612                Some((event_code, Event::EventGroupCreate(event)))
613            }
614
615            EventType::EventGroupSync
616            | EventType::EventGroupWaitBits
617            | EventType::EventGroupClearBits
618            | EventType::EventGroupClearBitsFromIsr
619            | EventType::EventGroupSetBits
620            | EventType::EventGroupSetBitsFromIsr
621            | EventType::EventGroupSyncBlock
622            | EventType::EventGroupWaitBitsBlock => {
623                let handle = object_handle(&mut r, event_id)?;
624                let bits = r.read_u32()?;
625                let event = EventGroupEvent {
626                    event_count,
627                    timestamp,
628                    handle,
629                    name: entry_table.symbol(handle).cloned().map(ObjectName::from),
630                    bits,
631                };
632                Some((
633                    event_code,
634                    match event_type {
635                        EventType::EventGroupSync => Event::EventGroupSync(event),
636                        EventType::EventGroupWaitBits => Event::EventGroupWaitBits(event),
637                        EventType::EventGroupClearBits => Event::EventGroupClearBits(event),
638                        EventType::EventGroupClearBitsFromIsr => Event::EventGroupClearBitsFromIsr(event),
639                        EventType::EventGroupSetBits => Event::EventGroupSetBits(event),
640                        EventType::EventGroupSetBitsFromIsr => Event::EventGroupSetBitsFromIsr(event),
641                        EventType::EventGroupSyncBlock => Event::EventGroupSyncBlock(event),
642                        _ /*EventType::EventGroupWaitBitsBlock*/ => Event::EventGroupWaitBitsBlock(event),
643                    },
644                ))
645            }
646
647            EventType::MessageBufferCreate => {
648                let handle: ObjectHandle = object_handle(&mut r, event_id)?;
649                let buffer_size = r.read_u32()?;
650                let entry = entry_table.entry(handle);
651                entry.set_class(ObjectClass::MessageBuffer);
652                let event = MessageBufferCreateEvent {
653                    event_count,
654                    timestamp,
655                    handle,
656                    name: entry.symbol.clone().map(ObjectName::from),
657                    buffer_size,
658                };
659                Some((event_code, Event::MessageBufferCreate(event)))
660            }
661
662            EventType::MessageBufferSend
663            | EventType::MessageBufferReceive
664            | EventType::MessageBufferSendFromIsr
665            | EventType::MessageBufferReceiveFromIsr
666            | EventType::MessageBufferReset => {
667                let handle = object_handle(&mut r, event_id)?;
668                let bytes_in_buffer = r.read_u32()?;
669                let event = MessageBufferEvent {
670                    event_count,
671                    timestamp,
672                    handle,
673                    name: entry_table.symbol(handle).cloned().map(ObjectName::from),
674                    bytes_in_buffer,
675                };
676                Some((
677                    event_code,
678                    match event_type {
679                        EventType::MessageBufferSend => Event::MessageBufferSend(event),
680                        EventType::MessageBufferReceive => Event::MessageBufferReceive(event),
681                        EventType::MessageBufferSendFromIsr => Event::MessageBufferSendFromIsr(event),
682                        EventType::MessageBufferReceiveFromIsr => Event::MessageBufferReceiveFromIsr(event),
683                        _ /*EventType::MessageBufferReset*/ => Event::MessageBufferReset(event),
684                    },
685                ))
686            }
687
688            EventType::MessageBufferSendBlock | EventType::MessageBufferReceiveBlock => {
689                let handle = object_handle(&mut r, event_id)?;
690                let event = MessageBufferBlockEvent {
691                    event_count,
692                    timestamp,
693                    handle,
694                    name: entry_table.symbol(handle).cloned().map(ObjectName::from),
695                };
696                Some((
697                    event_code,
698                    match event_type {
699                        EventType::MessageBufferSendBlock => Event::MessageBufferSendBlock(event),
700                        _ /*EventType::MessageBufferReceiveBlock*/ => Event::MessageBufferReceiveBlock(event),
701                    },
702                ))
703            }
704
705            EventType::StateMachineCreate => {
706                let handle = object_handle(&mut r, event_id)?;
707                let _unused = r.read_u32()?;
708                let entry = entry_table.entry(handle);
709                entry.set_class(ObjectClass::StateMachine);
710                let sym = entry.symbol.as_ref().ok_or(Error::ObjectLookup(handle))?;
711                let event = StateMachineCreateEvent {
712                    event_count,
713                    timestamp,
714                    handle,
715                    name: sym.clone().into(),
716                };
717                Some((event_code, Event::StateMachineCreate(event)))
718            }
719
720            EventType::StateMachineStateCreate => {
721                let state_handle = object_handle(&mut r, event_id)?;
722                let state_machine_handle = object_handle(&mut r, event_id)?;
723                let entry = entry_table.entry(state_handle);
724                entry.set_class(ObjectClass::StateMachine);
725                let state_machine_sym = entry_table
726                    .entry(state_machine_handle)
727                    .symbol
728                    .as_ref()
729                    .map(|s| ObjectName::from(s.clone()))
730                    .ok_or(Error::ObjectLookup(state_machine_handle))?;
731                let state_sym = entry_table
732                    .entry(state_handle)
733                    .symbol
734                    .as_ref()
735                    .map(|s| ObjectName::from(s.clone()))
736                    .ok_or(Error::ObjectLookup(state_handle))?;
737                let event = StateMachineStateEvent {
738                    event_count,
739                    timestamp,
740                    handle: state_machine_handle,
741                    name: state_machine_sym,
742                    state_handle,
743                    state: state_sym,
744                };
745                Some((event_code, Event::StateMachineStateCreate(event)))
746            }
747
748            EventType::StateMachineStateChange => {
749                let state_machine_handle = object_handle(&mut r, event_id)?;
750                let state_handle = object_handle(&mut r, event_id)?;
751                let state_machine_sym = entry_table
752                    .entry(state_machine_handle)
753                    .symbol
754                    .as_ref()
755                    .map(|s| ObjectName::from(s.clone()))
756                    .ok_or(Error::ObjectLookup(state_machine_handle))?;
757                let state_sym = entry_table
758                    .entry(state_handle)
759                    .symbol
760                    .as_ref()
761                    .map(|s| ObjectName::from(s.clone()))
762                    .ok_or(Error::ObjectLookup(state_handle))?;
763                let event = StateMachineStateChangeEvent {
764                    event_count,
765                    timestamp,
766                    handle: state_machine_handle,
767                    name: state_machine_sym,
768                    state_handle,
769                    state: state_sym,
770                };
771                Some((event_code, Event::StateMachineStateChange(event)))
772            }
773
774            EventType::UnusedStack => {
775                let handle = object_handle(&mut r, event_id)?;
776                let low_mark = r.read_u32()?;
777                let sym = entry_table
778                    .symbol(handle)
779                    .ok_or(Error::ObjectLookup(handle))?;
780                let event = UnusedStackEvent {
781                    event_count,
782                    timestamp,
783                    handle,
784                    task: sym.clone().into(),
785                    low_mark,
786                };
787                Some((event_code, Event::UnusedStack(event)))
788            }
789
790            EventType::UserEvent(raw_arg_count) => {
791                // Always expect at least a channel
792                if num_params.0 < 1 {
793                    return Err(Error::InvalidEventParameterCount(
794                        event_code.event_id(),
795                        1,
796                        num_params,
797                    ));
798                }
799
800                // Account for fixed user events when can occupy part of the user event ID space
801                let (is_fixed, arg_count) = if event_id.0 >= FIXED_USER_EVENT_ID
802                    && usize::from(raw_arg_count) >= usize::from(num_params)
803                {
804                    (
805                        true,
806                        UserEventArgRecordCount((event_id.0 - FIXED_USER_EVENT_ID) as u8),
807                    )
808                } else {
809                    (false, raw_arg_count)
810                };
811
812                if usize::from(arg_count) >= usize::from(num_params) {
813                    return Err(Error::InvalidEventParameterCount(
814                        event_code.event_id(),
815                        usize::from(arg_count),
816                        num_params,
817                    ));
818                }
819
820                // Parse out <channel-handle> [args] <format-string>
821                let channel_handle = object_handle(&mut r, event_id)?;
822                let channel = entry_table
823                    .symbol(channel_handle)
824                    .map(|sym| UserEventChannel::Custom(sym.clone().into()))
825                    .unwrap_or(UserEventChannel::Default);
826
827                self.arg_buf.clear();
828
829                let format_string = if is_fixed {
830                    let fmt_string_handle = object_handle(&mut r, event_id)?;
831
832                    let num_arg_bytes = usize::from(arg_count.0) * 4;
833                    if num_arg_bytes != 0 {
834                        self.arg_buf.resize(num_arg_bytes, 0);
835                        r.read_exact(&mut self.arg_buf)?;
836                    }
837
838                    let res = entry_table
839                        .symbol(fmt_string_handle)
840                        .map(|s| TrimmedString::from_str(s))
841                        .ok_or(Error::FixedUserEventFmtStringLookup(fmt_string_handle));
842                    match res {
843                        Ok(fmt_string) => fmt_string,
844                        Err(e) => {
845                            // Need to read out the rest of the arg data so the parser can skip over the
846                            // invalid data
847                            // +2 since we already read channel and fmt string words
848                            let remaining_param_words =
849                                num_params.0.saturating_sub(arg_count.0 + 2);
850                            if remaining_param_words != 0 {
851                                let mut parameters = [0; EventParameterCount::MAX];
852                                r.read_u32_into(
853                                    &mut parameters[..usize::from(remaining_param_words)],
854                                )?;
855                            }
856                            return Err(e);
857                        }
858                    }
859                } else {
860                    // arg_count includes the format string, we want the args, if any
861                    let not_fmt_str_arg_count = if arg_count.0 != 0 {
862                        usize::from(arg_count) - 1
863                    } else {
864                        0
865                    };
866                    let num_arg_bytes = not_fmt_str_arg_count * 4;
867                    if num_arg_bytes != 0 {
868                        self.arg_buf.resize(num_arg_bytes, 0);
869                        r.read_exact(&mut self.arg_buf)?;
870                    }
871
872                    let num_fmt_str_bytes =
873                        (usize::from(num_params) - 1 - not_fmt_str_arg_count) * 4;
874                    self.read_string(&mut r, num_fmt_str_bytes)?
875                };
876
877                let (formatted_string, args) = match format_symbol_string(
878                    entry_table,
879                    Protocol::Streaming,
880                    self.endianness.into(),
881                    &format_string,
882                    &self.arg_buf,
883                ) {
884                    Ok((fs, args)) => (fs, args),
885                    Err(e) => {
886                        error!("Failed to parse user event format string arguments, using the raw symbol instead. {e}");
887                        (
888                            FormattedString(format_string.clone().into()),
889                            Default::default(),
890                        )
891                    }
892                };
893
894                let event = UserEvent {
895                    event_count,
896                    timestamp,
897                    channel,
898                    format_string: FormatString(format_string.0),
899                    formatted_string,
900                    args,
901                };
902                Some((event_code, Event::User(event)))
903            }
904
905            EventType::Unknown(_)
906                if self
907                    .custom_printf_event_id
908                    .map(|id| id == event_id)
909                    .unwrap_or(false) =>
910            {
911                if num_params.0 != 0 {
912                    return Err(Error::InvalidEventParameterCount(
913                        event_code.event_id(),
914                        0,
915                        num_params,
916                    ));
917                }
918
919                let channel_handle = object_handle(&mut r, event_id)?;
920                let channel = entry_table
921                    .symbol(channel_handle)
922                    .map(|sym| UserEventChannel::Custom(sym.clone().into()))
923                    .unwrap_or(UserEventChannel::Default);
924
925                let args_len = r.read_u16()?;
926                let fmt_len = r.read_u16()?;
927
928                self.arg_buf.clear();
929                let num_arg_bytes = usize::from(args_len) * 4;
930                if num_arg_bytes != 0 {
931                    self.arg_buf.resize(num_arg_bytes, 0);
932                    r.read_exact(&mut self.arg_buf)?;
933                }
934
935                let format_string = self.read_string(&mut r, fmt_len.into())?;
936
937                let (formatted_string, args) = match format_symbol_string(
938                    entry_table,
939                    Protocol::Streaming,
940                    self.endianness.into(),
941                    &format_string,
942                    &self.arg_buf,
943                ) {
944                    Ok((fs, args)) => (fs, args),
945                    Err(e) => {
946                        error!("Failed to parse custom printf event format string arguments, using the raw symbol instead. {e}");
947                        (
948                            FormattedString(format_string.clone().into()),
949                            Default::default(),
950                        )
951                    }
952                };
953
954                let event = UserEvent {
955                    event_count,
956                    timestamp,
957                    channel,
958                    format_string: FormatString(format_string.0),
959                    formatted_string,
960                    args,
961                };
962                Some((event_code, Event::User(event)))
963            }
964
965            // Return the base event type for everything else
966            _ => {
967                let mut parameters = [0; EventParameterCount::MAX];
968                r.read_u32_into(&mut parameters[..usize::from(num_params)])?;
969                let event = BaseEvent {
970                    code: event_code,
971                    event_count,
972                    timestamp,
973                    parameters,
974                };
975                Some((event_code, Event::Unknown(event)))
976            }
977        })
978    }
979
980    fn read_string<R: Read>(&mut self, r: &mut R, max_len: usize) -> Result<TrimmedString, Error> {
981        self.buf.clear();
982        self.buf.resize(max_len, 0);
983        r.read_exact(&mut self.buf)?;
984        Ok(TrimmedString::from_raw(&self.buf))
985    }
986}
987
988fn object_handle<T: byteordered::byteorder::ReadBytesExt, E: byteordered::Endian>(
989    r: &mut ByteOrdered<T, E>,
990    event_id: EventId,
991) -> Result<ObjectHandle, Error> {
992    let oh = r.read_u32()?;
993    ObjectHandle::new(oh).ok_or(Error::InvalidObjectHandle(event_id))
994}