www.pudn.com > WSN-SEASON.rar > mflood.cc


#include  
#include  
//#include  
#include  
#include  
//#include  
 
// New packet type 
int hdr_mflood::offset_; 
static class MFloodHeaderClass : public PacketHeaderClass { 
public: 
	MFloodHeaderClass() : PacketHeaderClass("PacketHeader/MFlood",  
					      sizeof(hdr_mflood)) { 
		bind_offset(&hdr_mflood::offset_); 
	} 
} class_mfloodhdr; 
 
// TCL Hooks 
static class MFloodclass : public TclClass { 
public: 
	MFloodclass() : TclClass("Agent/MFlood") {} 
	TclObject* create(int argc, const char*const* argv) { 
		assert(argc == 5); 
		return (new MFlood((nsaddr_t) atoi(argv[4])));	// PBO agrv[4] is index_} 
	} 
} class_rtProtoMFlood; 
 
 
int 
MFlood::command(int argc, const char*const* argv) { 
	Tcl& tcl = Tcl::instance(); 
	if(argc == 2) {		 
		if(strncasecmp(argv[1], "id", 2) == 0) { 
			tcl.resultf("%d", index_); 
			return TCL_OK; 
		} 
		else if (strcmp(argv[1], "uptarget") == 0) { 
			if (uptarget_ != 0) 
				tcl.result(uptarget_->name()); 
			return (TCL_OK); 
		} 
		//add by season test command() 
		else if (strcmp(argv[1], "hello") == 0) { 
			//test tcl call c++ method 
			printf("~~~~~~~test tcl call c++ method~~~~~~~~~\nHello world!!!!!!\n~~~~~~~test tcl call c++ method~~~~~~~~~\n"); 
			 
			//test c++ call tcl method 
			/* 
			printf("~~~~~~~test c++ call tcl method~~~~~~~~~\n"); 
			char out[100];  
			int color = 0; 
			sprintf(out, "%s setColor %d",name(),color); 
			Tcl& tcl = Tcl::instance();      
			tcl.eval(out); 
			*/ 
			return (TCL_OK); 
		} 
	} else if(argc == 3) { 
		if(strcmp(argv[1], "index_") == 0) { 
			index_ = atoi(argv[2]); 
			return TCL_OK; 
		} else if(strcmp(argv[1], "log-target") == 0 || strcmp(argv[1], "tracetarget") == 0) { 
			logtarget = (Trace*) TclObject::lookup(argv[2]); 
			if(logtarget == 0) return TCL_ERROR; 
			return TCL_OK; 
		} 
		else if (strcmp(argv[1], "uptarget") == 0) { 
			if (*argv[2] == '0') { 
				target_ = 0; 
				return (TCL_OK); 
			} 
			uptarget_ = (NsObject*)TclObject::lookup(argv[2]); 
			if (uptarget_ == 0) { 
				tcl.resultf("no such object %s", argv[2]); 
				return (TCL_ERROR); 
			} 
			return (TCL_OK); 
		} 
	else if (strcasecmp (argv[1], "port-dmux") == 0) { 
           		TclObject *obj; 
            		port_dmux_ = (NsObject *) obj; 
            		return TCL_OK; 
  		}  	 
	} 
	return Agent::command(argc, argv); 
} 
 
MFlood::MFlood(nsaddr_t id) : Agent(PT_MFLOOD), port_dmux_(0) { 
	index_ = id; 
	logtarget = 0; 
	myseq_ = 0; 
} 
 
 
// Route Handling Functions 
void 
MFlood::rt_resolve(Packet *p) { 
	struct hdr_cmn *ch = HDR_CMN(p); 
	struct hdr_ip *ih = HDR_IP(p); 
	struct hdr_mflood *fh = HDR_MFLOOD(p); 
	MFlood_RTEntry* rt; 
 
	rt = rtable_.rt_lookup(ih->saddr()); 
	if(rt == NULL) { 
		rt = new MFlood_RTEntry(ih->saddr(), fh->seq_); 
 
		LIST_INSERT_HEAD(&rtable_.rthead,rt,rt_link);		 
	 
		//printf("%.8f %d,no uptarget,\n",NOW_,index_); 
		forward(rt,p,FORWARD_DELAY); 
		 
//printf("%.8f %d,no rt,so forward.rt_seq:%d,pkt seq:%d\n",NOW_,index_,rt->max_seqno,fh->seq_); 
rtable_.rt_print();		 
		 
	} 
//	else if(rt->seq_ < fh->seq_ ) 
	else if(rt->isNewSeq(fh->seq_) ) 
	{ 
		//printf("%.8f %d,no uptarget,\n",NOW_,index_); 
		forward(rt, p, FORWARD_DELAY); 
		 
//		rt->seq_ = fh->seq_; 
		rt->addSeq(fh->seq_); 
 
//printf("%.8f %d,rt seq too small,so forward,rt_seq:%d,packet seq:%d.\n",NOW_,index_,rt->max_seqno,fh->seq_);	 
rtable_.rt_print();		 
	} 
	else 
	{ 
		drop(p, "LOWSEQ"); 
	} 
} 
 
 
// Packet Reception Routines 
void 
MFlood::recv(Packet *p, Handler*) { 
	struct hdr_cmn *ch = HDR_CMN(p); 
	struct hdr_ip *ih = HDR_IP(p); 
	struct hdr_mflood *fh = HDR_MFLOOD(p); 
	assert(initialized()); 
 
	if((ih->saddr() == index_) && (ch->num_forwards() == 0)) {	// Must be a packet I'm originating...		 
		ch->size() += IP_HDR_LEN;		// Add the IP Header 
		ih->ttl_ = NETWORK_DIAMETER; 
		fh->seq_ = myseq_++;			 
		forward((MFlood_RTEntry*)1,p,0);		 
		return; 
	} else if(ih->saddr() == index_) {	// I received a packet that I sent.  Probably a routing loop. 
		drop(p, DROP_RTR_ROUTE_LOOP); 
		return; 
	} else {		// Packet I'm forwarding... 
		if(--ih->ttl_ == 0) {	// Check the TTL.  If it is zero, then discard. 
			drop(p, DROP_RTR_TTL); 
	 		return; 
		} 
	} 
 
	rt_resolve(p); 
} 
 
 
// Packet Transmission Routines 
void 
MFlood::forward(MFlood_RTEntry* rt, Packet *p, double delay) { 
	struct hdr_cmn *ch = HDR_CMN(p); 
	struct hdr_ip *ih = HDR_IP(p); 
 
	assert(ih->ttl_ > 0); 
	assert(rt != 0); 
//	assert(rt->rt_flags == RTF_UP); 
	ch->next_hop_ = -1;	//Broadcast address 
	ch->addr_type() = NS_AF_INET; 
	ch->direction() = hdr_cmn::DOWN;       //important: change the packet's direction 
	if(delay > 0.0) { 
 		Scheduler::instance().schedule(target_, p, Random::uniform(delay*2)); 
	} else {		// Not a broadcast packet, no delay, send immediately 
 		Scheduler::instance().schedule(target_, p, 0.); 
	} 
}