1 // Copyright (C) 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 
6 #include "e2e_test_service.hpp"
7 
8 static bool is_remote_test = false;
9 static bool remote_client_allowed = true;
10 
11 std::vector<std::vector<vsomeip::byte_t>> payloads_profile_01_;
12 std::vector<std::vector<vsomeip::byte_t>> payloads_custom_profile_;
13 std::map<vsomeip::method_t, uint32_t> received_requests_counters_;
14 
e2e_test_service()15 e2e_test_service::e2e_test_service() :
16     app_(vsomeip::runtime::get()->create_application()),
17     is_registered_(false),
18     blocked_(false),
19     number_of_received_messages_(0),
20     offer_thread_(std::bind(&e2e_test_service::run, this)) {
21 }
22 
init()23 bool e2e_test_service::init() {
24     std::lock_guard<std::mutex> its_lock(mutex_);
25 
26     if (!app_->init()) {
27         ADD_FAILURE() << "Couldn't initialize application";
28         return false;
29     }
30     // profile01 CRC8 Method ID: 0x8421
31     app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
32             vsomeip_test::TEST_SERVICE_INSTANCE_ID, vsomeip_test::TEST_SERVICE_METHOD_ID,
33             std::bind(&e2e_test_service::on_message, this,
34                     std::placeholders::_1));
35 
36     // custom profile CRC32 Method ID: 0x6543
37     app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
38             vsomeip_test::TEST_SERVICE_INSTANCE_ID, 0x6543,
39             std::bind(&e2e_test_service::on_message, this,
40                     std::placeholders::_1));
41 
42     app_->register_message_handler(vsomeip_test::TEST_SERVICE_SERVICE_ID,
43             vsomeip_test::TEST_SERVICE_INSTANCE_ID,
44             vsomeip_test::TEST_SERVICE_METHOD_ID_SHUTDOWN,
45             std::bind(&e2e_test_service::on_message_shutdown, this,
46                     std::placeholders::_1));
47 
48     app_->register_state_handler(
49             std::bind(&e2e_test_service::on_state, this,
50                     std::placeholders::_1));
51 
52     // offer field 0x8001 eventgroup 0x01
53     std::set<vsomeip::eventgroup_t> its_eventgroups;
54     its_eventgroups.insert(0x01);
55 
56     // offer field 0x8002 eventgroup 0x02
57     std::set<vsomeip::eventgroup_t> its_eventgroups_2;
58     its_eventgroups_2.insert(0x02);
59 
60     // profile01 CRC8 Event ID: 0x8001
61     app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID,
62                 static_cast<vsomeip::event_t>(0x8001), its_eventgroups,
63                 vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(),
64                 false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE);
65 
66     // set value to field which gets filled by e2e protection  with CRC on sending
67     // after e2e protection the payload for first event should look like:
68     // {{0xa4, 0xa1, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff}
69     std::shared_ptr<vsomeip::payload> its_payload =
70             vsomeip::runtime::get()->create_payload();
71     vsomeip::byte_t its_data[8] = {0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff};
72     its_payload->set_data(its_data, 8);
73 
74     app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID,
75             static_cast<vsomeip::event_t>(0x8001), its_payload);
76 
77     // custom profile CRC32 Event ID: 0x8002
78     app_->offer_event(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID,
79                 static_cast<vsomeip::event_t>(0x8002), its_eventgroups_2,
80                 vsomeip::event_type_e::ET_FIELD, std::chrono::milliseconds::zero(),
81                 false, true, nullptr, vsomeip::reliability_type_e::RT_UNRELIABLE);
82 
83     // set value to field which gets filled by e2e protection  with CRC on sending
84     // after e2e protection the payload for first event should look like:
85     // {{0x89, 0x0e, 0xbc, 0x80, 0xff, 0xff, 0x00, 0x32}
86     std::shared_ptr<vsomeip::payload> its_payload_8002 =
87             vsomeip::runtime::get()->create_payload();
88     vsomeip::byte_t its_data_8002[8] = {0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x32};
89     its_payload_8002->set_data(its_data_8002, 8);
90 
91     app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID,
92             static_cast<vsomeip::event_t>(0x8002), its_payload_8002);
93 
94     return true;
95 }
96 
start()97 void e2e_test_service::start() {
98     VSOMEIP_INFO << "Starting...";
99     app_->start();
100 }
101 
stop()102 void e2e_test_service::stop() {
103     VSOMEIP_INFO << "Stopping...";
104     app_->clear_all_handler();
105     app_->stop();
106 }
107 
join_offer_thread()108 void e2e_test_service::join_offer_thread() {
109     if (offer_thread_.joinable()) {
110         offer_thread_.join();
111     }
112 }
113 
offer()114 void e2e_test_service::offer() {
115     app_->offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID);
116 }
117 
stop_offer()118 void e2e_test_service::stop_offer() {
119     app_->stop_offer_service(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID);
120 }
121 
on_state(vsomeip::state_type_e _state)122 void e2e_test_service::on_state(vsomeip::state_type_e _state) {
123     VSOMEIP_INFO << "Application " << app_->get_name() << " is "
124             << (_state == vsomeip::state_type_e::ST_REGISTERED ? "registered." :
125                     "deregistered.");
126 
127     if(_state == vsomeip::state_type_e::ST_REGISTERED) {
128         if(!is_registered_) {
129             is_registered_ = true;
130             std::lock_guard<std::mutex> its_lock(mutex_);
131             blocked_ = true;
132             // "start" the run method thread
133             condition_.notify_one();
134         }
135     }
136     else {
137         is_registered_ = false;
138     }
139 }
140 
on_message(const std::shared_ptr<vsomeip::message> & _request)141 void e2e_test_service::on_message(const std::shared_ptr<vsomeip::message>& _request) {
142     ASSERT_EQ(vsomeip_test::TEST_SERVICE_SERVICE_ID, _request->get_service());
143     ASSERT_EQ(vsomeip_test::TEST_SERVICE_INSTANCE_ID, _request->get_instance());
144 
145     VSOMEIP_INFO << "Received a message with Client/Session [" << std::setw(4)
146         << std::setfill('0') << std::hex << _request->get_client() << "/"
147         << std::setw(4) << std::setfill('0') << std::hex
148         << _request->get_session() << "] method: " << _request->get_method() ;
149 
150     std::shared_ptr<vsomeip::message> its_response =
151             vsomeip::runtime::get()->create_response(_request);
152     std::shared_ptr< vsomeip::payload > its_vsomeip_payload =
153             vsomeip::runtime::get()->create_payload();
154     std::shared_ptr<vsomeip::payload> its_event_payload =
155             vsomeip::runtime::get()->create_payload();
156 
157     // send fixed payload for profile 01 CRC8
158     if (_request->get_method() == vsomeip_test::TEST_SERVICE_METHOD_ID) {
159         its_vsomeip_payload->set_data(payloads_profile_01_[received_requests_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID] % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND]);
160         its_response->set_payload(its_vsomeip_payload);
161         app_->send(its_response);
162 
163         // set value to field which gets filled by e2e protection with CRC on sending
164         vsomeip::byte_t its_data[8] = {0x00, 0x00, (uint8_t)received_requests_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID], 0xff, 0xff, 0xff, 0xff, 0xff};
165         its_event_payload->set_data(its_data, 8);
166         app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID,
167                 static_cast<vsomeip::event_t>(0x8001), its_event_payload);
168         received_requests_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID]++;
169     } else if (_request->get_method() == 0x6543) {
170         //send fixed payload for custom profile CRC32
171         its_vsomeip_payload->set_data(payloads_custom_profile_[received_requests_counters_[0x6543] % vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND]);
172         its_response->set_payload(its_vsomeip_payload);
173         app_->send(its_response);
174 
175         // set value to field which gets filled by e2e protection with 4 byte CRC 32 on sending
176         vsomeip::byte_t its_data[8] = {0x00, 0x00, 0x00, 0x00, 0xff, 0xff, (uint8_t)received_requests_counters_[0x6543], 0x32};
177         its_event_payload->set_data(its_data, 8);
178         app_->notify(vsomeip_test::TEST_SERVICE_SERVICE_ID, vsomeip_test::TEST_SERVICE_INSTANCE_ID,
179                 static_cast<vsomeip::event_t>(0x8002), its_event_payload);
180         received_requests_counters_[0x6543]++;
181     }
182 
183     number_of_received_messages_++;
184     if(number_of_received_messages_ == vsomeip_test::NUMBER_OF_MESSAGES_TO_SEND * 2) {
185         VSOMEIP_INFO << "Received all messages!";
186     }
187 }
188 
on_message_shutdown(const std::shared_ptr<vsomeip::message> & _request)189 void e2e_test_service::on_message_shutdown(
190         const std::shared_ptr<vsomeip::message>& _request) {
191     (void)_request;
192     VSOMEIP_INFO << "Shutdown method was called, going down now.";
193     stop();
194 }
195 
run()196 void e2e_test_service::run() {
197     std::unique_lock<std::mutex> its_lock(mutex_);
198     while (!blocked_)
199         condition_.wait(its_lock);
200    offer();
201 }
202 
TEST(someip_e2e_test,basic_subscribe_request_response)203 TEST(someip_e2e_test, basic_subscribe_request_response) {
204     e2e_test_service test_service;
205     if (test_service.init()) {
206         test_service.start();
207         test_service.join_offer_thread();
208     }
209 }
210 
211 #ifndef _WIN32
main(int argc,char ** argv)212 int main(int argc, char** argv) {
213 
214     /*
215      e2e profile01 CRC8 protected sample payloads using the following config at receiver:
216     "service_id" : "0x1234",
217     "event_id" : "0x8421",
218     "profile" : "CRC8",
219     "variant" : "checker",
220     "crc_offset" : "0",
221     "data_id_mode" : "3",
222     "data_length" : "56",
223     "data_id" : "0xA73"
224      */
225     payloads_profile_01_.push_back({{0x82, 0xa4, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}});
226     payloads_profile_01_.push_back({{0x39, 0xa8, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}});
227     payloads_profile_01_.push_back({{0x87, 0xa4, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}});
228     payloads_profile_01_.push_back({{0x3c, 0xa8, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}});
229     payloads_profile_01_.push_back({{0x55, 0xac, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}});
230     payloads_profile_01_.push_back({{0x82, 0xa4, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}});
231     payloads_profile_01_.push_back({{0x39, 0xa8, 0xe3, 0xff, 0xff, 0xff, 0xff, 0xff}});
232     payloads_profile_01_.push_back({{0x87, 0xa4, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}});
233     payloads_profile_01_.push_back({{0x3c, 0xa8, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}});
234     payloads_profile_01_.push_back({{0x55, 0xac, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff}});
235 
236     /*
237      e2e custom profile CRC32 protected sample payloads using the following config at receiver:
238     "service_id" : "0x1234",
239     "event_id" : "0x6543",
240     "profile" : "CRC32",
241     "variant" : "checker",
242     "crc_offset" : "0"
243      */
244     payloads_custom_profile_.push_back({{0xa4, 0xb2, 0x75, 0x1f, 0xff, 0x00, 0xff, 0x32}});
245     payloads_custom_profile_.push_back({{0xa5, 0x70, 0x1f, 0x28, 0xff, 0x01, 0xff, 0x32}});
246     payloads_custom_profile_.push_back({{0xa7, 0x36, 0xa1, 0x71, 0xff, 0x02, 0xff, 0x32}});
247     payloads_custom_profile_.push_back({{0xa6, 0xf4, 0xcb, 0x46, 0xff, 0x03, 0xff, 0x32}});
248     payloads_custom_profile_.push_back({{0xa3, 0xbb, 0xdd, 0xc3, 0xff, 0x04, 0xff, 0x32}});
249     payloads_custom_profile_.push_back({{0xa2, 0x79, 0xb7, 0xf4, 0xff, 0x05, 0xff, 0x32}});
250     payloads_custom_profile_.push_back({{0xa0, 0x3f, 0x09, 0xad, 0xff, 0x06, 0xff, 0x32}});
251     payloads_custom_profile_.push_back({{0xa1, 0xfd, 0x63, 0x9a, 0xff, 0x07, 0xff, 0x32}});
252     payloads_custom_profile_.push_back({{0xaa, 0xa1, 0x24, 0xa7, 0xff, 0x08, 0xff, 0x32}});
253     payloads_custom_profile_.push_back({{0xab, 0x63, 0x4e, 0x90, 0xff, 0x09, 0xff, 0x32}});
254 
255     received_requests_counters_[vsomeip_test::TEST_SERVICE_METHOD_ID] = 0;
256     received_requests_counters_[0x7654] = 0;
257     received_requests_counters_[0x6543] = 0;
258     received_requests_counters_[0x5432] = 0;
259 
260     std::string test_remote("--remote");
261     std::string test_local("--local");
262     std::string test_allow_remote_client("--allow");
263     std::string test_deny_remote_client("--deny");
264     std::string help("--help");
265 
266     int i = 1;
267     while (i < argc)
268     {
269         if(test_remote == argv[i])
270         {
271             is_remote_test = true;
272         }
273         else if(test_local == argv[i])
274         {
275             is_remote_test = false;
276         }
277         else if(test_allow_remote_client == argv[i])
278         {
279             remote_client_allowed = true;
280         }
281         else if(test_deny_remote_client == argv[i])
282         {
283             remote_client_allowed = false;
284         }
285         else if(help == argv[i])
286         {
287             VSOMEIP_INFO << "Parameters:\n"
288             << "--remote: Run test between two hosts\n"
289             << "--local: Run test locally\n"
290             << "--allow: test is started with a policy that allows remote messages sent by this test client to the service\n"
291             << "--deny: test is started with a policy that denies remote messages sent by this test client to the service\n"
292             << "--help: print this help";
293         }
294         i++;
295     }
296 
297     ::testing::InitGoogleTest(&argc, argv);
298     return RUN_ALL_TESTS();
299 }
300 #endif
301