Menu

CANNL.h

Go to the documentation of this file.
00001 /*******************************************************************************
00002  *
00003  * Copyright (c) 2008-2010 Michael Schulze <mschulze@ivs.cs.uni-magdeburg.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 #ifndef __CANNL_h__
00041 #define __CANNL_h__
00042 
00043 #include "case/Delegate.h"
00044 #include "mw/nl/DistinctNL.h"
00045 #include "mw/nl/Packet.h"
00046 #include "mw/afp/Config.h"
00047 #include "mw/common/NodeID.h"
00048 #include "mw/common/Subject.h"
00049 #include "mw/common/Event.h"
00050 #include "mw/el/EventLayerCallBack.h"
00051 #include "mw/nl/can/canID.h"
00052 #include "debug.h"
00053 #include <stdio.h>
00054 
00055 namespace famouso {
00056     namespace mw {
00057         namespace nl {
00058 
00067             template< class CAN_Driver, class CCP, class BP >
00068             class CANNL : public DistinctNL {
00069                     typedef CANNL   type;
00070                     uint16_t tx_node;
00071                     CAN_Driver driver;
00072                     CCP ccp;
00073                     BP  etagBP;
00074                     typename CAN_Driver::MOB mob;
00075                 public:
00076                     struct info {
00077                         enum {
00078                             payload = 8
00079                         };
00080                     };
00081 
00082                     typedef uint16_t SNN;
00083 
00084                     typedef Packet<SNN> Packet_t;
00085 
00087                     typedef afp::MultiSubjectConfig<SNN> AFP_Config;
00088 
00089 
00090                     CANNL() : tx_node(0) {}
00091                     ~CANNL() {}
00092 
00099                     void init() {
00100                         TRACE_FUNCTION;
00101                         driver.init();
00102                         // the CAN Configuration Protocol has to run, before this
00103                         // function returns
00104                         tx_node = ccp.ccp_configure_tx_node(getNodeID<void>(), driver);
00105                         famouso::util::Delegate<> dg;
00106                         dg.bind<type, &type::rx_interrupt>(this);
00107                         driver.set_rx_Interrupt(dg);
00108                         driver.rx_interrupts(true);
00109                     }
00110 
00116                     void bind(const Subject &s, SNN &snn) {
00117                         TRACE_FUNCTION;
00118                         snn = etagBP.bind_subject(s, tx_node, driver);
00119                     }
00120 
00125                     void deliver(const Packet_t& p) {
00126                         // senden des CAN Paketes
00127                         TRACE_FUNCTION;
00128                         typename CAN_Driver::MOB m;
00129 
00130                         m.extended();
00131                         m.id().prio(0xfd);
00132                         m.id().fragment(p.fragment);
00133                         m.id().tx_node(tx_node);
00134                         m.id().etag(p.snn);
00135                         m.len() = 0;
00136                         while (m.len() != p.data_length) {
00137                             m.data()[m.len()] = p.data[m.len()];
00138                             ++m.len();
00139                         }
00140                         driver.transmit(m);
00141                     }
00142 
00147                     void fetch(Packet_t& p) {
00148                         // ist das Auslesen eines einzelnen Paketes
00149                         TRACE_FUNCTION;
00150                         p.data = mob.data();
00151                         p.data_length = mob.len();
00152                         p.fragment=mob.id().fragment();
00153                     }
00154 
00155 
00161                     void tx_interrupt() {
00162                         TRACE_FUNCTION;
00163                     }
00164 
00179                     void rx_interrupt() {
00180                         TRACE_FUNCTION;
00181                         driver.receive(&mob);
00182                         if (ccp.handle_ccp_configure_request(mob, driver))
00183                             return;
00184                         if (etagBP.handle_subject_bind_request(mob, driver))
00185                             return;
00186                         famouso::mw::el::IncommingEventFromNL(this);
00187                     }
00188 
00193                     SNN lastPacketSNN() {
00194                         return mob.id().etag();
00195                     }
00196 
00197             };
00198         } // namespace nl
00199     } // namespace mw
00200 } //namespace famouso
00201 
00202 #endif /* __CANNL_h__ */
00203