1 // Copyright (C) 2014-2017 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 #ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING
6 #include <csignal>
7 #endif
8 #include <chrono>
9 #include <condition_variable>
10 #include <iomanip>
11 #include <iostream>
12 #include <sstream>
13 #include <thread>
14 
15 #include <vsomeip/vsomeip.hpp>
16 
17 #include "sample-ids.hpp"
18 
19 class service_sample {
20 public:
service_sample(bool _use_static_routing)21     service_sample(bool _use_static_routing) :
22             app_(vsomeip::runtime::get()->create_application()),
23             is_registered_(false),
24             use_static_routing_(_use_static_routing),
25             blocked_(false),
26             running_(true),
27             offer_thread_(std::bind(&service_sample::run, this)) {
28     }
29 
init()30     bool init() {
31         std::lock_guard<std::mutex> its_lock(mutex_);
32 
33         if (!app_->init()) {
34             std::cerr << "Couldn't initialize application" << std::endl;
35             return false;
36         }
37         app_->register_state_handler(
38                 std::bind(&service_sample::on_state, this,
39                         std::placeholders::_1));
40         app_->register_message_handler(
41                 SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_METHOD_ID,
42                 std::bind(&service_sample::on_message, this,
43                         std::placeholders::_1));
44 
45         std::cout << "Static routing " << (use_static_routing_ ? "ON" : "OFF")
46                   << std::endl;
47         return true;
48     }
49 
start()50     void start() {
51         app_->start();
52     }
53 
54 #ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING
55     /*
56      * Handle signal to shutdown
57      */
stop()58     void stop() {
59         running_ = false;
60         blocked_ = true;
61         app_->clear_all_handler();
62         stop_offer();
63         condition_.notify_one();
64         offer_thread_.join();
65         app_->stop();
66     }
67 #endif
68 
offer()69     void offer() {
70         app_->offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
71         app_->offer_service(SAMPLE_SERVICE_ID + 1, SAMPLE_INSTANCE_ID);
72     }
73 
stop_offer()74     void stop_offer() {
75         app_->stop_offer_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
76         app_->stop_offer_service(SAMPLE_SERVICE_ID + 1, SAMPLE_INSTANCE_ID);
77     }
78 
on_state(vsomeip::state_type_e _state)79     void on_state(vsomeip::state_type_e _state) {
80         std::cout << "Application " << app_->get_name() << " is "
81                 << (_state == vsomeip::state_type_e::ST_REGISTERED ?
82                         "registered." : "deregistered.")
83                 << std::endl;
84 
85         if (_state == vsomeip::state_type_e::ST_REGISTERED) {
86             if (!is_registered_) {
87                 is_registered_ = true;
88                 blocked_ = true;
89                 condition_.notify_one();
90             }
91         } else {
92             is_registered_ = false;
93         }
94     }
95 
on_message(const std::shared_ptr<vsomeip::message> & _request)96     void on_message(const std::shared_ptr<vsomeip::message> &_request) {
97         std::cout << "Received a message with Client/Session [" << std::setw(4)
98             << std::setfill('0') << std::hex << _request->get_client() << "/"
99             << std::setw(4) << std::setfill('0') << std::hex
100             << _request->get_session() << "]"
101             << std::endl;
102 
103         std::shared_ptr<vsomeip::message> its_response
104             = vsomeip::runtime::get()->create_response(_request);
105 
106         std::shared_ptr<vsomeip::payload> its_payload
107             = vsomeip::runtime::get()->create_payload();
108         std::vector<vsomeip::byte_t> its_payload_data;
109         for (std::size_t i = 0; i < 120; ++i)
110             its_payload_data.push_back(static_cast<vsomeip::byte_t>(i % 256));
111         its_payload->set_data(its_payload_data);
112         its_response->set_payload(its_payload);
113 
114         app_->send(its_response);
115     }
116 
run()117     void run() {
118         std::unique_lock<std::mutex> its_lock(mutex_);
119         while (!blocked_)
120             condition_.wait(its_lock);
121 
122         bool is_offer(true);
123 
124         if (use_static_routing_) {
125             offer();
126             while (running_);
127         } else {
128             while (running_) {
129                 if (is_offer)
130                     offer();
131                 else
132                     stop_offer();
133 
134                 for (int i = 0; i < 10 && running_; i++)
135                     std::this_thread::sleep_for(std::chrono::milliseconds(1000));
136                 is_offer = !is_offer;
137             }
138         }
139     }
140 
141 private:
142     std::shared_ptr<vsomeip::application> app_;
143     bool is_registered_;
144     bool use_static_routing_;
145 
146     std::mutex mutex_;
147     std::condition_variable condition_;
148     bool blocked_;
149     bool running_;
150 
151     // blocked_ must be initialized before the thread is started.
152     std::thread offer_thread_;
153 };
154 
155 #ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING
156     service_sample *its_sample_ptr(nullptr);
handle_signal(int _signal)157     void handle_signal(int _signal) {
158         if (its_sample_ptr != nullptr &&
159                 (_signal == SIGINT || _signal == SIGTERM))
160             its_sample_ptr->stop();
161     }
162 #endif
163 
main(int argc,char ** argv)164 int main(int argc, char **argv) {
165     bool use_static_routing(false);
166 
167     std::string static_routing_enable("--static-routing");
168 
169     for (int i = 1; i < argc; i++) {
170         if (static_routing_enable == argv[i]) {
171             use_static_routing = true;
172         }
173     }
174 
175     service_sample its_sample(use_static_routing);
176 #ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING
177     its_sample_ptr = &its_sample;
178     signal(SIGINT, handle_signal);
179     signal(SIGTERM, handle_signal);
180 #endif
181     if (its_sample.init()) {
182         its_sample.start();
183         return 0;
184     } else {
185         return 1;
186     }
187 }
188