Menu

AbstractNetworkLayer.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Copyright (c) 2008-2010 Michael Schulze <mschulze@ivs.cs.uni-magdeburg.de>
00004  *                    2010 Philipp Werner <philipp.werner@st.ovgu.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 #ifndef __AbstractNetworkLayer_h__
00042 #define __AbstractNetworkLayer_h__
00043 
00044 #include "debug.h"
00045 #include "mw/common/Event.h"
00046 #include "mw/nl/DistinctNL.h"
00047 #include "mw/afp/Fragmenter.h"
00048 #include "mw/afp/Defragmentation.h"
00049 
00050 namespace famouso {
00051     namespace mw {
00052         namespace anl {
00053 
00070             template < class NL, class AFP_FragConfig = typename NL::AFP_Config, class AFP_DefragConfig = typename NL::AFP_Config >
00071             class AbstractNetworkLayer : public NL {
00072 
00075                     afp::DefragmentationProcessorANL<AFP_DefragConfig> defrag;
00076 
00077                 public:
00078 
00081                     typedef typename NL::SNN SNN;
00082 
00086                     SNN   subscribe_SNN;
00087 
00090                     AbstractNetworkLayer() :
00091                        defrag(NL::info::payload) {
00092                     }
00093 
00097                     void init() {
00098                         NL::init();
00099                         Subject s("SUBSCRIBE");
00100                         NL::bind(s, subscribe_SNN);
00101                     }
00102 
00108                     void announce(const Subject &s, SNN &snn) {
00109                         TRACE_FUNCTION;
00110                         NL::bind(s, snn);
00111                         // nach dem Bind noch bekannt geben,
00112                         // das dieser Kanal publiziert wird
00113                     }
00114 
00124                     void publish(const SNN &snn, const Event &e) {
00125                         TRACE_FUNCTION;
00126                         if (e.length <= NL::info::payload) {
00127                             typename NL::Packet_t p(snn, &e[0], e.length);
00128                             NL::deliver(p);
00129                         } else {
00130                             // Fragmentation using AFP (if disabled, a warning is emitted to the log)
00131                             typedef afp::Fragmenter<AFP_FragConfig, NL::info::payload> Frag;
00132 
00133                             if (e.length != (typename Frag::elen_t) e.length) {
00134                                 ::logging::log::emit< ::logging::Warning>()
00135                                     << PROGMEMSTRING("AFP: Cannot publish event... too large.")
00136                                     << ::logging::log::endl;
00137                                 return;
00138                             }
00139 
00140                             Frag frag(e.data, e.length);
00141 
00142                             if (frag.error())
00143                                 return;
00144 
00145                             uint8_t buffer [NL::info::payload];
00146                             typename Frag::flen_t length;
00147                             while ( (length = frag.get_fragment(buffer)) ) {
00148                                 typename NL::Packet_t p(snn, buffer, length, true);
00149                                 NL::deliver(p);
00150                             }
00151                         }
00152                     }
00153 
00164                     void subscribe(const Subject &s, SNN &snn) {
00165                         TRACE_FUNCTION;
00166                         NL::bind(s, snn);
00167                         // nach dem Bind auch noch bekannt geben,
00168                         // dass dieser Kanal subscribiert wird
00169                         typename NL::Packet_t p(subscribe_SNN, const_cast<uint8_t*>(s.tab()), 8);
00170                         NL::deliver(p);
00171                     }
00172 
00173 
00187                     int8_t fetch(const SNN &snn, Event &e, const famouso::mw::nl::DistinctNL *bnl) {
00188                         TRACE_FUNCTION;
00189                         if (snn == NL::lastPacketSNN()) {
00190                             typename NL::Packet_t p;
00191                             NL::fetch(p);
00192                             if (!p.fragment) {
00193                                 e.length = p.data_length;
00194                                 e.data = p.data;
00195                                 return 1;
00196                             } else {
00197                                 // Apply AFP
00198                                 afp::DefragmentationStep<AFP_DefragConfig> ds(p.data, p.data_length, snn);
00199                                 defrag.process_fragment(ds);
00200                                 if (ds.event_complete()) {
00201                                     e.data = ds.get_event_data();
00202                                     e.length = ds.get_event_length();
00203                                     return 1;
00204                                 } else {
00205                                     return 0;
00206                                 }
00207                             }
00208                         } else {
00209                             return -1;
00210                         }
00211                     }
00212 
00218                     void event_process_request(famouso::mw::nl::DistinctNL * const bnl) {
00219                     }
00220 
00224                     void event_processed() {
00225                         defrag.last_event_processed();
00226                     }
00227 
00228             };
00229 
00230         } // namespace anl
00231     } // namespace mw
00232 } //namespace famouso
00233 
00234 #endif /* __AbstractNetworkLayer_h__ */