Menu

Client.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 __etagBP_Client_h__
00041 #define __etagBP_Client_h__
00042 
00043 #include "mw/nl/can/constants.h"
00044 #include "mw/nl/can/canETAGS.h"
00045 #include "mw/common/Subject.h"
00046 
00047 #include "mw/nl/can/etagBP/PreventBlockingOfMiddlewareCoreInBlockingProtocol.h"
00048 #include "mw/nl/can/etagBP/InterruptEnabler.h"
00049 #include "config/type_traits/contains_type.h"
00050 CONTAINS_TYPE_(asio_tag);
00051 #include "config/type_traits/if_select_type.h"
00052 
00053 namespace famouso {
00054     namespace mw {
00055         namespace nl {
00056             namespace CAN {
00057                 namespace etagBP {
00058 
00079                     template < class CAN_Driver >
00080                     class Client {
00081                             struct BindSubjectInfo {
00082                                 typename CAN_Driver::MOB mob;
00083                                 uint16_t etag;
00084                                 uint8_t round;
00085                                 BindSubjectInfo () : etag(0), round(0){}
00086                             };
00087 
00088                             BindSubjectInfo * volatile _bsi;
00089                             public:
00090 
00091                             typedef typename CAN_Driver::MOB::IDType IDType;
00092 
00093                             Client(): _bsi(0) {}
00105                             uint16_t bind_subject(const Subject &sub, uint16_t tx_node, CAN_Driver& canDriver) {
00106                                 //  select if we need a special treatment in
00107                                 //  case of using asio as middleware core event
00108                                 //  loop processing facility.  We detect it by
00109                                 //  looking into the CAN driver. If the driver
00110                                 //  has an asio_tag, the system uses asio
00111                                 //  normally too.  If it is not the case we
00112                                 //  select an InterruptEnabler that allows
00113                                 //  recognizing interrupts in case of using
00114                                 //  the binding protocol from within an interrupt
00115                                 //  context.
00116                                 typename  if_select_type <
00117                                               contains_type_asio_tag<CAN_Driver>::value,
00118                                               PreventBlockingOfMiddlewareCoreInBlockingProtocol,
00119                                               InterruptEnabler
00120                                           >::type unblocker;
00121 
00122                                 BindSubjectInfo bsi;
00123                                 IDType *id = reinterpret_cast<IDType*>(&(bsi.mob.id()));
00124                                 bsi.mob.len(8);
00125                                 bsi.mob.extended();
00126                                 for (uint8_t i = 0;i < bsi.mob.len();++i)
00127                                     bsi.mob.data()[i] = sub.tab()[i];
00128 
00129                                 _bsi=&bsi;
00130 
00131                                 id->prio(0xFD);
00132                                 id->etag(famouso::mw::nl::CAN::detail::ETAGS::GET_ETAG);
00133                                 id->tx_node(tx_node);
00134                                 canDriver.transmit(bsi.mob);
00135 
00136                                 while (_bsi)
00137                                     unblocker.process();
00138 
00139                                 return bsi.etag;
00140 
00141                             }
00142 
00152                             bool handle_subject_bind_request(typename CAN_Driver::MOB &mob, CAN_Driver& canDriver) {
00153                                 IDType *id = &mob.id();
00154                                 if (id->etag() == famouso::mw::nl::CAN::detail::ETAGS::SUPPLY_ETAG_NEW_BP) {
00155                                     if (_bsi){
00156                                         // index describes which part of the subject is in the message
00157                                         uint8_t index=mob.data()[1]<<2;
00158                                         // check if we are in the correct round
00159                                         if ((_bsi->round<<2) == index) {
00160                                             typename CAN_Driver::MOB &request_mob=const_cast<typename CAN_Driver::MOB &>(_bsi->mob);
00161                                             // test if the got half subject matches with the subject of the request
00162                                             // if not then the answer of the broker was not for us.
00163                                             for (uint8_t count=0;count<4;++count)
00164                                                 if (request_mob.data()[index+count] != mob.data()[4+count]) {
00165                                                     _bsi->round=0;
00166                                                     return true;
00167                                                 }
00168                                             // if the half subject matches then process further
00169                                             _bsi->round++;
00170                                         }
00171                                         // Do we have two correct half subject matches?
00172                                         // if yes then the broker answer was for us and we
00173                                         // got the etag
00174                                         if (_bsi->round == 2 ) {
00175                                             // read the etag
00176                                             _bsi->etag = ((mob.data()[2] & 0x3f) << 8) + mob.data()[3];
00177                                             // signalise the blocked binding method that the request is fulfilled
00178                                             _bsi=NULL;
00179                                         }
00180                                     }
00181                                     return true;
00182                                 } else {
00183                                     return false;
00184                                 }
00185                             }
00186                     };
00187 
00188                 }
00189             } /* namespace CAN */
00190         } /* namespace nl */
00191     } /* namespace mw */
00192 } /* namespace famouso */
00193 
00194 #endif
00195