        
/*  Sample simulation program:  ALOHA protocol, with a "p-persistent"
    feature added.

    There are NNodes network nodes which transmit on the same channel.
    Time is slotted, i.e. transmission can begin only at integer times.
    If more than one station attempts transmission during a given slot,
    they will "collide," corrupting each others' messages, and they
    must try again.  To avoid repeated collisions, a station which has
    a frame to be transmitted will do so only with probability P.  Its
    interface hardware generates a random number between 0 and 1, and
    transmits only if the number is less than P; otherwise it waits 
    until the next slot and repeats the process.

    We say a station is ACTIVE if it has something to send; otherwise
    it is IDLE.  An IDLE station will become active in any given slot
    with probability NewMsgProb. 

    We are interested in the long-run average message delay.   Our
    approximation to "long-run" will be 10,000 time slots. */


#include <stdlib.h>  /* needed for RAND_MAX */


#define IDLE 0
#define ACTIVE 1
#define NSLOTS 10000
#define MAXNODES 100


int NNodes, /* number of nodes in the network */
    State[MAXNODES], /* current node states, IDLE or ACTIVE */
    Delay[MAXNODES], /* delays so far to message, if any, at each node */
    NMsg, /* number of successfully transmitted messages so far */
    SumDelay; /* overall total delays accumulated so far */


float P, /* probability that an ACTIVE node will send */
      NewMsgProb; /* probability that an IDLE node will become ACTIVE */


/* the function Rnd(Prob) simulates a random event of probability
   Prob, with the return value 1 meaning the event occurred and 0
   meaning that it did not occur */

int Rnd(Prob)
   float Prob;

{  return((rand() < Prob * RAND_MAX));  }


Init(argc,argv)
   int argc; char **argv;

{  int Node;
   
   sscanf(argv[1],"%f",&NewMsgProb);
   sscanf(argv[2],"%f",&P);
   sscanf(argv[3],"%d",&NNodes);

   SumDelay = 0;
   NMsg = 0;
   for (Node = 0; Node < NNodes; Node++)  
      State[Node] = IDLE;
}


main(argc,argv)
   int argc; char **argv;

{  int Slot,NTry,Node,TryNode;  

   Init(argc,argv);


   /* simulate the system for NSLOTS time periods */
   for (Slot = 0; Slot < NSLOTS; Slot++)  {
      NTry = 0;
      /* for each node, check whether it has changed from IDLE to
         ACTIVE, and if ACTIVE (from just now or beforehand) check
         whether it will attempt to transmit */
      for (Node = 0; Node < NNodes; Node++)  {
         if (State[Node] == IDLE && Rnd(NewMsgProb))  {
            State[Node] = ACTIVE;
            Delay[Node] = 0;
         }
         if (State[Node] == ACTIVE)  { 
            Delay[Node]++;
            /* decide whether to transmit */
            if (Rnd(P))  {
               NTry++;
               TryNode = Node;
            }
         }
      }
      /* a successful transmission will occur if exactly one node
         attempted transmission */
      if (NTry == 1)  {
         NMsg++;
         SumDelay += Delay[TryNode];
         State[TryNode] = IDLE;
      }
   }

   if (NMsg > 0)
      printf("long-run average delay = %f\n",SumDelay/((float) NMsg));
   else
      printf("NMsg = 0\n");
}


