From 4ac73e3b9c0ff7aef80ad45f1bfead52bb2ffc99 Mon Sep 17 00:00:00 2001 From: "E. Scott Daniels" Date: Tue, 13 Aug 2019 11:35:04 -0400 Subject: [PATCH] Add rmr_get_xact function 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 Change-Id: I303478df3e9558740b2c193c99416c2dfa9b9475 --- CHANGES | 4 ++ CMakeLists.txt | 4 +- doc/CMakeLists.txt | 1 + doc/src/library/.gitignore | 1 + doc/src/library/api_qref.im | 12 +++++ doc/src/man/rmr.7.xfm | 2 + doc/src/man/rmr_bytes2xact.3.xfm | 2 + doc/src/man/rmr_get_meid.3.xfm | 1 + doc/src/man/rmr_get_xact.3.xfm | 102 +++++++++++++++++++++++++++++++++++++++ doc/src/man/rmr_str2xact.3.xfm | 2 + src/rmr/common/include/rmr.h | 1 + src/rmr/common/src/mbuf_api.c | 37 +++++++++++++- test/mbuf_api_static_test.c | 47 ++++++++++++++++-- 13 files changed, 209 insertions(+), 7 deletions(-) create mode 100644 doc/src/man/rmr_get_xact.3.xfm diff --git a/CHANGES b/CHANGES index 3e1ae6d..8c54566 100644 --- 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). diff --git a/CMakeLists.txt b/CMakeLists.txt index e9b68f3..2c95159 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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" ) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index fe59f5e..77cea9b 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -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 diff --git a/doc/src/library/.gitignore b/doc/src/library/.gitignore index 28155e7..a474f3f 100644 --- a/doc/src/library/.gitignore +++ b/doc/src/library/.gitignore @@ -7,3 +7,4 @@ *.rst *.md *.toc +*.sp diff --git a/doc/src/library/api_qref.im b/doc/src/library/api_qref.im index 0f305fb..ba23054 100644 --- a/doc/src/library/api_qref.im +++ b/doc/src/library/api_qref.im @@ -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 diff --git a/doc/src/man/rmr.7.xfm b/doc/src/man/rmr.7.xfm index 1c973c6..5de226f 100644 --- a/doc/src/man/rmr.7.xfm +++ b/doc/src/man/rmr.7.xfm @@ -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), diff --git a/doc/src/man/rmr_bytes2xact.3.xfm b/doc/src/man/rmr_bytes2xact.3.xfm index 97fb5a3..2f62a5f 100644 --- a/doc/src/man/rmr_bytes2xact.3.xfm +++ b/doc/src/man/rmr_bytes2xact.3.xfm @@ -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), diff --git a/doc/src/man/rmr_get_meid.3.xfm b/doc/src/man/rmr_get_meid.3.xfm index 939a372..bcf7ce0 100644 --- a/doc/src/man/rmr_get_meid.3.xfm +++ b/doc/src/man/rmr_get_meid.3.xfm @@ -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 index 0000000..cb924a5 --- /dev/null +++ b/doc/src/man/rmr_get_xact.3.xfm @@ -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 + +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 + diff --git a/doc/src/man/rmr_str2xact.3.xfm b/doc/src/man/rmr_str2xact.3.xfm index 6bc40d0..06ec74d 100644 --- a/doc/src/man/rmr_str2xact.3.xfm +++ b/doc/src/man/rmr_str2xact.3.xfm @@ -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), diff --git a/src/rmr/common/include/rmr.h b/src/rmr/common/include/rmr.h index 5802cc6..d43d3ba 100644 --- a/src/rmr/common/include/rmr.h +++ b/src/rmr/common/include/rmr.h @@ -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 ); diff --git a/src/rmr/common/src/mbuf_api.c b/src/rmr/common/src/mbuf_api.c index 1074e37..e88ab23 100644 --- a/src/rmr/common/src/mbuf_api.c +++ b/src/rmr/common/src/mbuf_api.c @@ -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; } diff --git a/test/mbuf_api_static_test.c b/test/mbuf_api_static_test.c index 2482f0c..1ee2858 100644 --- a/test/mbuf_api_static_test.c +++ b/test/mbuf_api_static_test.c @@ -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" ); -- 2.16.6