diff_prob.cc
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:22k
- /*
- * diff_prob.cc
- * Copyright (C) 2000 by the University of Southern California
- * $Id: diff_prob.cc,v 1.10 2005/08/25 18:58:03 johnh Exp $
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * 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. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
- *
- *
- * The copyright of this module includes the following
- * linking-with-specific-other-licenses addition:
- *
- * In addition, as a special exception, the copyright holders of
- * this module give you permission to combine (via static or
- * dynamic linking) this module with free software programs or
- * libraries that are released under the GNU LGPL and with code
- * included in the standard release of ns-2 under the Apache 2.0
- * license or under otherwise-compatible licenses with advertising
- * requirements (or modified versions of such code, with unchanged
- * license). You may copy and distribute such a system following the
- * terms of the GNU GPL for this module and the licenses of the
- * other code concerned, provided that you include the source code of
- * that other code when and as the GNU GPL requires distribution of
- * source code.
- *
- * Note that people who make modified versions of this module
- * are not obligated to grant this special exception for their
- * modified versions; it is their choice whether to do so. The GNU
- * General Public License gives permission to release a modified
- * version without this exception; this exception also makes it
- * possible to release a modified version which carries forward this
- * exception.
- *
- */
- /****************************************************************/
- /* diff_prob.cc : Chalermek Intanagonwiwat (USC/ISI) 05/18/99 */
- /****************************************************************/
- // Important Note: Work still in progress !
- #include <assert.h>
- #include <math.h>
- #include <stdio.h>
- #include <signal.h>
- #include <float.h>
- #include <tcl.h>
- #include <stdlib.h>
- #include "diff_header.h"
- #include "agent.h"
- #include "tclcl.h"
- #include "ip.h"
- #include "config.h"
- #include "packet.h"
- #include "trace.h"
- #include "random.h"
- #include "classifier.h"
- #include "node.h"
- #include "diffusion.h"
- #include "iflist.h"
- #include "hash_table.h"
- #include "arp.h"
- #include "mac.h"
- #include "ll.h"
- #include "dsr/path.h"
- #include "god.h"
- #include "routing_table.h"
- #include "diff_prob.h"
- static class DiffusionProbClass : public TclClass {
- public:
- DiffusionProbClass() : TclClass("Agent/Diffusion/ProbGradient") {}
- TclObject* create(int , const char*const* ) {
- return(new DiffusionProb());
- }
- } class_diffusion_probability;
- void InterestTimer::expire(Event *)
- {
- a_->InterestPropagate(pkt_, hashPtr_);
- }
- void EnergyTimer::expire(Event *)
- {
- if (node_->energy_model()->energy() < threshold_) {
- if (a_->NEG_REINF_ == true) {
- a_->SendNegReinf();
- }
- threshold_ = threshold_/2;
- a_->is_low_power = true;
- }
- if (threshold_ >= init_eng_/8)
- resched(ENERGY_CHECK);
- }
- DiffusionProb::DiffusionProb() : DiffusionAgent()
- {
- is_low_power = false;
- num_neg_bcast_send = 0;
- num_neg_bcast_rcv = 0;
- }
- void DiffusionProb::recv(Packet* packet, Handler*)
- {
- hdr_cdiff* dfh = HDR_CDIFF(packet);
- // Packet Hash Table is used to keep info about experienced pkts.
- Pkt_Hash_Entry *hashPtr= PktTable.GetHash(dfh->sender_id, dfh->pk_num);
- #ifdef DEBUG_PROB
- printf("DF node %x recv %s (%x, %x, %d)n",
- THIS_NODE, MsgStr[dfh->mess_type], (dfh->sender_id).addr_,
- (dfh->sender_id).port_, dfh->pk_num);
- #endif
- // Received this packet before ?
- if (hashPtr != NULL) {
- consider_old(packet);
- return;
- }
- // Never receive it before ? Put in hash table.
- PktTable.put_in_hash(dfh);
- // Take action for a new pkt.
-
- consider_new(packet);
- }
- void DiffusionProb::consider_old(Packet *pkt)
- {
- hdr_cdiff* dfh = HDR_CDIFF(pkt);
- unsigned char msg_type = dfh->mess_type;
- unsigned int dtype = dfh->data_type;
- Pkt_Hash_Entry *hashPtr;
- From_List *fromPtr;
- nsaddr_t from_nodeID, forward_nodeID;
- switch (msg_type) {
- case INTEREST :
- hashPtr = PktTable.GetHash(dfh->sender_id, dfh->pk_num);
- if (hashPtr->is_forwarded == true) {
- Packet::free(pkt);
- return;
- }
- from_nodeID = (dfh->sender_id).addr_;
- forward_nodeID = (dfh->forward_agent_id).addr_;
- hashPtr->num_from++;
- fromPtr = new From_List;
- AGT_ADDR(fromPtr) = dfh->forward_agent_id;
- fromPtr->rank = hashPtr->num_from;
- if (from_nodeID == forward_nodeID)
- fromPtr->is_sink = true;
- fromPtr->next = hashPtr->from_agent;
- hashPtr->from_agent = fromPtr;
- // Check if this hashPtr has timer, and if lists already exist,
- // to decide whether to create or update Out_List and In_List
- if (hashPtr->timer == NULL) {
- if (hashPtr->has_list==false) {
- CreateIOList(hashPtr, dtype);
- }
- else {
- UpdateIOList(fromPtr, dtype);
- }
- }
-
- Packet::free(pkt);
- break;
- default :
- Packet::free(pkt);
- break;
- }
- }
- void DiffusionProb::consider_new(Packet *pkt)
- {
- hdr_cdiff* dfh = HDR_CDIFF(pkt);
- unsigned char msg_type = dfh->mess_type;
- unsigned int dtype = dfh->data_type;
- Pkt_Hash_Entry *hashPtr;
- From_List *fromPtr;
- Agent_List *agentPtr;
- Agent_List *cur;
- PrvCurPtr RetVal;
- nsaddr_t from_nodeID, forward_nodeID;
- int i;
- switch (msg_type) {
- case INTEREST :
- hashPtr = PktTable.GetHash(dfh->sender_id, dfh->pk_num);
- // Check if it comes from sink agent of this node
- // If so we have to keep it in sink list
- from_nodeID = (dfh->sender_id).addr_;
- forward_nodeID = (dfh->forward_agent_id).addr_;
- if (THIS_NODE == from_nodeID) {
- // It's from a sink on this node.
- // Is it already in list ?
- RetVal = INTF_FIND(routing_table[dtype].sink, dfh->sender_id);
- if (RetVal.cur == NULL) {
- // No, it's not.
- agentPtr = new Agent_List;
- AGT_ADDR(agentPtr) = dfh->sender_id;
- INTF_INSERT(routing_table[dtype].sink, agentPtr);
- God::instance()->AddSink(dtype, THIS_NODE);
- }
- }
- else {
-
- // It's not from a sink on this node.
- fromPtr = new From_List;
- hashPtr->from_agent = fromPtr;
- hashPtr->num_from = 1;
- AGT_ADDR(fromPtr) = dfh->forward_agent_id;
- fromPtr->rank = 1;
- fromPtr->next = NULL;
- // Is the forwarder node is a sink node ?
- // This information is useful when we do negative reinforcement.
- if ( from_nodeID == forward_nodeID )
- fromPtr->is_sink = true;
- }
- // Do we have to request data ?
- if (routing_table[dtype].source == NULL) {
- // No, we don't. Better forward the interest.
- hashPtr->timer = new InterestTimer(this, hashPtr, pkt);
- (hashPtr->timer)->sched(INTEREST_DELAY*Random::uniform(1.0));
- }
- else {
-
- // Since this node has sources,it won't propagate the interest.
- // We need to create Out_List and In_List in routing table [dtype] now.
- CreateIOList(hashPtr, dtype);
- data_request_all(dtype);
- Packet::free(pkt);
- }
- break;
- case POS_REINFORCE :
- if ( POS_REINF_ == false ) {
- printf("Hey, we are not in pos_reinf mode.n");
- Packet::free(pkt);
- exit(-1);
- }
- IncGradient(dtype, dfh->forward_agent_id);
- CAL_RANGE(routing_table[dtype].active);
- if (routing_table[dtype].source == NULL) {
- if (is_low_power == false) {
- FwdPosReinf(dtype, pkt);
- return;
- }
- }
- Packet::free(pkt);
- break;
- case NEG_REINFORCE :
- if (NEG_REINF_ == false) {
- printf("Hey, we are not in neg_reinf mode.n");
- Packet::free(pkt);
- exit(-1);
- }
- // Negative Reinforcement won't be forwarded.
- num_neg_bcast_rcv++;
- for (i=0; i<MAX_DATA_TYPE; i++) {
- RetVal = INTF_FIND(routing_table[i].active, dfh->sender_id);
- if (RetVal.cur == NULL ) {
- continue;
- }
- // If it is not a sink, we decrease the gradient.
- if ( IS_SINK(RetVal.cur) == false) {
- DecGradient(i, dfh->sender_id);
- CAL_RANGE(routing_table[i].active);
- }
- }
- Packet::free(pkt);
- break;
- case DATA_READY :
- // put source_agent in source list of routing table
- agentPtr = new Agent_List;
- AGT_ADDR(agentPtr) = dfh->sender_id;
- agentPtr->next = routing_table[dtype].source;
- routing_table[dtype].source = agentPtr;
- if (routing_table[dtype].active != NULL ||
- routing_table[dtype].sink != NULL) {
- SEND_MESSAGE(dtype, dfh->sender_id, DATA_REQUEST);
- }
- Packet::free(pkt);
- break;
- case DATA :
- DataForSink(pkt);
- routing_table[dtype].IncRecvCnt(dfh->forward_agent_id);
- ForwardData(pkt);
- if (routing_table[dtype].counter >= MAX_REINFORCE_COUNTER) {
- if (is_low_power == false) {
- if (POS_REINF_ == true)
- GenPosReinf(dtype);
- return;
- }
- if (routing_table[dtype].sink != NULL) {
- if (POS_REINF_ == true)
- GenPosReinf(dtype);
- return;
- }
- }
- break;
- case INHIBIT :
- if (routing_table[dtype].active == NULL) {
- Packet::free(pkt);
- return;
- }
- RetVal=INTF_FIND(routing_table[dtype].active, dfh->sender_id);
- if (RetVal.cur == NULL){
- Packet::free(pkt);
- return;
- }
- INTF_REMOVE(RetVal.prv, RetVal.cur);
- INTF_INSERT(routing_table[dtype].inactive, RetVal.cur);
- routing_table[dtype].num_active --;
- NORMALIZE(routing_table[dtype].active);
- CAL_RANGE(routing_table[dtype].active);
- if (routing_table[dtype].num_active < 1) {
- // *** You need to stop the source if you have one. *****
- if (routing_table[dtype].source != NULL ) {
- for (cur=routing_table[dtype].source; cur != NULL;
- cur=AGENT_NEXT(cur)) {
- SEND_MESSAGE(dtype, AGT_ADDR(cur), DATA_STOP);
- }
- Packet::free(pkt);
- return;
- }
- // If not, send inhibit signal upstream
- SendInhibit(dtype);
- }
-
- Packet::free(pkt);
- return;
- case TX_FAILED :
- if (BACKTRACK_ == false) {
- printf("We are not in backtracking mode.n");
- Packet::free(pkt);
- exit(-1);
- }
- if (routing_table[dtype].active == NULL) {
- ForwardTxFailed(pkt);
- return;
- }
- // RetVal=INTF_FIND(routing_table[dtype].active, dfh->sender_id);
- RetVal=INTF_FIND(routing_table[dtype].active, dfh->forward_agent_id);
- if (RetVal.cur != NULL){
- INTF_REMOVE(RetVal.prv, RetVal.cur);
- INTF_INSERT(routing_table[dtype].inactive, RetVal.cur);
- routing_table[dtype].num_active --;
- NORMALIZE(routing_table[dtype].active);
- CAL_RANGE(routing_table[dtype].active);
- }
- if (routing_table[dtype].num_active < 1) {
- ForwardTxFailed(pkt);
- return;
- }
-
- ReTxData(pkt);
- Packet::free(pkt);
- return;
- default :
-
- Packet::free(pkt);
- break;
- }
- }
- void DiffusionProb::InterestPropagate(Packet *pkt,
- Pkt_Hash_Entry *hashPtr)
- {
- hdr_cdiff *dfh = HDR_CDIFF(pkt);
- unsigned int dtype=dfh->data_type;
- CreateIOList(hashPtr, dtype);
- if ( routing_table[dtype].source != NULL ) {
- data_request_all(dtype);
- Packet::free(pkt);
- return;
- }
- MACprepare(pkt, MAC_BROADCAST, NS_AF_ILINK, 0);
- MACsend(pkt, 0);
- overhead++;
- hashPtr->is_forwarded = true;
- }
- void DiffusionProb::ForwardData(Packet *pkt)
- {
- hdr_cdiff *dfh = HDR_CDIFF(pkt);
- unsigned int dtype =dfh->data_type;
- Out_List *cur_out;
- Packet *cur_pkt;
- hdr_cdiff *cur_dfh;
- hdr_ip *cur_iph;
- cur_out = WHERE_TO_GO(routing_table[dtype].active);
- if (cur_out !=NULL) {
- // Got somewhere to go.
- cur_pkt = pkt;
- cur_iph = HDR_IP(cur_pkt);
- cur_iph->dst_ = AGT_ADDR(cur_out);
- cur_dfh = HDR_CDIFF(cur_pkt);
- cur_dfh->forward_agent_id = here_;
- cur_dfh->num_next = 1;
- cur_dfh->next_nodes[0] = NODE_ADDR(cur_out);
- cur_out->num_data_send++;
- #ifdef DEBUG_PROB
- printf("DF node %x will send data (%x, %x, %d) to %xn",
- THIS_NODE, (cur_dfh->sender_id).addr_,
- (cur_dfh->sender_id).port_, cur_dfh->pk_num,
- AGT_ADDR(cur_out));
- #endif
- MACprepare(cur_pkt, NODE_ADDR(cur_out), NS_AF_INET, 1);
- MACsend(cur_pkt, 0);
- return;
- }
- if (routing_table[dtype].sink != NULL) {
- // No where to go but have sinks.
- Packet::free(pkt);
- return;
- }
- // No where to go and no sink.
- // Check if we have sources on this node.
- // If so, we stop the sources. Otherwise, we generate the transmission
- // failure packet.
- Agent_List *cur;
- if (routing_table[dtype].source != NULL ) {
- for (cur=routing_table[dtype].source; cur != NULL; cur=AGENT_NEXT(cur)) {
- // DATA_STOP never go out of the node, so don't care if wireless.
- SEND_MESSAGE(dtype, AGT_ADDR(cur), DATA_STOP);
- }
- Packet::free(pkt);
- return;
- }
- // No source, generate the transmission failure packet.
- if (BACKTRACK_ == false) {
- Packet::free(pkt);
- return;
- }
- // YES, we are in backtracking mode so send TX_FAILED to the forwarder.
- cur_pkt = prepare_message(dtype, dfh->forward_agent_id, TX_FAILED);
- cur_dfh = HDR_CDIFF(cur_pkt);
- cur_dfh->info.sender = dfh->sender_id;
- cur_dfh->info.seq = dfh->pk_num;
- hdr_cmn *cmh = HDR_CMN(pkt);
- cur_dfh->info.size = cmh->size_;
- MACprepare(cur_pkt, (dfh->forward_agent_id).addr_, NS_AF_INET, 0);
- MACsend(cur_pkt, 0);
- Packet::free(pkt);
- }
- void DiffusionProb::ForwardTxFailed(Packet *pkt)
- {
- hdr_cdiff *dfh = HDR_CDIFF(pkt);
- hdr_ip *iph = HDR_IP(pkt);
- dfh->forward_agent_id = here_;
- Pkt_Hash_Entry *hashPtr=PktTable.GetHash(dfh->info.sender, dfh->info.seq);
- if (hashPtr == NULL) {
- Packet::free(pkt);
- return;
- }
- iph->dst_ = hashPtr->forwarder_id;
- dfh->num_next = 1;
- dfh->next_nodes[0] = (hashPtr->forwarder_id).addr_;
- MACprepare(pkt, (hashPtr->forwarder_id).addr_, NS_AF_INET, 0);
- MACsend(pkt, 0);
- overhead++;
- }
- void DiffusionProb::ReTxData(Packet *pkt)
- {
- hdr_cdiff *dfh = HDR_CDIFF(pkt);
- Pkt_Hash_Entry *hashPtr=PktTable.GetHash(dfh->info.sender, dfh->info.seq);
- // Make sure it has data on its cache.
- if (hashPtr == NULL) {
- printf("No hash for (%x, %x, %d)n", (dfh->info.sender).addr_,
- (dfh->info.sender).port_, dfh->info.seq);
- return;
- }
- int dtype = dfh->data_type;
- Out_List *to_out = WHERE_TO_GO(routing_table[dtype].active);
- if (to_out == NULL) return;
- Packet *rtxPkt = prepare_message(dtype, AGT_ADDR(to_out), DATA);
- hdr_cdiff *rtx_dfh = HDR_CDIFF(rtxPkt);
- hdr_cmn *rtx_cmh = HDR_CMN(rtxPkt);
- rtx_dfh->sender_id = dfh->info.sender;
- rtx_dfh->pk_num = dfh->info.seq;
- rtx_cmh->size_ = dfh->info.size;
-
- MACprepare(rtxPkt, NODE_ADDR(to_out), NS_AF_INET, 1);
- MACsend(rtxPkt, 0);
- printf("Retransmit (%d,%d,%d)n",(rtx_dfh->sender_id).addr_,
- (rtx_dfh->sender_id).port_, rtx_dfh->pk_num);
- }
- void DiffusionProb::data_request_all(unsigned int dtype)
- {
- Agent_List *cur_agent;
- for (cur_agent=routing_table[dtype].source; cur_agent != NULL;
- cur_agent = AGENT_NEXT(cur_agent) ) {
- SEND_MESSAGE(dtype, AGT_ADDR(cur_agent), DATA_REQUEST);
- }
- }
- void DiffusionProb::CreateIOList(Pkt_Hash_Entry *hashPtr,
- unsigned int dtype)
- {
- From_List *fromPtr;
- // Better clear out all existing IO lists first.
- INTF_FREEALL(routing_table[dtype].active);
- INTF_FREEALL(routing_table[dtype].inactive);
- INTF_FREEALL(routing_table[dtype].iif);
- INTF_FREEALL(routing_table[dtype].down_iif);
- routing_table[dtype].num_active=0;
- routing_table[dtype].counter=0;
- for (fromPtr = hashPtr->from_agent; fromPtr != NULL;
- fromPtr = FROM_NEXT(fromPtr) ) {
- add_outlist(dtype, fromPtr);
- }
- hashPtr->has_list = true;
- CalGradient(dtype);
- CAL_RANGE(routing_table[dtype].active);
- }
- void DiffusionProb::UpdateIOList(From_List *fromPtr,
- unsigned int dtype)
- {
- add_outlist(dtype, fromPtr);
- CalGradient(dtype);
- CAL_RANGE(routing_table[dtype].active);
- }
- void DiffusionProb::add_outlist(unsigned int dtype, From_List *foundPtr)
- {
- Out_List *outPtr = new Out_List;
- AGT_ADDR(outPtr) = AGT_ADDR(foundPtr);
- outPtr->rank = foundPtr->rank;
- outPtr->is_sink = foundPtr->is_sink;
- INTF_INSERT(routing_table[dtype].active, outPtr);
- routing_table[dtype].num_active ++;
- }
- void DiffusionProb::Print_IOlist()
- {
- Out_List *cur_out;
- In_List *cur_in;
- int i;
- for (i=0; i<1; i++) {
- printf("Node %d neg bcast send %d, neg bcast rcv %dn",
- THIS_NODE, num_neg_bcast_send, num_neg_bcast_rcv);
- for (cur_out = routing_table[i].active; cur_out != NULL;
- cur_out = OUT_NEXT(cur_out) ) {
- printf("DF node %d has oif %d (%f,%d) send data %d recv neg %d pos %dn",
- THIS_NODE, NODE_ADDR(cur_out), GRADIENT(cur_out),
- routing_table[i].num_active, NUM_DATA_SEND(cur_out),
- NUM_NEG_RECV(cur_out), NUM_POS_RECV(cur_out));
- }
- for (cur_in = routing_table[i].iif; cur_in != NULL;
- cur_in = IN_NEXT(cur_in) ) {
- printf("Diffusion node %d has iif for %dn",
- THIS_NODE, NODE_ADDR(cur_in));
- }
- for (cur_out = routing_table[i].inactive; cur_out != NULL;
- cur_out = OUT_NEXT(cur_out) ) {
- printf("Diffusion node %d has down oif %d (%f, %d) send %dn",
- THIS_NODE, NODE_ADDR(cur_out), cur_out->gradient,
- routing_table[i].num_active, cur_out->num_data_send);
- }
- for (cur_in = routing_table[i].down_iif; cur_in != NULL;
- cur_in = IN_NEXT(cur_in) ) {
- printf("Diffusion node %d has down_iif for %d (recv %d)n", THIS_NODE,
- NODE_ADDR(cur_in), cur_in->total_received);
- }
- }
-
- }
- void DiffusionProb::CalGradient(unsigned int dtype)
- {
- Out_List *cur_out;
-
- for (cur_out = routing_table[dtype].active; cur_out != NULL;
- cur_out = OUT_NEXT(cur_out) ) {
- cur_out->gradient = pow(2, routing_table[dtype].num_active -
- cur_out->rank) /
- ( pow(2, routing_table[dtype].num_active) - 1);
- }
- }
- void DiffusionProb::IncGradient(unsigned int dtype, ns_addr_t addr)
- {
- Out_List *cur_out;
- PrvCurPtr RetVal;
- RetVal=INTF_FIND(routing_table[dtype].active, addr);
- if (RetVal.cur != NULL) {
- cur_out = (Out_List *)(RetVal.cur);
- GRADIENT(cur_out) = GRADIENT(cur_out) + 0.99;
- NORMALIZE(routing_table[dtype].active);
- }
- }
- void DiffusionProb::DecGradient(unsigned int dtype, ns_addr_t addr)
- {
- Out_List *cur_out;
- PrvCurPtr RetVal;
- RetVal=INTF_FIND(routing_table[dtype].active, addr);
- if (RetVal.cur != NULL) {
- for (cur_out = routing_table[dtype].active; cur_out != NULL;
- cur_out = OUT_NEXT(cur_out) )
- GRADIENT(cur_out) = GRADIENT(cur_out) + 1.0;
- cur_out = (Out_List *)(RetVal.cur);
- GRADIENT(cur_out) = GRADIENT(cur_out) - 1.99;
- if (GRADIENT(cur_out)< 0.0) {
- GRADIENT(cur_out) = 0.0;
- }
- NORMALIZE(routing_table[dtype].active);
- }
- }
- void DiffusionProb::GenPosReinf(unsigned int dtype)
- {
- In_List *cur_in, *max_in;
- Packet *pkt;
- max_in = FIND_MAX_IN(routing_table[dtype].iif);
- if (max_in != NULL) {
- if ( (max_in->total_received - max_in->prev_received) <
- routing_table[dtype].counter) {
- pkt=prepare_message(dtype, AGT_ADDR(max_in), POS_REINFORCE);
- MACprepare(pkt, NODE_ADDR(max_in), NS_AF_INET, 0);
- MACsend(pkt, 0);
- overhead++;
- }
- }
- routing_table[dtype].counter = 0;
- for (cur_in = routing_table[dtype].iif; cur_in != NULL;
- cur_in = IN_NEXT(cur_in) ) {
- cur_in->prev_received = cur_in->total_received;
- }
- }
- void DiffusionProb::FwdPosReinf(unsigned int dtype, Packet *pkt)
- {
- In_List *cur_in, *max_in=NULL;
- hdr_ip *iph = HDR_IP(pkt);
- hdr_cdiff *dfh = HDR_CDIFF(pkt);
- max_in = FIND_MAX_IN(routing_table[dtype].iif);
- if (max_in != NULL) {
- iph->dst_ = AGT_ADDR(max_in);
- dfh->num_next = 1;
- dfh->next_nodes[0] = NODE_ADDR(max_in);
- dfh->forward_agent_id = here_;
- MACprepare(pkt, NODE_ADDR(max_in), NS_AF_INET, 0);
- MACsend(pkt, 0);
- overhead++;
- }
- else {
- Packet::free(pkt);
- }
- routing_table[dtype].counter = 0;
- for (cur_in = routing_table[dtype].iif; cur_in != NULL;
- cur_in = IN_NEXT(cur_in) ) {
- cur_in->prev_received = cur_in->total_received;
- }
- }
- void DiffusionProb::Start()
- {
- DiffusionAgent::Start();
- energy_timer = new EnergyTimer(this, node);
- energy_timer->resched(ENERGY_CHECK + ENERGY_CHECK * Random::uniform(1.0));
- }
- void DiffusionProb::InterfaceDown(int dtype, ns_addr_t DownDiff)
- {
- PrvCurPtr RetVal;
- RetVal = INTF_FIND(routing_table[dtype].iif, DownDiff);
- if (RetVal.cur != NULL) {
- INTF_REMOVE(RetVal.prv, RetVal.cur);
- INTF_INSERT(routing_table[dtype].down_iif, RetVal.cur);
- return;
- }
- RetVal = INTF_FIND(routing_table[dtype].active, DownDiff);
- if (RetVal.cur == NULL)
- return;
- INTF_REMOVE(RetVal.prv, RetVal.cur);
- INTF_INSERT(routing_table[dtype].inactive, RetVal.cur);
- routing_table[dtype].num_active --;
- NORMALIZE(routing_table[dtype].active);
- CAL_RANGE(routing_table[dtype].active);
- if (routing_table[dtype].num_active < 1) {
- // ** If we have a source, stop the source.
- // If not, send inhibit signal upstream. **
- Agent_List *cur;
- if (routing_table[dtype].source != NULL ) {
- for (cur=routing_table[dtype].source; cur != NULL; cur=AGENT_NEXT(cur)) {
- SEND_MESSAGE(dtype, AGT_ADDR(cur), DATA_STOP);
- }
- }
- else {
- SendInhibit(dtype);
- }
- }
- }
- void DiffusionProb::SendInhibit(int dtype)
- {
- // Wireless. Just use one MAC broadcast.
- ns_addr_t bcast_addr;
- bcast_addr.addr_ = MAC_BROADCAST;
- bcast_addr.port_ = ROUTING_PORT;
- Packet *pkt = prepare_message(dtype, bcast_addr, INHIBIT);
- MACprepare(pkt, MAC_BROADCAST, NS_AF_ILINK, 0);
- MACsend(pkt, 0);
- overhead++;
- return;
- }
- // For negative reinforcement, we don't care the data type.
- // Any neighbor upstream of any data type should be informed.
- void DiffusionProb::SendNegReinf()
- {
- ns_addr_t bcast_addr;
- bcast_addr.addr_ = MAC_BROADCAST;
- bcast_addr.port_ = ROUTING_PORT;
- Packet *pkt = prepare_message(0, bcast_addr, NEG_REINFORCE);
- MACprepare(pkt, MAC_BROADCAST, NS_AF_ILINK, 0);
- MACsend(pkt, 0);
- overhead++;
- return;
- }