📄 mc-agent.cc
字号:
/************************************************** * File: mc-agent.cc Author: Suman Banerjee <suman@cs.umd.edu> Date: 15th March, 2001 Terms: GPL Narada implementation in myns This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ***************************************************/#include <stdlib.h>#include <assert.h>#include <scheduler.h>#include <node.h>#include "mc-agent.h"#include "misc.h"NamedConstant const_seek_nbr_cnt("const_seek_nbr_cnt",8);NamedConstant const_mesh_neighbors("const_mesh_neighbors",2);NamedConstant const_mesh_neighbor_keepalive_period("const_mesh_neighbor_keepalive_period",30.00);NamedConstant const_mesh_neighbor_refresh_timeout("const_mesh_neighbor_refresh_timeout",60.00);NamedConstant const_mesh_rt_exchange_period("const_mesh_rt_exchange_period",30.00);NamedConstant const_mesh_rt_exchange_timeout("const_mesh_rt_exchange_timeout",60.00);NamedConstant const_mesh_link_add_period("const_mesh_link_add_period",100.00);NamedConstant const_mesh_link_drop_period("const_mesh_link_drop_period",100.00);NamedConstant const_mesh_setup_neighbor_timeout("const_mesh_setup_neighbor_timeout",10.00);NamedConstant const_data_transmit_interval("const_data_transmit_interval",2.00);NamedConstant linkdropthreshold("linkdropthreshold",2);NamedConstant linkaddthreshold("linkaddthreshold",5.00);NamedConstant infinitelinkcost("infinitelinkcost",10000.00);NamedConstant invalid("invalid",-12345);NamedConstant maxmeshmembers("maxmeshmembers",50);NamedConstant random_data_source("random_data_source",2);mcAgent::~mcAgent (void) { delete mesh_refresh_timer; delete mesh_keepalive_timer; //sri's code delete mesh_rt_exchange_timer; delete mesh_rt_exchange_check_timer; delete mesh_link_add_timer; delete mesh_link_drop_timer; delete data_timer; /* Suman's correction */ // printf ("[timer-debug] at %8.4f < ag %d nd %d > about to delete all timers \n", Scheduler::Clock(), id,n->id); for (void *pos = mesh_setup_neighbor_timer_list.GetHeadPosition(); pos != NULL; /* Suman's correction */ /* pos = */ mesh_setup_neighbor_timer_list.GetNext(pos)) { MeshSetupNeighborTimer *msnt = mesh_setup_neighbor_timer_list.GetAt(pos); msnt->CancelTimer(); delete msnt; } mesh_setup_neighbor_timer_list.RemoveAll(); for (int i = 0; i < MAXMESHMEMBERS; i++) { if ((meshrt.valid[i]) && (meshrt.pathlen[i] == 1)) assert (meshrt.path[i] == NULL); if ((meshrt.valid[i]) && (meshrt.pathlen[i] > 1)) { free(meshrt.path[i]); meshrt.path[i] = NULL; } } delete[] meshrt.valid; delete[] meshrt.cost; delete[] meshrt.pathlen; delete[] meshrt.path; return; //}void mcAgent::init (int Id, int Index, Node *N) { Agent::init(Id,Index,N); t = AGENT_APPLICATION_MC; rp.agent_id = -1; mesh_refresh_timer = new MeshRefreshTimeoutTimer(this); mesh_keepalive_timer = new MeshKeepAliveTimer(this);//sri's code mesh_rt_exchange_timer = new MeshRTExchangeTimer(this); mesh_link_add_timer = new MeshLinkAddTimer(this); mesh_link_drop_timer = new MeshLinkDropTimer(this); mesh_rt_exchange_check_timer = new MeshRTExchangeCheckTimer(this); data_timer = new DataTimer(this); datasource = false; // if (id == RANDOM_DATA_SOURCE) DATA SOURCE not needed -- Suman // datasource = true; // return;}void mcAgent::start (void) { #ifdef LOG_MCAGENT_START printf("[start] at %8.4f < ag %d nd %d > started\n",Scheduler::Clock(),id,n->id); #endif // LOG_MCAGENT_START Agent::start(); meshrt.valid = new (bool[MAXMESHMEMBERS]); meshrt.cost = new (double[MAXMESHMEMBERS]); meshrt.pathlen = new (int[MAXMESHMEMBERS]); meshrt.path= new (AgentInfo * [MAXMESHMEMBERS]); //sri's code for (int i = 0; i < MAXMESHMEMBERS; i++) { meshrt.valid[i] = false; meshrt.cost[i] = (double) INVALID; meshrt.pathlen[i] = INVALID; meshrt.path[i] = NULL; } meshrt.valid[id] = true; meshrt.cost[id] = 0; meshrt.pathlen[id] = 0; meshrt.path[id] = NULL; // if (rp.agent_id == -1) { printf ("[Err] at %8.4f < ag %d nd %d > doesn't know RP\n",Scheduler::Clock(),id,n->id); exit (-1); } //sri's code data_seq_no = 0; if (datasource == true) data_timer->SetTimer(get_time_till_next_transmit()); // mesh_refresh_seq_no = 0; AppPacket *p = new AppPacket(PING_RP); p->u.ping_p.seek_nbr_cnt = CONST_SEEK_NBR_CNT; send_pkt(p,rp.agent_id,rp.node_id); return;}void mcAgent::stop (void) { #ifdef LOG_MCAGENT_STOP printf("[mcagent-stop] at %8.4f < ag %d nd %d > stopped \n",Scheduler::Clock(),id,n->id); #endif // LOG_MCAGENT_STOP mesh_refresh_timer->CancelTimer(); mesh_keepalive_timer->CancelTimer(); //sri's code mesh_rt_exchange_timer->CancelTimer(); mesh_link_add_timer->CancelTimer(); mesh_link_drop_timer->CancelTimer(); mesh_rt_exchange_check_timer->CancelTimer(); data_timer->CancelTimer(); /* Suman's correction */ // printf ("[timer-debug] at %8.4f < ag %d nd %d > about to delete all timers \n", Scheduler::Clock(), id,n->id); for (void *pos = mesh_setup_neighbor_timer_list.GetHeadPosition(); pos != NULL; /* Suman's correction */ /* pos = mesh_setup_neighbor_timer_list.GetNext(pos) */) { MeshSetupNeighborTimer *msnt = mesh_setup_neighbor_timer_list.GetAt(pos); msnt->CancelTimer(); delete msnt; /* Suman's correction -- BEGIN */ void * old_pos = pos; mesh_setup_neighbor_timer_list.GetNext(pos); mesh_setup_neighbor_timer_list.RemoveAt(old_pos);/* END */ } setup_neighbor_list.RemoveAll(); mesh_neighbor_list.RemoveAll(); stopped_member_list.RemoveAll(); mesh_setup_neighbor_timer_list.RemoveAll(); remove_all_agent_list(); Agent::stop(); return;}void mcAgent::remove_all_agent_list (void) { for (void *pos = all_agent_list.GetHeadPosition(); pos != NULL; ) { MeshMember *mm = all_agent_list.GetAt(pos); delete[] mm->source; void *old_pos = pos; all_agent_list.GetNext(pos); delete mm; all_agent_list.RemoveAt(old_pos); } return;}void mcAgent::specific_rx_pkt_handler (Packet *p) { if (p->t != PACKET_APP) { printf ("[Err] at %8.4f < ag %d nd %d > received unknown packet type\n", Scheduler::Clock(),id,n->id); return; } AppPacket *ap = (AppPacket *)p; switch (ap->st) { case PING_RP_RESPONSE : handle_rp_ping_response(ap); break; case MESH_NEIGHBOR_SETUP_REQUEST : handle_mesh_neighbor_setup_req(ap); break; case MESH_NEIGHBOR_SETUP_RESPONSE : handle_mesh_neighbor_setup_resp(ap); break; case MESH_NEIGHBOR_REFRESH : handle_mesh_member_refresh(ap); break;//sri's code case MESH_RT_EXCHANGE : handle_mesh_rt_exchange(ap); break; case MESH_LINK_ADD : handle_mesh_link_add(ap); break; case MESH_LINK_ADD_RESPONSE : handle_mesh_link_add_response(ap); break; case MESH_LINK_DROP : handle_mesh_link_drop(ap); break; case DATA : handle_data(ap); break; // default : printf ("[Err] at %8.4f < ag %d nd %d > received unknown packet subtype\n", Scheduler::Clock(),id,n->id); } return;}MeshMember *mcAgent::create_new_mesh_member_info (int aid, int nid) { assert (all_agent_list.Locate(aid) == NULL); MeshMember *mm = new MeshMember (aid, nid, Scheduler::Clock()); all_agent_list.Add(mm,aid); return mm;}void mcAgent::handle_rp_ping_response (AppPacket *ap) { for (int i = 0; i < ap->u.pingresp_p.ret_nbr_cnt; i++) { MeshMember *mm = create_new_mesh_member_info(ap->u.pingresp_p.ret_nbrs[i].agent_id, ap->u.pingresp_p.ret_nbrs[i].node_id);#ifdef LOG_APP_RP printf ("[pingresp] at %8.4f < ag %d nd %d > found < ag %d nd %d >\n", Scheduler::Clock(), id, n->id, mm->ainfo.agent_id, mm->ainfo.node_id);#endif // LOG_APP_RP } select_mesh_neighbors(); mesh_refresh_timer->SetTimer(CONST_MESH_NEIGHBOR_REFRESH_TIMEOUT); if (mesh_rt_exchange_timer == NULL) { printf("[timer-debug] at %8.4f < ag %d nd %d > timer is null\n",Scheduler::Clock(),id,n->id); } mesh_rt_exchange_timer->SetTimer(CONST_MESH_RT_EXCHANGE_PERIOD); mesh_rt_exchange_check_timer->SetTimer(CONST_MESH_RT_EXCHANGE_TIMEOUT); mesh_link_add_timer->SetTimer(CONST_MESH_LINK_ADD_PERIOD); mesh_link_drop_timer->SetTimer(CONST_MESH_LINK_DROP_PERIOD); return;}/* Select a list of mesh neighbors. These neigbors will be sent *//* periodic mesh refresh messages */void mcAgent::select_mesh_neighbors (void) { int all_agent_count = all_agent_list.GetSize(); int num_mesh_neighbors = (CONST_MESH_NEIGHBORS > all_agent_count) ? all_agent_count : CONST_MESH_NEIGHBORS; int *neigh_indices = get_rand_set(num_mesh_neighbors,all_agent_count); int nlist_index = 0; int this_index = 0; for (void *pos = all_agent_list.GetHeadPosition(); pos != NULL; all_agent_list.GetNext(pos) ) { if (nlist_index == num_mesh_neighbors) break; MeshMember *mm = all_agent_list.GetAt(pos); if (neigh_indices[nlist_index] == this_index) { /* Assign this agent to be a neighbor */ add_to_setup_neighbor_list(mm); MeshSetupNeighborTimer *msnt = new MeshSetupNeighborTimer(this,mm); msnt->SetTimer(CONST_MESH_SETUP_NEIGHBOR_TIMEOUT); /* Suman's correction */ // printf ("[timer-debug] About to add timer at %8.4f for %d at %d\n", Scheduler::Clock(), mm->ainfo.agent_id, id); #ifdef LOG_SELECT_NEIGHBOR printf("[select-neigh] at %8.4f < ag %d nd %d > selects < ag %d nd %d >\n",Scheduler::Clock(),id,n->id,mm->ainfo.agent_id,mm->ainfo.node_id); #endif // LOG_SELECT_NEIGHBOR mesh_setup_neighbor_timer_list.Add(msnt, mm->ainfo.agent_id); tx_mesh_neighbor_setup_req(mm); nlist_index ++; } this_index ++; } delete [] neigh_indices; // tx_mesh_neighbor_refresh(); mesh_keepalive_timer->SetTimer(CONST_MESH_NEIGHBOR_KEEPALIVE_PERIOD); return;}void mcAgent::tx_mesh_neighbor_setup_req (MeshMember *mm) { #ifdef LOG_APP_NEIGHBOR printf ("[setup-neighbor] at %8.4f < ag %d nd %d > requests < ag %d nd %d >\n", Scheduler::Clock(), id, n->id, mm->ainfo.agent_id, mm->ainfo.node_id); #endif // LOG_APP_NEIGHBOR AppPacket *ap = new AppPacket (MESH_NEIGHBOR_SETUP_REQUEST); send_pkt(ap,mm->ainfo.agent_id,mm->ainfo.node_id); return;}// Respond to neighbor setup request with accept or rejectvoid mcAgent::tx_mesh_neighbor_setup_resp (MeshMember *mm, bool accept) { AppPacket *ap = new AppPacket (MESH_NEIGHBOR_SETUP_RESPONSE); ap->u.meshneighborsetupresp_p.accept = accept; send_pkt(ap,mm->ainfo.agent_id,mm->ainfo.node_id); return;}void mcAgent::tx_mesh_refresh (void) { forward_mesh_refresh(id,n->id,mesh_refresh_seq_no,-1,true); return;}/* Forward a mesh refresh packet to all neighbors, except the one specified */void mcAgent::forward_mesh_refresh (int o_aid, int o_nid, int o_seqno, int except_aid, bool isalive) { for (void *pos = mesh_neighbor_list.GetHeadPosition(); pos != NULL; mesh_neighbor_list.GetNext(pos) ) { MeshMember *mm = mesh_neighbor_list.GetAt(pos); if (mm->ainfo.agent_id == except_aid) continue; AppPacket *ap = new AppPacket(MESH_NEIGHBOR_REFRESH); ap->u.meshrefresh_p.is_alive = isalive; ap->u.meshrefresh_p.neighbor_seq_no = mesh_refresh_seq_no; ap->u.meshrefresh_p.origin.agent_id = o_aid; ap->u.meshrefresh_p.origin.node_id = o_nid; ap->u.meshrefresh_p.origin_seq_no = o_seqno; #ifdef LOG_MESH_REFRESH printf ("[mesh-refresh] at %8.4f < ag %d nd %d > is-src < ag %d nd %d > is-dest < ag %d nd %d > is-origin < %d > is-ssn\n", Scheduler::Clock(), id, n->id, mm->ainfo.agent_id, mm->ainfo.node_id, o_aid, o_nid, o_seqno); #endif // LOG_MESH_REFRESH send_pkt(ap,mm->ainfo.agent_id,mm->ainfo.node_id); } mesh_refresh_seq_no ++; return;}//sri's codevoid mcAgent::tx_mesh_rt_exchange (void) { for (void *pos = mesh_neighbor_list.GetHeadPosition(); pos != NULL; mesh_neighbor_list.GetNext(pos) ) { MeshMember *mm = mesh_neighbor_list.GetAt(pos); AppPacket *ap = new AppPacket(MESH_RT_EXCHANGE); ap->u.meshrt_p.valid = new (bool[MAXMESHMEMBERS]); ap->u.meshrt_p.pathlen = new (int[MAXMESHMEMBERS]); ap->u.meshrt_p.cost = new (double[MAXMESHMEMBERS]); ap->u.meshrt_p.path = new (struct AgentInfo *[MAXMESHMEMBERS]); for (int i = 0; i < MAXMESHMEMBERS; i++) { if ((meshrt.valid[i]) && (meshrt.pathlen[i] > 1) && (meshrt.path[i][0].agent_id == mm->ainfo.agent_id)) { ap->u.meshrt_p.valid[i] = false; ap->u.meshrt_p.pathlen[i] = INVALID; ap->u.meshrt_p.path[i] = NULL; ap->u.meshrt_p.cost[i] = INFINITELINKCOST; } else { ap->u.meshrt_p.valid[i] = meshrt.valid[i]; ap->u.meshrt_p.pathlen[i] = meshrt.pathlen[i]; ap->u.meshrt_p.cost[i] = meshrt.cost[i]; if (meshrt.valid[i] == true) { if (i != id) if (meshrt.pathlen[i] > 1) ap->u.meshrt_p.path[i] = (struct AgentInfo *) safe_malloc((meshrt.pathlen[i]-1)*sizeof(struct AgentInfo)); for (int j = 0; j < meshrt.pathlen[i] - 1; j++) { ap->u.meshrt_p.path[i][j].agent_id = meshrt.path[i][j].agent_id; ap->u.meshrt_p.path[i][j].node_id = meshrt.path[i][j].node_id; } } else { ap->u.meshrt_p.path[i] = NULL; } } } #ifdef LOG_APP_MESH_RT printf ("[mesh-rt-send] at %8.4f < ag %d nd %d > updates < ag %d nd %d >\n", Scheduler::Clock(), id, n->id, mm->ainfo.agent_id, mm->ainfo.node_id); #endif // LOG_APP_MESH_RT send_pkt(ap,mm->ainfo.agent_id,mm->ainfo.node_id); } return; } void mcAgent::handle_mesh_rt_exchange(AppPacket *ap) { MeshMember *mm = find_mesh_member_info (ap->src_agent); bool changes = false; // Do not accept anything from non-neighbors if (mm == NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -