summaryrefslogtreecommitdiff
path: root/implementation/runtime/include/application_impl.hpp
blob: 5dc9ef8b94c3dc72286fa7baa0d26d97fa90fd67 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
// Copyright (C) 2014-2021 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef VSOMEIP_V3_APPLICATION_IMPL_HPP_
#define VSOMEIP_V3_APPLICATION_IMPL_HPP_

#include <atomic>
#include <condition_variable>
#include <deque>
#include <map>
#include <mutex>
#include <set>
#include <string>
#include <thread>
#include <vector>

#include <boost/asio/signal_set.hpp>
#include <boost/asio/steady_timer.hpp>
#include <boost/asio/ip/address.hpp>

#include <vsomeip/export.hpp>
#include <vsomeip/application.hpp>

#ifdef ANDROID
#include "../../configuration/include/internal_android.hpp"
#else
#include "../../configuration/include/internal.hpp"
#endif // ANDROID
#include "../../routing/include/routing_manager_host.hpp"

namespace vsomeip_v3 {

class runtime;
class configuration;
class routing_manager;
class routing_manager_stub;

class application_impl: public application,
        public routing_manager_host,
        public std::enable_shared_from_this<application_impl> {
public:
    VSOMEIP_EXPORT application_impl(const std::string &_name,
            const std::string &_path);
    VSOMEIP_EXPORT  ~application_impl();

    VSOMEIP_EXPORT bool init();
    VSOMEIP_EXPORT void start();
    VSOMEIP_EXPORT void stop();
    VSOMEIP_EXPORT void process(int _number);

    VSOMEIP_EXPORT security_mode_e get_security_mode() const;

    // Provide services / events
    VSOMEIP_EXPORT void offer_service(service_t _service, instance_t _instance,
            major_version_t _major, minor_version_t _minor);

    VSOMEIP_EXPORT void stop_offer_service(service_t _service, instance_t _instance,
            major_version_t _major, minor_version_t _minor);

    VSOMEIP_EXPORT void offer_event(service_t _service, instance_t _instance,
            event_t _notifier,
            const std::set<eventgroup_t> &_eventgroups, event_type_e _type,
            std::chrono::milliseconds _cycle, bool _change_resets_cycle,
            bool _update_on_change,
            const epsilon_change_func_t &_epsilon_change_func,
            reliability_type_e _reliability);

    VSOMEIP_EXPORT void stop_offer_event(service_t _service,
            instance_t _instance, event_t _event);

    // Consume services / events
    VSOMEIP_EXPORT void request_service(
            service_t _service, instance_t _instance,
            major_version_t _major, minor_version_t _minor);
    VSOMEIP_EXPORT void release_service(
            service_t _service, instance_t _instance);

    VSOMEIP_EXPORT void request_event(service_t _service,
            instance_t _instance, event_t _event,
            const std::set<eventgroup_t> &_eventgroups,
            event_type_e _type, reliability_type_e _reliability);
    VSOMEIP_EXPORT void release_event(service_t _service,
            instance_t _instance, event_t _event);

    VSOMEIP_EXPORT void subscribe(service_t _service, instance_t _instance,
            eventgroup_t _eventgroup, major_version_t _major, event_t _event);
    VSOMEIP_EXPORT void subscribe_with_debounce(service_t _service, instance_t _instance,
            eventgroup_t _eventgroup, major_version_t _major,
            event_t _event, const debounce_filter_t &_filter);

    VSOMEIP_EXPORT void unsubscribe(service_t _service, instance_t _instance,
            eventgroup_t _eventgroup);
    VSOMEIP_EXPORT void unsubscribe(service_t _service, instance_t _instance,
            eventgroup_t _eventgroup, event_t _event);

    VSOMEIP_EXPORT bool is_available(service_t _service, instance_t _instance,
            major_version_t _major, minor_version_t _minor) const;

    VSOMEIP_EXPORT void send(std::shared_ptr<message> _message);

    VSOMEIP_EXPORT void notify(service_t _service, instance_t _instance,
            event_t _event, std::shared_ptr<payload> _payload,
            bool _force) const;

    VSOMEIP_EXPORT void notify_one(service_t _service, instance_t _instance,
            event_t _event, std::shared_ptr<payload> _payload, client_t _client,
            bool _force) const;

    VSOMEIP_EXPORT void register_state_handler(const state_handler_t &_handler);
    VSOMEIP_EXPORT void unregister_state_handler();

    VSOMEIP_EXPORT void register_message_handler(service_t _service,
            instance_t _instance, method_t _method, const message_handler_t &_handler);
    VSOMEIP_EXPORT void unregister_message_handler(service_t _service,
            instance_t _instance, method_t _method);

    VSOMEIP_EXPORT void register_availability_handler(service_t _service,
            instance_t _instance, const availability_handler_t &_handler,
            major_version_t _major, minor_version_t _minor);
    VSOMEIP_EXPORT void register_availability_handler(service_t _service,
            instance_t _instance, const availability_state_handler_t &_handler,
            major_version_t _major, minor_version_t _minor);
    VSOMEIP_EXPORT void unregister_availability_handler(service_t _service,
            instance_t _instance,
            major_version_t _major, minor_version_t _minor);

    VSOMEIP_EXPORT void register_subscription_handler(service_t _service,
            instance_t _instance, eventgroup_t _eventgroup, const subscription_handler_t &_handler);
    VSOMEIP_EXPORT void register_subscription_handler(service_t _service,
            instance_t _instance, eventgroup_t _eventgroup, const subscription_handler_ext_t &_handler);
    VSOMEIP_EXPORT void unregister_subscription_handler(service_t _service,
                instance_t _instance, eventgroup_t _eventgroup);

    VSOMEIP_EXPORT bool is_routing() const;

    // routing_manager_host
    VSOMEIP_EXPORT const std::string & get_name() const;
    VSOMEIP_EXPORT client_t get_client() const;
    VSOMEIP_EXPORT void set_client(const client_t &_client);
    VSOMEIP_EXPORT session_t get_session(bool _is_request);
    VSOMEIP_EXPORT const vsomeip_sec_client_t *get_sec_client() const;
    VSOMEIP_EXPORT diagnosis_t get_diagnosis() const;
    VSOMEIP_EXPORT std::shared_ptr<configuration> get_configuration() const;
    VSOMEIP_EXPORT std::shared_ptr<configuration_public> get_public_configuration() const;
    VSOMEIP_EXPORT boost::asio::io_context &get_io();

    VSOMEIP_EXPORT void on_state(state_type_e _state);
    VSOMEIP_EXPORT void on_availability(service_t _service, instance_t _instance,
            availability_state_e _state, major_version_t _major, minor_version_t _minor);
    VSOMEIP_EXPORT void on_message(std::shared_ptr<message> &&_message);
    VSOMEIP_EXPORT void on_subscription(service_t _service, instance_t _instance,
            eventgroup_t _eventgroup, client_t _client, const vsomeip_sec_client_t *_sec_client,
            const std::string &_env, bool _subscribed, const std::function<void(bool)> &_accepted_cb);
    VSOMEIP_EXPORT void on_subscription_status(service_t _service, instance_t _instance,
            eventgroup_t _eventgroup, event_t _event, uint16_t _error);
    VSOMEIP_EXPORT void register_subscription_status_handler(service_t _service,
            instance_t _instance, eventgroup_t _eventgroup, event_t _event,
            subscription_status_handler_t _handler, bool _is_selective);
    VSOMEIP_EXPORT void unregister_subscription_status_handler(service_t _service,
                instance_t _instance, eventgroup_t _eventgroup, event_t _event);

    // service_discovery_host
    VSOMEIP_EXPORT routing_manager * get_routing_manager() const;

    VSOMEIP_EXPORT bool are_available(available_t &_available,
                       service_t _service, instance_t _instance,
                       major_version_t _major, minor_version_t _minor) const;
    VSOMEIP_EXPORT void set_routing_state(routing_state_e _routing_state);

    VSOMEIP_EXPORT void clear_all_handler();


    VSOMEIP_EXPORT void get_offered_services_async(offer_type_e _offer_type, const offered_services_handler_t &_handler);

    VSOMEIP_EXPORT void on_offered_services_info(std::vector<std::pair<service_t, instance_t>> &_services);

    VSOMEIP_EXPORT void set_watchdog_handler(const watchdog_handler_t &_handler, std::chrono::seconds _interval);

    VSOMEIP_EXPORT void register_async_subscription_handler(service_t _service,
            instance_t _instance, eventgroup_t _eventgroup, const async_subscription_handler_t &_handler);

    VSOMEIP_EXPORT void register_async_subscription_handler(service_t _service,
            instance_t _instance, eventgroup_t _eventgroup, const async_subscription_handler_ext_t &_handler);

    VSOMEIP_EXPORT void set_sd_acceptance_required(const remote_info_t& _remote,
                                                   const std::string& _path, bool _enable);
    VSOMEIP_EXPORT void set_sd_acceptance_required(
            const sd_acceptance_map_type_t& _remotes, bool _enable);

    VSOMEIP_EXPORT sd_acceptance_map_type_t get_sd_acceptance_required();

    VSOMEIP_EXPORT void register_sd_acceptance_handler(const sd_acceptance_handler_t &_handler);

    VSOMEIP_EXPORT void register_reboot_notification_handler(const reboot_notification_handler_t &_handler);

    VSOMEIP_EXPORT void register_routing_ready_handler(const routing_ready_handler_t &_handler);
    VSOMEIP_EXPORT void register_routing_state_handler(const routing_state_handler_t &_handler);

    VSOMEIP_EXPORT bool update_service_configuration(service_t _service,
                                                     instance_t _instance,
                                                     std::uint16_t _port,
                                                     bool _reliable,
                                                     bool _magic_cookies_enabled,
                                                     bool _offer);

    VSOMEIP_EXPORT void update_security_policy_configuration(uint32_t _uid,
                                                             uint32_t _gid,
                                                             std::shared_ptr<policy> _policy,
                                                             std::shared_ptr<payload> _payload,
                                                             const security_update_handler_t &_handler);
    VSOMEIP_EXPORT void remove_security_policy_configuration(uint32_t _uid,
                                                             uint32_t _gid,
                                                             const security_update_handler_t &_handler);

    VSOMEIP_EXPORT void register_message_acceptance_handler(const message_acceptance_handler_t &_handler);

    VSOMEIP_EXPORT std::map<std::string, std::string>
            get_additional_data(const std::string &_plugin_name);

    VSOMEIP_EXPORT void register_subscription_handler(service_t _service,
                instance_t _instance, eventgroup_t _eventgroup,
                const subscription_handler_sec_t &_handler);
    VSOMEIP_EXPORT void register_async_subscription_handler(
                service_t _service, instance_t _instance, eventgroup_t _eventgroup,
                async_subscription_handler_sec_t _handler);

private:
    //
    // Types
    //

    enum class handler_type_e : uint8_t {
        MESSAGE,
        AVAILABILITY,
        STATE,
        SUBSCRIPTION,
        OFFERED_SERVICES_INFO,
        WATCHDOG,
        UNKNOWN
    };

    struct sync_handler {

        sync_handler(const std::function<void()> &_handler) :
                    handler_(_handler),
                    service_id_(ANY_SERVICE),
                    instance_id_(ANY_INSTANCE),
                    method_id_(ANY_METHOD),
                    session_id_(0),
                    eventgroup_id_(0),
                    handler_type_(handler_type_e::UNKNOWN) { }

        sync_handler(service_t _service_id, instance_t _instance_id,
                     method_t _method_id, session_t _session_id,
                     eventgroup_t _eventgroup_id, handler_type_e _handler_type) :
                    handler_(nullptr),
                    service_id_(_service_id),
                    instance_id_(_instance_id),
                    method_id_(_method_id),
                    session_id_(_session_id),
                    eventgroup_id_(_eventgroup_id),
                    handler_type_(_handler_type) { }

        std::function<void()> handler_;
        service_t service_id_;
        instance_t instance_id_;
        method_t method_id_;
        session_t session_id_;
        eventgroup_t eventgroup_id_;
        handler_type_e handler_type_;
    };

    struct message_handler {
        message_handler(const message_handler_t &_handler) :
            handler_(_handler) {}

        bool operator<(const message_handler& _other) const {
            return handler_.target<void (*)(const std::shared_ptr<message> &)>()
                    < _other.handler_.target<void (*)(const std::shared_ptr<message> &)>();
        }
        message_handler_t handler_;
    };

    //
    // Methods
    //
    availability_state_e is_available_unlocked(service_t _service, instance_t _instance,
                               major_version_t _major, minor_version_t _minor) const;

    availability_state_e are_available_unlocked(available_t &_available,
                                service_t _service, instance_t _instance,
                                major_version_t _major, minor_version_t _minor) const;

    void register_availability_handler_unlocked(service_t _service,
            instance_t _instance, availability_state_handler_t _handler,
            major_version_t _major, minor_version_t _minor);


    void main_dispatch();
    void dispatch();
    void invoke_handler(std::shared_ptr<sync_handler> &_handler);
    std::shared_ptr<sync_handler> get_next_handler();
    void reschedule_availability_handler(const std::shared_ptr<sync_handler> &_handler);
    bool has_active_dispatcher();
    bool is_active_dispatcher(const std::thread::id &_id);
    void remove_elapsed_dispatchers();

    void shutdown();

    void send_back_cached_event(service_t _service, instance_t _instance, event_t _event);
    void send_back_cached_eventgroup(service_t _service, instance_t _instance, eventgroup_t _eventgroup);
    void check_send_back_cached_event(service_t _service, instance_t _instance,
                                      event_t _event, eventgroup_t _eventgroup,
                                      bool *_send_back_cached_event,
                                      bool *_send_back_cached_eventgroup);
    void remove_subscription(service_t _service, instance_t _instance,
                             eventgroup_t _eventgroup, event_t _event);
    bool check_for_active_subscription(service_t _service, instance_t _instance,
                                       event_t _event);

    void deliver_subscription_state(service_t _service, instance_t _instance,
            eventgroup_t _eventgroup, event_t _event, uint16_t _error);

    bool check_subscription_state(service_t _service, instance_t _instance,
            eventgroup_t _eventgroup, event_t _event);

    void print_blocking_call(const std::shared_ptr<sync_handler>& _handler);

    void watchdog_cbk(boost::system::error_code const &_error);

    bool is_local_endpoint(const boost::asio::ip::address &_unicast, port_t _port);

    //
    // Attributes
    //
    std::shared_ptr<runtime> runtime_;
    std::atomic<client_t> client_; // unique application identifier
    session_t session_;
    std::mutex session_mutex_;

    std::mutex initialize_mutex_;
    bool is_initialized_;

    std::string name_;

    std::string path_;
    std::shared_ptr<configuration> configuration_;

    boost::asio::io_context io_;
    std::set<std::shared_ptr<std::thread> > io_threads_;
    std::shared_ptr<boost::asio::io_context::work> work_;

    // Proxy to or the Routing Manager itself
    std::shared_ptr<routing_manager> routing_;

    // vsomeip state (registered / deregistered)
    state_type_e state_;

    // vsomeip state handler
    std::mutex state_handler_mutex_;
    state_handler_t handler_;

    // vsomeip security mode
    security_mode_e security_mode_;

    // vsomeip offered services handler
    std::mutex offered_services_handler_mutex_;
    offered_services_handler_t offered_services_handler_;

    // Method/Event (=Member) handlers
    std::map<service_t,
            std::map<instance_t, std::map<method_t, message_handler_t> > > members_;
    mutable std::mutex members_mutex_;

    // Availability handlers
    using availability_major_minor_t =
        std::map<major_version_t,
            std::map<minor_version_t, std::pair<availability_state_handler_t, bool>>>;
    std::map<service_t, std::map<instance_t, availability_major_minor_t>> availability_;
    mutable std::mutex availability_mutex_;

    // Availability
    using available_instance_t =
        std::map<instance_t,
            std::map<major_version_t, std::pair<minor_version_t, availability_state_e>>>;
    using available_ext_t = std::map<service_t, available_instance_t>;
    mutable available_ext_t available_;

    // Subscription handlers
    std::map<service_t,
            std::map<instance_t,
                    std::map<eventgroup_t,
                            std::pair<subscription_handler_sec_t,
                                async_subscription_handler_sec_t> > > > subscription_;
    mutable std::mutex subscription_mutex_;
    std::map<service_t,
        std::map<instance_t, std::map<eventgroup_t,
        std::map<client_t, error_handler_t > > > > eventgroup_error_handlers_;
    mutable std::mutex subscription_error_mutex_;

#ifdef VSOMEIP_ENABLE_SIGNAL_HANDLING
    // Signals
    boost::asio::signal_set signals_;
    bool catched_signal_;
#endif

    // Handlers
    mutable std::deque<std::shared_ptr<sync_handler>> handlers_;
    mutable std::mutex handlers_mutex_;

    // Dispatching
    std::atomic<bool> is_dispatching_;
    // Dispatcher threads
    std::map<std::thread::id, std::shared_ptr<std::thread>> dispatchers_;
    // Dispatcher threads that elapsed and can be removed
    std::set<std::thread::id> elapsed_dispatchers_;
    // Dispatcher threads that are running
    std::set<std::thread::id> running_dispatchers_;
    // Mutex to protect access to dispatchers_ & elapsed_dispatchers_
    std::mutex dispatcher_mutex_;

    // Condition to wakeup the dispatcher thread
    mutable std::condition_variable dispatcher_condition_;
    std::size_t max_dispatchers_;
    std::size_t max_dispatch_time_;

    std::condition_variable stop_cv_;
    std::mutex start_stop_mutex_;
    bool stopped_;
    std::thread stop_thread_;

    std::condition_variable block_stop_cv_;
    std::mutex block_stop_mutex_;
    bool block_stopping_;

    static uint32_t app_counter__;
    static std::mutex app_counter_mutex__;

    bool is_routing_manager_host_;

    // Event subscriptions
    std::mutex subscriptions_mutex_;
    std::map<service_t, std::map<instance_t,
            std::map<event_t, std::map<eventgroup_t, bool>>>> subscriptions_;

    std::thread::id stop_caller_id_;
    std::thread::id start_caller_id_;

    bool stopped_called_;

    std::map<service_t, std::map<instance_t, std::map<eventgroup_t,
            std::map<event_t, std::pair<subscription_status_handler_t, bool> > > > > subscription_status_handlers_;
    std::mutex subscription_status_handlers_mutex_;

    std::mutex subscriptions_state_mutex_;
    std::map<service_t,
        std::map<instance_t,
            std::map<eventgroup_t,
                std::map<event_t, subscription_state_e>
            >
        >
    > subscription_state_;

    std::mutex watchdog_timer_mutex_;
    boost::asio::steady_timer watchdog_timer_;
    watchdog_handler_t watchdog_handler_;
    std::chrono::seconds watchdog_interval_;

    bool client_side_logging_;
    std::set<std::tuple<service_t, instance_t> > client_side_logging_filter_;

    std::map<std::pair<service_t, instance_t>,
            std::deque<std::shared_ptr<sync_handler> > > availability_handlers_;

    vsomeip_sec_client_t sec_client_;

    bool has_session_handling_;
};

} // namespace vsomeip_v3

#endif // VSOMEIP_V3_APPLICATION_IMPL_HPP_