📄 ramimo_proc.pr.c
字号:
/**********************************************************************/
/*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 + -