• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2014-2019 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 <chrono>
7 #include <condition_variable>
8 #include <iostream>
9 #include <sstream>
10 #include <thread>
11 #include <map>
12 
13 #include <gtest/gtest.h>
14 #include <vsomeip/vsomeip.hpp>
15 #include <vsomeip/internal/logger.hpp>
16 
17 #include "second_address_test_globals.hpp"
18 
19 class second_address_test_service {
20 public:
second_address_test_service(struct second_address_test::service_info _service_info)21     second_address_test_service(struct second_address_test::service_info _service_info) :
22             service_info_(_service_info),
23             app_(vsomeip::runtime::get()->create_application("second_address_test_service")),
24             offer_thread_(std::bind(&second_address_test_service::run, this)) {
25 
26         if (!app_->init()) {
27             ADD_FAILURE() << "Couldn't initialize application";
28             return;
29         }
30 
31         app_->register_state_handler(
32                 std::bind(&second_address_test_service::on_state, this,
33                         std::placeholders::_1));
34 
35         app_->register_message_handler(service_info_.service_id,
36                 service_info_.instance_id, service_info_.request_method_id,
37                 std::bind(&second_address_test_service::on_message, this,
38                         std::placeholders::_1));
39 
40         app_->register_message_handler(service_info_.service_id,
41                 service_info_.instance_id, service_info_.notify_method_id,
42                 std::bind(&second_address_test_service::on_notify, this,
43                         std::placeholders::_1));
44 
45         app_->register_message_handler(service_info_.service_id,
46                 service_info_.instance_id, service_info_.shutdown_method_id,
47                 std::bind(&second_address_test_service::on_shutdown_method_called, this,
48                         std::placeholders::_1));
49 
50         app_->register_subscription_handler(service_info_.service_id,
51                 service_info_.instance_id, service_info_.eventgroup_id,
52                 std::bind(&second_address_test_service::subscription_handler,
53                           this, std::placeholders::_1, std::placeholders::_2,
54                           std::placeholders::_3, std::placeholders::_4));
55 
56         app_->register_subscription_handler(service_info_.service_id,
57                 service_info_.instance_id, service_info_.selective_eventgroup_id,
58                 std::bind(&second_address_test_service::selective_subscription_handler,
59                           this, std::placeholders::_1, std::placeholders::_2,
60                           std::placeholders::_3, std::placeholders::_4));
61 
62         app_->start();
63     }
64 
~second_address_test_service()65     ~second_address_test_service() {
66         offer_thread_.join();
67     }
68 
stop()69     void stop() {
70         app_->stop_offer_service(service_info_.service_id, service_info_.instance_id);
71         app_->clear_all_handler();
72         app_->stop();
73     }
74 
75 private:
on_state(vsomeip::state_type_e _state)76     void on_state(vsomeip::state_type_e _state) {
77         VSOMEIP_INFO << "Application " << app_->get_name() << " is "
78             << (_state == vsomeip::state_type_e::ST_REGISTERED ?
79                     "registered" : "deregistered") << " on service.";
80 
81         if (_state == vsomeip::state_type_e::ST_REGISTERED) {
82             std::lock_guard<std::mutex> its_lock(mutex_);
83             wait_until_registered_ = false;
84             condition_.notify_one();
85         }
86     }
87 
on_shutdown_method_called(const std::shared_ptr<vsomeip::message> & _message)88     void on_shutdown_method_called(const std::shared_ptr<vsomeip::message> &_message) {
89         app_->send(vsomeip::runtime::get()->create_response(_message));
90 
91         VSOMEIP_WARNING << "************************************************************";
92         VSOMEIP_WARNING << "Shutdown method called on service -> going down!";
93         VSOMEIP_WARNING << "************************************************************";
94 
95         std::lock_guard<std::mutex> its_lock(mutex_);
96         wait_until_shutdown_method_called_ = false;
97         condition_.notify_one();
98     }
99 
on_message(const std::shared_ptr<vsomeip::message> & _message)100     void on_message(const std::shared_ptr<vsomeip::message> &_message) {
101         EXPECT_EQ(service_info_.service_id, _message->get_service());
102         EXPECT_EQ(service_info_.request_method_id, _message->get_method());
103         EXPECT_EQ(service_info_.instance_id, _message->get_instance());
104 
105         std::shared_ptr<vsomeip::message> response = vsomeip::runtime::get()->create_response(_message);
106         response->set_payload(_message->get_payload());
107         app_->send(response);
108 
109         std::lock_guard<std::mutex> its_lock(mutex_);
110         messages_received_++;
111 
112         if (messages_received_ == second_address_test::number_of_messages_to_send) {
113             wait_until_receive_messages_ = false;
114             condition_.notify_one();
115         }
116     }
117 
on_notify(const std::shared_ptr<vsomeip::message> & _message)118     void on_notify(const std::shared_ptr<vsomeip::message> &_message) {
119         EXPECT_EQ(service_info_.service_id, _message->get_service());
120         EXPECT_EQ(service_info_.notify_method_id, _message->get_method());
121         EXPECT_EQ(service_info_.instance_id, _message->get_instance());
122 
123         auto its_payload = _message->get_payload();
124         notifications_to_send_ = its_payload->get_data()[0];
125 
126         std::lock_guard<std::mutex> its_lock(mutex_);
127         wait_until_notify_method_called_ = false;
128         condition_.notify_one();
129     }
130 
offer()131     void offer() {
132         app_->offer_service(service_info_.service_id, service_info_.instance_id);
133 
134         std::set<vsomeip::eventgroup_t> its_eventgroups;
135         its_eventgroups.insert(service_info_.eventgroup_id);
136 
137         app_->offer_event(service_info_.service_id, service_info_.instance_id,
138                 service_info_.event_id, its_eventgroups,
139                 vsomeip::event_type_e::ET_EVENT, std::chrono::milliseconds::zero(),
140                 false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN);
141 
142         its_eventgroups.clear();
143         its_eventgroups.insert(service_info_.selective_eventgroup_id);
144 
145         app_->offer_event(service_info_.service_id, service_info_.instance_id,
146                 service_info_.selective_event_id, its_eventgroups,
147                 vsomeip::event_type_e::ET_SELECTIVE_EVENT, std::chrono::milliseconds::zero(),
148                 false, true, nullptr, vsomeip::reliability_type_e::RT_UNKNOWN);
149     }
150 
notify()151     void notify() {
152         EXPECT_TRUE(client_subscribed_);
153         EXPECT_TRUE(client_subscribed_selective_);
154         auto its_payload = vsomeip::runtime::get()->create_payload();
155 
156         std::uint32_t i = 0;
157 
158         for (; i < notifications_to_send_; i++) {
159             its_payload->set_data(std::vector<vsomeip::byte_t>(i+1, 0x55));
160             app_->notify(service_info_.service_id, service_info_.instance_id,
161                     service_info_.event_id, its_payload);
162         }
163 
164         for (; i < 2 * notifications_to_send_; i++) {
165             its_payload->set_data(std::vector<vsomeip::byte_t>(i+1, 0x55));
166             app_->notify_one(service_info_.service_id, service_info_.instance_id,
167                     service_info_.selective_event_id, its_payload, client_id_);
168         }
169     }
170 
run()171     void run() {
172         VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex
173                 << service_info_.service_id << "] Running";
174 
175         std::unique_lock<std::mutex> its_lock(mutex_);
176         while (wait_until_registered_) {
177             condition_.wait(its_lock);
178         }
179 
180         VSOMEIP_DEBUG << "[" << std::setw(4) << std::setfill('0') << std::hex
181                 << service_info_.service_id << "] Offering";
182         offer();
183 
184         while (wait_until_receive_messages_) {
185             condition_.wait(its_lock);
186         }
187 
188         VSOMEIP_DEBUG << "Service waiting for notify method has been called";
189         while (wait_until_notify_method_called_) {
190             condition_.wait(its_lock);
191         }
192 
193         VSOMEIP_DEBUG << "Service notifying events";
194         notify();
195 
196         while (wait_until_shutdown_method_called_) {
197             condition_.wait(its_lock);
198         }
199 
200         its_lock.unlock();
201         stop();
202     }
203 
subscription_handler(vsomeip::client_t _client,std::uint32_t _uid,std::uint32_t _gid,bool _subscribed)204     bool subscription_handler(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, bool _subscribed) {
205         (void)_uid;
206         (void)_gid;
207         VSOMEIP_DEBUG << __func__ << ": client 0x" << std::hex << std::setw(4) << std::setfill('0') << _client
208                 << ((_subscribed) ? " subscribed" : "unsubscribed") << " on service.";
209         client_subscribed_ = _subscribed;
210         return true;
211     }
212 
selective_subscription_handler(vsomeip::client_t _client,std::uint32_t _uid,std::uint32_t _gid,bool _subscribed)213     bool selective_subscription_handler(vsomeip::client_t _client, std::uint32_t _uid, std::uint32_t _gid, bool _subscribed) {
214         (void)_uid;
215         (void)_gid;
216         VSOMEIP_DEBUG << __func__ << ": client 0x" << std::hex << std::setw(4) << std::setfill('0') << _client
217                 << ((_subscribed) ? " subscribed" : "unsubscribed") << " on service.";
218         client_subscribed_selective_ = _subscribed;
219         client_id_ = _client;
220         return true;
221     }
222 
223 private:
224     struct second_address_test::service_info service_info_;
225     std::shared_ptr<vsomeip::application> app_;
226 
227     bool wait_until_registered_ = true;
228     bool wait_until_receive_messages_ = true;
229     bool wait_until_notify_method_called_ = true;
230     bool wait_until_shutdown_method_called_ = true;
231     bool client_subscribed_ = false;
232     bool client_subscribed_selective_ = false;
233     vsomeip::client_t client_id_ = 0;
234     std::uint32_t messages_received_ = 0;
235     std::uint8_t notifications_to_send_ = 0;
236     std::mutex mutex_;
237     std::condition_variable condition_;
238     std::thread offer_thread_;
239 };
240 
TEST(someip_second_address_test,test_communication_with_client)241 TEST(someip_second_address_test, test_communication_with_client)
242 {
243     second_address_test_service its_sample(second_address_test::service);
244 }
245 
246 #ifndef _WIN32
main(int argc,char ** argv)247 int main(int argc, char** argv)
248 {
249     ::testing::InitGoogleTest(&argc, argv);
250     return RUN_ALL_TESTS();
251 }
252 #endif
253