Add SI95 transport library to doc
[ric-plt/lib/rmr.git] / docs / user-guide.rst
index b13234a..e4cb20c 100644 (file)
@@ -9,18 +9,22 @@
 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 
-:) 
+The RIC Message Router (RMR) is a library for peer-to-peer 
+communication. Applications use the library to send and 
+receive messages where the message routing and endpoint 
+selection is based on the message type rather than DNS host 
+name-IP port combinations. 
+This document contains information that developers need to 
+know to use the RMR library. Because the primary 
+documentation for the RMR library is a collection of UNIX 
+manpages (included in the development package, and available 
+via the man command when installed), there is no separate 
+"User's Guide." To provide 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 :) 
  
  
  
@@ -128,8 +132,7 @@ xaction
   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 
    
@@ -147,21 +150,21 @@ 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. 
+  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. 
+The function returns a pointer to a rmr_mbuf structure, or 
+NULL on error. 
  
 ERRORS 
 -------------------------------------------------------------------------------------------- 
@@ -176,12 +179,12 @@ ENOMEM
 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) 
+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 
@@ -204,8 +207,8 @@ 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 
+*src* to the managed entity 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. 
  
@@ -275,11 +278,11 @@ 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. 
+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. 
  
@@ -689,20 +692,20 @@ SYNOPSIS
 DESCRIPTION 
 -------------------------------------------------------------------------------------------- 
  
-The rmr_get_meid function will copy the managed equipment ID 
+The rmr_get_meid function will copy the managed entity 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 
+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 
+*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 
@@ -722,7 +725,7 @@ EINVAL
  
 ENOMEM 
    
-  A nil pointer was passed for * dest, * however it was not 
+  A nil pointer was passed for *dest,* however it was not 
   possible to allocate a buffer using malloc(). 
  
  
@@ -1107,18 +1110,18 @@ 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). 
+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 
+*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 
@@ -1138,7 +1141,7 @@ EINVAL
  
 ENOMEM 
    
-  A nil pointer was passed for * dest, * however it was not 
+  A nil pointer was passed for *dest,* however it was not 
   possible to allocate a buffer using malloc(). 
  
  
@@ -1180,13 +1183,19 @@ 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. 
+RMR based applications. The *max_msg_size* parameter is used 
+to allocate receive buffers and is the maximum message size 
+which the application expects to receive. This value is the 
+sum of **both** the maximum payload size **and** the maximum 
+trace data size. This value is also used as the default 
+message size when allocating message buffers. Messages 
+arriving which are longer than the given maximum will be 
+dropped without notification to the application. A warning is 
+written to standard error for the first message which is too 
+large on each connection. 
  
 *Flags* allows for selection of some RMr options at the time 
-of initialisation. These are set by ORing RMRFL_ constants 
+of initialisation. These are set by ORing RMRFL constants 
 from the RMr header file. Currently the following flags are 
 supported: 
  
@@ -1207,6 +1216,18 @@ RMRFL_NOTHREAD
 RMRFL_MTCALL 
    
   Enable multi-threaded call support. 
+   
+RMRFL_NOLOCK 
+   
+  Some underlying transport providers (e.g. SI95) enable 
+  locking to be turned off if the user application is single 
+  threaded, or otherwise can guarantee that RMR functions 
+  will not be invoked concurrently from different threads. 
+  Turning off locking can help make message receipt more 
+  efficient. If this flag is set when the underlying 
+  transport does not support disabling locks, it will be 
+  ignored. 
  
  
 Multi-threaded Calling 
@@ -1218,10 +1239,10 @@ 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 
+to invoke a blocking call function with the guarantee 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. 
+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 
@@ -1242,24 +1263,194 @@ setup. The following variables will be used when found.
  
  
  
-RMR_SEED_RT 
+RMR_ASYNC_CONN 
+   
+  Allows the async connection mode to be turned off (by 
+  setting the value to 0. When set to 1, or missing from the 
+  environment, RMR will invoke the connection interface in 
+  the transport mechanism using the non-blocking (async) 
+  mode. This will likely result in many "soft failures" 
+  (retry) until the connection is established, but allows 
+  the application to continue unimpeeded should the 
+  connection be slow to set up. 
+   
+RMR_BIND_IF 
+   
+  This provides the interface that RMR will bind listen 
+  ports to allowing for a single interface to be used rather 
+  than listening across all interfaces. This should be the 
+  IP address assigned to the interface that RMR should 
+  listen on, and if not defined RMR will listen on all 
+  interfaces. 
    
-  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_CTL_PORT 
+   
+  This variable defines the port that RMR should open for 
+  communications with Route Manager, and other RMR control 
+  applications. If not defined, the port 4561 is assumed. 
+   
+  Previously, the RMR_RTG_SVC (route table generator service 
+  port) was used to define this port. However, a future 
+  version of Route Manager will require RMR to connect and 
+  request tables, thus that variable is now used to supply 
+  the Route Manager well known address and port. 
+   
+  To maintain backwards compatablibility with the older 
+  Route Manager versions, the presence of this variable in 
+  the environment will shift RMR's behaviour with respect to 
+  the default value used when RMR_RTG_SVC is **not** 
+  defined. 
+   
+  When RMR_CTL_PORT is **defined:** RMR assumes that Route 
+  Manager requires RMR to connect and request table updates 
+  is made, and the default well known address for Route 
+  manager is used (routemgr:4561). 
+   
+  When RMR_CTL_PORT is **undefined:** RMR assumes that Route 
+  Manager will connect and push table updates, thus the 
+  default listen port (4561) is used. 
+   
+  To avoid any possible misinterpretation and/or incorrect 
+  assumptions on the part of RMR, it is recommended that 
+  both the RMR_CTL_PORT and RMR_RTG_SVC be defined. In the 
+  case where both variables are defined, RMR will behave 
+  exactly as is communicated with the variable's values. 
    
  
 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. 
+  The value of this variable depends on the Route Manager in 
+  use. 
+   
+  When the Route Manager is expecting to connect to an xAPP 
+  and push route tables, this variable must indicate the 
+  port which RMR should use to listen for these connections. 
+   
+  When the Route Manager is expecting RMR to connect and 
+  request a table update during initialisation, the variable 
+  should be the host of the Route Manager process. 
+   
+  The RMR_CTL_PORT variable (added with the support of 
+  sending table update requests to Route manager), controls 
+  the behaviour if this variable is not set. See the 
+  description of that variable for details. 
+   
+RMR_HR_LOG 
+   
+  By default RMR writes messages to standard error 
+  (incorrectly referred to as log messages) in human 
+  readable format. If this environment variable is set to 0, 
+  the format of standard error messages might be written in 
+  some format not easily read by humans. If missing, a value 
+  of 1 is assumed. 
+   
+RMR_LOG_VLEVEL 
+   
+  This is a numeric value which corresponds to the verbosity 
+  level used to limit messages written to standard error. 
+  The lower the number the less chatty RMR functions are 
+  during execution. The following is the current 
+  relationship between the value set on this variable and 
+  the messages written: 
+   
+0 
+   
+  Off; no messages of any sort are written. 
+   
+1 
+   
+  Only critical messages are written (default if this 
+  variable does not exist) 
+   
+2 
+   
+  Errors and all messages written with a lower value. 
+   
+3 
+   
+  Warnings and all messages written with a lower value. 
+   
+4 
+   
+  Informational and all messages written with a lower 
+  value. 
+   
+5 
+   
+  Debugging mode -- all messages written, however this 
+  requires RMR to have been compiled with debugging 
+  support enabled. 
+RMR_RTG_ISRAW 
+   
+  **Deprecated.** Should be set to 1 if the route table 
+  generator is sending "plain" messages (not using RMR to 
+  send messages, 0 if the rtg is using RMR to send. The 
+  default is 1 as we don't expect the rtg to use RMR. 
+   
+  This variable is only recognised when using the NNG 
+  transport library as it is not possible to support NNG 
+  "raw" communications with other transport libraries. It is 
+  also necessary to match the value of this variable with 
+  the capabilities of the Route Manager; at some point in 
+  the future RMR will assume that all Route Manager messages 
+  will arrive via an RMR connection and will ignore this 
+  variable. 
+RMR_SEED_RT 
+   
+  This is used to supply a static route table which can be 
+  used for debugging, testing, or if no route table 
+  generator process is being used to supply the route table. 
+  If not defined, no static table is used and RMR will not 
+  report *ready* until a table is received. The static route 
+  table may contain both the route table (between newrt 
+  start and end records), and the MEID map (between meid_map 
+  start and end records) 
+RMR_SRC_ID 
+   
+  This is either the name or IP address which is placed into 
+  outbound messages as the message source. This will used 
+  when an RMR based application uses the rmr_rts_msg() 
+  function to return a response to the sender. If not 
+  supplied RMR will use the hostname which in some container 
+  environments might not be routable. 
+   
+  The value of this variable is also used for Route Manager 
+  messages which are sent via an RMR connection. 
+RMR_VCTL_FILE 
+   
+  This supplies the name of a verbosity control file. The 
+  core RMR functions do not produce messages unless there is 
+  a critical failure. However, the route table collection 
+  thread, not a part of the main message processing 
+  component, can write additional messages to standard 
+  error. If this variable is set, RMR will extract the 
+  verbosity level for these messages (0 is silent) from the 
+  first line of the file. Changes to the file are detected 
+  and thus the level can be changed dynamically, however RMR 
+  will only suss out this variable during initialisation, so 
+  it is impossible to enable verbosity after startup. 
+RMR_WARNINGS 
+   
+  If set to 1, RMR will write some warnings which are 
+  non-performance impacting. If the variable is not defined, 
+  or set to 0, RMR will not write these additional warnings. 
  
  
 RETURN VALUE 
@@ -1351,8 +1542,8 @@ 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. 
+failure indicates that the RMr context (a void pointer passed 
+to this function was not valid. 
  
 SEE ALSO 
 -------------------------------------------------------------------------------------------- 
@@ -1390,23 +1581,23 @@ 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 
+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 respons
-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. 
+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 messag
+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 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. 
@@ -1428,7 +1619,7 @@ 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 
+the application uses the *rmr_rts_msg()* function and does 
 not adjust the transaction ID. 
  
 Retries 
@@ -1722,7 +1913,7 @@ RMR_ERR_EMPTY
 RMR_ERR_NOTSUPP 
    
   The multi-threaded option was not enabled when RMr was 
-  initialised. See the man page for *rmr_init() * for 
+  initialised. See the man page for *rmr_init()* for 
   details. 
    
  
@@ -1913,10 +2104,37 @@ 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: 
+RMR_OK when the message receive process was successful and 
+the message can be used by the caller. Depending on the 
+underlying transport mechanism, one of the following RMR 
+error stats may be returned: 
+RMR_ERR_EMPTY 
+   
+  The message received had no payload, or was completely 
+  empty. 
+   
+RMR_ERR_TIMEOUT 
+   
+  For some transport mechanisms, or if reading the receive 
+  queue from multiple threads, it is possible for one thread 
+  to find no data waiting when it queries the queue. When 
+  this state is reported, the message buffer does not 
+  contain message data and the user application should 
+  reinvoke the receive function. 
+When an RMR error state is reported, the underlying errno 
+value might provide more information. The following is a list 
+of possible values that might accompany the states listed 
+above: 
+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: 
  
  
  
@@ -2463,12 +2681,12 @@ 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
+state and will be RMR_OK when the send was successful
  
 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 
+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. 
@@ -2476,6 +2694,15 @@ 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. 
  
+**CAUTION:** In some cases it is extremely likely that the 
+message returned by the send function does **not** reference 
+the same memory structure. Thus is important for the user 
+programme to capture the new pointer for future use or to be 
+passed to rmr_free(). If you are experiencing either double 
+free errors or segment faults in either rmr_free() or 
+rmr_send_msg(), ensure that the return value from this 
+function is being captured and used. 
 ERRORS 
 -------------------------------------------------------------------------------------------- 
  
@@ -2605,19 +2832,18 @@ cycles.
       }
       // 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 );
+     send_msg->mtype = MT_ANSWER;
+     msg->len = generate_data( pm );       // something that fills the payload in
+     msg = rmr_send_msg( mr, send_msg );   // ensure new pointer used after send
      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// check for RMR_ERR_RETRY, and resend if needed
      m    s    m// else return error
      m    s}
      m}
      mreturn OK;
-     m    r    ;
  
  
  
@@ -2630,6 +2856,46 @@ 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_fack 
+SYNOPSIS 
+-------------------------------------------------------------------------------------------- 
+:: 
+  
+ #include <rmr/rmr.h>
+ void rmr_set_fack( void* vctx );
+DESCRIPTION 
+-------------------------------------------------------------------------------------------- 
+The rmr_set_fack function enables *fast TCP acknowledgements* 
+if the underlying transport library supports it. This might 
+be useful for applications which must send messages as a 
+maximum rate. 
+RETURN VALUE 
+-------------------------------------------------------------------------------------------- 
+There is no return value. 
+ERRORS 
+-------------------------------------------------------------------------------------------- 
+This function does not generate any errors. 
+SEE ALSO 
+-------------------------------------------------------------------------------------------- 
+rmr_init(3), 
 NAME 
 -------------------------------------------------------------------------------------------- 
  
@@ -2651,44 +2917,44 @@ 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 
+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. 
+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 
+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 
+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 
+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. 
+Currently errno is **not** set by this function; the only 
+cause of a failure is an invalid context (*vctx*) pointer. 
  
 EXAMPLE 
 -------------------------------------------------------------------------------------------- 
@@ -2732,7 +2998,7 @@ SYNOPSIS
 :: 
   
  #include <rmr/rmr.h>
- int rmr_bytes2payload( rmr_mbuf_t* mbuf, unsigned char* data, int len )
+ int rmr_set_trace( rmr_mbuf_t* mbuf, unsigned char* data, int len )
  
  
  
@@ -2766,6 +3032,99 @@ rmr_ring_free(3), rmr_str2meid(3), rmr_str2xact(3),
 rmr_wh_open(3), rmr_wh_send_msg(3) 
  
  
+NAME 
+-------------------------------------------------------------------------------------------- 
+rmr_set_trace 
+SYNOPSIS 
+-------------------------------------------------------------------------------------------- 
+:: 
+  
+ #include <rmr/rmr.h>
+ #include <rmr/rmr_logging.h>
+ void rmr_set_vlevel( int new_level )
+DESCRIPTION 
+-------------------------------------------------------------------------------------------- 
+The rmr_set_vlevel allows the user programme to set the 
+verbosity level which is used to determine the messages RMR 
+writes to standard error. The new_vlevel value must be one of 
+the following constants which have the indicated meanings: 
+RMR_VL_OFF 
+   
+  Turns off all message writing. This includes the stats and 
+  debugging messages generated by the route collector thread 
+  which are normally affected only by the externally managed 
+  verbose level file (and related environment variable). 
+   
+RMR_VL_CRIT 
+   
+  Write only messages of critical importance. From the point 
+  of view of RMR, when a critical proper behaviour of the 
+  library cannot be expected or guaranteed. 
+RMR_VL_ERR 
+   
+  Include error messages in the output. An error is an event 
+  from which RMR has no means to recover. Continued proper 
+  execution is likely except where the affected connection 
+  and/or component mentioned in the error is concerned. 
+RMR_VL_WARN 
+   
+  Include warning messages in the output. A warning 
+  indicates an event which is not considered to be normal, 
+  but is expected and continued acceptable behaviour of the 
+  system is assured. 
+RMR_VL_INFO 
+   
+  Include informational messagees in the output. 
+  Informational messages include some diagnostic information 
+  which explain the activities of RMR. 
+RMR_VL_DEBUG 
+   
+  Include all debugging messages in the output. Debugging 
+  must have also been enabled during the build as a 
+  precaution to accidentally enabling this level of output 
+  as it can grossly affect performance. 
+generally RMR does not write messages to the standard error 
+device from *critical path* functions, therefore it is 
+usually not harmful to enable a verbosity level of either 
+RMR_VL_CRIT, or RMR_VL_ERR. 
+Messages written from the route table collection thread are 
+still governed by the value placed into the verbose level 
+control file (see the man page for rmr_init()); those 
+messages are affected only when logging is completely 
+disabled by passing RMR_VL_OFF to this function. 
+The verbosity level can also be set via an environment 
+variable prior to the start of the RMR based application. The 
+environment variable is read only during initialisation; if 
+the programme must change the value during execution, this 
+function must be used. The default value, if this function is 
+never called, and the environment variable is not present, is 
+RMR_VL_ERR. 
+SEE ALSO 
+-------------------------------------------------------------------------------------------- 
+rmr_init(3) 
 NAME 
 -------------------------------------------------------------------------------------------- 
  
@@ -2786,7 +3145,7 @@ DESCRIPTION
 -------------------------------------------------------------------------------------------- 
  
 The rmr_str2meid function will copy the string pointed to by 
-src to the managed equipment ID (meid) field in the given 
+src to the managed entity 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 
@@ -3348,6 +3707,205 @@ 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_call 
+SYNOPSIS 
+-------------------------------------------------------------------------------------------- 
+:: 
+  
+ #include <rmr/rmr.h>
+ rmr_mbuf_t* rmr_wh_call( void* vctx, rmr_whid_t whid, rmr_mbuf_t* msg, int call_id, int max_wait )
+DESCRIPTION 
+-------------------------------------------------------------------------------------------- 
+The rmr_wh_call function accepts a message buffer (msg) from 
+the user application and attempts to send it using the 
+wormhole ID provided (whid). If the send is successful, the 
+call will block until either a response message is received, 
+or the max_wait number of milliseconds has passed. In order 
+for the response to be recognised as a response, the remote 
+process **must** use rmr_rts_msg() to send their response. 
+Like *rmr_wh_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 call_id parameter is a number in the 
+range of 2 through 255 and is used to identify the calling 
+thread in order to properly match a response message when it 
+arrives. Providing this value, and ensuring the proper 
+uniqueness, is the responsibility of the user application and 
+as such the ability to use the rmr_wh_call() function from 
+potentially non-threaded concurrent applications (such as 
+Go's goroutines) is possible. 
+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, new message buffer, with the payload containing 
+the response from the remote endpoint is returned. The state 
+in this buffer will reflect the overall send operation state 
+and should be RMR_OK. 
+If a message is returned with a state which is anything other 
+than RMR_OK, the indication is that the send was not 
+successful. The user application must check the state and 
+determine the course of action. If the return value is NULL, 
+no message, the indication is that there was no response 
+received within the timeout (max_wait) period of time. 
+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. 
+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 <rmr/rmr.h>    .// 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_call( mrc, whid, sbuf, 1000 );    f    s// expect a response in 1s or less
+            if( sbuf != NULL && sbuf->state = RMR_OK ) {
+              sprintf( stderr, "response: %s\\n", sbuf->payload );    x// assume they sent a string
+            } else {
+              sprintf( stderr, "response not received, or send error\\n" );
+            }
+         }
+       }
+       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), 
+rmr_wh_state(3) 
 NAME 
 -------------------------------------------------------------------------------------------- 
  
@@ -3486,8 +4044,8 @@ 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) 
+rmr_mk_ring(3), rmr_ring_free(3), rmr_wh_close(3), 
+rmr_wh_send_msg(3), rmr_wh_state(3) 
  
  
 NAME 
@@ -3748,5 +4306,73 @@ 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) 
+rmr_set_stimeout(3), rmr_wh_open(3), rmr_wh_close(3), 
+rmr_wh_state(3) 
+NAME 
+-------------------------------------------------------------------------------------------- 
+rmr_wh_state 
+SYNOPSIS 
+-------------------------------------------------------------------------------------------- 
+:: 
+  
+ #include <rmr/rmr.h>
+ int rmr_wh_state( void* vctx, rmr_whid_t whid )
+DESCRIPTION 
+-------------------------------------------------------------------------------------------- 
+The rmr_wh_state function will return the current state of 
+the connection associated with the given wormhole (whid). The 
+return value indicates whether the connection is open 
+(RMR_OK), or closed (any other return value). 
+When using some transport mechanisms (e.g. NNG), it may not 
+be possible for RMR to know the actual state and the 
+connection may always be reported as "open." 
+RETURN 
+-------------------------------------------------------------------------------------------- 
+The following values are potential return values. 
+RMR_OK 
+   
+  The wormhole ID is valid and the connection is "open." 
+   
+RMR_ERR_WHID 
+   
+  THe wormhole ID passed into the function was not valid. 
+   
+RMR_ERR_NOENDPT 
+   
+  The wormhole is not open (not connected). 
+   
+RMR_ERR_BADARG 
+   
+  The context passed to the function was nil or invalid. 
+   
+RMR_ERR_NOWHOPEN 
+   
+  Wormholes have not been initialised (no wormhole open call 
+  has been made). 
+   
+SEE ALSO 
+-------------------------------------------------------------------------------------------- 
  
+rmr_wh_open(3), rmr_wh_send_msg(3), rmr_wh_close(3)