📄 gear.cc
字号:
// which is inside the region too, so we just broadcast this // message DiffPrintWithTime(DEBUG_IMPORTANT, "Gear - Broadcasting message: last_hop: %d!\n", msg->last_hop_); msg->next_hop_ = BROADCAST_ADDR; ((DiffusionRouting *)dr_)->sendMessage(msg, post_filter_handle_); break; case BROADCAST_SUPPRESS: // We are either inside the region and have no neighbors // also inside this region OR packet came from inside the // region and we are outside the region. In either case, we // do not forward the packet DiffPrintWithTime(DEBUG_IMPORTANT, "Gear - Suppressing broadcast !\n"); break; case OUTSIDE_REGION: // The packet is still outside the region. In order to route // it to the region, we first try using a 'greedy mode'. If // that doesn't work, we probably need to navigate around a // hole DiffPrintWithTime(DEBUG_IMPORTANT, "Gear - Packet outside target region !\n"); next_hop = findNextHop(geo_header, true); // If there are no neighbors, let's try to go around a hole if (next_hop == BROADCAST_ADDR){ // Check if we should still be looking for a path if (geo_header->path_len_ < MAX_PATH_LEN) next_hop = findNextHop(geo_header, false); } // Still no neighbors, nothing we can do ! if (next_hop == BROADCAST_ADDR){ DiffPrintWithTime(DEBUG_IMPORTANT, "Gear - Cannot find next hop !\n"); } else{ // Forward message to next_hop msg->next_hop_ = next_hop; DiffPrintWithTime(DEBUG_IMPORTANT, "Gear - Forwarding message !\n"); DiffPrintWithTime(DEBUG_IMPORTANT, "Gear - Next Hop: %d\n", next_hop); DiffPrintWithTime(DEBUG_IMPORTANT, "Gear - Last Hop: %d\n", msg->last_hop_); ((DiffusionRouting *)dr_)->sendMessage(msg, post_filter_handle_); } break; default: break; } // Let's not forget to delete both geo_header and pkt_header delete pkt_header; delete geo_header; } else{ // This message has no packet header information, so we just forward it DiffPrintWithTime(DEBUG_IMPORTANT, "Gear - Forwarding message without packet header info !\n"); ((DiffusionRouting *)dr_)->sendMessage(msg, post_filter_handle_); } } else{ // This is a message from gradient to a local app DiffPrintWithTime(DEBUG_LOTS_DETAILS, "Gear - Forwarding message to a local agent !\n"); ((DiffusionRouting *)dr_)->sendMessage(msg, post_filter_handle_); } break; default: // All other messages are just forwarded without any changes ((DiffusionRouting *)dr_)->sendMessage(msg, post_filter_handle_); break; }}handle GeoRoutingFilter::setupPreFilter(){ NRAttrVec attrs; handle h; // Set up a filter that matches every packet coming in attrs.push_back(NRClassAttr.make(NRAttribute::IS, NRAttribute::INTEREST_CLASS)); h = ((DiffusionRouting *)dr_)->addFilter(&attrs, GEOROUTING_PRE_FILTER_PRIORITY, filter_callback_); ClearAttrs(&attrs); return h;}handle GeoRoutingFilter::setupPostFilter(){ NRAttrVec attrs; handle h; // This is a filter that matches all packets after processing by the // gradient filter attrs.push_back(NRClassAttr.make(NRAttribute::IS, NRAttribute::INTEREST_CLASS)); h = ((DiffusionRouting *)dr_)->addFilter(&attrs, GEOROUTING_POST_FILTER_PRIORITY, filter_callback_); ClearAttrs(&attrs); return h;}void GeoRoutingFilter::run(){#ifdef NS_DIFFUSION TimerCallback *neighbor_timer, *beacon_timer; // Set up node location DiffPrintWithTime(DEBUG_ALWAYS, "Initializing GEAR IN NS!\n"); getNodeLocation(&geo_longitude_, &geo_latitude_); DiffPrintWithTime(DEBUG_ALWAYS, "Gear - Location %f,%f\n", geo_longitude_, geo_latitude_); // Set up filters pre_filter_handle_ = setupPreFilter(); post_filter_handle_ = setupPostFilter(); // Add periodic neighbor checking timer neighbor_timer = new GeoNeighborsTimer(this); ((DiffusionRouting *)dr_)->addTimer(GEO_NEIGHBOR_DELAY, neighbor_timer); // Add periodic beacon request timer beacon_timer = new GeoBeaconRequestTimer(this); ((DiffusionRouting *)dr_)->addTimer(GEO_BEACON_REQUEST_CHECK_PERIOD, beacon_timer); DiffPrintWithTime(DEBUG_ALWAYS, "Gear - Pre-filter: received handle %d !\n", pre_filter_handle_); DiffPrintWithTime(DEBUG_ALWAYS, "Gear - Post-filter: received handle %d !\n", post_filter_handle_); DiffPrintWithTime(DEBUG_ALWAYS, "Gear - Initialized !\n");#endif // NS_DIFFUSION // Sends a beacon request upon start-up beaconTimeout();#ifndef NS_DIFFUSION // We don't do anything while (1){ sleep(1000); }#endif // !NS_DIFFUSION}#ifdef NS_DIFFUSIONGeoRoutingFilter::GeoRoutingFilter(const char *diffrtg){ DiffAppAgent *agent;#else GeoRoutingFilter::GeoRoutingFilter(int argc, char **argv){ // Parse command line options parseCommandLine(argc, argv);#endif // NS_DIFFUSION TimerCallback *neighbor_timer, *beacon_timer; struct timeval tv; // Initialize a few parameters initial_energy_ = GEO_INITIAL_ENERGY; unit_energy_for_send_ = GEO_UNIT_ENERGY_FOR_SEND; unit_energy_for_recv_ = GEO_UNIT_ENERGY_FOR_RECV; num_pkt_sent_ = 0; num_pkt_recv_ = 0; // Initialize beacon timestamp last_beacon_reply_tv_.tv_sec = 0; last_beacon_reply_tv_.tv_usec = 0; last_neighbor_request_tv_.tv_sec = 0; last_neighbor_request_tv_.tv_usec = 0;#ifdef NS_DIFFUSION agent = (DiffAppAgent *)TclObject::lookup(diffrtg); dr_ = agent->dr();#else getNodeLocation(&geo_longitude_, &geo_latitude_); DiffPrintWithTime(DEBUG_ALWAYS, "Gear - Location %f,%f\n", geo_longitude_, geo_latitude_);#endif // NS_DIFFUSION GetTime(&tv); SetSeed(&tv); pkt_count_ = GetRand(); rdm_id_ = GetRand();#ifndef NS_DIFFUSION // Create Diffusion Routing class dr_ = NR::createNR(diffusion_port_);#endif // !NS_DIFFUSION filter_callback_ = new GeoFilterReceive(this);#ifndef NS_DIFFUSION // Set up filters pre_filter_handle_ = setupPreFilter(); post_filter_handle_ = setupPostFilter(); // Add periodic neighbor checking timer neighbor_timer = new GeoNeighborsTimer(this); ((DiffusionRouting *)dr_)->addTimer(GEO_NEIGHBOR_DELAY, neighbor_timer); // Add periodic beacon request timer beacon_timer = new GeoBeaconRequestTimer(this); ((DiffusionRouting *)dr_)->addTimer(GEO_BEACON_REQUEST_CHECK_PERIOD, beacon_timer); DiffPrintWithTime(DEBUG_ALWAYS, "Gear - Pre-filter received handle %d !\n", pre_filter_handle_); DiffPrintWithTime(DEBUG_ALWAYS, "Gear - Post-filter received handle %d !\n", post_filter_handle_); DiffPrintWithTime(DEBUG_ALWAYS, "Gear - Initialized !\n");#endif // !NS_DIFFUSION}void GeoRoutingFilter::getNodeLocation(double *longitude, double *latitude){#ifdef NS_DIFFUSION double z; MobileNode *node = ((DiffusionRouting *)dr_)->getNode(); node->getLoc(longitude, latitude, &z);#else char *longitude_env, *latitude_env; bool got_location = false;#ifdef USE_EMSIM char *sim_loc_env; float my_longitude, my_latitude;#endif // USE_EMSIM longitude_env = getenv("gear_longitude"); latitude_env = getenv("gear_latitude"); if (longitude_env && latitude_env){ *longitude = atof(longitude_env); *latitude = atof(latitude_env); DiffPrintWithTime(DEBUG_ALWAYS, "Gear - Using location from gear_longitude, gear_latitude\n"); got_location = true; }#ifdef USE_EMSIM else{ // Try to get location from SIM_LOC (emsim environment variable) sim_loc_env = getenv("SIM_LOC"); if (sim_loc_env){ if (sscanf(sim_loc_env, "%f %f", &my_longitude, &my_latitude) == 2){ DiffPrintWithTime(DEBUG_ALWAYS, "Gear - Using location from SIM_LOC !\n"); *longitude = (double) my_longitude; *latitude = (double) my_latitude; got_location = true; } } }#endif // USE_EMSIM // Check if we were successful getting the node location if (!got_location){ DiffPrintWithTime(DEBUG_ALWAYS, "Gear - Could not get the node location !\n"); exit(-1); }#endif // NS_DIFFUSION}bool GeoRoutingFilter::checkNeighbors(){ NeighborList::iterator neighbor_itr; NeighborEntry *neighbor_entry; struct timeval tv; GetTime(&tv); for (neighbor_itr = neighbors_list_.begin(); neighbor_itr != neighbors_list_.end(); ++neighbor_itr){ neighbor_entry = *neighbor_itr; if ((tv.tv_sec - neighbor_entry->tv_.tv_sec) >= GEO_NEIGHBOR_UPDATE) return true; } return false;}void GeoRoutingFilter::sendNeighborRequest(){ NRAttrVec attrs; Message *beacon_msg; TimerCallback *beacon_timer; // Check if we need to send a beacon request to update our neighbor // information if (!checkNeighbors()) return; // Yes ! Create the beacon message attrs.push_back(GeoBeaconTypeAttr.make(NRAttribute::IS, GEO_REQUEST)); attrs.push_back(GeoLatitudeAttr.make(NRAttribute::IS, geo_latitude_)); attrs.push_back(GeoLongitudeAttr.make(NRAttribute::IS, geo_longitude_)); attrs.push_back(GeoRemainingEnergyAttr.make(NRAttribute::IS, remainingEnergy())); // Neighbor beacon msg is a DATA message beacon_msg = new Message(DIFFUSION_VERSION, DATA, 0, 0, attrs.size(), pkt_count_, rdm_id_, BROADCAST_ADDR, LOCALHOST_ADDR); // Don't forget to increment pkt_count pkt_count_++; beacon_msg->msg_attr_vec_ = CopyAttrs(&attrs); // Generate a beacon request, add some random jitter before actually // sending it DiffPrintWithTime(DEBUG_IMPORTANT, "Gear - Broadcasting neighbor info request...\n"); beacon_timer = new GeoMessageSendTimer(this, CopyMessage(beacon_msg)); ((DiffusionRouting *)dr_)->addTimer(GEO_BEACON_DELAY + (int) ((GEO_BEACON_JITTER * (GetRand() * 1.0 / RAND_MAX) - (GEO_BEACON_JITTER / 2))), beacon_timer); GetTime(&last_neighbor_request_tv_); ClearAttrs(&attrs); delete beacon_msg;}void GeoRoutingFilter::updateNeighbor(int32_t neighbor_id, double neighbor_longitude, double neighbor_latitude, double neighbor_energy){ NeighborEntry *neighbor_entry; // Look for this neighbor in our neighbor's list neighbor_entry = findNeighbor(neighbor_id); if (!neighbor_entry){ // Insert a new neighbor into our list DiffPrintWithTime(DEBUG_IMPORTANT, "Gear - Inserting new neighbor %d !\n", neighbor_id); neighbor_entry = new NeighborEntry(neighbor_id, neighbor_longitude, neighbor_latitude, neighbor_energy); // Insert new element with key neighbor_id into the hash map neighbors_list_.push_back(neighbor_entry); } else{ // Update an existing neighbor entry DiffPrintWithTime(DEBUG_IMPORTANT, "Gear - Updating neighbor %d !\n", neighbor_id); neighbor_entry->longitude_ = neighbor_longitude; neighbor_entry->latitude_ = neighbor_latitude; neighbor_entry->remaining_energy_ = neighbor_energy; GetTime(&(neighbor_entry->tv_)); }}PktHeader * GeoRoutingFilter::retrievePacketHeader(Message *msg){ PacketList::iterator packet_itr; PktHeader *pkt_header = NULL; for (packet_itr = message_list_.begin(); packet_itr != message_list_.end(); ++packet_itr){ pkt_header = *packet_itr; if ((pkt_header->rdm_id_ == msg->rdm_id_) && (pkt_header->pkt_num_ == msg->pkt_num_)){ packet_itr = message_list_.erase(packet_itr); return pkt_header; } } // Entry not found in our list return NULL;}PktHeader * GeoRoutingFilter::preProcessMessage(Message *msg){ float longitude_min, longitude_max; float latitude_min, latitude_max; PktHeader *pkt_header = NULL; pkt_header = stripOutHeader(msg); if (!pkt_header){ // This is a message either coming from a local application (for // which a geo_header hasn't been extracted yet) or a message with // no geographic information (in which case there's nothing we can // do about). We first try to extract geographic information from // the message in order to create a new geo_header if (extractLocation(msg, &longitude_min, &longitude_max, &latitude_min, &latitude_max)){ // Create new Packet Header pkt_header = new PktHeader; // Fill in the new packet header pkt_header->pkt_num_ = msg->pkt_num_; pkt_header->rdm_id_ = msg->rdm_id_; pkt_header->prev_hop_ = msg->last_hop_; pkt_header->pkt_type_ = UNICAST_ORIGINAL; pkt_header->path_len_ = 0; pkt_header->dst_region_.center_.longitude_ = (longitude_min + longitude_max) / 2; pkt_header->dst_region_.center_.latitude_ = (latitude_min + latitude_max) / 2; pkt_header->dst_region_.radius_ = Distance(longitude_min, latitude_min, longitude_max, latitude_max) / 2; DiffPrintWithTime(DEBUG_IMPORTANT, "Gear - ExtractLocation %f,%f, %f,%f (%f,%f)\n", longitude_min, longitude_max, latitude_min, latitude_max, pkt_header->dst_region_.center_.longitude_, pkt_header->dst_region_.center_.latitude_); } } return pkt_header;}PktHeader * GeoRoutingFilter::stripOutHeader(Message *msg){ NRSimpleAttribute<void *> *geo_header_attribute; GeoHeader *geo_header;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -