Wiselib
|
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