| 1998 | } |
| 1999 | |
| 2000 | void routing_manager_impl::on_remote_subscribe(std::shared_ptr<remote_subscription>& _subscription, |
| 2001 | const remote_subscription_callback_t& _callback) { |
| 2002 | |
| 2003 | auto its_eventgroupinfo = _subscription->get_eventgroupinfo(); |
| 2004 | if (!its_eventgroupinfo) { |
| 2005 | VSOMEIP_ERROR_P << "Eventgroupinfo is invalid"; |
| 2006 | return; |
| 2007 | } |
| 2008 | |
| 2009 | const ttl_t its_ttl = _subscription->get_ttl(); |
| 2010 | |
| 2011 | const auto its_service = its_eventgroupinfo->get_service(); |
| 2012 | const auto its_instance = its_eventgroupinfo->get_instance(); |
| 2013 | const auto its_eventgroup = its_eventgroupinfo->get_eventgroup(); |
| 2014 | const auto its_major = its_eventgroupinfo->get_major(); |
| 2015 | |
| 2016 | // Get remote port(s) |
| 2017 | auto its_reliable = _subscription->get_reliable(); |
| 2018 | if (its_reliable) { |
| 2019 | uint16_t its_port = configuration_->get_reliable_port(its_service, its_instance); |
| 2020 | its_reliable->set_remote_port(its_port); |
| 2021 | } |
| 2022 | |
| 2023 | auto its_unreliable = _subscription->get_unreliable(); |
| 2024 | if (its_unreliable) { |
| 2025 | uint16_t its_port = configuration_->get_unreliable_port(its_service, its_instance); |
| 2026 | its_unreliable->set_remote_port(its_port); |
| 2027 | } |
| 2028 | |
| 2029 | // Calculate expiration time |
| 2030 | const std::chrono::steady_clock::time_point its_expiration = std::chrono::steady_clock::now() + std::chrono::seconds(its_ttl); |
| 2031 | |
| 2032 | // Try to update the subscription. This will fail, if the subscription does |
| 2033 | // not exist or is still (partly) pending. |
| 2034 | remote_subscription_id_t its_id; |
| 2035 | std::set<client_t> its_added; |
| 2036 | std::unique_lock its_update_lock{update_remote_subscription_mutex_}; |
| 2037 | if (_subscription->is_expired()) { |
| 2038 | VSOMEIP_WARNING_P << "Remote subscription already expired"; |
| 2039 | return; |
| 2040 | } else { |
| 2041 | _subscription->set_forwarded(); |
| 2042 | } |
| 2043 | |
| 2044 | auto its_result = its_eventgroupinfo->update_remote_subscription(_subscription, its_expiration, its_added, its_id, true); |
| 2045 | if (its_result) { |
| 2046 | if (!_subscription->is_pending()) { // resubscription without change |
| 2047 | its_update_lock.unlock(); |
| 2048 | _callback(_subscription); |
| 2049 | its_update_lock.lock(); |
| 2050 | } else if (!its_added.empty()) { // new clients for a selective subscription |
| 2051 | const client_t its_offering_client = find_local_client(its_service, its_instance); |
| 2052 | send_subscription(its_offering_client, its_service, its_instance, its_eventgroup, its_major, its_added, |
| 2053 | _subscription->get_id()); |
| 2054 | } else { // identical subscription is not yet processed |
| 2055 | std::stringstream its_warning; |
| 2056 | its_warning << "A remote subscription is already pending [" << hex4(its_service) << "." << hex4(its_instance) << "." |
| 2057 | << hex4(its_eventgroup) << "] from "; |
no test coverage detected