00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #ifndef MESSAGE_FORMAT_HPP
00028 #define MESSAGE_FORMAT_HPP
00029
00030 #include "include/hamcast_logging.h"
00031 #include "include/utils/addr_storage.hpp"
00032 #include <sys/socket.h>
00033 #include <boost/intrusive_ptr.hpp>
00034 #include <iostream>
00035 #include <string>
00036 #include <list>
00037
00038 #include <sstream>
00039 #include <boost/thread.hpp>
00040
00041
00046 struct intrusive_message{
00047 intrusive_message(): refs(0) {}
00048
00049 private:
00050 int refs;
00051 boost::mutex m_global_lock;
00052
00056 friend inline void intrusive_ptr_release(struct intrusive_message* p){
00057 HC_LOG_TRACE("");
00058
00059 p->m_global_lock.lock();
00060 if(--p->refs == 0 ) {
00061 HC_LOG_DEBUG("del element");
00062 p->m_global_lock.unlock();
00063 delete p;
00064 return;
00065 }
00066 HC_LOG_DEBUG("release ref ==> now: " << p->refs);
00067 p->m_global_lock.unlock();
00068 }
00069
00073 friend inline void intrusive_ptr_add_ref(struct intrusive_message* p){
00074 HC_LOG_TRACE("");
00075
00076 boost::lock_guard<boost::mutex> lock(p->m_global_lock);
00077 p->refs++;
00078 HC_LOG_DEBUG("add ref ==> now: " << p->refs);
00079 }
00080 };
00081
00082
00086 typedef struct {
00087
00091 enum message_type{
00092 TEST_MSG ,
00093 CLOCK_MSG ,
00094 RECEIVER_MSG ,
00095 ROUTING_MSG ,
00096 CONFIG_MSG ,
00097 EXIT_CMD ,
00098 DEBUG_MSG
00099 };
00100
00101 std::string msg_type_to_string(){
00102 HC_LOG_TRACE("");
00103 switch(type){
00104 case TEST_MSG: return "TEST_MSG";
00105 case CLOCK_MSG: return "CLOCK_MSG";
00106 case RECEIVER_MSG: return "RECEIVER_MSG";
00107 case ROUTING_MSG: return "ROUTING_MSG";
00108 case DEBUG_MSG: return "DEBUG_MSG";
00109 case EXIT_CMD: return "EXIT_CMD";
00110 case CONFIG_MSG: return "CONFIG_MSG";
00111 default: return "ERROR";
00112 }
00113 }
00114
00118 message_type type;
00119
00123 boost::intrusive_ptr<struct intrusive_message> msg;
00124 } proxy_msg;
00125
00126
00127
00131 struct test_msg: public intrusive_message{
00135 test_msg(int value): m_value(value) {
00136 HC_LOG_TRACE("");
00137 }
00138
00139 ~test_msg(){
00140 HC_LOG_TRACE("");
00141 }
00142
00146 void test(){
00147 HC_LOG_TRACE("");
00148 std::cout << "Test Message value:" << m_value << std::endl;
00149 }
00150 private:
00151 int m_value;
00152 };
00153
00154
00158 struct clock_msg: public intrusive_message{
00159
00163 enum clock_action{
00164 SEND_GQ_TO_ALL ,
00165 SEND_GSQ ,
00166 DEL_GROUP ,
00167 SEND_GQ
00168 };
00169
00176 clock_msg(clock_action type, int if_index, addr_storage g_addr){
00177 HC_LOG_TRACE("");
00178 this->type = type;
00179 this->if_index = if_index;
00180 this->g_addr = g_addr;
00181 }
00182
00187 clock_msg(clock_action type){
00188 this->type = type;
00189 }
00190
00191 ~clock_msg(){
00192 HC_LOG_TRACE("");
00193 }
00194
00198 clock_action type;
00199
00203 int if_index;
00204
00208 addr_storage g_addr;
00209 };
00210
00211
00216 struct receiver_msg: public intrusive_message{
00217
00221 enum receiver_action{
00222 JOIN ,
00223 LEAVE ,
00224 CACHE_MISS
00225 };
00226
00227
00235 receiver_msg(receiver_action type, int if_index, addr_storage src_addr, addr_storage g_addr):
00236 type(type), if_index(if_index), src_addr(src_addr), g_addr(g_addr) {
00237 HC_LOG_TRACE("");
00238 }
00239
00240
00247 receiver_msg(receiver_action type, int if_index, addr_storage g_addr):
00248 type(type), if_index(if_index), g_addr(g_addr) {
00249 HC_LOG_TRACE("");
00250 }
00251
00252 ~receiver_msg(){
00253 HC_LOG_TRACE("");
00254 }
00255
00259 receiver_action type;
00260
00264 int if_index;
00265
00269 addr_storage src_addr;
00270
00274 addr_storage g_addr;
00275
00276 };
00277
00278
00282 struct routing_msg: public intrusive_message{
00283
00287 enum routing_action{
00288 ADD_VIF ,
00289 DEL_VIF ,
00290 ADD_ROUTE ,
00291 DEL_ROUTE
00292 };
00293
00300 routing_msg(routing_action type,int if_index, int vif){
00301 HC_LOG_TRACE("");
00302 this->type= type;
00303 this->if_index = if_index;
00304 this->vif =vif;
00305 }
00306
00315 routing_msg(routing_action type,int vif, addr_storage g_addr, addr_storage src_addr, std::list<int> output_vif):
00316 type(type), vif(vif), output_vif(output_vif), g_addr(g_addr), src_addr(src_addr) {
00317 HC_LOG_TRACE("");
00318 }
00319
00327 routing_msg(routing_action type, int vif, addr_storage g_addr, addr_storage src_addr){
00328 this->type = type;
00329 this->vif = vif;
00330 this->g_addr = g_addr;
00331 this->src_addr = src_addr;
00332 HC_LOG_TRACE("");
00333 }
00334
00338 ~routing_msg(){
00339 HC_LOG_TRACE("");
00340 }
00341
00345 routing_action type;
00346
00350 int if_index;
00351
00355 int vif;
00359 std::list<int> output_vif;
00360
00364 addr_storage g_addr;
00365
00369 addr_storage src_addr;
00370 };
00371
00372
00377 struct config_msg: public intrusive_message{
00378
00382 enum config_action{
00383 ADD_DOWNSTREAM ,
00384 DEL_DOWNSTREAM ,
00385 SET_UPSTREAM
00386 };
00387
00388
00395 config_msg(config_action type,int if_index, int vif):
00396 type(type), if_index(if_index), vif(vif) {
00397 HC_LOG_TRACE("");
00398 }
00399
00400 ~config_msg(){
00401 HC_LOG_TRACE("");
00402 }
00403
00407 config_action type;
00408
00412 int if_index;
00413
00417 int vif;
00418 };
00419
00420
00424 struct debug_msg: public intrusive_message{
00425 public:
00426
00430 enum lod{
00431 LESS=0 ,
00432 NORMAL=1 ,
00433 MORE=2 ,
00434 MORE_MORE=3
00435 };
00436
00443 debug_msg(lod details, int counter, int timeout_msec): level_of_detail(details), m_counter(counter), m_timeout_msec(timeout_msec){
00444 HC_LOG_TRACE("");
00445 HC_LOG_DEBUG("counter: " << m_counter);
00446 }
00447
00448 ~debug_msg(){
00449 HC_LOG_TRACE("");
00450 }
00451
00455 void add_debug_msg(std::string debug_input){
00456 HC_LOG_TRACE("");
00457 boost::lock_guard<boost::mutex> lock(m_global_lock);
00458 m_str << debug_input << std::endl;
00459 m_counter--;
00460 cond_all_done.notify_all();
00461 }
00462
00466 bool all_done(){
00467 HC_LOG_TRACE("");
00468 boost::lock_guard<boost::mutex> lock(m_global_lock);
00469 return m_counter <= 0;
00470 }
00471
00475 std::string get_debug_msg(){
00476 HC_LOG_TRACE("");
00477 boost::lock_guard<boost::mutex> lock(m_global_lock);
00478 return m_str.str();
00479 }
00480
00484 void join_debug_msg(){
00485 boost::unique_lock<boost::mutex> lock(m_global_lock);
00486 while(m_counter > 0){
00487 cond_all_done.timed_wait(lock,boost::posix_time::millisec(m_timeout_msec));
00488 m_counter =0;
00489 }
00490 }
00491
00495 lod get_level_of_detail(){
00496 return level_of_detail;
00497 }
00498
00499 private:
00500 lod level_of_detail;
00501 std::stringstream m_str;
00502 boost::mutex m_global_lock;
00503 boost::condition_variable cond_all_done;
00504 int m_counter;
00505 int m_timeout_msec;
00506
00507 };
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517 #endif // MESSAGE_FORMAT_HPP
00518