1 // Copyright (C) 2015-2019 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
2 // This Source Code Form is subject to the terms of the Mozilla Public
3 // License, v. 2.0. If a copy of the MPL was not distributed with this
4 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 
6 #include <atomic>
7 
8 #include "../npdu_tests/npdu_test_rmd.hpp"
9 
10 #include <vsomeip/internal/logger.hpp>
11 #include "npdu_test_globals.hpp"
12 
13 #include "../npdu_tests/npdu_test_globals.hpp"
14 
npdu_test_rmd()15 npdu_test_rmd::npdu_test_rmd() :
16     app_(vsomeip::runtime::get()->create_application()),
17     is_registered_(false),
18     blocked_(false),
19     offer_thread_(std::bind(&npdu_test_rmd::run, this))
20 {
21     // TODO Auto-generated constructor stub
22 }
23 
init()24 void npdu_test_rmd::init() {
25     std::lock_guard<std::mutex> its_lock(mutex_);
26 
27     app_->init();
28 
29 #ifdef RMD_CLIENT_SIDE
30     app_->register_message_handler(npdu_test::RMD_SERVICE_ID_CLIENT_SIDE,
31 #elif defined (RMD_SERVICE_SIDE)
32     app_->register_message_handler(npdu_test::RMD_SERVICE_ID_SERVICE_SIDE,
33 #endif
34             npdu_test::RMD_INSTANCE_ID, npdu_test::RMD_SHUTDOWN_METHOD_ID,
35             std::bind(&npdu_test_rmd::on_message_shutdown,
36                     this, std::placeholders::_1));
37 
38     app_->register_state_handler(
39             std::bind(&npdu_test_rmd::on_state, this,
40                     std::placeholders::_1));
41 }
42 
start()43 void npdu_test_rmd::start() {
44     VSOMEIP_INFO << "Starting...";
45     app_->start();
46 }
47 
stop()48 void npdu_test_rmd::stop() {
49     VSOMEIP_INFO << "Stopping...";
50 
51     app_->unregister_message_handler(npdu_test::RMD_SERVICE_ID_CLIENT_SIDE,
52             npdu_test::RMD_INSTANCE_ID, npdu_test::RMD_SHUTDOWN_METHOD_ID);
53     app_->unregister_state_handler();
54     offer_thread_.join();
55     app_->stop();
56 }
57 
on_state(vsomeip::state_type_e _state)58 void npdu_test_rmd::on_state(
59         vsomeip::state_type_e _state) {
60     VSOMEIP_INFO << "Application " << app_->get_name() << " is "
61             << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." :
62                     "deregistered.");
63 
64     if(_state == vsomeip::state_type_e::ST_REGISTERED)
65     {
66         if(!is_registered_)
67         {
68             std::lock_guard<std::mutex> its_lock(mutex_);
69             is_registered_ = true;
70             blocked_ = true;
71             // "start" the run method thread
72             condition_.notify_one();
73         }
74     }
75     else
76     {
77         is_registered_ = false;
78     }
79 }
80 
on_message_shutdown(const std::shared_ptr<vsomeip::message> & _request)81 void npdu_test_rmd::on_message_shutdown(
82         const std::shared_ptr<vsomeip::message>& _request) {
83     (void)_request;
84     std::shared_ptr<vsomeip::message> request = vsomeip::runtime::get()->create_request(false);
85 #ifdef RMD_CLIENT_SIDE
86     static int counter = 0;
87     counter++;
88     VSOMEIP_INFO << counter << " of " << npdu_test::client_ids_clients.size()
89             << " clients are finished.";
90 
91     if (counter == npdu_test::client_ids_clients.size()) {
92         VSOMEIP_INFO << "All clients are finished, notify routing manager daemon on service side.";
93         // notify the RMD_SERVICE_SIDE that he can shutdown as well
94         std::this_thread::sleep_for(std::chrono::seconds(1));
95         request->set_service(npdu_test::RMD_SERVICE_ID_SERVICE_SIDE);
96         request->set_instance(npdu_test::RMD_INSTANCE_ID);
97         request->set_method(npdu_test::RMD_SHUTDOWN_METHOD_ID);
98         request->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN);
99         app_->send(request);
100         std::this_thread::sleep_for(std::chrono::seconds(5));
101         stop();
102     }
103 #elif defined RMD_SERVICE_SIDE
104     VSOMEIP_INFO << "All clients are finished shutting down services";
105     // shutdown all services
106     for(unsigned int i = 0; i < npdu_test::service_ids.size(); i++) {
107         request->set_service(npdu_test::service_ids[i]);
108         request->set_instance(npdu_test::instance_ids[i]);
109         request->set_method(npdu_test::NPDU_SERVICE_SHUTDOWNMETHOD_ID);
110         request->set_message_type(vsomeip::message_type_e::MT_REQUEST_NO_RETURN);
111         app_->send(request);
112     }
113     app_->stop_offer_service(npdu_test::RMD_SERVICE_ID_SERVICE_SIDE, npdu_test::RMD_INSTANCE_ID);
114 
115     VSOMEIP_INFO << "Wait a few seconds until all services are shutdown.";
116     std::atomic<bool> finished(false);
117     for (int i = 0; !finished && i < 20; i++) {
118         app_->get_offered_services_async(
119                 vsomeip::offer_type_e::OT_REMOTE,
120                 [&](const std::vector<std::pair<vsomeip::service_t,
121                                                 vsomeip::instance_t>> &_services){
122             if (_services.empty()) {
123                 finished = true;
124             }
125         });
126         std::this_thread::sleep_for(std::chrono::seconds(1));
127     }
128     stop();
129 #endif
130 }
131 
join_shutdown_thread()132 void npdu_test_rmd::join_shutdown_thread() {
133     shutdown_thread_.join();
134 }
135 
run()136 void npdu_test_rmd::run() {
137     std::unique_lock<std::mutex> its_lock(mutex_);
138     while (!blocked_)
139         condition_.wait(its_lock);
140 #ifdef RMD_CLIENT_SIDE
141     app_->offer_service(npdu_test::RMD_SERVICE_ID_CLIENT_SIDE, npdu_test::RMD_INSTANCE_ID);
142 #elif defined (RMD_SERVICE_SIDE)
143     app_->offer_service(npdu_test::RMD_SERVICE_ID_SERVICE_SIDE, npdu_test::RMD_INSTANCE_ID);
144 #endif
145 }
146 
TEST(someip_npdu_test,offer_routing_manager_functionality)147 TEST(someip_npdu_test, offer_routing_manager_functionality)
148 {
149     npdu_test_rmd daemon;
150     daemon.init();
151     daemon.start();
152 }
153 
main(int argc,char ** argv)154 int main(int argc, char** argv)
155 {
156     ::testing::InitGoogleTest(&argc, argv);
157     return RUN_ALL_TESTS();
158 }
159 
160 
161