casycom communicates over a socket connection, UNIX or TCP, using a stream of messages containing the marshalled arguments of object method calls. Each message consists of header and body. The header, the body, and the end of the message must be 8-byte aligned. All integers are written in little-endian byte order. The header is:

struct {
    uint32_t    sz;
    uint16_t    iid;
    uint8_t     fdoffset;
    uint8_t     hsz;
    char	objname[];
    char	method[];
    char	signature[];

sz is the size of the message body padded to 8 byte alignment. hsz is the size of the header padded to 8 byte alignment. fdoffset is the offset of the passed file descriptor in the body; if no file descriptor is passed, this should be 0xff.

iid is the instance id of the destination object, generated by the caller to be unique for the connection. To distinguish objects created by each side of the socket, the iid for the remote object is the same as the object id inside the client process, defined as the side that calls connect on the socket. Objects created on the client side by the server side are set to server object id + 32000. The side type is set by passing EXTERN_CLIENT or EXTERN_SERVER to the PExtern_Open call.

objname, method, and signature encode the message destination. All three are zero-terminated strings, concatenated together and directly following hsz. objname names the addressed interface, such as "Ping". If multiple versions of the interface exist, they should be distinguished by including the version number in the interface name, as in "Ping3". Casycom uses reply interfaces, rather than reply messages. These should be the same as the calling interface suffixed with an R, as in "PingR". Method names should use the same versioning convention, if needed.

The signature contains a textual description of the marshalled arguments in the message in the form of a sequence of letters. The meaning of the letters has been copied from the specification for DBus, which uses a similar system for encoding arguments. Unless otherwise specified, all arguments are encoded directly, as in *(uint32_t*)p = arg; integer byte order is always little-endian. Values must be aligned to the same alignment requrement as in memory, typically the size of the type.

bbool. Encoded as uint8_t.
hFile descriptor. Only valid for messages sent over a UNIX socket.
a Array. The next letter denotes array type. Encoded with uint32_t number of elements followed by the serialized array elements, padded to 4-byte alignment. If the elements require alignment greater than 4, the first element is aligned to the appropriate grain.
s String. Encoding same as array, with size equal to the length of the string including the zero terminator. The length can be set to zero for empty strings.
()Delimit compound types. Useful after a. These must be both aligned and padded to the grain of the largest element.


Each casycom implementation must implement handlers for the COM interface, used for protocol commands. There are three methods currently defined:

Export (const char* el), signature "s".
Contains a comma-delimited list of names of interfaces creatable by the sending side. Reply interfaces are never instantiated explicitly and are not included in the list.
Error (const char* msg), signature "s".
Sent by the remote object when it encounters an error.
Delete (void), signature "".
A notification sent by the remote object when it deletes itself.

Immediately upon establishing a connection, each side must send an Export message, listing exported interfaces. Once the message is received, the handshake is complete and the connection can be used. Normal operation involves sending and receiving messages, creating objects as needed. This completes the protocol specification.