Copyright © 2015, Bayerische Motoren Werke Aktiengesellschaft (BMW AG)

License

This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

Version

This documentation was generated for version of vsomeip.

1. vsomeip Overview

The vsomeip stack implements the Scalable service-Oriented MiddlewarE over IP (SOME/IP) protocol. The stack consists out of:

  • a shared library for SOME/IP (libvsomeip.so)

  • a second shared library for SOME/IP’s service discovery (libvsomeip-sd.so) which is loaded during runtime if the service discovery is enabled.

2. Build Instructions

2.1. Dependencies

  • A C++11 enabled compiler like gcc >= 4.8 is needed.

  • vsomeip uses cmake as buildsystem.

  • vsomeip uses Boost >= 1.54:

    • Ubuntu 14.04:

      • sudo apt-get install libboost-system1.54-dev libboost-thread1.54-dev libboost-log1.54-dev

    • Ubuntu 12.04: a PPA is necessary to use version 1.54 of Boost:

  • For the tests Google’s test framework gtest in version 1.7.0 is needed

  • To build the documentation asciidoc, source-highlight, doxygen and graphviz is needed:

    • sudo apt-get install asciidoc source-highlight doxygen graphviz

2.2. Compilation

For compilation call:

mkdir build
cd build
cmake ..
make -j8

To specify a installation directory (like --prefix= if you’re used to autotools) call cmake like:

cmake -DCMAKE_INSTALL_PREFIX:PATH=$YOUR_PATH ..
make -j8
make install

2.2.1. Compilation of tests

To compile the tests, first unzip gtest to location of your desire. Then run:

mkdir build
cd build
export GTEST_ROOT=$PATH_TO_GTEST/gtest-1.7.0/
cmake ..
make check

Additional make targets for the tests:

  • Call make build_tests to only compile the tests

  • Call ctest in the build directory to execute the tests without a verbose output

  • To run single tests call ctest --verbose --tests-regex $TESTNAME short form: ctest -V -R $TESTNAME

  • To list all available tests run ctest -N.

  • For further information about the tests please have a look at the readme.txt in the test subdirectory.

2.2.2. Generating the documentation

To generate the documentation call cmake as described in [Compilation] and then call make doc. This will generate:

  • The README file in html: $BUILDDIR/documentation/README.html

  • A doxygen documentation in $BUILDDIR/documentation/html/index.html

3. Starting vsomeip Applications / Used environment variables

On startup the following environment variables are read out:

  • VSOMEIP_APPLICATION_NAME: This environment variable is used to specify the name of the application. This name is later used to map a client id to the application in the configuration file. It is independent from the application’s binary name.

  • VSOMEIP_CONFIGURATION_FILE: This environment variable can be used to specify a configuration file to be used by the application. If this variable is not defined the default configuration file /etc/vsomeip.json will be used.

In the following example the application my_vsomeip_application is started. The settings are read from the file my_settings.json in the current working directory. The client id for the application can be found under the name my_vsomeip_client in the configuration file.

#!/bin/bash
export VSOMEIP_APPLICATION_NAME=my_vsomeip_client
export VSOMEIP_CONFIGURATION_FILE=my_settings.json
./my_vsomeip_application

4. Configuration File Structure

The configuration files for vsomeip are JSON-Files and are composed out of multiple key value pairs and arrays.

  • An object is an unordered set of name/value pairs. An object begins with { (left brace) and ends with } (right brace). Each name is followed by : (colon) and the name/value pairs are separated by , (comma).

  • An array is an ordered collection of values. An array begins with [ (left bracket) and ends with ] (right bracket). Values are separated by , (comma).

  • A value can be a string in double quotes, or a number, or true or false or null, or an object or an array. These structures can be nested.

json.org

Configuration file element explanation:

  • unicast

    The IP address of the host system.

  • netmask

    The netmask to specify the subnet of the host system.

  • logging

    • level

      Specifies the log level (valid values: trace, debug, info, warning, error, fatal).

    • console

      Specifies whether logging via console is enabled (valid values: true, false).

    • file

      • enable

        Specifies whether a log file should be created (valid values: true, false).

      • path

        The absolute path of the log file.

    • dlt

      Specifies whether Diagnostic Log and Trace (DLT) is enabled (valid values: true, false).

  • applications (array)

    Contains the applications of the host system that use this config file.

    • name

      The name of the application.

    • id

      The id of the application.

    • num_dispatchers

      The number of threads that shall be used to execute the callbacks to the application. If num_dispatchers is set to 0, the callbacks will be executed within the application thread. If an application wants/must do time consuming work directly within event, availability or message callbacks, num_dispatchers should be set to 2 or higher.

  • servicegroups (array)

    Services can be grouped together into one service group. A service group contains the services of a specific service provider and its connection information.

    Note It is also possible to define multiple service groups to address services from different service providers.
    • name

      The name of the service group.

    • unicast

      The IP address of the service provider (valid values: local if the service provider is the local host otherwise the valid IP address of the remote service provider).

    • delays

      Contains delays related to the Service Discovery respectively to the service instances.

      Note The multicast messages of the Service Discovery come with the risk of overflowing the net with too many messages. Therefore, the Service Discovery can be configured with a suitable message sending behavior.
      • initial

        Note A Service instance goes through different phases. One phase is called Initial Wait Phase. This phase is entered when the service is fully available and waits for the messages of a client’s Service Discovery.
        • minimum

          Specifies the minimum time during which the messages of a client’s Service Discovery will be ignored (value in milliseconds).

        • maximum

          Specifies the maximum time during which the messages of a client’s Service Discovery will be ignored (value in milliseconds).

      • repetition-base

        Note On condition that the initial delay is over, the Repetition Phase is entered. In this phase the services will be offered repeatedly via multicast by the Service Discovery of the service provider.

        The repetition base delay specifies the time after that the first offer will be started to send (value in milliseconds).

      • repetition-max

        Specifies the amount of sent offers within the repetition phase.

      • cyclic-offer

        Note After the specific amount of repetitions, the Main Phase is entered. In the Main Phase the Service Discovery of the service provider starts with a cyclic offer of the services.

        The cyclic offer specifies the interval in which the services will be offered via multicast (value in milliseconds).

      • cyclic-request

        Specifies the cyclic-request-delay. Currently unused.

    • services (array)

      Contains the services of the service provider.

      • service

        The id of the service.

      • instance

        The id of the service instance.

      • reliable

        Specifies that the communication with the service is reliable respectively the TCP protocol is used for communication.

        • port

          The port of the TCP endpoint.

        • enable-magic-cookies

          Specifies whether magic cookies are enabled (valid values: true, false).

      • unreliable

        Specifies that the communication with the service is unreliable respectively the UDP protocol is used for communication (valid values: the port of the UDP endpoint).

      • multicast

        A service can be offered to a specific group of clients via multicast.

        • address

          The specific multicast address.

        • port

          The specific port.

      • events (array)

        Contains the events of the service.

        • event

          The id of the event.

          • is_field

            Specifies whether the event is of type field.

            Note A field is a combination of getter, setter and notification event. It contains at least a getter, a setter, or a notifier. The notifier sends an event message that transports the current value of a field on change.
          • is_reliable

            Specifies whether the communication is reliable respectively whether the event is sent with the TCP protocol (valid values: true,false).

            If the value is false the UDP protocol will be used.

      • eventgroups (array)

        Events can be grouped together into on event group. For a client it is thus possible to subscribe for an event group and to receive the appropriate events within the group.

        • eventgroup

          The id of the event group.

        • events (array)

          Contains the ids of the appropriate events.

        • is_multicast

          Specifies whether the events should be sent via multicast (valid values: true,false).

        • multicast

          The multicast address which the events are sent to.

  • routing

    The name of the application that is responsible for the routing.

  • service-discovery

    Contains settings related to the Service Discovery of the host application.

    • enable

      Specifies whether the Service Discovery is enabled ( valid values: true, false).

    • multicast

      The multicast address which the messages of the Service Discovery will be sent to.

    • port

      The port of the Service Discovery.

    • protocol

      The protocol that is used for sending the Service Discovery messages (valid values: tcp,udp)

5. vsomeip Hello World

In this paragraph a Hello World program consisting out of a client and a service is developed. The client sends a message containing a string to the service. The service appends the received string to the string Hello and sends it back to the client. Upon receiving a response from the service the client prints the payload of the response ("Hello World"). This example is intended to be run on the same host.

All files listed here are contained in the examples\hello_world subdirectory.

5.1. Build instructions

The example can build with its own CMakeFile, please compile the vsomeip stack before hand as described in [Compilation]. Then compile the example starting from the repository root directory as followed:

cd examples/hello_world
mkdir build
cd build
cmake ..
make

5.2. Starting and expected output

5.2.1. Starting and expected output of service

$ VSOMEIP_CONFIGURATION_FILE=../helloworld-local.json \
  VSOMEIP_APPLICATION_NAME=hello_world_service \
  ./hello_world_service
2015-04-01 11:31:13.248437 [info] Using configuration file: ../helloworld-local.json
2015-04-01 11:31:13.248766 [debug] Routing endpoint at /tmp/vsomeip-0
2015-04-01 11:31:13.248913 [info] Service Discovery disabled. Using static routing information.
2015-04-01 11:31:13.248979 [debug] Application(hello_world_service, 4444) is initialized.
2015-04-01 11:31:22.705010 [debug] Application/Client 5555 got registered!

5.2.2. Starting and expected output of client

$ VSOMEIP_CONFIGURATION_FILE=../helloworld-local.json \
  VSOMEIP_APPLICATION_NAME=hello_world_client \
  ./hello_world_client
2015-04-01 11:31:22.704166 [info] Using configuration file: ../helloworld-local.json
2015-04-01 11:31:22.704417 [debug] Connecting to [0] at /tmp/vsomeip-0
2015-04-01 11:31:22.704630 [debug] Listening at /tmp/vsomeip-5555
2015-04-01 11:31:22.704680 [debug] Application(hello_world_client, 5555) is initialized.
Sending: World
Received: Hello World

5.3. CMakeFile

# Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

cmake_minimum_required (VERSION 2.8.7)
project (vSomeIPHelloWorld)

# This will get us acces to
#   VSOMEIP_INCLUDE_DIRS - include directories for vSomeIP
#   VSOMEIP_LIBRARIES    - libraries to link against
find_package(vsomeip)
if (NOT vsomeip_FOUND)
    message("vsomeip was not found. Please specify vsomeip_DIR")
endif()

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

include_directories(${VSOMEIP_INCLUDE_DIRS})

add_executable (hello_world_service hello_world_service.cpp)
target_link_libraries(hello_world_service ${VSOMEIP_LIBRARIES})

add_executable (hello_world_client hello_world_client.cpp)
target_link_libraries(hello_world_client ${VSOMEIP_LIBRARIES})

5.4. Configuration File For Client and Service

{
   "unicast" : "134.86.56.94",
   "logging" :
   {
      "level" : "debug",
      "console" : "true"
   },

   "applications" :
   [
      {
         "name" : "hello_world_service",
         "id" : "0x4444"
      },

      {
         "name" : "hello_world_client",
         "id" : "0x5555"
      }
   ],

   "servicegroups" :
   [
      {
         "name" : "default",
         "unicast" : "local",
         "services" :
         [
            {
               "service" : "0x1111",
               "instance" : "0x2222",
               "unreliable" : "30509"
            }
         ]
      }
   ],

   "routing" : "hello_world_service",
   "service-discovery" :
   {
      "enable" : "false"
   }
}

5.5. Service

// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <vsomeip/vsomeip.hpp>

static vsomeip::service_t service_id = 0x1111;
static vsomeip::instance_t service_instance_id = 0x2222;
static vsomeip::method_t service_method_id = 0x3333;

class hello_world_service {
public:
    // Get the vSomeIP runtime and
    // create a application via the runtime, we could pass the application name
    // here otherwise the name supplied via the VSOMEIP_APPLICATION_NAME
    // environment variable is used
    hello_world_service() :
                    rtm_(vsomeip::runtime::get()),
                    app_(rtm_->create_application())
    {
    }

    void init()
    {
        // init the application
        app_->init();

        // register a message handler callback for messages sent to our service
        app_->register_message_handler(service_id, service_instance_id,
                service_method_id,
                std::bind(&hello_world_service::on_message_cbk, this,
                        std::placeholders::_1));

        // register an event handler to get called back after registration at the
        // runtime was successful
        app_->register_event_handler(
                std::bind(&hello_world_service::on_event_cbk, this,
                        std::placeholders::_1));
    }

    void start()
    {
        // start the application and wait for the on_event callback to be called
        // this method only returns when app_->stop() is called
        app_->start();
    }

    void stop()
    {
        // Stop offering the service
        app_->stop_offer_service(service_id, service_instance_id);
        // unregister the event handler
        app_->unregister_event_handler();
        // unregister the message handler
        app_->unregister_message_handler(service_id, service_instance_id,
                service_method_id);
        // shutdown the application
        app_->stop();
    }

    void on_event_cbk(vsomeip::event_type_e _event)
    {
        if(_event == vsomeip::event_type_e::ET_REGISTERED)
        {
            // we are registered at the runtime and can offer our service
            app_->offer_service(service_id, service_instance_id);
        }
    }

    void on_message_cbk(const std::shared_ptr<vsomeip::message> &_request)
    {
        // Create a response based upon the request
        std::shared_ptr<vsomeip::message> resp = rtm_->create_response(_request);

        // Construct string to send back
        std::string str("Hello ");
        str.append(
                reinterpret_cast<const char*>(_request->get_payload()->get_data()),
                0, _request->get_payload()->get_length());

        // Create a payload which will be sent back to the client
        std::shared_ptr<vsomeip::payload> resp_pl = rtm_->create_payload();
        std::vector<vsomeip::byte_t> pl_data(str.begin(), str.end());
        resp_pl->set_data(pl_data);
        resp->set_payload(resp_pl);

        // Send the response back
        app_->send(resp, true);
        // we're finished stop now
        stop();
    }

private:
    std::shared_ptr<vsomeip::runtime> rtm_;
    std::shared_ptr<vsomeip::application> app_;
};

int main(int argc, char **argv)
{
    hello_world_service hw_srv;
    hw_srv.init();
    hw_srv.start();
    return 0;
}

The service example results in the following program execution:

Main

  1. main() (line 101-107)

    First the application is initialized (line 104). After the initialization is finished the application is started (line 105).

Initialization

  1. init() (line 26-42)

    The initialization contains the registration of a message handler and an event handler.

    The message handler declares a callback (on_message_cbk) for messages that are sent to the specific service (specifying the service id, the service instance id and the service method id).

    The event handler declares a callback (on_event_cbk) for events that occur. One event can be the successful registration of the application at the runtime.

Start

  1. start() (line 44-49)

    The application will be started. This function only returns when the application will be stopped.

Callbacks

  1. on_event_cbk() (line 64-71)

    This function is called by the application when an event occurred. If the event is related to the successful registration of the application at the runtime then the specific service is offered.

  2. on_message_cbk() (line 73-94)

    This function is called when a message/request from a client for the specified service was received.

    First a response based upon the request is created (line 76). Afterwards the string Hello will be concatenated with the payload of the client’s request (line 80-82). After that the payload of the response is created (line 85). The payload data is set with the previously concatenated string (line 87). Finally the response is sent back to the client (line 91) and the application is stopped (line 93).

Stop

  1. stop() (line 51-62)

    This function stops offering the service (line 54), unregister the message and the event handler (line 56-59) and shuts down the application (line 61).

5.6. Client

// Copyright (C) 2015 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include <vsomeip/vsomeip.hpp>
#include <iostream>

static vsomeip::service_t service_id = 0x1111;
static vsomeip::instance_t service_instance_id = 0x2222;
static vsomeip::method_t service_method_id = 0x3333;

class hello_world_client {
public:
    // Get the vSomeIP runtime and
    // create a application via the runtime, we could pass the application name
    // here otherwise the name supplied via the VSOMEIP_APPLICATION_NAME
    // environment variable is used
    hello_world_client() :
                    rtm_(vsomeip::runtime::get()),
                    app_(rtm_->create_application())
    {
    }

    void init(){
        // init the application
        app_->init();

        // register an event handler to get called back after registration at the
        // runtime was successful
        app_->register_event_handler(
                std::bind(&hello_world_client::on_event_cbk, this,
                        std::placeholders::_1));

        // register a callback which is called as soon as the service is available
        app_->register_availability_handler(service_id, service_instance_id,
                std::bind(&hello_world_client::on_availability_cbk, this,
                        std::placeholders::_1, std::placeholders::_2,
                        std::placeholders::_3));

        // register a callback for responses from the service
        app_->register_message_handler(vsomeip::ANY_SERVICE,
                service_instance_id, vsomeip::ANY_METHOD,
                std::bind(&hello_world_client::on_message_cbk, this,
                        std::placeholders::_1));
    }

    void start()
    {
        // start the application and wait for the on_event callback to be called
        // this method only returns when app_->stop() is called
        app_->start();
    }

    void on_event_cbk(vsomeip::event_type_e _event)
    {
        if(_event == vsomeip::event_type_e::ET_REGISTERED)
        {
            // we are registered at the runtime now we can request the service
            // and wait for the on_availability callback to be called
            app_->request_service(service_id, service_instance_id);
        }
    }

    void on_availability_cbk(vsomeip::service_t _service,
            vsomeip::instance_t _instance, bool _is_available)
    {
        // Check if the available service is the the hello world service
        if(service_id == _service && service_instance_id == _instance
                && _is_available)
        {
            // The service is available then we send the request
            // Create a new request
            std::shared_ptr<vsomeip::message> rq = rtm_->create_request();
            // Set the hello world service as target of the request
            rq->set_service(service_id);
            rq->set_instance(service_instance_id);
            rq->set_method(service_method_id);

            // Create a payload which will be sent to the service
            std::shared_ptr<vsomeip::payload> pl = rtm_->create_payload();
            std::string str("World");
            std::vector<vsomeip::byte_t> pl_data(std::begin(str), std::end(str));

            pl->set_data(pl_data);
            rq->set_payload(pl);
            // Send the request to the service. Response will be delivered to the
            // registered message handler
            std::cout << "Sending: " << str << std::endl;
            app_->send(rq, true);
        }
    }

    void on_message_cbk(const std::shared_ptr<vsomeip::message> &_response)
    {
        if(service_id == _response->get_service()
                && service_instance_id == _response->get_instance()
                && vsomeip::message_type_e::MT_RESPONSE
                        == _response->get_message_type()
                && vsomeip::return_code_e::E_OK == _response->get_return_code())
        {
            // Get the payload and print it
            std::shared_ptr<vsomeip::payload> pl = _response->get_payload();
            std::string resp = std::string(
                    reinterpret_cast<const char*>(pl->get_data()), 0,
                    pl->get_length());
            std::cout << "Received: " << resp << std::endl;
            stop();
        }
    }

    void stop()
    {
        // unregister the event handler
        app_->unregister_event_handler();
        // unregister the message handler
        app_->unregister_message_handler(vsomeip::ANY_SERVICE,
                service_instance_id, vsomeip::ANY_METHOD);
        // shutdown the application
        app_->stop();
    }

private:
    std::shared_ptr<vsomeip::runtime> rtm_;
    std::shared_ptr<vsomeip::application> app_;
};

int main(int argc, char **argv)
{
    hello_world_client hw_cl;
    hw_cl.init();
    hw_cl.start();
    return 0;
}

The client example results in the following program execution:

Main

  1. main() (line 130-136)

    First the application is initialized (line 133). After the initialization is finished the application is started (line 134).

Initialization

  1. init() (line 27-48)

    The initialization contains the registration of a message handler, an event handler and an availability handler.

    The event handler declares again a callback (on_event_cbk) for events that occur.

    The message handler declares a callback (on_message_cbk) for messages that are received from any service, any service instance and any method.

    The availability handler declares a callback (on_availability_cbk) which is called when the specific service is available (specifying the service id and the service instance id).

Start

  1. start() (line 50-55)

    The application will be started. This function only returns when the application will be stopped.

Callbacks

  1. on_event_cbk() (line 57-65)

    This function is called by the application when an event occurred. If the event is related to the successful registration of the application at the runtime then the specific service is requested.

  2. on_availability_cbk() (line 67-94)

    This function is called when the requested service is available or no longer available.

    First there is a check if the change of the availability is related to the hello world service and the availability changed to true. If the check is successful a service request is created and the appropriate service information are set (service id, service instance id, service method id) (line 76-80). After that the payload of the request is created (line 83). The data of the payload is World and will be set afterwards (line 84-87). Finally the request is sent to the service.

  3. on_message_cbk() (line 73-94)

    This function is called when a message/response was received. If the response is from the requested service, of type RESPONSE and the return code is OK (line 98-103) then the payload of the response is printed (line 105-109). Finally the application is stopped.

Stop

  1. stop() (line 114-123)

    This function unregister the event and the message handler (line 117-120) and shuts down the application (line 122).