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

📄 gpr_wlan_mac.pr.c

📁 opnet Ad hoc仿真源程序,自己构建的路由协议和网络模型
💻 C
📖 第 1 页 / 共 5 页
字号:
/** Frames cannot be transmitted until medium is idle. Once, the medium 	**/
/** is available then the station is eligible to transmit provided there	**/
/** is a need for backoff. Once the transmission is complete then the		**/
/** station will wait for the response provided the frame transmitted  		**/
/** requires a response (such as RTS and Data frames). If response			**/
/** is not needed then the station will defer to transmit next packet		**/

/* After receiving a stream interrupt, we need to switch states from	*/
/* idle to defer or transmit if there is a frame to transmit and the	*/
/* receiver is not busy													*/ 
/* If a frame is received indicating that the STA should scan, all bets */
/* are off, and the STA moves into the scan state to look for other APs */
#define READY_TO_TRANSMIT		(((intrpt_type == OPC_INTRPT_STRM && wlan_flags->data_frame_to_send == OPC_TRUE && \
								   (pcf_flag == OPC_BOOLINT_DISABLED || (wlan_flags->pcf_active == OPC_FALSE && \
								    (ap_flag == OPC_BOOLINT_ENABLED || cfp_ap_medium_control == OPC_FALSE)))) || \
								  fresp_to_send != WlanC_None || \
								  wlan_flags->polled == OPC_TRUE || \
								  wlan_flags->tx_beacon == OPC_TRUE || \
								  (wlan_flags->pcf_active == OPC_TRUE && ap_flag == OPC_BOOLINT_ENABLED)) && \
								 !roam_state_ptr->scan_mode)

/* When we have a frame to transmit, we move to transmit state if the	*/
/* medium was idle for at least a DIFS time, otherwise we go to defer	*/
/* state.																*/
#define MEDIUM_IS_IDLE			(((current_time - nav_duration + PRECISION_RECOVERY >= difs_time) && \
	             				  wlan_flags->receiver_busy == OPC_FALSE && \
								  (current_time - rcv_idle_time + PRECISION_RECOVERY >= difs_time) && \
								  wlan_flags->pcf_active == OPC_FALSE) || \
								 wlan_flags->forced_bk_end == OPC_TRUE)

/* Change state to Defer from Frm_End, if the input buffers are not empty or a frame needs	*/
/* to be retransmitted or the station has to respond to some frame.							*/		
#define FRAME_TO_TRANSMIT		(wlan_flags->data_frame_to_send == OPC_TRUE || fresp_to_send != WlanC_None || \
								 retry_count != 0 || wlan_flags->tx_beacon == OPC_TRUE || \
								 wlan_flags->cw_required == OPC_TRUE)
	
/* After deferring for either collision avoidance or interframe gap		*/
/* the channel will be available for transmission. 						*/
#define DEFERENCE_OFF			(intrpt_type == OPC_INTRPT_SELF && \
								 intrpt_code == WlanC_Deference_Off && \
								 wlan_flags->receiver_busy == OPC_FALSE)

/* Issue a transmission complete stat once the packet has successfully 	*/
/* been transmitted from the source station								*/						 
#define TRANSMISSION_COMPLETE	(intrpt_type == OPC_INTRPT_STAT && \
								 op_intrpt_stat () == TRANSMITTER_BUSY_INSTAT)

/* Backoff is performed based on the value of the backoff flag.			*/
#define PERFORM_BACKOFF			(wlan_flags->backoff_flag == OPC_TRUE || wlan_flags->perform_cw == OPC_TRUE)

/* Need to start transmitting frame once the backoff (self intrpt) 		*/
/* completed															*/
#define BACKOFF_COMPLETED		(intrpt_type == OPC_INTRPT_SELF && intrpt_code == WlanC_Backoff_Elapsed && \
								 (wlan_flags->receiver_busy == OPC_FALSE || wlan_flags->forced_bk_end == OPC_TRUE))

/* Contention Window period, which follows a successful packet			*/
/* transmission, is completed.											*/
#define CW_COMPLETED			(intrpt_type == OPC_INTRPT_SELF && intrpt_code == WlanC_CW_Elapsed && \
								 (wlan_flags->receiver_busy == OPC_FALSE || wlan_flags->forced_bk_end == OPC_TRUE))

/* After transmission the station will wait for a frame response for    */
/* Data and Rts frames.												    */
#define WAIT_FOR_FRAME          (expected_frame_type != WlanC_None)

/* Need to retransmit frame if there is a frame timeout and the         */
/* required frame is not received									    */
#define FRAME_TIMEOUT           (intrpt_type == OPC_INTRPT_SELF && intrpt_code == WlanC_Frame_Timeout)

/* If the frame is received appropriate response will be transmitted    */
/* provided the medium is considered to be idle						    */
#define FRAME_RCVD			    (intrpt_type == OPC_INTRPT_STRM && bad_packet_rcvd == OPC_FALSE && \
		 						 i_strm == LOW_LAYER_INPUT_STREAM)

/* Skip backoff if no backoff is needed								    */
#define TRANSMIT_FRAME			(!PERFORM_BACKOFF)

/* Expecting frame response	after data or Rts transmission			    */
#define EXPECTING_FRAME			(expected_frame_type != WlanC_None)

/* When the contention window period is over then we go to IDLE state	*/
/* if we don't have another frame to send at that moment. If we have	*/
/* one then we go to TRANSMIT state if we did not sense any activity	*/
/* on our receiver for a period that is greater than or equal to DIFS	*/
/* period; otherwise we go to DEFER state to defer and back-off before	*/
/* transmitting the new frame.											*/
#define	BACK_TO_IDLE			(CW_COMPLETED && wlan_flags->data_frame_to_send == OPC_FALSE && !roam_state_ptr->scan_mode)
	
#define SEND_NEW_FRAME_AFTER_CW	(CW_COMPLETED && wlan_flags->data_frame_to_send == OPC_TRUE && MEDIUM_IS_IDLE && !roam_state_ptr->scan_mode)

#define DEFER_AFTER_CW			(CW_COMPLETED && wlan_flags->data_frame_to_send == OPC_TRUE && !MEDIUM_IS_IDLE && !roam_state_ptr->scan_mode)

/* Macros that check the change in the busy status of the receiver.	   	*/
#define	RECEIVER_BUSY_HIGH		(intrpt_type == OPC_INTRPT_STAT && intrpt_code < TRANSMITTER_BUSY_INSTAT && \
								 op_stat_local_read (intrpt_code) > rx_power_threshold && !wlan_flags->collision)

#define	RECEIVER_BUSY_LOW		(intrpt_type == OPC_INTRPT_STAT && intrpt_code < TRANSMITTER_BUSY_INSTAT && !wlan_flags->receiver_busy)

#define	PERFORM_TRANSMIT		((BACKOFF_COMPLETED || SEND_NEW_FRAME_AFTER_CW))

#define	BACK_TO_DEFER			((FRAME_RCVD || DEFER_AFTER_CW || \
								 (wlan_flags->tx_beacon == OPC_TRUE && !wlan_flags->receiver_busy))) 							

/* Macro to evaluate whether the MAC is in a contention free period.	*/
#define	IN_CFP					(pcf_flag == OPC_BOOLINT_ENABLED && \
								 (cfp_ap_medium_control == OPC_TRUE || wlan_flags->pcf_active == OPC_TRUE))

/* After receiving a packet that indicates the end of the current CFP	*/
/* go to back to IDLE state if there is no packet to transmit in the CP.*/
#define	IDLE_AFTER_CFP			(intrpt_type == OPC_INTRPT_STRM && !FRAME_TO_TRANSMIT && !IN_CFP)

/* Macro to cancel the self interrupt for end of deference. It is		*/
/* called at the state transition from DEFER to IDLE.					*/
#define	CANCEL_DEF_EVENT		(op_ev_cancel (deference_evh))

#define FRM_END_TO_IDLE			(!FRAME_TO_TRANSMIT && !EXPECTING_FRAME && !IN_CFP)
	
#define	FRM_END_TO_DEFER		(!EXPECTING_FRAME && (FRAME_TO_TRANSMIT || IN_CFP))

/* Macros associated with the "SCAN" state. If the scan mode flag is	*/
/* set, the STA considers itself disconnected from its AP and starts	*/
/* scanning for a new AP-- only in DCF STAs.							*/
#define AP_DISCONNECTED 		(roam_state_ptr->scan_mode == OPC_TRUE)

#define AP_CONNECTED 			(roam_state_ptr->scan_mode == OPC_FALSE)

#define DATA_FRAME_TO_TX 		(wlan_flags->data_frame_to_send == OPC_TRUE)

#define SCAN_TIMEOUT			(intrpt_type == OPC_INTRPT_SELF && intrpt_code == WlanC_Scan_Timeout)	

#define SCAN_AFTER_CW			(CW_COMPLETED && AP_DISCONNECTED)


/** Function Prototypes **/
static void			wlan_mac_sv_init ();
static void			wlan_higher_layer_data_arrival ();
static void			wlan_physical_layer_data_arrival ();
static void			wlan_hlpk_enqueue (Packet* hld_pkptr, int dest_addr, Boolean polling);
static Boolean		wlan_tuple_find (int sta_addr, int seq_id, int frag_num, int dest_addr);
static void			wlan_data_process (Packet* seg_pkptr,int dest_addr, int sta_addr, int final_dest_addr, int frag_num, int more_frag, double pkt_id);
static void			wlan_accepted_frame_stats_update (Packet* seg_pkptr);
static void			wlan_interrupts_process ();
static void 		wlan_prepare_frame_to_send (int frame_type);
static void			wlan_frame_transmit ();
static void			wlan_schedule_deference ();
static void			wlan_frame_discard ();
static void			wlan_mac_rcv_channel_status_update (int channel_id);
static void			wlan_mac_error (const char* msg1, const char* msg2, const char* msg3);
static void			wlan_pcf_frame_discard ();
static int	   		wlan_hld_list_elem_add_comp (const void* list_elem_ptr1, const void* list_elem_ptr2);
static Boolean		wlan_poll_list_member_find (int dest_addr); 

static void						wlan_frame_type_conv (int frame_type, char* frame_type_name); 
static int						wlan_bss_id_list_manage (int bssid, const char* operation);
static PrgT_Mapping_Handle		wlan_bss_mapping_get (void);
static int 						wlan_get_ap_sta_addr (int bss_idx);
static WlanT_Sta_Mapping_Info*	wlan_sta_addr_register (int bss_idx, int sta_addr, int sta_is_ap);
static WlanT_Bss_Mapping_Info*	wlan_bss_info_get (int bssid);
static WlanT_Sta_Mapping_Info*	wlan_sta_info_get (int sta_addr, Boolean serialize);
static double 					wlan_min_freq_for_chan (int chan_num);
static void 					wlan_begin_new_scan (void);
static void 					wlan_set_transceiver_channel (int chan_num);
static void						wlan_ap_switch (void);
static void 					wlan_sta_addr_deregister (int bss_idx, int sta_addr);
static void						wlan_reset_sv (void);
static void 					wlan_ap_position_publish (void);
static void 					wlan_ap_eval_virtual (void);
static double 					wlan_ap_signal_strength_calc (double prop_distance, WlanT_AP_Position_Info *ap_info_ptr);
static void 					wlan_find_new_ap_virtual (void);

/* Callback functions		*/
#if defined (__cplusplus)
extern "C" {
#endif

static void*					wlan_bss_info_get_key (void *value_ptr);
static int 						wlan_mapping_int_key_compare (void *key_a_ptr, void *key_b_ptr);
static void 					wlan_bss_info_free (void *value_ptr);
static void*					wlan_sta_info_get_key (void *value_ptr);
static void 					wlan_sta_info_free (void *value_ptr);
static void*					wlan_dup_info_get_key (void *value_ptr);
static void 					wlan_dup_info_free (void *value_ptr);

#if defined (__cplusplus)
} /* end of 'extern "C" {' */
#endif

/* End of Header Block */


#if !defined (VOSD_NO_FIN)
#undef	BIN
#undef	BOUT
#define	BIN		FIN_LOCAL_FIELD(_op_last_line_passed) = __LINE__ - _op_block_origin;
#define	BOUT	BIN
#define	BINIT	FIN_LOCAL_FIELD(_op_last_line_passed) = 0; _op_block_origin = __LINE__;
#else
#define	BINIT
#endif /* #if !defined (VOSD_NO_FIN) */



/* State variable definitions */
typedef struct
	{
	/* Internal state tracking for FSM */
	FSM_SYS_STATE
	/* State Variables */
	int	                    		retry_count;
	int	                    		intrpt_type;
	WlanT_Mac_Intrpt_Code	  		intrpt_code;
	int	                    		my_address;
	Objid	                  		my_objid;
	Objid	                  		my_node_objid;
	Objid	                  		my_subnet_objid;
	Objid	                  		tx_objid;
	Objid	                  		txch_objid;
	Objid	                  		rx_objid;
	Objid	                  		rxch_objid;
	OmsT_Pr_Handle	         		own_process_record_handle;
	List*	                  		hld_list_ptr;
	double	                 		operational_speed;
	int	                    		frag_threshold;
	int	                    		packet_seq_number;
	int	                    		packet_frag_number;
	int	                    		destination_addr;
	Sbhandle	               		fragmentation_buffer_ptr;
	Sbhandle	               		common_rsmbuf_ptr;
	WlanT_Mac_Frame_Type	   		fresp_to_send;
	double	                 		nav_duration;
	int	                    		rts_threshold;
	int	                    		duplicate_entry;
	WlanT_Mac_Frame_Type	   		expected_frame_type;
	int	                    		remote_sta_addr;
	double	                 		backoff_slots;
	Stathandle	             		packet_load_handle;
	double	                 		intrpt_time;
	Packet *	               		wlan_transmit_frame_copy_ptr;
	Stathandle	             		backoff_slots_handle;
	int	                    		instrm_from_mac_if;
	int	                    		outstrm_to_mac_if;
	int	                    		num_fragments;
	OpT_Packet_Size	        		remainder_size;
	List*	                  		defragmentation_list_ptr;
	WlanT_Mac_Flags*	       		wlan_flags;
	OmsT_Aa_Address_Handle	 		oms_aa_handle;
	double	                 		current_time;
	double	                 		rcv_idle_time;
	Pmohandle	              		hld_pmh;
	int	                    		max_backoff;
	char	                   		current_state_name [32];
	Stathandle	             		hl_packets_rcvd;
	Stathandle	             		media_access_delay;
	Stathandle	             		ete_delay_handle;
	Stathandle	             		global_ete_delay_handle;
	Stathandle	             		global_throughput_handle;
	Stathandle	             		global_load_handle;
	Stathandle	             		global_dropped_data_handle;
	Stathandle	             		global_mac_delay_handle;
	Stathandle	             		ctrl_traffic_rcvd_handle_inbits;
	Stathandle	             		ctrl_traffic_sent_handle_inbits;
	Stathandle	             		ctrl_traffic_rcvd_handle;
	Stathandle	             		ctrl_traffic_sent_handle;
	Stathandle	             		data_traffic_rcvd_handle_inbits;
	Stathandle	             		data_traffic_sent_handle_inbits;
	Stathandle	             		data_traffic_rcvd_handle;
	Stathandle	             		data_traffic_sent_handle;
	double	                 		sifs_time;
	double	                 		slot_time;
	int	                    		cw_min;
	int	                    		cw_max;
	double	                 		difs_time;
	double	                 		plcp_overhead_control;
	double	                 		plcp_overhead_data;

⌨️ 快捷键说明

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