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