Add rmr_get_xact function 98/698/1 1.2.0
authorE. Scott Daniels <daniels@research.att.com>
Tue, 13 Aug 2019 15:35:04 +0000 (11:35 -0400)
committerE. Scott Daniels <daniels@research.att.com>
Tue, 13 Aug 2019 15:39:00 +0000 (11:39 -0400)
The rmr_get_xact function can be used to extract the transaction
information from a message. This is a convenience function.

Signed-off-by: E. Scott Daniels <daniels@research.att.com>
Change-Id: I303478df3e9558740b2c193c99416c2dfa9b9475

13 files changed:
CHANGES
CMakeLists.txt
doc/CMakeLists.txt
doc/src/library/.gitignore
doc/src/library/api_qref.im
doc/src/man/rmr.7.xfm
doc/src/man/rmr_bytes2xact.3.xfm
doc/src/man/rmr_get_meid.3.xfm
doc/src/man/rmr_get_xact.3.xfm [new file with mode: 0644]
doc/src/man/rmr_str2xact.3.xfm
src/rmr/common/include/rmr.h
src/rmr/common/src/mbuf_api.c
test/mbuf_api_static_test.c

diff --git a/CHANGES b/CHANGES
index 3e1ae6d..8c54566 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,10 @@
 API and build change  and fixe summaries. Doc correctsions
 and/or changes are not mentioned here; see the commit messages.
 
+2019 August 13; version 1.2.0 (API change, non-breaking)
+       The function rmr_get_xact() was added to proide a convenient
+       way to extract the transaction field from a message.
+
 2019 August 8; version 1.1.0 (API change)
        This change should be backward compatable/non-breaking
        A new field has been added to the message buffer (rmr_mbuf_t).
index e9b68f3..2c95159 100644 (file)
@@ -35,8 +35,8 @@ project( rmr LANGUAGES C )
 cmake_minimum_required( VERSION 3.5 )
 
 set( major_version "1" )               # should be automatically populated from git tag later, but until CI process sets a tag we use this
-set( minor_version "1" )
-set( patch_level "1" )
+set( minor_version "2" )
+set( patch_level "0" )
 
 set( install_root "${CMAKE_INSTALL_PREFIX}" )
 set( install_inc "include/rmr" )
index fe59f5e..77cea9b 100644 (file)
@@ -85,6 +85,7 @@ if( BUILD_DOC )
                rmr_get_srcip.3
                rmr_trace_ref.3
                rmr_set_stimeout.3
+               rmr_get_xact.3
        )
 
        # initialise lists of files we generated
index 28155e7..a474f3f 100644 (file)
@@ -7,3 +7,4 @@
 *.rst
 *.md
 *.toc
+*.sp
index 0f305fb..ba23054 100644 (file)
@@ -282,6 +282,8 @@ The bytes from the &cw(meid) field of the message buffer are copied to the &ital
 provided by the application. 
 The full field of &cw(RMR_MAX_MEID) bytes are copied; the caller must ensure that &ital(dest)
 is large enough.
+If the destination buffer pointer passed in is a nil pointer, the function will allocate a buffer
+and return a pointer, which the caller is expected to free, to the buffer.
 
 &proto_start
 unsigned char*  rmr_get_src( rmr_mbuf_t* mbuf, unsigned char* dest );
@@ -314,6 +316,16 @@ The bytes from the trace data, up to &tial(size) bytes, is copied from the messa
 to the &ital(dest) buffer provided by the caller.
 The return value is the number of bytes actually copied.
 
+&proto_start
+unsigned char*  rmr_get_xact( rmr_mbuf_t* mbuf, unsigned char* dest );
+&proto_end
+The bytes from the &ital(transaction) field in the message buffer are copied to the &ital(dest) buffer
+provided by the application. 
+The full field of &cw(RMR_MAX_MEID) bytes are copied; the caller must ensure that &ital(dest)
+is large enough.
+If the destination buffer pointer passed in is a nil pointer, the function will allocate a buffer
+and return a pointer, which the caller is expected to free, to the buffer.
+
 &proto_start
 int rmr_payload_size( rmr_mbuf_t* msg );
 &proto_end
index 1c973c6..5de226f 100644 (file)
@@ -104,10 +104,12 @@ rmr_call(3),
 rmr_free_msg(3),
 rmr_init(3),
 rmr_init_trace(3),
+rmr_get_meid(3),
 rmr_get_src(3),
 rmr_get_srcip(3),
 rmr_get_trace(3),
 rmr_get_trlen(3),
+rmr_get_xact(3),
 rmr_payload_size(3),
 rmr_rcv_msg(3),
 rmr_rcv_specific(3),
index 97fb5a3..2f62a5f 100644 (file)
@@ -75,7 +75,9 @@ 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),
index 939a372..bcf7ce0 100644 (file)
@@ -79,6 +79,7 @@ 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),
diff --git a/doc/src/man/rmr_get_xact.3.xfm b/doc/src/man/rmr_get_xact.3.xfm
new file mode 100644 (file)
index 0000000..cb924a5
--- /dev/null
@@ -0,0 +1,102 @@
+.if false
+==================================================================================
+       Copyright (c) 2019 Nokia 
+       Copyright (c) 2018-2019 AT&T Intellectual Property.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================================
+.fi
+
+.if false
+       Mnemonic        rmr_get_xact.xfm
+       Abstract        The manual page for the rmr_get_xact function.
+       Author          E. Scott Daniels
+       Date            13 August 2019
+.fi
+
+.gv e LIB lib
+.im &{lib}/man/setup.im 
+
+&line_len(6i)
+
+&h1(RMR Library Functions)
+&h2(NAME)
+       rmr_get_xact
+
+&h2(SYNOPSIS)
+&indent
+&ex_start
+#include <rmr/rmr.h>
+
+char* rmr_get_xact( rmr_mbuf_t* mbuf, unsigned char* dest )
+&ex_end
+
+&uindent
+
+&h2(DESCRIPTION)
+The &cw(rmr_get_xact) function will copy the transaction field from the message
+into the &ital(dest) buffer provided by the user.  
+The buffer referenced by &ital( dest ) is assumed to be at least &cw(RMR_MAX_XID) bytes in length.
+If &ital( dest ) is NULL, then a buffer is allocated (the calling application is expected
+to free when the buffer is no longer needed).
+
+&h2(RETURN VALUE)
+On success, a pointer to the extracted string is returned. 
+If &ital( dest ) was supplied, then this is just a pointer to the caller's buffer.
+If &ital( 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.
+
+&h2(ERRORS)
+If an error occurs, the value of the global variable &cw( errno ) will be set to one of 
+the following with the indicated meaning.
+
+&beg_dlist(.75i : ^&bold_font )
+&half_space
+&di(EINVAL) The message, or an internal portion of the message, was corrupted or the pointer was invalid.
+
+&half_space
+&di(ENOMEM) A nil pointer was passed for &ital( dest, ) however it was not possible to allocate a 
+       buffer using malloc().
+&end_dlist
+
+
+
+&h2(SEE ALSO )
+.ju off
+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)
+.ju on
+
+
+.qu
+
index 6bc40d0..06ec74d 100644 (file)
@@ -77,7 +77,9 @@ 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),
index 5802cc6..d43d3ba 100644 (file)
@@ -142,6 +142,7 @@ extern void rmr_free_msg( rmr_mbuf_t* mbuf );
 extern unsigned char*  rmr_get_meid( rmr_mbuf_t* mbuf, unsigned char* dest );
 extern unsigned char*  rmr_get_src( rmr_mbuf_t* mbuf, unsigned char* dest );
 extern unsigned char* rmr_get_srcip( rmr_mbuf_t* msg, unsigned char* dest );
+extern unsigned char*  rmr_get_xact( rmr_mbuf_t* mbuf, unsigned char* dest );
 extern rmr_mbuf_t* rmr_realloc_msg( rmr_mbuf_t* mbuf, int new_tr_size );
 extern int rmr_str2meid( rmr_mbuf_t* mbuf, unsigned char const* str );
 extern void rmr_str2payload( rmr_mbuf_t* mbuf, unsigned char const* str );
index 1074e37..e88ab23 100644 (file)
@@ -188,6 +188,39 @@ extern int rmr_str2xact( rmr_mbuf_t* mbuf, unsigned char const* str ) {
        return RMR_OK;
 }
 
+/*
+       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 equipment) from the header and copies the bytes
        to the user supplied area. If the user supplied pointer is nil, then
@@ -200,6 +233,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;
 
+       errno = 0;
+
        if( mbuf == NULL || mbuf->header == NULL ) {
                errno = EINVAL;
                return NULL;
@@ -213,7 +248,7 @@ extern unsigned char*  rmr_get_meid( rmr_mbuf_t* mbuf, unsigned char* dest ) {
        }
 
        hdr = (uta_mhdr_t *) mbuf->header;
-       memcpy( dest, hdr->meid, RMR_MAX_XID );
+       memcpy( dest, hdr->meid, RMR_MAX_MEID );
 
        return dest;
 }
index 2482f0c..1ee2858 100644 (file)
@@ -49,18 +49,30 @@ int mbuf_api_test( ) {
        char*   buf;
        void*   ptr;
        rmr_mbuf_t*     mbuf;
+       uta_mhdr_t*     hdr;
        unsigned char src_buf[256];
+       unsigned char dest_buf[256];
 
+
+       // --- dummy up a message buffer --------------------------------------------------------
        mbuf = (rmr_mbuf_t *) malloc( sizeof( *mbuf ) );
        if( mbuf == NULL ) {
                fprintf( stderr, "[FAIL] tester cannot allocate memory: mbuf\n" );
                exit( 1 );
        }
+       memset( mbuf, 0, sizeof( *mbuf ) );
+
+       mbuf->tp_buf = (void *) malloc( sizeof( char ) * 1024 );                // add a dummy header/payload
+       memset( mbuf->tp_buf, 0, sizeof( char ) * 1024 );
 
-       mbuf->payload = (void *) malloc( sizeof( char ) * 1024 );               // add a dummy payload
-       mbuf->tp_buf = mbuf->payload;
-       mbuf->header = mbuf->payload;
+       mbuf->header = mbuf->tp_buf;
        mbuf->alloc_len = 1024;
+       mbuf->payload = PAYLOAD_ADDR( mbuf->header );
+       hdr = (rmr_mbuf_t *) mbuf->header;
+       mbuf->xaction = hdr->xid;
+
+
+
 
        // --- test payload field  access functions ---------------------------------------------------
        memset( src_buf, 0, sizeof( src_buf ) );
@@ -147,6 +159,8 @@ int mbuf_api_test( ) {
 
 
        // --- test transaction field  access functions ---------------------------------------------------
+       snprintf( src_buf, sizeof( src_buf ), "xaction-test##################." );              // full 32 bytes
+
        errno = 0;
        i = rmr_bytes2xact( NULL, src_buf, RMR_MAX_XID );
        errors += fail_if( errno == 0, "(errno) attempt to copy bytes to xact with nil message" );
@@ -167,7 +181,32 @@ int mbuf_api_test( ) {
        errors += fail_if( errno != 0, "copy bytes to xact; expected errno to be ok" );
        errors += fail_if( i != RMR_MAX_XID, "copy bytes to xact; expected return value to be max xact len" );
 
-
+       errno = 0;
+       ptr = rmr_get_xact( NULL, NULL );
+       errors += fail_if( errno == 0, "get xaction with nil msg did not set errno" );
+       errors += fail_not_nil( ptr, "get xaction with nil msg did not return a nil pointer" );
+       
+       errno = 999;
+       ptr = rmr_get_xact( mbuf, NULL );
+       errors += fail_if( errno == 999, "get xaction with valid msg and nil dest didn't clear errno" );
+       errors += fail_not_equal( errno, 0, "get xaction with valid msg and nil dest set errno (a)" );
+       errors += fail_if_nil( ptr, "get xaction with valid msg  and nil dest did not return a valid pointer" );
+       if( ptr ) {
+               i = strcmp( ptr, src_buf );
+               errors += fail_not_equal( i, 0, "get xaction did not fetch expected string cmp return (a) was not 0" );
+               free( ptr );
+       }
+       
+       errno = 999;
+       ptr = rmr_get_xact( mbuf, dest_buf );
+       errors += fail_if( errno == 999, "get xaction with valid msg and nil dest didn't clear errno" );
+       errors += fail_not_equal( errno, 0, "get xaction with valid msg and nil dest set errno (a)" );
+       errors += fail_if_nil( ptr, "get xaction with valid msg  and valid dest did not return a valid pointer" );
+       errors += fail_if( ptr != dest_buf, "get xaction did not return pointer to dest string" );
+       if( ptr == dest_buf ) {
+               i = strcmp( ptr, src_buf );
+               errors += fail_not_equal( i, 0, "get xaction into dest string did not fetch expected string cmp return (a) was not 0" );
+       }
 
        errno = 0;
        snprintf( src_buf, sizeof( src_buf ), "xact-fits" );