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