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

📄 mac-tdma.cc

📁 在网络仿真模拟工具下实现支持时隙的MAC层TDMA协议
💻 CC
📖 第 1 页 / 共 2 页
字号:
void MacTdma::recv(Packet* p, Handler* h) {	struct hdr_cmn *ch = HDR_CMN(p);		/* Incoming packets from phy layer, send UP to ll layer. 	   Now, it is in receiving mode. 	*/	if (ch->direction() == hdr_cmn::UP) {		// Since we can't really turn the radio off at lower level, 		// we just discard the packet.		if (!radio_active_) {			free(p);			//printf("<%d>, %f, I am sleeping...\n", index_, NOW);			return;		}		sendUp(p);		//printf("<%d> packet recved: %d\n", index_, tdma_pr_++);		return;	}		/* Packets coming down from ll layer (from ifq actually),	   send them to phy layer. 	   Now, it is in transmitting mode. */	callback_ = h;	state(MAC_SEND);	sendDown(p);	//printf("<%d> packet sent down: %d\n", index_, tdma_ps_++);}void MacTdma::sendUp(Packet* p) {	struct hdr_cmn *ch = HDR_CMN(p);	/* Can't receive while transmitting. Should not happen...?*/	if (tx_state_ && ch->error() == 0) {		printf("<%d>, can't receive while transmitting!\n", index_);		ch->error() = 1;	};	/* Detect if there is any collision happened. should not happen...?*/	if (rx_state_ == MAC_IDLE) {		SET_RX_STATE(MAC_RECV);     // Change the state to recv.		pktRx_ = p;                 // Save the packet for timer reference.		/* Schedule the reception of this packet, 		   since we just see the packet header. */		double rtime = TX_Time(p);		assert(rtime >= 0);		/* Start the timer for receiving, will end when receiving finishes. */		mhRxPkt_.start(p, rtime);	} else {		/* Note: we don't take the channel status into account, 		   as collision should not happen...		*/		printf("<%d>, receiving, but the channel is not idle....???\n", index_);	}}/* Actually receive data packet when RxPktTimer times out. */void MacTdma::recvDATA(Packet *p){	/*Adjust the MAC packet size: strip off the mac header.*/	struct hdr_cmn *ch = HDR_CMN(p);	ch->size() -= ETHER_HDR_LEN;	ch->num_forwards() += 1;	/* Pass the packet up to the link-layer.*/	uptarget_->recv(p, (Handler*) 0);}/* Send packet down to the physical layer.    Need to calculate a certain time slot for transmission. */void MacTdma::sendDown(Packet* p) {	u_int32_t dst, src, size;  	struct hdr_cmn* ch = HDR_CMN(p);	struct hdr_mac_tdma* dh = HDR_MAC_TDMA(p);	/* Update the MAC header, same as 802.11 */	ch->size() += ETHER_HDR_LEN;	dh->dh_fc.fc_protocol_version = MAC_ProtocolVersion;	dh->dh_fc.fc_type       = MAC_Type_Data;	dh->dh_fc.fc_subtype    = MAC_Subtype_Data;		dh->dh_fc.fc_to_ds      = 0;	dh->dh_fc.fc_from_ds    = 0;	dh->dh_fc.fc_more_frag  = 0;	dh->dh_fc.fc_retry      = 0;	dh->dh_fc.fc_pwr_mgt    = 0;	dh->dh_fc.fc_more_data  = 0;	dh->dh_fc.fc_wep        = 0;	dh->dh_fc.fc_order      = 0;	if((u_int32_t)ETHER_ADDR(dh->dh_da) != MAC_BROADCAST)		dh->dh_duration = DATA_DURATION;	else		dh->dh_duration = 0;	dst = ETHER_ADDR(dh->dh_da);	src = ETHER_ADDR(dh->dh_sa);	size = ch->size();	/* buffer the packet to be sent. */	pktTx_ = p;}/* Actually send the packet. */void MacTdma::send() {	u_int32_t dst, src, size;	struct hdr_cmn* ch;	struct hdr_mac_tdma* dh;	double stime;	/* Check if there is any packet buffered. */	if (!pktTx_) {		printf("<%d>, %f, no packet buffered.\n", index_, NOW);		return;	}	/* Perform carrier sence...should not be collision...? */	if(!is_idle()) {		/* Note: we don't take the channel status into account, ie. no collision,		   as collision should not happen...		*/		printf("<%d>, %f, transmitting, but the channel is not idle...???\n", index_, NOW);		return;	}	ch = HDR_CMN(pktTx_);	dh = HDR_MAC_TDMA(pktTx_);  	dst = ETHER_ADDR(dh->dh_da);	src = ETHER_ADDR(dh->dh_sa);	size = ch->size();	stime = TX_Time(pktTx_);	/* Turn on the radio and transmit! */	SET_TX_STATE(MAC_SEND);						     	radioSwitch(ON);	/* Start a timer that expires when the packet transmission is complete. */	mhTxPkt_.start(pktTx_->copy(), stime);	downtarget_->recv(pktTx_, this);        	pktTx_ = 0;}// Turn on / off the radiovoid MacTdma::radioSwitch(int i) {	radio_active_ = i;	EnergyModel *em = netif_->node()->energy_model();	if (i == ON) {		if (em && em->sleep())			em->set_node_sleep(0);		//    printf("<%d>, %f, turn radio ON\n", index_, NOW);		return;	}	if (i == OFF) {		if (em && !em->sleep()) {			em->set_node_sleep(1);			//    netif_->node()->set_node_state(INROUTE);		};		//    printf("<%d>, %f, turn radio OFF\n", index_, NOW);		return;	}}// make the new preamble.void MacTdma::makePreamble() {	u_int32_t dst;	struct hdr_mac_tdma* dh;		// If there is a packet buffered, file its destination to preamble.	if (pktTx_) {		dh = HDR_MAC_TDMA(pktTx_);  		dst = ETHER_ADDR(dh->dh_da);		//printf("<%d>, %f, write %d to slot %d in preamble\n", index_, NOW, dst, slot_num_);		tdma_preamble_[slot_num_] = dst;	} else {		//printf("<%d>, %f, write NO_PKT to slot %d in preamble\n", index_, NOW, slot_num_);		tdma_preamble_[slot_num_] = NOTHING_TO_SEND;	}}/* Timers' handlers *//* Slot Timer:   For the preamble calculation, we should have it:   occupy one slot time,   radio turned on for the whole slot.*/void MacTdma::slotHandler(Event *e) {	// Restart timer for next slot.	mhSlot_.start((Packet *)e, slot_time_);	// Make a new presamble for next frame.	if ((slot_count_ == active_node_) || (slot_count_ == FIRST_ROUND)) {		//printf("<%d>, %f, make the new preamble now.\n", index_, NOW);		// We should turn the radio on for the whole slot time.		radioSwitch(ON);		makePreamble();		slot_count_ = 0;		return;	}	// If it is the sending slot for me.	if (slot_count_ == slot_num_) {		//printf("<%d>, %f, time to send.\n", index_, NOW);		// We have to check the preamble first to avoid the packets coming in the middle.		if (tdma_preamble_[slot_num_] != NOTHING_TO_SEND)			send();		else			radioSwitch(OFF);		slot_count_++;		return;	} 	// If I am supposed to listen in this slot	if ((tdma_preamble_[slot_count_] == index_) || ((u_int32_t)tdma_preamble_[slot_count_] == MAC_BROADCAST)) {		//printf("<%d>, %f, preamble[%d]=%d, I am supposed to receive now.\n", index_, NOW, slot_count_, tdma_preamble_[slot_count_]);		slot_count_++;		// Wake up the receive packets.		radioSwitch(ON);		return;	}	// If I dont send / recv, do nothing.	//printf("<%d>, %f, preamble[%d]=%d, nothing to do now.\n", index_, NOW, slot_count_, tdma_preamble_[slot_count_]);	radioSwitch(OFF);	slot_count_++;	return;}void MacTdma::recvHandler(Event *e) {	u_int32_t dst, src; 	int size;	struct hdr_cmn *ch = HDR_CMN(pktRx_);	struct hdr_mac_tdma *dh = HDR_MAC_TDMA(pktRx_);	/* Check if any collision happened while receiving. */	if (rx_state_ == MAC_COLL) 		ch->error() = 1;	SET_RX_STATE(MAC_IDLE);  	/* check if this packet was unicast and not intended for me, drop it.*/   	dst = ETHER_ADDR(dh->dh_da);	src = ETHER_ADDR(dh->dh_sa);	size = ch->size();	//printf("<%d>, %f, recv a packet [from %d to %d], size = %d\n", index_, NOW, src, dst, size);	// Turn the radio off after receiving the whole packet	radioSwitch(OFF);	/* Ordinary operations on the incoming packet */	// Not a pcket destinated to me.	if ((dst != MAC_BROADCAST) && (dst != (u_int32_t)index_)) {		drop(pktRx_);		return;	}  	/* Now forward packet upwards. */	recvDATA(pktRx_);}/* After transmission a certain packet. Turn off the radio. */void MacTdma::sendHandler(Event *e) {	//  printf("<%d>, %f, send a packet finished.\n", index_, NOW);	/* Once transmission is complete, drop the packet. 	   p  is just for schedule a event. */	SET_TX_STATE(MAC_IDLE);	Packet::free((Packet *)e);  	// Turn off the radio after sending the whole packet	radioSwitch(OFF);	/* unlock IFQ. */	if(callback_) {		Handler *h = callback_;		callback_ = 0;		h->handle((Event*) 0);	} }

⌨️ 快捷键说明

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