#include <vsomeip/application.hpp>
#include <vsomeip/runtime.hpp>
#include <compat/vsomeip/runtime.hpp>
#include <vsomeip/internal/logger.hpp>
#include "../include/application_impl.hpp"
#ifdef ANDROID
# include "../../../configuration/include/internal_android.hpp"
#else
# include "../../../configuration/include/internal.hpp"
#endif
#include "../../message/include/message_impl.hpp"
#include "../../message/include/payload_impl.hpp"
namespace vsomeip {
application_impl::application_impl(const std::string &_name) {
impl_ = vsomeip_v3::runtime::get()->create_application(_name);
}
application_impl::~application_impl() {
vsomeip::runtime::get()->remove_application(impl_->get_name());
}
const std::string &
application_impl::get_name() const {
return impl_->get_name();
}
client_t
application_impl::get_client() const {
return impl_->get_client();
}
void
application_impl::set_configuration(const std::shared_ptr<configuration> _configuration) {
(void)_configuration;
}
bool
application_impl::init() {
return impl_->init();
}
void
application_impl::start() {
impl_->start();
}
void
application_impl::stop() {
impl_->stop();
}
void
application_impl::offer_service(service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor) {
impl_->offer_service(_service, _instance, _major, _minor);
}
void
application_impl::stop_offer_service(service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor) {
impl_->stop_offer_service(_service, _instance, _major, _minor);
}
void
application_impl::offer_event(service_t _service, instance_t _instance,
event_t _event, const std::set<eventgroup_t> &_eventgroups,
bool _is_field) {
vsomeip_v3::event_type_e its_type(vsomeip_v3::event_type_e::ET_EVENT);
if (_is_field)
its_type = vsomeip_v3::event_type_e::ET_FIELD;
else {
const bool is_selective
= is_selective_event(_service, _instance, _eventgroups);
if (is_selective)
its_type = vsomeip_v3::event_type_e::ET_SELECTIVE_EVENT;
}
impl_->offer_event(_service, _instance, _event, _eventgroups, its_type);
}
void
application_impl::stop_offer_event(service_t _service, instance_t _instance,
event_t _event) {
impl_->stop_offer_event(_service, _instance, _event);
}
void
application_impl::request_service(service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor,
bool _use_exclusive_proxy) {
(void)_use_exclusive_proxy;
impl_->request_service(_service, _instance, _major, _minor);
}
void
application_impl::release_service(service_t _service, instance_t _instance) {
impl_->release_service(_service, _instance);
}
void
application_impl::request_event(service_t _service, instance_t _instance,
event_t _event, const std::set<eventgroup_t> &_eventgroups,
bool _is_field) {
const vsomeip_v3::event_type_e its_type = (_is_field) ?
vsomeip_v3::event_type_e::ET_FIELD :
vsomeip_v3::event_type_e::ET_EVENT;
impl_->request_event(_service, _instance, _event, _eventgroups, its_type);
}
void
application_impl::release_event(service_t _service, instance_t _instance,
event_t _event) {
impl_->release_event(_service, _instance, _event);
}
void
application_impl::subscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, major_version_t _major,
subscription_type_e _subscription_type, event_t _event) {
(void)_subscription_type; impl_->subscribe(_service, _instance, _eventgroup, _major, _event);
}
void
application_impl::unsubscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup) {
impl_->unsubscribe(_service, _instance, _eventgroup);
}
bool
application_impl::is_available(service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor) const {
return impl_->is_available(_service, _instance, _major, _minor);
}
void
application_impl::send(std::shared_ptr<message> _message, bool _flush = true) {
(void)_flush; if (_message) {
auto its_message = std::dynamic_pointer_cast<message_impl>(_message);
impl_->send(its_message->get_impl());
}
}
void
application_impl::notify(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload) const {
if (_payload) {
auto its_payload = std::dynamic_pointer_cast<payload_impl>(_payload);
impl_->notify(_service, _instance, _event, its_payload->get_impl());
} else {
impl_->notify(_service, _instance, _event, nullptr);
}
}
void
application_impl::notify_one(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload,
client_t _client) const {
if (_payload) {
auto its_payload = std::dynamic_pointer_cast<payload_impl>(_payload);
impl_->notify_one(_service, _instance, _event, its_payload->get_impl(), _client);
} else {
impl_->notify_one(_service, _instance, _event, nullptr, _client);
}
}
void
application_impl::register_state_handler(state_handler_t _handler) {
impl_->register_state_handler(
[_handler](vsomeip_v3::state_type_e _state) {
_handler(static_cast<vsomeip::state_type_e>(_state));
}
);
}
void
application_impl::unregister_state_handler() {
impl_->unregister_state_handler();
}
void
application_impl::register_message_handler(
service_t _service, instance_t _instance, method_t _method,
message_handler_t _handler) {
impl_->register_message_handler(_service, _instance, _method,
[_handler](const std::shared_ptr<vsomeip_v3::message> &_message) {
auto its_message = std::make_shared<message_impl>(_message);
_handler(its_message);
}
);
}
void
application_impl::unregister_message_handler(
service_t _service, instance_t _instance, method_t _method) {
impl_->unregister_message_handler(_service, _instance, _method);
}
void
application_impl::register_availability_handler(
service_t _service, instance_t _instance,
availability_handler_t _handler,
major_version_t _major, minor_version_t _minor) {
impl_->register_availability_handler(_service, _instance, _handler,
_major, _minor);
}
void
application_impl::unregister_availability_handler(
service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor) {
impl_->unregister_availability_handler(_service, _instance, _major, _minor);
}
void
application_impl::register_subscription_handler(
service_t _service, instance_t _instance, eventgroup_t _eventgroup,
subscription_handler_t _handler) {
{
std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
eventgroups_[_service][_instance].insert(_eventgroup);
}
impl_->register_subscription_handler(_service, _instance, _eventgroup,
[_handler](client_t _client, vsomeip::uid_t _uid,
vsomeip::gid_t _gid, bool _accepted){
(void)_uid;
(void)_gid;
return _handler(_client, _accepted);
}
);
}
void
application_impl::unregister_subscription_handler(
service_t _service, instance_t _instance, eventgroup_t _eventgroup) {
impl_->unregister_subscription_handler(_service, _instance, _eventgroup);
}
#define ERROR_HANDLER_DUMMY_EVENT 0xFFFE
void
application_impl::register_subscription_error_handler(
service_t _service, instance_t _instance, eventgroup_t _eventgroup,
error_handler_t _handler) {
impl_->register_subscription_status_handler(
_service, _instance, _eventgroup, ERROR_HANDLER_DUMMY_EVENT,
[_handler](service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event,
uint16_t _error) {
(void)_service;
(void)_instance;
(void)_eventgroup;
(void)_event;
_handler(_error);
},
true
);
}
void
application_impl::unregister_subscription_error_handler(
service_t _service, instance_t _instance, eventgroup_t _eventgroup) {
impl_->unregister_subscription_status_handler(_service, _instance,
_eventgroup, ERROR_HANDLER_DUMMY_EVENT);
}
void
application_impl::clear_all_handler() {
impl_->clear_all_handler();
}
bool
application_impl::is_routing() const {
return impl_->is_routing();
}
void
application_impl::offer_event(
service_t _service, instance_t _instance, event_t _event,
const std::set<eventgroup_t> &_eventgroups,
bool _is_field,
std::chrono::milliseconds _cycle,
bool _change_resets_cycle,
const epsilon_change_func_t &_epsilon_change_func) {
vsomeip_v3::event_type_e its_type(vsomeip_v3::event_type_e::ET_EVENT);
if (_is_field)
its_type = vsomeip_v3::event_type_e::ET_FIELD;
else {
const bool is_selective
= is_selective_event(_service, _instance, _eventgroups);
if (is_selective)
its_type = vsomeip_v3::event_type_e::ET_SELECTIVE_EVENT;
}
impl_->offer_event(_service, _instance, _event, _eventgroups,
its_type, _cycle, _change_resets_cycle, true,
[_epsilon_change_func](
const std::shared_ptr<vsomeip_v3::payload> &_lhs,
const std::shared_ptr<vsomeip_v3::payload> &_rhs) {
auto its_lhs = std::make_shared<payload_impl>(_lhs);
auto its_rhs = std::make_shared<payload_impl>(_rhs);
return _epsilon_change_func(its_lhs, its_rhs);
}
);
}
void
application_impl::notify(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload, bool _force) const {
if (_payload) {
auto its_payload = std::dynamic_pointer_cast<payload_impl>(_payload);
impl_->notify(_service, _instance, _event, its_payload->get_impl(),
_force);
} else {
impl_->notify(_service, _instance, _event, nullptr, _force);
}
}
void
application_impl::notify_one(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload,
client_t _client, bool _force) const {
if (_payload) {
auto its_payload = std::dynamic_pointer_cast<payload_impl>(_payload);
impl_->notify_one(_service, _instance, _event, its_payload->get_impl(),
_client, _force);
} else {
impl_->notify_one(_service, _instance, _event, nullptr, _client,
_force);
}
}
bool
application_impl::are_available(available_t &_available,
service_t _service, instance_t _instance,
major_version_t _major, minor_version_t _minor) const {
return impl_->are_available(_available, _service, _instance, _major,
_minor);
}
void
application_impl::notify(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload,
bool _force, bool _flush) const {
(void)_flush;
if (_payload) {
auto its_payload = std::dynamic_pointer_cast<payload_impl>(_payload);
impl_->notify(_service, _instance, _event, its_payload->get_impl(),
_force);
} else {
impl_->notify(_service, _instance, _event, nullptr, _force);
}
}
void
application_impl::notify_one(service_t _service, instance_t _instance,
event_t _event, std::shared_ptr<payload> _payload,
client_t _client, bool _force, bool _flush) const {
(void)_flush;
if (_payload) {
auto its_payload = std::dynamic_pointer_cast<payload_impl>(_payload);
impl_->notify_one(_service, _instance, _event, its_payload->get_impl(),
_client, _force);
} else {
impl_->notify_one(_service, _instance, _event, nullptr, _client,
_force);
}
}
void
application_impl::set_routing_state(routing_state_e _routing_state) {
impl_->set_routing_state(
static_cast<vsomeip_v3::routing_state_e>(_routing_state));
}
void
application_impl::unsubscribe(service_t _service, instance_t _instance,
eventgroup_t _eventgroup, event_t _event) {
impl_->unsubscribe(_service, _instance, _eventgroup, _event);
}
void
application_impl::register_subscription_status_handler(service_t _service,
instance_t _instance, eventgroup_t _eventgroup, event_t _event,
subscription_status_handler_t _handler) {
register_subscription_status_handler(_service, _instance,
_eventgroup, _event, _handler, false);
}
void
application_impl::register_subscription_status_handler(service_t _service,
instance_t _instance, eventgroup_t _eventgroup, event_t _event,
subscription_status_handler_t _handler, bool _is_selective) {
if (_is_selective) {
std::set<vsomeip::eventgroup_t> its_eventgroups;
its_eventgroups.insert(_eventgroup);
impl_->request_event(_service, _instance, _event, its_eventgroups,
vsomeip_v3::event_type_e::ET_SELECTIVE_EVENT);
}
impl_->register_subscription_status_handler(_service, _instance,
_eventgroup, _event,
[_handler](const vsomeip_v3::service_t _service,
const vsomeip_v3::instance_t _instance,
const vsomeip_v3::eventgroup_t _eventgroup,
const vsomeip_v3::event_t _event,
const uint16_t _error) {
if (_handler)
_handler(_service, _instance, _eventgroup, _event, _error);
},
_is_selective);
}
void
application_impl::get_offered_services_async(
offer_type_e _offer_type, offered_services_handler_t _handler) {
impl_->get_offered_services_async(
static_cast<vsomeip_v3::offer_type_e>(_offer_type), _handler);
}
void
application_impl::set_watchdog_handler(
watchdog_handler_t _handler, std::chrono::seconds _interval) {
impl_->set_watchdog_handler(_handler, _interval);
}
void
application_impl::register_async_subscription_handler(
service_t _service, instance_t _instance, eventgroup_t _eventgroup,
async_subscription_handler_t _handler) {
{
std::lock_guard<std::mutex> its_lock(eventgroups_mutex_);
eventgroups_[_service][_instance].insert(_eventgroup);
}
impl_->register_async_subscription_handler(_service, _instance,
_eventgroup, [_handler](client_t _client,
vsomeip::uid_t _uid, vsomeip::gid_t _gid, bool _accepted,
std::function<void(const bool)> _handler2) {
(void)_uid;
(void)_gid;
_handler(_client, _accepted, _handler2);
});
}
void
application_impl::set_offer_acceptance_required(
ip_address_t _address, const std::string _path, bool _enable) {
(void)_address;
(void)_path;
(void)_enable;
VSOMEIP_ERROR << __func__ << ": Must not be called from compatibility layer.";
}
vsomeip::application::offer_acceptance_map_type_t
application_impl::get_offer_acceptance_required() {
VSOMEIP_ERROR << __func__ << ": Must not be called from compatibility layer.";
return vsomeip::application::offer_acceptance_map_type_t();
}
void
application_impl::register_offer_acceptance_handler(
offer_acceptance_handler_t _handler) {
(void)_handler;
VSOMEIP_ERROR << __func__ << ": Must not be called from compatibility layer.";
}
void
application_impl::register_reboot_notification_handler(
reboot_notification_handler_t _handler) {
(void)_handler;
VSOMEIP_ERROR << __func__ << ": Must not be called from compatibility layer.";
}
void
application_impl::register_routing_ready_handler(
routing_ready_handler_t _handler) {
(void)_handler;
VSOMEIP_ERROR << __func__ << ": Must not be called from compatibility layer.";
}
void
application_impl::register_routing_state_handler(
routing_state_handler_t _handler) {
(void)_handler;
VSOMEIP_ERROR << __func__ << ": Must not be called from compatibility layer.";
}
bool
application_impl::update_service_configuration(
service_t _service, instance_t _instance,
std::uint16_t _port, bool _reliable,
bool _magic_cookies_enabled, bool _offer) {
(void)_service;
(void)_instance;
(void)_port;
(void)_reliable;
(void)_magic_cookies_enabled;
(void)_offer;
VSOMEIP_ERROR << __func__ << ": Must not be called from compatibility layer.";
return false;
}
void
application_impl::update_security_policy_configuration(
uint32_t _uid, uint32_t _gid,
std::shared_ptr<policy> _policy, std::shared_ptr<payload> _payload,
security_update_handler_t _handler) {
(void)_uid;
(void)_gid;
(void)_policy;
(void)_payload;
(void)_handler;
VSOMEIP_ERROR << __func__ << ": Must not be called from compatibility layer.";
}
void
application_impl::remove_security_policy_configuration(
uint32_t _uid, uint32_t _gid, security_update_handler_t _handler) {
(void)_uid;
(void)_gid;
(void)_handler;
VSOMEIP_ERROR << __func__ << ": Must not be called from compatibility layer.";
}
bool
application_impl::is_selective_event(
vsomeip::service_t _service, vsomeip::instance_t _instance,
const std::set<vsomeip::eventgroup_t> &_eventgroups) {
bool is_selective(false);
std::lock_guard<std::mutex> its_events_lock(eventgroups_mutex_);
const auto its_service = eventgroups_.find(_service);
if (its_service != eventgroups_.end()) {
const auto its_instance = its_service->second.find(_instance);
if (its_instance != its_service->second.end()) {
for (const auto eg : _eventgroups) {
const auto its_egrp = its_instance->second.find(eg);
if (its_egrp != its_instance->second.end()) {
is_selective = true;
break;
}
}
}
}
return is_selective;
}
}