📄 proc.pr.c
字号:
/** state (TEST) exit executives **/
FSM_STATE_EXIT_FORCED (2, "TEST", "Proc [TEST exit execs]")
FSM_PROFILE_SECTION_IN ("Proc [TEST exit execs]", state2_exit_exec)
{
}
FSM_PROFILE_SECTION_OUT ("Proc [TEST exit execs]", state2_exit_exec)
/** state (TEST) transition processing **/
FSM_TRANSIT_MISSING ("TEST")
/*---------------------------------------------------------*/
/** state (SRC_ARVL) enter executives **/
FSM_STATE_ENTER_FORCED (3, state3_enter_exec, "SRC_ARVL", "Proc [SRC_ARVL enter execs]")
FSM_PROFILE_SECTION_IN ("Proc [SRC_ARVL enter execs]", state3_enter_exec)
{
/**********************************************************************************/
/*Queue the packet from the traffic generator ready for transmission */
/**********************************************************************************/
/*Get the packet from the incoming stream*/
pktptr = op_pk_get(SRC_STRM);
/*Place it in the queue ready for transmission*/
op_subq_pk_insert(SRC_QUEUE, pktptr, OPC_QPOS_TAIL);
#ifdef PRINT_SRC_ARVL
printf("SRC_ARVL STATE\n");
printf("Node %d\n", userid);
printf("Inserted a packet into the tail of the SRC_QUEUE\n");
#endif
/**********************************************************************************/
/*Schedule an RTS transmission interrupt to start the transmission process if the */
/*channel is free and the node is not currently processing anything */
/**********************************************************************************/
if( (pcs_state == 0) && (vcs_state == 0) && (inprogress == 0) )
{
/*Schedule RTS Interrupt in DIFS seconds time*/
nexttxevent = op_intrpt_schedule_self(op_sim_time() + difs, RTS_INT);
txreq = 1;
txcode = RTS_INT;
/*Update the inprogress variable*/
inprogress = 1;
#ifdef PRINT_SRC_ARVL
printf("Scheduled an RTS transmission interrupt!\n");
#endif
}
}
FSM_PROFILE_SECTION_OUT ("Proc [SRC_ARVL enter execs]", state3_enter_exec)
/** state (SRC_ARVL) exit executives **/
FSM_STATE_EXIT_FORCED (3, "SRC_ARVL", "Proc [SRC_ARVL exit execs]")
FSM_PROFILE_SECTION_IN ("Proc [SRC_ARVL exit execs]", state3_exit_exec)
{
}
FSM_PROFILE_SECTION_OUT ("Proc [SRC_ARVL exit execs]", state3_exit_exec)
/** state (SRC_ARVL) transition processing **/
FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "SRC_ARVL", "WAIT")
/*---------------------------------------------------------*/
/** state (TX) enter executives **/
FSM_STATE_ENTER_FORCED (4, state4_enter_exec, "TX", "Proc [TX enter execs]")
FSM_PROFILE_SECTION_IN ("Proc [TX enter execs]", state4_enter_exec)
{
#ifdef PRINT_TX
printf("TX STATE\n");
printf("Node %d\n", userid);
#endif
/*If transmission of an RTS packet*/
if(RTS)
{
/*Create an RTS packet*/
pktptr = op_pk_create_fmt("RTS_pkt");
/*set the appropriate size of the packet - An RTS packet is 20 bytes*/
op_pk_total_size_set(pktptr, 160);
/*Set the fields of the RTS packet*/
op_pk_nfd_set(pktptr, "SRC", userid);
//TEMPORARY FOR NOW
op_pk_nfd_set(pktptr, "DEST", 1);
//TEMPORARY FOR NOW
op_pk_nfd_set(pktptr, "DURATION", 12.0);
#ifdef PRINT_TX
printf("Transmitting an RTS Packet\n");
printf("Packet Size = %d\n", op_pk_total_size_get(pktptr));
op_pk_nfd_get(pktptr, "SRC", &tempint);
printf("Packet SRC ID = %d\n", tempint);
op_pk_nfd_get(pktptr, "DEST", &tempint);
printf("Packet DEST ID = %d\n", tempint);
op_pk_nfd_get(pktptr, "DURATION", &tempdouble);
printf("Packet Duration Field = %lf\n", tempdouble);
#endif
}
/*If transmission of a CTS packet*/
else if(CTS)
{
/*Create an CTS packet*/
pktptr = op_pk_create_fmt("CTS_pkt");
/*set the appropriate size of the packet - A CTS packet is 14 bytes*/
op_pk_total_size_set(pktptr, 112);
/*Set the fields of the CTS packet*/
op_pk_nfd_set(pktptr, "SRC", userid);
//TEMPORARY FOR NOW
op_pk_nfd_set(pktptr, "DEST", 1);
//TEMPORARY FOR NOW
op_pk_nfd_set(pktptr, "DURATION", 12.0);
#ifdef PRINT_TX
printf("Transmitting a CTS Packet\n");
printf("Packet Size = %d\n", op_pk_total_size_get(pktptr));
op_pk_nfd_get(pktptr, "SRC", &tempint);
printf("Packet SRC ID = %d\n", tempint);
op_pk_nfd_get(pktptr, "DEST", &tempint);
printf("Packet DEST ID = %d\n", tempint);
op_pk_nfd_get(pktptr, "DURATION", &tempdouble);
printf("Packet Duration Field = %lf\n", tempdouble);
#endif
}
/*If transmission of a DATA packet*/
else if(DATA)
{
/*Access the packet at the head of the SRC subqueue*/
origpktptr = op_subq_pk_access(SRC_QUEUE, OPC_QPOS_HEAD);
/*Create a copy of the packet for transmission*/
pktptr = op_pk_copy(origpktptr);
#ifdef PRINT_TX
printf("Transmitting a copy of a DATA Packet\n");
printf("Packet Size = %d\n", op_pk_total_size_get(pktptr));
op_pk_nfd_get(pktptr, "SRC", &tempint);
printf("Packet SRC ID = %d\n", tempint);
op_pk_nfd_get(pktptr, "DEST", &tempint);
printf("Packet DEST ID = %d\n", tempint);
#endif
}
/*If transmission of an ACK packet*/
else if(ACK)
{
/*Create an ACK packet*/
pktptr = op_pk_create_fmt("ACK_pkt");
/*set the appropriate size of the packet - An ACK packet is 14 bytes*/
op_pk_total_size_set(pktptr, 112);
/*Set the fields of the ACK packet*/
op_pk_nfd_set(pktptr, "SRC", userid);
//TEMPORARY FOR NOW
op_pk_nfd_set(pktptr, "DEST", 1);
#ifdef PRINT_TX
printf("Transmitting an ACK Packet\n");
printf("Packet Size = %d\n", op_pk_total_size_get(pktptr));
op_pk_nfd_get(pktptr, "SRC", &tempint);
printf("Packet SRC ID = %d\n", tempint);
op_pk_nfd_get(pktptr, "DEST", &tempint);
printf("Packet DEST ID = %d\n", tempint);
#endif
/*A transfer is complete and so the in progress variable can be reset*/
inprogress = 0;
}
/*Reset the transmission required variable - now that the transmission is taking place*/
txreq = 0;
txcode = 0;
rob = -1.0;
/*Transmit the packet*/
op_pk_send(pktptr, TX_STRM);
}
FSM_PROFILE_SECTION_OUT ("Proc [TX enter execs]", state4_enter_exec)
/** state (TX) exit executives **/
FSM_STATE_EXIT_FORCED (4, "TX", "Proc [TX exit execs]")
FSM_PROFILE_SECTION_IN ("Proc [TX exit execs]", state4_exit_exec)
{
}
FSM_PROFILE_SECTION_OUT ("Proc [TX exit execs]", state4_exit_exec)
/** state (TX) transition processing **/
FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "TX", "WAIT")
/*---------------------------------------------------------*/
/** state (SENSE) enter executives **/
FSM_STATE_ENTER_FORCED (5, state5_enter_exec, "SENSE", "Proc [SENSE enter execs]")
FSM_PROFILE_SECTION_IN ("Proc [SENSE enter execs]", state5_enter_exec)
{
/******************************************/
/*Code for physical carrier sensing update*/
/******************************************/
if(PCS)
{
/*Read the update from the receiver or transmitter channels*/
pcs_state = (int) op_stat_local_read(op_intrpt_stat());
#ifdef PRINT_SENSE
printf("SENSE STATE\n");
printf("Updating the Physical Carrier Sensing Status!\n");
printf("Node User ID = %d\n", userid);
printf("Updated PCS_STATE = %d\n", pcs_state);
#endif
/*If the channel has become busy then any pending transmission or rob calculation interrupts need to be cancelled*/
if(pcs_state == 1)
{
if(op_ev_valid(nexttxevent) == OPC_TRUE)
{
/*Update the backoff time if one has been set*/
if(rob != -1.0)
{
#ifdef PRINT_SENSE
printf("Updating backoff time!\n");
printf("Original backoff time to %lfs\n", rob);
#endif
rob = op_ev_time(nexttxevent) - op_sim_time();
#ifdef PRINT_SENSE
printf("New backoff time to %lfs\n", rob);
#endif
}
/*Cancel the transmission event*/
op_ev_cancel(nexttxevent);
#ifdef PRINT_SENSE
printf("Cancelling a Scheduled Transmission Event!\n");
#endif
}
if(op_ev_valid(robevent) == OPC_TRUE)
{
/*Cancel the backoff timer calculation event*/
op_ev_cancel(robevent);
#ifdef PRINT_SENSE
printf("Cancelling a Scheduled ROB Event!\n");
#endif
}
}
}
/******************************************************/
/*Code for virtual carrier sensing busy channel update*/
/******************************************************/
else if(VCS_busy)
{
#ifdef PRINT_SENSE
printf("SENSE STATE\n");
printf("Updating the Virtual Carrier Sensing Status!\n");
printf("Channel is sensed BUSY! via VCS\n");
#endif
/*The channel has become busy so any pending transmission or rob calculation interrupts need to be cancelled*/
if(op_ev_valid(nexttxevent) == OPC_TRUE)
{
/*Update the backoff time if one has been set*/
if(rob != -1.0)
{
#ifdef PRINT_SENSE
printf("Updating backoff time!\n");
printf("Original backoff time to %lfs\n", rob);
#endif
rob = op_ev_time(nexttxevent) - op_sim_time();
#ifdef PRINT_SENSE
printf("New backoff time to %lfs\n", rob);
#endif
}
/*Cancel the transmission event*/
op_ev_cancel(nexttxevent);
#ifdef PRINT_SENSE
printf("Cancelling a Scheduled Transmission Event!\n");
#endif
}
if(op_ev_valid(robevent) == OPC_TRUE)
{
/*Cancel the backoff timer calculation event*/
op_ev_cancel(robevent);
#ifdef PRINT_SENSE
printf("Cancelling a Scheduled ROB Event!\n");
#endif
}
/*Determine if the channel is already sensed busy*/
if(vcs_state == 1)
{
#ifdef PRINT_SENSE
printf("Channel was already sensed BUSY via VCS!\n");
printf("Time of Previous Free Interrupt = %lf\n", op_ev_time(chfreeint));
printf("New Time for Free Channel = %lf\n", op_sim_time() + vcs_duration);
#endif
/*Reschedule the channel free interrupt if the new duration is later than the previous*/
if((op_sim_time() + vcs_duration) > op_ev_time(chfreeint))
{
op_ev_cancel(chfreeint);
chfreeint = op_intrpt_schedule_self(op_sim_time() + vcs_duration, VCS_FREE_INT);
}
}
else
{
chfreeint = op_intrpt_schedule_self(op_sim_time() + vcs_duration, VCS_FREE_INT);
#ifdef PRINT_SENSE
printf("Channel was not already sensed BUSY via VCS!\n");
printf("Time for Free Channel = %lf\n", op_sim_time() + vcs_duration);
#endif
}
/*Update the vcs state variable*/
vcs_state = 1;
}
/******************************************************/
/*Code for virtual carrier sensing free channel update*/
/******************************************************/
else if(VCS_free)
{
#ifdef PRINT_SENSE
printf("SENSE STATE\n");
printf("Updating the Virtual Carrier Sensing Status!\n");
printf("Channel is sensed FREE via VCS!\n");
#endif
/*Update the vcs state variable*/
vcs_state = 0;
}
/************************************/
/*Code for the channel becoming free*/
/************************************/
/*If the channel is now free then a random backoff interrupt may need to be scheduled*/
if((pcs_state == 0) && (vcs_state == 0))
{
#ifdef PRINT_SENSE
printf("Channel has just become FREE!\n");
#endif
/*Schedule a random backoff interrupt if there is a required transmission*/
/*or there is no transfer in progress and there are packets queued*/
if( (txreq != 0) || ( (inprogress == 0) && (op_subq_empty(SRC_QUEUE) == OPC_FALSE) ) )
{
robevent = op_intrpt_schedule_self(op_sim_time() + difs, ROB_INT);
/*Update variables if this is a new transmission*/
if(inprogress == 0)
{
txreq = 1;
txcode = RTS_INT;
inprogress = 1;
}
#ifdef PRINT_SENSE
printf("Scheduled a Random Backoff Interrupt for %lfs\n", op_ev_time(robevent));
#endif
}
}
}
FSM_PROFILE_SECTION_OUT ("Proc [SENSE enter execs]", state5_enter_exec)
/** state (SENSE) exit executives **/
FSM_STATE_EXIT_FORCED (5, "SENSE", "Proc [SENSE exit execs]")
FSM_PROFILE_SECTION_IN ("Proc [SENSE exit execs]", state5_exit_exec)
{
}
FSM_PROFILE_SECTION_OUT ("Proc [SENSE exit execs]", state5_exit_exec)
/** state (SENSE) transition processing **/
FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "SENSE", "WAIT")
/*---------------------------------------------------------*/
/** state (RX_ARVL) enter executives **/
FSM_STATE_ENTER_FORCED (6, state6_enter_exec, "RX_ARVL", "Proc [RX_ARVL enter execs]")
FSM_PROFILE_SECTION_IN ("Proc [RX_ARVL enter execs]", state6_enter_exec)
{
#ifdef PRINT_TX
printf("RX_ARVL STATE\n");
printf("Node %d\n", userid);
#endif
/******************************************************************/
/*Determine whether the incoming packet can be correctly received */
/******************************************************************/
/*Get the packet from the incoming stream*/
pktptr = op_pk_get(RX_STRM);
/*Read the user ID of the source node*/
op_pk_nfd_get(pktptr, "SRC", &srcid);
/*Obtain the source nodes object ID from the user ID*/
other_node_id = op_id_from_userid(subnet_id, OPC_OBJTYPE_NDMOB, srcid);
/*Determine the location of the source node*/
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));
#ifdef PRINT_RX_ARVL
printf("Packet Heard from Node %d\n", srcid);
printf("Distance Between Tx and Rx Nodes = %lf\n", distance);
printf("Transmitting Range = %lf\n", tx_range);
#endif
/**********************************************************************/
/*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) )
{
/*Determine the packet type from its name*/
op_pk_format(pktptr, &pktname);
#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 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);
/*Schedule an interrupt to update the channel status*/
op_intrpt_schedule_self(op_sim_time(), VCS_BUSY_INT);
#ifdef PRINT_RX_ARVL
printf("RTS Packet Information:\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -