Menu

Headers.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Copyright (c) 2009-2010 Philipp Werner <philipp.werner@st.ovgu.de>
00004  *                         Michael Schulze <mschulze@ivs.cs.uni-magdeburg.de>
00005  * All rights reserved.
00006  *
00007  *    Redistribution and use in source and binary forms, with or without
00008  *    modification, are permitted provided that the following conditions
00009  *    are met:
00010  *
00011  *    * Redistributions of source code must retain the above copyright
00012  *      notice, this list of conditions and the following disclaimer.
00013  *
00014  *    * Redistributions in binary form must reproduce the above copyright
00015  *      notice, this list of conditions and the following disclaimer in
00016  *      the documentation and/or other materials provided with the
00017  *      distribution.
00018  *
00019  *    * Neither the name of the copyright holders nor the names of
00020  *      contributors may be used to endorse or promote products derived
00021  *      from this software without specific prior written permission.
00022  *
00023  *
00024  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
00025  *    IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00026  *    TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00027  *    PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00028  *    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00029  *    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00030  *    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00031  *    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00032  *    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00033  *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00034  *    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035  *
00036  *
00037  * $Id$
00038  *
00039  ******************************************************************************/
00040 
00041 
00042 #ifndef __HEADERS_H_FCE771847176E1__
00043 #define __HEADERS_H_FCE771847176E1__
00044 
00045 
00046 #include "debug.h"
00047 
00048 
00049 namespace famouso {
00050     namespace mw {
00051         namespace afp {
00052             namespace defrag {
00053 
00054 
00058                 template <class DCP>
00059                 class Headers {
00060 
00061                         typedef typename DCP::SizeProp::elen_t   elen_t;
00062                         typedef typename DCP::SizeProp::flen_t   flen_t;
00063                         typedef typename DCP::SizeProp::fcount_t fcount_t;
00064 
00065                         typedef class DCP::DemuxPolicy::EventSeqHeaderPolicy EventSeqHeader;
00066                         typedef class DCP::EventDataReconstructionPolicy::FECHeaderPolicy FECHeader;
00067 
00068                     protected:
00069 
00071                         flen_t all_header_length;
00072 
00074                         flen_t ext_header_length;
00075 
00076                     public:
00077 
00079                         bool first_fragment;
00080 
00082                         fcount_t fseq;
00083 
00085                         EventSeqHeader eseq;
00086 
00088                         FECHeader fec;
00089 
00090 
00096                         Headers(const uint8_t * data) {
00097                             // TODO: security: check fragment_length (additional parameter before reading from data)
00098                             all_header_length = 0;                  // Default: error status
00099                             ext_header_length = 0;
00100 
00101                             // Read basic header
00102                             uint8_t h = data[0];
00103 
00104                             flen_t b_header_length = 1;             // basic header length
00105                             while (h & 0x80) {
00106                                 b_header_length++;
00107                                 h <<= 1;
00108                             }
00109 
00110                             bool one_more_header = h & 0x40;        // extension header?
00111                             first_fragment = h & 0x20;
00112 
00113                             if (b_header_length > sizeof(fseq) || b_header_length > 6) {
00114                                 ::logging::log::emit< ::logging::Warning>()
00115                                     << PROGMEMSTRING("AFP: Receiving to large event! Dropping fragment!")
00116                                     << ::logging::log::endl;
00117                                 fseq = 0;
00118                                 return;
00119                             }
00120 
00121                             // Read fragment sequence number
00122                             fseq = data[0] & (0x3f >> b_header_length);
00123                             for (uint8_t i = 1; i < b_header_length; i++) {
00124                                 fseq <<= 8;
00125                                 fseq |= data[i];
00126                             }
00127 
00128                             data += b_header_length;
00129 
00130                             // Read extension headers
00131                             flen_t e_header_length;
00132                             while (one_more_header) {
00133                                 if (eseq.check(data))
00134                                     e_header_length = eseq.read_header(data);
00135                                 else if (fec.check(data))
00136                                     e_header_length = fec.read_header(data);
00137                                 else {
00138                                     // Header not supported
00139                                     ::logging::log::emit< ::logging::Error>()
00140                                         << PROGMEMSTRING("AFP: Unknown or unsupported extension header ")
00141                                         << (*data & 0x1f)
00142                                         << PROGMEMSTRING("! Dropping fragment!")
00143                                         << ::logging::log::endl;
00144                                     return;
00145                                 }
00146                                 if (!e_header_length) {
00147                                     // Error reading header
00148                                     return;
00149                                 }
00150                                 one_more_header = *data & 0x40;
00151                                 ext_header_length += e_header_length;
00152                                 data += e_header_length;
00153                             }
00154 
00155                             // Set value removing error status
00156                             all_header_length = b_header_length + ext_header_length;
00157                         }
00158 
00160                         bool error() const {
00161                             return all_header_length == 0;
00162                         }
00163 
00165                         flen_t length() const {
00166                             return all_header_length;
00167                         }
00168 
00170                         flen_t ext_length() const {
00171                             return ext_header_length;
00172                         }
00173                 };
00174 
00175 
00176             } // namespace defrag
00177         } // namespace afp
00178     } // namespace mw
00179 } // namespace famouso
00180 
00181 
00182 #endif // __HEADERS_H_FCE771847176E1__
00183