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 #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
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
00119
00120 if (hashPtr != NULL) {
00121 consider_old(packet);
00122 return;
00123 }
00124
00125
00126
00127 PktTable.put_in_hash(dfh);
00128
00129
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
00171
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
00213
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
00222
00223
00224 RetVal = INTF_FIND(routing_table[dtype].sink, dfh->sender_id);
00225
00226 if (RetVal.cur == NULL) {
00227
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
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
00248
00249
00250 if ( from_nodeID == forward_nodeID )
00251 fromPtr->is_sink = true;
00252
00253 }
00254
00255
00256
00257
00258 if (routing_table[dtype].source == NULL) {
00259
00260
00261
00262 hashPtr->timer = new InterestTimer(this, hashPtr, pkt);
00263 (hashPtr->timer)->sched(INTEREST_DELAY*Random::uniform(1.0));
00264 }
00265 else {
00266
00267
00268
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
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
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
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
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
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
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
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
00519
00520 Packet::free(pkt);
00521 return;
00522 }
00523
00524
00525
00526
00527
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
00535
00536 SEND_MESSAGE(dtype, AGT_ADDR(cur), DATA_STOP);
00537 }
00538 Packet::free(pkt);
00539 return;
00540 }
00541
00542
00543
00544 if (BACKTRACK_ == false) {
00545 Packet::free(pkt);
00546 return;
00547 }
00548
00549
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
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
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
00876
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
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
00909
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