Wiselib
|
00001 // 00002 // File: hdlclustering.h 00003 // Author: mpairakt 00004 // 00005 // Created on September 23, 2009, 12:32 PM 00006 // 00007 00008 #ifndef _HDL_CLUSTERING_H 00009 #define _HDL_CLUSTERING_H 00010 00011 #include "util/delegates/delegate.hpp" 00012 00013 namespace wiselib { 00021 template<typename OsModel_P, 00022 typename Radio_P = typename OsModel_P::Radio> 00023 class HdlClustering { 00024 00025 public: 00026 00027 typedef int cluster_id_t; 00028 typedef int cluster_level_t; //quite useless within current scheme, supported for compatibility issues 00029 typedef OsModel_P OsModel; 00030 typedef Radio_P Radio; 00031 00032 typedef HdlClustering<OsModel_P, Radio_P> self_t; 00033 00034 typedef typename Radio::node_id_t node_id_t; 00035 typedef typename Radio::size_t size_t; 00036 typedef typename Radio::block_data_t block_data_t; 00037 00038 typedef delegate1<void, int> cluster_delegate_t; 00039 00040 //quite useless within current scheme, supported for compatibility issues 00041 enum EventIds { 00042 CLUSTER_HEAD_CHANGED = 0, 00043 NODE_JOINED = 1, 00044 NODE_LEFT = 2 00045 }; 00046 00047 //quite useless within current scheme, supported for compatibility issues 00048 enum ClusterIds { 00049 UNKNOWN_CLUSTER_HEAD = 0 00050 }; 00051 00052 inline void enable( void ); 00053 inline void disable( void ); 00054 00055 //same as original get_hdl() 00056 inline cluster_id_t cluster_id( cluster_level_t ) { return HDL_; } 00057 00058 //quite useless within current scheme, supported for compatibility issues 00059 inline cluster_level_t cluster_level() { return 0; } 00060 00061 template<class T, void (T::*TMethod)(int)> 00062 inline int reg_changed_callback( T *obj_pnt ) { 00063 state_changed_callback_=cluster_delegate_t::from_method<T, TMethod>( obj_pnt ); 00064 } 00065 inline void unreg_changed_callback( int idx ) { 00066 state_changed_callback_=cluster_delegate_t(); 00067 } 00068 00069 inline void receive(node_id_t from, size_t len, block_data_t* data); 00070 00071 inline void set_sink( bool sink) { sink_=sink; } 00072 00075 HdlClustering() { HDL_=-1; }; 00076 ~HdlClustering() {}; 00078 00079 private: 00080 Radio& radio() 00081 { return *radio_; } 00082 00083 Radio * radio_; 00084 00085 bool sink_; 00086 cluster_id_t HDL_; 00087 int callback_id_; 00088 cluster_delegate_t state_changed_callback_; 00089 00090 }; 00091 00092 00093 template<typename OsModel_P, 00094 typename Radio_P> 00095 void 00096 HdlClustering<OsModel_P, Radio_P>:: 00097 enable( void ) { 00098 radio().enable_radio(); 00099 callback_id_ = radio().template reg_recv_callback<self_t, 00100 &self_t::receive>( this ); 00101 if(sink_) { 00102 //I am sink, bcast first message with HDL_=0 00103 typename radio().block_data_t m_hdl=HDL_=0; 00104 radio().send(radio().BROADCAST_ADDRESS, 1, &m_hdl); 00105 } 00106 } 00107 00108 template<typename OsModel_P, 00109 typename Radio_P> 00110 void 00111 HdlClustering<OsModel_P, Radio_P>:: 00112 disable( void ) { 00113 radio().unreg_recv_callback( callback_id_ ); 00114 radio().disable(); 00115 } 00116 00117 template<typename OsModel_P, 00118 typename Radio_P> 00119 void 00120 HdlClustering<OsModel_P, Radio_P>:: 00121 receive(node_id_t from, size_t len, block_data_t* data) { 00122 00123 if ( from == radio().id( os() ) ) return; 00124 00125 if((HDL_==-1)||(HDL_<*data-1)) { 00126 HDL_=*data+1; 00127 typename radio().block_data_t m_hdl=HDL_; 00128 radio().send(Radio::BROADCAST_ADDRESS, 1, &m_hdl); 00129 state_changed_callback_(NODE_JOINED); 00130 00131 } 00132 } 00133 } 00134 00135 00136 #endif /* _HDL_CLUSTERING_H */