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