Applicable Versions
NetSim Standard
NetSim Pro


Applicable Releases
v13.1

Machine learning (ML) algorithms use agents that interact with the environment.  The agent selects actions and the environment responds to these actions and presents new situations to the agent. 


There are many applications where users interface their ML algorithms with NetSim, which acts as the environment. When running those algorithms they may wish to change an 


This is a toy example that describes how a user can change the state of NetSim's Random number generator when a particular event is triggered.  Such state changes can be periodic or event-triggered. 


NetSim's RNG is based on the following recursive relationship

X_(i+1) = (a*X_i + c) mod m,    i = 0, 1, 2, ...

X_0 is the seed of the RNG


The "state" of the RNG at any time, t, is only dependent on X_i since a, c, and m, are constants. Here X_i is the random integer generated just prior to tLet's say for example when some condition is hit, you wish to replace X_i with a different integer X'_i thereby leading to

X'_(i+1) = (a*X'_i + c) mod m,    i = 0, 1, 2, ...

The "state" of the RNG is changed and a new random number stream is generated from X_(i+1) onwards.  


1. Declare the new event along with previously defined timer events.

In TCP protocol existing timer events are declared as part of the TCP_Enum.h file which is part of the TCP source code project. Add a new event RUN_RNG as highlighted below:

    BEGIN_ENUM(TCP_Subevent)

{

    DECL_ENUM_ELEMENT_WITH_VAL(TCP_RTO_TIMEOUT, TX_PROTOCOL_TCP * 100),

    DECL_ENUM_ELEMENT(TCP_TIME_WAIT_TIMEOUT),

    DECL_ENUM_ELEMENT(RUN_RNG),

}


2. Declare and define a function to handle the event when triggered.

Function prototypes are usually added to the main header file of the project. A function handle_run_rng() to handle the RUN_RNG event is declared in the TCP.h main header file of TCP protocol as shown below:


    //RTO

    double get_RTT(PTCB tcb, UINT ackNo);

    double calculate_RTO(double R,

                         double* srtt,

                         double* rtt_var);

    void add_timeout_event(PNETSIM_SOCKET s,

                           NetSim_PACKET* packet);

    void handle_rto_timer();


    void restart_rto_timer(PNETSIM_SOCKET s);


    //Time wait Timer

    void start_timewait_timer(PNETSIM_SOCKET s);


    //Run RNG

    void handle_run_rng();


The function is defined in the TCP.c file, as shown below:


static void handle_run_rng()

{

    int counter = 100; 

    for (int i = 0; i < counter; i++)

        NETSIM_RAND();

}


3. Register the event at the appropriate place in code based on whether it is periodic or event triggered.

In this example, the RUN_RNG event is registered whenever the RTO timer of TCP times out. The function handle_rto_timer which is part of the RTO.c file is modified for this purpose, as highlighted below:


void handle_rto_timer()

{

    PNETSIM_SOCKET s = find_socket_at_source(pstruEventDetails->pPacket);

    if (!s)

    {

        fnNetSimError("%s is called without proper socket.\n" \

                      "This may also happen due to\n"\

                      "1. Multiple syn error\n"\

                      "2. RST packet received\n"\

                      "Ignore this error if happen due to above. Check tcp log for more details.\n",

                      __FUNCTION__);

        return;

    }

    if (!s->tcb || s->tcb->isOtherTimerCancel)

        return;


    s->tcb->isRTOTimerRunning = false;

    bool isPresent = isAnySegmentInQueue(&s->tcb->retransmissionQueue);

    

    if (isPresent)

    {

        NetSim_PACKET* segment = get_earliest_copy_segment_from_queue(&s->tcb->retransmissionQueue);

        

        print_tcp_log("\nDevice %d, Time %0.2lf: RTO Time expire.",

                      pstruEventDetails->nDeviceId,

                      pstruEventDetails->dEventTime);

        

        s->tcpMetrics->timesRTOExpired++;


        Backoff_RTO(&TCP_RTO(s->tcb));


        NetSim_EVENTDETAILS pevent;

        memcpy(&pevent, pstruEventDetails, sizeof pevent);

        pevent.nSubEventType = RUN_RNG;

        fnpAddEvent(&pevent);


        if (isTCPControl(segment))

        {

            handle_rto_timer_for_ctrl(s);

        }

        else

        {

            //Call congestion algorithm

            s->tcb->rto_expired(s);


            resend_segment(s, segment);

        }


        fn_NetSim_Packet_FreePacket(segment);

        

    }

    else

    {

        //Ignore this event

    }

    fn_NetSim_Packet_FreePacket(pstruEventDetails->pPacket);

}


Note: When registering a new event the parameters associated with the event such as the even time, packet, packet id, packet size, segment id, application id, etc, can be configured based on the requirement. In the above case, the new event is assumed to retain the properties of the previous event. 


Upon rebuilding the TCP project source codes and running the simulation, one can notice the new events triggered alongside RTO_TIMEOUT events, in the event trace log file as shown below. Nothing else happens. Given the recursive iterations in our RNG, a new X'_i is created and the "state" of the RNG is changed. 




Useful links


1. For more information on NetSim visit https://www.tetcos.com 

2. Example code and documentation on unsupervised learning (clustering and SOM) applied in NetSim are available in https://tetcos.com/file-exchange.html