Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add downlink frame counter and global health packet transmission #75

Merged
merged 11 commits into from
Jan 4, 2025
Merged
8 changes: 8 additions & 0 deletions doc/breathe/source/foxsimile.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ We will use multiple loopback IP address to emulate all systems. On macOS, these

This will take a moment to run.

On macOS, you will also need to allow your loopback interface (``lo0``) to route to multicast IP addresses:

.. code-block:: bash

sudo route -nv add -net 224.1.1.118 -interface lo0

On Linux there is a similar ``route`` command with slightly different flags. There are workarounds for this—you can do only point-to-point communication and hardcode a ``gse`` IP address in ``foxsimile_systems.json``—but this is closer to the flight network setup.

Running
-------
Each of the following commands is a separate process that will run throughout your test. Either detach them, or run each in its own terminal.
Expand Down
31 changes: 31 additions & 0 deletions include/Buffers.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class DownlinkBufferElement {
const size_t get_max_packet_size() const {return max_packet_size;};
const uint16_t get_packets_per_frame() const {return packets_per_frame;};
const uint16_t get_this_packet_index() const {return this_packet_index;};
const uint16_t get_frame_counter() const {return frame_counter;};
const RING_BUFFER_TYPE_OPTIONS get_type() const {return type;};

/**
Expand All @@ -105,12 +106,20 @@ class DownlinkBufferElement {
* @warning Indexed from 1, not 0.
* @param new_this_packet_index the index of this packet in the frame.
*/

void set_this_packet_index(uint16_t new_this_packet_index);

/**
* @brief Set the data type transmitted in this frame.
* @param new_type type of data.
*/
void set_type(RING_BUFFER_TYPE_OPTIONS new_type);

/**
* @brief Set the frame counter for this packet.
* @param new_frame_counter frame number this packet comes from.
*/
void set_frame_counter(uint16_t new_frame_counter);

/**
* @brief Create a `std::string` representation of this object.
Expand Down Expand Up @@ -168,6 +177,15 @@ class DownlinkBufferElement {
* This will be used on the ground to log data to the appropriate file.
*/
RING_BUFFER_TYPE_OPTIONS type;

/**
* @brief A counter for each complete downlink frame to be sent.
* If this `DownlinkBufferElement` is a packet which is part of a larger
* frame which requires reassembly on the ground, this `::frame_counter`
* field can be used to identify dropped packets and still correctly
* assemble partial source frames.
*/
uint16_t frame_counter;
};


Expand Down Expand Up @@ -515,6 +533,8 @@ class SystemManager {
std::queue<UplinkBufferElement>& new_uplink_buffer
);

void clear_errors();

/**
* @brief Add a `FramePacketizer` object for handling `new_type`s of data.
* Some `System`s have frames that require packetization, if they are larger than the network MTU. In that case, an appropriate `FramePacketizer` (for the `System`, data type, frame size, and packet size) should be created and added to this `SystemManager`.
Expand Down Expand Up @@ -559,6 +579,14 @@ class SystemManager {
* @return PacketFramer*
*/
PacketFramer* get_packet_framer(RING_BUFFER_TYPE_OPTIONS type);
/**
* @brief Getter for total downlinked frame count for the provided data `type`.
* @param type data type of the frame you want the count for.
* @return uint8_t
*/
uint16_t get_frame_count(RING_BUFFER_TYPE_OPTIONS type);

void increment_frame_count(RING_BUFFER_TYPE_OPTIONS type);

/**
* @brief The underlying `System` configuration information.
Expand All @@ -584,6 +612,8 @@ class SystemManager {
*/
SYSTEM_STATE system_state;

uint16_t errors;

/**
* @brief Track which type of remote memory this `System` is currently reading.
*/
Expand All @@ -604,6 +634,7 @@ class SystemManager {
private:
std::unordered_map<RING_BUFFER_TYPE_OPTIONS, FramePacketizer*> lookup_frame_packetizer;
std::unordered_map<RING_BUFFER_TYPE_OPTIONS, PacketFramer*> lookup_packet_framer;
std::unordered_map<RING_BUFFER_TYPE_OPTIONS, uint16_t> lookup_frame_count;

};

Expand Down
13 changes: 13 additions & 0 deletions include/Circle.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,24 @@ class Circle {
*/
void flush();

/**
* @brief Add the Formatter status packet to the downlink buffer for transmission.
*/
void send_global_health();


/**
* @brief Utility to normalized `Timing` data for each `SystemManager` to the total loop period.
*/
void normalize_times_to_period();

/**
* @brief Assemble a packet reporting health of all the `System`s in `::system_order` for downlink.
*
* @return std::vector<uint8_t> a health packet below the MTU derived from the `System` named .
*/
std::vector<uint8_t> make_global_health_packet();

/**
* @brief The ordered list of `SystemManager`s that will be accessed in the event loop.
*/
Expand Down
25 changes: 24 additions & 1 deletion include/Parameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,24 @@ namespace config{
}
}

namespace errors {
enum class system: uint16_t {
reading_packet = 0x01 << 0, // can't read some packet
reading_frame = 0x01 << 1, // can't read whole frame
reading_invalid = 0x01 << 2, // response from system failed some checks
writing_invalid = 0x01 << 3, // response to write command is bad
frame_packetizing = 0x01 << 4, // can't make packets from frame
packet_framing = 0x01 << 5, // can't make frame from packet
commanding = 0x01 << 6, // can't send a command (any reason)
uplink_forwarding = 0x01 << 7, // can't send an uplink command (any reason)
downlink_buffering = 0x01 << 8, // can't create DownlinkBufferElement for packet or queue it
command_lookup = 0x01 << 9, // lookup command code in deck gets no result
buffer_lookup = 0x01 << 10, // lookup ring_buffer_params gets no object
spw_vcrc = 0x01 << 11, // SpaceWire CRC version is not `f`
spw_length = 0x01 << 12, // SpaceWire message is too short to parse
};
}

/**
* @brief List of ring buffer commands that read ring buffer for detector systems.
* The values are the second byte of an uplink command for the given system.
Expand Down Expand Up @@ -164,6 +182,7 @@ enum class RING_BUFFER_TYPE_OPTIONS: uint8_t {
POW = 0x11, /*!< Power (housekeeping) data. Used for dedicated Housekeeping board. */
RTD = 0x12, /*!< Temperature sensor (housekeeping) data. Used for dedicated Housekeeping board. */
INTRO = 0x13, /*!< Software (housekeeping) data. Used for dedicated Housekeeping board. */
PING = 0x20, /*!< Formatter ping. Used to flag health of software system. */
REPLY = 0x30, /*!< Reply data. Used to indicate response to an uplink command. */
NONE = 0xff /*!< No known data type. */
};
Expand All @@ -180,7 +199,9 @@ static const std::unordered_map<RING_BUFFER_TYPE_OPTIONS, std::string> RING_BUFF
{RING_BUFFER_TYPE_OPTIONS::POW, "pow"},
{RING_BUFFER_TYPE_OPTIONS::RTD, "rtd"},
{RING_BUFFER_TYPE_OPTIONS::INTRO, "intro"},
{RING_BUFFER_TYPE_OPTIONS::NONE, "none"},
{RING_BUFFER_TYPE_OPTIONS::REPLY, "reply"},
{RING_BUFFER_TYPE_OPTIONS::PING, "ping"},
{RING_BUFFER_TYPE_OPTIONS::NONE, "none"}
};

/**
Expand All @@ -195,6 +216,8 @@ static const std::unordered_map<std::string, RING_BUFFER_TYPE_OPTIONS> RING_BUFF
{"pow", RING_BUFFER_TYPE_OPTIONS::POW},
{"rtd", RING_BUFFER_TYPE_OPTIONS::RTD},
{"intro", RING_BUFFER_TYPE_OPTIONS::INTRO},
{"reply", RING_BUFFER_TYPE_OPTIONS::REPLY},
{"ping", RING_BUFFER_TYPE_OPTIONS::PING},
{"none", RING_BUFFER_TYPE_OPTIONS::NONE},
};

Expand Down
11 changes: 11 additions & 0 deletions include/Utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,17 @@ STATE_ORDER operator++(STATE_ORDER& order);
*/
STATE_ORDER operator++(STATE_ORDER& order, int);

uint16_t operator|(errors::system l, uint16_t r);
uint16_t operator|(uint16_t l, errors::system r);
uint16_t& operator|=(uint16_t& l, errors::system r);
errors::system& operator|=(errors::system& l, uint16_t r);

uint16_t operator&(errors::system l, uint16_t r);
uint16_t operator&(uint16_t l, errors::system r);
uint16_t& operator&=(uint16_t& l, errors::system r);
errors::system& operator&=(errors::system& l, uint16_t r);
uint16_t operator~(errors::system err);

/**
* @brief Namespace for SpaceWire-related utilities.
*/
Expand Down
Loading
Loading