X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=docs%2Fuser-guide.rst;fp=docs%2Fuser-guide.rst;h=b13234a93565c79f2d13c287867f38c6ff460897;hb=392168d467d7949f391602f53f9fd62d2a64d12b;hp=0000000000000000000000000000000000000000;hpb=3879c38814010dfbbb896a9fc6492bff48c9b77a;p=ric-plt%2Flib%2Frmr.git diff --git a/docs/user-guide.rst b/docs/user-guide.rst new file mode 100644 index 0000000..b13234a --- /dev/null +++ b/docs/user-guide.rst @@ -0,0 +1,3752 @@ + +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. SPDX-License-Identifier: CC-BY-4.0 +.. CAUTION: this document is generated from source in doc/src/rtd. +.. To make changes edit the source and recompile the document. +.. Do NOT make changes directly to .rst or .md files. + + +RMR User's Guide +============================================================================================ + +The RIC Message Router (RMR) is a library which applications +use to send and receive messages where the message routing, +endpoint selection, is based on the message type rather than +on traditional DNS names or IP addresses. Because the user +documentation for RMR is a collection of UNIX manpages +(included in the development package, and avalable via the +man command when installed), there is no separate "User's +Guide." To prvide something for the document scrapers to +find, this is a collection of the RMR manual pages formatted +directly from their source which might be a bit ragged when +combined into a single markup document. Read the manual pages +:) + + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + rmr_mbuf_t* rmr_alloc_msg( void* ctx, int size ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_alloc_msg function is used to allocate a buffer which +the user programme can write into and then send through the +RMR library. The buffer is allocated such that sending it +requires no additional copying out of the buffer. If the +value passed in size is 0, then the default size supplied on +the *rmr_init* call will be used. The *ctx* parameter is the +void context pointer that was returned by the *rmr_init* +function. + +The pointer to the message buffer returned is a structure +which has some user application visible fields; the structure +is described in rmr.h, and is illustrated below. + + +:: + + typedef struct { + int state; + int mtype; + int len; + unsigned char* payload; + unsigned char* xaction; + uint sub_id; + uint tp_state; + } rmr_mbuf_t; + + + + + +state + + Is the current buffer state. Following a call to + rmr_send_msg the state indicates whether the buffer was + successfully sent which determines exactly what the + payload points to. If the send failed, the payload + referenced by the buffer is the message that failed to + send (allowing the application to attempt a + retransmission). When the state is RMR_OK the buffer + represents an empty buffer that the application may fill + in in preparation to send. + + +mtype + + When sending a message, the application is expected to set + this field to the appropriate message type value (as + determined by the user programme). Upon send this value + determines how the RMR library will route the message. For + a buffer which has been received, this field will contain + the message type that was set by the sending application. + + +len + + The application using a buffer to send a message is + expected to set the length value to the actual number of + bytes that it placed into the message. This is likely less + than the total number of bytes that the message can carry. + For a message buffer that is passed to the application as + the result of a receive call, this will be the value that + the sending application supplied and should indicate the + number of bytes in the payload which are valid. + + +payload + + The payload is a pointer to the actual received data. The + user programme may read and write from/to the memory + referenced by the payload up until the point in time that + the buffer is used on a rmr_send, rmr_call or rmr_reply + function call. Once the buffer has been passed back to a + RMR library function the user programme should **NOT** + make use of the payload pointer. + + +xaction + + The *xaction* field is a pointer to a fixed sized area in + the message into which the user may write a transaction + ID. The ID is optional with the exception of when the user + application uses the rmr_call function to send a message + and wait for the reply; the underlying RMR processing + expects that the matching reply message will also contain + the same data in the *xaction* field. + + + +sub_id + + This value is the subscription ID. It, in combination with + the message type is used by rmr to determine the target + endpoint when sending a message. If the application to + application protocol does not warrant the use of a + subscription ID, the RMR constant RMR_VOID_SUBID should be + placed in this field. When an application is forwarding or + returning a buffer to the sender, it is the application's + responsibility to set/reset this value. + + +tp_state + + For C applications making use of RMR, the state of a + transport based failure will often be available via errno. + However, some wrapper environments may not have direct access + to the C-lib errno value. RMR send and receive operations + will place the current value of errno into this field which + should make it available to wrapper functions. User + applications are strongly cautioned against relying on the + value of errno as some transport mechanisms may not set this + value on all calls. This value should also be ignored any + time the message status is RMR_OK. + + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +The function returns a pointer to a rmr_mbuf structure, or NULL +on error. + +ERRORS +-------------------------------------------------------------------------------------------- + + + +ENOMEM + + Unable to allocate memory. + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_tralloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3), +rmr_init_trace(3), rmr_get_trace(3), rmr_get_trlen(3), +rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3), +rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), +rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3), +rmr_ring_free(3), rmr_set_trace(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_bytes2meid + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + int rmr_bytes2meid( rmr_mbuf_t* mbuf, unsigned char* src, int len ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_bytes2meid function will copy up to *len* butes from +*src* to the managed equipment ID (meid) field in the +message. The field is a fixed length, gated by the constant +RMR_MAX_MEID and if len is larger than this value, only +RMR_MAX_MEID bytes will actually be copied. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +On success, the actual number of bytes copied is returned, or +-1 to indicate a hard error. If the length is less than 0, or +not the same as length passed in, errno is set to one of the +errors described in the *Errors* section. + +ERRORS +-------------------------------------------------------------------------------------------- + +If the returned length does not match the length passed in, +errno will be set to one of the following constants with the +meaning listed below. + + + +EINVAL + + The message, or an internal portion of the message, was + corrupted or the pointer was invalid. + + +EOVERFLOW + + The length passed in was larger than the maximum length of + the field; only a portion of the source bytes were copied. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_call(3), +rmr_free_msg(3), rmr_get_rcvfd(3), rmr_get_meid(3), +rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3), +rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3), +rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3), +rmr_ring_free(3), rmr_str2meid(3), rmr_str2xact(3), +rmr_wh_open(3), rmr_wh_send_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_bytes2payload + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + void rmr_bytes2payload( rmr_mbuf_t* mbuf, unsigned char* src, int len ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +This is a convenience function as some wrapper languages +might not have the ability to directly copy into the payload +buffer. The bytes from * src * for the length given are +copied to the payload. It is the caller's responsibility to +ensure that the payload is large enough. Upon successfully +copy, the len field in the message buffer is updated to +reflect the number of bytes copied. + +There is little error checking, and no error reporting. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +None. + +EXAMPLE +-------------------------------------------------------------------------------------------- + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_bytes2payload(3), +rmr_call(3), rmr_free_msg(3), rmr_get_rcvfd(3), +rmr_get_meid(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), +rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3), +rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_bytes2xact + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + int rmr_bytes2xact( rmr_mbuf_t* mbuf, unsigned char* src, int len ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_bytes2xact function will copy up to *len* butes from +*src* to the transaction ID (xaction) field in the message. +The field is a fixed length, gated by the constant +RMR_MAX_XID and if len is larger than this value, only +RMR_MAX_XID bytes will actually be copied. + + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +On success, the actual number of bytes copied is returned, +or -1 to indicate a hard error. If the length is less than +0, or not the same as length passed in, errno is set to +one of the errors described in the *Errors* section. + +ERRORS +-------------------------------------------------------------------------------------------- + +If the returned length does not match the length passed +in, errno will be set to one of the following constants +with the meaning listed below. + + +EINVAL + + The message, or an internal portion of the message, was + corrupted or the pointer was invalid. + + +EOVERFLOW + + The length passed in was larger than the maximum length of + the field; only a portion of the source bytes were copied. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_bytes2meid(3), rmr_call(3), +rmr_free_msg(3), rmr_get_meid(3), rmr_get_rcvfd(3), +rmr_get_xact(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), +rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3), +rmr_wh_open(3), rmr_wh_send_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_call + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + extern rmr_mbuf_t* rmr_call( void* vctx, rmr_mbuf_t* msg ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_call function sends the user application message to a +remote endpoint, and waits for a corresponding response +message before returning control to the user application. The +user application supplies a completed message buffer, as it +would for a rmr_send call, but unlike with the send, the +buffer returned will have the response from the application +that received the message. + +Messages which are received while waiting for the response +are queued internally by RMR, and are returned to the user +application when rmr_rcv_msg is invoked. These messages are +returned in th order received, one per call to rmr_rcv_msg. + +Call Timeout +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The rmr_call function implements a timeout failsafe to +prevent, in most cases, the function from blocking forever. +The timeout period is **not** based on time (calls to clock +are deemed too expensive for a low latency system level +library, but instead the period is based on the number of +received messages which are not the response. Using a +non-time mechanism for *timeout* prevents the async queue +from filling (which would lead to message drops) in an +environment where there is heavy message traffic. + +When the threshold number of messages have been queued +without receiving a response message, control is returned to +the user application and a NULL pointer is returned to +indicate that no message was received to process. Currently +the threshold is fixed at 20 messages, though in future +versions of the library this might be extended to be a +parameter which the user application may set. + +Retries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The send operations in RMr will retry *soft* send failures +until one of three conditions occurs: + + + +1. + + The message is sent without error + + +2. + + The underlying transport reports a * hard * failure + + +3. + + The maximum number of retry loops has been attempted + + +A retry loop consists of approximately 1000 send attemps ** +without** any intervening calls to * sleep() * or * usleep(). +* The number of retry loops defaults to 1, thus a maximum of +1000 send attempts is performed before returning to the user +application. This value can be set at any point after RMr +initialisation using the * rmr_set_stimeout() * function +allowing the user application to completely disable retires +(set to 0), or to increase the number of retry loops. + +Transport Level Blocking +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The underlying transport mechanism used to send messages is +configured in *non-blocking* mode. This means that if a +message cannot be sent immediately the transport mechanism +will **not** pause with the assumption that the inability to +send will clear quickly (within a few milliseconds). This +means that when the retry loop is completely disabled (set to +0), that the failure to accept a message for sending by the +underlying mechanisms (software or hardware) will be reported +immediately to the user application. + +It should be noted that depending on the underlying transport +mechanism being used, it is extremly possible that during +normal operations that retry conditions are very likely to +happen. These are completely out of RMr's control, and there +is nothing that RMr can do to avoid or midigate these other +than by allowing RMr to retry the send operation, and even +then it is possible (e.g. during connection reattempts), that +a single retry loop is not enough to guarentee a successful +send. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +The rmr_call function returns a pointer to a message buffer +with the state set to reflect the overall state of call +processing (see Errors below). In some cases a NULL pointer +will be returned; when this is the case only *errno* will be +available to describe the reason for failure. + +ERRORS +-------------------------------------------------------------------------------------------- + +These values are reflected in the state field of the returned +message. + + + +RMR_OK + + The call was successful and the message buffer references + the response message. + + +RMR_ERR_CALLFAILED + + The call failed and the value of *errno,* as described + below, should be checked for the specific reason. + + +The global "variable" *errno* will be set to one of the +following values if the overall call processing was not +successful. + + + +ETIMEDOUT + + Too many messages were queued before receiving the + expected response + + +ENOBUFS + + The queued message ring is full, messages were dropped + + +EINVAL + + A parameter was not valid + + +EAGAIN + + The underlying message system wsa interrupted or the + device was busy; the message was **not** sent, and user + application should call this function with the message + again. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + +The following code bit shows one way of using the rmr_call +function, and illustrates how the transaction ID must be set. + + +:: + + int retries_left = 5; // max retries on dev not available + int retry_delay = 50000; // retry delay (usec) + static rmr_mbuf_t* mbuf = NULL; // response msg + msg_t* pm; // private message (payload) + m// get a send buffer and reference the payload + mbuf = rmr_alloc_msg( mr, RMR_MAX_RCV_BYTES ); + pm = (msg_t*) mbuf->payload; + p// generate an xaction ID and fill in payload with data and msg type + snprintf( mbuf->xaction, RMR_MAX_XID, "%s", gen_xaction() ); + snprintf( pm->req, sizeof( pm->req ), "{ \\"req\\": \\"num users\\"}" ); + mbuf->mtype = MT_REQ; + + msg = rmr_call( mr, msg ); + if( ! msg ) { // probably a timeout and no msg received + return NULL; // let errno trickle up + } + if( mbuf->state != RMR_OK ) { + while( retries_left-- > 0 && // loop as long as eagain + errno == EAGAIN && + (msg = rmr_call( mr, msg )) != NULL && + mbuf->state != RMR_OK ) { + usleep( retry_delay ); + } + + if( mbuf == NULL || mbuf->state != RMR_OK ) { + rmr_free_msg( mbuf ); // safe if nil + return NULL; + } + } + // do something with mbuf + + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_free_msg(3), rmr_init(3), +rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3), +rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3), +rmr_fib(3), rmr_has_str(3), rmr_set_stimeout(3), +rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_wh_open + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + void rmr_close( void* vctx ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_close function closes the listen socket effectively +cutting the application off. The route table listener is also +stopped. Calls to rmr_rcv_msg() will fail with unpredictable +error codes, and calls to rmr_send_msg(), rmr_call(), and +rmr_rts_msg() will have unknown results. + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), +rmr_get_rcvfd(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), +rmr_mk_ring(3), rmr_ring_free(3), rmr_wh_open(3), +rmr_wh_send_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_free_msg + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + void rmr_free_msg( rmr_mbuf_t* mbuf ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The message buffer is returned to the pool, or the associated +memory is released depending on the needs of the underlying +messaging system. This allows the user application to release +a buffer that is not going to be used. It is safe to pass a +nil pointer to this function, and doing so does not result in +a change to the value of errrno. + +After calling, the user application should **not** use any of +the pointers (transaction ID, or payload) which were +available. + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_init(3), +rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3), +rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3), +rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3), +rmr_ring_free(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_get_meid + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + char* rmr_get_meid( rmr_mbuf_t* mbuf, unsigned char* dest ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_get_meid function will copy the managed equipment ID +(meid) field from the message into the *dest* buffer provided +by the user. The buffer referenced by * dest * is assumed to +be at least RMR_MAX_MEID bytes in length. If * dest * is +NULL, then a buffer is allocated (the calling application is +expected to free when the buffer is no longer needed). + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +On success, a pointer to the extracted string is returned. If +* dest * was supplied, then this is just a pointer to the +caller's buffer. If * dest * was NULL, this is a pointer to +the allocated buffer. If an error occurs, a nil pointer is +returned and errno is set as described below. + +ERRORS +-------------------------------------------------------------------------------------------- + +If an error occurs, the value of the global variable errno +will be set to one of the following with the indicated +meaning. + + + +EINVAL + + The message, or an internal portion of the message, was + corrupted or the pointer was invalid. + + +ENOMEM + + A nil pointer was passed for * dest, * however it was not + possible to allocate a buffer using malloc(). + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_bytes2meid(3), +rmr_call(3), rmr_free_msg(3), rmr_get_rcvfd(3), +rmr_get_xact(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), +rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3), +rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_get_rcvfd + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + void* rmr_get_rcvfd( void* ctx ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_get_rcvfd function returns a file descriptor which +may be given to epoll_wait() by an application that wishes to +use event poll in a single thread rather than block on the +arrival of a message via calls to rmr_rcv_msg(). When +epoll_wait() indicates that this file descriptor is ready, a +call to rmr_rcv_msg() will not block as at least one message +has been received. + +The context (ctx) pointer passed in is the pointer returned +by the call to rmr_init(). + +**NOTE:** There is no support for epoll in Nanomsg, thus his +function is only supported when linking with the NNG version +of RMr and the file descriptor returned when using the +Nanomsg verfsion will always return an error. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +The rmr_get_rcvfd function returns a file descriptor greater +or equal to 0 on success and -1 on error. If this function is +called from a user application linked against the Nanomsg RMr +library, calls will always return -1 with errno set to +EINVAL. + +ERRORS +-------------------------------------------------------------------------------------------- + +The following error values are specifically set by this RMR +function. In some cases the error message of a system call is +propagated up, and thus this list might be incomplete. + + +EINVAL + + The use of this function is invalid in this environment. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + +The following short code bit illustrates the use of this +function. Error checking has been omitted for clarity. + + +:: + + #include + #include + #include + #include + int main() { + int rcv_fd; // pollable fd + void* mrc; //msg router context + struct epoll_event events[10]; // support 10 events to poll + struct epoll_event epe; // event definition for event to listen to + int ep_fd = -1; + rmr_mbuf_t* msg = NULL; + int nready; + int i; + + mrc = rmr_init( "43086", RMR_MAX_RCV_BYTES, RMRFL_NONE ); + rcv_fd = rmr_get_rcvfd( mrc ); + + rep_fd = epoll_create1( 0 ); _ B ,// initialise epoll environment + epe.events = EPOLLIN; + epe.data.fd = rcv_fd; + epoll_ctl( ep_fd, EPOLL_CTL_ADD, rcv_fd, &epe ); // add our info to the mix + + while( 1 ) { + nready = epoll_wait( ep_fd, events, 10, -1 ); // -1 == block forever (no timeout) + for( i = 0; i < nready && i < 10; i++ ) { // loop through to find what is ready + if( events[i].data.fd == rcv_fd ) { // RMr has something + msg = rmr_rcv_msg( mrc, msg ); + if( msg ) { + // do something with msg + } + } + + // check for other ready fds.... + } + } + } + + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), +rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3), +rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3), +rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3), +rmr_ring_free(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_get_src + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + unsigned char* rmr_get_src( rmr_mbuf_t* mbuf, unsigned char* dest ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_get_src function will copy the *source* information +from the message to a buffer (dest) supplied by the user. In +an RMr message, the source is the sender's information that +is used for return to sender function calls, and is generally +the hostname and port in the form *name*. The source might be +an IP address port combination; the data is populated by the +sending process and the only requirement is that it be +capable of being used to start a TCP session with the sender. + +The maximum size allowed by RMr is 64 bytes (including the +nil string terminator), so the user must ensure that the +destination buffer given is at least 64 bytes. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +On success, a pointer to the destination buffer is given as a +convenience to the user programme. On failure, a nil pointer +is returned and the value of errno is set. + +ERRORS +-------------------------------------------------------------------------------------------- + +If an error occurs, the value of the global variable errno +will be set to one of the following with the indicated +meaning. + + + +EINVAL + + The message, or an internal portion of the message, was + corrupted or the pointer was invalid. + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_bytes2meid(3), +rmr_call(3), rmr_free_msg(3), rmr_get_rcvfd(3), +rmr_get_srcip(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), +rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3), +rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_get_srcip + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + unsigned char* rmr_get_srcip( rmr_mbuf_t* mbuf, unsigned char* dest ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_get_srcip function will copy the *source IP address* +from the message to a buffer (dest) supplied by the user. In +an RMr message, the source IP address is the sender's +information that is used for return to sender function calls; +this function makes it available to the user application. The +address is maintained as IP:port where *IP* could be either +an IPv6 or IPv4 address depending on what was provided by the +sending application. + +The maximum size allowed by RMr is 64 bytes (including the +nil string terminator), so the user must ensure that the +destination buffer given is at least 64 bytes. The user +application should use the RMr constant RMR_MAX_SRC to ensure +that the buffer supplied is large enough, and to protect +against future RMr enhancements which might increase the +address buffer size requirement. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +On success, a pointer to the destination buffer is given as a +convenience to the user programme. On failure, a nil pointer +is returned and the value of errno is set. + +ERRORS +-------------------------------------------------------------------------------------------- + +If an error occurs, the value of the global variable errno +will be set to one of the following with the indicated +meaning. + + + +EINVAL + + The message, or an internal portion of the message, was + corrupted or the pointer was invalid. + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_bytes2meid(3), +rmr_call(3), rmr_free_msg(3), rmr_get_rcvfd(3), +rmr_get_src(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), +rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3), +rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_get_trace + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + int rmr_get_trace( rmr_mbuf_t* mbuf, unsigned char* dest, int size ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_get_trace function will copy the trace information +from the message into the user's allocated memory referenced +by dest. The size parameter is assumed to be the maximum +number of bytes which can be copied (size of the destination +buffer). + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +On success, the number of bytes actually copied is returned. +If the return value is 0, no bytes copied, then the reason +could be that the message pointer was nil, or the size +parameter was <= 0. + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_tralloc_msg(3), rmr_bytes2xact(3), +rmr_bytes2meid(3), rmr_call(3), rmr_free_msg(3), +rmr_get_rcvfd(3), rmr_get_trlen(3), rmr_init(3), +rmr_init_trace(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), +rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3), +rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3), +rmr_set_trace(3), rmr_trace_ref(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_get_trlen + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + int rmr_get_trlen( rmr_mbuf_t* msg ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +Given a message buffer, this function returns the amount of +space (bytes) that have been allocated for trace data. If no +trace data has been allocated, then 0 is returned. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +The number of bytes allocated for trace information in the +given message. + +ERRORS +-------------------------------------------------------------------------------------------- + + + +INVAL + + Parameter(s) passed to the function were not valid. + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), +rmr_get_trace(3), rmr_init(3), rmr_init_trace(3), +rmr_send_msg(3), rmr_rcv_msg(3), rmr_rcv_specific(3), +rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3), +rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3), +rmr_set_trace(3), rmr_tralloc_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_get_xact + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + char* rmr_get_xact( rmr_mbuf_t* mbuf, unsigned char* dest ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_get_xact function will copy the transaction field +from the message into the *dest* buffer provided by the user. +The buffer referenced by * dest * is assumed to be at least +RMR_MAX_XID bytes in length. If * dest * is NULL, then a +buffer is allocated (the calling application is expected to +free when the buffer is no longer needed). + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +On success, a pointer to the extracted string is returned. If +* dest * was supplied, then this is just a pointer to the +caller's buffer. If * dest * was NULL, this is a pointer to +the allocated buffer. If an error occurs, a nil pointer is +returned and errno is set as described below. + +ERRORS +-------------------------------------------------------------------------------------------- + +If an error occurs, the value of the global variable errno +will be set to one of the following with the indicated +meaning. + + + +EINVAL + + The message, or an internal portion of the message, was + corrupted or the pointer was invalid. + + +ENOMEM + + A nil pointer was passed for * dest, * however it was not + possible to allocate a buffer using malloc(). + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_bytes2xact(3), rmr_bytes2meid(3), +rmr_call(3), rmr_free_msg(3), rmr_get_rcvfd(3), +rmr_get_meid(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), +rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3), +rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_init + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + void* rmr_init( char* proto_port, int max_msg_size, int flags ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_init function prepares the environment for sending +and receiving messages. It does so by establishing a worker +thread (pthread) which subscribes to a route table generator +which provides the necessary routing information for the RMR +library to send messages. + +*Port* is used to listen for connection requests from other +RMR based applications. The value of *max_msg_size* will be +used when allocating zero copy send buffers which must be +allocated, possibly, prior to the application knowing the +actual size of a specific message. + +*Flags* allows for selection of some RMr options at the time +of initialisation. These are set by ORing RMRFL_ constants +from the RMr header file. Currently the following flags are +supported: + + + +RMRFL_NONE + + No flags are set. + + +RMRFL_NOTHREAD + + The route table collector thread is not to be started. + This should only be used by the route table generator + application if it is based on RMr. + + +RMRFL_MTCALL + + Enable multi-threaded call support. + + +Multi-threaded Calling +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The support for an application to issue a *blocking call* by +the rmr_call() function was limited such that only user +applications which were operating in a single thread could +safely use the function. Further, timeouts were message count +based and not time unit based. Multi-threaded call support +adds the ability for a user application with multiple threads +to invoke a blocking call function with the guarentee that +the correct response message is delivered to the thread. The +additional support is implemented with the * rmr_mt_call() * +and * rmr_mt_rcv() * function calls. + +Multi-threaded call support requires the user application to +specifically enable it when RMr is initialised. This is +necessary because a second, dedicated, receiver thread must +be started, and requires all messages to be examined and +queued by this thread. The additional overhead is minimal, +queuing information is all in the RMr message header, but as +an additional process is necessary the user application must +"opt in" to this approach. + + +ENVIRONMENT +-------------------------------------------------------------------------------------------- + +As a part of the initialisation process rmr_init will look +into the available environment variables to influence it's +setup. The following variables will be used when found. + + + +RMR_SEED_RT + + Assumes this is the filename of the seed route table file + to use. In normal situations, the library will wait for an + update from the route table generator (expected within a + few seconds of initialisation) before being able to send + messages. However, in some situations where a bootstrap + table is necessary, this is the means to supply it to the + library. + + +RMR_RTG_SVC + + The route table generator assumes that RMr is listening on + a well known port (4561) by default, but this environment + variable can be used to change the listening port if + needed. The value of the variable is expected to be just + the port. + + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +The rmr_init function returns a void pointer (a contex if you +will) that is passed as the first parameter to nearly all +other RMR functions. If rmr_init is unable to properly +initialise the environment, NULL is returned and errno is set +to an appropriate value. + +ERRORS +-------------------------------------------------------------------------------------------- + +The following error values are specifically set by this RMR +function. In some cases the error message of a system call is +propagated up, and thus this list might be incomplete. + + +ENOMEM + + Unable to allocate memory. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + + +:: + + void* uh; + rmr_mbuf* buf = NULL; + uh = rmr_init( "43086", 4096, 0 ); + buf = rmr_rcv_msg( uh, buf ); + + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), +rmr_get_rcvfd(3), rmr_mt_call(3), rmr_mt_rcv(3), +rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3), +rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3), +rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3), +rmr_ring_free(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_init_trace + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + void* rmr_init_trace( void* ctx ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_init_trace function establishes the default trace +space placed in each message buffer allocated with +rmr_alloc_msg(). If this function is never called, then no +trace space is allocated by default into any message buffer. + +Trace space allows the user application to pass some trace +token, or other data with the message, but outside of the +payload. Trace data may be added to any message with +rmr_set_trace(), and may be extracted from a message with +rmr_get_trace(). The number of bytes that a message contains +for/with trace data can be determined by invoking +rmr_get_trlen(). + +This function may be safely called at any time during the +life of the user programme to (re)set the default trace space +reserved. If the user programme needs to allocate a message +with trace space of a different size than is allocated by +default, without fear of extra overhead of reallocating a +message later, the rmr_tralloc_msg() function can be used. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +A value of 1 is returned on success, and 0 on failure. A +failure indicates that the RMr context (void *) passed to +this function was not valid. + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_tr_alloc_msg(3), rmr_call(3), +rmr_free_msg(3), rmr_get_rcvfd(3), rmr_get_trace(3), +rmr_get_trlen(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), +rmr_mk_ring(3), rmr_ring_free(3), rmr_set_trace(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_mt_call + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + extern rmr_mbuf_t* rmr_mt_call( void* vctx, rmr_mbuf_t* msg, int id, int timeout ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_mt_call function sends the user application message +to a remote endpoint, and waits for a corresponding response +message before returning control to the user application. The +user application supplies a completed message buffer, as it +would for a rmr_send_msg call, but unlike with a send, the +buffer returned will have the response from the application +that received the message. The thread invoking the * +rmr_mt_call()* will block until a message arrives or until +*timeout* milliseconds has passed; which ever comes first. +Using a timeout value of zero (0) will cause the thread to +block without a timeout. + +The * id * supplied as the third parameter is an integer in +the range of 2 through 255 inclusive. This is a caller +defined "thread number" and is used to match the response +message with the correct user application thread. If the ID +value is not in the proper range, the attempt to make the +call will fail. + +Messages which are received while waiting for the response +are queued on a *normal* receive queue and will be delivered +to the user application with the next invocation of * +rmr_mt_rcv() * or * rmr_rvv_msg().* by RMR, and are returned +to the user application when rmr_rcv_msg is invoked. These +messages are returned in th order received, one per call to +rmr_rcv_msg. + +NOTE: Currently the multi-threaded functions are supported +only when the NNG transport mechanism is being used. It will +not be possible to link a programme using the Nanomsg version +of the library when references to this function are present. + +The Transaction ID +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The user application is responsible for setting the value of +the transaction ID field before invoking *rmr_mt_call.* The +transaction ID is a RMR_MAX_XID byte field that is used to +match the response message when it arrives. RMr will compare +**all** of the bytes in the field, so the caller must ensure +that they are set correctly to avoid missing the response +message. (The application which returns the response message +is also expected to ensure that the return buffer has the +matching transaction ID. This can be done transparently if +the application uses the * rmr_rts_msg() * function and does +not adjust the transaction ID. + +Retries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The send operations in RMr will retry *soft* send failures +until one of three conditions occurs: + + + +1. + + The message is sent without error + + +2. + + The underlying transport reports a * hard * failure + + +3. + + The maximum number of retry loops has been attempted + + +A retry loop consists of approximately 1000 send attemps ** +without** any intervening calls to * sleep() * or * usleep(). +* The number of retry loops defaults to 1, thus a maximum of +1000 send attempts is performed before returning to the user +application. This value can be set at any point after RMr +initialisation using the * rmr_set_stimeout() * function +allowing the user application to completely disable retires +(set to 0), or to increase the number of retry loops. + +Transport Level Blocking +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The underlying transport mechanism used to send messages is +configured in *non-blocking* mode. This means that if a +message cannot be sent immediately the transport mechanism +will **not** pause with the assumption that the inability to +send will clear quickly (within a few milliseconds). This +means that when the retry loop is completely disabled (set to +0), that the failure to accept a message for sending by the +underlying mechanisms (software or hardware) will be reported +immediately to the user application. + +It should be noted that depending on the underlying transport +mechanism being used, it is extremly possible that during +normal operations that retry conditions are very likely to +happen. These are completely out of RMr's control, and there +is nothing that RMr can do to avoid or midigate these other +than by allowing RMr to retry the send operation, and even +then it is possible (e.g. during connection reattempts), that +a single retry loop is not enough to guarentee a successful +send. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +The rmr_mt_call function returns a pointer to a message +buffer with the state set to reflect the overall state of +call processing. If the state is RMR_OK then the buffer +contains the response message; otherwise the state indicates +the error encountered while attempting to send the message. + +If no response message is received when the timeout period +has expired, a nil pointer will be returned (NULL). + +ERRORS +-------------------------------------------------------------------------------------------- + +These values are reflected in the state field of the returned +message. + + + +RMR_OK + + The call was successful and the message buffer references + the response message. + + +RMR_ERR_BADARG + + An argument passed to the function was invalid. + + +RMR_ERR_CALLFAILED + + The call failed and the value of *errno,* as described + below, should be checked for the specific reason. + + +RMR_ERR_NOENDPT + + An endpoint associated with the message type could not be + found in the route table. + + +RMR_ERR_RETRY + + The underlying transport mechanism was unable to accept + the message for sending. The user application can retry + the call operation if appropriate to do so. + + +The global "variable" *errno* will be set to one of the +following values if the overall call processing was not +successful. + + + +ETIMEDOUT + + Too many messages were queued before receiving the + expected response + + +ENOBUFS + + The queued message ring is full, messages were dropped + + +EINVAL + + A parameter was not valid + + +EAGAIN + + The underlying message system wsa interrupted or the + device was busy; the message was **not** sent, and user + application should call this function with the message + again. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + +The following code bit shows one way of using the rmr_mt_call +function, and illustrates how the transaction ID must be set. + + +:: + + int retries_left = 5; // max retries on dev not available + static rmr_mbuf_t* mbuf = NULL; // response msg + msg_t* pm; // private message (payload) + m// get a send buffer and reference the payload + mbuf = rmr_alloc_msg( mr, RMR_MAX_RCV_BYTES ); + pm = (msg_t*) mbuf->payload; + p// generate an xaction ID and fill in payload with data and msg type + rmr_bytes2xact( mbuf, xid, RMR_MAX_XID ); + snprintf( pm->req, sizeof( pm->req ), "{ \\"req\\": \\"num users\\"}" ); + mbuf->mtype = MT_USR_RESP; + + msg = rmr_mt_call( mr, msg, my_id, 100 ); e :// wait up to 100ms + if( ! msg ) { // probably a timeout and no msg received + return NULL; // let errno trickle up + } + if( mbuf->state != RMR_OK ) { + while( retries_left-- > 0 && // loop as long as eagain + mbuf->state == RMR_ERR_RETRY && + (msg = rmr_mt_call( mr, msg )) != NULL && + mbuf->state != RMR_OK ) { + usleep( retry_delay ); + } + + if( mbuf == NULL || mbuf->state != RMR_OK ) { + rmr_free_msg( mbuf ); // safe if nil + return NULL; + } + } + // do something with mbuf + + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_free_msg(3), rmr_init(3), +rmr_mt_rcv(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_fib(3), rmr_has_str(3), +rmr_set_stimeout(3), rmr_tokenise(3), rmr_mk_ring(3), +rmr_ring_free(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_mt_rcv + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + rmr_mbuf_t* rmr_mt_rcv( void* vctx, rmr_mbuf_t* old_msg, int timeout ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_mt_rcv function blocks until a message is received, +or the timeout period (milliseconds) has passed. The result +is an RMr message buffer which references a received message. +In the case of a timeout the state will be reflected in an +"empty buffer" (if old_msg was not nil, or simply with the +return of a nil pointer. If a timeout value of zero (0) is +given, then the function will block until the next message +received. + +The *vctx* pointer is the pointer returned by the rmr_init +function. *Old_msg* is a pointer to a previously used message +buffer or NULL. The ability to reuse message buffers helps to +avoid alloc/free cycles in the user application. When no +buffer is available to supply, the receive function will +allocate one. + +The *old_msg* parameter allows the user to pass a previously +generated RMr message back to RMr for reuse. Optionally, the +user application may pass a nil pointer if no reusable +message is available. When a timeout occurs, and old_msg was +not nil, the state will be returned by returning a pointer to +the old message with the state set. + +It is possible to use the *rmr_rcv_msg()* function instead of +this function. Doing so might be advantagous if the user +programme does not always start the multi-threaded mode and +the use of *rmr_rcv_msg()* would make the flow of the code +more simple. The advantags of using this function are the +ability to set a timeout without using epoll, and a small +performance gain (if multi-threaded mode is enabled, and the +*rmr_rcv_msg()* function is used, it simply invokes this +function without a timeout value, thus there is the small +cost of a second call that results). Similarly, the +*rmr_torcv_msg()* call can be used when in multi-threaded +mode with the same "pass through" overhead to using this +function directly. + +NOTE: Currently the multi-threaded functions are supported +only when the NNG transport mechanism is being used. It will +not be possible to link a programme using the nanomsg version +of the library when references to this function are present. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +When a message is received before the timeout period expires, +a pointer to the RMr message buffer which describes the +message is returned. This will, with a high probability, be a +different message buffer than *old_msg;* the user application +should not continue to use *old_msg* after it is passed to +this function. + +In the event of a timeout the return value will be the old +msg with the state set, or a nil pointer if no old message +was provided. + +ERRORS +-------------------------------------------------------------------------------------------- + +The *state* field in the message buffer will be set to one of +the following values: + + + +RMR_OK + + The message was received without error. + + +RMR_ERR_BADARG + + A parameter passed to the function was not valid (e.g. a + nil pointer). indicate either RMR_OK or RMR_ERR_EMPTY if + an empty message was received. + + +RMR_ERR_EMPTY + + The message received had no associated data. The length of + the message will be 0. + + +RMR_ERR_NOTSUPP + + The multi-threaded option was not enabled when RMr was + initialised. See the man page for *rmr_init() * for + details. + + +RMR_ERR_RCVFAILED + + A hard error occurred preventing the receive from + completing. + +When a nil pointer is returned, or any other state value was +set in the message buffer, errno will be set to one of the +following: + + + +INVAL + + Parameter(s) passed to the function were not valid. + + +EBADF + + The underlying message transport is unable to process the + request. + + +ENOTSUP + + The underlying message transport is unable to process the + request. + + +EFSM + + The underlying message transport is unable to process the + request. + + +EAGAIN + + The underlying message transport is unable to process the + request. + + +EINTR + + The underlying message transport is unable to process the + request. + + +ETIMEDOUT + + The underlying message transport is unable to process the + request. + + +ETERM + + The underlying message transport is unable to process the + request. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + + + +:: + + rmr_mbuf_t* mbuf = NULL; // received msg + msg = rmr_mt_recv( mr, mbuf, 100 ); // wait up to 100ms + if( msg != NULL ) { + switch( msg->state ) { + case RMR_OK: + printf( "got a good message\\n" ); + break; + case RMR_ERR_EMPTY: + printf( "received timed out\\n" ); + break; + default: + printf( "receive error: %d\\n", mbuf->state ); + break; + } + } else { + printf( "receive timeout (nil)\\n" ); + } + + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), +rmr_get_rcvfd(3), rmr_init(3), rmr_mk_ring(3), +rmr_mt_call(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_torcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_ring_free(3), rmr_torcv_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_payload_size + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + int rmr_payload_size( rmr_mbuf_t* msg ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +Given a message buffer, this function returns the amount of +space (bytes) available for the user application to consume +in the message payload. This is different than the message +length available as a field in the message buffer. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +The number of bytes available in the payload. + +ERRORS +-------------------------------------------------------------------------------------------- + + + +INVAL + + Parameter(s) passed to the function were not valid. + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3), +rmr_send_msg(3), rmr_rcv_msg(3), rmr_rcv_specific(3), +rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3), +rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_rcv_msg + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + rmr_mbuf_t* rmr_rcv_msg( void* vctx, rmr_mbuf_t* old_msg ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_rcv_msg function blocks until a message is received, +returning the message to the caller via a pointer to a +rmr_mbuf_t structure type. If messages were queued while +waiting for the response to a previous invocation of +rmr_call, the oldest message is removed from the queue and +returned without delay. + +The *vctx* pointer is the pointer returned by the rmr_init +function. *Old_msg* is a pointer to a previously used message +buffer or NULL. The ability to reuse message buffers helps to +avoid alloc/free cycles in the user application. When no +buffer is available to supply, the receive function will +allocate one. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +The function returns a pointer to the rmr_mbuf_t structure +which references the message information (state, length, +payload), or a NULL pointer in the case of an extreme error. + +ERRORS +-------------------------------------------------------------------------------------------- + +The *state* field in the message buffer will indicate either +RMR_OK or RMR_ERR_EMPTY if an empty message was received. If +a nil pointer is returned, or any other state value was set +in the message buffer, errno will be set to one of the +following: + + + +INVAL + + Parameter(s) passed to the function were not valid. + + +EBADF + + The underlying message transport is unable to process the + request. + + +ENOTSUP + + The underlying message transport is unable to process the + request. + + +EFSM + + The underlying message transport is unable to process the + request. + + +EAGAIN + + The underlying message transport is unable to process the + request. + + +EINTR + + The underlying message transport is unable to process the + request. + + +ETIMEDOUT + + The underlying message transport is unable to process the + request. + + +ETERM + + The underlying message transport is unable to process the + request. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), +rmr_get_rcvfd(3), rmr_init(3), rmr_mk_ring(3), +rmr_payload_size(3), rmr_send_msg(3), rmr_torcv_msg(3), +rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3), +rmr_ring_free(3), rmr_torcv_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_ready + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + int rmr_ready( void* vctx ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_ready function checks to see if a routing table has +been successfully received and installed. The return value +indicates the state of readiness. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +A return value of 1 (true) indicates that the routing table +is in place and attempts to send messages can be made. When 0 +is returned (false) the routing table has not been received +and thus attempts to send messages will fail with *no +endpoint* errors. + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3), +rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3), +rmr_rcv_specific(3), rmr_rts_msg(3), rmr_fib(3), +rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3), +rmr_ring_free(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_realloc_payload + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + extern rmr_mbuf_t* rmr_realloc_payload( rmr_mbuf_t* msg, int new_len, int copy, int clone ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_realloc_payload function will return a pointer to an +RMR message buffer struct (rmr_mbuf_t) which has a payload +large enough to accomodate *new_len* bytes. If necessary, the +underlying payload is reallocated, and the bytes from the +original payload are copied if the *copy* parameter is true +(1). If the message passed in has a payload large enough, +there is no additional memory allocation and copying. + +Cloning The Message Buffer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This function can also be used to generate a separate copy of +the original message, with the desired payload size, without +destroying the original message buffer or the original +payload. A standalone copy is made only when the *clone* +parameter is true (1). When cloning, the payload is copied to +the cloned message **only** if the *copy* parameter is true. + +Message Buffer Metadata +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The metadata in the original message buffer (message type, +subscription ID, and payload length) will be preserved if the +*copy* parameter is true. When this parameter is not true +(0), then these values are set to the uninitialised value +(-1) for type and ID, and the length is set to 0. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +The rmr_realloc_payload function returns a pointer to the +message buffer with the payload which is large enough to hold +*new_len* bytes. If the *clone* option is true, this will be +a pointer to the newly cloned message buffer; the original +message buffer pointer may still be used to referenced that +message. It is the calling application's responsibility to +free the memory associateed with both messages using the +rmr_free_msg() function. + +When the *clone* option is not used, it is still good +practice by the calling application to capture and use this +reference as it is possible that the message buffer, and not +just the payload buffer, was reallocated. In the event of an +error, a nil pointer will be returned and the value of +*errno* will be set to reflect the problem. + +ERRORS +-------------------------------------------------------------------------------------------- + +These value of *errno* will reflect the error condition if a +nil pointer is returned: + + + +ENOMEM + + Memory allocation of the new payload failed. + + +EINVAL + + The pointer passed in was nil, or refrenced an invalid + message, or the required length was not valid. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + +The following code bit illustrates how this function can be +used to reallocate a buffer for a return to sender +acknowledgement message which is larger than the message +received. + + +:: + + if( rmr_payload_size( msg ) < ack_sz ) { // received message too small for ack + msg = rmr_realloc_payload( msg, ack_sz, 0, 0 ); // reallocate the message with a payload big enough + if( msg == NULL ) { + fprintf( stderr, "[ERR] realloc returned a nil pointer: %s\\n", strerror( errno ) ); + } else { + } e// populate and send ack message + }} + } + + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_free_msg(3), rmr_init(3), +rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3), +rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3), +rmr_fib(3), rmr_has_str(3), rmr_set_stimeout(3), +rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_rts_msg + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + rmr_mbuf_t* rmr_rts_msg( void* vctx, rmr_mbuf_t* msg ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_rts_msg function sends a message returning it to the +endpoint which sent the message rather than selecting an +endpoint based on the message type and routing table. Other +than this small difference, the behaviour is exactly the same +as rmr_send_msg. + +Retries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The send operations in RMr will retry *soft* send failures +until one of three conditions occurs: + + + +1. + + The message is sent without error + + +2. + + The underlying transport reports a * hard * failure + + +3. + + The maximum number of retry loops has been attempted + + +A retry loop consists of approximately 1000 send attemps ** +without** any intervening calls to * sleep() * or * usleep(). +* The number of retry loops defaults to 1, thus a maximum of +1000 send attempts is performed before returning to the user +application. This value can be set at any point after RMr +initialisation using the * rmr_set_stimeout() * function +allowing the user application to completely disable retires +(set to 0), or to increase the number of retry loops. + +Transport Level Blocking +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The underlying transport mechanism used to send messages is +configured in *non-blocking* mode. This means that if a +message cannot be sent immediately the transport mechanism +will **not** pause with the assumption that the inability to +send will clear quickly (within a few milliseconds). This +means that when the retry loop is completely disabled (set to +0), that the failure to accept a message for sending by the +underlying mechanisms (software or hardware) will be reported +immediately to the user application. + +It should be noted that depending on the underlying transport +mechanism being used, it is extremly possible that during +normal operations that retry conditions are very likely to +happen. These are completely out of RMr's control, and there +is nothing that RMr can do to avoid or midigate these other +than by allowing RMr to retry the send operation, and even +then it is possible (e.g. during connection reattempts), that +a single retry loop is not enough to guarentee a successful +send. + +PAYLOAD SIZE +-------------------------------------------------------------------------------------------- + +When crafting a response based on a received message, the +user application must take care not to write more bytes to +the message payload than the allocated message has. In the +case of a received message, it is possible that the response +needs to be larger than the payload associated with the +inbound message. In order to use the return to sender +function, the source infomration in the orignal message must +be present in the response; information which cannot be added +to a message buffer allocated through the standard RMR +allocation function. To allocate a buffer with a larger +payload, and which retains the necessary sender data needed +by this function, the *rmr_realloc_payload()* function must +be used to extend the payload to a size suitable for the +response. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +On success, a new message buffer, with an empty payload, is +returned for the application to use for the next send. The +state in this buffer will reflect the overall send operation +state and should be RMR_OK. + +If the state in the returned buffer is anything other than +UT_OK, the user application may need to attempt a +retransmission of the message, or take other action depending +on the setting of errno as described below. + +In the event of extreme failure, a NULL pointer is returned. +In this case the value of errno might be of some use, for +documentation, but there will be little that the user +application can do other than to move on. + +ERRORS +-------------------------------------------------------------------------------------------- + +The following values may be passed back in the *state* field +of the returned message buffer. + + + +RMR_ERR_BADARG + + The message buffer pointer did not refer to a valid + message. + +RMR_ERR_NOHDR + + The header in the message buffer was not valid or + corrupted. + +RMR_ERR_NOENDPT + + The message type in the message buffer did not map to a + known endpoint. + +RMR_ERR_SENDFAILED + + The send failed; errno has the possible reason. + + +The following values may be assigned to errno on failure. + + +INVAL + + Parameter(s) passed to the function were not valid, or the + underlying message processing environment was unable to + interpret the message. + + +ENOKEY + + The header information in the message buffer was invalid. + + +ENXIO + + No known endpoint for the message could be found. + + +EMSGSIZE + + The underlying transport refused to accept the message + because of a size value issue (message was not attempted + to be sent). + + +EFAULT + + The message referenced by the message buffer is corrupt + (NULL pointer or bad internal length). + + +EBADF + + Internal RMR error; information provided to the message + transport environment was not valid. + + +ENOTSUP + + Sending was not supported by the underlying message + transport. + + +EFSM + + The device is not in a state that can accept the message. + + +EAGAIN + + The device is not able to accept a message for sending. + The user application should attempt to resend. + + +EINTR + + The operation was interrupted by delivery of a signal + before the message was sent. + + +ETIMEDOUT + + The underlying message environment timed out during the + send process. + + +ETERM + + The underlying message environment is in a shutdown state. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3), +rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3), +rmr_rcv_specific(3), rmr_ready(3), rmr_fib(3), +rmr_has_str(3), rmr_set_stimeout(3), rmr_tokenise(3), +rmr_mk_ring(3), rmr_ring_free(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_send_msg + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + rmr_mbuf_t* rmr_send_msg( void* vctx, rmr_mbuf_t* msg ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_send_msg function accepts a message buffer from the +user application and attempts to send it. The destination of +the message is selected based on the message type specified +in the message buffer, and the matching information in the +routing tables which are currently in use by the RMR library. +This may actually result in the sending of the message to +multiple destinations which could degrade expected overall +performance of the user application. (Limiting excessive +sending of messages is the responsibility of the +application(s) responsible for building the routing table +used by the RMR library, and not the responsibility of the +library.) + +Retries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The send operations in RMr will retry *soft* send failures +until one of three conditions occurs: + + + +1. + + The message is sent without error + + +2. + + The underlying transport reports a * hard * failure + + +3. + + The maximum number of retry loops has been attempted + + +A retry loop consists of approximately 1000 send attemps ** +without** any intervening calls to * sleep() * or * usleep(). +* The number of retry loops defaults to 1, thus a maximum of +1000 send attempts is performed before returning to the user +application. This value can be set at any point after RMr +initialisation using the * rmr_set_stimeout() * function +allowing the user application to completely disable retires +(set to 0), or to increase the number of retry loops. + +Transport Level Blocking +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The underlying transport mechanism used to send messages is +configured in *non-blocking* mode. This means that if a +message cannot be sent immediately the transport mechanism +will **not** pause with the assumption that the inability to +send will clear quickly (within a few milliseconds). This +means that when the retry loop is completely disabled (set to +0), that the failure to accept a message for sending by the +underlying mechanisms (software or hardware) will be reported +immediately to the user application. + +It should be noted that depending on the underlying transport +mechanism being used, it is extremly possible that during +normal operations that retry conditions are very likely to +happen. These are completely out of RMr's control, and there +is nothing that RMr can do to avoid or midigate these other +than by allowing RMr to retry the send operation, and even +then it is possible (e.g. during connection reattempts), that +a single retry loop is not enough to guarentee a successful +send. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +On success, a new message buffer, with an empty payload, is +returned for the application to use for the next send. The +state in this buffer will reflect the overall send operation +state and should be RMR_OK. + +When the message cannot be successfully sent this function +will return the unsent (original) message buffer with the +state set to indicate the reason for failure. The value of * +errno * may also be set to reflect a more detailed failure +reason if it is known. + +In the event of extreme failure, a NULL pointer is returned. +In this case the value of errno might be of some use, for +documentation, but there will be little that the user +application can do other than to move on. + +ERRORS +-------------------------------------------------------------------------------------------- + +The following values may be passed back in the *state* field +of the returned message buffer. + + + +RMR_RETRY + + The message could not be sent, but the underlying + transport mechanism indicates that the failure is + temporary. If the send operation is tried again it might + be successful. + +RMR_SEND_FAILED + + The send operation was not successful and the underlying + transport mechanism indicates a permanent (hard) failure; + retrying the send is not possible. + +RMR_ERR_BADARG + + The message buffer pointer did not refer to a valid + message. + +RMR_ERR_NOHDR + + The header in the message buffer was not valid or + corrupted. + +RMR_ERR_NOENDPT + + The message type in the message buffer did not map to a + known endpoint. + + +The following values may be assigned to errno on failure. + + +INVAL + + Parameter(s) passed to the function were not valid, or the + underlying message processing environment was unable to + interpret the message. + + +ENOKEY + + The header information in the message buffer was invalid. + + +ENXIO + + No known endpoint for the message could be found. + + +EMSGSIZE + + The underlying transport refused to accept the message + because of a size value issue (message was not attempted + to be sent). + + +EFAULT + + The message referenced by the message buffer is corrupt + (NULL pointer or bad internal length). + + +EBADF + + Internal RMR error; information provided to the message + transport environment was not valid. + + +ENOTSUP + + Sending was not supported by the underlying message + transport. + + +EFSM + + The device is not in a state that can accept the message. + + +EAGAIN + + The device is not able to accept a message for sending. + The user application should attempt to resend. + + +EINTR + + The operation was interrupted by delivery of a signal + before the message was sent. + + +ETIMEDOUT + + The underlying message environment timed out during the + send process. + + +ETERM + + The underlying message environment is in a shutdown state. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + +The following is a simple example of how the rmr_send_msg +function is called. In this example, the send message buffer +is saved between calls and reused eliminating alloc/free +cycles. + + +:: + + static rmr_mbuf_t* send_msg = NULL; // message to send; reused on each call + msg_t* send_pm; // payload for send + msg_t* pm; // our message format in the received payload + mif( send_msg == NULL ) { + send_msg = rmr_alloc_msg( mr, MAX_SIZE ); r// new buffer to send + } + // reference payload and fill in message type + pm = (msg_t*) send_msg->payload; + send_msg->mtype = MT_ANSWER; + msg->len = generate_data( pm ); e// something that fills the payload in + msg = rmr_send_msg( mr, send_msg ); + mif( ! msg ) { + m !return ERROR; + m} else { + m sif( msg->state != RMR_OK ) { + m s m// check for eagain, and resend if needed + m s m// else return error + m s} + m} + mreturn OK; + m r ; + + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3), +rmr_payload_size(3), rmr_rcv_msg(3), rmr_rcv_specific(3), +rmr_rts_msg(3), rmr_ready(3), rmr_mk_ring(3), +rmr_ring_free(3), rmr_torcv_rcv(3), rmr_wh_send_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_set_stimeout + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + rmr_mbuf_t* rmr_set_stimeout( void* vctx, int rloops ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_set_stimeout function sets the configuration for how +RMr will retry message send operations which complete with +either a * timeout * or * again * completion value. (Send +operations include all of the possible message send +functions: * rmr_send_msg(), rmr_call(), rmr_rts_msg() * and +* rmr_wh_send_msg(). * The * rloops * parameter sets the +maximum number of retry loops that will be attempted before +giving up and returning the unsuccessful state to the user +application. Each retry loop is approximately 1000 attempts, +and RMr does ** not ** invoke any sleep function between +retries in the loop; a small, 1 mu-sec, sleep is executed +between loop sets if the * rloops * value is greater than 1. + + +Disabling Retries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +By default, the send operations will execute with an * rloop +* setting of 1; each send operation will attempt to resend +the message approximately 1000 times before giving up. If the +user application does not want to have send operations retry +when the underlying transport mechanism indicates * timeout * +or * again, * the application should invoke this function and +pass a value of 0 (zero) for * rloops. * With this setting, +all RMr send operations will attempt a send operation only ** +once, ** returning immediately to the caller with the state +of that single attempt. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +This function returns a -1 to indicate that the * rloops * +value could not be set, and the value * RMR_OK * to indicate +success. + +ERRORS +-------------------------------------------------------------------------------------------- + +Currently errno is ** not ** set by this function; the only +cause of a failure is an invalid context (* vctx *) pointer. + +EXAMPLE +-------------------------------------------------------------------------------------------- + +The following is a simple example of how the rmr_set_stimeout +function is called. + + +:: + + #define NO_FLAGS 0 + char* Oport = "43086"; // port for message router listen + int rmax_size = 4096; // max message size for default allocations + void* mr_context; // message router context + mr_context = rmr_init( port, max_size, NO_FLAGS ); + if( mr_context != NULL ) { + rmr_set_stimeout( mr_context, 0 ); // turn off retries + } + + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3), +rmr_payload_size(3), rmr_rcv_msg(3), rmr_rcv_specific(3), +rmr_rts_msg(3), rmr_ready(3), rmr_mk_ring(3), +rmr_ring_free(3), rmr_send_msg(3), rmr_torcv_rcv(3), +rmr_wh_send_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_set_trace + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + int rmr_bytes2payload( rmr_mbuf_t* mbuf, unsigned char* data, int len ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_set_trace function will copy len bytes from data into +the trace portion of mbuf. If the trace area of mbuf is not +the correct size, the message buffer will be reallocated to +ensure that enough space is available for the trace data. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +The rmr_set_trace function returns the number of bytes +successfully copied to the message. If 0 is returned either +the message pointer was nil, or the size in the parameters +was <= 0. + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_tralloc_msg(3), rmr_bytes2xact(3), +rmr_bytes2payload(3), rmr_call(3), rmr_free_msg(3), +rmr_get_rcvfd(3), rmr_get_meid(3), rmr_get_trace(3), +rmr_get_trlen(3), rmr_init(3), rmr_init_trace(3), +rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3), +rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3), +rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), rmr_mk_ring(3), +rmr_ring_free(3), rmr_str2meid(3), rmr_str2xact(3), +rmr_wh_open(3), rmr_wh_send_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_str2meid + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + int rmr_str2meid( rmr_mbuf_t* mbuf, unsigned char* src, int len ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_str2meid function will copy the string pointed to by +src to the managed equipment ID (meid) field in the given +message. The field is a fixed length, gated by the constant +RMR_MAX_MEID and if string length is larger than this value, +then **nothing** will be copied. (Note, this differs slightly +from the behaviour of the lrmr_bytes2meid() function.) + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +On success, the value RMR_OK is returned. If the string +cannot be copied to the message, the return value will be one +of the errors listed below. + +ERRORS +-------------------------------------------------------------------------------------------- + +If the return value is not RMR_OK, then it will be set to one +of the values below. + + + +RMR_ERR_BADARG + + The message, or an internal portion of the message, was + corrupted or the pointer was invalid. + + +RMR_ERR_OVERFLOW + + The length passed in was larger than the maximum length of + the field; only a portion of the source bytes were copied. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), +rmr_get_meid(3), rmr_get_rcvfd(3), rmr_payload_size(3), +rmr_send_msg(3), rmr_rcv_msg(3), rmr_rcv_specific(3), +rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3), +rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3), +rmr_bytes2meid(3), rmr_wh_open(3), rmr_wh_send_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_str2xact + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + int rmr_str2xact( rmr_mbuf_t* mbuf, unsigned char* src, int len ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_str2xact function will copy the string pointed to by +src to the transaction ID (xaction) field in the given +message. The field is a fixed length, gated by the constant +RMR_MAX_XID and if string length is larger than this value, +then **nothing** will be copied. (Note, this differs slightly +from the behaviour of the lrmr_bytes2xact() function.) + + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +On success, the value RMR_OK is returned. If the string +cannot be copied to the message, the return value will be +one of the errors listed below. + +ERRORS +-------------------------------------------------------------------------------------------- + +If the return value is not RMR_OK, then it will be set to +one of the values below. + + +RMR_ERR_BADARG + + The message, or an internal portion of the message, was + corrupted or the pointer was invalid. + + +RMR_ERR_OVERFLOW + + The length passed in was larger than the maximum length of + the field; only a portion of the source bytes were copied. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_bytes2meid(3), rmr_bytes2xact(3), +rmr_call(3), rmr_free_msg(3), rmr_get_meid(3), +rmr_get_rcvfd(3), rmr_get_xact(3), rmr_payload_size(3), +rmr_send_msg(3), rmr_rcv_msg(3), rmr_rcv_specific(3), +rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3), +rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3), +rmr_str2meid(3), rmr_wh_open(3), rmr_wh_send_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +RMR support functions + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + #include + char* rmr_fib( char* fname ); + int rmr_has_str( char const* buf, char const* str, char sep, int max ); + int rmr_tokenise( char* buf, char** tokens, int max, char sep ); + void* rmr_mk_ring( int size ); + void rmr_ring_free( void* vr ); + static inline void* rmr_ring_extract( void* vr ) + static inline int rmr_ring_insert( void* vr, void* new_data ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +These functions support the RMR library, and are made +available to user applications as some (e.g. route table +generators) might need and/or want to make use of them. The +rmr_fib function accepts a file name and reads the entire +file into a single buffer. The intent is to provide an easy +way to load a static route table without a lot of buffered +I/O hoops. + +The rmr_has_str function accepts a *buffer* containing a set +of delimited tokens (e.g. foo,bar,goo) and returns true if +the target string, *str,* matches one of the tokens. The +*sep* parameter provides the separation character in the +buffer (e.g a comma) and *max* indicates the maximum number +of tokens to split the buffer into before checking. + +The rmr_tokenise function is a simple tokeniser which splits +*buf* into tokens at each occurrence of *sep*. Multiple +occurrences of the separator character (e.g. a,,b) result in +a nil token. Pointers to the tokens are placed into the +*tokens* array provided by the caller which is assumed to +have at least enough space for *max* entries. + +The rmr_mk_ring function creates a buffer ring with *size* +entries. + +The rmr_ring_free function accepts a pointer to a ring +context and frees the associated memory. + +The rmr_ring_insert and rmr_ring_extract functions are +provided as static inline functions via the +*rmr/ring_inline.h* header file. These functions both accept +the ring *context* returned by mk_ring, and either insert a +pointer at the next available slot (tail) or extract the data +at the head. + +RETURN VALUES +-------------------------------------------------------------------------------------------- + +The following are the return values for each of these +functions. + +The rmr_fib function returns a pointer to the buffer +containing the contents of the file. The buffer is terminated +with a single nil character (0) making it a legitimate C +string. If the file was empty or nonexistent, a buffer with +an immediate nil character. If it is important to the calling +programme to know if the file was empty or did not exist, the +caller should use the system stat function call to make that +determination. + +The rmr_has_str function returns 1 if *buf* contains the +token referenced by &ita and false (0) if it does not. On +error, a -1 value is returned and errno is set accordingly. + +The rmr_tokenise function returns the actual number of token +pointers placed into *tokens* + +The rmr_mk_ring function returns a void pointer which is the +*context* for the ring. + +The rmr_ring_insert function returns 1 if the data was +successfully inserted into the ring, and 0 if the ring is +full and the pointer could not be deposited. + +The rmr_ring_extract will return the data which is at the +head of the ring, or NULL if the ring is empty. + +ERRORS +-------------------------------------------------------------------------------------------- + +Not many of these functions set the value in errno, however +the value may be one of the following: + + +INVAL + + Parameter(s) passed to the function were not valid. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3), +rmr_payload_size(3), rmr_send_msg(3), rmr_rcv_msg(3), +rmr_rcv_specific(3), rmr_rts_msg(3), rmr_ready(3), + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_torcv_msg + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + rmr_mbuf_t* rmr_torcv_msg( void* vctx, rmr_mbuf_t* old_msg, int ms_to ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_torcv_msg function will pause for *ms_to* +milliseconds waiting for a message to arrive. If a message +arrives before the timeout expires the message buffer +returned will have a status of RMR_OK and the payload will +contain the data received. If the timeout expires before the +message is received, the status will have the value +RMR_ERR_TIMEOUT. When a received message is returned the +message buffer will also contain the message type and length +set by the sender. If messages were queued while waiting for +the response to a previous invocation of rmr_call, the oldest +message is removed from the queue and returned without delay. + +The *vctx* pointer is the pointer returned by the rmr_init +function. *Old_msg* is a pointer to a previously used message +buffer or NULL. The ability to reuse message buffers helps to +avoid alloc/free cycles in the user application. When no +buffer is available to supply, the receive function will +allocate one. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +The function returns a pointer to the rmr_mbuf_t structure +which references the message information (state, length, +payload), or a NULL pointer in the case of an extreme error. + +ERRORS +-------------------------------------------------------------------------------------------- + +The *state* field in the message buffer will be one of the +following: + + + +RMR_OK + + The message buffer (payload) references the received data. + + +RMR_ERR_INITFAILED + + The first call to this function must initialise an + underlying system notification mechanism. On failure, this + error is returned and errno will have the system error + status set. If this function fails to intialise, the poll + mechansim, it is likely that message receives will never + be successful. + + +RMR_ERR_TIMEOUT + + The timeout expired before a complete message was + received. All other fields in the message buffer are not + valid. + + +RMR_ERR_EMPTY + + A message was received, but it had no payload. All other + fields in the message buffer are not valid. + + + + +INVAL + + Parameter(s) passed to the function were not valid. + + +EBADF + + The underlying message transport is unable to process the + request. + + +ENOTSUP + + The underlying message transport is unable to process the + request. + + +EFSM + + The underlying message transport is unable to process the + request. + + +EAGAIN + + The underlying message transport is unable to process the + request. + + +EINTR + + The underlying message transport is unable to process the + request. + + +ETIMEDOUT + + The underlying message transport is unable to process the + request. + + +ETERM + + The underlying message transport is unable to process the + request. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), +rmr_get_rcvfd(3), rmr_init(3), rmr_payload_size(3), +rmr_rcv_msg(3), rmr_send_msg(3), rmr_rcv_specific(3), +rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3), +rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_trace_ref + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + int rmr_trace_ref( rmr_mbuf_t* mbuf, int* sizeptr ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_trace_ref function return a pointer to the trace area +in the message, and optionally populate the user programme +supplied size integer with the trace area size, if *sizeptr* +is not nil. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +On success, a void pointer to the trace area of the message +is returned. A nil pointer is returned if the message has no +trace data area allocated, or if the message itself is +invalid. + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_tralloc_msg(3), rmr_bytes2xact(3), +rmr_bytes2meid(3), rmr_call(3), rmr_free_msg(3), +rmr_get_rcvfd(3), rmr_get_trlen(3), rmr_init(3), +rmr_init_trace(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), +rmr_mk_ring(3), rmr_ring_free(3), rmr_str2meid(3), +rmr_str2xact(3), rmr_wh_open(3), rmr_wh_send_msg(3), +rmr_set_trace(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_tralloc_msg + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + rmr_mbuf_t* rmr_tralloc_msg( void* vctx, int size, + int trace_size, unsigned const char *tr_data ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_alloc_msg function is used to allocate a buffer which +the user programme can write into and then send through the a +library. The buffer is allocated such that sending it +requires no additional copying from the buffer as it passes +through the underlying transport mechanism. + +The *size* parameter is used to set the payload length in the +message and If it is 0, then the default size supplied on the +*rmr_init* call will be used. In addition to allocating the +payload, a space in the buffer is reserved for *trace* data +(tr_size bytes), and the bytes pointed to by *tr_data* are +copied into that portion of the message. The *vctx* parameter +is the void context pointer that was returned by the +*rmr_init* function. + +The pointer to the message buffer returned is a structure +which has some user application visible fields; the structure +is described in rmr.h, and is illustrated below. + + +:: + + typedef struct { + int state; + int mtype; + int len; + unsigned char* payload; + unsigned char* xaction; + } rmr_mbuf_t; + + + + + +state + + Is the current buffer state. Following a call to + rmr_send_msg the state indicates whether the buffer was + successfully sent which determines exactly what the + payload points to. If the send failed, the payload + referenced by the buffer is the message that failed to + send (allowing the application to attempt a + retransmission). When the state is a_OK the buffer + represents an empty buffer that the application may fill + in in preparation to send. + + +mtype + + When sending a message, the application is expected to set + this field to the appropriate message type value (as + determined by the user programme). Upon send this value + determines how the a library will route the message. For a + buffer which has been received, this field will contain + the message type that was set by the sending application. + + +len + + The application using a buffer to send a message is + expected to set the length value to the actual number of + bytes that it placed into the message. This is likely less + than the total number of bytes that the message can carry. + For a message buffer that is passed to the application as + the result of a receive call, this will be the value that + the sending application supplied and should indicate the + number of bytes in the payload which are valid. + + +payload + + The payload is a pointer to the actual received data. The + user programme may read and write from/to the memory + referenced by the payload up until the point in time that + the buffer is used on a rmr_send, rmr_call or rmr_reply + function call. Once the buffer has been passed back to a a + library function the user programme should **NOT** make + use of the payload pointer. + + +xaction + + The *xaction* field is a pointer to a fixed sized area in + the message into which the user may write a transaction + ID. The ID is optional with the exception of when the user + application uses the rmr_call function to send a message + and wait for the reply; the underlying a processing + expects that the matching reply message will also contain + the same data in the *xaction* field. + + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +The function returns a pointer to a rmr_mbuf structure, or +NULL on error. + +ERRORS +-------------------------------------------------------------------------------------------- + + + +ENOMEM + + Unable to allocate memory. + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_mbuf(3) rmr_call(3), rmr_free_msg(3), +rmr_init(3), rmr_init_trace(3), rmr_get_trace(3), +rmr_get_trlen(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), +rmr_mk_ring(3), rmr_ring_free(3), rmr_set_trace(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_wh_open + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + void rmr_close( void* vctx, rmr_whid_t whid ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_wh_close function closes the wormhole associated with +the wormhole id passed in. Future calls to rmr_wh_send_msg +with this ID will fail. + +The underlying TCP connection to the remote endpoint is +**not** closed as this session may be reqruired for +regularlly routed messages (messages routed based on message +type). There is no way to force a TCP session to be closed at +this point in time. + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), +rmr_get_rcvfd(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), +rmr_mk_ring(3), rmr_ring_free(3), rmr_wh_open(3), +rmr_wh_send_msg(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_wh_open + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + void* rmr_wh_open( void* vctx, char* target ) + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_wh_open function creates a direct link for sending, a +wormhole, to another RMr based process. Sending messages +through a wormhole requires that the connection be +established overtly by the user application (via this +function), and that the ID returned by rmr_wh_open be passed +to the rmr_wh_send_msg function. + +*Target* is the *name* or *IP-address* combination of the +processess that the wormhole should be connected to. *Vctx* +is the RMr void context pointer that was returned by the +rmr_init function. + +When invoked, this function immediatly attempts to connect to +the target process. If the connection cannot be established, +an error is returned to the caller, and no direct messages +can be sent to the target. Once a wormhole is connected, the +underlying transport mechanism (e.g. NNG) will provide +reconnects should the connection be lost, however the +handling of messages sent when a connection is broken is +undetermined as each underlying transport mechanism may +handle buffering and retries differently. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +The rmr_wh_open function returns a type rmr_whid_t which must +be passed to the rmr_wh_send_msg function when sending a +message. The id may also be tested to determine success or +failure of the connection by using the RMR_WH_CONNECTED macro +and passing the ID as the parameter; a result of 1 indicates +that the connection was esablished and that the ID is valid. + +ERRORS +-------------------------------------------------------------------------------------------- + +The following error values are specifically set by this RMR +function. In some cases the error message of a system call is +propagated up, and thus this list might be incomplete. + + +EINVAL + + A parameter passed was not valid. + +EACCESS + + The user applicarion does not have the ability to + establish a wormhole to the indicated target (or maybe any + target). + +ECONNREFUSED + + The connection was refused. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + + +:: + + void* rmc; + rmr_whid_t wh; + rmc = rmr_init( "43086", 4096, 0 ); // init context + wh = rmr_wh_open( rmc, "localhost:6123" ); + if( !RMR_WH_CONNECTED( wh ) ) { + f fprintf( stderr, "unable to connect wormhole: %s\\n", + strerror( errno ) ); + } + + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), +rmr_get_rcvfd(3), rmr_payload_size(3), rmr_send_msg(3), +rmr_rcv_msg(3), rmr_rcv_specific(3), rmr_rts_msg(3), +rmr_ready(3), rmr_fib(3), rmr_has_str(3), rmr_tokenise(3), +rmr_mk_ring(3), rmr_ring_free(3), rmr_wh_send_msg(3), +rmr_wh_close(3) + + +NAME +-------------------------------------------------------------------------------------------- + +rmr_wh_send_msg + +SYNOPSIS +-------------------------------------------------------------------------------------------- + + +:: + + #include + rmr_mbuf_t* rmr_wh_send_msg( void* vctx, rmr_whid_t id, rmr_mbuf_t* msg ); + + + +DESCRIPTION +-------------------------------------------------------------------------------------------- + +The rmr_wh_send_msg function accepts a message buffer from +the user application and attempts to send it using the +wormhole ID provided (id). Unlike *rmr_send_msg,* this +function attempts to send the message directly to a process +at the other end of a wormhole which was created with +*rmr_wh-open().* When sending message via wormholes, the +normal RMr routing based on message type is ignored, and the +caller may leave the message type unspecified in the message +buffer (unless it is needed by the receiving process). + +The message buffer (msg) used to send is the same format as +used for regular RMr send and reply to sender operations, +thus any buffer allocated by these means, or calls to +*rmr_rcv_msg()* can be passed to this function. + +Retries +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The send operations in RMr will retry *soft* send failures +until one of three conditions occurs: + + + +1. + + The message is sent without error + + +2. + + The underlying transport reports a * hard * failure + + +3. + + The maximum number of retry loops has been attempted + + +A retry loop consists of approximately 1000 send attemps ** +without** any intervening calls to * sleep() * or * usleep(). +* The number of retry loops defaults to 1, thus a maximum of +1000 send attempts is performed before returning to the user +application. This value can be set at any point after RMr +initialisation using the * rmr_set_stimeout() * function +allowing the user application to completely disable retires +(set to 0), or to increase the number of retry loops. + +Transport Level Blocking +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The underlying transport mechanism used to send messages is +configured in *non-blocking* mode. This means that if a +message cannot be sent immediately the transport mechanism +will **not** pause with the assumption that the inability to +send will clear quickly (within a few milliseconds). This +means that when the retry loop is completely disabled (set to +0), that the failure to accept a message for sending by the +underlying mechanisms (software or hardware) will be reported +immediately to the user application. + +It should be noted that depending on the underlying transport +mechanism being used, it is extremly possible that during +normal operations that retry conditions are very likely to +happen. These are completely out of RMr's control, and there +is nothing that RMr can do to avoid or midigate these other +than by allowing RMr to retry the send operation, and even +then it is possible (e.g. during connection reattempts), that +a single retry loop is not enough to guarentee a successful +send. + +RETURN VALUE +-------------------------------------------------------------------------------------------- + +On success, a new message buffer, with an empty payload, is +returned for the application to use for the next send. The +state in this buffer will reflect the overall send operation +state and should be RMR_OK. + +If the state in the returned buffer is anything other than +RMR_OK, the user application may need to attempt a +retransmission of the message, or take other action depending +on the setting of errno as described below. + +In the event of extreme failure, a NULL pointer is returned. +In this case the value of errno might be of some use, for +documentation, but there will be little that the user +application can do other than to move on. + +ERRORS +-------------------------------------------------------------------------------------------- + +The following values may be passed back in the *state* field +of the returned message buffer. + + + +RMR_ERR_WHID + + The wormhole ID passed in was not associated with an open + wormhole, or was out of range for a valid ID. + +RMR_ERR_NOWHOPEN + + No wormholes exist, further attempt to validate the ID are + skipped. + +RMR_ERR_BADARG + + The message buffer pointer did not refer to a valid + message. + +RMR_ERR_NOHDR + + The header in the message buffer was not valid or + corrupted. + + +The following values may be assigned to errno on failure. + + +INVAL + + Parameter(s) passed to the function were not valid, or the + underlying message processing environment was unable to + interpret the message. + + +ENOKEY + + The header information in the message buffer was invalid. + + +ENXIO + + No known endpoint for the message could be found. + + +EMSGSIZE + + The underlying transport refused to accept the message + because of a size value issue (message was not attempted + to be sent). + + +EFAULT + + The message referenced by the message buffer is corrupt + (NULL pointer or bad internal length). + + +EBADF + + Internal RMR error; information provided to the message + transport environment was not valid. + + +ENOTSUP + + Sending was not supported by the underlying message + transport. + + +EFSM + + The device is not in a state that can accept the message. + + +EAGAIN + + The device is not able to accept a message for sending. + The user application should attempt to resend. + + +EINTR + + The operation was interrupted by delivery of a signal + before the message was sent. + + +ETIMEDOUT + + The underlying message environment timed out during the + send process. + + +ETERM + + The underlying message environment is in a shutdown state. + + +EXAMPLE +-------------------------------------------------------------------------------------------- + +The following is a simple example of how the a wormhole is +created (rmr_wh_open) and then how rmr_wh_send_msg function +is used to send messages. Some error checking is omitted for +clarity. + + +:: + + #include .// system headers omitted for clarity + int main() { + rmr_whid_t whid = -1; // wormhole id for sending + void* mrc; //msg router context + int i; + rmr_mbuf_t* sbuf; // send buffer + int count = 0; + mrc = rmr_init( "43086", RMR_MAX_RCV_BYTES, RMRFL_NONE ); + if( mrc == NULL ) { + fprintf( stderr, "[FAIL] unable to initialise RMr environment\\n" ); + exit( 1 ); + } + while( ! rmr_ready( mrc ) ) { e i// wait for routing table info + sleep( 1 ); + } + sbuf = rmr_alloc_msg( mrc, 2048 ); + while( 1 ) { + if( whid < 0 ) { + whid = rmr_wh_open( mrc, "localhost:6123" ); // open fails if endpoint refuses conn + w if( RMR_WH_CONNECTED( wh ) ) { + snprintf( sbuf->payload, 1024, "periodic update from sender: %d", count++ ); + sbuf->len = strlen( sbuf->payload ); + sbuf = rmr_wh_send_msg( mrc, whid, sbuf ); + } + } + sleep( 5 ); + } + } + + + +SEE ALSO +-------------------------------------------------------------------------------------------- + +rmr_alloc_msg(3), rmr_call(3), rmr_free_msg(3), rmr_init(3), +rmr_payload_size(3), rmr_rcv_msg(3), rmr_rcv_specific(3), +rmr_rts_msg(3), rmr_ready(3), rmr_fib(3), rmr_has_str(3), +rmr_tokenise(3), rmr_mk_ring(3), rmr_ring_free(3), +rmr_set_stimeout(3), rmr_wh_open(3), rmr_wh_close(3) +