-
Notifications
You must be signed in to change notification settings - Fork 12
Printf Oriented Message Protocol
License
Parrot-Developers/libpomp
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
pomp - Printf Oriented Message Protocol
This library offers a simple protocol to encode/decode messages and exchange
them between processes on a socket (inet or local).
A message is composed of a 32-bit id and a payload. The payload is composed
of any number of typed arguments.
The encoding/decoding is done with printf/scanf like functions with a format
string and a variable number of arguments. However, no actual string formatting
is done, the payload is a binary representation of arguments.
The payload contains the type of the arguments as well as the value of the
arguments, hence making it robust during decoding at runtime.
Both sender and receiver shall provide the format string. How the knowledge of
the format string is shared is out of the scope of this library. It can simply
be a shared header with defines.
Key points :
- no need to use a description language and code generator, the format string
indicates the type of the message arguments.
- the use of printf/scanf like functions allows the compiler to check the
coherence between the format string and the actual type of the arguments so
the encoding/decoding engine can be generic and safe.
- as the type of arguments is included in the payload, the decoding engine can
check that the provided format string matches the actual message content.
How to use :
1) Instantiate a server and a client context object.
They can be in separate processes or in the same one. Communication is
done with sockets (inet or local).
The server will listen for any number of incoming connections on the given
address. Both server and client are notified of the remote peer connection
and disconnection as well as the reception of a message.
The client/server context object offers a file descriptor that need to
be added in an event loop to process io events.
ctx = pomp_ctx_new(&cb, NULL);
pomp_ctx_listen(ctx, addr, addrlen);
or
pomp_ctx_connect(ctx, addr, addrlen);
fd = pomp_ctx_get_fd(ctx);
The library automatically handles reconnections after timeout and remote
disconnections.
Note: retrieving the fd of the context to put it in an external event loop
is only available under linux. For other systems, please take a look
at the loop API.
2) Send a message.
A message can be sent at the context object level or at the connection
object level. The difference is mainly for server where a broadcast is done
at the context object level.
uint32_t counter = 10;
uint32_t msgid = 42;
pomp_ctx_send(ctx, msgid, "%d%s", counter, "PING");
The message id can be used freely to identify the message, mainly its
format string at reception.
The format string is a subset of what is supported by a standard printf
function but allows the compiler to check that given arguments have the
correct type. Basically only format specifier is supported, no extra string
shall be given.
3) Receive the message.
The reception of a message is indicated in the context object callback. You
just need to get the message id and handle the message accordingly.
uint32_t counter = 0;
char *str = NULL;
uint32_t msgid = pomp_msg_get_id(msg);
pomp_msg_read(msg, "%d%ms", &counter, &str);
free(str);
Again the format string allows the compiler to check that the type of the
argument is valid. The decoding engine will also make sure it matches the
real message payload.
Note that string decoding uses a special string specifier '%ms' that
indicate that an allocated string will be returned. This avoid buffer
overflows by ensuring corret size of buffer. Caller needs however to free it
afterwards. This '%ms' specifier is a GNU extension to scanf but will be
part of POSIX specifications.
4) Cleanup.
Simply stop and destroy created objects.
pomp_ctx_stop(ctx);
pomp_ctx_destroy(ctx);
Even if the library can be used without any generated code from description
files, it can be used as a basic component to build a more complicated protocol
between 2 entities.
This library should become useful when one wants to exchange messages between
2 processes. The library handles many aspects of an inter-process communication
that can be hard to make it right, simple and robust.
Format string specification:
- %hhi : 8-bit signed integer.
- %hi : 16-bit signed integer.
- %i : 32-bit signed integer.
- %li : 32-bit signed integer if __WORDSIZE is 32 else 64-bit signed integer.
- %lli : 64-bit signed integer.
Note : variants with %d are also supported for signed integer.
- %hhu : 8-bit unsigned integer.
- %hu : 16-bit unsigned integer.
- %u : 32-bit unsigned integer.
- %lu : 32-bit unsigned integer if __WORDSIZE is 32 else 64-bit signed integer.
- %llu : 64-bit unsigned integer.
- %s : string (encoding only).
- %ms : string (decoding only). Caller shall free the returned string.
Note : for decoding, %ms expects a pointer to a string (char **) not just a
string (char*) like a standard scanf with %s.
- %p%u : buffer (with its size). For decoding, buffer is still owned by the
message, caller shall NOT free the returned pointer.
Note : both %p AND %u shall be given.
- %f : 32-bit floating point.
- %lf : 64-bit floating point.
Note : variants with %F, %g, %G, %e, %E are also supported for floating point.
- %x : file descriptor. Can only be sent on a local unix socket.
Note : for encoding, the file descriptor will be internally duplicated. For
decoding, the returned file descriptor shall NOT be closed by caller.
However caller shall duplicate it if it needs to use it after the
message is released.
About
Printf Oriented Message Protocol
Resources
License
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published