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).
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" )
rmr_get_srcip.3
rmr_trace_ref.3
rmr_set_stimeout.3
+ rmr_get_xact.3
)
# initialise lists of files we generated
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 );
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
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),
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_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),
--- /dev/null
+.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
+
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),
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 );
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
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;
}
hdr = (uta_mhdr_t *) mbuf->header;
- memcpy( dest, hdr->meid, RMR_MAX_XID );
+ memcpy( dest, hdr->meid, RMR_MAX_MEID );
return dest;
}
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 ) );
// --- 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" );
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" );