ccsds_tc_services
The ccsds_tc_services library provides service-aware helpers that
sit above raw ccsds_frames telecommand transfer frame terms.
This first implementation slice covers:
extracting telecommand segments from CCSDS telecommand transfer frames
encoding telecommand segments back into telecommand transfer frames
tracking segmented telecommand reassembly state per spacecraft identifier and virtual channel identifier
keeping pending segmented data separately per MAP identifier inside each virtual channel
detecting telecommand frame-sequence discontinuities during reassembly
applying configurable discontinuity recovery policies during reassembly
returning explicit recovery event streams from the richer frame reassembly predicates
returning provenance-aware reassembled service-unit terms that preserve the ordered per-frame mission-specific segment-header suffixes contributing to a complete telecommand service unit
grouping complete telecommand service units into MAP-aware dispatch buckets so callers can route them by MAP identifier without rebuilding that bookkeeping
Representation
Telecommand segments extracted by this library are represented using the compound term:
tc_segment(SequenceFlags, MapId, HeaderSuffix, Data)
Where:
SequenceFlagsis one ofcontinuation,first,last, orunsegmentedMapIdis the multiplexer access point identifier in the range 0-63HeaderSuffixis the list of mission-specific segment-header octets that follow the standard first octetDatais the segment data as a list of bytes
The compact term tc_segment(SequenceFlags, MapId, Data) is also
accepted by predicates such as valid_segment/1 and
insert_tc_segment/3 as shorthand for an empty header suffix.
Reassembled service units that are reconstructed from multiple transfer
frames use the empty list as HeaderSuffix, as there is no single
mission-specific suffix value that unambiguously represents the merged
result.
When callers need that provenance instead of the compact compatibility view, the companion reassembly predicates return terms of the form:
tc_reassembled_segment(MapId, HeaderSuffixes, Data)
Where HeaderSuffixes is the ordered list of the per-frame
mission-specific segment-header suffixes that contributed to the
complete service unit.
MAP-aware dispatch helpers group complete telecommand service units into terms of the form:
map_dispatch(MapId, ServiceUnits)
Where ServiceUnits is a list of complete telecommand service-unit
terms for a single MapId, preserving the original service-unit order
inside each bucket and the first-seen order of the MAP buckets.
Telecommand reassembly state is represented using the compound term:
tc_reassembly_state(Channels)
Where Channels is a list of terms of the form:
tc_reassembly_channel(SpacecraftId, VirtualChannelId, ExpectedSequenceNumber, PendingSegments)
The PendingSegments list stores the currently buffered segmented
data by MAP identifier using terms of the form:
tc_pending_segment(MapId, PendingData)
Pending buffered fragments can be queried using pending_fragments/2,
which returns flattened terms of the form:
pending_fragment(SpacecraftId, VirtualChannelId, MapId, PendingData)
Discontinuity recovery policies are represented by the atoms:
throw
drop
resynchronize
The policies have the following meaning when a frame sequence discontinuity is found for a telecommand virtual channel:
throw: raise adomain_error/2exceptiondrop: discard all pending MAP fragments for that virtual channel and skip the discontinuous frame payloadresynchronize: discard all pending MAP fragments for that virtual channel and still process the current frame payload
Recovery event streams are returned by reassemble_tc_frame/6 and
reassemble_tc_frames/6 as lists of terms of the form:
dropped_fragment(SpacecraftId, VirtualChannelId, MapId, Reason, PendingData)
skipped_frame(SpacecraftId, VirtualChannelId, Discontinuity)
resynchronized(SpacecraftId, VirtualChannelId, Discontinuity)
Where Discontinuity is represented by:
discontinuity(ExpectedSequenceNumber, SequenceNumber)
Provenance-aware reassembly is provided by the companion predicates
reassemble_tc_frame_with_provenance/5-6 and
reassemble_tc_frames_with_provenance/5-6.
MAP-aware dispatch is provided by dispatch_service_units_by_map/2-3,
which accept both compact telecommand segment terms and provenance-aware
reassembled telecommand service-unit terms.
Scope
This first milestone interprets the standard telecommand MAP and
sequence semantics from the first segment-header octet, where the high
two bits encode the sequence flags and the low six bits encode the MAP
identifier. Transfer frames with longer mission-specific segment headers
are also supported: additional segment-header octets are exposed in
extracted segment terms as the HeaderSuffix component and are
preserved when updating frames.
Examples
To extract a telecommand segment from a telecommand transfer frame term:
| ?- ccsds_tc_services::extract_tc_segment(tc_transfer_frame(0, 1, 0, 42, 3, 7, segment_header([0xC5]), [1,2,3], none), Segment).
To update a telecommand transfer frame from a telecommand segment term:
| ?- ccsds_tc_services::insert_tc_segment(tc_segment(first, 42, [1,2,3]), tc_transfer_frame(0, 1, 0, 42, 3, 7, none, [], none), UpdatedFrame).
To inspect the mission-specific segment-header suffix from an extracted telecommand segment term:
| ?- ccsds_tc_services::segment_header_suffix(tc_segment(first, 5, [0xAA,0xBB], [1,2,3]), HeaderSuffix).
Mission-specific segment-header suffix octets are preserved when present in the input frame term:
| ?- ccsds_tc_services::insert_tc_segment(tc_segment(first, 42, [1,2,3]), tc_transfer_frame(0, 1, 0, 42, 3, 7, segment_header([0x00,0xAA,0xBB]), [], none), UpdatedFrame).
To reassemble a segmented telecommand service unit across a sequence of frames:
| ?- ccsds_tc_services::reassemble_tc_frames([tc_transfer_frame(0, 1, 0, 42, 3, 7, segment_header([0x45]), [1,2], none), tc_transfer_frame(0, 1, 0, 42, 3, 8, segment_header([0x85]), [3,4], none)], tc_reassembly_state([]), Segments, UpdatedState).
To reassemble a segmented telecommand service unit across a sequence of frames and preserve the ordered per-frame mission-specific header-suffix provenance:
| ?- ccsds_tc_services::reassemble_tc_frames_with_provenance([tc_transfer_frame(0, 1, 0, 42, 3, 7, segment_header([0x45,0xAA]), [1,2], none), tc_transfer_frame(0, 1, 0, 42, 3, 8, segment_header([0x85,0xBB]), [3,4], none)], tc_reassembly_state([]), ReassembledSegments, UpdatedState, Events).
To group complete telecommand service units into MAP-aware dispatch buckets:
| ?- ccsds_tc_services::dispatch_service_units_by_map([tc_segment(unsegmented, 7, [], [0x01]), tc_reassembled_segment(6, [[0xBB]], [0x03]), tc_reassembled_segment(7, [[0xAA]], [0x02])], Dispatches).
To resynchronize on a discontinuous telecommand frame while receiving explicit recovery events:
| ?- ccsds_tc_services::reassemble_tc_frame(tc_transfer_frame(0, 1, 0, 42, 3, 9, segment_header([0xC6]), [9], none), resynchronize, tc_reassembly_state([tc_reassembly_channel(42, 3, 8, [tc_pending_segment(5, [1])])]), Segments, UpdatedState, Events).
API documentation
Open the ../../apis/library_index.html#ccsds_tc_services link in a web browser.
Loading
To load all entities in this library, load the loader.lgt file:
| ?- logtalk_load(ccsds_tc_services(loader)).
Testing
To test this library predicates, load the tester.lgt file:
| ?- logtalk_load(ccsds_tc_services(tester)).