InOrderEventDataReconstructor.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #ifndef __INORDEREVENTDATARECONSTRUCTOR_H_3E331BC5510F68__
00042 #define __INORDEREVENTDATARECONSTRUCTOR_H_3E331BC5510F68__
00043
00044
00045 #include "debug.h"
00046
00047 #include "mw/afp/defrag/detail/VarHeaderLength.h"
00048
00049
00050 namespace famouso {
00051 namespace mw {
00052 namespace afp {
00053 namespace defrag {
00054
00055
00065 template <class DCP>
00066 class InOrderEventDataReconstructor {
00067
00068 typedef typename DCP::SizeProp::elen_t elen_t;
00069 typedef typename DCP::SizeProp::flen_t flen_t;
00070 typedef typename DCP::SizeProp::fcount_t fcount_t;
00071
00072 typedef class DCP::DefragStatistics Statistics;
00073 typedef class DCP::Allocator Allocator;
00074 typedef detail::VarHeaderLength<DCP> VHL;
00075
00076 public:
00077
00078 typedef NoFECHeaderSupport<DCP> FECHeaderPolicy;
00079
00080 private:
00081
00082 uint8_t * event_data;
00083
00084 elen_t event_length;
00085
00086 fcount_t event_fragment_count;
00087
00088 fcount_t arrived_fragment_count;
00089
00090 flen_t no_ext_mtu;
00091
00092 public:
00093
00098 InOrderEventDataReconstructor(flen_t no_ext_mtu)
00099 : event_data(0), event_length(0),
00100 event_fragment_count(0),
00101 arrived_fragment_count(0),
00102 no_ext_mtu(no_ext_mtu) {
00103 }
00104
00106 ~InOrderEventDataReconstructor() {
00107 if (!is_complete())
00108 Statistics::event_incomplete();
00109
00110 Statistics::fragments_currently_expected_sub(event_fragment_count - arrived_fragment_count);
00111
00112 if (event_data)
00113 Allocator::free(event_data);
00114 }
00115
00122 void put_fragment(const Headers<DCP> & header, const uint8_t * data, flen_t length) {
00123
00124 FOR_FAMOUSO_ASSERT_ONLY(bool wrong_mtu_or_frag_len = length != no_ext_mtu - VHL::get_basic_header_len(header.fseq) && header.fseq != 0);
00125 FAMOUSO_ASSERT(!wrong_mtu_or_frag_len);
00126 FAMOUSO_ASSERT(!is_complete());
00127
00128 if (no_ext_mtu == 0)
00129 return;
00130 if (header.fec.occurs()) {
00131 ::logging::log::emit< ::logging::Warning>()
00132 << PROGMEMSTRING("AFP: FEC not supported -> drop")
00133 << ::logging::log::endl;
00134 goto set_error;
00135 }
00136
00137 if (!event_data) {
00138
00139 if (!header.first_fragment)
00140 goto set_error;
00141
00142 event_fragment_count = header.fseq + 1;
00143
00144 event_data = Allocator::alloc(VHL::get_payload(event_fragment_count, no_ext_mtu));
00145 if (!event_data) {
00146 ::logging::log::emit< ::logging::Warning>()
00147 << PROGMEMSTRING("AFP: Out of memory -> drop")
00148 << ::logging::log::endl;
00149 goto set_error;
00150 }
00151
00152 memcpy(event_data, data, length);
00153
00154 Statistics::fragments_expected(event_fragment_count);
00155 Statistics::fragments_currently_expected_add(event_fragment_count - 1);
00156 } else {
00157
00158 fcount_t seq_upcount = event_fragment_count - header.fseq - 1;
00159
00160 if (seq_upcount != arrived_fragment_count)
00161 goto set_error;
00162
00163 memcpy(event_data + event_length, data, length);
00164
00165 Statistics::fragments_currently_expected_sub(1);
00166 }
00167
00168 arrived_fragment_count++;
00169 event_length += length;
00170
00171 Statistics::fragment_used();
00172
00173 if (is_complete())
00174 Statistics::event_complete();
00175
00176 return;
00177
00178 set_error:
00179 no_ext_mtu = 0;
00180 return;
00181 }
00182
00186 bool is_complete() {
00187 return get_data();
00188 }
00189
00194 uint8_t * get_data() {
00195
00196
00197
00198
00199 return (arrived_fragment_count == event_fragment_count && !error()) ? event_data : 0;
00200 }
00201
00206 elen_t get_length() {
00207 FAMOUSO_ASSERT(is_complete());
00208 return event_length;
00209 }
00210
00214 bool error() {
00215 return no_ext_mtu == 0;
00216 }
00217 };
00218
00219
00220 }
00221 }
00222 }
00223 }
00224
00225
00226 #endif // __INORDEREVENTDATARECONSTRUCTOR_H_3E331BC5510F68__
00227