From 569372494abebe531fa8bc76e09454dbde47ae48 Mon Sep 17 00:00:00 2001 From: Anthony Templeton Date: Mon, 30 Mar 2026 09:02:32 -0400 Subject: [PATCH] feat: uslp ccsds standard --- src/Ccsds.zig | 37 ++++++++++++++++++++-------- src/Uslp.zig | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 10 deletions(-) create mode 100644 src/Uslp.zig diff --git a/src/Ccsds.zig b/src/Ccsds.zig index a68a3ff..525cf97 100644 --- a/src/Ccsds.zig +++ b/src/Ccsds.zig @@ -4,6 +4,7 @@ const std = @import("std"); const Ccsds = @This(); +packetType: pktType, header: HeaderMetadata, primaryHeader: []const u8, secondaryHeader: ?[]const u8, @@ -13,6 +14,24 @@ allocator: std.mem.Allocator, pub fn init(pl: []const u8, allocator: std.mem.Allocator, config: ?Config) !Ccsds { var rawPackets = try allocator.dupe(u8, pl); // dupe so it doesn't go out of scope too early + const primaryHeader = rawPackets[0..6]; + const headers = fetchHeader(rawPackets, config); + const end = 5 + headers.header.packetSize; // num of header bytes + packet_size + const packets = rawPackets[headers.start..end]; + + _ = allocator.resize(rawPackets, end); + + return .{ + .header = headers.header, + .primaryHeader = primaryHeader, + .secondaryHeader = headers.secondaryHeader, + .packets = packets, + .rawData = rawPackets, + .allocator = allocator, + }; +} + +pub fn fetchHeader(rawPackets: []u8, config: ?Config) struct {header: HeaderMetadata, secondaryHeader: ?[]const u8, start: u8} { const primaryHeader = rawPackets[0..6]; const version = @as(u3, @truncate((primaryHeader[0] >> 5) & 0x07)); const packetType = @as(u1, @truncate((primaryHeader[0] >> 4) & 0x01)); @@ -46,18 +65,11 @@ pub fn init(pl: []const u8, allocator: std.mem.Allocator, config: ?Config) !Ccsd .packetSequenceCount = packetSequenceCount, .packetSize = packetSize + 1, }; - const end = 5 + header.packetSize; // num of header bytes + packet_size - const packets = rawPackets[start..end]; - - _ = allocator.resize(rawPackets, end); return .{ - .header = header, - .primaryHeader = primaryHeader, - .secondaryHeader = secondaryHeader, - .packets = packets, - .rawData = rawPackets, - .allocator = allocator, + .header = header, + .secondaryHeader = secondaryHeader, + .start = start, }; } @@ -83,6 +95,11 @@ pub const HeaderMetadata = packed struct { packetSize: u16, }; +pub const pktType = enum { + spacePkt, + uslp +}; + /// If you choose to use the CCSDS config you need to call this function first to get the Config struct pub fn parseConfig(configContent: []const u8, allocator: std.mem.Allocator) !Config { const configParsed = try std.json.parseFromSlice(Config, allocator, configContent, .{}); diff --git a/src/Uslp.zig b/src/Uslp.zig new file mode 100644 index 0000000..877c88c --- /dev/null +++ b/src/Uslp.zig @@ -0,0 +1,68 @@ +const std = @import("std"); + +pub const Uslp = @This(); + +primaryHeader: USLPHeader, +insertZone: []const u8, +dataHeader: DataHeader, +TFDZ: []const u8, +OpControl: u32, +FrameError: u16, +rawData: []const u8, +allocator: std.mem.Allocator, + +pub fn init(pl: []const u8, allocator: std.mem.Allocator) !Uslp{ + var rawPackets = try allocator.dupe(u8, pl); // dupe so it doesn't go out of scope too early + const primaryHeader = rawPackets[1..6]; + const headers = fetchHeader(rawPackets); + const end = 5 + headers.header.packetSize; // num of header bytes + packet_size + const packets = rawPackets[headers.start..end]; + + _ = allocator.resize(rawPackets, end); + + return .{ + .header = headers.header, + .allocator = allocator, + .rawData = rawPackets, + }; +} + +pub fn deinit(self: *Uslp) !void { + self.allocator.free(self.rawData); +} + +pub fn fetchHeader(rawPackets: u8) struct {header: USLPHeader } { + const header = rawPackets[0..6]; + const tfv = @as(u4, @truncate((header[0] >> 5) & 0x07)); + std.debug.print("%s", .{tfv}); + // const tfvn = rawPackets[0..3]; + // const scid = rawPackets[3..19]; +} + +pub const DataHeader = packed struct {}; + +pub const USLPHeader = packed struct { + xferFrameVersion: u4, + scID: u16, + srcID: u1, + virtChannel: u6, + mapID: u4, + eofFlag: u1, + frameLength: u16, + bypassCntrl: u1, + protocolCmd: u1, + spare: u2, + ocf: u1, + VCFrameCountLength: u3, + VCFrameCount: u56, +}; + + +test "CCSDS Structure Testing w/o config" { + const raw_test_packet: [16]u8 = .{ 0x78, 0x97, 0xC0, 0x00, 0x00, 0x0A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A }; + var converted_test_packet = try Uslp.init(&raw_test_packet, std.testing.allocator, null); + defer converted_test_packet.deinit(); + + try std.testing.expectEqual(3, converted_test_packet.header.version); + +}