⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hgpsagent.cc

📁 在Linux下做的QuadTree的程序
💻 CC
字号:
#include "hgpsagent.h"static class HGPSAgentClass : public TclClass{    public:    HGPSAgentClass():TclClass("Agent/HGPSAgent")    {    }    TclObject* create(int, const char *const *)    {	return (new HGPSAgent());    }}class_HGPSAgent;HGPSAgent::HGPSAgent() : Agent(PT_HGPS),verbose_(1),send_buf_timer(this){    router = new HGPSRouter(this);    locserver = new LocServer(this);    verbose_ = 1;    sleepevent = new Event;    sleephandler = new HGPSSleepHandler(this);    locserver->setRouter(router);    router->setLocServer(locserver);    for (int i=0;i<SEND_BUF_SIZE;i++) {	send_buf[i].p = NULL;	send_buf[i].t = -999.0;    }    asleep = true;    wakeup_time = 0.0;    bind("off_HGPS_", &off_hgps_);    bind("off_ll_", &off_ll_);    bind("off_mac_", &off_mac_);    bind("off_ip_", &off_ip_);    bind("update_distance_", &update_distance_);}HGPSAgent::~HGPSAgent(){    fprintf(stderr,"DFU: Don't do this! I haven't figured out ~HGPSAgent too\n");      exit(-1);}voidHGPSAgent::trace(char* fmt, ...){    va_list ap;            if (!logtarget) return;    va_start(ap, fmt);    vsprintf(logtarget->buffer(), fmt, ap);    logtarget->dump();    va_end(ap);}voidHGPSAgent::startUp(){    wakeup_time = Scheduler::instance().clock();    assert(asleep == true);    asleep = false;    router->start();    locserver->start();    send_buf_timer.sched(BUFFER_CHECK + BUFFER_CHECK * Random::uniform(1.0));	      real_ll->start();}voidHGPSAgent::sleep(){    assert(asleep == false);    //stop hgpsrouter and locserver    router->sleep();    locserver->sleep();    //cancel send_buf_timer    send_buf_timer.force_cancel();    //kill all the packets in send buffer    int c;    for (c  = 0 ; c < SEND_BUF_SIZE ; c++) {	if (send_buf[c].p) {	    drop(send_buf[c].p, DROP_RTR_SLEEP);	    send_buf[c].p = NULL;	}    }    //stop the link layer    real_ll->sleep();    asleep = true;}intHGPSAgent::command(int argc, const char*const* argv){  TclObject *obj;    if (argc == 2)     {      if (strcasecmp(argv[1], "reset") == 0)	{	  Terminate();	  return Agent::command(argc, argv);	}      if (strcasecmp(argv[1], "start-hgps") == 0)	{	  startUp();          return TCL_OK;	}    }  else if(argc == 3)     {      if (strcasecmp(argv[1], "ip-addr") == 0) 	{	 myaddr_ = atoi(argv[2]);	 return TCL_OK;	}       if (strcasecmp(argv[1],"wakeup") == 0) 	{	  startUp();	  //schedule a sleeping timer	  Scheduler::instance().schedule(sleephandler,sleepevent,atof(argv[2]));	  return TCL_OK;	}       if (strcasecmp(argv[1], "test-query") == 0)  {	    if (asleep) {		return TCL_OK;	    }	    nsaddr_t dst= atoi(argv[2]);	    //hmmm, right now i just schedule an event first, if it's still too memory-consuming, then...	    Packet *p = allocpkt();	    hdr_ip *iph =  (hdr_ip*)p->access(off_ip_); 	    hdr_cmn *cmnh =  (hdr_cmn*)p->access(off_cmn_); 	    hdr_hgps *hgpsh =  (hdr_hgps*)p->access(off_hgps_); 	    iph->dst() = dst;    	    iph->src() = myaddr_;	    hgpsh->init();    	    hgpsh->type_ = DATA;	    cmnh->size() += IP_HDR_LEN;	    cmnh->size() = 128; //default	    cmnh->num_forwards() = 0;	    trace("S %.9f _%d_ originating pkt %d->%d",Scheduler::instance().clock(),myaddr_,iph->src(),iph->dst());    	    handlePktWithoutLoc(p,false);	    return TCL_OK;      }      if( (obj = TclObject::lookup(argv[2])) == 0) 	{	  fprintf(stderr, "HGPSAgent: %s lookup of %s failed\n", argv[1],		  argv[2]);	  return TCL_ERROR;	}	      if (strcasecmp(argv[1],"mobile-node") == 0) {	  locserver->setMobileNode((MobileNode *)obj);	  return TCL_OK;      }      if (strcasecmp(argv[1], "log-target") == 0) 	{	  logtarget = (Trace*) obj;	  return TCL_OK;	}      if (strcasecmp(argv[1],"add-real-ll") == 0 )        {	  real_ll = (LL *) obj;	  return TCL_OK;	}         }  else if (argc == 4)    {      if (strcasecmp(argv[1], "add-ll") == 0) 	{	  if( (obj = TclObject::lookup(argv[2])) == 0) {	    fprintf(stderr, "HGPSAgent: %s lookup of %s failed\n", argv[1],		    argv[2]);	    return TCL_ERROR;	  }	  ll = (NsObject*) obj;	  if( (obj = TclObject::lookup(argv[3])) == 0) {	    fprintf(stderr, "HGPSAgent: %s lookup of %s failed\n", argv[1],		    argv[3]);	    return TCL_ERROR;	  }	  ifq = (PriQueue *) obj;	  return TCL_OK;	}          }  return Agent::command(argc, argv);}voidHGPSAgent::recv(Packet *p, Handler *){    hdr_ip *iph = (hdr_ip *) p->access (off_ip_);    hdr_cmn *cmnh = (hdr_cmn *) p->access (off_cmn_);    hdr_hgps *hgpsh =  (hdr_hgps*)p->access(off_hgps_);    if (asleep) {	//drop the packet	drop(p,DROP_RTR_SLEEP);	return;    }    /*     *  Must be a packet I'm originating...     */     if(iph->src_ == myaddr_ && cmnh->num_forwards() == 0) {	iph->ttl_ = HGPS_IP_DEF_TTL;    }    /*     *  Packet I'm forwarding...       */    else {	/*	 *  Check the TTL.  If it is zero, then discard.  	 */	if(--iph->ttl_ == 0) {	    drop(p, DROP_RTR_TTL);	    return;	}    }     if (!hgpsh->valid_) {	hgpsh->init();	hgpsh->type_ = DATA;	iph->src() = myaddr_;	cmnh->size() += IP_HDR_LEN;	cmnh->num_forwards() = 0;	trace("S %.9f _%d_ originating pkt %d->%d",Scheduler::instance().clock(),myaddr_,iph->src(),iph->dst());#ifdef HGPS_DEBUG150	assert((iph->dst()>0)&& (iph->dst()<=150));#endif	handlePktWithoutLoc(p,false);    }else{	if (hgpsh->type_ == LOC_QUERY) {	    hgpsh->query_forwards_++;	}else if (hgpsh->type_ == LOC_QUERY_RESPONSE) {	    hgpsh->query_response_forwards_++;	}	forwardHGPSPkt(p);    }}voidHGPSAgent::forwardHGPSPkt(Packet *p){    hdr_ip *iph = (hdr_ip *) p->access (off_ip_);    hdr_hgps *hgpsh =  (hdr_hgps*)p->access(off_hgps_);    //take different actions based on the type of packet    if (hgpsh->type_ == LOC_UPDATE) {	locserver->recvUpdate(p);    }else if (hgpsh->type_ == LOC_UPDATE_FP) {	locserver->recvFPUpdate(p);    }else if (hgpsh->type_ == ROUTE_UPDATE) {	router->recvNeighborUpdate(p);    }else if ((hgpsh->type_ == LOC_QUERY)) {	locserver->recvQuery(p,false);    }else {	if (iph->dst() == myaddr_) {	   handlePktReceipt(p);	}else {	    router->sendOutPktWithLocation(p,0.0,true);	}    }}voidHGPSAgent::handlePktWithoutLoc(Packet *&p,bool retry){    hdr_ip *iph = (hdr_ip *)p->access(off_ip_);    hdr_cmn *cmnh = (hdr_cmn *)p->access (off_cmn_);    hdr_hgps *hgpsh =  (hdr_hgps*)p->access(off_hgps_);    Scheduler & s = Scheduler::instance();    //try to see if I'm lucky enough that the dstination is only 2 hops away    if ((cmnh->next_hop() = router->getNextHopFromNT(iph->dst(), hgpsh->dst_loc_))) {#ifdef TEST_QUERY        //drop(p,DROP_IFQ_ARP_FULL);	Packet::free(p);        return;#endif	if (verbose_) {	    trace("S$hit NT %.5f _%d_ %d->%d",s.clock(),myaddr_,iph->src(),iph->dst());	}	hgpsh->src_loc_ = locserver->getGrid();	s.schedule(ll,p,0);	p = NULL;	return;    }#ifdef TEST_WS    //if God says the destination is not awake yet    if (!God::instance()->isAwake(iph->dst())) {	drop(p, DROP_RTR_SLEEP);	return;    }#endif    //I have to find out the dst location first!    if (locserver->getLocation(iph->dst(),hgpsh->dst_loc_)) {#ifndef TEST_QUERY	if (hgpsh->dst_loc_.loc != -1) {	    hgpsh->src_loc_ = locserver->getGrid();	    router->sendOutPktWithLocation(p,0.0,false);	    p = NULL;	    return;	}#endif    }    //stick packet in send buffer#ifndef TEST_QUERY    if (!retry) {	stickPacketInSendBuffer(p);    }#endif#ifdef TEST_QUERY     //drop(p,DROP_IFQ_ARP_FULL);    Packet::free(p);    return;#endif    if (verbose_) {	trace("S$miss %.5f _%d_ %d->%d",s.clock(),myaddr_,iph->src(),iph->dst());    }}voidHGPSAgent::handlePktReceipt(Packet *p){    hdr_ip *iph = (hdr_ip *) p->access (off_ip_);    hdr_cmn *cmh = (hdr_cmn *) p->access (off_cmn_);    hdr_hgps *hgpsh =  (hdr_hgps*)p->access(off_hgps_);    if (hgpsh->type_ == DATA) {	//log the src location information	locserver->addUpdateLiveConn(iph->src(),hgpsh->src_loc_);	locserver->updateLocCache(iph->src(),hgpsh->src_loc_,CACHE_TIMEOUT);	//send it to the upper layer	cmh->size() = cmh->size() - IP_HDR_LEN - hgpsh->size();	hgpsh->valid_ = 0;	target_->recv(p,(Handler*)0);	return;    }    if (hgpsh->type_ == ERR) {	//this is a location err, i should purge the location information of the destination	locserver->purgeLocCache(hgpsh->id_);	Packet::free(p);	return;    }    if (hgpsh->type_ == LOC_NOTIFICATION) {	//this is a location change notification, change my cache entires accordingly	locserver->updateLocCache(iph->dst(),hgpsh->dst_loc_, CACHE_TIMEOUT);	Packet::free(p);	return;    }    if (hgpsh->type_ == LOC_QUERY) {	locserver->recvQuery(p,false);	return;    }    if (hgpsh->type_ == LOC_QUERY_RESPONSE) {	locserver->recvQueryResponse(p);	return;    }}/* this function is called by locserver when a LOC_QUERY_RESPONSE is received */voidHGPSAgent::notifyLocation(nsaddr_t id, location loc){    int c;    hdr_ip *iph;    hdr_hgps *hgpsh;    double delay = 0.0;    for (c=0; c< SEND_BUF_SIZE;c++) {	if (send_buf[c].p == NULL) continue;        iph = (hdr_ip *)(send_buf[c].p)->access(off_ip_);	if (iph->dst() == id) {	    hgpsh = (hdr_hgps *)(send_buf[c].p)->access(off_hgps_);	    hgpsh->dst_loc_ = loc;	    hgpsh->src_loc_ = locserver->getGrid();	    router->sendOutPktWithLocation(send_buf[c].p,delay,true);	    assert(send_buf[c].p == NULL);	    delay = delay + ARP_TIMEOUT;	}    }}voidHGPSAgent::Terminate(){    int c;    for (c  = 0 ; c < SEND_BUF_SIZE ; c++) {	if (send_buf[c].p) {	    drop(send_buf[c].p, DROP_END_OF_SIMULATION);	    send_buf[c].p = NULL;	}    }}/* -------------- below are sendbuf related functions ----------------- */voidHGPSAgent::stickPacketInSendBuffer(Packet *p){  double min = 99999.0;//initialize min to some big enough number  int min_index = 0;  int c;  hdr_ip *iph = (hdr_ip *) p->access (off_ip_);  if (verbose_)    trace("Sdebug %.5f _%d_ stuck into send buff %d -> %d",	  Scheduler::instance().clock(), 	  myaddr_, iph->src(),iph->dst());  for (c = 0 ; c < SEND_BUF_SIZE ; c ++)    if (send_buf[c].p == NULL)      {	send_buf[c].t = Scheduler::instance().clock();	send_buf[c].p = p;	return;      }    else if (send_buf[c].t < min)      {	min = send_buf[c].t;	min_index = c;      }    // kill somebody  dropSendBuff(send_buf[min_index].p);  assert(send_buf[min_index].p == NULL);  send_buf[min_index].t = Scheduler::instance().clock();  send_buf[min_index].p = p;}voidHGPSAgent::dropSendBuff(Packet *&p)  // log p as being dropped by the sendbuffer in HGPS agent{  hdr_ip *iph = (hdr_ip *) p->access (off_ip_);  trace("Ssb %.5f _%d_ dropped %d -> %d", Scheduler::instance().clock(), 	myaddr_, iph->src(), iph->dst());  drop(p, DROP_RTR_QTIMEOUT);  p = NULL;}voidHGPSAgent::sendBufferCheck()  // see if any packets in send buffer need route requests sent out  // for them, or need to be expired{ // this is called about once a second.  run everybody through the  // get route for pkt routine to see if it's time to do another   // location query or what not  int c;  for (c  = 0 ; c <SEND_BUF_SIZE ; c++)    {      if (send_buf[c].p == NULL) continue;      if ((Scheduler::instance().clock() - send_buf[c].t)> SEND_TIMEOUT)	{	  	  dropSendBuff(send_buf[c].p);	  send_buf[c].p = NULL;	  continue;	}#ifdef HGPS_DEBUG      hdr_ip *iph = (hdr_ip *)send_buf[c].p->access(off_ip_);      trace("Sdebug %.5f _%d_ checking for route for dst %d",	    Scheduler::instance().clock(), myaddr_, 	    iph->dst());#endif      handlePktWithoutLoc(send_buf[c].p, true);#ifdef HGPS_DEBUG      hdr_ip *iph = (hdr_ip *)send_buf[c].p->access(off_ip_);      if (send_buf[c].p == NULL) 	trace("Sdebug %.5f _%d_ sendbuf pkt to %d liberated by handlePktWOSR",	    Scheduler::instance().clock(), myaddr_; 	    iph->src());#endif    }}voidHGPSSendBufferTimer::expire(Event *e){    a_->sendBufferCheck();    resched(BUFFER_CHECK + BUFFER_CHECK * (double) ((int) e>>5 & 0xff) / 256.0);}voidHGPSSleepHandler::handle(Event *e){    a_->sleep();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -