| Did you know ... | Search Documentation: |
| Pack logtalk -- logtalk-3.100.1/docs/handbook/_sources/libraries/ccsds_packet_services.rst.txt |
.. _library_ccsds_packet_services:
ccsds_packet_services
The ccsds_packet_services library provides service-aware helpers
that sit above the raw ccsds_packets and ccsds_frames codec
libraries.
The current implementation supports telemetry and advanced orbiting
systems packet-zone handling above the raw ccsds_frames payload
bridge:
Packet zones are represented using the compound term:
::
packet_zone(PrefixData, Packets, SuffixData)
Where:
PrefixData is a list of bytes preceding the first complete packetPackets is a list of complete ccsds_packet(...) termsSuffixData is a list of bytes trailing the last complete packet
When a telemetry transfer frame first header pointer indicates that no
packet starts in the frame data field, the full data field is
represented as:
::
packet_zone(DataField, [], [])
For AOS packet service data fields, the same term is used after decoding the two-octet M_PDU first header pointer:
packet_zone(PrefixData, [], []) corresponds to first header
pointer 2047 and means that no packet starts in this frame packet
zonepacket_zone([], [], SuffixData) corresponds to first header
pointer 2046 and means that the packet zone contains idle data
only
Cross-frame packet reassembly state is represented using the compound term:
::
packet_reassembly_state(PendingData)
Where PendingData is a list of bytes belonging to an incomplete
packet whose header started in an earlier frame and whose remaining
bytes are expected in a later frame.
Frame-channel reassembly state is represented using the compound term:
::
channel_reassembly_state(Channels)
Where Channels is a list of terms of the form:
::
reassembly_channel(FrameType, SpacecraftId, VirtualChannelId, CounterModulus, ExpectedFrameCount, PendingData)
The FrameType argument is either tm or aos. The keyed state
is used by the frame-level reassembly predicates so that interleaved
virtual channels and TM versus AOS streams do not collide.
Discontinuity recovery policies are represented by the atoms:
::
throw drop resynchronize
The policies have the following meaning when a frame-count discontinuity is detected for a keyed channel:
throw: raise a domain_error/2 exception and leave recovery to
the callerdrop: discard any buffered fragment for that keyed channel and
skip the discontinuous frame payload entirelyresynchronize: discard any buffered fragment for that keyed
channel but still process the current frame, ignoring any pre-pointer
continuation bytes
Recovery event streams are returned by the seven-argument TM and AOS frame reassembly predicates as lists of terms of the form:
::
dropped_fragment(FrameType, SpacecraftId, VirtualChannelId, Reason, PendingData)
skipped_frame(FrameType, SpacecraftId, VirtualChannelId, Discontinuity)
resynchronized(FrameType, SpacecraftId, VirtualChannelId, Discontinuity)
Where Reason is either:
discontinuity(StoredCounterModulus, CounterModulus, ExpectedFrameCount, VirtualChannelFrameCount)idle_only(VirtualChannelFrameCount) for AOS idle-only M_PDUs that
clear a buffered fragmentTo split a packet zone using a first header pointer and parse the complete packets that start there:
::
| ?- ccsds_packet_services::split_packet_zone([0xAA,0xBB,0x00,0x00,0xC0,0x00,0x00,0x00,0x42,0xCC], 2, 0, PacketZone).
To rebuild a packet zone and recover the corresponding first header pointer:
::
| ?- ccsds_packet_services::join_packet_zone(packet_zone([0xAA,0xBB], [ccsds_packet(0,0,0,0,3,0,none,[0x42])], [0xCC]), 0, Bytes, FirstHeaderPointer).
To extract a packet zone from a telemetry transfer frame term:
::
| ?- ccsds_packet_services::extract_tm_packets(tm_transfer_frame(0, 42, 3, 0, 16, 32, 0, 0, 0, 3, 2, none, [0xAA,0xBB,0x00,0x00,0xC0,0x00,0x00,0x00,0x42,0xCC], none, none), 0, PacketZone).
To update a telemetry transfer frame from a packet zone term:
::
| ?- ccsds_packet_services::insert_tm_packets(packet_zone([0xAA,0xBB], [ccsds_packet(0,0,0,0,3,0,none,[0x42])], [0xCC]), 0, tm_transfer_frame(0, 42, 3, 0, 16, 32, 0, 0, 0, 3, 0, none, [], none, none), UpdatedFrame).
If the input TM frame already carries a fecf/1 term,
insert_tm_packets/4 refreshes it from the updated frame bytes.
Frames with none keep none.
To split an AOS M_PDU packet-service data field:
::
| ?- ccsds_packet_services::split_aos_packet_zone([0x00,0x02,0xAA,0xBB,0x00,0x00,0xC0,0x00,0x00,0x00,0x42,0xCC], 0, PacketZone).
To rebuild an AOS M_PDU packet-service data field from a packet zone term:
::
| ?- ccsds_packet_services::join_aos_packet_zone(packet_zone([0xAA,0xBB], [ccsds_packet(0,0,0,0,3,0,none,[0x42])], [0xCC]), 0, Bytes).
To extract a packet zone from an AOS transfer frame term:
::
| ?- ccsds_packet_services::extract_aos_packets(aos_transfer_frame(1, 42, 3, 16, signaling_field(0,0,0,0), none, [0x00,0x02,0xAA,0xBB,0x00,0x00,0xC0,0x00,0x00,0x00,0x42,0xCC], none, none), 0, PacketZone).
To update an AOS transfer frame from a packet zone term:
::
| ?- ccsds_packet_services::insert_aos_packets(packet_zone([0xAA,0xBB], [ccsds_packet(0,0,0,0,3,0,none,[0x42])], [0xCC]), 0, aos_transfer_frame(1, 42, 3, 16, signaling_field(0,0,0,0), none, [], none, none), UpdatedFrame).
If the input AOS frame already carries a fecf/1 term,
insert_aos_packets/4 refreshes it from the updated frame bytes.
Frames with none keep none.
To get the initial low-level packet reassembly state:
::
| ?- ccsds_packet_services::initial_reassembly_state(State).
To get the initial keyed frame-channel reassembly state:
::
| ?- ccsds_packet_services::initial_channel_reassembly_state(State).
To reassemble a packet zone against a prior trailing fragment:
::
| ?- ccsds_packet_services::reassemble_packet_zone(packet_zone([0x00,0x00,0x42], [ccsds_packet(0,0,0,0,3,1,none,[0x43])], []), 0, packet_reassembly_state([0x00,0x00,0xC0,0x00]), Packets, UpdatedState).
To reassemble complete packets across a sequence of telemetry transfer frames:
::
| ?- ccsds_packet_services::reassemble_tm_frames([tm_transfer_frame(0, 42, 3, 0, 16, 32, 0, 0, 0, 3, 0, none, [0x00,0x00,0xC0,0x00], none, none), tm_transfer_frame(0, 42, 3, 0, 16, 33, 0, 0, 0, 3, 3, none, [0x00,0x00,0x42,0x00,0x00,0xC0,0x01,0x00,0x00,0x43], none, none)], 0, channel_reassembly_state([]), Packets, UpdatedState).
To reassemble telemetry transfer frames while resynchronizing automatically on a detected discontinuity:
::
| ?- ccsds_packet_services::reassemble_tm_packets(tm_transfer_frame(0, 42, 3, 0, 16, 34, 0, 0, 0, 3, 3, none, [0x00,0x00,0x42,0x00,0x00,0xC0,0x02,0x00,0x00,0x44], none, none), 0, resynchronize, channel_reassembly_state([reassembly_channel(tm,42,3,256,33,[0x00,0x00,0xC0,0x00])]), Packets, UpdatedState).
To reassemble a telemetry transfer frame and also receive explicit recovery events:
::
| ?- ccsds_packet_services::reassemble_tm_packets(tm_transfer_frame(0, 42, 3, 0, 16, 34, 0, 0, 0, 3, 3, none, [0x00,0x00,0x42,0x00,0x00,0xC0,0x02,0x00,0x00,0x44], none, none), 0, resynchronize, channel_reassembly_state([reassembly_channel(tm,42,3,256,33,[0x00,0x00,0xC0,0x00])]), Packets, UpdatedState, Events).
To reassemble complete packets across a sequence of AOS transfer frames:
::
| ?- ccsds_packet_services::reassemble_aos_frames([aos_transfer_frame(1, 42, 3, 16, signaling_field(0,0,0,0), none, [0x00,0x00,0x00,0x00,0xC0,0x00], none, none), aos_transfer_frame(1, 42, 3, 17, signaling_field(0,0,0,0), none, [0x00,0x03,0x00,0x00,0x42,0x00,0x00,0xC0,0x01,0x00,0x00,0x43], none, none)], 0, channel_reassembly_state([]), Packets, UpdatedState).
To reassemble AOS transfer frames while dropping a discontinuous frame and resetting the keyed buffered fragment:
::
| ?- ccsds_packet_services::reassemble_aos_packets(aos_transfer_frame(1, 42, 3, 18, signaling_field(0,0,0,0), none, [0x00,0x03,0x00,0x00,0x42,0x00,0x00,0xC0,0x02,0x00,0x00,0x44], none, none), 0, drop, channel_reassembly_state([reassembly_channel(aos,42,3,16777216,17,[0x00,0x00,0xC0,0x00])]), Packets, UpdatedState).
To reassemble AOS transfer frames and receive explicit recovery events across a frame sequence:
::
| ?- ccsds_packet_services::reassemble_aos_frames([aos_transfer_frame(1, 42, 3, 16, signaling_field(0,0,0,0), none, [0x00,0x00,0x00,0x00,0xC0,0x00], none, none), aos_transfer_frame(1, 42, 3, 18, signaling_field(0,0,0,0), none, [0x00,0x03,0x00,0x00,0x42,0x00,0x00,0xC0,0x02,0x00,0x00,0x44], none, none)], 0, drop, channel_reassembly_state([]), Packets, UpdatedState, Events).
To inspect the currently buffered keyed pending fragments:
::
| ?- ccsds_packet_services::pending_fragments(channel_reassembly_state([reassembly_channel(tm,42,3,256,33,[0x00,0x00,0xC0,0x00])]), PendingFragments).
For AOS packet service, idle-only M_PDUs clear any pending fragment
state. This matches the packet-zone interpretation where first header
pointer 2046 denotes idle data rather than continuation bytes.
If a TM or AOS frame arrives with a virtual-channel frame count
different from the keyed state expected count, the frame-level
reassembly predicates apply the selected discontinuity recovery policy.
The five-argument variants default to the throw policy. The
seven-argument variants additionally report the recovery decisions as an
explicit event stream.
This milestone covers TM transfer frame packet zones, AOS packet-service M_PDUs, low-level packet-fragment stitching, and keyed TM/AOS cross-frame packet reassembly with continuity checks and configurable discontinuity recovery. Future milestones can extend the same library with segmentation policies, idle packet generation, richer per-channel recovery controls, and higher level packetization policies.
Open the `../../apis/library_index.html#ccsds_packet_services <../../apis/library_index.html#ccsds_packet_services>`__ link in a web browser.
To load all entities in this library, load the loader.lgt file:
::
| ?- logtalk_load(ccsds_packet_services(loader)).
To test this library predicates, load the tester.lgt file:
::
| ?- logtalk_load(ccsds_packet_services(tester)).