Menu

SingleEventDemux.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Copyright (c) 2009-2010 Philipp Werner <philipp.werner@st.ovgu.de>
00004  * All rights reserved.
00005  *
00006  *    Redistribution and use in source and binary forms, with or without
00007  *    modification, are permitted provided that the following conditions
00008  *    are met:
00009  *
00010  *    * Redistributions of source code must retain the above copyright
00011  *      notice, this list of conditions and the following disclaimer.
00012  *
00013  *    * Redistributions in binary form must reproduce the above copyright
00014  *      notice, this list of conditions and the following disclaimer in
00015  *      the documentation and/or other materials provided with the
00016  *      distribution.
00017  *
00018  *    * Neither the name of the copyright holders nor the names of
00019  *      contributors may be used to endorse or promote products derived
00020  *      from this software without specific prior written permission.
00021  *
00022  *
00023  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00024  *    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00025  *    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00026  *    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00027  *    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00028  *    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00029  *    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00030  *    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00031  *    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00033  *    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  *
00035  *
00036  * $Id$
00037  *
00038  ******************************************************************************/
00039 
00040 
00041 #ifndef __SINGLEEVENTDEMUX_H_068FBC9538BBE3__
00042 #define __SINGLEEVENTDEMUX_H_068FBC9538BBE3__
00043 
00044 
00045 #include "object/PlacementNew.h"
00046 #include "mw/afp/defrag/Defragmenter.h"
00047 
00048 #include "mw/afp/defrag/NoEventSeqHeaderSupport.h"
00049 
00050 
00051 namespace famouso {
00052     namespace mw {
00053         namespace afp {
00054             namespace defrag {
00055 
00056 
00057 
00061                 template <typename DCP, class Subject_t>
00062                 struct EmptyDemuxKey {
00063                     enum { uses_subject = 0 };
00064 
00065                     EmptyDemuxKey(const Headers<DCP> & header, const Subject_t & subj) {
00066                     }
00067                 };
00068 
00069 
00070 
00071                 // TODO: testing
00089                 template <class DCP>
00090                 class  SingleEventDemux {
00091 
00092                         typedef typename DCP::SizeProp::elen_t   elen_t;
00093                         typedef typename DCP::SizeProp::flen_t   flen_t;
00094                         typedef typename DCP::SizeProp::fcount_t fcount_t;
00095 
00096                         typedef typename DCP::EventDemuxKey KeyType;
00097 
00098                     public:
00099 
00100                         typedef NoEventSeqHeaderSupport<DCP> EventSeqHeaderPolicy;
00101 
00102                     private:
00103 
00105                         flen_t mtu;
00106 
00108                         uint8_t _defragmenter[sizeof(Defragmenter<DCP>)];
00109 
00111                         Defragmenter<DCP> * curr_defrag;
00112 
00113                     public:
00114 
00116                         SingleEventDemux(flen_t mtu)
00117                                 : mtu(mtu), curr_defrag(0) {
00118                         }
00119 
00121                         ~SingleEventDemux() {
00122                             if (curr_defrag)
00123                                 curr_defrag->~Defragmenter<DCP>();
00124                         }
00125 
00126                         // Event must have been processed before you can start receiving a new event.
00127                         void * get_defragmenter_handle(const Headers<DCP> & header, const KeyType & key) {
00128                             // Start new defragmentation only with first fragment.
00129                             if (header.first_fragment) {
00130                                 // First fragment!
00131 
00132                                 // Improve robustness:
00133                                 // Channel is assumed to be perfect, so old defragmenters should be
00134                                 // freed when a new first fragment arrives. But in case there are
00135                                 // packet loss or reordering and current event is not complete while
00136                                 // we get first fragment of the next event drop incomplete event.
00137                                 if (curr_defrag) {
00138                                     free_defragmenter(curr_defrag);
00139                                 }
00140 
00141                                 // Start new defragmentation
00142                                 FAMOUSO_ASSERT(mtu > header.length());
00143                                 curr_defrag = new(_defragmenter) Defragmenter<DCP>(mtu - header.ext_length());
00144                             } else {
00145                                 // Not first fragment: if we are defragmenting an event return
00146                                 // the current defragmenter, otherwise drop this fragment by
00147                                 // returning zero.
00148                             }
00149 
00150                             return curr_defrag;
00151                         }
00152 
00153                         Defragmenter<DCP> * get_defragmenter(void * handle) {
00154                             return curr_defrag;
00155                         }
00156 
00157                         // Event must have been processed before you can start receiving a new event.
00158                         void free_defragmenter(void * handle) {
00159                             curr_defrag->~Defragmenter<DCP>();
00160                             curr_defrag = 0;
00161                         }
00162 
00163                 };
00164 
00165 
00166             } // namespace defrag
00167         } // namespace afp
00168     } // namespace mw
00169 } // namespace famouso
00170 
00171 
00172 #endif // __SINGLEEVENTDEMUX_H_068FBC9538BBE3__
00173