| 26 | max_message_size_(_max_message_size), cleanup_timer_running_(false), cleanup_timer_(_io) { } |
| 27 | |
| 28 | std::pair<bool, message_buffer_t> tp_reassembler::process_tp_message(const byte_t* const _data, std::uint32_t _data_size, |
| 29 | const boost::asio::ip::address& _address, std::uint16_t _port) { |
| 30 | std::pair<bool, message_buffer_t> ret; |
| 31 | if (_data_size < VSOMEIP_FULL_HEADER_SIZE) { |
| 32 | return std::make_pair(false, message_buffer_t()); |
| 33 | } |
| 34 | |
| 35 | cleanup_timer_start(false); |
| 36 | |
| 37 | const service_t its_service = bithelper::read_uint16_be(&_data[VSOMEIP_SERVICE_POS_MIN]); |
| 38 | const method_t its_method = bithelper::read_uint16_be(&_data[VSOMEIP_METHOD_POS_MIN]); |
| 39 | const client_t its_client = bithelper::read_uint16_be(&_data[VSOMEIP_CLIENT_POS_MIN]); |
| 40 | const session_t its_session = bithelper::read_uint16_be(&_data[VSOMEIP_SESSION_POS_MIN]); |
| 41 | const interface_version_t its_interface_version = _data[VSOMEIP_INTERFACE_VERSION_POS]; |
| 42 | const message_type_e its_msg_type = tp::tp_flag_unset(_data[VSOMEIP_MESSAGE_TYPE_POS]); |
| 43 | |
| 44 | const std::uint64_t its_tp_message_id = |
| 45 | ((static_cast<std::uint64_t>(its_service) << 48) | (static_cast<std::uint64_t>(its_method) << 32) |
| 46 | | (static_cast<std::uint64_t>(its_client) << 16) | (static_cast<std::uint64_t>(its_interface_version) << 8) |
| 47 | | (static_cast<std::uint64_t>(its_msg_type))); |
| 48 | |
| 49 | std::scoped_lock its_lock(mutex_); |
| 50 | ret.first = false; |
| 51 | const auto found_ip = tp_messages_.find(_address); |
| 52 | if (found_ip != tp_messages_.end()) { |
| 53 | const auto found_port = found_ip->second.find(_port); |
| 54 | if (found_port != found_ip->second.end()) { |
| 55 | auto found_tp_msg = found_port->second.find(its_tp_message_id); |
| 56 | if (found_tp_msg != found_port->second.end()) { |
| 57 | if (found_tp_msg->second.first == its_session) { |
| 58 | // received additional segment for already known message |
| 59 | if (found_tp_msg->second.second.add_segment(_data, _data_size)) { |
| 60 | // message is complete |
| 61 | ret.first = true; |
| 62 | ret.second = found_tp_msg->second.second.get_message(); |
| 63 | // cleanup tp_message as message was moved and cleanup map |
| 64 | found_port->second.erase(its_tp_message_id); |
| 65 | if (found_port->second.empty()) { |
| 66 | found_ip->second.erase(found_port); |
| 67 | if (found_ip->second.empty()) { |
| 68 | tp_messages_.erase(found_ip); |
| 69 | } |
| 70 | } |
| 71 | } |
| 72 | } else { |
| 73 | VSOMEIP_WARNING_P << "Received new segment although old one is not finished yet. Dropping old. (" << hex4(its_client) |
| 74 | << ") [" << hex4(its_service) << "." << hex4(its_method) << "." << hex2(its_interface_version) << "." |
| 75 | << hex2(static_cast<uint8_t>(its_msg_type)) << "] Old: 0x" << hex4(found_tp_msg->second.first) |
| 76 | << ", new: 0x" << hex4(its_session); |
| 77 | // new segment with different session id -> throw away current |
| 78 | found_tp_msg->second.first = its_session; |
| 79 | found_tp_msg->second.second = tp_message(_data, _data_size, max_message_size_); |
| 80 | } |
| 81 | } else { |
| 82 | found_port->second.emplace( |
| 83 | std::make_pair(its_tp_message_id, std::make_pair(its_session, tp_message(_data, _data_size, max_message_size_)))); |
| 84 | } |
| 85 | } else { |