Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

diff_prob.cc

Go to the documentation of this file.
00001 // Copyright (c) 2000 by the University of Southern California
00002 // All rights reserved.
00003 //
00004 // Permission to use, copy, modify, and distribute this software and its
00005 // documentation in source and binary forms for non-commercial purposes
00006 // and without fee is hereby granted, provided that the above copyright
00007 // notice appear in all copies and that both the copyright notice and
00008 // this permission notice appear in supporting documentation. and that
00009 // any documentation, advertising materials, and other materials related
00010 // to such distribution and use acknowledge that the software was
00011 // developed by the University of Southern California, Information
00012 // Sciences Institute.  The name of the University may not be used to
00013 // endorse or promote products derived from this software without
00014 // specific prior written permission.
00015 //
00016 // THE UNIVERSITY OF SOUTHERN CALIFORNIA makes no representations about
00017 // the suitability of this software for any purpose.  THIS SOFTWARE IS
00018 // PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES,
00019 // INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00020 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 //
00022 // Other copyrights might apply to parts of this software and are so
00023 // noted when applicable.
00024 //
00025 
00026 /****************************************************************/
00027 /* diff_prob.cc : Chalermek Intanagonwiwat (USC/ISI)  05/18/99  */
00028 /****************************************************************/
00029 
00030 // Important Note: Work still in progress !
00031 
00032 #include <assert.h>
00033 #include <math.h>
00034 #include <stdio.h>
00035 #include <signal.h>
00036 #include <float.h>
00037 
00038 #include <tcl.h>
00039 #include <stdlib.h>
00040 
00041 #include "diff_header.h"
00042 #include "agent.h"
00043 #include "tclcl.h"
00044 #include "ip.h"
00045 #include "config.h"
00046 #include "packet.h"
00047 #include "trace.h"
00048 #include "random.h"
00049 #include "classifier.h"
00050 #include "node.h"
00051 #include "diffusion.h"
00052 #include "iflist.h"
00053 #include "hash_table.h"
00054 #include "arp.h"
00055 #include "mac.h"
00056 #include "ll.h"
00057 #include "dsr/path.h"
00058 #include "god.h"
00059 #include "routing_table.h"
00060 #include "diff_prob.h"
00061 
00062 
00063 static class DiffusionProbClass : public TclClass {
00064 public:
00065   DiffusionProbClass() : TclClass("Agent/Diffusion/ProbGradient") {}
00066   TclObject* create(int , const char*const* ) {
00067     return(new DiffusionProb());
00068   }
00069 } class_diffusion_probability;
00070 
00071 
00072 
00073 void InterestTimer::expire(Event *)
00074 {
00075   a_->InterestPropagate(pkt_, hashPtr_);
00076 }
00077 
00078 
00079 void EnergyTimer::expire(Event *)
00080 {
00081   if (node_->energy_model()->energy() < threshold_) {    
00082     if (a_->NEG_REINF_ == true) {
00083       a_->SendNegReinf();
00084     }
00085     threshold_ = threshold_/2;
00086     a_->is_low_power = true;
00087   }
00088 
00089   if (threshold_ >= init_eng_/8) 
00090     resched(ENERGY_CHECK); 
00091 }
00092 
00093 
00094 DiffusionProb::DiffusionProb() : DiffusionAgent()
00095 {
00096   is_low_power = false;
00097   num_neg_bcast_send = 0;
00098   num_neg_bcast_rcv = 0;
00099 }
00100 
00101 
00102 void DiffusionProb::recv(Packet* packet, Handler*)
00103 {
00104   hdr_cdiff* dfh = HDR_CDIFF(packet);
00105 
00106   // Packet Hash Table is used to keep info about experienced pkts.
00107 
00108   Pkt_Hash_Entry *hashPtr= PktTable.GetHash(dfh->sender_id, dfh->pk_num);
00109 
00110 
00111 #ifdef DEBUG_PROB
00112      printf("DF node %x recv %s (%x, %x, %d)\n",
00113             THIS_NODE, MsgStr[dfh->mess_type], (dfh->sender_id).addr_, 
00114             (dfh->sender_id).port_, dfh->pk_num);
00115 #endif
00116 
00117 
00118      // Received this packet before ?
00119 
00120      if (hashPtr != NULL) {
00121        consider_old(packet);
00122        return;
00123      }
00124 
00125      // Never receive it before ? Put in hash table.
00126 
00127      PktTable.put_in_hash(dfh);
00128 
00129      // Take action for a new pkt.
00130        
00131      consider_new(packet);     
00132 }
00133 
00134 
00135 void DiffusionProb::consider_old(Packet *pkt)
00136 {
00137   hdr_cdiff* dfh = HDR_CDIFF(pkt);
00138   unsigned char msg_type = dfh->mess_type;
00139   unsigned int dtype = dfh->data_type;
00140 
00141   Pkt_Hash_Entry *hashPtr;
00142   From_List  *fromPtr;
00143   nsaddr_t from_nodeID, forward_nodeID;
00144 
00145   switch (msg_type) {
00146     case INTEREST :
00147 
00148       hashPtr = PktTable.GetHash(dfh->sender_id, dfh->pk_num);
00149 
00150       if (hashPtr->is_forwarded == true) {
00151         Packet::free(pkt);
00152         return;
00153       }
00154 
00155       from_nodeID = (dfh->sender_id).addr_;
00156       forward_nodeID = (dfh->forward_agent_id).addr_;
00157 
00158 
00159       hashPtr->num_from++;
00160       fromPtr = new From_List;
00161       AGT_ADDR(fromPtr) = dfh->forward_agent_id;
00162       fromPtr->rank = hashPtr->num_from;
00163 
00164       if (from_nodeID == forward_nodeID)
00165         fromPtr->is_sink = true;
00166 
00167       fromPtr->next = hashPtr->from_agent;
00168       hashPtr->from_agent = fromPtr;
00169 
00170       // Check if this hashPtr has timer, and if lists already exist,
00171       // to decide whether to create or update Out_List and In_List
00172 
00173       if (hashPtr->timer == NULL) {
00174         if (hashPtr->has_list==false) {
00175           CreateIOList(hashPtr, dtype);
00176         } 
00177         else {
00178           UpdateIOList(fromPtr, dtype);
00179         }
00180       }
00181       
00182       Packet::free(pkt);
00183       break;
00184 
00185     default : 
00186       Packet::free(pkt);        
00187       break;
00188   }
00189 }
00190 
00191 
00192 void DiffusionProb::consider_new(Packet *pkt)
00193 {
00194   hdr_cdiff* dfh = HDR_CDIFF(pkt);
00195   unsigned char msg_type = dfh->mess_type;
00196   unsigned int dtype = dfh->data_type;
00197 
00198   Pkt_Hash_Entry *hashPtr;
00199   From_List  *fromPtr;
00200   Agent_List *agentPtr;
00201   Agent_List *cur;
00202   PrvCurPtr  RetVal;
00203   nsaddr_t   from_nodeID, forward_nodeID;
00204 
00205   int i;
00206 
00207   switch (msg_type) {
00208     case INTEREST : 
00209 
00210       hashPtr = PktTable.GetHash(dfh->sender_id, dfh->pk_num);
00211 
00212       // Check if it comes from sink agent of this node
00213       // If so we have to keep it in sink list 
00214 
00215       from_nodeID = (dfh->sender_id).addr_;
00216       forward_nodeID = (dfh->forward_agent_id).addr_;
00217 
00218 
00219       if (THIS_NODE == from_nodeID) {       
00220 
00221         // It's from a sink on this node.
00222         // Is it already in list ?
00223 
00224         RetVal = INTF_FIND(routing_table[dtype].sink, dfh->sender_id);
00225 
00226         if (RetVal.cur == NULL) {            
00227           // No, it's not.
00228           agentPtr = new Agent_List;
00229           AGT_ADDR(agentPtr) = dfh->sender_id;
00230           INTF_INSERT(routing_table[dtype].sink, agentPtr);
00231 
00232           God::instance()->AddSink(dtype, THIS_NODE);
00233         }       
00234 
00235       }
00236       else {                             
00237         
00238         // It's not from a sink on this node.
00239 
00240         fromPtr = new From_List;
00241         hashPtr->from_agent = fromPtr;
00242         hashPtr->num_from = 1;
00243         AGT_ADDR(fromPtr) = dfh->forward_agent_id;
00244         fromPtr->rank = 1;
00245         fromPtr->next = NULL;    
00246 
00247         // Is the forwarder node is a sink node ? 
00248         // This information is useful when we do negative reinforcement.
00249 
00250         if ( from_nodeID == forward_nodeID )
00251           fromPtr->is_sink = true;
00252 
00253       }
00254 
00255 
00256       // Do we have to request data ?
00257 
00258       if (routing_table[dtype].source == NULL) {     
00259 
00260         // No, we don't. Better forward the interest.
00261 
00262         hashPtr->timer = new InterestTimer(this, hashPtr, pkt);
00263         (hashPtr->timer)->sched(INTEREST_DELAY*Random::uniform(1.0));
00264       } 
00265       else {
00266         
00267         // Since this node has sources,it won't propagate the interest.
00268         // We need to create Out_List and In_List in routing table [dtype] now.
00269 
00270         CreateIOList(hashPtr, dtype);
00271         data_request_all(dtype);
00272 
00273         Packet::free(pkt);
00274       }
00275       break;
00276 
00277 
00278     case POS_REINFORCE :
00279 
00280       if ( POS_REINF_ == false ) {
00281         printf("Hey, we are not in pos_reinf mode.\n");
00282         Packet::free(pkt);
00283         exit(-1);
00284       }
00285 
00286       IncGradient(dtype, dfh->forward_agent_id);
00287       CAL_RANGE(routing_table[dtype].active);
00288 
00289       if (routing_table[dtype].source == NULL) {
00290         if (is_low_power == false) {
00291           FwdPosReinf(dtype, pkt);
00292           return;
00293         }
00294       } 
00295 
00296       Packet::free(pkt);
00297       break;
00298 
00299 
00300     case NEG_REINFORCE :  
00301 
00302       if (NEG_REINF_ == false) {
00303         printf("Hey, we are not in neg_reinf mode.\n");
00304         Packet::free(pkt);
00305         exit(-1);
00306       }
00307 
00308       // Negative Reinforcement won't be forwarded.
00309 
00310       num_neg_bcast_rcv++;
00311 
00312       for (i=0; i<MAX_DATA_TYPE; i++) {
00313         RetVal = INTF_FIND(routing_table[i].active, dfh->sender_id);
00314         if (RetVal.cur == NULL ) {
00315           continue;
00316         }
00317 
00318         // If it is not a sink, we decrease the gradient.
00319 
00320         if ( IS_SINK(RetVal.cur) == false) {
00321           DecGradient(i, dfh->sender_id);
00322           CAL_RANGE(routing_table[i].active);
00323         }
00324       }
00325 
00326       Packet::free(pkt);
00327       break;
00328 
00329 
00330     case DATA_READY :
00331 
00332       // put source_agent in source list of routing table
00333 
00334       agentPtr = new Agent_List;
00335       AGT_ADDR(agentPtr) = dfh->sender_id;
00336       agentPtr->next = routing_table[dtype].source;
00337       routing_table[dtype].source = agentPtr;
00338 
00339       if (routing_table[dtype].active != NULL ||
00340           routing_table[dtype].sink != NULL) {
00341         SEND_MESSAGE(dtype, dfh->sender_id, DATA_REQUEST);
00342       }
00343 
00344       Packet::free(pkt);
00345       break;
00346 
00347 
00348     case DATA :
00349 
00350       DataForSink(pkt);
00351 
00352       routing_table[dtype].IncRecvCnt(dfh->forward_agent_id);
00353       ForwardData(pkt);
00354 
00355       if (routing_table[dtype].counter >= MAX_REINFORCE_COUNTER) {
00356         if (is_low_power == false) {
00357           if (POS_REINF_ == true)
00358             GenPosReinf(dtype);
00359           return;
00360         }
00361         if (routing_table[dtype].sink != NULL) {
00362           if (POS_REINF_ == true)
00363             GenPosReinf(dtype);
00364           return;
00365         }
00366       }
00367       break;
00368 
00369 
00370     case INHIBIT :
00371 
00372       if (routing_table[dtype].active == NULL) {
00373         Packet::free(pkt);
00374         return;
00375       }
00376 
00377       RetVal=INTF_FIND(routing_table[dtype].active, dfh->sender_id);
00378       if (RetVal.cur == NULL){
00379         Packet::free(pkt);
00380         return;
00381       }
00382 
00383       INTF_REMOVE(RetVal.prv, RetVal.cur);
00384       INTF_INSERT(routing_table[dtype].inactive, RetVal.cur);
00385       routing_table[dtype].num_active --;
00386       NORMALIZE(routing_table[dtype].active);
00387       CAL_RANGE(routing_table[dtype].active);
00388 
00389       if (routing_table[dtype].num_active < 1) {
00390 
00391         // *** You need to stop the source if you have one. *****
00392 
00393         if (routing_table[dtype].source != NULL ) {
00394           for (cur=routing_table[dtype].source; cur != NULL; 
00395                cur=AGENT_NEXT(cur)) {
00396             SEND_MESSAGE(dtype, AGT_ADDR(cur), DATA_STOP);
00397           }
00398           Packet::free(pkt);
00399           return;
00400         }
00401 
00402         // If not, send inhibit signal upstream
00403 
00404         SendInhibit(dtype);
00405       }
00406       
00407       Packet::free(pkt);
00408       return;
00409 
00410 
00411     case TX_FAILED :
00412 
00413       if (BACKTRACK_ == false) {
00414         printf("We are not in backtracking mode.\n");
00415         Packet::free(pkt);
00416         exit(-1);
00417       }
00418 
00419       if (routing_table[dtype].active == NULL) {
00420         ForwardTxFailed(pkt);
00421         return;
00422       }
00423 
00424       //      RetVal=INTF_FIND(routing_table[dtype].active, dfh->sender_id);
00425 
00426       RetVal=INTF_FIND(routing_table[dtype].active, dfh->forward_agent_id);
00427 
00428       if (RetVal.cur != NULL){
00429         INTF_REMOVE(RetVal.prv, RetVal.cur);
00430         INTF_INSERT(routing_table[dtype].inactive, RetVal.cur);
00431         routing_table[dtype].num_active --;
00432         NORMALIZE(routing_table[dtype].active);
00433         CAL_RANGE(routing_table[dtype].active);
00434       }
00435 
00436       if (routing_table[dtype].num_active < 1) {
00437         ForwardTxFailed(pkt);
00438         return;
00439       }
00440       
00441       ReTxData(pkt);
00442 
00443       Packet::free(pkt);
00444       return;
00445 
00446 
00447     default : 
00448       
00449       Packet::free(pkt);        
00450       break;
00451   }
00452 }
00453 
00454 
00455 void DiffusionProb::InterestPropagate(Packet *pkt, 
00456                                                Pkt_Hash_Entry *hashPtr)
00457 {
00458   hdr_cdiff *dfh = HDR_CDIFF(pkt);
00459   unsigned int dtype=dfh->data_type;
00460 
00461   CreateIOList(hashPtr, dtype);
00462 
00463   if ( routing_table[dtype].source != NULL ) { 
00464     data_request_all(dtype);
00465     Packet::free(pkt);
00466     return;
00467   }
00468 
00469   MACprepare(pkt, MAC_BROADCAST, NS_AF_ILINK, 0);
00470   MACsend(pkt, 0);
00471   overhead++;
00472   hashPtr->is_forwarded = true;
00473 }
00474 
00475 
00476 void DiffusionProb::ForwardData(Packet *pkt)
00477 {
00478   hdr_cdiff     *dfh  = HDR_CDIFF(pkt);
00479   unsigned int dtype =dfh->data_type;
00480   Out_List     *cur_out;
00481   Packet       *cur_pkt;
00482   hdr_cdiff     *cur_dfh;
00483   hdr_ip       *cur_iph;
00484 
00485   cur_out = WHERE_TO_GO(routing_table[dtype].active);
00486 
00487   if (cur_out !=NULL) {
00488 
00489     // Got somewhere to go.
00490 
00491       cur_pkt = pkt;
00492       cur_iph = HDR_IP(cur_pkt);
00493 
00494       cur_iph->dst_ = AGT_ADDR(cur_out);
00495 
00496       cur_dfh = HDR_CDIFF(cur_pkt);
00497       cur_dfh->forward_agent_id = here_;
00498       cur_dfh->num_next = 1;
00499       cur_dfh->next_nodes[0] = NODE_ADDR(cur_out);
00500 
00501       cur_out->num_data_send++;
00502 
00503 #ifdef DEBUG_PROB
00504       printf("DF node %x will send data (%x, %x, %d) to %x\n",
00505                THIS_NODE, (cur_dfh->sender_id).addr_,
00506                (cur_dfh->sender_id).port_, cur_dfh->pk_num,
00507                AGT_ADDR(cur_out));
00508 #endif
00509 
00510       MACprepare(cur_pkt, NODE_ADDR(cur_out), NS_AF_INET, 1);
00511       MACsend(cur_pkt, 0);
00512 
00513       return;
00514   }
00515 
00516   if (routing_table[dtype].sink != NULL) {
00517 
00518     // No where to go but have sinks.
00519 
00520     Packet::free(pkt);
00521     return;
00522   }
00523 
00524   // No where to go and no sink.    
00525   // Check if we have sources on this node.
00526   // If so, we stop the sources. Otherwise, we generate the transmission
00527   // failure packet. 
00528 
00529   Agent_List *cur;
00530 
00531   if (routing_table[dtype].source != NULL ) {
00532     for (cur=routing_table[dtype].source; cur != NULL; cur=AGENT_NEXT(cur)) {
00533 
00534       // DATA_STOP never go out of the node, so don't care if wireless.
00535 
00536       SEND_MESSAGE(dtype, AGT_ADDR(cur), DATA_STOP);
00537     }
00538     Packet::free(pkt);
00539     return;
00540   }
00541 
00542   // No source, generate the transmission failure packet.
00543 
00544   if (BACKTRACK_ == false) {
00545     Packet::free(pkt);
00546     return;
00547   }
00548 
00549   // YES, we are in backtracking mode so send TX_FAILED to the forwarder.
00550 
00551   cur_pkt = prepare_message(dtype, dfh->forward_agent_id, TX_FAILED);
00552   cur_dfh = HDR_CDIFF(cur_pkt);
00553   cur_dfh->info.sender = dfh->sender_id;
00554   cur_dfh->info.seq = dfh->pk_num;
00555 
00556   hdr_cmn *cmh = HDR_CMN(pkt);
00557   cur_dfh->info.size = cmh->size_;
00558 
00559   MACprepare(cur_pkt, (dfh->forward_agent_id).addr_, NS_AF_INET, 0);
00560   MACsend(cur_pkt, 0);
00561 
00562   Packet::free(pkt);
00563 }
00564 
00565 
00566 void DiffusionProb::ForwardTxFailed(Packet *pkt)
00567 {
00568   hdr_cdiff *dfh = HDR_CDIFF(pkt);
00569   hdr_ip   *iph = HDR_IP(pkt);
00570 
00571   dfh->forward_agent_id = here_;
00572 
00573   Pkt_Hash_Entry *hashPtr=PktTable.GetHash(dfh->info.sender, dfh->info.seq);
00574 
00575   if (hashPtr == NULL) {
00576     Packet::free(pkt);
00577     return;
00578   }
00579 
00580   iph->dst_ = hashPtr->forwarder_id;
00581   dfh->num_next = 1;
00582   dfh->next_nodes[0] = (hashPtr->forwarder_id).addr_;
00583 
00584   MACprepare(pkt, (hashPtr->forwarder_id).addr_, NS_AF_INET, 0);
00585   MACsend(pkt, 0);
00586 
00587   overhead++;
00588 }
00589 
00590 
00591 void DiffusionProb::ReTxData(Packet *pkt)
00592 {
00593   hdr_cdiff *dfh = HDR_CDIFF(pkt);  
00594   Pkt_Hash_Entry *hashPtr=PktTable.GetHash(dfh->info.sender, dfh->info.seq);
00595 
00596   // Make sure it has data on its cache.
00597 
00598   if (hashPtr == NULL) {
00599     printf("No hash for (%x, %x, %d)\n", (dfh->info.sender).addr_, 
00600            (dfh->info.sender).port_, dfh->info.seq);
00601     return;
00602   }
00603 
00604   int dtype = dfh->data_type;
00605   Out_List *to_out = WHERE_TO_GO(routing_table[dtype].active);
00606 
00607   if (to_out == NULL) return;
00608 
00609   Packet *rtxPkt = prepare_message(dtype, AGT_ADDR(to_out), DATA);
00610   hdr_cdiff *rtx_dfh = HDR_CDIFF(rtxPkt);
00611   hdr_cmn  *rtx_cmh = HDR_CMN(rtxPkt);
00612 
00613   rtx_dfh->sender_id = dfh->info.sender;
00614   rtx_dfh->pk_num = dfh->info.seq;
00615   rtx_cmh->size_ = dfh->info.size;
00616   
00617   MACprepare(rtxPkt, NODE_ADDR(to_out), NS_AF_INET, 1);
00618   MACsend(rtxPkt, 0);
00619 
00620   printf("Retransmit (%d,%d,%d)\n",(rtx_dfh->sender_id).addr_, 
00621          (rtx_dfh->sender_id).port_, rtx_dfh->pk_num);
00622 }
00623 
00624 
00625 void DiffusionProb::data_request_all(unsigned int dtype)
00626 {
00627   Agent_List *cur_agent;
00628 
00629   for (cur_agent=routing_table[dtype].source; cur_agent != NULL; 
00630        cur_agent = AGENT_NEXT(cur_agent) ) {
00631     SEND_MESSAGE(dtype, AGT_ADDR(cur_agent), DATA_REQUEST);
00632   }
00633 }
00634 
00635 
00636 void DiffusionProb::CreateIOList(Pkt_Hash_Entry *hashPtr, 
00637                                           unsigned int dtype)
00638 {
00639   From_List *fromPtr;
00640 
00641   // Better clear out all existing IO lists first.
00642 
00643   INTF_FREEALL(routing_table[dtype].active);
00644   INTF_FREEALL(routing_table[dtype].inactive);
00645   INTF_FREEALL(routing_table[dtype].iif);
00646   INTF_FREEALL(routing_table[dtype].down_iif);
00647   routing_table[dtype].num_active=0;
00648   routing_table[dtype].counter=0;
00649 
00650   for (fromPtr = hashPtr->from_agent; fromPtr != NULL;
00651        fromPtr = FROM_NEXT(fromPtr) ) {
00652     add_outlist(dtype, fromPtr);
00653   }
00654 
00655   hashPtr->has_list = true;
00656 
00657   CalGradient(dtype);
00658   CAL_RANGE(routing_table[dtype].active);
00659 }
00660 
00661 
00662 void DiffusionProb::UpdateIOList(From_List *fromPtr, 
00663                                           unsigned int dtype)
00664 {
00665   add_outlist(dtype, fromPtr);
00666   CalGradient(dtype);
00667   CAL_RANGE(routing_table[dtype].active);
00668 }
00669 
00670 
00671 void DiffusionProb::add_outlist(unsigned int dtype, From_List *foundPtr)
00672 {
00673   Out_List *outPtr = new Out_List;
00674 
00675   AGT_ADDR(outPtr) = AGT_ADDR(foundPtr);
00676   outPtr->rank = foundPtr->rank;
00677   outPtr->is_sink = foundPtr->is_sink;
00678 
00679   INTF_INSERT(routing_table[dtype].active, outPtr);
00680   routing_table[dtype].num_active ++;
00681 }
00682 
00683 
00684 void DiffusionProb::Print_IOlist()
00685 {
00686   Out_List *cur_out;
00687   In_List *cur_in;
00688   int     i;
00689 
00690   for (i=0; i<1; i++) {
00691     printf("Node %d neg bcast send %d, neg bcast rcv %d\n",
00692            THIS_NODE, num_neg_bcast_send, num_neg_bcast_rcv);
00693     for (cur_out = routing_table[i].active; cur_out != NULL; 
00694          cur_out = OUT_NEXT(cur_out) ) {
00695       printf("DF node %d has oif %d (%f,%d) send data %d recv neg %d pos %d\n", 
00696            THIS_NODE, NODE_ADDR(cur_out), GRADIENT(cur_out),
00697            routing_table[i].num_active, NUM_DATA_SEND(cur_out), 
00698            NUM_NEG_RECV(cur_out), NUM_POS_RECV(cur_out));
00699     }
00700 
00701     for (cur_in = routing_table[i].iif; cur_in != NULL;
00702          cur_in = IN_NEXT(cur_in) ) {
00703       printf("Diffusion node %d has iif for %d\n", 
00704              THIS_NODE, NODE_ADDR(cur_in));
00705     }
00706 
00707     for (cur_out = routing_table[i].inactive; cur_out != NULL; 
00708          cur_out = OUT_NEXT(cur_out) ) {
00709       printf("Diffusion node %d has down oif %d (%f, %d) send %d\n", 
00710            THIS_NODE, NODE_ADDR(cur_out), cur_out->gradient,
00711            routing_table[i].num_active, cur_out->num_data_send);
00712 
00713     }
00714 
00715     for (cur_in = routing_table[i].down_iif; cur_in != NULL;
00716          cur_in = IN_NEXT(cur_in) ) {
00717       printf("Diffusion node %d has down_iif for %d (recv %d)\n", THIS_NODE, 
00718              NODE_ADDR(cur_in), cur_in->total_received);
00719     }
00720 
00721   }
00722   
00723 }
00724 
00725 
00726 void DiffusionProb::CalGradient(unsigned int dtype)
00727 {
00728   Out_List *cur_out;
00729   
00730   for (cur_out = routing_table[dtype].active; cur_out != NULL;
00731        cur_out = OUT_NEXT(cur_out) ) {
00732     cur_out->gradient = pow(2, routing_table[dtype].num_active - 
00733                             cur_out->rank) / 
00734                        ( pow(2, routing_table[dtype].num_active) - 1);
00735   }
00736 }
00737 
00738 
00739 
00740 void DiffusionProb::IncGradient(unsigned int dtype, ns_addr_t addr)
00741 {
00742   Out_List *cur_out;
00743   PrvCurPtr RetVal;
00744 
00745   RetVal=INTF_FIND(routing_table[dtype].active, addr);
00746 
00747   if (RetVal.cur != NULL) {
00748     cur_out = (Out_List *)(RetVal.cur);
00749     GRADIENT(cur_out) = GRADIENT(cur_out) + 0.99;
00750     NORMALIZE(routing_table[dtype].active);
00751   }
00752 
00753 }
00754 
00755 
00756 void DiffusionProb::DecGradient(unsigned int dtype, ns_addr_t addr)
00757 {
00758   Out_List *cur_out;
00759   PrvCurPtr RetVal;
00760 
00761   RetVal=INTF_FIND(routing_table[dtype].active, addr);
00762 
00763   if (RetVal.cur != NULL) {
00764 
00765     for (cur_out = routing_table[dtype].active; cur_out != NULL;
00766          cur_out = OUT_NEXT(cur_out) ) 
00767       GRADIENT(cur_out) = GRADIENT(cur_out) + 1.0;
00768 
00769     cur_out = (Out_List *)(RetVal.cur);
00770     GRADIENT(cur_out) = GRADIENT(cur_out) - 1.99;
00771     if (GRADIENT(cur_out)< 0.0) {
00772        GRADIENT(cur_out) = 0.0;
00773     }
00774     NORMALIZE(routing_table[dtype].active);
00775   }
00776 }
00777 
00778 
00779 
00780 void DiffusionProb::GenPosReinf(unsigned int dtype)
00781 {
00782   In_List *cur_in, *max_in;
00783   Packet *pkt;
00784 
00785   max_in = FIND_MAX_IN(routing_table[dtype].iif);
00786 
00787   if (max_in != NULL) {
00788    if ( (max_in->total_received - max_in->prev_received) < 
00789          routing_table[dtype].counter) {
00790 
00791       pkt=prepare_message(dtype, AGT_ADDR(max_in), POS_REINFORCE);
00792 
00793       MACprepare(pkt, NODE_ADDR(max_in), NS_AF_INET, 0);
00794       MACsend(pkt, 0);
00795 
00796       overhead++;
00797 
00798     }
00799   }
00800 
00801   routing_table[dtype].counter = 0;
00802   for (cur_in = routing_table[dtype].iif; cur_in != NULL;
00803        cur_in = IN_NEXT(cur_in) ) {
00804     cur_in->prev_received = cur_in->total_received;
00805   }
00806 
00807 }
00808 
00809 
00810 void DiffusionProb::FwdPosReinf(unsigned int dtype, Packet *pkt)
00811 {
00812   In_List  *cur_in, *max_in=NULL;
00813   hdr_ip   *iph = HDR_IP(pkt);
00814   hdr_cdiff *dfh = HDR_CDIFF(pkt);
00815 
00816   max_in = FIND_MAX_IN(routing_table[dtype].iif);
00817   if (max_in != NULL) {
00818 
00819     iph->dst_ = AGT_ADDR(max_in);
00820 
00821     dfh->num_next = 1;
00822     dfh->next_nodes[0] = NODE_ADDR(max_in);
00823     dfh->forward_agent_id = here_;
00824 
00825     MACprepare(pkt, NODE_ADDR(max_in), NS_AF_INET, 0);
00826     MACsend(pkt, 0);
00827 
00828     overhead++;
00829   }
00830   else {
00831     Packet::free(pkt);
00832   }
00833 
00834   routing_table[dtype].counter = 0;
00835   for (cur_in = routing_table[dtype].iif; cur_in != NULL;
00836        cur_in = IN_NEXT(cur_in) ) {
00837     cur_in->prev_received = cur_in->total_received;
00838   }
00839 }
00840 
00841 
00842 void DiffusionProb::Start()
00843 {
00844   DiffusionAgent::Start();
00845 
00846   energy_timer = new EnergyTimer(this, node);
00847   energy_timer->resched(ENERGY_CHECK + ENERGY_CHECK * Random::uniform(1.0));
00848 }
00849 
00850 
00851 void DiffusionProb::InterfaceDown(int dtype, ns_addr_t DownDiff)
00852 {
00853   PrvCurPtr RetVal;
00854 
00855   RetVal = INTF_FIND(routing_table[dtype].iif, DownDiff);
00856 
00857   if (RetVal.cur != NULL) {
00858     INTF_REMOVE(RetVal.prv, RetVal.cur);
00859     INTF_INSERT(routing_table[dtype].down_iif, RetVal.cur);
00860     return;
00861   }
00862 
00863   RetVal = INTF_FIND(routing_table[dtype].active, DownDiff);
00864   if (RetVal.cur == NULL)
00865     return;
00866 
00867   INTF_REMOVE(RetVal.prv, RetVal.cur);
00868   INTF_INSERT(routing_table[dtype].inactive, RetVal.cur);
00869   routing_table[dtype].num_active --;
00870   NORMALIZE(routing_table[dtype].active);
00871   CAL_RANGE(routing_table[dtype].active);
00872 
00873   if (routing_table[dtype].num_active < 1) {
00874 
00875     // ** If we have a source, stop the source.
00876     // If not, send inhibit signal upstream. **
00877 
00878     Agent_List *cur;
00879 
00880     if (routing_table[dtype].source != NULL ) {
00881       for (cur=routing_table[dtype].source; cur != NULL; cur=AGENT_NEXT(cur)) {
00882              SEND_MESSAGE(dtype, AGT_ADDR(cur), DATA_STOP);
00883       }
00884     }
00885     else {
00886       SendInhibit(dtype);
00887     }
00888   }
00889 }
00890 
00891 
00892 void DiffusionProb::SendInhibit(int dtype)
00893 {
00894   // Wireless. Just use one MAC broadcast.
00895 
00896     ns_addr_t bcast_addr;
00897     bcast_addr.addr_ = MAC_BROADCAST;
00898     bcast_addr.port_ = ROUTING_PORT;
00899 
00900     Packet *pkt = prepare_message(dtype, bcast_addr, INHIBIT);
00901     MACprepare(pkt, MAC_BROADCAST, NS_AF_ILINK, 0);
00902     MACsend(pkt, 0);
00903     overhead++;
00904     return;
00905 }
00906 
00907 
00908 // For negative reinforcement, we don't care the data type.
00909 // Any neighbor upstream of any data type should be informed.
00910 
00911 void DiffusionProb::SendNegReinf()
00912 {
00913     ns_addr_t bcast_addr;
00914     bcast_addr.addr_ = MAC_BROADCAST;
00915     bcast_addr.port_ = ROUTING_PORT;
00916 
00917     Packet *pkt = prepare_message(0, bcast_addr, NEG_REINFORCE);
00918     MACprepare(pkt, MAC_BROADCAST, NS_AF_ILINK, 0);
00919     MACsend(pkt, 0);
00920     overhead++;
00921     return;
00922 }
00923 

Generated on Tue Apr 20 12:14:13 2004 for NS2.26SourcesOriginal by doxygen 1.3.3