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