00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*- 00002 00003 // -- BEGIN LICENSE BLOCK ---------------------------------------------- 00004 00024 // -- END LICENSE BLOCK ------------------------------------------------ 00025 00026 //---------------------------------------------------------------------- 00033 //---------------------------------------------------------------------- 00034 00035 #include <sick_safetyscanners/data_processing/UDPPacketMerger.h> 00036 00037 namespace sick { 00038 namespace data_processing { 00039 00040 UDPPacketMerger::UDPPacketMerger() 00041 : m_is_complete(false) 00042 , m_deployed_packet_buffer() 00043 { 00044 } 00045 00046 00047 bool UDPPacketMerger::isComplete() const 00048 { 00049 return m_is_complete; 00050 } 00051 00052 sick::datastructure::PacketBuffer UDPPacketMerger::getDeployedPacketBuffer() 00053 { 00054 m_is_complete = false; 00055 return m_deployed_packet_buffer; 00056 } 00057 00058 bool UDPPacketMerger::addUDPPacket(const datastructure::PacketBuffer& buffer) 00059 { 00060 if (isComplete()) 00061 { 00062 m_is_complete = false; 00063 } 00064 sick::datastructure::DatagramHeader datagram_header; 00065 sick::data_processing::ParseDatagramHeader datagram_header_parser; 00066 datagram_header_parser.parseUDPSequence(buffer, datagram_header); 00067 addToMap(buffer, datagram_header); 00068 deployPacketIfComplete(datagram_header); 00069 00070 return isComplete(); 00071 } 00072 00073 bool UDPPacketMerger::addToMap(const datastructure::PacketBuffer& buffer, 00074 const datastructure::DatagramHeader& header) 00075 { 00076 sick::datastructure::ParsedPacketBuffer parsed_packet_buffer(buffer, header); 00077 auto it = m_parsed_packet_buffer_map.find(header.getIdentification()); 00078 if (it != m_parsed_packet_buffer_map.end()) 00079 { 00080 it->second.push_back(parsed_packet_buffer); 00081 } 00082 else 00083 { 00084 sick::datastructure::ParsedPacketBuffer::ParsedPacketBufferVector vec; 00085 vec.push_back(parsed_packet_buffer); 00086 m_parsed_packet_buffer_map[header.getIdentification()] = vec; 00087 } 00088 return true; 00089 } 00090 00091 bool UDPPacketMerger::deployPacketIfComplete(datastructure::DatagramHeader& header) 00092 { 00093 auto it = m_parsed_packet_buffer_map.find(header.getIdentification()); 00094 00095 if (it == m_parsed_packet_buffer_map.end()) 00096 { 00097 return false; 00098 } 00099 if (!checkIfComplete(header)) 00100 return false; 00101 00102 sick::datastructure::ParsedPacketBuffer::ParsedPacketBufferVector vec = 00103 getSortedParsedPacketBufferForIdentification(header); 00104 sick::datastructure::PacketBuffer::VectorBuffer headerless_packet_buffer = 00105 removeHeaderFromParsedPacketBuffer(vec); 00106 m_deployed_packet_buffer.setBuffer(headerless_packet_buffer); 00107 return true; 00108 } 00109 00110 bool UDPPacketMerger::checkIfComplete(sick::datastructure::DatagramHeader& header) 00111 { 00112 uint32_t total_length = header.getTotalLength(); 00113 sick::datastructure::ParsedPacketBuffer::ParsedPacketBufferVector vec = 00114 getSortedParsedPacketBufferForIdentification(header); 00115 uint32_t cur_length = calcualteCurrentLengthOfParsedPacketBuffer(vec); 00116 if (cur_length != total_length) 00117 { 00118 return false; 00119 } 00120 m_is_complete = true; 00121 return true; 00122 } 00123 00124 uint32_t UDPPacketMerger::calcualteCurrentLengthOfParsedPacketBuffer( 00125 const sick::datastructure::ParsedPacketBuffer::ParsedPacketBufferVector& vec) 00126 { 00127 uint32_t cur_length = 0; 00128 00129 for (auto& parsed_packet_buffer : vec) 00130 { 00131 sick::datastructure::PacketBuffer packet_buffer = parsed_packet_buffer.getPacketBuffer(); 00132 cur_length += (packet_buffer.getLength() - sick::datastructure::DatagramHeader::HEADER_SIZE); 00133 } 00134 return cur_length; 00135 } 00136 00137 sick::datastructure::ParsedPacketBuffer::ParsedPacketBufferVector 00138 UDPPacketMerger::getSortedParsedPacketBufferForIdentification( 00139 const sick::datastructure::DatagramHeader& header) 00140 { 00141 auto it = m_parsed_packet_buffer_map.find(header.getIdentification()); 00142 sick::datastructure::ParsedPacketBuffer::ParsedPacketBufferVector vec = it->second; 00143 std::sort( 00144 vec.begin(), vec.end(), sick::datastructure::ParsedPacketBuffer::sortForIncreasingOffset); 00145 return vec; 00146 } 00147 00148 sick::datastructure::PacketBuffer::VectorBuffer UDPPacketMerger::removeHeaderFromParsedPacketBuffer( 00149 const sick::datastructure::ParsedPacketBuffer::ParsedPacketBufferVector& vec) 00150 { 00151 sick::datastructure::PacketBuffer::VectorBuffer headerless_packet_buffer; 00152 for (auto& parsed_packet_buffer : vec) 00153 { 00154 sick::datastructure::PacketBuffer packet_buffer = parsed_packet_buffer.getPacketBuffer(); 00155 00156 headerless_packet_buffer.insert(headerless_packet_buffer.end(), 00157 packet_buffer.getBuffer().begin() + 00158 sick::datastructure::DatagramHeader::HEADER_SIZE, 00159 packet_buffer.getBuffer().end()); 00160 } 00161 return headerless_packet_buffer; 00162 } 00163 00164 00165 } // namespace data_processing 00166 } // namespace sick