Back to Documentation

The HSN protocol - Hardcore Satellite Network

Brief Description

HSN is a performance-enhanced transport protocol for use with CAN 2.B which enables reliable transmission of long messages over the CAN bus. HSN is port-oriented allowing one incoming connection per port at a time.

A connection is established at the destination when a source transmits a START frame to a given destination and port. If the destination port is busy, the source is added to a queue of pending connections. When a frame, e.g. START, is successfully received at the destination, the destination replies with ACK causing the transmitter to resume tranmission of any number of DATA frames.

The connection is terminated when the source sends END and receives a FACK from the destination. Both START, DATA and END may contain 0-8 bytes of data which are successively added to the destination port buffer and returned to the receiving application upon successful reception of an HSN packet. If there are pending connections in the queue, it is flushed and all the sources in the queue will receive a NACK letting them know that their initial START frame was not accepted which will cause them to resend it. Whoever makes it to the destination first, will get a connection to the port and the rest will end up in the pending queue again.


Error Handling

The protocol implementation ensures reliable transmission of HSN packets by means of a FRAME/ACK approach making the transmitter (source) send only one CAN frame at a time and waiting to acknowledge (ACK) before continuing with the next frame in the message. All frames contain a one bit sequence number which is altered for every unique frame making it possible for the receiver to detect retransmissions.

If CAN frames are lost, a timeout mechanism on the transmission side will try to resend the lost frame until a maximum number of retries have occured.

If the receiver has not heard from the source for a given period of time, it adds the connection to the pending queue and flushes the queue.

If the source for some reason does not follow the protocol or tries to send a too long packet to a given port, the source will receive a ABORT frame causing it to abort the transmission.


Frame Description

The HSN frames are identified by the CAN identifier and packet payload data is kept in the CAN frame data. CAN 2.B with 29 bit identifier is used.

ID Structure:   ---P PPPP PPPS SSSS SDDD DDDF TTTT Q---
P: Port
S: Source
D: Destination
F: Flag (not used)
T: Frame type
Q: Sequence number
-: Not used

Receivers must filter CAN frames on Destination in order only to receive frame targeted at themselves. The addresses on AAUSAT-II are:

HSN_ADDRESS_BROADCAST 0
HSN_ADDRESS_PAYLOAD   1
HSN_ADDRESS_OBC       2
HSN_ADDRESS_COM       3
HSN_ADDRESS_ADCS      4
HSN_ADDRESS_EPS       5

Frame types

Source -> Dest
 START (0x2): Opens a connection to a port. May contain data bytes.
 DATA  (0x4): Contains data bytes to an open connection.
 END   (0x6): Ends a connection. May contain data bytes.

Dest   -> Source
 ACK   (0x8): Acknowledges the reception of START or DATA.
 NACK  (0xA): Not-acknowledge. Causes source to restart transmission.
 FACK  (0xC): Acknowledgement of END. Causes source to terminate.
 ABORT (0xE): Used to tell source to immediately terminate
              transmission due to protocol abuse.

Protocol Implementation Notes

HSN has been implemented in a platform-independent manner allowing it to make the best possible use of the limited memory ressources on PIC controllers while maintaining readability and useability for inclusion into more powerful systems like the eCos environment.

Event-driven or Polled

For the sake of flexibility for the programmer, HSN can be run both polled or event-driven. By passing it a function pointer at initilialisation time, HSN can call back to the application when a protocol event occurs - e.g. a finished or aborted transmission or when a packet is received.

The HSN events can then be handled by the application by making a query on the packet which caused the event to occur. The query call returns info in struct telling if the packet is active, done or inactive.

If the application chooses to run HSN polled, the call back pointer should simply be NULL causing HSN to ignore it. The application must then poll the query call and receive call in order to react to incoming packets and finished transmissions.

Packet Reception

Calling the receive function returns true if a packet has been received on any port and a pointer to a packet struct is also returned. The memory of this struct is allocated by the protocol and the application must indicate to HSN when it has finished processing the data (e.g. copying it to another location) so HSN can re-enable the port. HSN only buffers one incoming packet on a given port in order to save memory.

Packet Transmission

The transmit function is passed a pointer to a packet struct allocated by the application. The data is NOT copied by HSN, so the application should not re-use this memory before the transmission is finished. Use the query call to find out if the packet is done.

Timeout Handling

In order to handle timeouts, the application must call the timeout checking routine periodically. This causes HSN to run through its active transmissions and connections (active ports) to check if they have been idle for too long and take the appropriate action.

Configuration and Hardware-specifics

HSN is configurable for running on any platform by static definitions made in a seperate file (hsn_config.h). In this file, ports and local address is defined along with buffer sizes and timeout limits for transmission and reception. Also, all platform-specific functions are defined here as macros such as CAN_SEND and GET_TIME etc.

Application Programmers Interface

/**
 * Initialise HSN protocol system.
 * call is a pointer to a call back function in
 * the application layer.
 */
void   HSN_init(void *call);

/**
 * Called upon CAN message reception
 * This is where most of the HSN state machine resides.
 * Take a deep breath before plunging in!
 */
U8     HSN_frame_received(can_message_t * message);

/**
 * Start transmission
 * Return True if a transmission was successfully started.
 */
bool_t HSN_transmit(hsn_packet_t * packet);

/**
 * Receive HSN on specific port.
 * Return True if packet is available on specified port.
 */
bool_t HSN_receive_port(port_t port, hsn_packet_t ** packet);

/**
 * Receive HSN on any port.
 * @return True if packet is available.
 */
bool_t HSN_receive(hsn_packet_t ** packet);

/**
 * Release rx_object
 * Re-enables reception on the port
 */
void   HSN_rx_done(hsn_packet_t * packet);

/**
 * Check for timeout in reception and transmission
 * Run this function peridodically to check for timed
 * out connections so ports can be freed and transmitters
 * be kicked back into business.
 */
void   HSN_timeout_check(void);

/**
 * Query the protocol engine about given packet
 * Returns information about stuff in the info struct.
 */
void   HSN_query_packet(hsn_packet_t * packet, hsn_info_t * info);

/**
 * Structure for CAN messages
 */
typedef struct {
    U32 id;
    U8 length;
    U8 data[8];
    U32 time_stamp;
    U32 mboxNo;
    Bool ext;
} can_message_t;

/**
 * Structure to pass data between HSN and application layer
 */
typedef struct hsn_packet_s {
    U8 *data;
    buf_size_t size;
    addr_t addr;
    port_t port;
} hsn_packet_t;