Correct documentation for MEID
[ric-plt/lib/rmr.git] / src / rmr / common / src / mbuf_api.c
index 65979de..84996ee 100644 (file)
@@ -22,7 +22,9 @@
        Mnemonic:       mbuf_api.c
        Abstract:       These are common functions which work only on the mbuf and
                                thus (because they do not touch an endpoint or context)
        Mnemonic:       mbuf_api.c
        Abstract:       These are common functions which work only on the mbuf and
                                thus (because they do not touch an endpoint or context)
-                               can be agnostic to the underlying transport.
+                               can be agnostic to the underlying transport, or the transport
+                               layer provides a transport specific function (e.g. payload 
+                               reallocation).
 
        Author:         E. Scott Daniels
        Date:           8 February 2019
 
        Author:         E. Scott Daniels
        Date:           8 February 2019
                EINVAL id poitner, buf or buf header are bad.
                EOVERFLOW if the bytes given would have overrun
 
                EINVAL id poitner, buf or buf header are bad.
                EOVERFLOW if the bytes given would have overrun
 
+       We have been told that the meid will be a string, so we enforce that even if
+       the user is copying in bytes.  We will add a 0 byte at len+1 when len is less
+       than the field size, or as the last byte (doing damage to their string) if
+       the caller didn't play by the rules. If they pass a non-nil terminated set
+       of bytes which are the field length, we'll indicate truncation.
+
 */
 extern int rmr_bytes2meid( rmr_mbuf_t* mbuf, unsigned char const* src, int len ) {
        uta_mhdr_t* hdr;
 */
 extern int rmr_bytes2meid( rmr_mbuf_t* mbuf, unsigned char const* src, int len ) {
        uta_mhdr_t* hdr;
@@ -64,11 +72,20 @@ extern int rmr_bytes2meid( rmr_mbuf_t* mbuf, unsigned char const* src, int len )
        if( len > RMR_MAX_MEID ) {
                len = RMR_MAX_MEID;
                errno = EOVERFLOW;
        if( len > RMR_MAX_MEID ) {
                len = RMR_MAX_MEID;
                errno = EOVERFLOW;
-       }
+       } 
 
        hdr = (uta_mhdr_t *) mbuf->header;
        memcpy( hdr->meid, src, len );
 
 
        hdr = (uta_mhdr_t *) mbuf->header;
        memcpy( hdr->meid, src, len );
 
+       if( len == RMR_MAX_MEID ) {
+               if( *(hdr->meid+len-1) != 0 ) {
+                       *(hdr->meid+len-1) = 0;
+                       errno = EOVERFLOW;
+               }
+       } else {
+               *(hdr->meid+len) = 0;
+       }
+
        return len;
 }
 
        return len;
 }
 
@@ -189,7 +206,40 @@ extern int rmr_str2xact( rmr_mbuf_t* mbuf, unsigned char const* str ) {
 }
 
 /*
 }
 
 /*
-       Extracts the meid (managed equipment) from the header and copies the bytes
+       Extracts the transaction bytes from the header and places into a
+       user supplied buffer (dest). The buffer must be at least RMR_MAX_XID
+       bytes in length as this function will copy the entire field (even if
+       the sender saved a shorter "string." If the user supplies a nil poniter
+       as the destination, a buffer is allocated; the caller must free when
+       finished.  The buffer will be exactly RMR_MAX_XID bytes long.
+
+       The return value is a pointer to the buffer that was filled (to
+       the dest buffer provided, or the buffer we allocated). If there is an
+       error, a nil pointer is returned, and errno should suggest the root
+       cause of the issue (invalid message or no memory).
+*/
+extern unsigned char*  rmr_get_xact( rmr_mbuf_t* mbuf, unsigned char* dest ) {
+       errno = 0;
+
+       if( mbuf == NULL || mbuf->xaction == NULL ) {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       if( ! dest ) {
+               if( (dest = (unsigned char *) malloc( sizeof( unsigned char ) * RMR_MAX_XID )) == NULL ) {
+                       errno = ENOMEM;
+                       return NULL;
+               }
+       }
+
+       memcpy( dest, mbuf->xaction, RMR_MAX_XID );
+
+       return dest;
+}
+
+/*
+       Extracts the meid (managed entity) from the header and copies the bytes
        to the user supplied area. If the user supplied pointer is nil, then
        a buffer will be allocated and it is the user's responsibilty to free.
        A pointer is returned to the destination memory (allocated or not)
        to the user supplied area. If the user supplied pointer is nil, then
        a buffer will be allocated and it is the user's responsibilty to free.
        A pointer is returned to the destination memory (allocated or not)
@@ -200,6 +250,8 @@ extern int rmr_str2xact( rmr_mbuf_t* mbuf, unsigned char const* str ) {
 extern unsigned char*  rmr_get_meid( rmr_mbuf_t* mbuf, unsigned char* dest ) {
        uta_mhdr_t* hdr;
 
 extern unsigned char*  rmr_get_meid( rmr_mbuf_t* mbuf, unsigned char* dest ) {
        uta_mhdr_t* hdr;
 
+       errno = 0;
+
        if( mbuf == NULL || mbuf->header == NULL ) {
                errno = EINVAL;
                return NULL;
        if( mbuf == NULL || mbuf->header == NULL ) {
                errno = EINVAL;
                return NULL;
@@ -213,7 +265,7 @@ extern unsigned char*  rmr_get_meid( rmr_mbuf_t* mbuf, unsigned char* dest ) {
        }
 
        hdr = (uta_mhdr_t *) mbuf->header;
        }
 
        hdr = (uta_mhdr_t *) mbuf->header;
-       memcpy( dest, hdr->meid, RMR_MAX_XID );
+       memcpy( dest, hdr->meid, RMR_MAX_MEID );
 
        return dest;
 }
 
        return dest;
 }
@@ -279,6 +331,41 @@ extern int rmr_set_trace( rmr_mbuf_t* msg, unsigned const char* data, int size )
 }
 
 
 }
 
 
+/*
+       Returns a pointer (reference) to the trace data in the message. If sizeptr
+       is supplied, then the trace data size is assigned to the referenced
+       integer so that the caller doesn't need to make a second call to get the
+       value.
+
+       CAUTION:  user programmes should avoid writing to the referenced trace
+                       area (use rmr_set_trace() to avoid possible data overruns. This
+                       function is a convenience, and it is expected that users will
+                       use the trace data as read-only so as a copy is not necessary.
+*/
+extern void* rmr_trace_ref( rmr_mbuf_t* msg, int* sizeptr ) {
+       uta_mhdr_t*     hdr = NULL;
+       int size = 0;
+
+       if( sizeptr != NULL ) {
+               *sizeptr = 0;                                   // ensure reset if we bail
+       }
+
+       if( msg == NULL ) {
+               return NULL;
+       }
+
+       hdr = msg->header;
+       if( (size = RMR_TR_LEN( hdr )) <= 0 ) {
+               return NULL;
+       }
+
+       if( sizeptr != NULL ) {
+               *sizeptr = size;
+       }
+
+       return (void *) TRACE_ADDR( hdr );
+}
+
 /*
        Copies the trace bytes from the message header into the buffer provided by
        the user. If the trace data in the header is less than size, then only
 /*
        Copies the trace bytes from the message header into the buffer provided by
        the user. If the trace data in the header is less than size, then only
@@ -347,3 +434,34 @@ extern unsigned char* rmr_get_src( rmr_mbuf_t* msg, unsigned char* dest ) {
 
        return dest;
 }
 
        return dest;
 }
+
+/*
+       Returns the string with the IP address as reported by the sender. This is
+       the IP address that the sender has sussed off of one of the interfaces
+       and cannot be guarenteed to be the acutal IP address which was used to
+       establish the connection.   The caller must provide a buffer of at least
+       64 bytes; the string will be nil terminated. A pointer to the user's buffer
+       is returned on success, nil on failure.
+*/
+extern unsigned char* rmr_get_srcip( rmr_mbuf_t* msg, unsigned char* dest ) {
+       uta_mhdr_t*     hdr = NULL;
+       char*   rstr = NULL;
+
+       errno = EINVAL;
+
+       if( dest != NULL && msg != NULL ) {
+               hdr = msg->header;
+               if( HDR_VERSION( msg->header ) > 2 ) {          // src ip was not present in hdr until ver 3
+                       errno = 0;
+                       strcpy( dest, hdr->srcip );
+                       rstr = dest;
+               } else  {
+                       errno = 0;
+                       strcpy( dest, hdr->src );                               // reutrn the name:port for old messages
+                       rstr = dest;
+               }
+       }
+
+       return rstr;
+}
+