A datagram is a block of data, usually max 1K long, containing data, and some header information.
Each message follows the same basic protocol, with the exception of the ROCK_ACK_MESSAGE
The basic protocol is:
type, seq, port, name, followed by message-specific-data.
I.e. every message starts with 4 fields, type, seq, port, and name.
- Message type is an unsigned 32 bit integer. All integers are in little endian format.
- Message sequence number is an unsigned 64 bit integer.
- Message port is a 32 bit signed integer.
- Message name is a string, and a string is always an unsigned 32 bit integer (length) followed by that many bytes (the string itself). The final NULL character is not included in the string, because the length implies that when it is read at the other end, the NULL will be added after length bytes are read.
The message-specific-data can be anything that the application wishes to place there. This data can be made up of unsigned and signed integers (8, 16, 32, and 64 bit), 32 bit float, 64 bit double precision float, or long double precision float (64 bit mantissa followed by 32 bit exponent).
- The port is the port that the sender rock is receiving messages on.
- The name is the system-wide unique name of the sending rock.
The port and IP address (of the datagram) make up the full address of the sender from the point of view of the operating system, and its name is the way a rock application addresses it. (From an application's perspective, messages are sent to a rock, addressed by "name", which the rock infrastructure converts to address:port.) This is convenient, because the rock manager starts up all the rocks, and configures them on hosts and ports. The application software is abstracted from this, which allows rocks to be restarted at different address:port without any effect on the applications.
The one exception to this basic protocol is the ROCK_ACK_MESSAGE, whose 'header' is just the type and sequence number. However, following the sequence number, the ack message can contain command-specific data (specific to the type of command it is acknowledging), which is a way to return context information or a 'return value'.
As explained above, the very first 4 bytes in a message are the message type. Message type zero is the ROCK_ACK_MESSAGE, message type 1 is the ROCK_HELLO_MESSAGE, and so on. Following is a description of each of the pre-defined messages:
- ROCK_ACK_MESSAGE 0 The format of the ack message is type,seq, followed by command-specific-data. An ack is sent back to the sender, for every message received.
- ROCK_HELLO_MESSAGE 1 A hello message is the first thing a rock must do to announce its presence immediately after it starts up. The hello message format is type,seq,port,name,rock_type. The rock_type is the type name of the rock. The infrastructure indexes remote rocks by name (system wide unique name) and by type (type has a one to one relationship with rock implementation, but a one to many relationship to rock instances).
- ROCK_BYE_MESSAGE 2 The bye message is sent just before a rock exits. The format of the bye message is type,seq,port,name
- ROCK_PING_MESSAGE 3 The ping message is similar in function to a hello message, except it is sent while the rock is running periodically to announce that the rock is still there. The format of the ping message is type,seq,port,name,rock_type,load_factor The load_factor is an unsigned 8bit integer, which indicates how loaded the rock is. 0 = no load, 0xff = max load.
- ROCK_LONG_MESSAGE_HDR 4 When a message needs to be sent that is longer than the packet size that the rock infrastructure was configured for, then that data must be sent in a number of packets. The long message header is sent first, to announce the fact that a number of packets are following, to make up a larger-than-usual message. The format of the long message header is type,seq,port,name,long_size,num_packets. The long_size is the total size of the message that is being sent in fragments.
- ROCK_LONG_MESSAGE_PKT 5 The long message is fragmented into a number of packets. The format of the long message packet is type,seq,port,name,hdr_seq,pkt_num,this_size,data... The hdr_seq is the sequence number of the header that this packet belongs to. The this_size parameter is the size of the data that is being contained in this packet (not the size of the message).
- ROCK_KILL_MESSAGE 6 This message is sent by a manager to a rock to tell it to exit. The kill message format is type,seq,port,name.
There is a difference between the reply message protocol, and a normal message - in that a normal message is sent to a known rock. A reply message could be sent to anyone. Therefore, if a reply message message-type must be unique... but how can it be unique? Impossible, because The Karoo System will be used by many different developers and there is no central registration for message type numbers.
Therefore... a "reply message" is one who's message-type's MSB is set, and the receiver will then switch not just on the message-type, but also on the sender's rock name.