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

📄 wlan_mac_smac_nav_rpm_3mar06_ver1.function block

📁 opnet网络仿真
💻 FUNCTION BLOCK
📖 第 1 页 / 共 5 页
字号:
	/* statwires.																*/
	num_statwires = op_topo_assoc_count (my_objid, OPC_TOPO_ASSOC_IN, OPC_OBJTYPE_STATWIRE);
	for (i = 0; i < num_statwires; i++)
	{
		/* Access the next statwire. Skip it if it is coming from the			*/
		/* transmitter.															*/
		statwire_objid = op_topo_assoc (my_objid, OPC_TOPO_ASSOC_IN, OPC_OBJTYPE_STATWIRE, i);
		op_ima_obj_attr_get (statwire_objid, "high threshold trigger", &threshold);

		/* If the trigger is not disabled then the statwire is from the			*/
		/* receiver. Overwrite the attribute value unless they are already same.*/
		if (threshold != OPC_BOOLDBL_DISABLED && threshold != rx_power_threshold)
			op_ima_obj_attr_set (statwire_objid, "high threshold trigger", rx_power_threshold);			
	}

	/* Create an ICI to be used during the communication with LLC.				*/
	llc_iciptr = op_ici_create ("wlan_mac_ind");
	if (llc_iciptr == OPC_NIL)
	{
		wlan_mac_error ("Unable to create ICI for communication with LLC.", OPC_NIL, OPC_NIL);
	}

	/* Initialize the variable which keeps track of number of PCF enabled nodes	*/
	/* in the network 															*/	
	pcf_network = 0;

	/* Create the mutex that will be used to serialize calling of prg_mapping	*/
	/* functions, which read/write global model related mapping information,	*/
	/* under multi-threaded execution with multiple CPUs.						*/
	mapping_info_mutex = op_prg_mt_mutex_create (OPC_MT_MUTEX_READER_WRITER, 0, "WLAN Mapping Info Mutex");

	// wsn mutex
	// creates the mutex that controls access to energy consumption and node status global varaibles
	wsn_network_mutex = op_prg_mt_mutex_create (OPC_MT_MUTEX_READER_WRITER, 0, "WLAN Network Lifetime Mutex");

	// wsn mutex
	// creates the mutex that controls a medium busy global variable used by the adaptive timeout 
	wsn_channel_busy_mutex = op_prg_mt_mutex_create (OPC_MT_MUTEX_READER_WRITER, 0, "WSN Channel Busy Mutex");

	FOUT;
}

static void 
wlan_frame_transmit ()
{
	char						msg_string  [120];
	char						msg_string1 [120];
	WlanT_Hld_List_Elem*		hld_ptr;
	double						pkt_tx_time;
		
	/** Main procedure to invoke function for preparing and  **/
	/** transmitting the appropriate frames.			     **/
	FIN (wlan_frame_transmit());


		/* If not PCF, an Ack needs to be sent for the data */
		/* prepare Ack for transmission	                    */
		if ((wlan_flags->polled == OPC_FALSE) && 
			(fresp_to_send == WlanC_Ack))
		{
			wlan_prepare_frame_to_send (fresp_to_send);

			/* Break the routine once Ack is prepared to transmit */
			FOUT;
		}

		/* Beacon transmission has priority unless we are in the middle of	*/
		/* transmitting fragments of a data packet.							*/
		else if (wlan_flags->tx_beacon == OPC_TRUE && 
			(op_sar_buf_size (fragmentation_buffer_ptr) == 0 || 
			(wlan_flags->rts_sent == OPC_FALSE && op_sar_buf_size (fragmentation_buffer_ptr) == packet_size_dcf)))
		{
			/* Reset any pending responses since beacon will terminate sequence anyway */
			fresp_to_send = WlanC_None;

			/* Prepare beacon frame to be transmitted */
			wlan_prepare_frame_to_send (WlanC_Beac);

			/* Break the routine once beacon prepared to transmit */
			FOUT;
		}

		/* Send a CTS frame if it is the type of frame we need to send a		*/
		/* response of.															*/
		else if (fresp_to_send == WlanC_Cts)
		{
			wlan_prepare_frame_to_send (fresp_to_send);
			/* Break the routine if Cts or Ack is already prepared to transmit.	*/
			FOUT;
		}

		/* If it is a retransmission then check which type of frame needs to be	*/
		/* retransmitted and then prepare and transmit that frame.				*/
		else if (short_retry_count + long_retry_count > 0)
		{
			/* If the last frame unsuccessfully transmitted was an RTS  or a 	*/
			/* CTS-to-self then transmit it again.								*/
			if ((last_frametx_type == WlanC_Rts || last_frametx_type == WlanC_Cts) && 
				wlan_flags->rts_sent == OPC_FALSE &&  wlan_flags->polled == OPC_FALSE)
			{
				wlan_prepare_frame_to_send (last_frametx_type);
			}

			/* If our last transmission was a data packet, then it means it was	*/
			/* not acknowledged. Restart the transmission process. Do the same	*/
			/* if we are resuming our retransmission after sending a beacon		*/
			/* frame or a management frame reporting end of CFP.				*/
			else if ((last_frametx_type == WlanC_Data   || last_frametx_type == WlanC_Beac ||
				last_frametx_type == WlanC_Cf_End || last_frametx_type == WlanC_Cf_End_A) && wlan_flags->polled == OPC_FALSE)
			{
				/* Check whether we need to start the retransmission with an	*/
				/* RTS message.													*/
				if (wlan_flags->frame_size_req_rts == OPC_TRUE && wlan_flags->rts_sent == OPC_FALSE)
				{
					/* Retransmit the RTS frame to again contend for the data .	*/
					wlan_prepare_frame_to_send (WlanC_Rts);		
				}


				/* Just retransmit the data packet if no protection is needed.	*/
				else
				{
					wlan_prepare_frame_to_send (WlanC_Data);
				
				}
			}
			else
			{
				/* We continue with the retransmission process. Either we have	*/
				/* received the expected CTS for our last RTS before and now we	*/
				/* can retransmit our data frame, or we moved from DCF period	*/
				/* into PCF period and have been polled by the AP for			*/
				/* transmission. In case of PCF, also check whether we have an	*/
				/* ACK to append to our data packet.							*/
				wlan_prepare_frame_to_send (WlanC_Data);
				
			}

			FOUT;
		}

		/* If higher layer queue is not empty then dequeue a packet	*/
		/* from the higher layer and insert it into fragmentation 	*/
		/* buffer check whether fragmentation and RTS-CTS exchange 	*/
		/* is needed  based on thresholds							*/
		/* Check if fragmentation buffer is empty. If it is empty   */
		/* then dequeue a packet from the higher layer queue.		*/ 
		else if ((op_prg_list_size (hld_list_ptr) != 0) && (op_sar_buf_size (fragmentation_buffer_ptr) == 0))
		{	
			/* If rts is already sent then transmit data otherwise	*/
			/* check if rts needs to be sent or not.				*/
			if (wlan_flags->rts_sent == OPC_FALSE)
			{

				/* Remove packet from higher layer queue. */
				hld_ptr = (WlanT_Hld_List_Elem *) op_prg_list_remove (hld_list_ptr, 0);

				/* Update the higher layer queue size statistic.				*/
				if (active_pc)
					op_stat_write (hl_packets_rcvd, (double) (op_prg_list_size (hld_list_ptr) + op_prg_list_size (cfpd_list_ptr)));
				else
					op_stat_write (hl_packets_rcvd, (double) op_prg_list_size (hld_list_ptr));

				/* Determine packet size to determine later whether fragmentation	*/
				/* and/or rts-cts exchange is needed.								*/
				packet_size_dcf = op_pk_total_size_get (hld_ptr->pkptr);

				/* Updating the total packet size of the higher layer buffer.	*/
				total_hlpk_size = total_hlpk_size - packet_size_dcf;

				/* Setting destination address state variable	*/				
				destination_addr = hld_ptr->destination_address;

				/* Packet seq number modulo 4096 counter.	*/
				packet_seq_number = (packet_seq_number + 1) % 4096;  

				/* Packet fragment number is initialized.	*/
				packet_frag_number = 0;				

				/* Packet needs to be fragmented if it is more than			*/
				/* fragmentation threshold, provided fragmentation is		*/
				/* enabled. Broadcast packets are not fragmented regardless	*/
				/* of their sizes.											*/
				if (frag_threshold != -1 && destination_addr >= 0 && packet_size_dcf > (frag_threshold * 8))
				{
					/* Determine number of fragments for the packet	*/
					/* and the size of the last fragment			*/							
					num_fragments =  (int) (packet_size_dcf / (frag_threshold * 8));
					remainder_size = packet_size_dcf - (num_fragments * frag_threshold * 8);

					/* If the remainder size is non zero it means that the	*/
					/* last fragment is fractional but since the number 	*/
					/* of fragments is a whole number we need to transmit	*/
					/* one additional fragment to ensure that all of the	*/
					/* data bits will be transmitted						*/
					if (remainder_size != 0)
						num_fragments = num_fragments + 1;									 
					else
						/* Special case: data size is a multiple of the		*/
						/* fragment size, so all the fragments will be the	*/
						/* same size. To be consistent with other cases,	*/
						/* set remainder_size to the size of the last		*/
						/* fragment.										*/
						remainder_size = frag_threshold * 8;
				}
				else
				{			
					/* If no fragments needed then number of	*/
					/* packets to be transmitted is set to 1	*/								
					num_fragments = 1;
					remainder_size = packet_size_dcf;
				}

				/* Storing Data packet id for debugging purposes.	*/			
				pkt_in_service = op_pk_id (hld_ptr->pkptr);		

				/* Insert packet to fragmentation buffer	*/					
				op_sar_segbuf_pk_insert (fragmentation_buffer_ptr, hld_ptr->pkptr, 0);

				/* Computing packet duration in the queue in seconds	*/
				/* and reporting it to the statistics					*/
				pkt_tx_time = (current_time - hld_ptr->time_rcvd);

				/* Printing out information to ODB.	*/
				if (wlan_trace_active == OPC_TRUE)
				{
					sprintf (msg_string, "Data packet " OPC_PACKET_ID_FMT " is removed from higher layer buffer", pkt_in_service);
					sprintf	(msg_string1, "The queueing delay for data packet " OPC_PACKET_ID_FMT " is %fs", 	
						pkt_in_service, pkt_tx_time);	
					op_prg_odb_print_major (msg_string, msg_string1, OPC_NIL);
				}

				/* Store the arrival time of the packet.	*/
				receive_time_dcf = hld_ptr->time_rcvd;

				/* Free up allocated memory for the data packet removed from the higher		*/
				/* layer queue.																*/
				op_prg_mem_free (hld_ptr);


				/* Send RTS if RTS is enabled and packet size is more than RTS threshold.	*/
				/* No RTS message is sent for broadcast packets regradless of their sizes.	*/
				if (rts_threshold != -1 && destination_addr >= 0 && 
					(packet_size_dcf + WLANC_MSDU_HEADER_SIZE) > (rts_threshold * 8) &&
					wlan_flags->polled == OPC_FALSE)			
				{
					/* Set the flag indicating that an RTS is needed for the current frame	*/
					/* due to its size.														*/
					wlan_flags->frame_size_req_rts = OPC_TRUE;

					/* Prepare RTS frame for transmission.									*/
					wlan_prepare_frame_to_send (WlanC_Rts);
					/* Break the routine as RTS is already prepared.						*/
					FOUT;
				}

				else
				{
					/* Reset the flag indicating an RTS was not necessary due to current	*/
					/* frame size.															*/
					wlan_flags->frame_size_req_rts = OPC_FALSE;

				}
			}
		}

		/* This is a normal DCF transmission. Prepare the frame for		*/
		/* for transmission.											*/
		wlan_prepare_frame_to_send (WlanC_Data);
		
	FOUT;
}



static void 
wlan_prepare_frame_to_send (WlanT_Mac_Frame_Type frame_type)
{
	Packet*							seg_pkptr;
	OpT_Packet_Size					tx_datapacket_size;
	WlanT_Mac_Frame_Type			type;
	//int								i;
	double							tx_data_rate;
	double							duration, mac_delay;
	double							total_pk_size;
	double							tx_end_time;
	double							total_plcp_overhead;
	WlanT_Data_Header_Fields*		pk_dhstruct_ptr;
	WlanT_Control_Header_Fields*	pk_chstruct_ptr;
	WlanT_Beacon_Body_Fields*		pk_bbstruct_ptr;
	Packet*							wlan_transmit_frame_ptr;
	char							msg_string [120];
	char							frame_type_str [32];

	/** Prepare frames to transmit by setting appropriate fields in the 	**/
	/** packet format for Data,Cts,Rts or Ack.  If data or Rts packet needs **/
	/** to be retransmitted then the copy of the packet is resent.          **/
	FIN (wlan_prepare_frame_to_send (frame_type));

⌨️ 快捷键说明

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