| 436 | } |
| 437 | |
| 438 | bool event::add_subscriber(eventgroup_t _eventgroup, const std::shared_ptr<debounce_filter_impl_t>& _filter, client_t _client, |
| 439 | bool _force) { |
| 440 | |
| 441 | std::scoped_lock its_lock(eventgroups_mutex_); |
| 442 | bool ret = false; |
| 443 | if (_force // remote events managed by rm_impl |
| 444 | || is_provided_ // events provided by rm_proxies |
| 445 | || is_shadow_ // local events managed by rm_impl |
| 446 | || is_cache_placeholder_) { |
| 447 | |
| 448 | if (_filter) { |
| 449 | VSOMEIP_WARNING << "Using client [" << hex4(_client) << "] specific filter configuration for SOME/IP event " |
| 450 | << hex4(get_service()) << "." << hex4(get_instance()) << "." << hex4(get_event()) << "."; |
| 451 | std::stringstream its_filter_parameters; |
| 452 | its_filter_parameters << "(on_change=" << std::boolalpha << _filter->on_change_ << ", interval=" << _filter->interval_ |
| 453 | << ", on_change_resets_interval=" << std::boolalpha << _filter->on_change_resets_interval_ |
| 454 | << ", ignore=[ "; |
| 455 | for (auto i : _filter->ignore_) |
| 456 | its_filter_parameters << "(" << i.first << ", " << hex2(i.second) << ") "; |
| 457 | its_filter_parameters << "], send_current_value_after_=" << std::boolalpha << _filter->send_current_value_after_ << ")"; |
| 458 | |
| 459 | VSOMEIP_INFO << "Filter parameters: " << its_filter_parameters.str(); |
| 460 | |
| 461 | if (_filter->send_current_value_after_) { |
| 462 | VSOMEIP_WARNING << "Filter uses unsupported parameter `send_current_value_after_`"; |
| 463 | } |
| 464 | |
| 465 | { |
| 466 | std::scoped_lock lk{filters_mutex_}; |
| 467 | filters_[_client] = [_filter](const std::shared_ptr<payload>& _old, const std::shared_ptr<payload>& _new) { |
| 468 | bool is_changed(false), is_elapsed(false); |
| 469 | |
| 470 | // Check whether we should forward because of changed data |
| 471 | if (_filter->on_change_) { |
| 472 | length_t its_min_length, its_max_length; |
| 473 | |
| 474 | if (_old->get_length() < _new->get_length()) { |
| 475 | its_min_length = _old->get_length(); |
| 476 | its_max_length = _new->get_length(); |
| 477 | } else { |
| 478 | its_min_length = _new->get_length(); |
| 479 | its_max_length = _old->get_length(); |
| 480 | } |
| 481 | |
| 482 | // Check whether all additional bytes (if any) are excluded |
| 483 | for (length_t i = its_min_length; i < its_max_length; i++) { |
| 484 | auto j = _filter->ignore_.find(i); |
| 485 | // A change is detected when an additional byte is not |
| 486 | // excluded at all or if its exclusion does not cover all |
| 487 | // bits |
| 488 | if (j == _filter->ignore_.end() || j->second != 0xFF) { |
| 489 | is_changed = true; |
| 490 | break; |
| 491 | } |
| 492 | } |
| 493 | |
| 494 | if (!is_changed) { |
| 495 | const byte_t* its_old = _old->get_data(); |
no test coverage detected