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

📄 wlan_mac_smac_nav_rpm_3mar06_ver1.function block

📁 opnet网络仿真
💻 FUNCTION BLOCK
📖 第 1 页 / 共 5 页
字号:
	rcvd_frame_drate  = wsn_data_rate;
	
	/* First initialize the transmission data rate to the lowest supported	*/
	/* data rate, which is the data rate used for control frames.			*/
	tx_data_rate = control_data_rate;

	/* It this is a CP period and the frame to be transmitted is a data/ACK.*/
	if ((wlan_flags->pcf_active == OPC_FALSE) && 
		((frame_type == WlanC_Data) || (frame_type == WlanC_Data_Ack)))
	{
		/* Adjust the transmission data rate based on the operational speed.*/
		tx_data_rate = wsn_data_rate;

		/* Set the variable which keeps track of the last transmitted frame.	*/
		last_frametx_type = frame_type;

		/* If it is a retransmission of a packet. Obtain the frame from the 	*/
		/* the copy pointer which was stored during the previous transmission	*/
		if ((short_retry_count + long_retry_count > 0) && (wlan_transmit_frame_copy_ptr != OPC_NIL))
		{
			/* If it is a retransmission then just transmit the previous frame	*/			
			wlan_transmit_frame_ptr = op_pk_copy (wlan_transmit_frame_copy_ptr);

			/* Reset header type in case Ack status has changed for frame */
			op_pk_nfd_set_int32 (wlan_transmit_frame_ptr, "Type", frame_type);

			/* If retry count is non-zero means that the frame is a */
			/* retransmission of the last transmitted frame			*/
			op_pk_nfd_access (wlan_transmit_frame_ptr, "Wlan Header", &pk_dhstruct_ptr);
			pk_dhstruct_ptr->retry = 1;

			/* Reset more_data bit in case queue status has changed since last transmission			*/
			/* If this STA has been polled, and there are additional packets remaining				*/
			if ((wlan_flags->polled == OPC_TRUE) && (op_prg_list_size (hld_list_ptr) != 0))
			{
				/* Set more data bit to tell AP that STA has more packets */
				pk_dhstruct_ptr->more_data = 1;
			}

			/* Printing out information to ODB.	*/
			if (wlan_trace_active == OPC_TRUE)
			{
				sprintf (msg_string, "Data fragment %d for packet " OPC_PACKET_ID_FMT " is retransmitted",
					pk_dhstruct_ptr->fragment_number, pkt_in_service);							
				op_prg_odb_print_major (msg_string, OPC_NIL);
			}					

			/* Calculate NAV duration till the channel will be occupied by 	*/
			/* station. The duration is SIFS time plus the ACK frame time,	*/
			/* which the station needs in response to the data frame (note:	*/
			/* no need to check for broadcast packets, since for broadcast	*/
			/* packets the encapsulating if condition will be never true).	*/
			duration = sifs_time + TXTIME_CTRL (WLANC_ACK_LENGTH);		

			/* Since the number of fragments for the last transmitted frame is	*/
			/* already decremented, there will be more fragments to transmit  	*/
			/* if number of fragments is more than zero.					  	*/
			if (num_fragments != 1)	
			{
				/* If more fragments need to be transmitted then the station 	*/
				/* need to compute the duration until the receipt of the       	*/
				/* the acknowledgement for the next fragment. 224 bits (header	*/
				/* size) is the length of the control fields in the data  		*/
				/* frame and needs to be accounted in the duration calculation.	*/
				if (num_fragments == 2)
					tx_datapacket_size = remainder_size + WLANC_MSDU_HEADER_SIZE;
				else
					tx_datapacket_size = (frag_threshold * 8) + WLANC_MSDU_HEADER_SIZE;
				duration = 2 * duration + sifs_time + TXTIME_DATA (tx_datapacket_size);
			}

			/* Set the type of the expected response to "ACK".	*/			
			expected_frame_type = WlanC_Ack;

			/* Station update its own nav_duration during CP   	*/
			/* NAV should be updated only during the CP period 	*/
			/* During CFP NAV duration is updated only during	*/
			/* the transmission of the beacon frames			*/
			if (cfp_ap_medium_control == OPC_FALSE)
				nav_duration = current_time + duration + (double) (op_pk_total_size_get (wlan_transmit_frame_ptr)) / wsn_data_rate;
		}
		else
		{
			/* Creating transmit data packet type.							*/
			wlan_transmit_frame_ptr = op_pk_create_fmt ("wsn_data");

			/* Prepare data frame fields for transmission.					*/		
			pk_dhstruct_ptr = wlan_mac_pk_dhstruct_create ();

			type = frame_type;

			pk_dhstruct_ptr->retry = 0;				
			pk_dhstruct_ptr->order = 1;
			pk_dhstruct_ptr->sequence_number = packet_seq_number;

			/* Calculate nav duration till the channel will be occupied by  */
			/* station. The duration is SIFS time plus the ack frame time   */
			/* which the station needs in response to the data frame. For	*/
			/* broadcast packets, the duration is zero since they are not	*/
			/* acknowledged.												*/
			if (destination_addr >= 0)
				duration = sifs_time + TXTIME_CTRL (WLANC_ACK_LENGTH);
			else
				duration = 0.0;

			/* If there is more than one fragment to transmit then remove	*/
			/* fragmentation threshold size length of data from the buffer	*/
			/* for transmission.											*/
			if  (num_fragments > 1)
			{
				/* Remove next fragment from the fragmentation buffer for 	*/
				/* transmission and set the appropriate fragment number.  	*/
				seg_pkptr = op_sar_srcbuf_seg_remove (fragmentation_buffer_ptr, frag_threshold * 8);

				/* Indicate in transmission frame that more fragments need	*/
				/* to be sent.												*/
				pk_dhstruct_ptr->more_frag = 1;

				/* Since more fragments need to be transmitted then the		*/
				/* station need to broadcast the time until the receipt of	*/
				/* the acknowledgement for the next fragment. 224 bits		*/
				/* (header size) is the length of control fields in the		*/
				/* data frame and need to be accounted for in the duration	*/
				/* calculation.												*/
				if (num_fragments == 2)
					tx_datapacket_size = remainder_size + WLANC_MSDU_HEADER_SIZE;
				else
					tx_datapacket_size = (frag_threshold * 8) + WLANC_MSDU_HEADER_SIZE;
				duration = 2 * duration + sifs_time + TXTIME_DATA (tx_datapacket_size);

				/* Set fragment number in packet field.						*/
				pk_dhstruct_ptr->fragment_number = packet_frag_number ;

				/* Printing out information to ODB.							*/
				if (wlan_trace_active == OPC_TRUE)
				{
					sprintf (msg_string, "Data fragment %d for packet " OPC_PACKET_ID_FMT " is transmitted", packet_frag_number, pkt_in_service);							
					op_prg_odb_print_major (msg_string, OPC_NIL);
				}

				/* Setting packet fragment number for next fragment to be	*/
				/* transmitted.												*/
				packet_frag_number = packet_frag_number + 1;    	
			}
			else
			{

				/* Remove the last fragment from the fragmentation buffer for 		*/
				/* transmission and disable more fragmentation bit.					*/

				seg_pkptr = op_sar_srcbuf_seg_remove (fragmentation_buffer_ptr, remainder_size);					

				pk_dhstruct_ptr->more_frag = 0;


				/* Printing out information to ODB.	*/
				if (wlan_trace_active == OPC_TRUE)
				{
					sprintf (msg_string, "Data fragment %d for packet " OPC_PACKET_ID_FMT " is transmitted", packet_frag_number, pkt_in_service);								
					op_prg_odb_print_major (msg_string, OPC_NIL);
				}

				pk_dhstruct_ptr->fragment_number = packet_frag_number;

			}	

			/* Setting the Header field structure.	*/

		
			/* This is the CP, so set duration field.											*/
			pk_dhstruct_ptr->duration  = duration;
			
			pk_dhstruct_ptr->address1  = destination_addr;
			pk_dhstruct_ptr->address2  = my_address;

			/* In the BSS network the Data frame is going from AP to sta then fromds bit is set.	*/
			if (ap_flag == OPC_BOOLINT_ENABLED)
				pk_dhstruct_ptr->fromds	 = 1;
			else
				pk_dhstruct_ptr->fromds	 = 0;

			/* if in the BSS network the Data frame is going from sta to AP then tods bit is set.	*/					
			if ((bss_flag == OPC_TRUE) && 
				(ap_flag == OPC_BOOLINT_DISABLED) &&
				(ap_relay == OPC_TRUE))
			{
				pk_dhstruct_ptr->tods = 1;

				/* If Infrastructure BSS then the immediate destination will be Access point, which 	*/
				/* then forward the frame to the appropriate destination.								*/
				pk_dhstruct_ptr->address1 = ap_mac_address ;
				pk_dhstruct_ptr->address3 = destination_addr;
			}
			else
			{
				pk_dhstruct_ptr->tods = 0;
			}

			/* If this STA has been polled, and there are additional packets remaining				*/
			if ((wlan_flags->polled == OPC_TRUE) && (op_prg_list_size (hld_list_ptr) != 0))
			{
				/* Set more data bit to tell AP that STA has more packets */
				pk_dhstruct_ptr->more_data = 1;
			}

			/* If we are sending the first fragment of the data fragment for the first	*/
			/* time, then this is the end of media access duration, hence we must		*/
			/* update the media access delay statistics.								*/
			if (packet_size_dcf == op_pk_total_size_get (seg_pkptr) + op_sar_buf_size (fragmentation_buffer_ptr))
			{
				mac_delay = current_time - receive_time_dcf;
				op_stat_write (media_access_delay, mac_delay);
				op_stat_write (global_mac_delay_handle, mac_delay);
			}

			/* Populate the packet fields.								*/
			op_pk_nfd_set_int32 (wlan_transmit_frame_ptr, "Type",           type);
			op_pk_nfd_set_int32 (wlan_transmit_frame_ptr, "Accept",         OPC_TRUE);
			op_pk_nfd_set_pkid  (wlan_transmit_frame_ptr, "Data Packet ID", pkt_in_service);

			/* Set the frame control field and nav duration.		   	*/
			op_pk_nfd_set (wlan_transmit_frame_ptr, "Wlan Header", pk_dhstruct_ptr,	
				wlan_mac_pk_dhstruct_copy, wlan_mac_pk_dhstruct_destroy, sizeof (WlanT_Data_Header_Fields));

			/* The actual data is placed in the Frame Body field.		*/
			op_pk_nfd_set_pkt (wlan_transmit_frame_ptr, "Frame Body", seg_pkptr);

			/* Add some bulk to the packet to model the transmission	*/
			/* delay of PLCP fields accurately which are always			*/
			/* transmitted at 1 Mbps regardless of the actual data rate	*/
			/* used for data frames.									*/

			// mib data size
			// took all bytes out of wlan_mac packet format, and inherited bit made it the size of the data!

			// original data code
			//total_plcp_overhead = PLCP_OVERHEAD_DATA ((int) op_pk_total_size_get (wlan_transmit_frame_ptr) - WLANC_DEFAULT_PLCP_OVERHEAD);
			//op_pk_bulk_size_set (wlan_transmit_frame_ptr, (OpT_Packet_Size) (total_plcp_overhead * wsn_data_rate - WLANC_DEFAULT_PLCP_OVERHEAD));

			#ifndef OPD_NO_DEBUG
				printf("\n");
				printf("The MSDU header size is %d \n",  WLANC_MSDU_HEADER_SIZE);
				printf("The tx_datapacket_size is %d\n",tx_datapacket_size);
				printf("The PHY size is %d\n", (int)(WLANC_PLCP_OVERHEAD_DSSS_LONG * WSNC_DATA_RATE));
				printf("The real packet size in function is is %d bits\n\n",(int)(WLANC_PLCP_OVERHEAD_DSSS_LONG * WSNC_DATA_RATE) + WLANC_MSDU_HEADER_SIZE + op_pk_total_size_get (wlan_transmit_frame_ptr));
			#endif
			// mib added
			op_pk_total_size_set (wlan_transmit_frame_ptr, (OpT_Packet_Size) ( (int)(WLANC_PLCP_OVERHEAD_DSSS_LONG * WSNC_DATA_RATE) + WLANC_MSDU_HEADER_SIZE + op_pk_total_size_get (wlan_transmit_frame_ptr)));
			
			/* Expect acknowledgement only for directed frames.			*/
			if (destination_addr < 0)
			{
				expected_frame_type = WlanC_None;

				/* Reset the retry count because we won't await an ACK.	*/
				/* The retry count can be non-zero even for a broadcast	*/
				/* frame since it can be proceeded by a CTS-to-self		*/
				/* frame in an 11g WLAN, which may have been			*/
				/* retransmitted.										*/
				short_retry_count = 0;

				/* Due to possible earlier use of CTS-to-self frame		*/
				/* exchange, reset the rts_sent flag.					*/
				wlan_flags->rts_sent = OPC_FALSE;

				/* Transmission of a broadcast frame is always assumed	*/
				/* successful. Hence, set the flag for CW backoff.		*/
				wlan_flags->cw_required = OPC_TRUE;
			}
			else
			{
				/* Ack frame is expected in response to data frame.		*/
				expected_frame_type = WlanC_Ack;
			}

			/* Make copy of the frame before transmission -- make sure	*/
			/* that a packet destined for broadcast addresses is not	*/
			/* copied as that would never to destroyed (due to unACKing	*/
			/* nature of broadcast traffic).							*/
			if (destination_addr >= 0)
				wlan_transmit_frame_copy_ptr = op_pk_copy (wlan_transmit_frame_ptr);
			else
				wlan_transmit_frame_copy_ptr = (Packet *) OPC_NIL;

			/* Station update of its own nav_duration.					*/
			if (cfp_ap_medium_control == OPC_FALSE)
				nav_duration = current_time + duration + (double) (op_pk_total_size_get (wlan_transmit_frame_ptr)) / wsn_data_rate ;
		}

		/* Place the transmission data rate and physical layer			*/
		/* technology information into the packet.						*/
		wlan_frame_tx_phy_info_set (wlan_transmit_frame_ptr, tx_data_rate);

		/* Update the data traffic sent statistics.						*/
		total_pk_size = (double) op_pk_total_size_get (wlan_transmit_frame_ptr);
		op_stat_write (data_traffic_sent_handle_inbits, total_pk_size);
		op_stat_write (data_traffic_sent_handle, 1.0);

		/* Write a value of 0 for the end of transmission.				*/

⌨️ 快捷键说明

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