ComLib is the communication part of Pocolibs. It is mainly composed of two high-level communication paradigms: a message based client/server and shared memory with one exclusive writer and several readers (called posters).
This library was initially developed for the 'Hilare 2' robot platform at LAAS, hence many parts of its API use the h2 prefix to identify themselve.
The comLib API allows several Unix processes on the same machine to communicate. posterLib has an extension that make it possible to semi-transparently access posters on other nodes of the network. See the remotePosterLib documentation for that.
#include <h2initGlob.h> STATUS h2initGlob(int ticksPerSec)
All comLib objects are derived from a common h2 device structure which is stored in shared memory. These objects are persistent across processes, but lost on reboot of the system. The h2devLib library is used internally to manage these objects.
h2devLib also provides a set of command line tools needed to manage the persistant objects outside of existing processes.
h2 init h2 end h2 info h2 clean <id>
#include <h2semLib.h> H2SEM_ID h2semAlloc(int type)
h2semAlloc() creates a shared counting semaphore. type can be
H2SEM_SYNC to specify a semaphore which is to be used for
synchronization purpose, that is a private semaphore, or
to create a semaphore which is used as a mutual exclusion semaphore.
h2semAlloc() returns the semaphore identifier for the newly created
NULL in case of an error. In that case an error code
is left in the task's errno value.
#include <h2semLib.h> STATUS h2semDelete(H2SEM_ID sem)
h2semDelete() deletes a semaphore from the process and releases any
resources used by the semaphore. sem is the identifier of the
semaphore to delete.
#include <h2semLib.h> STATUS h2semGive(H2SEM_ID sem)
h2semGive() implements the V operation on the given semaphore.
#include <h2semLib.h> STATUS h2semTake(H2SEM_ID sem, int timeout)
h2semTake() implements the P operation on the semaphore. timeout
specifies a number of ticks in which the operation must succeed. If the
semaphore was not taken with this delay,
ERROR is returned and the
errno value of the task is set to
The behaviour of processes blocked on a semaphore when it is deleted is not defined.
#include <h2semLib.h> BOOL h2semFlush(H2SEM_ID sem)
h2semFlush() resets the value of the specified semaphore to 0, causing
the next call to
h2semTake() to effectively block the calling task.
ERROR in case an error occured. In that case an error
code is left in the task's errno value.
#include <commonStructLib.h> STATUS commonStructCreate(int len, void **pStructAddr)
#include <commonStructLib.h> STATUS commonStructDelete(const void *pCommonStruct)
#include <commonStructLib.h> STATUS commonStructGive(const void *pCommonStruct)
#include <commonStructLib.h> STATUS commonStructTake(const void *pCommonStruct)
#include <h2timerLib.h> H2TIMER_ID h2timerAlloc(void);
h2timerAlloc() allocates a new inactive timer.
h2timerAlloc() returns the identifier of the newly allocated timer or
NULL in case of an error.
#include <h2timerLib.h> STATUS h2timerStart(H2TIMER_ID timerId, int period, int delay);
h2timerStart() arms a timer that will trigger after delay ticks and
then every period ticks per second. period must be a multiple or a
integer divisor of delay for implementation reasons.
#include <h2timerLib.h> STATUS h2timerPause(H2TIMER_ID timerId);
h2timerPause() blocks the current task until the next expiration of the
timer specified by timerId. This function will not block if it was not
called enough times in the past to ensure that all expirations of the
timer have been waited on.
#include <h2timerLib.h> STATUS h2timerPauseReset(H2TIMER_ID timerId);
h2timerPauseReset() first flushes the synchronisation semaphore used
by the timer and waits for the next expiration of the timer. This
ensures that the task will at least yield the processor before
#include <h2timerLib.h> STATUS h2timerStop(H2TIMER_ID timerId);
h2timerStop() stops the given timer. No more events will be
generated by this timer. Calling
h2timerPause() on a stopped timer
has a undefined behaviour.
#include <h2timerLib.h> STATUS h2timerChangePeriod(H2TIMER_ID timerId, int period);
h2timerChangePeriod() changes the period of a running timer.
#include <h2timerLib.h> STATUS h2timerFree(H2TIMER_ID timerId);
h2timerFree() frees a timer and returns it to the timer pool of pocoLibs.
If it was running, it is first stopped.
: the timer library has not been initialized.
: no free timer was available in h2timerAlloc().
: The specified timer to h2timerStart() is already running.
: The specified period is not a multiple or a divisor of the delay of
: The specified timer is not running for h2timerChangePeriod().
#include <h2time.h> STATUS h2timeGet(H2TIME *pTimeStr)
h2timeGet() fills the
H2TIME_STR structure pointed to by pTimeStr with
the current time.
#include <h2time.h> STATUS h2GetTimeSpec(H2TIMESPEC *pTimeSpec)
h2GetTimeSpec() fills the
H2TIMESPEC_STR structure pointed to by
pTimeSpec with the current time.
#include <h2time.h> STATUS h2timeInterval(H2TIME *pOldTime, unsigned long *pNmsec)
h2timeInterval() computes the elapsed number of mili-seconds between
the time structure pointed to by pOldTime and the current time. The
value is returned in the long pointed to by pNmsec.
#include <moxLib.h> STATUS mboxCreate(const char *name, int len, MBOX_ID *pMboxId);
#include <moxLib.h> STATUS mboxResize(MBOX_ID mboxId, int size);
#include <moxLib.h> STATUS mboxDelete(MBOX_ID mboxId);
#include <moxLib.h> STATUS mboxEnd(long taskId);
#include <moxLib.h> STATUS mboxFind(const char *name, MBOX_ID *pMboxId);
#include <moxLib.h> STATUS mboxInit(const char *procName);
#include <moxLib.h> STATUS mboxIoctl(MBOX_ID mboxId, int codeFunc, void *pArg);
#include <moxLib.h> BOOL mboxPause(MBOX_ID mboxId, int timeout);
#include <moxLib.h> int mboxRcv(MBOX_ID mboxId, MBOX_ID *pFromId, char *buf, int maxbytes, int timeout);
#include <moxLib.h> STATUS mboxSend(MBOX_ID toId, MBOX_ID fromId, char *buf, int nbytes);
#include <moxLib.h> STATUS mboxSkip(MBOX_ID mboxId);
#include <moxLib.h> int mboxSpy(MBOX_ID mboxId, MBOX_ID *pFromId, int *pNbytes, char *buf, int maxbytes);
These functions will be used both on the client and server sides of a task.
#include <csLib.h> STATUS csMboxInit ( const char *mboxBaseName, int rcvMboxSize, int replyMboxSize );
Calling this function creates two mailboxes: one will receive requests sent by clients when this task is acting as a server and the other will receive replies from servers to which this task has sent requests.
mboxBaseName is the base name for the created mailboxes. rcvMboxSize is the size of the request mailbox. replyMboxSize is the sie of the reply mailbox. If any of the Size argument is zero, the corresponding mailbox will not be created.
Note: this function must be called before any call to
#include <csLib.h> STATUS csMboxEnd ( void );
This function frees the mailboxes created by
#include <csLib.h> STATUS csMboxUpdate( int rcvMboxSize, int replyMboxSize );
This function makes it possible to change the size of either mailbox of a running task.
#include <csLib.h> int csMboxWait ( int timeout, int mboxMask );
This function waits for the arrival of either a request or a reply in
one of the task's mailboxes.
timeout is expressed in ticks or can be one of the
mboxMask_ is a logical combinaison of
specifying which mailboxes are waited upon.
csMboxWait returns a combinaision of
indicate which mailboxes were ready. It can also return
0 if a
timeout occured (there will be no message available) or
ERROR if an
#include <csLib.h> int csMboxStatus ( int mask );
This function checks the state of the mailboxes of a task, like csMboxWait, but without waiting.
#include <csLib.h> STATUS csServInit ( int maxRqstDataSize, int maxReplyDataSize, SERV_ID *pServId );
Sets up the calling task as a server. maxRqstDataSize is the maximum size, in bytes, of a request that will be received. maxReplyDataSize is the maximum size, in bytes, of a reply that will be sent. pServId is a pointer to store the identifier of the created server.
This function pre-allocates all memory needed to store the various messages. So further interactions with the server will not cause any memory allocation from the comLib level.
#include <csLib.h> STATUS csServInitN ( int maxRqstDataSize, int maxReplyDataSize, int nbRqstFunc, SERV_ID *pServId );
This is the sams as
csServInit(), with an extra parameter
nbReqstFunc, to specify the maximum number of request types that
will be supported (instead of the default
#include <csLib.h> STATUS csServEnd ( SERV_ID servId );
This function frees all the memory associated with a server task.
#include <csLib.h> STATUS csServFuncInstall ( SERV_ID servId, int rqstType, FUNCPTR rqstFunc );
This function allow a server to install the callback associated with a
given request type.
servId is the identifer of the server.
rqstType is an integer representing the request type (id). It should
be between 0 and
NMAX_RQST_TYPE - 1. (or the valur of nbRqstFunc
csServInitN() if the latter initialisation function was used).
rqstFunc is a pointer to the function associated with this request.
#include <csLib.h> STATUS csServRqstExec ( SERV_ID servId );
This function reads a request from the input mailbox, checks its type
and calls the associated callback (installed via
#include <csLib.h> STATUS csServRqstParamsGet ( SERV_ID servId, int rqstId, char *rqstDataAdrs, int rqstDataSize, FUNCPTR decodFunc );
This function should be called by the callback associated with a
request type to read its parameters (if they exist).
servId is the server identifier.
rqstId is the request identifier
rqstDataAdrs is a pointer to storage where the parameters will be
rqstDataSize is the size of the above storage structure.
decodFunc is a pointer to an optional decoding function. (
means a simple copy of the bytes).
#include <csLib.h> STATUS csServReplySend ( SERV_ID servId, int rqstId, int replyType, int replyBilan, char *replyDataAdrs, int replyDataSize, FUNCPTR codFunc );
This function is used to send a reply to the client. Two kinds of replies are possible: an intermediate reply and a final reply.
servId is the identifier of the server.
rqstId is the identifier of the request
replyType is the type of the reply (
replyBilan is the result of the execution (
OK or an error code).
replyDataAdrs is the pointer to the reply to be sent.
replyDataSize is the length of the reply structure.
codFunc is an optional encoding function. (`NULL means a simple copy
of the bytes).
#include <csLib.h> STATUS csServRqstIdFree ( SERV_ID servId, int rqstId );
This function frees the id of a received request. Normally this is
done automatically by
csServReplySend when the final reply is sent
to a client. So this function should not be called directly.
#include <csLib.h> STATUS csClientInit ( const char *servMboxName, int maxRqstSize, int maxIntermedReplySize, int maxFinalReplySize, CLIENT_ID *pClientId );
This function initializes the current task as a client of a given server.
servMboxName is the name of the mailbox of the server task. maxRqstSize is the maximum size of a request that will be sent to the server. maxIntermedReplySize is the maximum size of an intermediate reply that will be received maxFinalReplySize is the maximum size of a final reply that will be received. pClientId is a pointer where the identifier of the client will be stored.
This function will pre-allocate all the memory needed to interact with the given server. No further memory allocation will be made when sending requests or receiving replies to/from the given server.
#include <csLib.h> STATUS csClientEnd ( CLIENT_ID clientId );
Frees all resources associated with this clientId.
#include <csLib.h> STATUS csClientRqstSend ( CLIENT_ID clientId, int rqstType, char *rqstDataAdrs, int rqstDataSize, FUNCPTR codFunc, BOOL intermedFlag, int intermedReplyTout, int finalReplyTout, int *pRqstId );
This function sends a request to a server. Sending requests is always non-blocking.
clientId is the idenfier of the client (which has been associated with a
rqstType is the type of the request that will be executed.
rqstDataAdrs is a pointer to the request parameters.
rqstDataSize is the length of the above structure.
codeFunc is an optional encoding function for the parameters.
intermedFlag is a flag indicating if an intermediate reply is
TRUE) or not (
intermedReplyTout is the timeout to wait on the intermediate reply
finalReplyTot is the timeout to wait on the final reply in ticks.
pRqstId is a pointer to store the request identifier.
#include <csLib.h> int csClientReplyRcv ( CLIENT_ID clientId, int rqstId, int block, char *intermedReplyDataAdrs, int intermedReplyDataSize, FUNCPTR intermedReplyDecodFunc, char *finalReplyDataAdrs, int finalReplyDataSize, FUNCPTR finalReplyDecodFunc );
This function allows to receive (either in a blocking or non-blocking way) replies from a server (which can be the intermediate reply or the final one).
clientId is the client identifier. rqstId is the request identifier (returned by csClientRqstSend). block is a flag indicating the type of blocking behaviour. It can be any of:
intermedReplyDataAdrs is a pointer to storage for the intermediate reply. intermedReplyDataSize is the size of the above structure. intermedReplyDecodFunc is an optional function to decode the intermediate reply. finalReplyDataAdrs is a pointer to storage for the final reply. finalReplyDataSize is the size of the above structure. finalReplyDecodFunc is an optional function to decode the final reply.
#include <csLib.h> int csClientRqstIdFree ( CLIENT_ID clientId, int rqstId );
This function is used to free the request identifier associated with a
request. It is automatically be
csClientReplyRcv() upon receiving
the final reply associated with the given request and should thus not
be called directly.
'h2' events are implemented using the per-task private semaphore also associated with the mailboxes owned by the task.
#include <h2evnLib.h> h2evnSusp(int timeout)
This function suspends the execution of the current task, waiting for an external event. (ie executes 'P' on the associated sempaphore).
#include <h2evnLib.h> h2evnSignal(long taskId);
Send an event to the specified task. (ie executes 'V' on the associated semaphore).
#include <h2evnLib.h> h2evnClear(void)
This function flushes pending events for the current task.
#include <posterLib.h> STATUS posterCreate (const char *name, int size, POSTER_ID *pPosterId );
This function creates a new poster, identified by name, with a size of size bytes. The identifier of the new poster is returned in pPosterId.
posterCreate() returns OK upon successful creation of the poster or
ERROR in case of an error and sets the errno value of the current
A buffer of size bytes is allocated in shared memory together with the associated synchronisation object.
#include <posterLib.h> STATUS posterDelete ( POSTER_ID dev );
posterDelete() frees the memory and synchronisation object used by
the given dev poster identifier.
The behaviour of tasks accessing the poster after it has been deleted is undefined.
#include <posterLib.h> STATUS posterFind (const char *name, POSTER_ID *pPosterId );
posterFind() looks for a poster by its name. If such a poster is
found, its identifer is stored into pPosterId and the function
OK. Otherwise it sets the errno value of the current task
#include <posterLib.h> int posterWrite ( POSTER_ID posterId, int offset, void *buf, int nbytes );
posterWrite() permforms a synchronized write on the
poster. nbytes bytes from the buf memory area are copied into the
poster, starting at offset.
The number of successfully copied bytes (which should be equal to
nbytes) is returned when the copy was successful. Otherwise
Only the task owning a poster (ie the task which created it) can write in a poster.
#include <posterLib.h> int posterRead ( POSTER_ID posterId, int offset, void *buf, int nbytes );
posterRead() performs a synchronised read on the poster. nbytes
bytes starting at offset in the poster are copied into buf, which
should have been allocated and have at least nbytes.
The number of successfully copied bytes (which should be equal to
nbytes) is returned when the copy was successful. Otherwise
All tasks can perform read operations of a posters. The synchronisation object ensures that read and write operations are mutually exclusive.
#include <posterLib.h> STATUS posterTake ( POSTER_ID posterId, POSTER_OP op );
posterTake() locks the lock associated with the given
poster. posterId is the identifier of the poster to lock and op is
the operation that is going to be performed. It can be
POSTER_READto indicate that data is going to be read from the poster. Any task can use this operation.
POSTER_WRITEto indicate that data is going to be written to the poster. Only the owner of a poster can perform this operation.
Performing data transfers to/from a poster that doesn't respect the
operation that was declared in op (ie writing data to a poster
POSTER_READ or reading data from a poster locked with
POSTER_WRITE has an undefined behaviour.
posterGive() is an alernate way to access poster
posterWrite() would be too ineficient
because a large number of sparse data need to be accessed.
For cases where the data to be transferred is contiguous, posterRead()
and posterWrite are easier to use and less error prone.
#include <posterLib.h> STATUS posterGive ( POSTER_ID posterId );
posterGive() unlocks the lock associated with a poster. posterId
is the identifier of the poster to unlock. The poster should have been
#include <posterLib.h> void * posterAddr ( POSTER_ID posterId );
posterAddr() returns the address of the data in the poster
This address is only valid after calling
posterTake() on the
poster. Dereferencing this address returned whithout holding the lock
on the poster has an undefined behaviour.
#include <posterLib.h> STATUS posterIoctl(POSTER_ID posterId, int code, void *parg);
posterIoctl() performs control operations on the poster. code
defines the operation to be performed and pargs is a pointer to
arguments that are used depending on the operation.
The following operations are available:
FIO_FRESHsets an integer pointed to by pargs to 0 if no new data has been written in the poster since the last read operation, or 1 otherwise.
FIO_GETDATEreturns the time of last modification of the poster info into an
H2TIMESPECstructure pointed to by pargs.
FIO_NMSECset the number of milli-seconds since the last write operation on the poster in an integer pointed to by pargs.
FIO_GETSIZEreturns the size of the poster in bytes in a
size_tvalue pointed to by pargs.
FIO_RESIZEallows the owner of a poster to change its size. The newsize should be passed in an
size_tvalue pointed by pargs.
FIO_GETSTATSreturns statistics on the operation on the given poster in a
#include <posterLib.h> char* posterName(POSTER_ID posterId);
posterName() returns the name of the poster identified by posterId.
#include <posterLib.h> STATUS posterForget(POSTER_ID posterId);
posterForget() forgets the poster identified by posterId. It is
the opposite of
posterFind() for tasks who read posters. This is the
way to free local data associated with a poster will no longer be
used, or that has been deleted by its owner.
In the case where a poster has been deleted and re-created by its
owner, it is mandatory to call
posterForget() followed by
posterFind() to be able to access the new instance of the poster.