vsomeip icon indicating copy to clipboard operation
vsomeip copied to clipboard

Failed to handle eventgroup subscription for multiple routing managers within single process

Open zhaoxin39913 opened this issue 2 years ago • 8 comments

Hi vsomeip experts:

Currently I am trying to test multiple routing managers in V3.3.8 and V3.4.9-r1 (with build option ENABLE_MULTIPLE_ROUTING_MANAGERS=1) in single process for VLAN user case. However I encountered eventgroup subscription error in my test. Here are my test setup:

Server Device: Simply modify example code "notify-sample.cpp" to create 2 vsomeip instances in notify-sample process, each instance has a dedicated JSON file to bind its own IP address in different VLAN. instance 1 (in VLAN 1):

name: "notify_sample_1" 
file: "notify_sample_1.json"
unicast : "10.10.1.104"
netmask : "255.255.255.0"
multicast: 225.0.0.1
device: "eth0.1"

instance 2 (in VLAN 2):

name: "notify_sample_2"
file: notify_sample_2.json
unicast: "10.10.2.104"
netmask: "255.255.255.0"
multicast: 226.0.0.1
device: "eth0.2"

Client Device 1 (in VLAN 1): subscribe-sample process -> notify_sample_1

unicast: "10.10.1.101"
netmask: "255.255.255.0"
multicast: 225.0.0.1

Client Device 2 (in VLAN 2): subscribe-sample process -> notify_sample_2

unicast: "10.10.2.102"
netmask: "255.255.255.0"
multicast: 226.0.0.1

On Server device side I run below command which starts 2 vsomeip instances in notify-sample process but always get below error logs. However I didn't see such issue if I run notify_sample_1 and notify_sample_2 in separate processes. I think it should be a bug.

zhax@zhax-desktop:~/work/COVESA/src/vsomeip/build/examples$ VSOMEIP_CONFIGURATION_notify_sample_1=./notify_sample_1.json VSOMEIP_CONFIGURATION_notify_sample_2=./notify_sample_2.json ./notify-sample
2023-10-18 17:10:47.250235 [info] Using configuration file: "./notify_sample_1.json".
2023-10-18 17:10:47.252889 [info] Parsed vsomeip configuration in 1ms
2023-10-18 17:10:47.253443 [info] Initializing vsomeip (3.3.8) application "notify_sample_1".
2023-10-18 17:10:47.254329 [info] Instantiating routing manager [Host].
2023-10-18 17:10:47.257402 [info] create_routing_root: Routing root @ /tmp/notify_sample_1-0
2023-10-18 17:10:47.260614 [info] Service Discovery enabled. Trying to load module.
2023-10-18 17:10:47.269711 [info] Service Discovery module loaded.
2023-10-18 17:10:47.271031 [info] Application(notify_sample_1, 0111) is initialized (11, 100).
2023-10-18 17:10:47.271592 [info] offer_event: Event [1234.5678.8778] uses configured cycle time 0ms
2023-10-18 17:10:47.272285 [info] REGISTER EVENT(0111): [1234.5678.8778:is_provider=true]
2023-10-18 17:10:47.273334 [info] OFFER(0111): [1234.5678:0.0] (true)
2023-10-18 17:10:47.277271 [info] Starting vsomeip application "notify_sample_1" (0111) using 2 threads I/O nice 255
2023-10-18 17:10:47.278073 [info] create_local_server: Listening @ /tmp/notify_sample_1-111
Setting event (Length=1).
2023-10-18 17:10:47.283114 [info] main dispatch thread id from application: 0111 (notify_sample_1) is: ffffb260f100 TID: 700048
2023-10-18 17:10:47.284613 [info] Using configuration file: "./notify_sample_2.json".
2023-10-18 17:10:47.284034 [info] Client [0111] routes unicast:10.10.1.104, netmask:255.255.255.0
2023-10-18 17:10:47.284963 [info] shutdown thread id from application: 0111 (notify_sample_1) is: ffffb1dff100 TID: 700049
2023-10-18 17:10:47.290826 [info] Watchdog is disabled!
Application notify_sample_1 is registered.
2023-10-18 17:10:47.292896 [info] io thread id from application: 0111 (notify_sample_1) is: ffffb2e1f100 TID: 700047
2023-10-18 17:10:47.293133 [info] io thread id from application: 0111 (notify_sample_1) is: ffffb0ddf100 TID: 700051
2023-10-18 17:10:47.295273 [info] vSomeIP 3.3.8 | (default)
2023-10-18 17:10:47.296075 [info] Parsed vsomeip configuration in 0ms
2023-10-18 17:10:47.296569 [info] Initializing vsomeip (3.3.8) application "notify_sample_2".
2023-10-18 17:10:47.296655 [info] Network interface "eth0.1" state changed: up
2023-10-18 17:10:47.297433 [info] Instantiating routing manager [Host].
2023-10-18 17:10:47.300810 [info] create_routing_root: Routing root @ /tmp/notify_sample_2-0
2023-10-18 17:10:47.301189 [info] Route "225.0.0.1/32 if: eth0.1 gw: n/a" state changed: up
2023-10-18 17:10:47.302513 [info] udp_server_endpoint_impl: SO_RCVBUF is: 212992 (1703936) local port:30490
2023-10-18 17:10:47.302670 [info] Service Discovery enabled. Trying to load module.
2023-10-18 17:10:47.303517 [info] Service Discovery module loaded.
2023-10-18 17:10:47.304173 [info] Application(notify_sample_2, 0222) is initialized (11, 100).
2023-10-18 17:10:47.304552 [info] offer_event: Event [1234.5678.8778] uses configured cycle time 0ms
2023-10-18 17:10:47.305105 [info] REGISTER EVENT(0222): [1234.5678.8778:is_provider=true]
2023-10-18 17:10:47.306189 [info] udp_server_endpoint_impl<multicast>: SO_RCVBUF is: 212992 (1703936) local port:30490
2023-10-18 17:10:47.305636 [info] OFFER(0222): [1234.5678:0.0] (true)
2023-10-18 17:10:47.307542 [info] Starting vsomeip application "notify_sample_2" (0222) using 2 threads I/O nice 255
2023-10-18 17:10:47.308853 [info] udp_server_endpoint_impl: SO_RCVBUF is: 212992 (1703936) local port:31000
2023-10-18 17:10:47.309829 [info] SOME/IP routing ready.
2023-10-18 17:10:47.310128 [info] create_local_server: Listening @ /tmp/notify_sample_2-222
2023-10-18 17:10:47.310398 [info] main dispatch thread id from application: 0222 (notify_sample_2) is: ffff9afdf100 TID: 700054
Setting event (Length=1).
2023-10-18 17:10:47.312169 [info] shutdown thread id from application: 0222 (notify_sample_2) is: ffff9a7cf100 TID: 700055
2023-10-18 17:10:47.311274 [info] Client [0222] routes unicast:10.10.2.104, netmask:255.255.255.0
2023-10-18 17:10:47.317509 [info] Watchdog is disabled!
Application notify_sample_2 is registered.
2023-10-18 17:10:47.319367 [info] io thread id from application: 0222 (notify_sample_2) is: ffff9b7ef100 TID: 700053
2023-10-18 17:10:47.319586 [info] io thread id from application: 0222 (notify_sample_2) is: ffff997af100 TID: 700057
2023-10-18 17:10:47.321523 [info] vSomeIP 3.3.8 | (default)
2023-10-18 17:10:47.322680 [info] Network interface "eth0.2" state changed: up
2023-10-18 17:10:47.327182 [info] Route "226.0.0.1/32 if: eth0.2 gw: n/a" state changed: up
2023-10-18 17:10:47.328601 [info] udp_server_endpoint_impl: SO_RCVBUF is: 212992 (1703936) local port:30490
2023-10-18 17:10:47.331466 [info] udp_server_endpoint_impl: SO_RCVBUF is: 212992 (1703936) local port:31000
2023-10-18 17:10:47.331911 [info] udp_server_endpoint_impl<multicast>: SO_RCVBUF is: 212992 (1703936) local port:30490
2023-10-18 17:10:47.332400 [info] SOME/IP routing ready.
2023-10-18 17:10:47.408465 [info] REMOTE SUBSCRIBE(0000): [1234.5678.4465] from 10.10.2.102:58489 unreliable was accepted
2023-10-18 17:10:47.439834 [error] Subscriber's IP isn't in the same subnet as host's IP: 10.10.1.101
2023-10-18 17:10:47.441636 [error] process_eventgroupentry: Invalid port or IP address in first IPv4 endpoint option specified! 10.10.1.101 session: 4eb8
2023-10-18 17:10:47.479655 [error] Subscriber's IP isn't in the same subnet as host's IP: 10.10.1.101
2023-10-18 17:10:47.481430 [error] process_eventgroupentry: Invalid port or IP address in first IPv4 endpoint option specified! 10.10.1.101 session: 4eb9
2023-10-18 17:10:47.540820 [error] Subscriber's IP isn't in the same subnet as host's IP: 10.10.1.101
2023-10-18 17:10:47.542072 [error] process_eventgroupentry: Invalid port or IP address in first IPv4 endpoint option specified! 10.10.1.101 session: 4eba
2023-10-18 17:10:47.542667 [error] Subscriber's IP isn't in the same subnet as host's IP: 10.10.1.101
2023-10-18 17:10:47.543188 [error] process_eventgroupentry: Invalid port or IP address in first IPv4 endpoint option specified! 10.10.1.101 session: 4eba
2023-10-18 17:10:47.362790 [error] Subscriber's IP isn't in the same subnet as host's IP: 10.10.1.101
2023-10-18 17:10:47.365337 [error] process_eventgroupentry: Invalid port or IP address in first IPv4 endpoint option specified! 10.10.1.101 session: 4ebb
2023-10-18 17:10:47.366320 [error] Subscriber's IP isn't in the same subnet as host's IP: 10.10.1.101
2023-10-18 17:10:47.366979 [error] process_eventgroupentry: Invalid port or IP address in first IPv4 endpoint option specified! 10.10.1.101 session: 4ebb
2023-10-18 17:10:48.361428 [error] Subscriber's IP isn't in the same subnet as host's IP: 10.10.1.101
2023-10-18 17:10:48.362970 [error] process_eventgroupentry: Invalid port or IP address in first IPv4 endpoint option specified! 10.10.1.101 session: 4ebc
2023-10-18 17:10:48.363717 [error] Subscriber's IP isn't in the same subnet as host's IP: 10.10.1.101
2023-10-18 17:10:48.364294 [error] process_eventgroupentry: Invalid port or IP address in first IPv4 endpoint option specified! 10.10.1.101 session: 4ebc
Setting event (Length=2).
Setting event (Length=2).

notify-sample.cpp

 // Copyright (C) 2014-2017 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/.
 #ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING
 #include <csignal>
 #endif
 #include <chrono>
 #include <condition_variable>
 #include <iomanip>
 #include <iostream>
 #include <sstream>
 #include <thread>
 #include <mutex>
 
 #include <vsomeip/vsomeip.hpp>
 
 #include "sample-ids.hpp"
 
 #define VLAN_1_SUPPORT
 #define VLAN_2_SUPPORT
 //#define VLAN_3_SUPPORT
 
 class service_sample {
 public:
     service_sample(uint32_t _cycle, uint32_t _vlan, std::string _appName) :
             app_(vsomeip::runtime::get()->create_application(_appName)),
             is_registered_(false),
             cycle_(_cycle),
             vlan_(_vlan),
             blocked_(false),
             running_(true),
             is_offered_(false),
             offer_thread_(std::bind(&service_sample::run, this)),
             notify_thread_(std::bind(&service_sample::notify, this)) {
     }

    bool init() {
        std::lock_guard<std::mutex> its_lock(mutex_);

        if (!app_->init()) {
            std::cerr << "Couldn't initialize application" << std::endl;
            return false;
        }
        app_->register_state_handler(
                std::bind(&service_sample::on_state, this,
                        std::placeholders::_1));

        app_->register_message_handler(
                SAMPLE_SERVICE_ID,
                SAMPLE_INSTANCE_ID,
                SAMPLE_GET_METHOD_ID,
                std::bind(&service_sample::on_get, this,
                          std::placeholders::_1));

        app_->register_message_handler(
                SAMPLE_SERVICE_ID,
                SAMPLE_INSTANCE_ID,
                SAMPLE_SET_METHOD_ID,
                std::bind(&service_sample::on_set, this,
                          std::placeholders::_1));

        std::set<vsomeip::eventgroup_t> its_groups;
        its_groups.insert(SAMPLE_EVENTGROUP_ID);
        app_->offer_event(
                SAMPLE_SERVICE_ID,
                SAMPLE_INSTANCE_ID,
                SAMPLE_EVENT_ID,
                its_groups,
                vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(),
                false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN);
        {
            std::lock_guard<std::mutex> its_lock(payload_mutex_);
            payload_ = vsomeip::runtime::get()->create_payload();
        }

        blocked_ = true;
        condition_.notify_one();
        return true;
    }

    void start() {
        app_->start();
    }

#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING
    /*
     * Handle signal to shutdown
     */
    void stop() {
        running_ = false;
        blocked_ = true;
        condition_.notify_one();
        notify_condition_.notify_one();
        app_->clear_all_handler();
        stop_offer();
        offer_thread_.join();
        notify_thread_.join();
        app_->stop();
    }
#endif

    void offer() {
        std::lock_guard<std::mutex> its_lock(notify_mutex_);
        app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
        is_offered_ = true;
        notify_condition_.notify_one();
    }

    void stop_offer() {
        app_->stop_offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
        is_offered_ = false;
    }

    void on_state(vsomeip::state_type_e _state) {
        std::cout << "Application " << app_->get_name() << " is "
        << (_state == vsomeip::state_type_e::ST_REGISTERED ?
                "registered." : "deregistered.") << std::endl;

        if (_state == vsomeip::state_type_e::ST_REGISTERED) {
            if (!is_registered_) {
                is_registered_ = true;
            }
        } else {
            is_registered_ = false;
        }
    }

    void on_get(const std::shared_ptr<vsomeip::message> &_message) {
        std::shared_ptr<vsomeip::message> its_response
            = vsomeip::runtime::get()->create_response(_message);
        {
            std::lock_guard<std::mutex> its_lock(payload_mutex_);
            its_response->set_payload(payload_);
        }
        app_->send(its_response);
    }

    void on_set(const std::shared_ptr<vsomeip::message> &_message) {
        std::shared_ptr<vsomeip::message> its_response
            = vsomeip::runtime::get()->create_response(_message);
        {
            std::lock_guard<std::mutex> its_lock(payload_mutex_);
            payload_ = _message->get_payload();
            its_response->set_payload(payload_);
        }

        app_->send(its_response);
        app_->notify(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID,
                     SAMPLE_EVENT_ID, payload_);
    }

    void run() {
        std::unique_lock<std::mutex> its_lock(mutex_);
        while (!blocked_)
            condition_.wait(its_lock);

        bool is_offer(true);
        while (running_) {
            if (is_offer)
                offer();
            else
                stop_offer();

            for (int i = 0; i < 10 && running_; i++)
                std::this_thread::sleep_for(std::chrono::milliseconds(1000));

            is_offer = !is_offer;
        }
    }

    void notify() {

        vsomeip::byte_t its_data[10];
        uint32_t its_size = 1;

        while (running_) {
            std::unique_lock<std::mutex> its_lock(notify_mutex_);
            while (!is_offered_ && running_)
                notify_condition_.wait(its_lock);
            while (is_offered_ && running_) {
                if (its_size == sizeof(its_data))
                    its_size = 1;

                for (uint32_t i = 0; i < its_size; ++i)
                    its_data[i] = static_cast<uint8_t>(i);

                {
                    std::lock_guard<std::mutex> its_lock(payload_mutex_);
                    payload_->set_data(its_data, its_size);

                    std::cout << "Setting event (Length=" << std::dec << its_size << ")." << std::endl;
                    app_->notify(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID, payload_);
                }

                its_size++;

                std::this_thread::sleep_for(std::chrono::milliseconds(cycle_));
            }
        }
    }

private:
    std::shared_ptr<vsomeip::application> app_;
    bool is_registered_;
    uint32_t cycle_;
    uint32_t vlan_;

    std::mutex mutex_;
    std::condition_variable condition_;
    bool blocked_;
    bool running_;

    std::mutex notify_mutex_;
    std::condition_variable notify_condition_;
    bool is_offered_;

    std::mutex payload_mutex_;
    std::shared_ptr<vsomeip::payload> payload_;

    // blocked_ / is_offered_ must be initialized before starting the threads!
    std::thread offer_thread_;
    std::thread notify_thread_;
};

#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING
#ifdef VLAN_1_SUPPORT
    service_sample *its_sample1_ptr(nullptr); // VLAN 1
#endif
#ifdef VLAN_2_SUPPORT
    service_sample *its_sample2_ptr(nullptr); // VLAN 2
#endif
#ifdef VLAN_3_SUPPORT
    service_sample *its_sample3_ptr(nullptr); // VLAN 3
#endif
    void handle_signal(int _signal) {
    if (_signal == SIGINT || _signal == SIGTERM)
    {
#ifdef VLAN_1_SUPPORT
        its_sample1_ptr->stop();
#endif
#ifdef VLAN_2_SUPPORT
        its_sample2_ptr->stop();
#endif
#ifdef VLAN_3_SUPPORT
        its_sample3_ptr->stop();
#endif
    }
}
#endif

int main(int argc, char **argv) {
    uint32_t cycle = 1000; // default 1s

    std::string cycle_arg("--cycle");

    for (int i = 1; i < argc; i++) {
        if (cycle_arg == argv[i] && i + 1 < argc) {
            i++;
            std::stringstream converter;
            converter << argv[i];
            converter >> cycle;
        }
    }

#ifdef VLAN_1_SUPPORT
    service_sample its_sample1(cycle, 1, "notify_sample_1");
#endif
#ifdef VLAN_2_SUPPORT
    service_sample its_sample2(cycle, 2, "notify_sample_2");
#endif
#ifdef VLAN_3_SUPPORT
    service_sample its_sample3(cycle, 3, "notify_sample_3");
#endif

#ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING
#ifdef VLAN_1_SUPPORT
    its_sample1_ptr = &its_sample1;
#endif
#ifdef VLAN_2_SUPPORT
    its_sample2_ptr = &its_sample2;
#endif
#ifdef VLAN_3_SUPPORT
    its_sample3_ptr = &its_sample3;
#endif

    signal(SIGINT, handle_signal);
    signal(SIGTERM, handle_signal);
#endif

#ifdef VLAN_1_SUPPORT
    if (its_sample1.init())
    {
        std::thread t1(&service_sample::start, &its_sample1);
        t1.detach();
    }
#endif
#ifdef VLAN_2_SUPPORT
    if (its_sample2.init())
    { 
        std::thread t2(&service_sample::start, &its_sample2);
        t2.detach();
    }
#endif
#ifdef VLAN_3_SUPPORT
    if (its_sample3.init())
    {
        std::thread t3(&service_sample::start, &its_sample3);
        t3.detach();
    }
#endif
    while(1)
    {std::this_thread::sleep_for(std::chrono::milliseconds(1000));}
    return 0;
}

notify_sample_1.json

{
    "unicast" : "10.10.1.104",
    "netmask" : "255.255.255.0",
    "applications" : 
    [
        {
            "name" : "notify_sample_1",
            "id" : "0x111"
        }
    ],
    "services" :
    [
        {
            "service" : "0x1234",
            "instance" : "0x5678",
            "unreliable" : "31000",
            "eventgroups" :
            [
                {
		    "eventgroup" : "0x4465",
                    "multicast" : { "address" : "238.238.0.1", "port" : "45678" },
                    "threshold" : "1"
                }
            ]
        }
    ],
    "routing" : "notify_sample_1",
    "network" : "notify_sample_1",
    "service-discovery" :
    {
        "enable" : "true",
        "multicast" : "225.0.0.1",
        "port" : "30490",
        "protocol" : "udp",
        "initial_delay_min" : "10",
        "initial_delay_max" : "100",
        "repetitions_base_delay" : "200",
        "repetitions_max" : "3",
        "ttl" : "3",
        "cyclic_offer_delay" : "2000",
        "request_response_delay" : "1500"
    }
}

notify_sample_2.json

{
    "unicast" : "10.10.2.104",
    "netmask" : "255.255.255.0",
    "applications" : 
    [
        {
            "name" : "notify_sample_2",
            "id" : "0x222"
        }            
    ],
    "services" :
    [
        {
            "service" : "0x1234",
            "instance" : "0x5678",
            "unreliable" : "31000",
            "eventgroups" :
            [
                {
		    "eventgroup" : "0x4466",
                    "multicast" : { "address" : "238.238.0.1", "port" : "45678" },
                    "threshold" : "1"
                }
            ]
        }
    ],
    "routing" : "notify_sample_2",
    "network" : "notify_sample_2",
    "service-discovery" :
    {
        "enable" : "true",
        "multicast" : "226.0.0.1",
        "port" : "30490",
        "protocol" : "udp",
        "initial_delay_min" : "10",
        "initial_delay_max" : "100",
        "repetitions_base_delay" : "200",
        "repetitions_max" : "3",
        "ttl" : "3",
        "cyclic_offer_delay" : "2000",
        "request_response_delay" : "1500"
    }
}

zhaoxin39913 avatar Oct 18 '23 10:10 zhaoxin39913

Can this bug be fixed in upcoming release? We would like to enable multiple routing managers within single process.

zhaoxin39913 avatar Nov 03 '23 02:11 zhaoxin39913

Hi COVESA team,

This issue is getting fixed by commenting out below code (between "#if 0" and "endif") in below function in service_discovery_impl.cpp. Could you please check if the change is reasonable or not?

bool service_discovery_impl::check_ipv4_address(
        const boost::asio::ip::address& its_address) const {
    //Check unallowed ipv4 address
    bool is_valid = true;

    static const boost::asio::ip::address_v4::bytes_type its_unicast_address =
            unicast_.to_v4().to_bytes();
    const boost::asio::ip::address_v4::bytes_type endpoint_address =
            its_address.to_v4().to_bytes();
#if 0
    static const boost::asio::ip::address_v4::bytes_type its_netmask =
            configuration_->get_netmask().to_v4().to_bytes();
#endif
    //same address as unicast address of DUT not allowed
    if (its_unicast_address == endpoint_address) {
        VSOMEIP_ERROR << "Subscriber's IP address is same as host's address! : "
                << its_address;
        is_valid = false;
    } else {
#if 0
        const std::uint32_t self = VSOMEIP_BYTES_TO_LONG(its_unicast_address[0],
                its_unicast_address[1], its_unicast_address[2], its_unicast_address[3]);
        const std::uint32_t remote = VSOMEIP_BYTES_TO_LONG(endpoint_address[0],
                endpoint_address[1], endpoint_address[2], endpoint_address[3]);
        const std::uint32_t netmask = VSOMEIP_BYTES_TO_LONG(its_netmask[0],
                its_netmask[1], its_netmask[2], its_netmask[3]);
        if ((self & netmask) != (remote & netmask)) {
            VSOMEIP_ERROR<< "Subscriber's IP isn't in the same subnet as host's IP: "
                    << its_address;
            is_valid = false;
#endif
        }
    }
    return is_valid;
}

zhaoxin39913 avatar Jan 17 '24 05:01 zhaoxin39913

@zhaoxin39913 , I also faced the same issue , Is that issue get resolved on with the mentioned solution Do we have any updated version on this?

vramasubbu avatar Feb 16 '24 09:02 vramasubbu

@zhaoxin39913 , I also faced the same issue , Is that issue get resolved on with the mentioned solution Do we have any updated version on this?

I see this is already fixed in latest branch but not tagged yet.

zhaoxin39913 avatar Apr 09 '24 04:04 zhaoxin39913