33//! This module implements a priority queue system designed for real-time
44//! space communication systems where message prioritization is critical
55//! for mission success.
6+ //!
7+ //! # Requirements Traceability
8+ //! - REQ-FN-001: Priority Classification (MessagePriority enum)
9+ //! - REQ-FN-009: Message Queue Management (PriorityQueue implementation)
10+ //! - REQ-FN-010: Real-Time Constraints (timing constraints in max_latency_ms)
611
712use core:: cmp:: Ordering ;
8- use serde:: { Deserialize , Serialize } ;
913use heapless:: binary_heap:: { BinaryHeap , Max } ;
14+ use serde:: { Deserialize , Serialize } ;
1015
11- use crate :: error:: { Result , SpaceCommError , MemoryErrorType } ;
12- use crate :: types:: { MessageId , ComponentId , BandType } ;
16+ use crate :: error:: { MemoryErrorType , Result , SpaceCommError } ;
17+ use crate :: types:: { BandType , ComponentId , MessageId } ;
1318
1419/// Message priority levels following NASA mission-critical classification
20+ /// REQ-FN-001: Priority Classification - Five-tier priority system
1521#[ derive( Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Serialize , Deserialize ) ]
1622#[ repr( u8 ) ]
1723pub enum MessagePriority {
1824 /// Lowest priority - routine housekeeping data
1925 /// Processing frequency: ~10 Hz
26+ /// REQ-FN-006: Low Priority Commands
2027 Low = 1 ,
2128
2229 /// Medium priority - normal telemetry and data
2330 /// Processing frequency: ~100 Hz
31+ /// REQ-FN-005: Medium Priority Commands
2432 Medium = 2 ,
2533
2634 /// High priority - important system status
2735 /// Processing frequency: ~500 Hz
36+ /// REQ-FN-004: High Priority Commands
2837 High = 3 ,
2938
3039 /// Critical priority - emergency commands and alerts
3140 /// Processing frequency: ~1000 Hz, latency <1ms
41+ /// REQ-FN-003: Critical Command Set
3242 Critical = 4 ,
3343
3444 /// Emergency priority - life-safety and mission-critical
3545 /// Processing frequency: immediate, latency <0.5ms
46+ /// REQ-FN-002: Emergency Command Set
3647 Emergency = 5 ,
3748}
3849
@@ -49,13 +60,14 @@ impl MessagePriority {
4960 }
5061
5162 /// Get the maximum acceptable latency in milliseconds
63+ /// REQ-FN-010: Real-Time Constraints - Processing latency requirements
5264 pub const fn max_latency_ms ( & self ) -> u32 {
5365 match self {
54- MessagePriority :: Low => 1000 , // 1 second
55- MessagePriority :: Medium => 100 , // 100 ms
56- MessagePriority :: High => 10 , // 10 ms
57- MessagePriority :: Critical => 1 , // 1 ms
58- MessagePriority :: Emergency => 0 , // Immediate
66+ MessagePriority :: Low => 10000 , // 10 seconds - REQ-FN-006
67+ MessagePriority :: Medium => 1000 , // 1 second - REQ-FN-005
68+ MessagePriority :: High => 100 , // 100 ms - REQ-FN-004
69+ MessagePriority :: Critical => 10 , // 10 ms - REQ-FN-003
70+ MessagePriority :: Emergency => 1 , // 1 ms - REQ-FN-002
5971 }
6072 }
6173
@@ -151,7 +163,9 @@ impl MessagePayload {
151163 MessagePayload :: Command { parameters, .. } => parameters. len ( ) ,
152164 MessagePayload :: Status { message, .. } => message. len ( ) ,
153165 MessagePayload :: Raw { data } => data. len ( ) ,
154- MessagePayload :: Emergency { description, data, .. } => description. len ( ) + data. len ( ) ,
166+ MessagePayload :: Emergency {
167+ description, data, ..
168+ } => description. len ( ) + data. len ( ) ,
155169 }
156170 }
157171
@@ -225,9 +239,9 @@ impl<const N: usize> PriorityQueue<N> {
225239
226240 self . sequence_counter = self . sequence_counter . wrapping_add ( 1 ) ;
227241
228- self . heap . push ( priority_message ) . map_err ( |_| {
229- SpaceCommError :: memory_error ( MemoryErrorType :: BufferOverflow , Some ( N ) )
230- } )
242+ self . heap
243+ . push ( priority_message )
244+ . map_err ( |_| SpaceCommError :: memory_error ( MemoryErrorType :: BufferOverflow , Some ( N ) ) )
231245 }
232246
233247 /// Remove and return the highest priority message
@@ -273,11 +287,12 @@ impl<const N: usize> PriorityQueue<N> {
273287
274288 while let Some ( priority_message) = self . heap . pop ( ) {
275289 let message_age = current_time_seconds. saturating_sub (
276- priority_message. message . timestamp / 1_000_000_000 // Convert ns to seconds
290+ priority_message. message . timestamp / 1_000_000_000 , // Convert ns to seconds
277291 ) ;
278292
279- if priority_message. message . ttl_seconds == 0 ||
280- message_age < priority_message. message . ttl_seconds . into ( ) {
293+ if priority_message. message . ttl_seconds == 0
294+ || message_age < priority_message. message . ttl_seconds . into ( )
295+ {
281296 // Message is not expired, keep it
282297 if temp_messages. push ( priority_message) . is_err ( ) {
283298 // If we can't store it, we have to drop it (should not happen in normal operation)
@@ -362,7 +377,7 @@ impl QueueStatistics {
362377#[ cfg( test) ]
363378mod tests {
364379 use super :: * ;
365- use crate :: types:: { MessageId , ComponentId } ;
380+ use crate :: types:: { ComponentId , MessageId } ;
366381
367382 fn create_test_message ( priority : MessagePriority , id : u64 ) -> Message {
368383 Message {
@@ -372,7 +387,7 @@ mod tests {
372387 destination : ComponentId :: new ( 2 ) ,
373388 timestamp : 0 ,
374389 payload : MessagePayload :: Raw {
375- data : heapless:: Vec :: new ( )
390+ data : heapless:: Vec :: new ( ) ,
376391 } ,
377392 preferred_band : BandType :: SBand ,
378393 ttl_seconds : 0 ,
@@ -394,9 +409,15 @@ mod tests {
394409 let mut queue: PriorityQueue < 10 > = PriorityQueue :: new ( ) ;
395410
396411 // Add messages in random order
397- queue. push ( create_test_message ( MessagePriority :: Low , 1 ) ) . unwrap ( ) ;
398- queue. push ( create_test_message ( MessagePriority :: Emergency , 2 ) ) . unwrap ( ) ;
399- queue. push ( create_test_message ( MessagePriority :: Medium , 3 ) ) . unwrap ( ) ;
412+ queue
413+ . push ( create_test_message ( MessagePriority :: Low , 1 ) )
414+ . unwrap ( ) ;
415+ queue
416+ . push ( create_test_message ( MessagePriority :: Emergency , 2 ) )
417+ . unwrap ( ) ;
418+ queue
419+ . push ( create_test_message ( MessagePriority :: Medium , 3 ) )
420+ . unwrap ( ) ;
400421
401422 // Should pop in priority order
402423 assert_eq ! ( queue. pop( ) . unwrap( ) . priority, MessagePriority :: Emergency ) ;
@@ -409,9 +430,15 @@ mod tests {
409430 let mut queue: PriorityQueue < 10 > = PriorityQueue :: new ( ) ;
410431
411432 // Add multiple messages with same priority
412- queue. push ( create_test_message ( MessagePriority :: High , 1 ) ) . unwrap ( ) ;
413- queue. push ( create_test_message ( MessagePriority :: High , 2 ) ) . unwrap ( ) ;
414- queue. push ( create_test_message ( MessagePriority :: High , 3 ) ) . unwrap ( ) ;
433+ queue
434+ . push ( create_test_message ( MessagePriority :: High , 1 ) )
435+ . unwrap ( ) ;
436+ queue
437+ . push ( create_test_message ( MessagePriority :: High , 2 ) )
438+ . unwrap ( ) ;
439+ queue
440+ . push ( create_test_message ( MessagePriority :: High , 3 ) )
441+ . unwrap ( ) ;
415442
416443 // Should pop in FIFO order (first added, first out)
417444 assert_eq ! ( queue. pop( ) . unwrap( ) . id. value( ) , 1 ) ;
@@ -423,20 +450,32 @@ mod tests {
423450 fn test_queue_capacity ( ) {
424451 let mut queue: PriorityQueue < 2 > = PriorityQueue :: new ( ) ;
425452
426- assert ! ( queue. push( create_test_message( MessagePriority :: Low , 1 ) ) . is_ok( ) ) ;
427- assert ! ( queue. push( create_test_message( MessagePriority :: Low , 2 ) ) . is_ok( ) ) ;
453+ assert ! ( queue
454+ . push( create_test_message( MessagePriority :: Low , 1 ) )
455+ . is_ok( ) ) ;
456+ assert ! ( queue
457+ . push( create_test_message( MessagePriority :: Low , 2 ) )
458+ . is_ok( ) ) ;
428459
429460 // Third message should fail
430- assert ! ( queue. push( create_test_message( MessagePriority :: Low , 3 ) ) . is_err( ) ) ;
461+ assert ! ( queue
462+ . push( create_test_message( MessagePriority :: Low , 3 ) )
463+ . is_err( ) ) ;
431464 }
432465
433466 #[ test]
434467 fn test_queue_statistics ( ) {
435468 let mut queue: PriorityQueue < 10 > = PriorityQueue :: new ( ) ;
436469
437- queue. push ( create_test_message ( MessagePriority :: Low , 1 ) ) . unwrap ( ) ;
438- queue. push ( create_test_message ( MessagePriority :: High , 2 ) ) . unwrap ( ) ;
439- queue. push ( create_test_message ( MessagePriority :: Emergency , 3 ) ) . unwrap ( ) ;
470+ queue
471+ . push ( create_test_message ( MessagePriority :: Low , 1 ) )
472+ . unwrap ( ) ;
473+ queue
474+ . push ( create_test_message ( MessagePriority :: High , 2 ) )
475+ . unwrap ( ) ;
476+ queue
477+ . push ( create_test_message ( MessagePriority :: Emergency , 3 ) )
478+ . unwrap ( ) ;
440479
441480 let stats = queue. statistics ( ) ;
442481 assert_eq ! ( stats. total, 3 ) ;
0 commit comments