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

📄 ramimo_proc.pr.c

📁 用OPNET实现802.11MAC协议DCF协议
💻 C
📖 第 1 页 / 共 5 页
字号:
				
				/**********************************************************************/
				/*If the packet can be received, carry out the appropriate processing */
				/**********************************************************************/
				/*Receive the packet if the source node is within transmission range and it is not a self packet*/
				if( (distance < tx_range) && (srcid != userid) )
				{
				 	 #ifdef PRINT_RX_ARVL
					    printf("Packet Can be Received\n");
				        printf("Packet Type = %s\n", pktname);
					#endif
					
				    /*If it is an RTS packet*/
				    if(strcmp(pktname, "RTS_pkt") == 0)
				    {
					    /*Read the source node user ID*/
					    op_pk_nfd_get(pktptr, "SRC", &srcid);
					
				    	/*Read the primary destination node user ID*/ 
						op_pk_nfd_get(pktptr, "DEST", &destid);
						
					    /*Determine the duration that the channel will be busy*/
				        op_pk_nfd_get(pktptr, "DURATION", &vcs_duration);
						
						/*Read tnhe sequence number field*/
				        op_pk_nfd_get(pktptr, "number", &seqnum); 
								
						#ifdef PRINT_RX_ARVL
						    printf("RTS Packet Information:\n");
						    printf("Packet SRC ID = %d\n", srcid);
					        printf("Packet DEST ID = %d\n", destid);
				            printf("Packet Duration Field = %lf\n", vcs_duration);
						    printf("Packet Sequence Number = %lf\n", seqnum);
						#endif
						
						/*Schedule an interrupt to update the channel status*/
				   		if(destid != userid)
						{	
							/*Schedule an interrupt to update the channel busy status if required*/
				     		op_intrpt_schedule_self(op_sim_time(), VCS_BUSY_INT);
							
						    #ifdef PRINT_RX_ARVL
						        printf("This Packet is Not Destined for Me\n");
				    		    printf("Scheduled a VCS Busy Interrupt\n");
				        	#endif
						}	
										
						/*Instigate the next stage in the transmission process if the RTS packet is destined for this node*/
						if(destid == userid)
						{
						
						    if((pcs_state == 0) && (vcs_state == 0))
						    {
							    if(busy == 0)
				 		        {
							        /*Store the user ID of the communicating node and the packet sequence number*/
				             	    commnodeid = srcid;
					        		sequencenum = seqnum;
						    	    busy = -1;
							    }
								
								if( (busy == -1) && (srcid == commnodeid) && (seqnum == sequencenum) )
							    {
							        /*Determine the location of the destination node*/
				                    other_node_id = op_id_from_userid(subnet_id, OPC_OBJTYPE_NDMOB, commnodeid); 
					
				                  	op_ima_obj_attr_get(other_node_id, "x position", &other_xpos);
				                    op_ima_obj_attr_get(other_node_id, "y position", &other_ypos);
				
				                	/*Work out the distance between nodes*/
				                    distance = sqrt((other_xpos - xpos)*(other_xpos - xpos) + (other_ypos - ypos)*(other_ypos - ypos));
					
				                    /*Work out the propagation delay between the source to destination node*/
				                    propdelay = distance/300000000.0;
							
					    			/*Set a timeout to return to the idle state after the data packet at the transmitter will have expired*/
						    		//tempdouble = ((double) retrylimit) * (((rtspktsize+ctspktsize+datapktsize+ackpktsize)/datarate)+(4.0*propdelay)+(3.0*sifs));
							    	if(op_ev_valid(rxtimeout) == OPC_TRUE)
										op_ev_cancel(rxtimeout);
									
									tempdouble = (((rtspktsize+ctspktsize+datapktsize+ackpktsize)/datarate)+(4.0*propdelay)+(3.0*sifs));
							        rxtimeout = op_intrpt_schedule_self(op_sim_time() + tempdouble, RX_TIMEOUT_INT);
								
									//printf("Timeout period = %lf\n", tempdouble);
									
									/*Schedule a CTS interrupt if appropriate and the channel is free*/
				    				/*Schedule CTS Interrupt in SIFS seconds time*/
				        	        nexttxevent = op_intrpt_schedule_self(op_sim_time() + sifs, CTS_INT);
				                	txreq = 1;
					        	    txstate = CTS_INT;
				    	     	
							        /*Reset the random backoff interval as this is a new transmission*/
				        			rob = -1.0;
								
				                    #ifdef PRINT_RX_ARVL
				                  	    printf("The Channel is Free and There Are No Ongoing Transmission\n");
				                        printf("Cancelled Any Pending Transmission Interrupts\n");
							            printf("Scheduled a CTS Tx Interrupt in SIFS seconds\n");
				              	    #endif
								}
									
					         }
							
						     op_prg_odb_bkpt("RX");
						 }
				  		  
				  		 /*Destroy the packet*/
				         op_pk_destroy(pktptr);		
					} 
				    /*If it is a CTS packet*/
				    else if(strcmp(pktname, "CTS_pkt") == 0)
				    {
					    /*Read the source node user ID*/
					    op_pk_nfd_get(pktptr, "SRC", &srcid);
					
				        /*Read the primary destination node user ID*/ 
						op_pk_nfd_get(pktptr, "DEST", &destid);
				
				 	    /*Determine the duration that the channel will be busy*/
				        op_pk_nfd_get(pktptr, "DURATION", &vcs_duration);
						
						/*Read tnhe sequence number field*/
				        op_pk_nfd_get(pktptr, "number", &seqnum); 
						
						#ifdef PRINT_RX_ARVL
						    printf("CTS Packet Information:\n");
						    printf("Packet SRC ID = %d\n", srcid);
				            printf("Packet DEST ID = %d\n", destid);
				    		printf("Packet Duration Field = %lf\n", vcs_duration);
						    printf("Packet Sequence Number = %lf\n", seqnum);
					 	#endif
						
						/*Schedule an interrupt to update the channel status*/
						if(destid != userid)
						{
							/*Schedule an interrupt to update the channel busy status if required*/
				     	    op_intrpt_schedule_self(op_sim_time(), VCS_BUSY_INT);
						
							#ifdef PRINT_RX_ARVL
						        printf("This Packet is Not Destined for Me\n");
				    		    printf("Scheduled a VCS Busy Interrupt\n");
					    	#endif
						}
								
						/*Instigate the next stage in the transmission process if the CTS packet is destined for this node*/
						/*and it is from the appropriate terminal*/
						if( (destid == userid) && (srcid == commnodeid) && (seqnum == sequencenum) )
						{
						    /*Reset the number of transmission attempts of the RTS packet*/
				    		numretries = 0;
							
					    	/*Reset the congestion window to its minimum value*/
						    cw_current = cw_vals[0];
							
				    		/*Cancel any associated timeoout or scheduled retransmissions*/
				            if(op_ev_valid(timeout) == OPC_TRUE)
				    	    	op_ev_cancel(timeout);
						
							/*Schedule a DATA Interrupt in SIFS seconds time*/
					        nexttxevent = op_intrpt_schedule_self(op_sim_time() + sifs, DATA_INT);
				   	        txreq = 1;
				       	   	txstate = DATA_INT;
								
							//printf("NODE ID = %d\n", userid);
							//printf("Data Interrupt Scheduled at %lf time\n", op_sim_time());
							//op_prg_odb_bkpt("WIN");
							
				    		/*Reset the random backoff interval if this is a new transmission*/
					    	rob = -1.0;
							
				   	     	#ifdef PRINT_RX_ARVL
				                printf("This Packet is Destined for Me\n");
					    	    printf("Reset Congestion Window and Number of Retransmission Attempts\n");
				  		        printf("Cancelled the RTS Timeout Interrupt\n");
				           	    printf("Scheduled a DATA transmission interrupt in SIFS seconds\n");
				            #endif
						}
							
						op_prg_odb_bkpt("RX");
						
						/*Destroy the packet*/
				        op_pk_destroy(pktptr);		
					}
				    /*If it is a DATA packet*/
					else if(strcmp(pktname, "DATA_pkt") == 0)
				    {
					    /*Read the source node user ID*/
					    op_pk_nfd_get(pktptr, "SRC", &srcid);
				
					    /*Read the primary destination node user ID*/ 
						op_pk_nfd_get(pktptr, "DEST", &destid);
					
					    /*Read the next hop information*/ 
						op_pk_nfd_get(pktptr, "nexthop", &nexthop);
					
					    /*Read the previous hop information*/ 
						op_pk_nfd_get(pktptr, "prevhop", &prevhop);
							
						/*Read the packet sequence number field*/
						op_pk_nfd_get(pktptr, "number", &seqnum);
									
						#ifdef PRINT_RX_ARVL
						    printf("DATA Packet Information:\n");
						    printf("Packet SRC ID = %d\n", srcid);
				            printf("Packet DEST ID = %d\n", destid);
						    printf("Packet Next Hop = %d\n", nexthop);
						    printf("Packet Previous Hop = %d\n", prevhop);
					   		printf("Packet Sequence Number = %lf\n", seqnum);
						#endif
								
						/*Instigate the next stage in the transmission process if the DATA packet is destined for this node*/
						/*and the channel is free*/
						if( (nexthop == userid) && (prevhop == commnodeid) && (seqnum == sequencenum) )
						{ 
						  	#ifdef PRINT_RX_ARVL
				           	    printf("This Packet is Destined for Me!\n");
						  	    printf("Current List Status:\n");
							    for(i=0;i<op_prg_list_size(listptr);i++)
								{	
								    listentryptr = op_prg_list_access(listptr, i);
									printf("List Entry [%d] - SRC = %d, NUM = %lf\n", i, listentryptr->srcid, listentryptr->number);
								}
				            #endif
								
							#ifdef PACKET
				                printf("Receiving a Data Packet at Node %d!\n", userid);
				                op_pk_nfd_get(pktptr, "SRC", &tempint);
				                printf("SRC Node = %d\n", tempint);
				                op_pk_nfd_get(pktptr, "DEST", &tempint);
				                printf("DEST Node = %d\n", tempint);
							    op_prg_odb_bkpt("PACKET");
				            #endif
				   	
						    /*THIS STATISTIC IS CONTRIVED FOR SPECIFIC SCENARIO*/
					        op_stat_write_t(linkstat, userid, op_sim_time());
						
							/*Remove any entries from the list that are no longer required*/
							for(i=0;i<100;i++)
				             	array[i] = 0;
								
							for(i=0;i<op_prg_list_size(listptr);i++)
							{
				                listentryptr = op_prg_list_access(listptr, i);
								
								/*Indicate entries that need to be removed*/
								if( (listentryptr->srcid == srcid) && (listentryptr->number < seqnum) )
					                array[i] = 1; 		
							}
								
							x = 0;	
								
							for(i=0;i<100;i++)	
							{
							    if(array[i] == 1)
								{
				  				    listentryptr = op_prg_list_remove(listptr, x);
								    op_prg_mem_free(listentryptr);
								}	
								else
									x++;						
							}
							
						    #ifdef PRINT_RX_ARVL
				        	    printf("Tidied List Status:\n");
							    for(i=0;i<op_prg_list_size(listptr);i++)
								{	
								    listentryptr = op_prg_list_access(listptr, i);
									printf("List Entry [%d] - SRC = %d, NUM = %lf\n", i, listentryptr->srcid, listentryptr->number);
								}
				           	#endif
							
							/*Determine if this packet has already been received + ignore and destroy it if it has*/
						    flag = 0;
							
							for(i=0;i<op_prg_list_size(listptr);i++)
							{
							    listentryptr = op_prg_list_access(listptr, i);
								
								/*If a match is found, this packet has already been received*/
								if( (listentryptr->srcid == srcid) && (listentryptr->number == seqnum) )
							        flag = 1;
							}
							
							/*Carry out required processing if this packet has not been received before*/
							if(flag == 0)
							{	
				              	/*Add this packet into the list of received packets*/
								listentryptr = op_prg_mem_alloc(sizeof(listentry));
								listentryptr->srcid = srcid;
								listentryptr->number = seqnum;
								op_prg_list_insert(listptr, listentryptr, OPC_LISTPOS_TAIL);	
								
							    #ifdef PRINT_RX_ARVL
				          	        printf("This Packet Has Not Been Received Before So Will Process It\n");
						 		    printf("Updated List Status:\n");
				       	    	    for(i=0;i<op_prg_list_size(listptr);i++)
									{	
									    listentryptr = op_prg_list_access(listptr, i);
										printf("List Entry [%d] - SRC = %d, NUM = %lf\n", i, listentryptr->srcid, listentryptr->number);
									}
				             
								#endif
								
							   	/*Update the packet information if this is not the final destination, and insert in queue ready for*/
				    			/*forwarding if it has not been received before*/
				    			if(destid != userid)
					    		{
						    	    /*Update the next and previous hop information*/ 
							        op_pk_nfd_set(pktptr, "nexthop", r_table[destid][0]);
				     				op_pk_nfd_set(pktptr, "prevhop", userid);
					 			
				  	    			/*Insert the packet in the tail of the transfer queue*/
				    				op_subq_pk_insert(SRC_QUEUE, pktptr, OPC_QPOS_TAIL);
								
					    			#ifdef PRINT_RX_ARVL
				                        printf("This Packet Needs Forwarding\n");
							    	    printf("Updated Next Hop = %d\n", r_table[destid][0]); 
				    			    	printf("Updated Previous Node = %d\n", userid);
				    				    printf("Inserted the Packet in the Tail of the SRC Queue\n");
				              	    #endif
						    	}
							    else
								{
								    /*Increment the number of received packets*/
								    numrxpkts++;
								
				   

⌨️ 快捷键说明

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