diff --git a/src/ccsds_space_packet.gleam b/src/ccsds_space_packet.gleam index d07cae2..eca8580 100644 --- a/src/ccsds_space_packet.gleam +++ b/src/ccsds_space_packet.gleam @@ -1,95 +1,26 @@ import gleam/bool -import gleam/int import gleam/io -import gleam/string_tree - -pub type SpacePacketVersion { - VersionZero -} - -pub type SpacePacketType { - Telemetry - Command -} - -pub type SpacePacketSequenceFlags { - Continuation - FirstSegment - LastSegment - Unsegmented -} - -pub type SpacePacketHeader { - SpacePacketHeader( - version: SpacePacketVersion, - sp_type: SpacePacketType, - sec_hdr_flag: Bool, - apid: Int, - seq_flag: SpacePacketSequenceFlags, - seq_count: Int, - packet_len: Int, - ) -} - -pub fn version_to_string(sp_version: SpacePacketVersion) -> String { - case sp_version { - VersionZero -> "v0" - } -} - -pub fn packet_type_to_string(sp_type: SpacePacketType) -> String { - case sp_type { - Telemetry -> "Telemetry" - Command -> "Command" - } -} - -pub fn seq_flag_to_string(sp_seq_flags: SpacePacketSequenceFlags) -> String { - case sp_seq_flags { - Continuation -> "Continuation" - FirstSegment -> "First Segment" - LastSegment -> "Last Segment" - Unsegmented -> "Unsegmented" - } -} - -pub fn space_packet_header_to_string(sp: SpacePacketHeader) -> String { - string_tree.new() - |> string_tree.append("Version: ") - |> string_tree.append(version_to_string(sp.version)) - |> string_tree.append("\n") - |> string_tree.append("Type: ") - |> string_tree.append(packet_type_to_string(sp.sp_type)) - |> string_tree.append("\n") - |> string_tree.append("Secondary Header Flag: ") - |> string_tree.append(bool.to_string(sp.sec_hdr_flag)) - |> string_tree.append("\n") - |> string_tree.append("APID: 0x") - |> string_tree.append(int.to_base16(sp.apid)) - |> string_tree.append("\n") - |> string_tree.append("Sequence Flags: ") - |> string_tree.append(seq_flag_to_string(sp.seq_flag)) - |> string_tree.append("\n") - |> string_tree.append("Sequence Count: ") - |> string_tree.append(int.to_string(sp.seq_count)) - |> string_tree.append("\n") - |> string_tree.append("Packet Length: ") - |> string_tree.append(int.to_string(sp.packet_len)) - |> string_tree.append("\n") - |> string_tree.to_string() -} +import gleam/result +import space_packet/primary_hdr pub fn main() { - let space_packet = - SpacePacketHeader( - VersionZero, - Telemetry, + let space_packet_pri_hdr = + primary_hdr.PrimaryHeader( + 0, + primary_hdr.Telemetry, False, 0x55, - Unsegmented, + primary_hdr.Unsegmented, 0x00, 0x00, ) - io.println(space_packet_header_to_string(space_packet)) + io.println(primary_hdr.to_string(space_packet_pri_hdr)) + + let hdr_bin = primary_hdr.to_bit_array(space_packet_pri_hdr) + + use hdr_new <- result.map(primary_hdr.from_bit_array(hdr_bin)) + + io.println("Is same: " <> bool.to_string(hdr_new == space_packet_pri_hdr)) + io.println("New Header:\n" <> primary_hdr.to_string(hdr_new)) } diff --git a/src/space_packet/primary_hdr.gleam b/src/space_packet/primary_hdr.gleam new file mode 100644 index 0000000..2e65b04 --- /dev/null +++ b/src/space_packet/primary_hdr.gleam @@ -0,0 +1,142 @@ +import gleam/bool +import gleam/int +import gleam/string_tree + +pub type PacketType { + Telemetry + Command +} + +fn packet_type_from_int(val: Int) -> PacketType { + case val { + 1 -> Command + _ -> Telemetry + } +} + +fn packet_type_to_int(val: PacketType) -> Int { + case val { + Command -> 1 + Telemetry -> 0 + } +} + +pub fn packet_type_to_string(sp_type: PacketType) -> String { + case sp_type { + Telemetry -> "Telemetry" + Command -> "Command" + } +} + +pub type SequenceFlags { + Continuation + FirstSegment + LastSegment + Unsegmented +} + +fn sequence_flags_from_int(val: Int) -> SequenceFlags { + case val { + 0b00 -> Continuation + 0b01 -> FirstSegment + 0b10 -> LastSegment + _ -> Unsegmented + } +} + +fn sequence_flags_to_int(val: SequenceFlags) -> Int { + case val { + Continuation -> 0b00 + FirstSegment -> 0b01 + LastSegment -> 0b10 + Unsegmented -> 0b11 + } +} + +pub fn seq_flag_to_string(sp_seq_flags: SequenceFlags) -> String { + case sp_seq_flags { + Continuation -> "Continuation" + FirstSegment -> "First Segment" + LastSegment -> "Last Segment" + Unsegmented -> "Unsegmented" + } +} + +pub type PrimaryHeader { + PrimaryHeader( + version: Int, + sp_type: PacketType, + sec_hdr_flag: Bool, + apid: Int, + seq_flag: SequenceFlags, + seq_count: Int, + packet_len: Int, + ) +} + +pub type ParseError { + InvalidSize +} + +pub fn to_string(hdr: PrimaryHeader) -> String { + string_tree.new() + |> string_tree.append("Version: ") + |> string_tree.append(int.to_string(hdr.version)) + |> string_tree.append("\n") + |> string_tree.append("Type: ") + |> string_tree.append(packet_type_to_string(hdr.sp_type)) + |> string_tree.append("\n") + |> string_tree.append("Secondary Header Flag: ") + |> string_tree.append(bool.to_string(hdr.sec_hdr_flag)) + |> string_tree.append("\n") + |> string_tree.append("APID: 0x") + |> string_tree.append(int.to_base16(hdr.apid)) + |> string_tree.append("\n") + |> string_tree.append("Sequence Flags: ") + |> string_tree.append(seq_flag_to_string(hdr.seq_flag)) + |> string_tree.append("\n") + |> string_tree.append("Sequence Count: ") + |> string_tree.append(int.to_string(hdr.seq_count)) + |> string_tree.append("\n") + |> string_tree.append("Packet Length: ") + |> string_tree.append(int.to_string(hdr.packet_len)) + |> string_tree.append("\n") + |> string_tree.to_string() +} + +pub fn from_bit_array(src: BitArray) -> Result(PrimaryHeader, ParseError) { + case src { + << + version:size(3), + sp_type:size(1), + sec_hdr_flag:size(1), + apid:size(11), + seq_flag:size(2), + seq_count:size(11), + packet_len:size(16), + >> -> { + Ok(PrimaryHeader( + version, + packet_type_from_int(sp_type), + sec_hdr_flag == 1, + apid, + sequence_flags_from_int(seq_flag), + seq_count, + packet_len, + )) + } + _ -> Error(InvalidSize) + } +} + +pub fn to_bit_array(src: PrimaryHeader) -> BitArray { + << + src.version:size(3), + packet_type_to_int(src.sp_type):size(1), + bool.to_int(src.sec_hdr_flag):size(1), + src.apid:size(11), + sequence_flags_to_int(src.seq_flag):size(2), + src.seq_count:size(11), + src.packet_len:size(16), + >> +}