From: E. Scott Daniels Date: Wed, 29 Apr 2020 14:07:53 +0000 (-0400) Subject: Phase 2 of image generation prep X-Git-Tag: 1.0.3~4 X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=commitdiff_plain;h=f7b9695ecc2b3ec3fff0af300f0588ead4b7ba0f;p=ric-app%2Fts.git Phase 2 of image generation prep This change: - deletes some of the unnecessary framework files which were imported at repo create time. - adds docs for RTD - Adds CMake files to build (easier for CI) - Tweaks the docker file to build using cmake Issue-ID: RIC-349 Signed-off-by: E. Scott Daniels Change-Id: I94202642764d4b4c0c3555a37dc8b36f4c009f3f --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bf365a8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.build/ +*- +*~ diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..d0d12e3 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,21 @@ +--- +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details +# Required +version: 2 + +formats: + - htmlzip + +build: + image: latest + +python: + version: 3.7 + install: + - requirements: docs/requirements-docs.txt + +sphinx: + configuration: docs/conf.py + diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e65e5f..63a70b5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,7 @@ #================================================================================== -# Copyright (c) 2019 Nokia -# Copyright (c) 2018-2019 AT&T Intellectual Property. +# Copyright (c) 2020 AT&T Intellectual Property. # -# Licensed under the Apache License, Version 2.0 (the "License"); +# 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 # @@ -19,26 +18,26 @@ # This CMake definition supports several -D command line options: # # -DDEBUG=n Enable debugging level n -# -DDEV_PKG=1 Development package configuration -# -DBUILD_DOC=1 Man pages generated -# -DPRESERVE_PTYPE=1 Do not change the processor type when naming deb packages # -DGPROF=1 Enable profiling compile time flags -# -DMAN_PREFIX= Supply a path where man pages are installed (default: /usr/share/man) +# +# Building the binaries in this project should be as easy as running the +# following command in this directory: +# rm -fr .build +# make .build +# cd .build +# cmake .. [-DGPROF=1] [-DDEBUG=1] +# make test [install] ARGS=-V +# project( ricxfcpp ) -cmake_minimum_required( VERSION 3.5 ) +cmake_minimum_required( VERSION 3.14 ) -set( major_version "0" ) # 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 "2" ) +set( major_version "1" ) # until CI supports auto tagging; must hard set +set( minor_version "0" ) +set( patch_level "0" ) set( install_root "${CMAKE_INSTALL_PREFIX}" ) -set( install_inc "include/ricxfcpp" ) -if( MAN_PREFIX ) - set( install_man ${MAN_PREFIX} ) # is there a cmake var for this -- can't find one -else() - set( install_man "/usr/share/man" ) # this needs to be fixed so it's not hard coded -endif() +set( install_inc "/usr/local/include" ) # Must use GNUInstallDirs to install libraries into correct # locations on all platforms. @@ -52,37 +51,6 @@ if( NOT CMAKE_INSTALL_LIBDIR ) endif() set( install_lib "${CMAKE_INSTALL_LIBDIR}" ) -message( "+++ ricxfcpp library install target directory: ${install_lib}" ) - -# ---------------- extract some things from git ------------------------------ - -# commit id for the version string -execute_process( - COMMAND bash -c "git rev-parse --short HEAD|awk '{printf\"%s\", $0}'" - OUTPUT_VARIABLE git_id -) - -# version information for library names and version string -execute_process( - COMMAND bash -c "git describe --tags --abbrev=0 HEAD 2>/dev/null | awk -v tag=0.0.4095 ' { tag=$1 } END{ print tag suffix }'|sed 's/\\./;/g' " - OUTPUT_VARIABLE mmp_version_str - ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE -) -message( "+++ mmp version from tag: '${mmp_version_str}'" ) - -# extra indicator to show that the build was based on modified file(s) and not the true commit -# (no hope of reproducing the exact library for debugging). Used only for the internal version -# string. -execute_process( - COMMAND bash -c "git diff --shortstat|awk -v fmt=%s -v r=-rotten '{ s=r } END { printf( fmt, s ) }'" - OUTPUT_VARIABLE spoiled_str -) - -# uncomment these lines once CI starts adding a tag on merge -#set( mmp_version ${mmp_version_str} ) -#list( GET mmp_version 0 major_version ) -#list( GET mmp_version 1 minor_version ) -#list( GET mmp_version 2 patch_level ) if( DEBUG ) # if set, we'll set debugging on in the compile set( debugging ${DEBUG} ) @@ -94,6 +62,14 @@ endif() unset( DEBUG CACHE ) # we don't want this to persist +# ---------------- extract some things from git ------------------------------ + +# commit id for the version string +execute_process( + COMMAND bash -c "git rev-parse --short HEAD|awk '{printf\"%s\", $0}'" + OUTPUT_VARIABLE git_id +) + # define constants used in the version string, debugging, etc. add_definitions( -DGIT_ID=${git_id} @@ -103,101 +79,23 @@ add_definitions( -DDEBUG=${debugging} ) -# ---------------- suss out pkg gen tools so we don't fail generating packages that the system cannot support -------------- - -# deb packages use underbars, and package manager(s) seem to flip the *_64 processor type -# to the old (non-standard) amd64 string, so we do it here for consistency. Set -DPRESERVE_PTYPE=1 -# to prevent the flip. RPM packages will always be given the system generated processor type string. -# -if( ${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64" ) - if( NOT PRESERVE_PTYPE ) - set( deb_sys_name "amd64" ) - else() - set( deb_sys_name ${CMAKE_SYSTEM_PROCESSOR} ) - endif() -else() - set( deb_sys_name ${CMAKE_SYSTEM_PROCESSOR} ) -endif() -unset( PRESERVE_PTYPE CACHE ) # we don't want this to persist - -set( rpm_sys_name ${CMAKE_SYSTEM_PROCESSOR} ) - -if( DEV_PKG ) - set( deb_pkg_name "ricxfcpp-dev" ) - set( rpm_pkg_name "ricxfcpp-devel" ) -else() - set( deb_pkg_name "ricxfcpp" ) - set( rpm_pkg_name "ricxfcpp" ) -endif() - -set( pkg_label "ricxfcpp${spoiled_str}-${major_version}.${minor_version}.${patch_level}-${sys_name}" ) -set( rpm_pkg_label "${rpm_pkg_name}${spoiled_str}-${major_version}.${minor_version}.${patch_level}-${rpm_sys_name}" ) -set( deb_pkg_label "${deb_pkg_name}${spoiled_str}_${major_version}.${minor_version}.${patch_level}_${deb_sys_name}" ) -message( "+++ pkg name: ${deb_pkg_label}.deb" ) - -set( gen_rpm 0 ) -find_program( rpm NAMES rpmbuild ) # rpm package gen requires this to be installed -if( "${rpm}" MATCHES "rpm-NOTFOUND" ) # cannot build rpm - set( pkg_list "DEB" ) - message( "### make package will generate only deb package; cannot find support to generate rpm packages" ) -else() - message( "+++ pkg name: ${rpm_pkg_label}.rpm" ) # debugging if we think we can gen rpm too - set( pkg_list "DEB;RPM" ) - set( gen_rpm 1 ) - message( "+++ make package will generate both deb and rpm packages" ) -endif() - - - -# this gets us round a chicken/egg problem. include files don't exist until make is run -# but Cmake insists on having these exist when we add them to include directories to -# enable code to find them after we build them. -# -include_directories( "${CMAKE_CURRENT_SOURCE_DIR}/src/messaging" ) - - # Compiler flags # set( CMAKE_POSITION_INDEPENDENT_CODE ON ) -set( CMAKE_C_FLAGS "-g " ) -set( CMAKE_CPP_FLAGS "-g " ) if( GPROF ) # if set, we'll set profiling flag on compiles message( "+++ profiling is on" ) set( CMAKE_C_FLAGS "-pg " ) set( CMAKE_CPP_FLAGS "-pg " ) else() + set( CMAKE_C_FLAGS "-g " ) + set( CMAKE_CPP_FLAGS "-g " ) message( "+++ profiling is off" ) endif() -unset( GPROF CACHE ) # we don't want this to persist - -# Include modules -add_subdirectory( src/messaging ) -add_subdirectory( src/xapp ) -#add_subdirectory( doc ) # this will auto skip if {X}fm is not available - +unset( GPROF CACHE ) # ensure this does not persist -# shared and static libraries are built from the same object files. -# -add_library( ricxfcpp_shared SHARED "$;$" ) -set_target_properties( ricxfcpp_shared - PROPERTIES - OUTPUT_NAME "ricxfcpp" - SOVERSION ${major_version} - VERSION ${major_version}.${minor_version}.${patch_level} -) -target_include_directories( ricxfcpp_shared PUBLIC "src/messenger" "src/xapp" ) +# each binary is built from a subset +add_subdirectory( src/ts_xapp ) -# we only build/export the static archive (.a) if generating a dev package -if( DEV_PKG ) - add_library( ricxfcpp_static STATIC "$;$" ) - set_target_properties( ricxfcpp_static - PROPERTIES - OUTPUT_NAME "ricxfcpp" - SOVERSION ${major_version} - VERSION ${major_version}.${minor_version}.${patch_level} - ) - target_include_directories( ricxfcpp_static PUBLIC "src/messenger" "src/xapp" ) -endif() # -------- unit testing ------------------------------------------------------- enable_testing() @@ -206,60 +104,3 @@ add_test( COMMAND bash ../test/unit_test.sh -q WORKING_DIRECTORY ../test ) - - -# ------------- packaging ----------------------------------------------------- - -# Define what should be installed, and where they should go. For dev package we install -# only the RMr headers, man pages and archive (.a) files. The run-time package gets just -# the library (.so) files and nothing more. -# -if( DEV_PKG ) - set( target_list "ricxfcpp_static" ) -else() - set( target_list "ricxfcpp_shared" ) -endif() - -install( TARGETS ${target_list} EXPORT LibraryConfig - LIBRARY DESTINATION ${install_lib} - ARCHIVE DESTINATION ${install_lib} - PUBLIC_HEADER DESTINATION ${install_inc} -) - -unset( DEV_PKG CACHE ) # prevent from being a hidden setting if user redoes things - -IF( EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake" ) - include( InstallRequiredSystemLibraries ) - - set( CPACK_DEBIAN_PACKAGE_NAME ${deb_pkg_name} ) - set( CPACK_RPM_PACKAGE_NAME ${rpm_pkg_name} ) - - set( CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/usr/local;/usr/local/bin;/usr/local/include;/usr/local/share;/usr/local/lib" ) - - set( CPACK_set_DESTDIR "on" ) - set( CPACK_PACKAGING_INSTALL_PREFIX "${install_root}" ) - set( CPACK_GENERATOR "${pkg_list}" ) - - set( CPACK_PACKAGE_DESCRIPTION "C++ framework for RIC xAPPs based on RMR." ) - set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "RIC xAPP C++ framework library" ) - set( CPACK_PACKAGE_VENDOR "None" ) - set( CPACK_PACKAGE_CONTACT "None" ) - set( CPACK_PACKAGE_VERSION_MAJOR "${major_version}" ) - set( CPACK_PACKAGE_VERSION_MINOR "${minor_version}" ) - set( CPACK_PACKAGE_VERSION_PATCH "${patch_level}" ) - set( CPACK_PACKAGE "${pkg_label}" ) # generic name for old versions of cpack - set( CPACK_DEBIAN_FILE_NAME "${deb_pkg_label}.deb" ) - set( CPACK_RPM_FILE_NAME "${rpm_pkg_label}.rpm" ) - - # Future: define dependencies on RMR and other libs - - set( CPACK_DEBIAN_PACKAGE_PRIORITY "optional" ) - set( CPACK_DEBIAN_PACKAGE_SECTION "ric" ) - set( CPACK_DEBIAN_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR} ) - set( CPACK_RPM_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR} ) - - # this seems ingnored if included - #set( CPACK_COMPONENTS_ALL Libraries ApplicationData ) - - INCLUDE( CPack ) -ENDIF() diff --git a/Dockerfile b/Dockerfile index 1e29e25..1260ecd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,10 +29,9 @@ # Author: E. Scott Daniels # -------------------------------------------------------------------------------------- -# nexus seems to use ports rather than adding release, prod, staging to the url :( # the builder has: git, wget, cmake, gcc/g++, make, python2/3. v7 dropped nng support # -FROM nexus3.o-ran-sc.org:10004/bldr-ubuntu18-c-go:7-u18.04 as buildenv +FROM nexus3.o-ran-sc.org:10004/o-ran-sc/bldr-ubuntu18-c-go:8-u18.04 as buildenv # spaces to save things in the build image to copy to final image RUN mkdir -p /playpen/assets /playpen/src /playpen/bin @@ -68,11 +67,15 @@ RUN wget -nv --content-disposition ${PC_STG_URL}/sdl_${SDL_VER}-1_amd64.deb/down # -# build and install the application +# build and install the application(s) # -COPY examples/* /playpen/src/ -RUN cd /playpen/src && make && make install - +COPY . /playpen/src/ +RUN cd /playpen/src && \ + rm -fr .build &&\ + mkdir .build && \ + cd .build && \ + cmake .. && \ + make install # non-programme things that we need to push to final image # @@ -110,9 +113,9 @@ WORKDIR /data COPY --from=buildenv /playpen/assets/* /data # if needed, set RMR vars -#ENV RMR_RTG_SVC=rm-host:port -#ENV RMR_VCTL_FILE=/tmp/rmr.v ENV RMR_SEED_RT=/data/bootstrap.rt +#ENV RMR_RTG_SVC=rm-host:port +ENV RMR_VCTL_FILE=/tmp/rmr.v +RUN echo "2" >/tmp/rmr.v -#CMD [ "ts_xapp_start.sh" ] CMD [ "/usr/local/bin/ts_xapp" ] diff --git a/build_rmr.sh b/build_rmr.sh deleted file mode 100755 index 905a15d..0000000 --- a/build_rmr.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env ksh - -# Mnemonic: rmr_build.sh -# Abstract: This will pull RMR from the repo, build and install. This -# is en lieu of using wget to fetch the RMR package from some -# repo and installing it. The package method is preferred -# but if that breaks this can be used in place of it. - -rmr_ver=${1:-3.6.2} - -# assume that we're in the proper directory -set -e -git clone "https://gerrit.o-ran-sc.org/r/ric-plt/lib/rmr" - -cd rmr -git checkout $ver -mkdir .build -cd .build -cmake .. -DDEV_PKG=1 -DPACK_EXTERNALS=1 -make install -cmake .. -DDEV_PKG=0 -make install - diff --git a/container-tag.yaml b/container-tag.yaml new file mode 100644 index 0000000..f04677f --- /dev/null +++ b/container-tag.yaml @@ -0,0 +1,3 @@ +# this is used by CI jobs to apply a tag when it builds the image +--- +tag: '1.0.0' diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 0000000..89d0765 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,2 @@ +/_build +/out diff --git a/docs/_static/logo.png b/docs/_static/logo.png new file mode 100644 index 0000000..c3b6ce5 Binary files /dev/null and b/docs/_static/logo.png differ diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..922e22f --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,6 @@ +from docs_conf.conf import * +linkcheck_ignore = [ + 'http://localhost.*', + 'http://127.0.0.1.*', + 'https://gerrit.o-ran-sc.org.*' +] diff --git a/docs/conf.yaml b/docs/conf.yaml new file mode 100644 index 0000000..1fcb96e --- /dev/null +++ b/docs/conf.yaml @@ -0,0 +1,3 @@ +--- +project_cfg: oran +project: ric-app-ts diff --git a/docs/favicon.ico b/docs/favicon.ico new file mode 100644 index 0000000..00b0fd0 Binary files /dev/null and b/docs/favicon.ico differ diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..b7d4ad6 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,20 @@ + +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. SPDX-License-Identifier: CC-BY-4.0 + +Traffic Steering xAPP +===================== + +.. toctree:: + :maxdepth: 1 + :caption: Documents: + + user-guide.rst + +.. toctree:: + :maxdepth: 1 + :caption: Misc: + + rel-notes.rst + +* :ref:`search` diff --git a/docs/rel-notes.rst b/docs/rel-notes.rst new file mode 100644 index 0000000..2c0d29b --- /dev/null +++ b/docs/rel-notes.rst @@ -0,0 +1,16 @@ + +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. SPDX-License-Identifier: CC-BY-4.0 + +.. CAUTION: this document is generated from source in doc/src/rtd. +.. To make changes edit the source and recompile the document. +.. Do NOT make changes directly to .rst or .md files. + +Traffic Steering xAPP +===================== + +2020 April 28 Version 1.0.0 +---------------------------- + + Initial release. + diff --git a/docs/requirements-docs.txt b/docs/requirements-docs.txt new file mode 100644 index 0000000..09a0c1c --- /dev/null +++ b/docs/requirements-docs.txt @@ -0,0 +1,5 @@ +sphinx +sphinx-rtd-theme +sphinxcontrib-httpdomain +recommonmark +lfdocs-conf diff --git a/docs/user-guide.rst b/docs/user-guide.rst new file mode 100644 index 0000000..68ceddf --- /dev/null +++ b/docs/user-guide.rst @@ -0,0 +1,21 @@ + + +.. This work is licensed under a Creative Commons Attribution 4.0 International License. +.. SPDX-License-Identifier: CC-BY-4.0 +.. +.. CAUTION: this document is generated from source in doc/src/* +.. To make changes edit the source and recompile the document. +.. Do NOT make changes directly to .rst or .md files. + + +============ +User's Guide +============ +--------------------- +Traffic Steering xAPP +--------------------- + +Introduction +============ + +Some text about the traffic steering xAPP will eventually be added here. diff --git a/src/messaging/README b/src/messaging/README deleted file mode 100644 index 0683082..0000000 --- a/src/messaging/README +++ /dev/null @@ -1,47 +0,0 @@ - -================================================================================== - Copyright (c) 2020 Nokia - Copyright (c) 2020 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. -================================================================================== - -This directory contains the source for the RMR messaging portion of the -framework. Specifially: - - message.* - provides a message class from which the user can extract/set information - (type, subscription ID, payload, etc.) and provides instance funcitons - for sending and replying to the message. User programmes will interact - directly with this. - - msg_component.* - This is a small type def that allows some of the getter functions in message - to return a smart pointer to memory which cannot directly be released (e.g - the payload). This allows the user programme to declare a variable of type - Msg_component (which is really a smart pointer with a custom deleter) rather - than having to understand the needed smart pointer construct for these things. - - messenger.* - This class provides the direct "wrapper" on top of RMR. It supports - high level operations such as Listen and callback management. - - callback.* - This provides the callback support to messenger (listen) functions. - - default_cb.* - This module contains any default callback functions which are provided - by the framework (e.g. health check processing). - - - diff --git a/src/messaging/callback.cpp b/src/messaging/callback.cpp deleted file mode 100644 index d4d697d..0000000 --- a/src/messaging/callback.cpp +++ /dev/null @@ -1,58 +0,0 @@ -// vi: ts=4 sw=4 noet: -/* -================================================================================== - Copyright (c) 2020 Nokia - Copyright (c) 2020 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. -================================================================================== -*/ - -/* - Mnemonic: callback.cpp - Abstract: Function defs for the callback managment object - Date: 9 March 2020 - Author: E. Scott Daniels -*/ - -#include - -#include - -#include "message.hpp" -//class Messenger; - - -/* - Builder. -*/ -Callback::Callback( user_callback ufun, void* data ) { // builder - user_fun = ufun; - udata = data; -} - -/* - there is nothing to be done from a destruction perspective, so no - destruction function needed at the moment. -*/ - -/* - Drive_cb will invoke the callback and pass along the stuff passed here. -*/ -void Callback::Drive_cb( Message& m ) { - if( user_fun != NULL ) { - user_fun( m, m.Get_mtype(), m.Get_subid(), m.Get_len(), m.Get_payload(), udata ); - } -} - - diff --git a/src/messaging/callback.hpp b/src/messaging/callback.hpp deleted file mode 100644 index b8e9dfa..0000000 --- a/src/messaging/callback.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// vi: ts=4 sw=4 noet: -/* -================================================================================== - Copyright (c) 2020 Nokia - Copyright (c) 2020 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. -================================================================================== -*/ - -/* - Mnemonic: callback.hpp - Abstract: class description for a callback managment object. - Date: 9 March 2020 - Author: E. Scott Daniels -*/ - - -#ifndef _CALLBACK_HPP -#define _CALLBACK_HPP - -#include - -class Messenger; -class Message; -#include "message.hpp" - -typedef void(*user_callback)( Message& m, int mtype, int subid, int payload_len, Msg_component payload, void* usr_data ); - -class Callback { - - private: - user_callback user_fun; - void* udata; // user data - - public: - Callback( user_callback, void* data ); // builder - void Drive_cb( Message& m ); // invoker -}; - - -#endif diff --git a/src/messaging/default_cb.cpp b/src/messaging/default_cb.cpp deleted file mode 100644 index 1083293..0000000 --- a/src/messaging/default_cb.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// vi: ts=4 sw=4 noet: -/* -================================================================================== - Copyright (c) 2020 Nokia - Copyright (c) 2020 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. -================================================================================== -*/ - -/* - Mnemonic: default_cb.cpp - Abstract: This is a set of static functions that are used as - the default Messenger callbacks. - - Date: 11 Mar 2020 - Author: E. Scott Daniels -*/ - -#include -#include - -#include -#include - - -#include - -#include "messenger.hpp" - -/* - This is the default health check function that we provide (user - may override it). It will respond to health check messages by - sending an OK back to the source. - - The mr paramter is obviously ignored, but to add this as a callback - the function sig must match. -*/ -void Health_ck_cb( Message& mbuf, int mtype, int sid, int len, Msg_component payload, void* data ) { - unsigned char response[128]; - - snprintf( (char* ) response, sizeof( response ), "OK\n" ); - mbuf.Send_response( RIC_HEALTH_CHECK_RESP, sid, strlen( (char *) response )+1, response ); -} diff --git a/src/messaging/default_cb.hpp b/src/messaging/default_cb.hpp deleted file mode 100644 index 2e96003..0000000 --- a/src/messaging/default_cb.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// vi: ts=4 sw=4 noet: -/* -================================================================================== - Copyright (c) 2020 Nokia - Copyright (c) 2020 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. -================================================================================== -*/ - -/* - Mnemonic: default_cb.hpp - Abstract: Headers/prototypes for the default callbacks. The - default callbacks are those which we install when - the messenger is created and handles things that - the application might not want to (e.g. health check). - - Date: 11 March 2020 - Author: E. Scott Daniels -*/ - -#ifndef _DEF_CB_H -#define _DEF_CB_H - - -void Health_ck_cb( Message& mbuf, int mtype, int sid, int len, Msg_component payload, void* data ); - - -#endif diff --git a/src/messaging/message.cpp b/src/messaging/message.cpp deleted file mode 100644 index 30a0fbc..0000000 --- a/src/messaging/message.cpp +++ /dev/null @@ -1,419 +0,0 @@ -// vi: ts=4 sw=4 noet: -/* -================================================================================== - Copyright (c) 2020 Nokia - Copyright (c) 2020 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. -================================================================================== -*/ - -/* - Mnemonic: message.cpp - Abstract: A message wrapper. This should completely hide the - underlying transport (RMR) message structure from - the user application. For the most part, the getters - are used by the framwork; it is unlikely that other - than adding/extracting the MEID, the user app will - be completely unaware of information that is not - presented in the callback parms. - - Date: 12 March 2020 - Author: E. Scott Daniels -*/ - -#include -#include - -#include - -#include - -#include "message.hpp" - -// --------------- private ------------------------------------------------ - -// --------------- builders/operators ------------------------------------- - -/* - Create a new message wrapper for an existing RMR msg buffer. -*/ -Message::Message( rmr_mbuf_t* mbuf, void* mrc ) { - this->mrc = mrc; // the message router context for sends - this->mbuf = mbuf; -} - -Message::Message( void* mrc, int payload_len ) { - this->mrc = mrc; - this->mbuf = rmr_alloc_msg( mrc, payload_len ); -} - -/* - Copy builder. Given a source object instance (soi), create a copy. - Creating a copy should be avoided as it can be SLOW! -*/ -Message::Message( const Message& soi ) { - int payload_size; - - mrc = soi.mrc; - payload_size = rmr_payload_size( soi.mbuf ); // rmr can handle a nil pointer - mbuf = rmr_realloc_payload( soi.mbuf, payload_size, RMR_COPY, RMR_CLONE ); -} - -/* - Assignment operator. Simiolar to the copycat, but "this" object exists and - may have data that needs to be released prior to making a copy of the soi. -*/ -Message& Message::operator=( const Message& soi ) { - int payload_size; - - if( this != &soi ) { // cannot do self assignment - if( mbuf != NULL ) { - rmr_free_msg( mbuf ); // release the old one so we don't leak - } - - payload_size = rmr_payload_size( soi.mbuf ); // rmr can handle a nil pointer - mrc = soi.mrc; - mbuf = rmr_realloc_payload( soi.mbuf, payload_size, RMR_COPY, RMR_CLONE ); - } - - return *this; -} - -/* - Move builder. Given a source object instance (soi), move the information from - the soi ensuring that the destriction of the soi doesn't trash things from - under us. -*/ -Message::Message( Message&& soi ) { - mrc = soi.mrc; - mbuf = soi.mbuf; - - soi.mrc = NULL; // prevent closing of RMR stuff on soi destroy - soi.mbuf = NULL; -} - -/* - Move Assignment operator. Move the message data to the existing object - ensure the object reference is cleaned up, and ensuring that the source - object references are removed. -*/ -Message& Message::operator=( Message&& soi ) { - if( this != &soi ) { // cannot do self assignment - if( mbuf != NULL ) { - rmr_free_msg( mbuf ); // release the old one so we don't leak - } - - mrc = soi.mrc; - mbuf = soi.mbuf; - - soi.mrc = NULL; - soi.mbuf = NULL; - } - - return *this; -} - - -/* - Destroyer. -*/ -Message::~Message() { - if( mbuf != NULL ) { - rmr_free_msg( mbuf ); - } - - mbuf = NULL; -} - - -// --- getters/setters ----------------------------------------------------- -/* - Copy the payload bytes, and return a smart pointer (unique) to it. - If the application needs to update the payload in place for a return - to sender call, or just to access the payload in a more efficent manner - (without the copy), the Get_payload() function should be considered. - - This function will return a NULL pointer if malloc fails. -*/ -//char* Message::Copy_payload( ){ -std::unique_ptr Message::Copy_payload( ){ - unsigned char* new_payload = NULL; - - if( mbuf != NULL ) { - new_payload = (unsigned char *) malloc( sizeof( unsigned char ) * mbuf->len ); - memcpy( new_payload, mbuf->payload, mbuf->len ); - } - - return std::unique_ptr( new_payload ); -} - -/* - Makes a copy of the MEID and returns a smart pointer to it. -*/ -std::unique_ptr Message::Get_meid(){ - unsigned char* m = NULL; - - m = (unsigned char *) malloc( sizeof( unsigned char ) * RMR_MAX_MEID ); - rmr_get_meid( mbuf, m ); - - return std::unique_ptr( m ); -} - -/* - Return the total size of the payload (the amount that can be written to - as opposed to the portion of the payload which is currently in use. - If mbuf isn't valid (nil, or message has a broken header) the return - will be -1. -*/ -int Message::Get_available_size(){ - return rmr_payload_size( mbuf ); // rmr can handle a nil pointer -} - -int Message::Get_mtype(){ - int rval = INVALID_MTYPE; - - if( mbuf != NULL ) { - rval = mbuf->mtype; - } - - return rval; -} - -/* - Makes a copy of the source field and returns a smart pointer to it. -*/ -std::unique_ptr Message::Get_src(){ - unsigned char* m = NULL; - - m = (unsigned char *) malloc( sizeof( unsigned char ) * RMR_MAX_SRC ); - memset( m, 0, sizeof( unsigned char ) * RMR_MAX_SRC ); - - if( m != NULL ) { - rmr_get_src( mbuf, m ); - } - - return std::unique_ptr( m ); -} - -int Message::Get_state( ){ - int state = INVALID_STATUS; - - if( mbuf != NULL ) { - state = mbuf->state; - } - - return state; -} - -int Message::Get_subid(){ - int rval = INVALID_SUBID; - - if( mbuf != NULL ) { - rval =mbuf->sub_id; - } - - return rval; -} - -/* - Return the amount of the payload (bytes) which is used. See - Get_available_size() to get the total usable space in the payload. -*/ -int Message::Get_len(){ - int rval = 0; - - if( mbuf != NULL ) { - rval = mbuf->len; - } - - return rval; -} - -/* - This returns a smart (unique) pointer to the payload portion of the - message. This provides the user application with the means to - update the payload in place to avoid multiple copies. The - user programme is responsible to determing the usable payload - length by calling Message:Get_available_size(), and ensuring that - writing beyond the indicated size does not happen. -*/ -Msg_component Message::Get_payload(){ - if( mbuf != NULL ) { - return std::unique_ptr( mbuf->payload ); - } - - return NULL; -} - -void Message::Set_meid( std::shared_ptr new_meid ) { - if( mbuf != NULL ) { - rmr_str2meid( mbuf, (unsigned char *) new_meid.get() ); - } -} - -void Message::Set_mtype( int new_type ){ - if( mbuf != NULL ) { - mbuf->mtype = new_type; - } -} - -void Message::Set_len( int new_len ){ - if( mbuf != NULL && new_len >= 0 ) { - mbuf->len = new_len; - } -} - -void Message::Set_subid( int new_subid ){ - if( mbuf != NULL ) { - mbuf->sub_id = new_subid; - } -} - - -// -------------- send functions --------------------------------- - -/* - This assumes that the contents of the mbuf were set by either a send attempt that - failed with a retry and thus is ready to be processed by RMR. - Exposed to the user, but not expected to be frequently used. -*/ -bool Message::Send( ) { - bool state = false; - - if( mbuf != NULL ) { - mbuf = rmr_send_msg( mrc, mbuf ); // send and pick up new mbuf - state = mbuf->state == RMR_OK; // overall state for caller - } - - return state; -} - -/* - Similar to Send(), this assumes that the message is already set up and this is a retry. - Exposed to the user, but not expected to be frequently used. -*/ -bool Message::Reply( ) { - bool state = false; - - if( mbuf != NULL ) { - mbuf = rmr_rts_msg( mrc, mbuf ); // send and pick up new mbuf - state = mbuf->state == RMR_OK; // state for caller based on send - } - - return state; -} - -/* - Send workhorse. - This will setup the message (type etc.) ensure the message payload space is - large enough and copy in the payload (if a new payload is given), then will - either send or rts the message based on the stype parm. - - If payload is nil, then we assume the user updated the payload in place and - no copy is needed. - - This is public, but most users should use Send_msg or Send_response functions. -*/ -bool Message::Send( int mtype, int subid, int payload_len, unsigned char* payload, int stype ) { - bool state = false; - - if( mbuf != NULL ) { - if( mtype != NO_CHANGE ) { - mbuf->mtype = mtype; - } - if( subid != NO_CHANGE ) { - mbuf->sub_id = subid; - } - - if( payload_len != NO_CHANGE ) { - mbuf->len = payload_len; - } - - if( payload != NULL ) { // if we have a payload, ensure msg has room, realloc if needed, then copy - mbuf = rmr_realloc_payload( mbuf, payload_len, RMR_NO_COPY, RMR_NO_CLONE ); // ensure message is large enough - if( mbuf == NULL ) { - return false; - } - - memcpy( mbuf->payload, payload, mbuf->len ); - } - - if( stype == RESPONSE ) { - mbuf = rmr_rts_msg( mrc, mbuf ); - } else { - mbuf = rmr_send_msg( mrc, mbuf ); - } - - state = mbuf->state == RMR_OK; - } - - return state; -} - -/* - Send a response to the endpoint that sent the original message. - - Response can be null and the assumption will be that the message payload - was updated in place and no additional copy is needed before sending the message. - - The second form of the call allows for a stack allocated buffer (e.g. char foo[120]) to - be passed as the payload. -*/ -bool Message::Send_response( int mtype, int subid, int response_len, std::shared_ptr response ) { - return Send( mtype, subid, response_len, response.get(), RESPONSE ); -} - -bool Message::Send_response( int mtype, int subid, int response_len, unsigned char* response ) { - return Send( mtype, subid, response_len, response, RESPONSE ); -} - -/* - These allow a response message to be sent without changing the mtype/subid. -*/ -bool Message::Send_response( int response_len, std::shared_ptr response ) { - return Send( NO_CHANGE, NO_CHANGE, response_len, response.get(), RESPONSE ); -} - -bool Message::Send_response( int response_len, unsigned char* response ) { - return Send( NO_CHANGE, NO_CHANGE, response_len, response, RESPONSE ); -} - - -/* - Send a message based on message type routing. - - Payload can be null and the assumption will be that the message payload - was updated in place and no additional copy is needed before sending the message. - - Return is a new mbuf suitable for sending another message, or the original buffer with - a bad state sent if there was a failure. -*/ -bool Message::Send_msg( int mtype, int subid, int payload_len, std::shared_ptr payload ) { - return Send( mtype, subid, payload_len, payload.get(), MESSAGE ); -} - -bool Message::Send_msg( int mtype, int subid, int payload_len, unsigned char* payload ) { - return Send( mtype, subid, payload_len, payload, MESSAGE ); -} - -/* - Similar send functions that allow the message type/subid to remain unchanged -*/ -bool Message::Send_msg( int payload_len, std::shared_ptr payload ) { - return Send( NO_CHANGE, NO_CHANGE, payload_len, payload.get(), MESSAGE ); -} - -bool Message::Send_msg( int payload_len, unsigned char* payload ) { - return Send( NO_CHANGE, NO_CHANGE, payload_len, payload, MESSAGE ); -} diff --git a/src/messaging/message.hpp b/src/messaging/message.hpp deleted file mode 100644 index 0db0927..0000000 --- a/src/messaging/message.hpp +++ /dev/null @@ -1,110 +0,0 @@ -// vi: ts=4 sw=4 noet: -/* -================================================================================== - Copyright (c) 2020 Nokia - Copyright (c) 2020 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. -================================================================================== -*/ - -/* - Mnemonic: message.hpp - Abstract: Headers for the message class. - This class provides an interface to the user application - when information from the message is needed. - - Date: 10 March 2020 - Author: E. Scott Daniels -*/ - -#ifndef _MESSAGE_HPP -#define _MESSAGE_HPP - - -#include -#include - -#include - -#include "msg_component.hpp" -#include "callback.hpp" -#include "default_cb.hpp" - -#ifndef RMR_NO_CLONE - #define RMR_NO_CLONE 0 - #define RMR_NO_COPY 0 - #define RMR_CLONE 1 - #define RMR_COPY 1 -#endif - - -// ------------------------------------------------------------------------ - -class Message { - private: - rmr_mbuf_t* mbuf; // the underlying RMR message buffer - void* mrc; // message router context - std::shared_ptr psp; // shared pointer to the payload to give out - - public: - static const int NO_CHANGE = -99; // indicates no change to a send/reply parameter - static const int INVALID_MTYPE = -1; - static const int INVALID_STATUS = -1; - static const int INVALID_SUBID = -2; - static const int NO_SUBID = -1; // not all messages have a subid - - static const int RESPONSE = 0; // send types - static const int MESSAGE = 1; - - Message( rmr_mbuf_t* mbuf, void* mrc ); // builders - Message( void* mrc, int payload_len ); - Message( const Message& soi ); // copy cat - Message& operator=( const Message& soi ); // copy operator - Message( Message&& soi ); // mover - Message& operator=( Message&& soi ); // move operator - ~Message(); // destroyer - - std::unique_ptr Copy_payload( ); // copy the payload; deletable smart pointer - - std::unique_ptr Get_meid(); // returns a copy of the meid bytes - int Get_available_size(); - int Get_len(); - int Get_mtype(); - Msg_component Get_payload(); - std::unique_ptr Get_src(); - int Get_state( ); - int Get_subid(); - - void Set_meid( std::shared_ptr new_meid ); - void Set_mtype( int new_type ); - void Set_subid( int new_subid ); - void Set_len( int new_len ); - - bool Reply( ); - bool Send( ); - bool Send( int mtype, int subid, int payload_len, unsigned char* payload, int stype ); - - bool Send_msg( int mtype, int subid, int payload_len, std::shared_ptr payload ); - bool Send_msg( int mtype, int subid, int payload_len, unsigned char* payload ); - bool Send_msg( int payload_len, std::shared_ptr payload ); - bool Send_msg( int payload_len, unsigned char* payload ); - - bool Send_response( int mtype, int subid, int payload_len, std::shared_ptr response ); - bool Send_response( int mtype, int subid, int payload_len, unsigned char* response ); - bool Send_response( int payload_len, std::shared_ptr response ); - bool Send_response( int payload_len, unsigned char* response ); -}; - - -#endif diff --git a/src/messaging/messenger.cpp b/src/messaging/messenger.cpp deleted file mode 100644 index 24fe164..0000000 --- a/src/messaging/messenger.cpp +++ /dev/null @@ -1,279 +0,0 @@ -// vi: ts=4 sw=4 noet: -/* -================================================================================== - Copyright (c) 2020 Nokia - Copyright (c) 2020 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. -================================================================================== -*/ - -/* - Mnemonic: messenger.cpp - Abstract: Message Router Messenger. - - Date: 10 March 2020 - Author: E. Scott Daniels -*/ - -#include -#include - -#include -#include - - -#include -#include -#include -#include -#include - -#include "callback.hpp" -#include "default_cb.hpp" // default callback prototypes -#include "message.hpp" -#include "messenger.hpp" - - -// --------------- private ----------------------------------------------------- - - -// ---------------- C++ buggerd up way of maintining class constants ---------- -const int Messenger::MAX_PAYLOAD = (1024*64); -const int Messenger::DEFAULT_CALLBACK = -1; - -// --------------- builders ----------------------------------------------- -/* - If wait4table is true, then the construction of the object does not - complete until the underlying transport has a new copy of the route - table. - - If port is nil, then the default port is used (4560). -*/ -Messenger::Messenger( char* port, bool wait4table ) { - if( port == NULL ) { - port = (char *) "4560"; - } - - gate = new std::mutex(); - listen_port = strdup( port ); - mrc = rmr_init( listen_port, Messenger::MAX_PAYLOAD, 0 ); - - if( wait4table ) { - this->Wait_for_cts( 0 ); - } - - Add_msg_cb( RIC_HEALTH_CHECK_REQ, Health_ck_cb, NULL ); // add our default call backs - - ok_2_run = true; -} - -/* - Move support. We DO allow the instance to be moved as only one copy - remains following the move. - Given a source object instance (soi) we move the information to - the new object, and then DELETE what was moved so that when the - user frees the soi, it doesn't destroy what we snarfed. -*/ -Messenger::Messenger( Messenger&& soi ) { - mrc = soi.mrc; - listen_port = soi.listen_port; - ok_2_run = soi.ok_2_run; - gate = soi.gate; - cb_hash = soi.cb_hash; // this seems dodgy - - soi.gate = NULL; - soi.listen_port = NULL; - soi.mrc = NULL; -} - -/* - Move operator. Given a source object instance, movee it's contents - to this insance. We must first clean up this instance. -*/ -Messenger& Messenger::operator=( Messenger&& soi ) { - if( this != &soi ) { // cannot move onto ourself - if( mrc != NULL ) { - rmr_close( mrc ); - } - if( listen_port != NULL ) { - free( listen_port ); - } - - mrc = soi.mrc; - listen_port = soi.listen_port; - ok_2_run = soi.ok_2_run; - gate = soi.gate; - cb_hash = soi.cb_hash; // this seems dodgy - - soi.gate = NULL; - soi.listen_port = NULL; - soi.mrc = NULL; - } - - return *this; -} - -/* - Destroyer. -*/ -Messenger::~Messenger() { - if( mrc != NULL ) { - rmr_close( mrc ); - } - - if( listen_port != NULL ) { - free( listen_port ); - } -} - -/* - Allow user to register a callback function invoked when a specific type of - message is received. The user may pass an optional data pointer which - will be passed to the function when it is called. The function signature - must be: - void fun( Messenger* mr, rmr_mbuf_t* mbuf, void* data ); - - The user can also invoke this function to set the "default" callback by - passing Messenger::DEFAULT_CALLBACK as the mtype. If no other callback - is defined for a message type, the default callback function is invoked. - If a default is not provided, a non-matching message is silently dropped. -*/ -void Messenger::Add_msg_cb( int mtype, user_callback fun_name, void* data ) { - Callback* cb; - - cb = new Callback( fun_name, data ); - cb_hash[mtype] = cb; - - callbacks = true; -} - -/* - Message allocation for user to send. User must destroy the message when - finished, but may keep the message for as long as is necessary - and reuse it over and over. -*/ -//Message* Messenger::Alloc_msg( int payload_size ) { -std::unique_ptr Messenger::Alloc_msg( int payload_size ) { - return std::unique_ptr( new Message( mrc, payload_size ) ); -} - -void Messenger::Listen( ) { - int count = 0; - rmr_mbuf_t* mbuf = NULL; - std::map::iterator mi; // map iterator; silly indirect way to point at the value - Callback* dcb = NULL; // default callback so we don't search - Callback* sel_cb; // callback selected to invoke - std::unique_ptrm; - - if( mrc == NULL ) { - return; - } - - mi = cb_hash.find( DEFAULT_CALLBACK ); - if( mi != cb_hash.end() ) { - dcb = mi->second; // oddly named second field is the address of the callback block - } - - while( ok_2_run ) { - mbuf = rmr_torcv_msg( mrc, mbuf, 2000 ); // come up for air every 2 sec to check ok2run - if( mbuf != NULL ) { - if( mbuf->state == RMR_OK ) { - m = std::unique_ptr( new Message( mbuf, mrc ) ); // auto delteted when scope terminates - - sel_cb = dcb; // start with default - if( callbacks && ((mi = cb_hash.find( mbuf->mtype )) != cb_hash.end()) ) { - sel_cb = mi->second; // override with user callback - } - if( sel_cb != NULL ) { - sel_cb->Drive_cb( *m ); // drive the selected one - mbuf = NULL; // not safe to use after given to cb - } - } else { - if( mbuf->state != RMR_ERR_TIMEOUT ) { - fprintf( stderr, " got bad status: %d\n", mbuf->state ); - } - } - } - } -} - -/* - Wait for the next message, up to a max timout, and return the message received. -*/ -std::unique_ptr Messenger::Receive( int timeout ) { - rmr_mbuf_t* mbuf = NULL; - std::unique_ptr m = NULL; - - if( mrc != NULL ) { - mbuf = rmr_torcv_msg( mrc, mbuf, timeout ); // future: do we want to reuse the mbuf here? - if( mbuf != NULL ) { - m = std::unique_ptr( new Message( mbuf, mrc ) ); - } - } - - return m; -} - -/* - Called to gracefully stop all listeners. -*/ -void Messenger::Stop( ) { - ok_2_run = false; -} - -/* - RMR messages must be released by RMR as there might be transport - buffers that have to be dealt with. Every callback is expected to - call this function when finished with the message. -void Messenger::Release_mbuf( void* vmbuf ) { - rmr_free_msg( (rmr_mbuf_t *) vmbuf ); -} -*/ - -/* - Wait for clear to send. - Until RMR loads a route table, all sends will fail with a - "no endpoint" state. This function allows the user application - to block until RMR has a viable route table. It does not guarentee - that every message that the user app will try to send has an entry. - - The use of this function by the user application allows for the - parallel initialisation of the application while waiting for the - route table service to generate a table for the application. The - initialisation function may be callsed with "no wait" and this - function invoked when the application has completed initialisation - and is ready to start sending messages. - - The max wait parameter is the maximum number of seconds to block. - If RMR never reports ready false is returned. A true return - incidcates all is ready. If max_wait is 0, then this will only - return when RMR is ready to send. -*/ -bool Messenger::Wait_for_cts( int max_wait ) { - bool block_4ever; - bool state = false; - - block_4ever = max_wait == 0; - while( block_4ever || max_wait > 0 ) { - if( rmr_ready( mrc ) ) { - state = true; - break; - } - - sleep( 1 ); - max_wait--; - } - - return state; -} diff --git a/src/messaging/messenger.hpp b/src/messaging/messenger.hpp deleted file mode 100644 index 0810aeb..0000000 --- a/src/messaging/messenger.hpp +++ /dev/null @@ -1,82 +0,0 @@ -// vi: ts=4 sw=4 noet: -/* -================================================================================== - Copyright (c) 2020 Nokia - Copyright (c) 2020 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. -================================================================================== -*/ - - -/* - Mnemonic: messenger.hpp - Abstract: Headers for the messenger class - - Date: 10 March 2020 - Author: E. Scott Daniels -*/ - -#ifndef _messenger_hpp -#define _messenger_hpp - - -#include -#include -#include -#include -#include - -#include - -#include "message.hpp" - -#ifndef RMR_FALSE - #define RMR_FALSE 0 - #define RMR_TRUE 1 -#endif - -class Messenger { - - private: - std::map cb_hash; // callback functions associated with message types - std::mutex* gate; // overall mutex should we need searialisation - bool ok_2_run; - bool callbacks = false; // true if callbacks are defined - void* mrc; // message router context - char* listen_port; // port we ask msg router to listen on - - // copy and assignment are PRIVATE so that they fail if xapp tries; messenger cannot be copied! - Messenger( const Messenger& soi ); - Messenger& operator=( const Messenger& soi ); - - public: - // -- constants which need an instance; that happens as a global in the .cpp file (wtf C++) - static const int MAX_PAYLOAD; // max message size we'll handle - static const int DEFAULT_CALLBACK; // parm for add callback to set default - - Messenger( char* port, bool wait4table ); // builder - Messenger( Messenger&& soi ); // move construction - Messenger& operator=( Messenger&& soi ); // move operator - ~Messenger(); // destroyer - - void Add_msg_cb( int mtype, user_callback fun_name, void* data ); - std::unique_ptr Alloc_msg( int payload_size ); // message allocation - void Listen( ); // lisen driver - std::unique_ptr Receive( int timeout ); // receive 1 message - void Stop( ); // force to stop - //void Release_mbuf( void* vmbuf ); - bool Wait_for_cts( int max_wait ); -}; - -#endif diff --git a/src/messaging/msg_component.hpp b/src/messaging/msg_component.hpp deleted file mode 100644 index d707257..0000000 --- a/src/messaging/msg_component.hpp +++ /dev/null @@ -1,57 +0,0 @@ -// vi: ts=4 sw=4 noet: -/* -================================================================================== - Copyright (c) 2020 Nokia - Copyright (c) 2020 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. -================================================================================== -*/ - -/* - Mnemonic: msg_component.hpp - Abstract: Defines a message component type which is needed in order - to use smart pointers (unique) to point at bytes in the - RMR message (which are not directly allocated and cannot - be freed/deleted outside of RMR (require a special destruction - call in the smart pointer). - - Date: 17 March 2020 - Author: E. Scott Daniels -*/ - -#ifndef _MSG_COMPONENT_HPP -#define _MSG_COMPONENT_HPP - -#include - -// -------------- smart pointer support -------------------------------- -/* - Pointers to a lot of things in the RMR message aren't directly - allocated and thus cannot be directly freed. To return a smart - pointer to these we have to ensure that no attempt to free/delete - the reference is made. This struct defines a type with a function - pointer (operator) that is 'registered' as the delete function for - such a smart pointer, and does _nothing_ when called. -*/ -typedef struct { - void operator()( unsigned char * p ){} -} unfreeable; - -/* - A 'generic' smart pointer to a component in the message which cannot - be directly freed (e.g. the payload, meid, etc). -*/ -using Msg_component = std::unique_ptr; - -#endif diff --git a/src/messaging/CMakeLists.txt b/src/ts_xapp/CMakeLists.txt similarity index 53% rename from src/messaging/CMakeLists.txt rename to src/ts_xapp/CMakeLists.txt index 507da84..06ea5f2 100644 --- a/src/messaging/CMakeLists.txt +++ b/src/ts_xapp/CMakeLists.txt @@ -1,10 +1,7 @@ -# vim: sw=4 ts=4 noet: -# #================================================================================== -# Copyright (c) 2020 Nokia -# Copyright (c) 2020 AT&T Intellectual Property. +# Copyright (c) 2020 AT&T Intellectual Property. # -# Licensed under the Apache License, Version 2.0 (the "License"); +# 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 # @@ -18,30 +15,11 @@ #================================================================================== # +add_executable( ts_xapp ts_xapp.cpp ) +target_link_libraries( ts_xapp ricxfcpp;rmr_si;sdl;pthread ) -# For clarity: this generates object, not a lib as the CM command implies. -# -add_library( message_objects OBJECT - callback.cpp - default_cb.cpp - message.cpp - messenger.cpp +install( + TARGETS ts_xapp + DESTINATION ${install_bin} ) -target_include_directories (message_objects PUBLIC - $ - $ - PRIVATE src) - -# header files should go into .../include/xfcpp/ -if( DEV_PKG ) - install( FILES - callback.hpp - default_cb.hpp - message.hpp - messenger.hpp - msg_component.hpp - DESTINATION ${install_inc} - ) -endif() - diff --git a/src/xapp/CMakeLists.txt b/src/ts_xapp/Makefile similarity index 58% rename from src/xapp/CMakeLists.txt rename to src/ts_xapp/Makefile index 093ef6f..08a350b 100644 --- a/src/xapp/CMakeLists.txt +++ b/src/ts_xapp/Makefile @@ -1,8 +1,8 @@ -# vim: sw=4 ts=4 noet: -# +# vim: ts=4 sw=4 noet: + #================================================================================== -# Copyright (c) 2020 Nokia -# Copyright (c) 2020 AT&T Intellectual Property. +# Copyright (c) 2020 Nokia +# Copyright (c) 2020 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. @@ -16,25 +16,18 @@ # See the License for the specific language governing permissions and # limitations under the License. #================================================================================== -# +# simple makefile to build the examples. This assumes that the xapp framework +# library has been installed or the LD_LIBRARY_PATH and C_INCLUDE_PATH environent +# variables are set to reference the needed files. -# For clarity: this generates object, not a lib as the CM command implies. -# -add_library( xapp_objects OBJECT - xapp.cpp -) +%.o:: %.cpp %.hpp + g++ -g ${prereq%% *} -c -target_include_directories (xapp_objects PUBLIC - $ - $ - PRIVATE src) +% :: %.cpp + g++ $< -g -o $@ -lricxfcpp -lrmr_si -lpthread -lm -lsdl -# header files should go into .../include/xfcpp/ -if( DEV_PKG ) - install( FILES - xapp.hpp - DESTINATION ${install_inc} - ) -endif() +all:: ts_xapp +install:: + cp ts_xapp /usr/local/bin/ diff --git a/examples/ts_xapp.cpp~ b/src/ts_xapp/ts_xapp.cpp similarity index 98% rename from examples/ts_xapp.cpp~ rename to src/ts_xapp/ts_xapp.cpp index 9ccd4b5..f6e2c37 100644 --- a/examples/ts_xapp.cpp~ +++ b/src/ts_xapp/ts_xapp.cpp @@ -98,13 +98,13 @@ void policy_callback( Message& mbuf, int mtype, int subid, int len, Msg_componen fprintf(stderr, "cb 2"); send_payload = msg->Get_payload(); // direct access to payload - snprintf( (char *) send_payload.get(), 2048, "{\"UEPredictionSet\" : [\"222\", \"333\", \"444\"]}", i ); + snprintf( (char *) send_payload.get(), 2048, "{\"UEPredictionSet\" : [\"222\", \"333\", \"444\"]}" ); fprintf(stderr, "cb 3"); // payload updated in place, nothing to copy from, so payload parm is nil if ( ! msg->Send_msg( mtype, Message::NO_SUBID, strlen( (char *) send_payload.get() )+1, NULL )) { - fprintf( stderr, " send failed: %d\n", i ); + fprintf( stderr, " send failed: %d\n", msg->Get_state() ); } fprintf(stderr, "cb 4"); @@ -163,7 +163,7 @@ extern int main( int argc, char** argv ) { int delay = 1000000; // mu-sec delay; default 1s - char* port = (char *) "4555"; + char* port = (char *) "4560"; int ai; diff --git a/src/xapp/README b/src/xapp/README deleted file mode 100644 index 39391b2..0000000 --- a/src/xapp/README +++ /dev/null @@ -1,27 +0,0 @@ - -================================================================================== - Copyright (c) 2020 Nokia - Copyright (c) 2020 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. -================================================================================== - -This directory contains the source for the overall Xapp class. -Specifially: - - xapp.* - Is the class that the user creates in their application. It provides, by - extension, the RMR messaging functions. - - - diff --git a/src/xapp/xapp.cpp b/src/xapp/xapp.cpp deleted file mode 100644 index 8feb52e..0000000 --- a/src/xapp/xapp.cpp +++ /dev/null @@ -1,100 +0,0 @@ -// vi: ts=4 sw=4 noet: -/* -================================================================================== - Copyright (c) 2020 Nokia - Copyright (c) 2020 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. -================================================================================== -*/ - -/* - Mnemonic: xapp.cpp - Abstract: The main xapp class. - This class actually extends the messenger class as most of what - would be done here is just passing through to the messenger. - - Date: 13 March 2020 - Author: E. Scott Daniels -*/ - -#include -#include - -#include -#include - - -#include -#include - -#include -#include "xapp.hpp" - -// --------------- private ----------------------------------------------------- - - - -// --------------- builders ----------------------------------------------- - -/* - If wait4table is true, then the construction of the object does not - complete until the underlying transport has a new copy of the route - table. - - If port is nil, then the default port is used (4560). -*/ -Xapp::Xapp( char* port, bool wait4table ) : Messenger( port, wait4table ) { - // nothing to do; all handled in Messenger constructor -} - -/* - Destroyer. -*/ -Xapp::~Xapp() { - // nothing to destroy; superclass destruction is magically invoked. -} - -/* - Start n threads, each running a listener which will drive callbacks. - - The final listener is started in the main thread; in otherwords this - function won't return unless that listener crashes. -*/ -void Xapp::Run( int nthreads ) { - int i; - std::thread** tinfo; // each thread we'll start - - tinfo = new std::thread* [nthreads-1]; - - for( i = 0; i < nthreads - 1; i++ ) { // thread for each n-1; last runs here - tinfo[i] = new std::thread( &Xapp::Listen, this ); - } - - this->Listen(); // will return only when halted - - for( i = 0; i < nthreads - 1; i++ ) { // wait for others to stop - tinfo[i]->join(); - } - - delete tinfo; -} - -/* - Halt the xapp. This will drive the messenger's stop function to prevent any - active listeners from running, and will shut things down. -*/ -void Xapp::Halt() { - this->Stop(); // messenger shut off -} - diff --git a/src/xapp/xapp.hpp b/src/xapp/xapp.hpp deleted file mode 100644 index 83540ec..0000000 --- a/src/xapp/xapp.hpp +++ /dev/null @@ -1,63 +0,0 @@ -// vi: ts=4 sw=4 noet: -/* -================================================================================== - Copyright (c) 2020 Nokia - Copyright (c) 2020 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. -================================================================================== -*/ - -/* - Mnemonic: xapp.hpp - Abstract: Headers for the xapp class. This class extends the messenger class - as most of the function of this class would be just passing through - calls to the messenger object. - - Date: 13 March 2020 - Author: E. Scott Daniels -*/ - -#ifndef _xapp_hpp -#define _xapp_hpp - - -#include -#include -#include -#include - -#include - -#include "callback.hpp" -#include "messenger.hpp" - -class Xapp : public Messenger { - - private: - std::string name; - - // copy and assignment are PRIVATE because we cant "clone" the listen environment - Xapp( const Xapp& soi ); - Xapp& operator=( const Xapp& soi ); - - public: - Xapp( char* listen_port, bool wait4rt ); // builder - Xapp( ); - ~Xapp(); // destroyer - - void Run( int nthreads ); // message listen driver - void Halt( ); // force to stop -}; - -#endif diff --git a/test/rmr_em.c b/test/rmr_em.c deleted file mode 100644 index c9f85cf..0000000 --- a/test/rmr_em.c +++ /dev/null @@ -1,255 +0,0 @@ -// vim: ts=4 sw=4 noet : -/* -================================================================================== - Copyright (c) 2020 Nokia - Copyright (c) 2020 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. -================================================================================== -*/ - -/* - Mnemonic: rmr_em.c - Abstract: RMR emulation for testing - - Date: 20 March - Author: E. Scott Daniels -*/ - -#include -#include -#include - - -/* - CAUTION: this is a copy of what is in RMR and it is needed as some of the framework - functions access the 'public' fields like state and mtype. -*/ -typedef struct { - int state; // state of processing - int mtype; // message type - int len; // length of data in the payload (send or received) - unsigned char* payload; // transported data - unsigned char* xaction; // pointer to fixed length transaction id bytes - int sub_id; // subscription id - int tp_state; // transport state (errno) valid only if state != RMR_OK, and even then may not be valid - - // these things are off limits to the user application - void* tp_buf; // underlying transport allocated pointer (e.g. nng message) - void* header; // internal message header (whole buffer: header+payload) - unsigned char* id; // if we need an ID in the message separate from the xaction id - int flags; // various MFL_ (private) flags as needed - int alloc_len; // the length of the allocated space (hdr+payload) - - void* ring; // ring this buffer should be queued back to - int rts_fd; // SI fd for return to sender - - int cookie; // cookie to detect user misuse of free'd msg -} rmr_mbuf_t; - -typedef struct { - char meid[32]; - char src[32]; -} header_t; - - -void* rmr_init( char* port, int flags ) { - return malloc( sizeof( char ) * 100 ); -} - -rmr_mbuf_t* rmr_alloc_msg( void* mrc, int payload_len ) { - rmr_mbuf_t* mbuf; - char* p; // the tp buffer; also the payload - header_t* h; - int len; - - len = (sizeof( char ) * payload_len) + sizeof( header_t ); - p = (char *) malloc( len ); - if( p == NULL ) { - return NULL; - } - h = (header_t *) p; - memset( p, 0, len ); - - mbuf = (rmr_mbuf_t *) malloc( sizeof( rmr_mbuf_t ) ); - if( mbuf == NULL ) { - free( p ); - return NULL; - } - memset( mbuf, 0, sizeof( rmr_mbuf_t ) ); - - mbuf->tp_buf = p; - mbuf->payload = (char *)p + sizeof( header_t ); - - - mbuf->len = 0; - mbuf->alloc_len = payload_len; - mbuf->payload = (void *) p; - strncpy( h->src, "host:ip", 8 ); - strncpy( h->meid, "EniMeini", 9 ); - - return mbuf; -} - -void rmr_free_msg( rmr_mbuf_t* mbuf ) { - if( mbuf ) { - if( mbuf->tp_buf ) { - free( mbuf->tp_buf ); - } - free( mbuf ); - } -} - -char* rmr_get_meid( rmr_mbuf_t* mbuf, char* m ) { - header_t* h; - - if( mbuf != NULL ) { - if( m == NULL ) { - m = (char *) malloc( sizeof( char ) * 32 ); - } - h = (header_t *) mbuf->tp_buf; - memcpy( m, h->meid, 32 ); - } - - return m; -} - -int rmr_payload_size( rmr_mbuf_t* mbuf ) { - - if( mbuf != NULL ) { - return mbuf->alloc_len; - } - - return 0; -} - -char *rmr_get_src( rmr_mbuf_t* mbuf, char *m ) { - header_t* h; - - if( mbuf != NULL ) { - if( m == NULL ) { - m = (char *) malloc( sizeof( char ) * 32 ); - } - h = (header_t *) mbuf->tp_buf; - memcpy( m, h->src, 32 ); - } - - return m; -} - -int rmr_str2meid( rmr_mbuf_t* mbuf, unsigned char* s ) { - header_t* h; - - if( mbuf != NULL ) { - if( s == NULL ) { - return 1; - } - - if( strlen( s ) > 31 ) { - return 1; - } - - h = (header_t *) mbuf->tp_buf; - strncpy( h->meid, s, 32 ); - return 0; - } - - return 1; -} - -rmr_mbuf_t* rmr_send_msg( void* mrc, rmr_mbuf_t* mbuf ) { - - if( mbuf != NULL ) { - mbuf->state = 0; - } - - return mbuf; -} - -rmr_mbuf_t* rmr_rts_msg( void* mrc, rmr_mbuf_t* mbuf ) { - - if( mbuf != NULL ) { - mbuf->state = 0; - } - - return mbuf; -} - -rmr_mbuf_t* rmr_realloc_payload( rmr_mbuf_t* mbuf, int payload_len, int copy, int clone ) { // ensure message is large enough - rmr_mbuf_t* nmb; - unsigned char* payload; - - if( mbuf == NULL ) { - return NULL; - } - - nmb = rmr_alloc_msg( NULL, payload_len ); - if( copy ) { - memcpy( nmb->payload, mbuf->payload, mbuf->len ); - nmb->len = mbuf->len; - } else { - nmb->len = 0; - } - nmb->state = mbuf->state; - - if( ! clone ) { - free( mbuf ); - } - return nmb; -} - -void rmr_close( void* mrc ) { - return; -} - -rmr_mbuf_t* rmr_torcv_msg( void* mrc, rmr_mbuf_t* mbuf, int timeout ) { - static int max2receive = 500; - static int mtype = 0; - - if( mbuf == NULL ) { - mbuf = rmr_alloc_msg( NULL, 2048 ); - } - - if( max2receive <= 0 ) { - mbuf->state = 12; - mbuf->len = 0; - mbuf->mtype = -1; - mbuf->sub_id = -1; - } - - max2receive--; - - mbuf->state = 0; - mbuf->len = 80; - mbuf->mtype = mtype; - mbuf->sub_id = -1; - - mtype++; - if( mtype > 100 ) { - mtype = 0; - } - - return mbuf; -} - -int rmr_ready( void* mrc ) { - static int state = 0; - - if( ! state ) { - state = 1; - return 0; - } - - return 1; -} - diff --git a/test/unit_test.cpp b/test/unit_test.cpp deleted file mode 100644 index b0612d8..0000000 --- a/test/unit_test.cpp +++ /dev/null @@ -1,302 +0,0 @@ -// vim: ts=4 sw=4 noet : -/* -================================================================================== - Copyright (c) 2020 Nokia - Copyright (c) 2020 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. -================================================================================== -*/ - -/* - Mnemonic: Unit_test.cpp - Abstract: This is the unit test driver for the C++ xAPP framework. It - operates by including all of the modules directly (in order - to build them with the necessary coverage flags), then - drives all that it can. The RMR emulation module provides - emulated RMR functions which simulate the creation, sending - and receiving of messages etc. - - Date: 20 March 2020 - Author: E. Scott Daniels -*/ - -#include - - -#include "../src/messaging/callback.hpp" -#include "../src/messaging/default_cb.hpp" -#include "../src/messaging/message.hpp" -#include "../src/messaging/messenger.hpp" -#include "../src/messaging/msg_component.hpp" -#include "../src/xapp/xapp.hpp" - -#include "../src/messaging/callback.cpp" -#include "../src/messaging/default_cb.cpp" -#include "../src/messaging/message.cpp" -#include "../src/messaging/messenger.cpp" -#include "../src/xapp/xapp.cpp" - -/* - callback error counts are global for ease. They track the number of times each callback - was invoked with the expected message type(s) and any times they were not. -*/ -int err_cb1 = 0; -int err_cb2 = 0; -int err_cbd = 0; - -int good_cb1 = 0; -int good_cb2 = 0; -int good_cbd = 0; - -/* - callback functions to register; driven as we "receive" messages (the RMR emulation package - will generate a message every time the receive function is called). -*/ -void cb1( Message& mbuf, int mtype, int subid, int len, Msg_component payload, void* data ) { - if( mtype != 1 ) { // should only be driven for type 1 messages - err_cb1++; - } else { - good_cb1++; - } -} -void cb2( Message& mbuf, int mtype, int subid, int len, Msg_component payload, void* data ) { - if( mtype != 2 ) { // should only be driven for type 2 messages - err_cb2++; - } else { - good_cb2++; - } -} -void cbd( Message& mbuf, int mtype, int subid, int len, Msg_component payload, void* data ) { - if( mtype > 0 && mtype < 3 ) { // should only be driven for types that arent 1 or 2 - if( err_cbd < 10 ) { - fprintf( stderr, " cbd: bad message type: %d\n", mtype ); - } - err_cbd++; - } else { - good_cbd++; - } -} - -/* - The Xapp Run() function only returns when Xapp is asked to stop, and that - isn't supported from inside any of the callbacks. This funciton is - started in a thread and after a few seconds it will drive the halt - function in the Xapp instance to stop the run function and allow the - unit test to finish. -*/ -void killer( std::shared_ptr x ) { - fprintf( stderr, " killer is waiting in the shadows\n" ); - sleep( 2 ); - fprintf( stderr, " killer is on the loose\n" ); - x->Halt(); -} - -int main( int argc, char** argv ) { - std::thread* tinfo; // we'll start a thread that will shut things down after a few seconds - std::unique_ptr msg; - std::shared_ptr x; - Msg_component payload; - std::unique_ptr ucs; - unsigned char* new_payload; - std::shared_ptr new_p_ref; // reference to payload to pass to send functions - char* port = (char *) "4560"; - int ai = 1; // arg processing index - int nthreads = 2; // ensure the for loop is executed in setup - int i; - int len; - int errors = 0; - char wbuf[256]; - - ai = 1; - while( ai < argc ) { // very simple flag processing (no bounds/error checking) - if( argv[ai][0] != '-' ) { - break; - } - - switch( argv[ai][1] ) { // we only support -x so -xy must be -x -y - case 'p': - port = argv[ai+1]; - ai++; - break; - - case 't': - nthreads = atoi( argv[ai+1] ); - ai++; - break; - } - - ai++; - } - - x = std::shared_ptr( new Xapp( port, true ) ); - x->Add_msg_cb( 1, cb1, NULL ); - x->Add_msg_cb( 2, cb2, NULL ); - x->Add_msg_cb( -1, cbd, NULL ); - - msg = x->Alloc_msg( 2048 ); - payload = msg->Get_payload(); - msg->Set_len( 128 ); - msg->Set_mtype( 100 ); - msg->Set_subid( -10 ); - - ucs = msg->Copy_payload( ); - if( ucs == NULL ) { - fprintf( stderr, " expected pointer to copy payload but got nil\n" ); - errors++; - } - - ucs = msg->Get_meid(); - if( ucs == NULL ) { - fprintf( stderr, " expected pointer to meid copy but got nil\n" ); - errors++; - } - - ucs = msg->Get_src(); - if( ucs == NULL ) { - fprintf( stderr, " expected pointer to src copy but got nil\n" ); - errors++; - } - - i = msg->Get_available_size(); - if( i != 2048 ) { - fprintf( stderr, " len expected payload avail size of 2048 but got %d\n", i ); - errors++; - } - - i = msg->Get_mtype(); - if( i != 100 ) { - fprintf( stderr, " expected mtype of 100 but got %d\n", i ); - errors++; - } - - i = msg->Get_state( ); - if( i != 0 ) { - fprintf( stderr, " expected state of 0 but got %d\n", i ); - errors++; - } - - i = msg->Get_subid(); - if( i != -10 ) { - fprintf( stderr, " expected subid of -10 but got %d\n", i ); - errors++; - } - - i = msg->Get_len(); - if( i != 128 ) { - fprintf( stderr, " len expected 128 but got %d\n", i ); - errors++; - } - - msg->Send(); // generic send as is functions - msg->Reply(); - - new_payload = (unsigned char *) malloc( sizeof( unsigned char ) * 2048 ); // a large payload - memset( new_payload, 0 , sizeof( unsigned char ) * 2048 ); - new_p_ref = std::shared_ptr( new_payload ); // reference it for send calls - - msg->Set_meid( new_p_ref ); - - msg->Send_msg( 255, new_p_ref ); // send without changing the message type/subid from above - msg->Send_msg( 255, new_payload ); // drive the alternate prototype - msg->Send_msg( 100, 1, 128, new_p_ref ); // send using just 128 bytes of payload - msg->Send_msg( 100, 1, 128, new_payload ); // drive with alternate prototype - - msg->Set_len( 128 ); - msg->Set_mtype( 100 ); - msg->Set_subid( -10 ); - - msg->Send_response( 100, new_p_ref ); // send a response (rts) with establisehd message type etc - msg->Send_response( 100, new_payload ); - msg->Send_response( 100, 10, 100, new_p_ref ); - msg->Send_response( 100, 10, 100, new_payload ); - - - msg = NULL; // should drive the message destroyer for coverage - - msg = x->Receive( 2000 ); - if( msg == NULL ) { - fprintf( stderr, " expected message from receive but got nil\n" ); - errors++; - } - - tinfo = new std::thread; // start killer thread to terminate things so that run doesn't hang forever - tinfo = new std::thread( killer, x ); - - x->Run( nthreads ); - x->Halt(); // drive for coverage - - if( err_cb1 + err_cb2 + err_cbd > 0 ) { - fprintf( stderr, " one or more callbacks reported an error: [%d] [%d] [%d]\n", err_cb1, err_cb2, err_cbd ); - fprintf( stderr, " callback good values: [%d] [%d] [%d]\n", good_cb1, good_cb2, good_cbd ); - errors++; - } - - // ----- specific move/copy coverage drivers --------------------------- - - Messenger m1( (char *) "1234", false ); // messenger class does NOT permit copies, so no need to test - Messenger m2( (char *) "9999", false ); - m1 = std::move( m2 ); // drives move operator= function - Messenger m3 = std::move( m1 ); // drives move constructor function - - std::unique_ptr msg2 = x->Alloc_msg( 2048 ); - std::unique_ptr msg3 = x->Alloc_msg( 4096 ); - - snprintf( wbuf, sizeof( wbuf ), "Stand up and cheer!!" ); - msg3->Set_len( strlen( wbuf ) ); - strcpy( (char *) (msg3->Get_payload()).get(), wbuf ); // populate the payload to vet copy later - fprintf( stderr, " set string (%s) \n", (char *) (msg3->Get_payload()).get() ); - - Message msg4 = *(msg3.get()); // drive copy builder; msg4 should have a 4096 byte payload - fprintf( stderr, " copy string (%s) \n", (char *) (msg4.Get_payload()).get() ); // and payload should be coppied - if( msg4.Get_available_size() != 4096 ) { - errors++; - fprintf( stderr, " message copy builder payload size smells: expected 4096, got %d\n", msg4.Get_available_size() ); - } - if( strcmp( (char *) msg4.Get_payload().get(), wbuf ) != 0 ) { - errors++; - fprintf( stderr, " message copy builder payload of copy not the expected string\n" ); - } - - snprintf( wbuf, sizeof( wbuf ), "Rambling Wreck; GT!" ); // different string into msg 2 to ensure copy replaced msg3 string - strcpy( (char *) (msg2->Get_payload()).get(), wbuf ); // populate the msg2 payload to vet copy - msg2->Set_len( strlen( wbuf ) ); - *msg3 = *msg2; // drive the copy operator= function - if( msg3->Get_available_size() != 2048 ) { - errors++; - fprintf( stderr, " message copy operator payload size smells: expected 2048, got %d\n", msg3->Get_available_size() ); - } - if( strcmp( (char *) msg3->Get_payload().get(), wbuf ) != 0 ) { - errors++; - fprintf( stderr, " message copy builder payload of copy not the expected string\n" ); - } - - Message msg5 = std::move( *(msg3.get()) ); // drive move constructor - if( msg5.Get_available_size() != 2048 ) { - errors++; - fprintf( stderr, " message copy operator payload size smells: expected 2048, got %d\n", msg5.Get_available_size() ); - } - if( strcmp( (char *) msg5.Get_payload().get(), wbuf ) != 0 ) { - errors++; - fprintf( stderr, " message copy builder payload of copy not the expected string\n" ); - } - - msg5.Set_len( 2 ); // bogus len for vetting later - msg5 = std::move( *(msg3.get()) ); - if( msg5.Get_len() == 21 ) { - errors++; - fprintf( stderr, " message move operator payload len smells: expected 21, got %d\n", msg5.Get_len() ); - } - - return errors > 0; -} diff --git a/test/unit_test.sh b/test/unit_test.sh index 7144f9c..d361fb7 100755 --- a/test/unit_test.sh +++ b/test/unit_test.sh @@ -63,18 +63,24 @@ spew="cat" # default to dumping all make output on failure (-q turns it to ~ while [[ $1 == "-"* ]] do case $1 in - -q) spew="head -40";; + -q) spew="head -40";; # how much to dump on build error -v) spew="cat";; esac shift done +if [[ ! -f unit_test.cpp ]] +then + echo "[PASS] no unit test source exists" + exit 0 +fi + make nuke >/dev/null make unit_test >/tmp/PID$$.log 2>&1 abort_if_error $? "unable to make" -spew="cat" +spew="cat" # after we build, dump everything on error ./unit_test >/tmp/PID$$.log 2>&1 abort_if_error $? "unit test failed" diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..7a1ec97 --- /dev/null +++ b/tox.ini @@ -0,0 +1,37 @@ +# This work is licensed under a Creative Commons Attribution 4.0 International License. +# SPDX-License-Identifier: CC-BY-4.0 +# Copyright (C) 2020 AT&T Intellectual Property +# documentation only + +# this file is needed to control the read the docs verification mechanism in jenkins + +[tox] +minversion = 2.0 +envlist = + docs, + docs-linkcheck, +skipsdist = true + +[testenv:docs] +basepython = python3 +deps = + sphinx + sphinx-rtd-theme + sphinxcontrib-httpdomain + recommonmark + lfdocs-conf + +commands = + sphinx-build -W -b html -n -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/html + echo "Generated docs available in {toxinidir}/docs/_build/html" +whitelist_externals = echo + +[testenv:docs-linkcheck] +basepython = python3 +deps = sphinx + sphinx-rtd-theme + sphinxcontrib-httpdomain + recommonmark + lfdocs-conf +commands = sphinx-build -W -b linkcheck -d {envtmpdir}/doctrees ./docs/ {toxinidir}/docs/_build/linkcheck +