| 1353 | } |
| 1354 | |
| 1355 | bool routing_manager_impl::deliver_notification(service_t _service, instance_t _instance, const byte_t* _data, length_t _length, |
| 1356 | bool _reliable, [[maybe_unused]] client_t _bound_client, |
| 1357 | [[maybe_unused]] const vsomeip_sec_client_t* _sec_client, uint8_t _status_check, |
| 1358 | bool _is_from_remote) { |
| 1359 | |
| 1360 | std::scoped_lock lck(event_registration_mutex_); |
| 1361 | event_t its_event_id = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); |
| 1362 | client_t its_client_id = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); |
| 1363 | |
| 1364 | std::shared_ptr<event> its_event = find_event(_service, _instance, its_event_id); |
| 1365 | if (its_event) { |
| 1366 | if (!its_event->is_provided()) { |
| 1367 | if (its_event->get_subscribers().size() == 0) { |
| 1368 | // no subscribers for this specific event / check subscriptions |
| 1369 | // to other events of the event's eventgroups |
| 1370 | bool cache_event = false; |
| 1371 | for (const auto eg : its_event->get_eventgroups()) { |
| 1372 | std::shared_ptr<eventgroupinfo> egi = find_eventgroup(_service, _instance, eg); |
| 1373 | if (egi) { |
| 1374 | for (const auto& e : egi->get_events()) { |
| 1375 | cache_event = (e->get_subscribers().size() > 0); |
| 1376 | if (cache_event) { |
| 1377 | break; |
| 1378 | } |
| 1379 | } |
| 1380 | if (cache_event) { |
| 1381 | break; |
| 1382 | } |
| 1383 | } |
| 1384 | } |
| 1385 | if (!cache_event) { |
| 1386 | VSOMEIP_WARNING_P << "Dropping [" << hex4(_service) << "." << hex4(_instance) << "." << hex4(its_event_id) |
| 1387 | << "]. No subscription to corresponding eventgroup."; |
| 1388 | return true; // as there is nothing to do |
| 1389 | } |
| 1390 | } |
| 1391 | } |
| 1392 | |
| 1393 | // Update the event with information which might not have been previously available. |
| 1394 | if (auto service = find_service(_service, _instance)) { |
| 1395 | its_event->set_version(service->get_major()); |
| 1396 | its_event->set_reliability(_reliable ? reliability_type_e::RT_RELIABLE : reliability_type_e::RT_UNRELIABLE); |
| 1397 | } |
| 1398 | |
| 1399 | auto its_length = utility::get_payload_size(_data, _length); |
| 1400 | auto its_payload = runtime::get()->create_payload(&_data[VSOMEIP_PAYLOAD_POS], its_length); |
| 1401 | |
| 1402 | // incoming events statistics |
| 1403 | (void)insert_event_statistics(_service, _instance, its_event_id, its_length); |
| 1404 | |
| 1405 | // Ignore the filter for messages coming from other local clients |
| 1406 | // as the filter was already applied there. |
| 1407 | auto its_subscribers = its_event->update_and_get_filtered_subscribers(its_payload, _is_from_remote); |
| 1408 | if (its_event->get_type() != event_type_e::ET_SELECTIVE_EVENT) { |
| 1409 | for (const auto its_local_client : its_subscribers) { |
| 1410 | if (std::shared_ptr<local_endpoint> its_local_target = find_routing_endpoint(its_local_client); its_local_target) { |
| 1411 | send_local(its_local_target, VSOMEIP_ROUTING_CLIENT, _data, _length, _instance, _reliable, protocol::id_e::SEND_ID, |
| 1412 | _status_check, VSOMEIP_ROUTING_CLIENT); |
nothing calls this directly
no test coverage detected