00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "geo-routing.hh"
00025
00026 #ifdef NS_DIFFUSION
00027 static class GeoRoutingFilterClass : public TclClass {
00028 public:
00029 GeoRoutingFilterClass() : TclClass("Application/DiffApp/GeoRoutingFilter") {}
00030 TclObject * create(int argc, const char*const* argv) {
00031 return (new GeoRoutingFilter());
00032 }
00033 } class_geo_routing_filter;
00034
00035 int GeoRoutingFilter::command(int argc, const char*const* argv) {
00036 if (argc == 2) {
00037 if (strcmp(argv[1], "start") == 0) {
00038 run();
00039 return TCL_OK;
00040 }
00041 }
00042 return DiffApp::command(argc, argv);
00043 }
00044 #endif // NS_DIFFUSION
00045
00046 void GeoFilterReceive::recv(Message *msg, handle h)
00047 {
00048 app_->recv(msg, h);
00049 }
00050
00051 int GeoMessageSendTimer::expire()
00052 {
00053
00054 agent_->messageTimeout(msg_);
00055
00056
00057 return -1;
00058 }
00059
00060 int GeoNeighborsTimer::expire()
00061 {
00062
00063 agent_->neighborTimeout();
00064
00065
00066 return 0;
00067 }
00068
00069 int GeoBeaconRequestTimer::expire()
00070 {
00071
00072 agent_->beaconTimeout();
00073
00074
00075 return 0;
00076 }
00077
00078 void GeoRoutingFilter::beaconTimeout()
00079 {
00080 NRAttrVec attrs;
00081 Message *beacon_msg;
00082 struct timeval tv;
00083
00084 GetTime(&tv);
00085
00086 DiffPrint(DEBUG_IMPORTANT, "Gear: %d.%06d - Beacon Timeout !\n",
00087 tv.tv_sec, tv.tv_usec);
00088
00089
00090
00091
00092 if ((last_neighbor_request_tv_.tv_sec == 0) ||
00093 ((tv.tv_sec - last_neighbor_request_tv_.tv_sec) >=
00094 GEO_NEIGHBOR_REQUEST_PERIOD)){
00095
00096
00097 GetTime(&last_neighbor_request_tv_);
00098
00099
00100 attrs.push_back(GeoBeaconTypeAttr.make(NRAttribute::IS, GEO_REQUEST));
00101 attrs.push_back(GeoLatitudeAttr.make(NRAttribute::IS, geo_latitude_));
00102 attrs.push_back(GeoLongitudeAttr.make(NRAttribute::IS, geo_longitude_));
00103 attrs.push_back(GeoRemainingEnergyAttr.make(NRAttribute::IS,
00104 remainingEnergy()));
00105
00106 beacon_msg = new Message(DIFFUSION_VERSION, DATA, 0, 0,
00107 attrs.size(), pkt_count_, rdm_id_,
00108 BROADCAST_ADDR, LOCALHOST_ADDR);
00109
00110 pkt_count_++;
00111
00112 beacon_msg->msg_attr_vec_ = CopyAttrs(&attrs);
00113
00114 DiffPrint(DEBUG_IMPORTANT, "Gear: %d.%06d - Sending Beacon Request...\n",
00115 tv.tv_sec, tv.tv_usec);
00116 ((DiffusionRouting *)dr_)->sendMessage(beacon_msg, post_filter_handle_);
00117
00118 ClearAttrs(&attrs);
00119 delete beacon_msg;
00120 }
00121 }
00122
00123 void GeoRoutingFilter::neighborTimeout()
00124 {
00125 NeighborList::iterator neighbor_itr;
00126 NeighborEntry *neighbor_entry;
00127 struct timeval tv;
00128
00129 GetTime(&tv);
00130
00131 DiffPrint(DEBUG_IMPORTANT, "Gear: %d.%06d - Neighbors Timeout !\n",
00132 tv.tv_sec, tv.tv_usec);
00133
00134 neighbor_itr = neighbors_list_.begin();
00135
00136 while (neighbor_itr != neighbors_list_.end()){
00137 neighbor_entry = *neighbor_itr;
00138 DiffPrint(DEBUG_IMPORTANT, "Gear: %d.%06d - Check: %d: %d --> %d\n",
00139 tv.tv_sec, tv.tv_usec, neighbor_entry->id_,
00140 neighbor_entry->tv_.tv_sec, tv.tv_sec);
00141
00142 if ((tv.tv_sec - neighbor_entry->tv_.tv_sec) >= GEO_NEIGHBOR_EXPIRED){
00143
00144 DiffPrint(DEBUG_IMPORTANT, "Gear: %d.%06d - Deleting neighbor %d\n",
00145 tv.tv_sec, tv.tv_usec, neighbor_entry->id_);
00146 neighbor_itr = neighbors_list_.erase(neighbor_itr);
00147 delete neighbor_entry;
00148 }
00149 else{
00150 DiffPrint(DEBUG_IMPORTANT, "Gear: %d.%06d - Neighbor %d, (%d,%d)\n",
00151 tv.tv_sec, tv.tv_usec, neighbor_entry->id_,
00152 neighbor_entry->tv_.tv_sec, neighbor_entry->tv_.tv_usec);
00153 neighbor_itr++;
00154 }
00155 }
00156 }
00157
00158 void GeoRoutingFilter::messageTimeout(Message *msg)
00159 {
00160 struct timeval tv;
00161
00162
00163 GetTime(&tv);
00164
00165
00166 DiffPrint(DEBUG_IMPORTANT, "Gear: %d.%06d - Message Timeout !\n",
00167 tv.tv_sec, tv.tv_usec);
00168
00169 ((DiffusionRouting *)dr_)->sendMessage(msg, post_filter_handle_,
00170 GEOROUTING_POST_FILTER_PRIORITY);
00171 }
00172
00173 void GeoRoutingFilter::recv(Message *msg, handle h)
00174 {
00175 struct timeval tv;
00176
00177 GetTime(&tv);
00178
00179 if (h == pre_filter_handle_){
00180 preProcessFilter(msg);
00181 return;
00182 }
00183
00184 if (h == post_filter_handle_){
00185 postProcessFilter(msg);
00186 return;
00187 }
00188
00189 DiffPrint(DEBUG_ALWAYS,
00190 "Gear: %d.%06d - Received message for an unknown handle %d !\n",
00191 tv.tv_sec, tv.tv_usec, h);
00192 }
00193
00194 void GeoRoutingFilter::preProcessFilter(Message *msg)
00195 {
00196 NRSimpleAttribute<void *> *heuristic_value_attribute = NULL;
00197 NRSimpleAttribute<int> *beacon_type_attribute = NULL;
00198 NRSimpleAttribute<double> *beacon_info_attribute = NULL;
00199 double neighbor_energy = 0.0;
00200 double neighbor_longitude = 0.0;
00201 double neighbor_latitude = 0.0;
00202 double new_heuristic_value = 0.0;
00203 int32_t neighbor_id;
00204 int beacon_type;
00205 struct timeval tv;
00206 HeuristicValue *heuristic_value = NULL;
00207 GeoLocation dst_location;
00208 TimerCallback *beacon_timer = NULL;
00209 NRAttrVec attrs;
00210 Message *beacon_msg = NULL;
00211 PktHeader *pkt_header = NULL;
00212
00213
00214 GetTime(&tv);
00215
00216 switch (msg->msg_type_){
00217
00218 case INTEREST:
00219 case EXPLORATORY_DATA:
00220 case PUSH_EXPLORATORY_DATA:
00221
00222 if (msg->new_message_){
00223
00224
00225
00226
00227
00228 pkt_header = preProcessMessage(msg);
00229
00230
00231 if (pkt_header){
00232 sendNeighborRequest();
00233 message_list_.push_back(pkt_header);
00234 }
00235 }
00236
00237 ((DiffusionRouting *)dr_)->sendMessage(msg, pre_filter_handle_);
00238
00239 break;
00240
00241 case DATA:
00242
00243
00244 beacon_type_attribute = GeoBeaconTypeAttr.find(msg->msg_attr_vec_);
00245
00246
00247
00248 if (!beacon_type_attribute){
00249 ((DiffusionRouting *)dr_)->sendMessage(msg, pre_filter_handle_);
00250
00251 break;
00252 }
00253
00254
00255 neighbor_id = msg->last_hop_;
00256
00257 if ((neighbor_id == BROADCAST_ADDR) ||
00258 (neighbor_id == LOCALHOST_ADDR)){
00259 DiffPrint(DEBUG_ALWAYS, "Gear: %d.%06d - Neighbor ID Invalid !\n",
00260 tv.tv_sec, tv.tv_usec);
00261 return;
00262 }
00263
00264
00265 beacon_type = beacon_type_attribute->getVal();
00266
00267 beacon_info_attribute = GeoLongitudeAttr.find(msg->msg_attr_vec_);
00268 if (beacon_info_attribute){
00269 neighbor_longitude = beacon_info_attribute->getVal();
00270 }
00271
00272 beacon_info_attribute = GeoLatitudeAttr.find(msg->msg_attr_vec_);
00273 if (beacon_info_attribute){
00274 neighbor_latitude = beacon_info_attribute->getVal();
00275 }
00276
00277 beacon_info_attribute = GeoRemainingEnergyAttr.find(msg->msg_attr_vec_);
00278 if (beacon_info_attribute){
00279 neighbor_energy = beacon_info_attribute->getVal();
00280 }
00281
00282
00283 updateNeighbor(neighbor_id, neighbor_longitude,
00284 neighbor_latitude, neighbor_energy);
00285
00286
00287 GetTime(&tv);
00288
00289 DiffPrint(DEBUG_IMPORTANT, "Gear: %d.%06d - Beacon Information id: %d - location: %f,%f - energy: %f\n",
00290 tv.tv_sec, tv.tv_usec,
00291 neighbor_id, neighbor_longitude,
00292 neighbor_latitude, neighbor_energy);
00293
00294 if (beacon_type == GEO_REQUEST){
00295 DiffPrint(DEBUG_IMPORTANT,
00296 "Gear: %d.%06d - Received a beacon request...\n",
00297 tv.tv_sec, tv.tv_usec);
00298
00299
00300
00301
00302 if (last_beacon_reply_tv_.tv_sec > 0){
00303
00304
00305 if ((tv.tv_sec - last_beacon_reply_tv_.tv_sec)
00306 < GEO_BEACON_REPLY_PERIOD){
00307 DiffPrint(DEBUG_IMPORTANT,
00308 "Gear: %d.%06d - Ignoring beacon request until %d.%06d!\n",
00309 tv.tv_sec, tv.tv_usec,
00310 (tv.tv_sec + GEO_BEACON_REPLY_PERIOD), tv.tv_usec);
00311 break;
00312 }
00313 }
00314
00315
00316 attrs.push_back(GeoLongitudeAttr.make(NRAttribute::IS, geo_longitude_));
00317 attrs.push_back(GeoLatitudeAttr.make(NRAttribute::IS, geo_latitude_));
00318 attrs.push_back(GeoRemainingEnergyAttr.make(NRAttribute::IS,
00319 remainingEnergy()));
00320 attrs.push_back(GeoBeaconTypeAttr.make(NRAttribute::IS, GEO_REPLY));
00321
00322
00323 heuristic_value_attribute = GeoHeuristicValueAttr.find(msg->msg_attr_vec_);
00324
00325 if (heuristic_value_attribute){
00326
00327
00328 heuristic_value = (HeuristicValue *) heuristic_value_attribute->getVal();
00329 dst_location.longitude_ = heuristic_value->dst_longitude_;
00330 dst_location.latitude_ = heuristic_value->dst_latitude_;
00331
00332
00333 DiffPrint(DEBUG_IMPORTANT,
00334 "Gear: %d.%06d - Requesting h-value in (%lf,%lf)\n",
00335 tv.tv_sec, tv.tv_usec,
00336 dst_location.longitude_, dst_location.latitude_);
00337
00338 new_heuristic_value = retrieveHeuristicValue(dst_location);
00339
00340 if (new_heuristic_value != INITIAL_HEURISTIC_VALUE){
00341
00342
00343
00344 heuristic_value = new HeuristicValue(dst_location.longitude_,
00345 dst_location.latitude_,
00346 new_heuristic_value);
00347
00348 DiffPrint(DEBUG_IMPORTANT,
00349 "Gear: %d.%06d - Current h-value for (%lf,%lf):%lf\n",
00350 tv.tv_sec, tv.tv_usec,
00351 dst_location.longitude_, dst_location.latitude_,
00352 new_heuristic_value);
00353
00354 attrs.push_back(GeoHeuristicValueAttr.make(NRAttribute::IS,
00355 (void *) heuristic_value,
00356 sizeof(HeuristicValue)));
00357 delete heuristic_value;
00358 }
00359 }
00360
00361 beacon_msg = new Message(DIFFUSION_VERSION, DATA, 0, 0, attrs.size(),
00362 pkt_count_, rdm_id_, BROADCAST_ADDR,
00363 LOCALHOST_ADDR);
00364
00365
00366 pkt_count_++;
00367 beacon_msg->msg_attr_vec_ = CopyAttrs(&attrs);
00368
00369 beacon_timer = new GeoMessageSendTimer(this, CopyMessage(beacon_msg));
00370
00371 ((DiffusionRouting *)dr_)->addTimer(GEO_BEACON_REPLY_DELAY +
00372 (int) ((GEO_BEACON_REPLY_JITTER *
00373 (GetRand() * 1.0 / RAND_MAX) -
00374 (GEO_BEACON_REPLY_JITTER / 2))),
00375 beacon_timer);
00376
00377 ClearAttrs(&attrs);
00378 delete beacon_msg;
00379
00380 DiffPrint(DEBUG_IMPORTANT,
00381 "Gear: %d.%06d - Sending a beacon reply in response to request !\n",
00382 tv.tv_sec, tv.tv_usec);
00383 DiffPrint(DEBUG_IMPORTANT,
00384 "Gear: %d.%06d - Local info: location: %f,%f - energy: %f\n",
00385 tv.tv_sec, tv.tv_usec,
00386 geo_longitude_, geo_latitude_, remainingEnergy());
00387
00388
00389 GetTime(&last_beacon_reply_tv_);
00390 }
00391 else{
00392 if (beacon_type == GEO_REPLY){
00393 DiffPrint(DEBUG_IMPORTANT, "Gear: %d.%06d - Received beacon reply\n",
00394 tv.tv_sec, tv.tv_usec);
00395 }
00396 else{
00397 if (beacon_type == GEO_UPDATE){
00398 DiffPrint(DEBUG_IMPORTANT,
00399 "Gear: %d.%06d - Received beacon update\n",
00400 tv.tv_sec, tv.tv_usec);
00401 }
00402 else{
00403 DiffPrint(DEBUG_ALWAYS,
00404 "Gear: %d.%06d - Received unknown message !\n",
00405 tv.tv_sec, tv.tv_usec);
00406 return;
00407 }
00408 }
00409
00410
00411 heuristic_value_attribute = GeoHeuristicValueAttr.find(msg->msg_attr_vec_);
00412
00413 if (heuristic_value_attribute){
00414 heuristic_value = (HeuristicValue *) heuristic_value_attribute->getVal();
00415
00416
00417 dst_location.longitude_ = heuristic_value->dst_longitude_;
00418 dst_location.latitude_ = heuristic_value->dst_latitude_;
00419
00420 DiffPrint(DEBUG_IMPORTANT,
00421 "Gear: %d.%06d - Received h-val update %d: (%lf,%lf):%f\n",
00422 tv.tv_sec, tv.tv_usec,
00423 neighbor_id, dst_location.longitude_,
00424 dst_location.latitude_,
00425 heuristic_value->heuristic_value_);
00426
00427 learned_cost_table_.updateEntry(neighbor_id, dst_location,
00428 heuristic_value->heuristic_value_);
00429 }
00430 }
00431
00432 break;
00433
00434 default:
00435
00436
00437
00438 ((DiffusionRouting *)dr_)->sendMessage(msg, pre_filter_handle_);
00439
00440 break;
00441
00442 }
00443 }
00444
00445 void GeoRoutingFilter::postProcessFilter(Message *msg)
00446 {
00447 PktHeader *pkt_header = NULL;
00448 GeoHeader *geo_header = NULL;
00449 int action;
00450 int32_t next_hop;
00451 struct timeval tv;
00452
00453
00454 GetTime(&tv);
00455
00456 switch (msg->msg_type_){
00457
00458 case INTEREST:
00459 case EXPLORATORY_DATA:
00460 case PUSH_EXPLORATORY_DATA:
00461
00462
00463 if (msg->next_hop_ != LOCALHOST_ADDR){
00464
00465
00466 pkt_header = retrievePacketHeader(msg);
00467
00468
00469
00470 if (pkt_header){
00471 geo_header = restoreGeoHeader(pkt_header, msg);
00472
00473
00474 geo_header->path_len_++;
00475
00476
00477
00478
00479
00480
00481 action = floodInsideRegion(geo_header);
00482
00483
00484 msg->msg_attr_vec_->push_back(GeoHeaderAttr.make(NRAttribute::IS,
00485 (void *) geo_header,
00486 sizeof(GeoHeader)));
00487
00488
00489 GetTime(&tv);
00490
00491 switch (action){
00492
00493 case BROADCAST:
00494
00495
00496
00497
00498 DiffPrint(DEBUG_IMPORTANT,
00499 "Gear: %d.%06d - Broadcasting message: last_hop: %d!\n",
00500 tv.tv_sec, tv.tv_usec, msg->last_hop_);
00501
00502 msg->next_hop_ = BROADCAST_ADDR;
00503 ((DiffusionRouting *)dr_)->sendMessage(msg, post_filter_handle_);
00504
00505 break;
00506
00507 case BROADCAST_SUPPRESS:
00508
00509
00510
00511
00512
00513 DiffPrint(DEBUG_IMPORTANT,
00514 "Gear: %d.%06d - Suppressing broadcast !\n",
00515 tv.tv_sec, tv.tv_usec);
00516
00517 break;
00518
00519 case OUTSIDE_REGION:
00520
00521
00522
00523
00524
00525 DiffPrint(DEBUG_IMPORTANT,
00526 "Gear: %d.%06d - Packet outside target region !\n",
00527 tv.tv_sec, tv.tv_usec);
00528
00529 next_hop = findNextHop(geo_header, true);
00530
00531
00532 if (next_hop == BROADCAST_ADDR){
00533
00534
00535 if (geo_header->path_len_ < MAX_PATH_LEN)
00536 next_hop = findNextHop(geo_header, false);
00537 }
00538
00539
00540 GetTime(&tv);
00541
00542
00543 if (next_hop == BROADCAST_ADDR){
00544 DiffPrint(DEBUG_IMPORTANT,
00545 "Gear: %d.%06d - Cannot find next hop !\n",
00546 tv.tv_sec, tv.tv_usec);
00547 }
00548 else{
00549
00550 msg->next_hop_ = next_hop;
00551 DiffPrint(DEBUG_IMPORTANT,
00552 "Gear: %d.%06d - Forwarding message !\n",
00553 tv.tv_sec, tv.tv_usec);
00554 DiffPrint(DEBUG_IMPORTANT,
00555 "Gear: %d.%06d - Next Hop: %d\n",
00556 tv.tv_sec, tv.tv_usec, next_hop);
00557 DiffPrint(DEBUG_IMPORTANT,
00558 "Gear: %d.%06d - Last Hop: %d\n",
00559 tv.tv_sec, tv.tv_usec, msg->last_hop_);
00560 ((DiffusionRouting *)dr_)->sendMessage(msg, post_filter_handle_);
00561 }
00562
00563 break;
00564
00565 default:
00566
00567 break;
00568 }
00569
00570
00571 delete pkt_header;
00572 delete geo_header;
00573 }
00574 else{
00575
00576 DiffPrint(DEBUG_IMPORTANT,
00577 "Gear: %d.%06d - Forwarding message without packet header info !\n",
00578 tv.tv_sec, tv.tv_usec);
00579 ((DiffusionRouting *)dr_)->sendMessage(msg, post_filter_handle_);
00580 }
00581 }
00582 else{
00583
00584 ((DiffusionRouting *)dr_)->sendMessage(msg, post_filter_handle_);
00585 }
00586
00587 break;
00588
00589 default:
00590
00591
00592 ((DiffusionRouting *)dr_)->sendMessage(msg, post_filter_handle_);
00593
00594 break;
00595 }
00596 }
00597
00598 handle GeoRoutingFilter::setupPreFilter()
00599 {
00600 NRAttrVec attrs;
00601 handle h;
00602
00603
00604 attrs.push_back(NRClassAttr.make(NRAttribute::IS,
00605 NRAttribute::INTEREST_CLASS));
00606
00607 h = ((DiffusionRouting *)dr_)->addFilter(&attrs,
00608 GEOROUTING_PRE_FILTER_PRIORITY,
00609 filter_callback_);
00610 ClearAttrs(&attrs);
00611 return h;
00612 }
00613
00614 handle GeoRoutingFilter::setupPostFilter()
00615 {
00616 NRAttrVec attrs;
00617 handle h;
00618
00619
00620
00621 attrs.push_back(NRClassAttr.make(NRAttribute::IS,
00622 NRAttribute::INTEREST_CLASS));
00623
00624 h = ((DiffusionRouting *)dr_)->addFilter(&attrs,
00625 GEOROUTING_POST_FILTER_PRIORITY,
00626 filter_callback_);
00627
00628 ClearAttrs(&attrs);
00629 return h;
00630 }
00631
00632 void GeoRoutingFilter::run()
00633 {
00634 #ifdef NS_DIFFUSION
00635 TimerCallback *neighbor_timer, *beacon_timer;
00636 struct timeval tv;
00637
00638
00639 getNodeLocation(&geo_longitude_, &geo_latitude_);
00640
00641
00642 GetTime(&tv);
00643
00644 DiffPrint(DEBUG_ALWAYS, "Gear: %d.%06d - Location %f,%f\n",
00645 tv.tv_sec, tv.tv_usec, geo_longitude_, geo_latitude_);
00646
00647
00648 pre_filter_handle_ = setupPreFilter();
00649 post_filter_handle_ = setupPostFilter();
00650
00651
00652 neighbor_timer = new GeoNeighborsTimer(this);
00653 ((DiffusionRouting *)dr_)->addTimer(GEO_NEIGHBOR_DELAY, neighbor_timer);
00654
00655
00656 beacon_timer = new GeoBeaconRequestTimer(this);
00657 ((DiffusionRouting *)dr_)->addTimer(GEO_BEACON_REQUEST_CHECK_PERIOD,
00658 beacon_timer);
00659
00660 DiffPrint(DEBUG_ALWAYS, "Gear: %d.%06d - Received handle %d for pre Filter !\n",
00661 tv.tv_sec, tv.tv_usec, pre_filter_handle_);
00662 DiffPrint(DEBUG_ALWAYS, "Gear: %d.%06d - Received handle %d for post Filter !\n",
00663 tv.tv_sec, tv.tv_usec, post_filter_handle_);
00664 DiffPrint(DEBUG_ALWAYS, "Gear: %d.%06d - Initialized !\n",
00665 tv.tv_sec, tv.tv_usec);
00666 #endif // NS_DIFFUSION
00667
00668
00669 beaconTimeout();
00670
00671 #ifndef NS_DIFFUSION
00672
00673 while (1){
00674 sleep(1000);
00675 }
00676 #endif // !NS_DIFFUSION
00677 }
00678
00679 #ifdef NS_DIFFUSION
00680 GeoRoutingFilter::GeoRoutingFilter()
00681 {
00682 #else
00683 GeoRoutingFilter::GeoRoutingFilter(int argc, char **argv)
00684 {
00685 TimerCallback *neighbor_timer, *beacon_timer;
00686
00687
00688 parseCommandLine(argc, argv);
00689 #endif // NS_DIFFUSION
00690
00691 struct timeval tv;
00692
00693
00694 initial_energy_ = GEO_INITIAL_ENERGY;
00695 unit_energy_for_send_ = GEO_UNIT_ENERGY_FOR_SEND;
00696 unit_energy_for_recv_ = GEO_UNIT_ENERGY_FOR_RECV;
00697 num_pkt_sent_ = 0;
00698 num_pkt_recv_ = 0;
00699
00700
00701 last_beacon_reply_tv_.tv_sec = 0;
00702 last_beacon_reply_tv_.tv_usec = 0;
00703 last_neighbor_request_tv_.tv_sec = 0;
00704 last_neighbor_request_tv_.tv_usec = 0;
00705
00706 getNodeLocation(&geo_longitude_, &geo_latitude_);
00707
00708
00709 GetTime(&tv);
00710
00711 DiffPrint(DEBUG_ALWAYS, "Gear: %d.%06d - Location %f,%f\n",
00712 tv.tv_sec, tv.tv_usec, geo_longitude_, geo_latitude_);
00713
00714 SetSeed(&tv);
00715 pkt_count_ = GetRand();
00716 rdm_id_ = GetRand();
00717
00718 #ifndef NS_DIFFUSION
00719
00720 dr_ = NR::createNR(diffusion_port_);
00721 #endif // !NS_DIFFUSION
00722
00723 filter_callback_ = new GeoFilterReceive(this);
00724
00725 #ifndef NS_DIFFUSION
00726
00727 pre_filter_handle_ = setupPreFilter();
00728 post_filter_handle_ = setupPostFilter();
00729
00730
00731 neighbor_timer = new GeoNeighborsTimer(this);
00732 ((DiffusionRouting *)dr_)->addTimer(GEO_NEIGHBOR_DELAY, neighbor_timer);
00733
00734
00735 beacon_timer = new GeoBeaconRequestTimer(this);
00736 ((DiffusionRouting *)dr_)->addTimer(GEO_BEACON_REQUEST_CHECK_PERIOD,
00737 beacon_timer);
00738
00739 DiffPrint(DEBUG_ALWAYS,
00740 "Gear: %d.%06d - Received handle %d for pre Filter !\n",
00741 tv.tv_sec, tv.tv_usec, pre_filter_handle_);
00742 DiffPrint(DEBUG_ALWAYS,
00743 "Gear: %d.%06d - Received handle %d for post Filter !\n",
00744 tv.tv_sec, tv.tv_usec, post_filter_handle_);
00745 DiffPrint(DEBUG_ALWAYS, "Gear: %d.%06d - Initialized !\n",
00746 tv.tv_sec, tv.tv_usec);
00747 #endif // !NS_DIFFUSION
00748 }
00749
00750 void GeoRoutingFilter::getNodeLocation(double *longitude, double *latitude)
00751 {
00752 #ifdef NS_DIFFUSION
00753 double z;
00754
00755 MobileNode *node = ((DiffusionRouting *)dr_)->getNode();
00756 node->getLoc(longitude, latitude, &z);
00757 #else
00758 char *longitude_env, *latitude_env;
00759 struct timeval tv;
00760
00761
00762 GetTime(&tv);
00763
00764 longitude_env = getenv("gear_longitude");
00765 latitude_env = getenv("gear_latitude");
00766
00767 if (longitude_env && latitude_env){
00768 *longitude = atof(longitude_env);
00769 *latitude = atof(latitude_env);
00770 }
00771 else{
00772 DiffPrint(DEBUG_ALWAYS,
00773 "Gear: %d.%06d - Cannot get location (gear_longitude, gear_latitude) !\n",
00774 tv.tv_sec, tv.tv_usec);
00775 exit(-1);
00776 }
00777 #endif // NS_DIFFUSION
00778 }
00779
00780 bool GeoRoutingFilter::checkNeighbors()
00781 {
00782 NeighborList::iterator neighbor_itr;
00783 NeighborEntry *neighbor_entry;
00784 struct timeval tv;
00785
00786 GetTime(&tv);
00787
00788 for (neighbor_itr = neighbors_list_.begin();
00789 neighbor_itr != neighbors_list_.end(); ++neighbor_itr){
00790 neighbor_entry = *neighbor_itr;
00791
00792 if ((tv.tv_sec - neighbor_entry->tv_.tv_sec) >= GEO_NEIGHBOR_UPDATE)
00793 return true;
00794 }
00795
00796 return false;
00797 }
00798
00799 void GeoRoutingFilter::sendNeighborRequest()
00800 {
00801 NRAttrVec attrs;
00802 Message *beacon_msg;
00803 TimerCallback *beacon_timer;
00804 struct timeval tv;
00805
00806
00807 GetTime(&tv);
00808
00809
00810
00811 if (!checkNeighbors())
00812 return;
00813
00814
00815 attrs.push_back(GeoBeaconTypeAttr.make(NRAttribute::IS, GEO_REQUEST));
00816 attrs.push_back(GeoLatitudeAttr.make(NRAttribute::IS, geo_latitude_));
00817 attrs.push_back(GeoLongitudeAttr.make(NRAttribute::IS, geo_longitude_));
00818 attrs.push_back(GeoRemainingEnergyAttr.make(NRAttribute::IS,
00819 remainingEnergy()));
00820
00821
00822 beacon_msg = new Message(DIFFUSION_VERSION, DATA, 0, 0,
00823 attrs.size(), pkt_count_, rdm_id_,
00824 BROADCAST_ADDR, LOCALHOST_ADDR);
00825
00826 pkt_count_++;
00827
00828 beacon_msg->msg_attr_vec_ = CopyAttrs(&attrs);
00829
00830
00831
00832 DiffPrint(DEBUG_IMPORTANT,
00833 "Gear: %d.%06d - Broadcasting neighbor info request...\n",
00834 tv.tv_sec, tv.tv_usec);
00835
00836 beacon_timer = new GeoMessageSendTimer(this, CopyMessage(beacon_msg));
00837
00838 ((DiffusionRouting *)dr_)->addTimer(GEO_BEACON_DELAY +
00839 (int) ((GEO_BEACON_JITTER *
00840 (GetRand() * 1.0 / RAND_MAX) -
00841 (GEO_BEACON_JITTER / 2))),
00842 beacon_timer);
00843
00844 GetTime(&last_neighbor_request_tv_);
00845
00846 ClearAttrs(&attrs);
00847 delete beacon_msg;
00848 }
00849
00850 void GeoRoutingFilter::updateNeighbor(int32_t neighbor_id,
00851 double neighbor_longitude,
00852 double neighbor_latitude,
00853 double neighbor_energy)
00854 {
00855 NeighborEntry *neighbor_entry;
00856 struct timeval tv;
00857
00858
00859 GetTime(&tv);
00860
00861
00862 neighbor_entry = findNeighbor(neighbor_id);
00863
00864 if (!neighbor_entry){
00865
00866 DiffPrint(DEBUG_IMPORTANT,
00867 "Gear: %d.%06d - Inserting new neighbor %d !\n",
00868 tv.tv_sec, tv.tv_usec, neighbor_id);
00869
00870 neighbor_entry = new NeighborEntry(neighbor_id, neighbor_longitude,
00871 neighbor_latitude, neighbor_energy);
00872
00873
00874 neighbors_list_.push_back(neighbor_entry);
00875 }
00876 else{
00877
00878 DiffPrint(DEBUG_IMPORTANT,
00879 "Gear: %d.%06d - Updating neighbor %d !\n",
00880 tv.tv_sec, tv.tv_usec, neighbor_id);
00881
00882 neighbor_entry->longitude_ = neighbor_longitude;
00883 neighbor_entry->latitude_ = neighbor_latitude;
00884 neighbor_entry->remaining_energy_ = neighbor_energy;
00885
00886 GetTime(&(neighbor_entry->tv_));
00887 }
00888 }
00889
00890 PktHeader * GeoRoutingFilter::retrievePacketHeader(Message *msg)
00891 {
00892 PacketList::iterator packet_itr;
00893 PktHeader *pkt_header = NULL;
00894
00895 for (packet_itr = message_list_.begin();
00896 packet_itr != message_list_.end(); ++packet_itr){
00897 pkt_header = *packet_itr;
00898 if ((pkt_header->rdm_id_ == msg->rdm_id_) &&
00899 (pkt_header->pkt_num_ == msg->pkt_num_)){
00900 packet_itr = message_list_.erase(packet_itr);
00901 return pkt_header;
00902 }
00903 }
00904
00905
00906 return NULL;
00907 }
00908
00909 PktHeader * GeoRoutingFilter::preProcessMessage(Message *msg)
00910 {
00911 float longitude_min, longitude_max;
00912 float latitude_min, latitude_max;
00913 PktHeader *pkt_header = NULL;
00914 struct timeval tv;
00915
00916
00917 GetTime(&tv);
00918
00919 pkt_header = stripOutHeader(msg);
00920
00921 if (!pkt_header){
00922
00923
00924
00925
00926
00927 if (extractLocation(msg, &longitude_min, &longitude_max,
00928 &latitude_min, &latitude_max)){
00929
00930
00931 pkt_header = new PktHeader;
00932
00933
00934 pkt_header->pkt_num_ = msg->pkt_num_;
00935 pkt_header->rdm_id_ = msg->rdm_id_;
00936 pkt_header->prev_hop_ = msg->last_hop_;
00937 pkt_header->pkt_type_ = UNICAST_ORIGINAL;
00938 pkt_header->path_len_ = 0;
00939
00940 pkt_header->dst_region_.center_.longitude_ = (longitude_min +
00941 longitude_max) / 2;
00942 pkt_header->dst_region_.center_.latitude_ = (latitude_min +
00943 latitude_max) / 2;
00944
00945 pkt_header->dst_region_.radius_ = Distance(longitude_min, latitude_min,
00946 longitude_max,
00947 latitude_max) / 2;
00948
00949 DiffPrint(DEBUG_IMPORTANT,
00950 "Gear: %d.%06d - ExtractLocation %f,%f, %f,%f (%f,%f)\n",
00951 tv.tv_sec, tv.tv_usec,
00952 longitude_min, longitude_max, latitude_min, latitude_max,
00953 pkt_header->dst_region_.center_.longitude_,
00954 pkt_header->dst_region_.center_.latitude_);
00955 }
00956 }
00957
00958 return pkt_header;
00959 }
00960
00961 PktHeader * GeoRoutingFilter::stripOutHeader(Message *msg)
00962 {
00963 NRSimpleAttribute<void *> *geo_header_attribute;
00964 GeoHeader *geo_header;
00965 PktHeader *pkt_header = NULL;
00966 struct timeval tv;
00967
00968
00969 GetTime(&tv);
00970
00971 geo_header_attribute = GeoHeaderAttr.find(msg->msg_attr_vec_);
00972
00973 if (geo_header_attribute){
00974 geo_header = (GeoHeader *)(geo_header_attribute->getVal());
00975
00976
00977 pkt_header = new PktHeader;
00978
00979 pkt_header->pkt_num_ = msg->pkt_num_;
00980 pkt_header->rdm_id_ = msg->rdm_id_;
00981 pkt_header->prev_hop_ = msg->last_hop_;
00982
00983
00984 pkt_header->pkt_type_ = geo_header->pkt_type_;
00985 pkt_header->dst_region_.center_.longitude_ = geo_header->dst_region_.center_.longitude_;
00986 pkt_header->dst_region_.center_.latitude_ = geo_header->dst_region_.center_.latitude_;
00987 pkt_header->dst_region_.radius_ = geo_header->dst_region_.radius_;
00988 pkt_header->path_len_ = geo_header->path_len_;
00989
00990 takeOutAttr(msg->msg_attr_vec_, GEO_HEADER_KEY);
00991 delete geo_header_attribute;
00992
00993 DiffPrint(DEBUG_IMPORTANT,
00994 "Gear: %d.%06d - Got GeoHeader last hop: %d, pkt(%d, %d) !\n",
00995 tv.tv_sec, tv.tv_usec, msg->last_hop_,
00996 msg->pkt_num_, msg->rdm_id_);
00997 DiffPrint(DEBUG_IMPORTANT,
00998 "Gear: %d.%06d - Type: %d, Region: %f,%f,%f, Path: %d !\n",
00999 tv.tv_sec, tv.tv_usec, pkt_header->pkt_type_,
01000 pkt_header->dst_region_.center_.longitude_,
01001 pkt_header->dst_region_.center_.latitude_,
01002 pkt_header->dst_region_.radius_,
01003 pkt_header->path_len_);
01004 }
01005 else{
01006 DiffPrint(DEBUG_IMPORTANT,
01007 "Gear: %d.%06d - GeoHeader Attribute not present !\n",
01008 tv.tv_sec, tv.tv_usec);
01009 }
01010 return pkt_header;
01011 }
01012
01013 void GeoRoutingFilter::takeOutAttr(NRAttrVec *attrs, int32_t key)
01014 {
01015 NRAttrVec::iterator attr_itr;
01016
01017 for (attr_itr = attrs->begin(); attr_itr != attrs->end(); ++attr_itr){
01018 if ((*attr_itr)->getKey() == key){
01019 break;
01020 }
01021 }
01022
01023 if (attr_itr != attrs->end())
01024 attrs->erase(attr_itr);
01025 }
01026
01027 bool GeoRoutingFilter::extractLocation(Message *msg,
01028 float *longitude_min,
01029 float *longitude_max,
01030 float *latitude_min,
01031 float *latitude_max)
01032 {
01033 NRSimpleAttribute<float> *lat_attr;
01034 NRSimpleAttribute<float> *long_attr;
01035 NRAttrVec::iterator itr;
01036 NRAttrVec *attrs;
01037 bool has_long_min = false;
01038 bool has_long_max = false;
01039 bool has_lat_min = false;
01040 bool has_lat_max = false;
01041
01042 attrs = msg->msg_attr_vec_;
01043
01044
01045
01046 itr = attrs->begin();
01047
01048 for (;;){
01049
01050 long_attr = LongitudeAttr.find_from(attrs, itr, &itr);
01051
01052 if (!long_attr)
01053 break;
01054
01055 if ((long_attr->getOp() == NRAttribute::GT) ||
01056 (long_attr->getOp() == NRAttribute::GE)){
01057 has_long_min = true;
01058 *longitude_min = long_attr->getVal();
01059 }
01060
01061 if ((long_attr->getOp() == NRAttribute::LT) ||
01062 (long_attr->getOp() == NRAttribute::LE)){
01063 has_long_max = true;
01064 *longitude_max = long_attr->getVal();
01065 }
01066
01067
01068 itr++;
01069 }
01070
01071
01072
01073 itr = attrs->begin();
01074
01075 for (;;){
01076
01077 lat_attr = LatitudeAttr.find_from(attrs, itr, &itr);
01078
01079 if (!lat_attr)
01080 break;
01081
01082 if ((lat_attr->getOp() == NRAttribute::GT) ||
01083 (lat_attr->getOp() == NRAttribute::GE)){
01084 has_lat_min = true;
01085 *latitude_min = lat_attr->getVal();
01086 }
01087
01088 if ((lat_attr->getOp() == NRAttribute::LT) ||
01089 (lat_attr->getOp() == NRAttribute::LE)){
01090 has_lat_max = true;
01091 *latitude_max = lat_attr->getVal();
01092 }
01093
01094
01095 itr++;
01096 }
01097
01098 if (has_long_min && has_long_max && has_lat_min && has_lat_min)
01099 return true;
01100
01101 return false;
01102 }
01103
01104 GeoHeader * GeoRoutingFilter::restoreGeoHeader(PktHeader *pkt_header, Message *msg)
01105 {
01106 GeoHeader *geo_header;
01107
01108 geo_header = new GeoHeader;
01109
01110 msg->last_hop_ = pkt_header->prev_hop_;
01111
01112 geo_header->pkt_type_ = pkt_header->pkt_type_;
01113 geo_header->dst_region_.center_.longitude_ = pkt_header->dst_region_.center_.longitude_;
01114 geo_header->dst_region_.center_.latitude_ = pkt_header->dst_region_.center_.latitude_;
01115 geo_header->dst_region_.radius_ = pkt_header->dst_region_.radius_;
01116 geo_header->path_len_ = pkt_header->path_len_;
01117
01118 return geo_header;
01119 }
01120
01121 int32_t GeoRoutingFilter::findNextHop(GeoHeader *geo_header, bool greedy)
01122 {
01123 NeighborList::iterator neighbor_itr;
01124 NeighborEntry *neighbor_entry;
01125 GeoLocation destination, min_neighbor_location;
01126 double current_learned_cost, min_learned_cost;
01127 double current_distance, min_distance;
01128 double distance, gap;
01129 int32_t min_cost_id, neighbor_id;
01130 int num_neighbors;
01131 double new_heuristic_value;
01132 struct timeval tv;
01133
01134
01135 GetTime(&tv);
01136
01137
01138 destination = geo_header->dst_region_.center_;
01139
01140 current_distance = Distance(geo_longitude_, geo_latitude_,
01141 destination.longitude_, destination.latitude_);
01142
01143 min_distance = MAX_INT;
01144 min_learned_cost = MAX_INT;
01145 num_neighbors = 0;
01146
01147
01148
01149 for (neighbor_itr = neighbors_list_.begin();
01150 neighbor_itr != neighbors_list_.end(); ++neighbor_itr){
01151 neighbor_entry = *neighbor_itr;
01152 num_neighbors++;
01153
01154 neighbor_id = neighbor_entry->id_;
01155 current_learned_cost = retrieveLearnedCost(neighbor_id, destination);
01156
01157
01158 distance = Distance(neighbor_entry->longitude_, neighbor_entry->latitude_,
01159 destination.longitude_, destination.latitude_);
01160
01161
01162
01163 if (greedy && (distance > current_distance))
01164 continue;
01165
01166 DiffPrint(DEBUG_IMPORTANT,
01167 "Gear: %d.%06d - Neighbor: %d: cost = %f, min_cost = %f\n",
01168 tv.tv_sec, tv.tv_usec,
01169 neighbor_id, current_learned_cost, min_learned_cost);
01170
01171
01172 if (current_learned_cost < min_learned_cost){
01173 min_learned_cost = current_learned_cost;
01174 min_cost_id = neighbor_entry->id_;
01175 min_neighbor_location.longitude_ = neighbor_entry->longitude_;
01176 min_neighbor_location.latitude_ = neighbor_entry->latitude_;
01177 }
01178 }
01179
01180 DiffPrint(DEBUG_IMPORTANT,
01181 "Gear: %d.%06d - # neighbors: %d; cur: %f,%f, dst: %f,%f\n",
01182 tv.tv_sec, tv.tv_usec,
01183 num_neighbors, geo_longitude_, geo_latitude_,
01184 destination.longitude_, destination.latitude_);
01185
01186
01187 if (min_learned_cost < MAX_INT){
01188
01189
01190 gap = Distance(min_neighbor_location.longitude_,
01191 min_neighbor_location.latitude_,
01192 geo_longitude_, geo_latitude_);
01193
01194
01195 new_heuristic_value = min_learned_cost + gap;
01196
01197
01198 if (h_value_table_.updateEntry(destination, new_heuristic_value))
01199 broadcastHeuristicValue(destination, new_heuristic_value);
01200
01201
01202 return min_cost_id;
01203 }
01204
01205
01206 return BROADCAST_ADDR;
01207 }
01208
01209 void GeoRoutingFilter::broadcastHeuristicValue(GeoLocation dst,
01210 double new_heuristic_value)
01211 {
01212 NRAttrVec attrs;
01213 HeuristicValue *heuristic_value;
01214 Message *beacon_msg;
01215 TimerCallback *beacon_timer;
01216
01217 attrs.push_back(GeoLongitudeAttr.make(NRAttribute::IS, geo_longitude_));
01218 attrs.push_back(GeoLatitudeAttr.make(NRAttribute::IS, geo_latitude_));
01219 attrs.push_back(GeoRemainingEnergyAttr.make(NRAttribute::IS,
01220 remainingEnergy()));
01221 attrs.push_back(GeoBeaconTypeAttr.make(NRAttribute::IS, GEO_UPDATE));
01222
01223 heuristic_value = new HeuristicValue(dst.longitude_,
01224 dst.latitude_, new_heuristic_value);
01225
01226 attrs.push_back(GeoHeuristicValueAttr.make(NRAttribute::IS,
01227 (void *) heuristic_value,
01228 sizeof(HeuristicValue)));
01229
01230 beacon_msg = new Message(DIFFUSION_VERSION, DATA, 0, 0,
01231 attrs.size(), pkt_count_, rdm_id_,
01232 BROADCAST_ADDR, LOCALHOST_ADDR);
01233
01234
01235 pkt_count_++;
01236
01237 beacon_msg->msg_attr_vec_ = CopyAttrs(&attrs);
01238
01239
01240
01241 beacon_timer = new GeoMessageSendTimer(this, CopyMessage(beacon_msg));
01242
01243 ((DiffusionRouting *)dr_)->addTimer(GEO_BEACON_DELAY +
01244 (int) ((GEO_BEACON_JITTER *
01245 (GetRand() * 1.0 / RAND_MAX) -
01246 (GEO_BEACON_JITTER / 2))),
01247 beacon_timer);
01248
01249
01250 ClearAttrs(&attrs);
01251 delete beacon_msg;
01252 delete heuristic_value;
01253 }
01254
01255 int GeoRoutingFilter::floodInsideRegion(GeoHeader *geo_header)
01256 {
01257 NeighborList::iterator neighbor_itr;
01258 NeighborEntry *neighbor_entry;
01259 GeoLocation destination;
01260 double radius, distance;
01261 struct timeval tv;
01262
01263
01264 GetTime(&tv);
01265
01266
01267 destination = geo_header->dst_region_.center_;
01268 radius = geo_header->dst_region_.radius_;
01269
01270 if (Distance(geo_longitude_, geo_latitude_,
01271 destination.longitude_, destination.latitude_) < radius){
01272
01273
01274 geo_header->pkt_type_ = BROADCAST_TYPE;
01275
01276 DiffPrint(DEBUG_IMPORTANT,
01277 "Gear: %d.%06d - Packet inside target region !\n",
01278 tv.tv_sec, tv.tv_usec);
01279
01280
01281
01282 for (neighbor_itr = neighbors_list_.begin();
01283 neighbor_itr != neighbors_list_.end(); ++neighbor_itr){
01284 neighbor_entry = *neighbor_itr;
01285
01286 DiffPrint(DEBUG_IMPORTANT,
01287 "Gear: %d.%06d - Neighbor %d, %lf,%lf !\n",
01288 tv.tv_sec, tv.tv_usec, neighbor_entry->id_,
01289 neighbor_entry->longitude_, neighbor_entry->latitude_);
01290
01291
01292 distance = Distance(neighbor_entry->longitude_,
01293 neighbor_entry->latitude_,
01294 destination.longitude_, destination.latitude_);
01295
01296
01297
01298 if (distance < radius)
01299 return BROADCAST;
01300 }
01301 return BROADCAST_SUPPRESS;
01302 }
01303 else{
01304 if (geo_header->pkt_type_ == BROADCAST_TYPE){
01305
01306 return BROADCAST_SUPPRESS;
01307 }
01308 else{
01309
01310
01311 return OUTSIDE_REGION;
01312 }
01313 }
01314 }
01315
01316 double GeoRoutingFilter::retrieveLearnedCost(int neighbor_id, GeoLocation dst)
01317 {
01318 int index;
01319
01320 index = learned_cost_table_.retrieveEntry(neighbor_id, &dst);
01321
01322 if (index != FAIL)
01323 return learned_cost_table_.table_[index].learned_cost_value_;
01324 else
01325 return estimateCost(neighbor_id, dst);
01326 }
01327
01328 double GeoRoutingFilter::estimateCost(int neighbor_id, GeoLocation dst)
01329 {
01330 NeighborEntry *neighbor_entry;
01331 double distance;
01332 struct timeval tv;
01333
01334
01335 GetTime(&tv);
01336
01337
01338
01339
01340
01341 if (neighbor_id < 0){
01342 DiffPrint(DEBUG_IMPORTANT,
01343 "Gear: %d.%06d - Invalid neighbor id: %d !\n",
01344 tv.tv_sec, tv.tv_usec, neighbor_id);
01345 return FAIL;
01346 }
01347
01348 neighbor_entry = findNeighbor(neighbor_id);
01349
01350 if (!neighbor_entry)
01351 return FAIL;
01352
01353 distance = Distance(neighbor_entry->longitude_, neighbor_entry->latitude_,
01354 dst.longitude_, dst.latitude_);
01355
01356 return distance;
01357 }
01358
01359 NeighborEntry * GeoRoutingFilter::findNeighbor(int32_t neighbor_id)
01360 {
01361 NeighborList::iterator neighbor_itr;
01362 NeighborEntry *neighbor_entry;
01363
01364 for (neighbor_itr = neighbors_list_.begin();
01365 neighbor_itr != neighbors_list_.end(); ++neighbor_itr){
01366 neighbor_entry = *neighbor_itr;
01367 if (neighbor_entry->id_ == neighbor_id)
01368 return neighbor_entry;
01369 }
01370 return NULL;
01371 }
01372
01373 double GeoRoutingFilter::retrieveHeuristicValue(GeoLocation dst)
01374 {
01375 int index;
01376
01377 index = h_value_table_.retrieveEntry(&dst);
01378
01379 if (index != FAIL)
01380 return h_value_table_.table_[index].heuristic_value_;
01381
01382 return INITIAL_HEURISTIC_VALUE;
01383 }
01384
01385 #ifndef USE_SINGLE_ADDRESS_SPACE
01386 int main(int argc, char **argv)
01387 {
01388 GeoRoutingFilter *geo_filter;
01389
01390 geo_filter = new GeoRoutingFilter(argc, argv);
01391 geo_filter->run();
01392
01393 return 0;
01394 }
01395 #endif // !USE_SINGLE_ADDRESS_SPACE