CommonAPI C SomeIP in 10 minutes - COVESA/capicxx-someip-tools GitHub Wiki (2024)

CommonAPI C++ in 10 minutes (with SOME/IP)

Table of contents


Step 3: Build the CommonAPI SOME/IP Runtime Library
Step 4: Write the Franca file and generate code
Step 5: Write the client and the service application
Step 6: Build and run

Step 1 & 2: Preparation / Prerequisites

The following description is tested with CommonAPI 3.2.3 and assumes that you use a standard Linux distribution (I tested it with Ubuntu 22.04) and that you have installed git and (CMake >=3.13). Please note that the code generators need the java 8 runtime environment. If you didn't pass the instructions of the page "CommonAPI C++ D-Bus in 10 minutes" then do now step 2 in order to get and build the CommonAPI runtime library.

Step 3: Build the CommonAPI SOME/IP Runtime Library

Start again with cloning the source code of CommonAPI-SomeIP:

$ git clone https://github.com/GENIVI/capicxx-someip-runtime.git

Just as CommonAPI C++ D-Bus requires the D-Bus library libdbus, the SOME/IP binding builds on the SOME/IP core library vsomeip. Fortunately. the source code of this library can be easily downloaded from github. Just clone the vsomeip repository:

$ git clone https://github.com/GENIVI/vsomeip.git

Before you can go ahead with compiling vsomeip you must ensure that the prerequisites are fulfilled. vsomeip uses the standard cross-platform C++ library Boost.Asio for the implementation of some core network functions. Before you can compile the vsomeip library make sure that Boost (>=1.55) is installed on your system. You can follow the installation instructions at http://www.boost.org/doc/libs/1_59_0/more/getting_started/unix-variants.html, but if you have an Ubuntu platform it is easier to install it with the package manager APT (see also the README on https://github.com/GENIVI/vsomeip). When Boost has been successfully installed, you can build vsomeip without further difficulty as usual:

$ cd vsomeip<.>/vsomeip$ cmake -Bbuild -DCMAKE_INSTALL_PREFIX=../install_folder -DENABLE_SIGNAL_HANDLING=1 -DDIAGNOSIS_ADDRESS=0x10 .<.>/vsomeip$ cmake --build build --target install

On my system CMake prints out the following lines concerning BOOST:

-- Found Boost: /usr/lib/x86_64-linux-gnu/cmake/Boost-1.74.0/BoostConfig.cmake (found suitable version "1.74.0", minimum required is "1.55") found components: system thread filesystem -- Using boost version: 107400

With ENABLE_SIGNAL_HANDLING=1 the signal handling of vsomeip (SIGINT/SIGTERM) is enabled; that you can abort vsomeip applications by ctrl-c. The second parameter DIAGNOSIS_ADDRESS specifies the first byte of the SOME/IP client ID (don't care if you do not know at the moment what it is). You just have to know that the client ID is a number in the SOME/IP message header which has to be unique in the system. In order to make sure that it is unique, for each device (or node) the vsomeip implementation sets the first byte of this client ID to a fixed value which must be different for all devices in the SOME/IP network. If you only intend to communicate locally via SOME/IP this is not necessary.

Now it should be no problem to build the CommonAPI C++ SOME/IP runtime library:

$ cd capicxx-someip-runtime<.>/capicxx-someip-runtime$ cmake -Bbuild -DCMAKE_INSTALL_PREFIX=../install_folder -DCMAKE_PREFIX_PATH=../install_folder -DUSE_INSTALLED_COMMONAPI=OFF .<.>/capicxx-someip-runtime$ cmake --build build --target install

Step 4: Write the Franca file and generate code

Now follow again the instructions of the page "CommonAPI C++ D-Bus in 10 minutes", Step 4:

  • Create a sub-directory project in your work directory and then the sub-directory fidl in the project directory.
  • Change to this sub-directory.
  • Now create HelloWorld.fidl as described in the D-Bus tutorial. It's CommonAPI: concerning the interface definition in the fidl there is no difference.

But the SOME/IP specification additionally requires the definition of service and method identifiers. Franca IDL provides the possibility to provide this kind of IPC framework specific parameters by means of so-called Franca deployment files. These deployment files have the ending .fdepl and have a Franca-like syntax (deployment parameter file). The exact content (which deployment parameters must be provided) must be specified also in a fdepl-file (deployment specification file). The deployment specification file which is implemented by the CommonAPI C++ SOME/IP specification can be found in the SOME/IP code generator project. If you don't want to check out the complete tools project just have a look at https://github.com/GENIVI/capicxx-someip-tools; you will find the file CommonAPI-4-SOMEIP_deployment_spec.fdepl in the directory org.genivi.commonapi.someip/deployment.

Based on this deployment specification it is possible to write the deployment parameter file; usually we call it like the fidl file, just with the ending fdepl, HelloWorld.fdepl.

import "platform:/plugin/org.genivi.commonapi.someip/deployment/CommonAPI-4-SOMEIP_deployment_spec.fdepl"import "HelloWorld.fidl"define org.genivi.commonapi.someip.deployment for interface commonapi.examples.HelloWorld { SomeIpServiceID = 4660 method sayHello { SomeIpMethodID = 30000 SomeIpReliable = true in { name { SomeIpStringEncoding = utf16le } } }}define org.genivi.commonapi.someip.deployment for provider as Service { instance commonapi.examples.HelloWorld { InstanceId = "commonapi.examples.HelloWorld" SomeIpInstanceID = 4660 SomeIpUnicastAddress = "192.168.0.2" SomeIpReliableUnicastPort = 30499 SomeIpUnreliableUnicastPort = 30499 }}

The SOME/IP deployment specification has some mandatory parameters; it imports the binding independent CommonAPI deployment specification. Therefore we find the parameter InstanceId in the instance deployment.

Now you need the SOME/IP code generator. It can be downloaded for a certain release just as the other code generators from github. Call the SOME/IP generator similar to the CommonAPI C++ D-Bus code generator before (I assume again that you have the code generator executables in cgen subfolder):

<.>/project$ ./cgen/commonapi_core_generator/commonapi-core-generator-linux-x86 -d src-gen/core -sk ./fidl/HelloWorld.fidl<.>/project$ ./cgen/commonapi_someip_generator/commonapi-someip-generator-linux-x86 -d src-gen/someip ./fidl/HelloWorld.fdepl

:exclamation: Please note that there are some SOME/IP parameters mandatory. Therefore the input file for the code generator is the deployment parameter file (fdepl); the fidl file itself cannot be used.

Step 5: Write the client and the service application

It's CommonAPI C++ :clap: Just follow step 5 of "CommonAPI C++ D-Bus in 10 minutes". There is no difference.

Step 6: Build and run

Since you must have installed CMake in order to build the CommonAPI runtime libraries, the fastest way to compile and build our applications is to write a simple CMake file. If already existent, replace your CMakeLists.txt directly in the project directory for the following:

cmake_minimum_required(VERSION 2.8)set(PRJ_NAME HelloWorld)set(CMAKE_VERBOSE_MAKEFILE on)OPTION(USE_FILE "Set to OFF to disable file logging" OFF )message(STATUS "USE_FILE is set to value: ${USE_FILE}")OPTION(USE_CONSOLE "Set to OFF to disable console logging" OFF )message(STATUS "USE_CONSOLE is set to value: ${USE_CONSOLE}")IF(USE_FILE) add_definitions(-DUSE_FILE)ENDIF(USE_FILE)IF(USE_CONSOLE) add_definitions(-DUSE_CONSOLE)ENDIF(USE_CONSOLE)SET(MAX_LOG_LEVEL "DEBUG" CACHE STRING "maximum log level")message(STATUS "MAX_LOG_LEVEL is set to value: ${MAX_LOG_LEVEL}")add_definitions(-DCOMMONAPI_LOGLEVEL=COMMONAPI_LOGLEVEL_${MAX_LOG_LEVEL})if (MSVC)# Visual C++ is not always sure whether he is really C++set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS /EHsc /wd\\\"4503\\\"")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_CRT_SECURE_NO_WARNINGS /wd\\\"4503\\\"")else()set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread -Wall -O0 -std=c++11 -D_GLIBCXX_USE_NANOSLEEP -DLINUX")endif()message(STATUS "Compiler options: ${CMAKE_CXX_FLAGS}") if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release." FORCE)endif(NOT CMAKE_BUILD_TYPE)message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")OPTION(USE_INSTALLED_COMMONAPI "Set to OFF to use the local (build tree) version of CommonAPI" ON)message(STATUS "USE_INSTALLED_COMMONAPI is set to value: ${USE_INSTALLED_COMMONAPI}")if ("${USE_INSTALLED_COMMONAPI}" STREQUAL "ON") FIND_PACKAGE(CommonAPI 3.2.0 REQUIRED CONFIG NO_CMAKE_PACKAGE_REGISTRY) FIND_PACKAGE(CommonAPI-DBus 3.2.0 REQUIRED CONFIG NO_CMAKE_PACKAGE_REGISTRY)else() FIND_PACKAGE(CommonAPI 3.2.0 REQUIRED CONFIG NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH) FIND_PACKAGE(CommonAPI-DBus 3.2.0 REQUIRED CONFIG NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH)endif()message(STATUS "CommonAPI_CONSIDERED_CONFIGS: ${CommonAPI_CONSIDERED_CONFIGS}")message(STATUS "COMMONAPI_INCLUDE_DIRS: ${COMMONAPI_INCLUDE_DIRS}")message(STATUS "CommonAPI-DBus_CONSIDERED_CONFIGS: ${CommonAPI-DBus_CONSIDERED_CONFIGS}")message(STATUS "COMMONAPI_DBUS_INCLUDE_DIRS: ${COMMONAPI_DBUS_INCLUDE_DIRS}")# CommonAPIinclude(FindPkgConfig)################################################################################ find DBus by using the 'pkg-config' toolif (MSVC) #Not beautiful, but it works if (DBus_DIR) if (DBus_BUILD_DIR) set(DBus_INCLUDE_DIRS "${DBus_DIR};${DBus_BUILD_DIR};") else () message (FATAL_ERROR "DBus_BUILD_DIR not set! Cannot continue.") endif () else() message (FATAL_ERROR "DBus_DIR not set! Cannot continue.") endif ()else() pkg_check_modules(DBus REQUIRED dbus-1>=1.4)endif()# SOME/IPfind_package (CommonAPI-SomeIP 3.2.0 REQUIRED)find_package (vsomeip3 3.1.0 REQUIRED)# Source Filesset(PRJ_SRC_PATH src)set(PRJ_SRC_GEN_PATH src-gen)set(PRJ_SRC_GEN_COMMONAPI_PATH ${PRJ_SRC_GEN_PATH}/core/v0/commonapi/examples)set(PRJ_SRC_GEN_COMMONAPI_DBUS_PATH ${PRJ_SRC_GEN_PATH}/dbus/v0/commonapi/examples)set(PRJ_SRC_GEN_COMMONAPI_SOMEIP_PATH ${PRJ_SRC_GEN_PATH}/someip/v0/commonapi/examples)set(PRJ_NAME_CLIENT ${PRJ_NAME}Client)set(PRJ_NAME_SERVICE ${PRJ_NAME}Service)# ApplicationFILE(GLOB PRJ_PROXY_GEN_SRCS ${PRJ_SRC_GEN_COMMONAPI_PATH}/*Proxy.cpp)FILE(GLOB PRJ_STUB_GEN_SRCS ${PRJ_SRC_GEN_COMMONAPI_PATH}/*Stub*.cpp)FILE(GLOB PRJ_STUB_IMPL_SRCS ${PRJ_SRC_COMMONAPI_PATH}/*Stub*.cpp)set(PRJ_CLIENT_SRCS ${PRJ_SRC_PATH}/${PRJ_NAME_CLIENT}.cpp ${PRJ_PROXY_GEN_SRCS})set(PRJ_SERVICE_SRCS ${PRJ_SRC_PATH}/${PRJ_NAME_SERVICE}.cpp ${PRJ_SRC_PATH}/${PRJ_NAME}StubImpl.cpp ${PRJ_STUB_GEN_SRCS} ${PRJ_STUB_IMPL_SRCS})# Boostfind_package( Boost 1.54 COMPONENTS system thread log REQUIRED )include_directories( ${Boost_INCLUDE_DIR} )# DBus libraryFILE(GLOB PRJ_DBUS_LIB_SRCS ${PRJ_SRC_GEN_COMMONAPI_DBUS_PATH}/*cpp)# SOME/IP libraryFILE(GLOB PRJ_SOMEIP_LIB_SRCS ${PRJ_SRC_GEN_COMMONAPI_SOMEIP_PATH}/*cpp)# PathsOPTION(USE_INSTALLED_DBUS "Set to OFF to use the local (patched) version of dbus" ON)message(STATUS "USE_INSTALLED_DBUS is set to value: ${USE_INSTALLED_DBUS}")include_directories( src-gen/core src-gen/dbus src-gen/someip ${COMMONAPI_INCLUDE_DIRS} ${COMMONAPI_DBUS_INCLUDE_DIRS} ${COMMONAPI_SOMEIP_INCLUDE_DIRS} ${DBus_INCLUDE_DIRS} ${VSOMEIP_INCLUDE_DIRS})if ("${USE_INSTALLED_DBUS}" STREQUAL "ON")link_directories( ${COMMONAPI_LIBDIR} ${COMMONAPI_DBUS_LIBDIR} ${COMMONAPI_SOMEIP_CMAKE_DIR}/build ${DBus_LIBRARY_DIRS} ${Boost_LIBRARY_DIR})else()link_directories( ${COMMONAPI_LIBDIR} ${COMMONAPI_DBUS_LIBDIR} ${COMMONAPI_SOMEIP_CMAKE_DIR}/build ${DBus_INCLUDE_DIRS}/dbus/.libs ${Boost_LIBRARY_DIR})endif()if (MSVC) set(LINK_LIBRARIES CommonAPI)else() set(LINK_LIBRARIES -Wl,--as-needed CommonAPI)endif()# Build Clientadd_executable(${PRJ_NAME_CLIENT} ${PRJ_CLIENT_SRCS})target_link_libraries(${PRJ_NAME_CLIENT} ${LINK_LIBRARIES})# Build serviceadd_executable(${PRJ_NAME_SERVICE} ${PRJ_SERVICE_SRCS})target_link_libraries(${PRJ_NAME_SERVICE} ${LINK_LIBRARIES})# Build DBus libraryadd_library (${PRJ_NAME}-dbus SHARED ${PRJ_DBUS_LIB_SRCS})target_link_libraries(${PRJ_NAME}-dbus CommonAPI-DBus)# Build SOME/IP libraryadd_library (${PRJ_NAME}-someip SHARED ${PRJ_SOMEIP_LIB_SRCS})target_link_libraries(${PRJ_NAME}-someip CommonAPI-SomeIP)

Now call CMake and make:

<.>/project$ cmake -Bbuild -DCMAKE_PREFIX_PATH=$(realpath ../install_folder) -DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=ON .<.>/project$ cmake --build build

Now we are on the verge to start the service and the client application. With earlier vsomeip versions it was necessary to create a configuration file for vsomeip but for simple HelloWorld applications without any external communication this is not necessary. However, by default CommonAPI uses the binding dbus, in order to use someip we need to create the file commonapi4someip.ini where it is possible to define other configurations as the logging options (not mandatory), more detail about this is provided on the next tutorial Loading Bindings And Libraries (D-Bus and SOME/IP).

<.>/project$ vi commonapi4someip.ini
[default]binding=someip[logging]console = truefile = ./mylog.logdlt = truelevel = verbose

Start the Service and the Client in two different terminals and they should communicate with each other using vsomeip.

<.>/project$ COMMONAPI_CONFIG=commonapi4someip.ini LD_LIBRARY_PATH=../install_folder/lib:$PWD/build/ build/HelloWorldService[23950.507151]~DLT~236605~INFO ~FIFO /tmp/dlt cannot be opened. Retrying later...[CAPI][INFO] Loading configuration file 'commonapi4someip.ini'[CAPI][INFO] Using default binding 'someip'[CAPI][INFO] Using default shared library folder '/usr/local/lib/commonapi'[CAPI][DEBUG] Loading library for local:commonapi.examples.HelloWorld:v0_1:commonapi.examples.HelloWorld stub.[CAPI][INFO] Loading configuration file /etc//commonapi-someip.ini[CAPI][DEBUG] Added address mapping: local:commonapi.examples.HelloWorld:v0_1:commonapi.examples.HelloWorld <--> [1234.1234(0.1)][CAPI][VERBOSE] Registering function for creating "commonapi.examples.HelloWorld:v0_1" proxy.[CAPI][INFO] Registering function for creating "commonapi.examples.HelloWorld:v0_1" stub adapter.[CAPI][DEBUG] Loading interface library "libHelloWorld-someip.so" succeeded.[CAPI][INFO] Registering stub for "local:commonapi.examples.HelloWorld:v0_1:commonapi.examples.HelloWorld"2024-01-15 15:19:37.859585 [info] Parsed vsomeip configuration in 0ms2024-01-15 15:19:37.860096 [info] Configuration module loaded.2024-01-15 15:19:37.860236 [info] Security disabled!2024-01-15 15:19:37.860327 [info] Initializing vsomeip (3.4.10) application "service-sample".2024-01-15 15:19:37.860947 [info] Instantiating routing manager [Host].2024-01-15 15:19:37.862274 [info] create_routing_root: Routing root @ /tmp/vsomeip-02024-01-15 15:19:37.863333 [info] Service Discovery enabled. Trying to load module.2024-01-15 15:19:37.866415 [info] Service Discovery module loaded.2024-01-15 15:19:37.866855 [info] vsomeip tracing not enabled. . vsomeip service discovery tracing not enabled. 2024-01-15 15:19:37.866967 [info] Application(service-sample, 1000) is initialized (11, 100).2024-01-15 15:19:37.868205 [info] Starting vsomeip application "service-sample" (1000) using 2 threads I/O nice 2552024-01-15 15:19:37.869827 [info] Client [1000] routes unicast:127.0.0.1, netmask:255.255.255.02024-01-15 15:19:37.869839 [info] shutdown thread id from application: 1000 (service-sample) is: 7fabd1aa0640 TID: 2366122024-01-15 15:19:37.869587 [info] main dispatch thread id from application: 1000 (service-sample) is: 7fabd22a1640 TID: 2366112024-01-15 15:19:37.871275 [info] create_local_server: Listening @ /tmp/vsomeip-10002024-01-15 15:19:37.871338 [info] Watchdog is disabled!2024-01-15 15:19:37.871649 [info] OFFER(1000): [1234.1234:0.1] (true)Successfully Registered Service!Waiting for calls... (Abort with CTRL+C)2024-01-15 15:19:37.872233 [info] io thread id from application: 1000 (service-sample) is: 7fabd2aa2640 TID: 2366102024-01-15 15:19:37.872284 [info] io thread id from application: 1000 (service-sample) is: 7fabd0a9e640 TID: 2366142024-01-15 15:19:37.873185 [info] vSomeIP 3.4.10 | (default)2024-01-15 15:19:37.873665 [info] Network interface "lo" state changed: up2024-01-15 15:19:47.873624 [info] vSomeIP 3.4.10 | (default)2024-01-15 15:19:48.958002 [info] Application/Client 1001 is registering.2024-01-15 15:19:48.958866 [info] Client [1000] is connecting to [1001] at /tmp/vsomeip-10012024-01-15 15:19:48.965954 [info] REGISTERED_ACK(1001)2024-01-15 15:19:48.047561 [info] REQUEST(1001): [1234.1234:0.4294967295]sayHello('World'): 'Hello World!'sayHello('World'): 'Hello World!'
<.>/project$ COMMONAPI_CONFIG=commonapi4someip.ini LD_LIBRARY_PATH=../install_folder/lib:$PWD/build/ build/HelloWorldClient[23961.712646]~DLT~236711~INFO ~FIFO /tmp/dlt cannot be opened. Retrying later...[CAPI][INFO] Loading configuration file 'commonapi4someip.ini'[CAPI][INFO] Using default binding 'someip'[CAPI][INFO] Using default shared library folder '/usr/local/lib/commonapi'[CAPI][DEBUG] Loading library for local:commonapi.examples.HelloWorld:v0_1:commonapi.examples.HelloWorld proxy.[CAPI][INFO] Loading configuration file /etc//commonapi-someip.ini[CAPI][DEBUG] Added address mapping: local:commonapi.examples.HelloWorld:v0_1:commonapi.examples.HelloWorld <--> [1234.1234(0.1)][CAPI][VERBOSE] Registering function for creating "commonapi.examples.HelloWorld:v0_1" proxy.[CAPI][INFO] Registering function for creating "commonapi.examples.HelloWorld:v0_1" stub adapter.[CAPI][DEBUG] Loading interface library "libHelloWorld-someip.so" succeeded.[CAPI][VERBOSE] Creating proxy for "local:commonapi.examples.HelloWorld:v0_1:commonapi.examples.HelloWorld"2024-01-15 15:19:48.930730 [info] Parsed vsomeip configuration in 0ms2024-01-15 15:19:48.932947 [info] Configuration module loaded.2024-01-15 15:19:48.933987 [info] Security disabled!2024-01-15 15:19:48.934975 [info] Initializing vsomeip (3.4.10) application "client-sample".2024-01-15 15:19:48.936279 [info] Instantiating routing manager [Proxy].2024-01-15 15:19:48.937839 [info] Client [ffff] is connecting to [0] at /tmp/vsomeip-02024-01-15 15:19:48.943738 [info] vsomeip tracing not enabled. . vsomeip service discovery tracing not enabled. 2024-01-15 15:19:48.943958 [info] Application(client-sample, ffff) is initialized (11, 100).Checking availability!2024-01-15 15:19:48.947412 [info] Starting vsomeip application "client-sample" (ffff) using 2 threads I/O nice 2552024-01-15 15:19:48.950385 [info] io thread id from application: ffff (client-sample) is: 7f8b4b048640 TID: 2367172024-01-15 15:19:48.950519 [info] io thread id from application: ffff (client-sample) is: 7f8b49845640 TID: 2367202024-01-15 15:19:48.951232 [info] shutdown thread id from application: ffff (client-sample) is: 7f8b4a046640 TID: 2367192024-01-15 15:19:48.951872 [info] main dispatch thread id from application: ffff (client-sample) is: 7f8b4a847640 TID: 2367182024-01-15 15:19:48.955628 [info] create_local_server: Listening @ /tmp/vsomeip-10012024-01-15 15:19:48.956241 [info] Client 1001 (client-sample) successfully connected to routing ~> registering..2024-01-15 15:19:48.956510 [info] Registering to routing manager @ vsomeip-02024-01-15 15:19:48.963835 [info] Application/Client 1001 (client-sample) is registered.2024-01-15 15:19:48.048616 [info] ON_AVAILABLE(1001): [1234.1234:0.1]Available...2024-01-15 15:19:48.049840 [info] Client [1001] is connecting to [1000] at /tmp/vsomeip-1000[CAPI][DEBUG] Message sent: SenderID: 1234 - ClientID: 4097, SessionID: 1Got message: 'Hello World!'[CAPI][DEBUG] Message sent: SenderID: 1234 - ClientID: 4097, SessionID: 2Got message: 'Hello World!'
CommonAPI C   SomeIP in 10 minutes - COVESA/capicxx-someip-tools GitHub Wiki (2024)
Top Articles
Latest Posts
Article information

Author: Corie Satterfield

Last Updated:

Views: 6170

Rating: 4.1 / 5 (62 voted)

Reviews: 93% of readers found this page helpful

Author information

Name: Corie Satterfield

Birthday: 1992-08-19

Address: 850 Benjamin Bridge, Dickinsonchester, CO 68572-0542

Phone: +26813599986666

Job: Sales Manager

Hobby: Table tennis, Soapmaking, Flower arranging, amateur radio, Rock climbing, scrapbook, Horseback riding

Introduction: My name is Corie Satterfield, I am a fancy, perfect, spotless, quaint, fantastic, funny, lucky person who loves writing and wants to share my knowledge and understanding with you.