All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.yamcs.simulator.ColumbusCcsdsPacket Maven / Gradle / Ivy

package org.yamcs.simulator;

import java.nio.ByteBuffer;
import org.yamcs.utils.TimeEncoding;

/**
 * CCSDS packets as used in Columbus/ISS
 * 
 * 
 * primary header (6 bytes):
 * 3 bit = version
 * 1 bit = type (0 = system packet, 1 = payload packet)
 * 1 bit = 2nd header present
 * 11 bit = apid
 * 
 * 2 bit = grouping, 01 = first, 00 = cont, 10 = last packet of group
 * 14 bit = seq
 * 
 * 16 bit = packet length (excluding primary header) minus 1
 * 
 * secondary header (10 bytes):
 * 32 bit = coarse time (seconds since 1970)
 * 8 bit = fine time
 * 2 bits = time id (see constants)
 * 1 bit = checksum present (2 bytes after user data)
 * 5 bits = packet type (see constants)
 * 32 bit = packet id
 * 
*/ public class ColumbusCcsdsPacket extends SimulatorCcsdsPacket { final byte SH_TIME_ID_NO_TIME_FIELD = 0; final byte SH_TIME_ID_TIME_OF_PACKET_GENERATION = 1; final byte SH_TIME_ID_TIME_TAG = 2; final byte SH_TIME_ID_UNDEFINED = 3; // Packet types final static byte SH_PKT_TYPE_CCSDS_CCSDS_PAYLOAD_HK_PACKET = 5; final static byte SH_PKT_TYPE_CCSDS_PAYLOAD_COMMAND_PACKET = 10; final static byte SH_PKT_TYPE_CCSDS_MEMORY_LOAD_PACKET = 11; final static byte SH_PKT_TYPE_CCSDS_RESPONSE_PACKET = 12; private int packetid, packetType; private long timeMillis; // yamcs time private boolean checksumPresent; public ColumbusCcsdsPacket(byte[] packet) { super(packet); readHeader(); } public ColumbusCcsdsPacket(ByteBuffer bb) { super(bb); readHeader(); } public ColumbusCcsdsPacket(int apid, int userDataLength, int packetid) { this(apid, userDataLength, packetid, true); } public ColumbusCcsdsPacket(int apid, int userDataLength, int packetid, boolean checksumPresent) { this(apid, userDataLength, SH_PKT_TYPE_CCSDS_CCSDS_PAYLOAD_HK_PACKET, packetid, checksumPresent); } public ColumbusCcsdsPacket(int apid, int userDataLength, int packetType, int packetid, boolean checksumPresent) { super(ByteBuffer.allocate(getPacketLength(userDataLength, checksumPresent))); setHeader(apid, 0, 1, 3, getSeq(apid)); timeMillis = TimeEncoding.getWallclockTime(); // gps time as of 2017 this.packetType = packetType; this.packetid = packetid; this.checksumPresent = checksumPresent; putHeader(); } private static int getPacketLength(int userDataLength, boolean checksumPresent) { int pl = userDataLength + 16; if (checksumPresent) { pl += 2; if ((pl & 1) == 1) { // need an even number of bytes to compute a checksum pl += 1; } } return pl; } public ByteBuffer getUserDataBuffer() { bb.position(16); return bb.slice(); } public int getPacketId() { return packetid; } public void setPacketId(int packetId) { this.packetid = packetId; } public int getPacketType() { return packetType; } public void setTime(long instant) { timeMillis = instant; putHeader(); } private void putHeader() { long gpsMillis = TimeEncoding.toGpsTimeMillisec(timeMillis); bb.putInt(6, (int) (gpsMillis / 1000)); bb.put(10, (byte) ((gpsMillis % 1000) * 256 / 1000)); int checksum = checksumPresent ? 1 : 0; bb.put(11, (byte) ((SH_TIME_ID_TIME_OF_PACKET_GENERATION << 6) | (checksum << 5) | packetType)); bb.putInt(12, packetid); // describePacketHeader(); } private void readHeader() { this.timeMillis = TimeEncoding.fromGpsCcsdsTime(bb.getInt(6), bb.get(10)); this.packetType = bb.get(11) & 0x1F; this.packetid = bb.getInt(12); this.checksumPresent = (bb.get(11) & 0x20) == 1; } @Override public void fillChecksum() { if (checksumPresent) { int checksum = 0; for (int i = 0; i < bb.capacity() - 2; i += 2) { checksum += bb.getShort(i); } bb.putShort(bb.capacity() - 2, (short) checksum); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy