Wiselib
wiselib.testing/external_interface/contiki/contiki_extended_radio.h
Go to the documentation of this file.
00001 /***************************************************************************
00002  ** This file is part of the generic algorithm library Wiselib.           **
00003  ** Copyright (C) 2008,2009 by the Wisebed (www.wisebed.eu) project.      **
00004  **                                                                       **
00005  ** The Wiselib is free software: you can redistribute it and/or modify   **
00006  ** it under the terms of the GNU Lesser General Public License as        **
00007  ** published by the Free Software Foundation, either version 3 of the    **
00008  ** License, or (at your option) any later version.                       **
00009  **                                                                       **
00010  ** The Wiselib is distributed in the hope that it will be useful,        **
00011  ** but WITHOUT ANY WARRANTY; without even the implied warranty of        **
00012  ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         **
00013  ** GNU Lesser General Public License for more details.                   **
00014  **                                                                       **
00015  ** You should have received a copy of the GNU Lesser General Public      **
00016  ** License along with the Wiselib.                                       **
00017  ** If not, see <http://www.gnu.org/licenses/>.                           **
00018  ***************************************************************************/
00019 #ifndef CONNECTOR_CONTIKI_EXTDATA_RADIOMODEL_H
00020 #define CONNECTOR_CONTIKI_EXTDATA_RADIOMODEL_H
00021 
00022 #include "external_interface/contiki/contiki_types.h"
00023 #include "util/delegates/delegate.hpp"
00024 #include "util/serialization/simple_types.h"
00025 #include "util/base_classes/extended_radio_base.h"
00026 #include "util/base_classes/base_extended_data.h"
00027 #include <string.h>
00028 extern "C" {
00029 #include "contiki.h"
00030 #include "net/rime.h"
00031 }
00032 
00033 namespace wiselib
00034 {
00035 
00036    namespace contiki
00037    {
00038       extern abc_conn contiki_extdata_radio_conn;
00039 
00040       typedef delegate1<void, struct abc_conn*> contiki_extended_receive_delegate_t;
00041       void contiki_register_receive( contiki_extended_receive_delegate_t& delegate );
00042 
00043       void init_contiki_extdata_radio( void );
00044    }
00045    // -----------------------------------------------------------------------
00046    // -----------------------------------------------------------------------
00047    // -----------------------------------------------------------------------
00053    template<typename OsModel_P>
00054    class ContikiExtendedDataRadioModel
00055       : public ExtendedRadioBase<OsModel_P, uint16_t, uint8_t, uint8_t>
00056    {
00057    public:
00058 
00059       typedef OsModel_P OsModel;
00060       typedef BaseExtendedData<OsModel> ExtendedData;
00061       typedef uint16_t node_id_t;
00062       typedef uint8_t  block_data_t;
00063       typedef uint8_t  size_t;
00064       typedef uint8_t  message_id_t;
00065 
00066       typedef ContikiExtendedDataRadioModel<OsModel> self_type;
00067       typedef self_type* self_pointer_t;
00068 
00069       typedef delegate3<void, uint16_t, uint8_t, uint8_t*> radio_delegate_t;
00070       typedef delegate4<void, uint16_t, uint8_t, uint8_t*, const ExtendedData&> extended_radio_delegate_t;
00071       // --------------------------------------------------------------------
00072       enum ErrorCodes
00073       {
00074          SUCCESS = OsModel::SUCCESS,
00075          ERR_UNSPEC = OsModel::ERR_UNSPEC
00076       };
00077       // --------------------------------------------------------------------
00078       enum SpecialNodeIds {
00079          BROADCAST_ADDRESS = 0xffff, 
00080          NULL_NODE_ID      = 0       
00081       };
00082       // --------------------------------------------------------------------
00083       enum Restrictions {
00084          MAX_MESSAGE_LENGTH = PACKETBUF_SIZE 
00085       };
00086       // --------------------------------------------------------------------
00087       void init()
00088       {
00089          contiki::init_contiki_extdata_radio();
00090       }
00091       // --------------------------------------------------------------------
00092       int enable_radio()
00093       {
00094          contiki::contiki_extended_receive_delegate_t d =
00095             contiki::contiki_extended_receive_delegate_t::from_method<self_type, &self_type::receive>( this );
00096          contiki::contiki_register_receive( d );
00097          return SUCCESS;
00098       }
00099       // --------------------------------------------------------------------
00100       int disable_radio()
00101       {
00102          contiki::contiki_register_receive( contiki::contiki_extended_receive_delegate_t() );
00103          return SUCCESS;
00104       }
00105       // --------------------------------------------------------------------
00106       node_id_t id()
00107       {
00108          uint16_t addr = rimeaddr_node_addr.u8[0] |
00109             (rimeaddr_node_addr.u8[1] << 8);
00110          return addr;
00111       }
00112       // --------------------------------------------------------------------
00113       int send( node_id_t dest, size_t len, block_data_t *data )
00114       {
00115          uint8_t buf[PACKETBUF_SIZE];
00116 
00117          // wirte own id and destination in first 4 bytes of buffer
00118          uint16_t addr = id();
00119          write<OsModel, block_data_t, node_id_t>( buf, addr );
00120          write<OsModel, block_data_t, node_id_t>( buf + sizeof(node_id_t), dest );
00121          // write payload
00122          memcpy( buf + 2*sizeof(node_id_t), data, len );
00123 
00124          packetbuf_clear();
00125          packetbuf_copyfrom( buf, len + 2*sizeof(node_id_t) );
00126          abc_send( &contiki::contiki_extdata_radio_conn );
00127          return SUCCESS;
00128       }
00129       // --------------------------------------------------------------------
00130       void receive( struct abc_conn* )
00131       {
00132          uint8_t buffer[PACKETBUF_SIZE];
00133          int len = packetbuf_copyto( buffer );
00134 
00135          uint16_t addr = rimeaddr_node_addr.u8[0] | (rimeaddr_node_addr.u8[1] << 8);
00136 
00137          uint16_t src = read<OsModel, block_data_t, node_id_t>( buffer );
00138          uint16_t dst = read<OsModel, block_data_t, node_id_t>( buffer + 2 );
00139 //          printf( "RCVD: src=%u, dst=%u, myaddr=%u of len=%u\n", src, dst, addr, len );
00140 
00141          if ( dst == addr || dst == BROADCAST_ADDRESS )
00142          {
00143             uint16_t  signal_strength = (uint16_t) packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY);
00144             ExtendedData ex;
00145             ex.set_link_metric( 255 - signal_strength );
00146 
00147             this->notify_receivers( src, len - 4, buffer + 4 );
00148             this->notify_receivers( src, len - 4, buffer + 4, ex );
00149          }
00150       }
00151    };
00152 
00153 }
00154 
00155 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines