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 client_sample {
20 public:
client_sample(bool _use_tcp)21 client_sample(bool _use_tcp) :
22 app_(vsomeip::runtime::get()->create_application()), use_tcp_(
23 _use_tcp) {
24 }
25
init()26 bool init() {
27 if (!app_->init()) {
28 std::cerr << "Couldn't initialize application" << std::endl;
29 return false;
30 }
31 std::cout << "Client settings [protocol="
32 << (use_tcp_ ? "TCP" : "UDP")
33 << "]"
34 << std::endl;
35
36 app_->register_state_handler(
37 std::bind(&client_sample::on_state, this,
38 std::placeholders::_1));
39
40 app_->register_message_handler(
41 vsomeip::ANY_SERVICE, SAMPLE_INSTANCE_ID, vsomeip::ANY_METHOD,
42 std::bind(&client_sample::on_message, this,
43 std::placeholders::_1));
44
45 app_->register_availability_handler(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID,
46 std::bind(&client_sample::on_availability,
47 this,
48 std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
49
50 std::set<vsomeip::eventgroup_t> its_groups;
51 its_groups.insert(SAMPLE_EVENTGROUP_ID);
52 app_->request_event(
53 SAMPLE_SERVICE_ID,
54 SAMPLE_INSTANCE_ID,
55 SAMPLE_EVENT_ID,
56 its_groups,
57 vsomeip::event_type_e::ET_FIELD);
58 app_->subscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID);
59
60 return true;
61 }
62
start()63 void start() {
64 app_->start();
65 }
66
67 #ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING
68 /*
69 * Handle signal to shutdown
70 */
stop()71 void stop() {
72 app_->clear_all_handler();
73 app_->unsubscribe(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENTGROUP_ID);
74 app_->release_event(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID, SAMPLE_EVENT_ID);
75 app_->release_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
76 app_->stop();
77 }
78 #endif
79
on_state(vsomeip::state_type_e _state)80 void on_state(vsomeip::state_type_e _state) {
81 if (_state == vsomeip::state_type_e::ST_REGISTERED) {
82 app_->request_service(SAMPLE_SERVICE_ID, SAMPLE_INSTANCE_ID);
83 }
84 }
85
on_availability(vsomeip::service_t _service,vsomeip::instance_t _instance,bool _is_available)86 void on_availability(vsomeip::service_t _service, vsomeip::instance_t _instance, bool _is_available) {
87 std::cout << "Service ["
88 << std::setw(4) << std::setfill('0') << std::hex << _service << "." << _instance
89 << "] is "
90 << (_is_available ? "available." : "NOT available.")
91 << std::endl;
92 }
93
on_message(const std::shared_ptr<vsomeip::message> & _response)94 void on_message(const std::shared_ptr<vsomeip::message> &_response) {
95 std::stringstream its_message;
96 its_message << "Received a notification for Event ["
97 << std::setw(4) << std::setfill('0') << std::hex
98 << _response->get_service() << "."
99 << std::setw(4) << std::setfill('0') << std::hex
100 << _response->get_instance() << "."
101 << std::setw(4) << std::setfill('0') << std::hex
102 << _response->get_method() << "] to Client/Session ["
103 << std::setw(4) << std::setfill('0') << std::hex
104 << _response->get_client() << "/"
105 << std::setw(4) << std::setfill('0') << std::hex
106 << _response->get_session()
107 << "] = ";
108 std::shared_ptr<vsomeip::payload> its_payload =
109 _response->get_payload();
110 its_message << "(" << std::dec << its_payload->get_length() << ") ";
111 for (uint32_t i = 0; i < its_payload->get_length(); ++i)
112 its_message << std::hex << std::setw(2) << std::setfill('0')
113 << (int) its_payload->get_data()[i] << " ";
114 std::cout << its_message.str() << std::endl;
115
116 if (_response->get_client() == 0) {
117 if ((its_payload->get_length() % 5) == 0) {
118 std::shared_ptr<vsomeip::message> its_get
119 = vsomeip::runtime::get()->create_request();
120 its_get->set_service(SAMPLE_SERVICE_ID);
121 its_get->set_instance(SAMPLE_INSTANCE_ID);
122 its_get->set_method(SAMPLE_GET_METHOD_ID);
123 its_get->set_reliable(use_tcp_);
124 app_->send(its_get);
125 }
126
127 if ((its_payload->get_length() % 8) == 0) {
128 std::shared_ptr<vsomeip::message> its_set
129 = vsomeip::runtime::get()->create_request();
130 its_set->set_service(SAMPLE_SERVICE_ID);
131 its_set->set_instance(SAMPLE_INSTANCE_ID);
132 its_set->set_method(SAMPLE_SET_METHOD_ID);
133 its_set->set_reliable(use_tcp_);
134
135 const vsomeip::byte_t its_data[]
136 = { 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
137 0x48, 0x49, 0x50, 0x51, 0x52 };
138 std::shared_ptr<vsomeip::payload> its_set_payload
139 = vsomeip::runtime::get()->create_payload();
140 its_set_payload->set_data(its_data, sizeof(its_data));
141 its_set->set_payload(its_set_payload);
142 app_->send(its_set);
143 }
144 }
145 }
146
147 private:
148 std::shared_ptr< vsomeip::application > app_;
149 bool use_tcp_;
150 };
151
152 #ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING
153 client_sample *its_sample_ptr(nullptr);
handle_signal(int _signal)154 void handle_signal(int _signal) {
155 if (its_sample_ptr != nullptr &&
156 (_signal == SIGINT || _signal == SIGTERM))
157 its_sample_ptr->stop();
158 }
159 #endif
160
main(int argc,char ** argv)161 int main(int argc, char **argv) {
162 bool use_tcp = false;
163
164 std::string tcp_enable("--tcp");
165 std::string udp_enable("--udp");
166
167 int i = 1;
168 while (i < argc) {
169 if (tcp_enable == argv[i]) {
170 use_tcp = true;
171 } else if (udp_enable == argv[i]) {
172 use_tcp = false;
173 }
174 i++;
175 }
176
177 client_sample its_sample(use_tcp);
178 #ifndef VSOMEIP_ENABLE_SIGNAL_HANDLING
179 its_sample_ptr = &its_sample;
180 signal(SIGINT, handle_signal);
181 signal(SIGTERM, handle_signal);
182 #endif
183 if (its_sample.init()) {
184 its_sample.start();
185 return 0;
186 } else {
187 return 1;
188 }
189 }
190