Public paste
code
By: S W | Date: Jan 6 2010 16:22 | Format: None | Expires: never | Size: 27.91 KB | Hits: 1990

  1. /* ******************************************************************
  2. Door Anne Westerhof (0815012) & Willem Burgers (0814830)
  3. ********************************************************************/
  4.  
  5. /* ******************************************************************
  6.  link simulator Theo Schouten april 2002
  7. adapted from
  8.  ALTERNATING BIT AND GO-BACK-N NETWORK EMULATOR: VERSION 1.1  J.F.Kurose
  9.  
  10.    This code can be used for unidirectional or bidirectional
  11.    data transfer protocols.
  12.   Network properties:
  13.    - one way packet delay averages 20 time units (flat distribution between
  14.      10 and 30), packets are received at least 2 time units apart
  15.    - packets can be lost or corrupted (either the header or the data portion)
  16.       according to user-defined probabilities
  17.    - packets will be delivered in the order in which they were sent
  18.       (although some can be lost).
  19. **********************************************************************/
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22.  
  23. #define BIDIRECTIONAL 1  /*  1 if for bidirectional, 0 for only A to B transfer */
  24.  
  25. /* Do not change the definitions below */
  26. #define  A    0
  27. #define  B    1
  28. #define  OFF  0
  29. #define  ON   1
  30.  
  31. typedef int bool;
  32. #define FALSE 0
  33. #define TRUE 1
  34.  
  35. /* a "msg" is the data unit passed from layer 5 (teachers code) to layer  */
  36. /* 4 (students' code). It contains the data (characters) to be delivered */
  37. /* to layer 5 via the students transport level protocol entities.         */
  38. struct msg {
  39.   unsigned char data[20];
  40.   };
  41.  
  42. /* a packet is the data unit passed from layer 4 (students code) to layer */
  43. /* 3 (teachers code). */
  44. struct pkt {
  45.    int seqnum;
  46.    int acknum;
  47.    int checksum;
  48.    struct msg mes;
  49.    };
  50.  
  51. static void tolayer3 (int AorB, struct pkt packet);
  52. static void tolayer5 (int AorB, struct msg mes );
  53. static void starttimer (int AorB, int tnum, float increment);
  54. static void stoptimer (int AorB, int tnum);
  55. static void onofflayer5 (int AorB, int ONorOFF);
  56. static double gettime();
  57.  
  58. /********* STUDENTS WRITE THE NEXT TEN ROUTINES *********/
  59.  
  60. static int DEBUG = 1; /* 0: the student code should print out nothing
  61.                          >0: printout relevant information */
  62. #define MAX_SEQ_NR 15
  63. #define NRBUFS      8       /* ( (MAX_SEQ_NR + 1) / 2 ) for selective repeat protocols */
  64. #define TO_PKT   50.0   /* Time-out for the packets */
  65. #define TO_ACK   20.0   /* Time-out for the acknowledgments */
  66.  
  67. int seqnumA, seqnumA2, seqnumB, seqnumB2;
  68. int ackA, sentA, receivedA, ackB, sentB, receivedB;
  69. int arrA, arrB;
  70. bool resendA, resendB;
  71. bool timerA, acktimerA, timerB, acktimerB;
  72.  
  73. int Checksum (int seqnum, int acknum, struct msg mes)
  74. {
  75.     int som = seqnum + acknum;
  76.     int i = 0;
  77.     for (i; i < 20;i++)
  78.     {
  79.         som = som + (int)mes.data[i];
  80.     }
  81.     return som;
  82. }
  83.  
  84. struct pkt MsgToPkt (struct msg m, bool AofB)
  85. {
  86.     struct pkt packetX;
  87.         if(AofB == A)
  88.         {
  89.                 packetX.seqnum = seqnumA;
  90.                 packetX.acknum = ackA;
  91.         }
  92.         else
  93.         {
  94.                 packetX.seqnum = seqnumB;
  95.                 packetX.acknum = ackB;
  96.         }
  97.         packetX.checksum = Checksum (packetX.seqnum, packetX.acknum, m);
  98.         packetX.mes = m;
  99.     return packetX;
  100. }
  101.  
  102. struct pkt Ack (bool AofB)
  103. {
  104.     struct pkt Ack;
  105.         Ack.seqnum = -1;
  106.         if(AofB == A)
  107.                 Ack.acknum = ackA;
  108.         else
  109.                 Ack.acknum = ackB;
  110.         Ack.checksum = Checksum(Ack.seqnum, Ack.acknum, Ack.mes);
  111.        return Ack;
  112. }
  113.  
  114. struct pkt window[2][NRBUFS];
  115.  
  116. bool buffervol (bool AofB)
  117. {
  118.         if (AofB == A)
  119.            if (arrA == NRBUFS)
  120.                    return TRUE;
  121.            else
  122.                    return FALSE;
  123.         else
  124.            if (arrB == NRBUFS)
  125.                    return TRUE;
  126.            else
  127.                    return FALSE;
  128. }
  129.  
  130. void addToBuffer(int AofB, struct pkt packet)
  131. {
  132.      if(AofB == A)
  133.          {
  134.                  window[A][arrA] = packet;
  135.                  arrA = arrA + 1;
  136.          }
  137.      else
  138.          {
  139.                  window[B][arrB] = packet;
  140.                  arrB = arrB + 1;
  141.          }
  142. }
  143.  
  144. void deleteFromBuffer(bool AofB, int aantal)
  145. {
  146.         if(aantal != 0)
  147.         {
  148.                 window[AofB][0]=window[AofB][1];
  149.                 window[AofB][1]=window[AofB][2];
  150.                 window[AofB][2]=window[AofB][3];
  151.                 window[AofB][3]=window[AofB][4];
  152.                 window[AofB][4]=window[AofB][5];
  153.                 window[AofB][5]=window[AofB][6];
  154.                 window[AofB][6]=window[AofB][7];
  155.                 if(AofB == A)
  156.                         arrA = arrA - 1;
  157.                 else
  158.                         arrB = arrB - 1;
  159.                 deleteFromBuffer(AofB,(aantal-1));
  160.         }
  161. }
  162.  
  163. struct pkt repack (struct pkt X, bool AofB)
  164. {
  165.        if(AofB == A)
  166.            X.acknum = ackA;
  167.        else
  168.            X.acknum = ackB;
  169.        X.checksum = Checksum (X.seqnum, X.acknum, X.mes);
  170.        return X;
  171. }
  172.  
  173. void resend (bool AofB)
  174. {
  175.         if(AofB == A)
  176.         {
  177.                 if(acktimerA==TRUE)
  178.                 {
  179.                         stoptimer(A,-1);
  180.                         acktimerA = FALSE;
  181.                 }
  182.         }
  183.         else
  184.         {
  185.                 if(acktimerB==TRUE)
  186.                 {
  187.                         stoptimer(B,-1);
  188.                         acktimerB = FALSE;
  189.                 }
  190.         }
  191.         tolayer3(AofB,repack(window[AofB][0],AofB));
  192.         int index = 1;
  193.         if(AofB == A)
  194.         {
  195.                 for(index;index<arrA;index++)
  196.         {
  197.                 tolayer3(A,repack(window[A][index],A));
  198.         }
  199.     }
  200.         else
  201.         {
  202.                 for(index;index<arrB;index++)
  203.         {
  204.                 tolayer3(B,repack(window[B][index],B));
  205.         }
  206.     }
  207. }
  208.  
  209. void deletePacket(bool AofB, int recAck)
  210. {
  211.         int index = 0;
  212.         for(index; index < NRBUFS; index++)
  213.         {
  214.                 if (window[AofB][index].seqnum == recAck)
  215.                 {
  216.                         deleteFromBuffer(AofB,(index+1));
  217.                         onofflayer5(AofB,ON);
  218.                         break;
  219.                 }
  220.         }
  221. }
  222.  
  223. static void A_init()
  224. {
  225.         onofflayer5(A,ON); seqnumA = MAX_SEQ_NR; seqnumA2 = 0; ackA = 0;
  226.         sentA = 0; receivedA = 0; arrA = 0; resendA = FALSE;
  227. }
  228. static void B_init()
  229. {
  230.         onofflayer5(B,ON); seqnumB = MAX_SEQ_NR; seqnumB2 = 0; ackB = 0;
  231.         sentB = 0; receivedB = 0; arrB = 0; resendB = FALSE;
  232. }
  233.  
  234. static void A_output(struct msg m)
  235. {
  236.     seqnumA = (seqnumA+1)%(MAX_SEQ_NR+1);
  237.         sentA = sentA + 1;
  238.         if(acktimerA==TRUE)
  239.         {
  240.         stoptimer(A,-1);
  241.         acktimerA = FALSE;
  242.     }
  243.         struct pkt packet = MsgToPkt(m,A);
  244.     addToBuffer(A, packet);
  245.         tolayer3(A,packet);
  246.         if(buffervol(A) == TRUE)
  247.                 onofflayer5(A,OFF);
  248. }
  249.  
  250. static void B_output(struct msg m)
  251. {
  252.         seqnumB = (seqnumB+1)%(MAX_SEQ_NR+1);
  253.         sentB = sentB + 1;
  254.         if(acktimerB==TRUE)
  255.         {
  256.         stoptimer(B,-1);
  257.         acktimerB = FALSE;
  258.     }
  259.         struct pkt packet = MsgToPkt(m,B);
  260.     addToBuffer(B, packet);
  261.         tolayer3(B,packet);
  262.         if(buffervol(B) == TRUE)
  263.                 onofflayer5(B,OFF);
  264. }
  265. static void A_input(struct pkt p)
  266. {
  267.         if (p.checksum == Checksum(p.seqnum, p.acknum, p.mes))
  268.         {
  269.                 if (p.seqnum >= 0)
  270.                 {
  271.                         if (p.seqnum != seqnumA2)
  272.                         {
  273.                                 //resend ack
  274.                         }
  275.                         else
  276.                         {
  277.                                 seqnumA2 = (seqnumA2+1) % (MAX_SEQ_NR+1);
  278.                                 ackA = receivedA + 1;
  279.                                 receivedA = (receivedA+1) % (MAX_SEQ_NR+1);
  280.                                 tolayer5(A,p.mes);
  281.                                 if(acktimerA == FALSE)
  282.                                 {
  283.                                         starttimer(A,-1,TO_ACK);
  284.                                         acktimerA = TRUE;
  285.                                 }
  286.                         }
  287.                 }
  288.                 if(p.acknum > 0)
  289.                 {
  290.                         int recAck;
  291.                         recAck = (p.acknum-1) % (MAX_SEQ_NR+1);
  292.                         deletePacket(A,recAck);
  293.                 }
  294.                 if(p.acknum < 0)
  295.                 {
  296.                         int recAck;
  297.                         recAck = ((0-p.acknum)-2) % (MAX_SEQ_NR+1);
  298.                         deletePacket(A,recAck);
  299.                         resend(A);
  300.                 }
  301.         }
  302.         else
  303.         {
  304.                 ackA = 0-(receivedA+1);
  305.                 if(acktimerA == FALSE)
  306.                 {
  307.                         starttimer(A,-1,TO_ACK);
  308.                         acktimerA = TRUE;
  309.                 }
  310.         }
  311. }
  312. static void B_input(struct pkt p)
  313. {
  314.         if (p.checksum == Checksum(p.seqnum, p.acknum, p.mes))
  315.         {
  316.                 if (p.seqnum >= 0)
  317.                 {
  318.                         if (p.seqnum != seqnumB2)
  319.                         {
  320.                                 //resend ack
  321.                         }
  322.                         else
  323.                         {
  324.                                 seqnumB2 = (seqnumB2+1) % (MAX_SEQ_NR+1);
  325.                                 ackB = receivedB + 1;
  326.                                 receivedB = (receivedB+1) % (MAX_SEQ_NR+1);
  327.                                 tolayer5(B,p.mes);
  328.                                 if(acktimerB == FALSE)
  329.                                 {
  330.                                         starttimer(B,-1,TO_ACK);
  331.                                         acktimerB = TRUE;
  332.                                 }
  333.                         }
  334.                 }
  335.                 if(p.acknum > 0)
  336.                 {
  337.                         int recAck;
  338.                         recAck = (p.acknum-1) % (MAX_SEQ_NR+1);
  339.                         deletePacket(B,recAck);
  340.                 }
  341.                 if(p.acknum < 0)
  342.                 {
  343.                         int recAck;
  344.                         recAck = ((0-p.acknum)-2) % (MAX_SEQ_NR+1);
  345.                         deletePacket(B,recAck);
  346.                         resend(B);
  347.                 }
  348.         }
  349.         else
  350.         {
  351.                 ackB = 0-(receivedB+1);
  352.                 if(acktimerB == FALSE)
  353.                 {
  354.                         starttimer(B,-1,TO_ACK);
  355.                         acktimerB = TRUE;
  356.                 }
  357.         }
  358. }
  359. static void A_timerinterrupt(int tnum)
  360. {
  361.         if(tnum<0)
  362.         {
  363.         acktimerA = FALSE;
  364.         tolayer3(A,Ack(A));
  365.     }
  366. }
  367. static void B_timerinterrupt(int tnum)
  368. {
  369.         if(tnum<0)
  370.         {
  371.         acktimerB = FALSE;
  372.         tolayer3(B,Ack(B));
  373.     }
  374. }
  375. static void A_finish() {}
  376. static void B_finish() {}
  377. /*****************************************************************
  378. ***************** NETWORK EMULATION CODE STARTS BELOW ***********
  379. The code below emulates the layer 3 and below network environment:
  380.   - emulates the tranmission and delivery (possibly with bit-level corruption
  381.     and packet loss) of packets across the layer 3/4 interface
  382.   - handles the starting/stopping of timers, and generates timer
  383.     interrupts (resulting in calling students timer handler).
  384.   - generates message to be sent (passed from later 5 to 4)
  385.  
  386. The code is designed such that it can ran on nearly any machine that supports
  387. C, no use is made of UNIX features.
  388.  
  389. A exception might be the random number generator that is needed.
  390. That is placed in the function simrand() and should return a float with
  391. a flat distribution in the range [0,1].
  392. ******************************************************************/
  393. /****************************************************************************/
  394. /* simrand(): return a float in range [0,1].  The routine below is used to */
  395. /* isolate all random number generation in one location.  We assume that the*/
  396. /* system-supplied rand() function return an int in therange [0,mmm]        */
  397. /****************************************************************************/
  398. static float simrand()
  399. {
  400.   double mmm = RAND_MAX; /*2147483647; largest int  - MACHINE DEPENDENT!!!!!!!!   */
  401.   float x;                   /* individual students may need to change mmm */
  402.   x = rand()/mmm;            /* x should be uniform in [0,1] */
  403.   return(x);
  404. }
  405.  
  406. /****************************************************************************
  407. THERE IS NOT REASON THAT ANY STUDENT SHOULD HAVE TO READ OR UNDERSTAND
  408. THE CODE BELOW.  YOU SHOLD NOT TOUCH, OR REFERENCE (in your code) ANY
  409. OF THE DATA STRUCTURES BELOW.
  410. If you're interested in how I designed the emulator, you're welcome
  411. to look at the code.
  412. *****************************************************************************/
  413.  
  414. struct event {
  415.    double evtime;          /* event time, allow very long*/
  416.    int evtype;             /* event type code */
  417.    int eventity;           /* entity where event occurs */
  418.    int tnum;               /* number of the timer or dropped packet indicator */
  419.    struct pkt *pktptr;     /* ptr to packet (if any) assoc w/ this event */
  420.    struct event *prev;
  421.    struct event *next;
  422.  };
  423. static struct event *evlist = NULL;   /* the event list */
  424.  
  425. /* possible events: */
  426. #define  TIMER_INTERRUPT 0  
  427. #define  FROM_LAYER5     1
  428. #define  FROM_LAYER3     2
  429.  
  430.  
  431. static int nsimmax = 10;           /* number of msgs to generate, then stop */
  432. static float lossprob = 0.1;      /* probability that a packet is dropped  */
  433. static float corruptprob=0.1;     /* probability that one bit is packet is flipped */
  434. static float lambda=1000.0;       /* arrival rate of messages from layer 5 */  
  435. static int TRACE=0; /* Trace level, set at command line
  436.      >= 3: print when packet is lost or currupted
  437.      >= 4: print events in main loop, used to call the student written functions
  438.      >= 5: print a lot of details
  439.   */
  440.  
  441. static double simtime = 0.000;  /* current simulation time */
  442. static int OOA=OFF, OOB=OFF;   /* turn Layer5 OFF */
  443.  
  444. static int nsim = 0;              /* number of messages from 5 to 4 so far */
  445. static int nrec = 0;              /* number received on layer 5 so far */
  446. static int nsimA=0, nsimB=0, nrecA=0, nrecB=0; /* detailed per A and B */
  447. static int seqA = -1, seqB = -1; /* last encoded sequence number received */
  448. static int okA = 1, okB = 1; /* order of receiving is correct */
  449.  
  450. static int nrestartA=0, nrestartB=0; /* number of starts of running timer */
  451. static int nstopA=0, nstopB=0;       /* number of stops of not-running timer */
  452. static int ntoA=0, ntoB=0;           /* number of timeouts */
  453.  
  454. static int nto3A=0, nto3B=0;           /* number sent into layer 3 */
  455. static int nlostA=0, nlostB=0;         /* number lost in media */
  456. static int ncorA=0, ncorB=0;           /* number corrupted by media*/
  457.  
  458. static void generate_next_arrival();
  459. static void insertevent(struct event *p);
  460. static float simrand();
  461.  
  462. static void init(int argc, char *argv[])    /* initialize the simulator */
  463. {
  464.   int i;
  465.   float sum, avg;
  466.   int count[10], k;
  467. #define SIMRC 10000
  468.  
  469.    printf("-----  Link level Network Simulator Version 2 -------- n");
  470.    printf(" %s n",(BIDIRECTIONAL == 1)?"Bidirectional":"Only A to B");
  471.    srand(9999);              /* init random number generator */
  472. /* test random number generator for students */
  473.    sum = 0.0;
  474.    for(i=0; i < 10; i++) count[i] = 0;
  475.    for (i=0; i<SIMRC; i++) {
  476.       avg = simrand();    /* simrand() should be uniform in [0,1] */
  477.       k= avg * 10; if( k < 0) k =0; else if(k > 9) k = 9;
  478.       count[k]++;
  479.       sum += avg;
  480.    }
  481.    avg = sum/SIMRC;
  482. /*for(i=0; i < 10; i++) printf("%d ",count[i]);
  483. printf("n avg: %fn",avg); */
  484.    k=0;
  485.    for(i=0; i < 10; i++) if ( count[i] < 0.09 * SIMRC || count[i] > 0.11 *SIMRC) k++;
  486.    if (avg < 0.45 || avg > 0.55 || k > 0) {
  487.     printf("It is likely that random number generation on your machinen" );
  488.     printf("is different from what this emulator expects.  Please taken");
  489.     printf("a look at the routine simrand() in the emulator code. Sorry. n");
  490.     printf(" average of %d calls: %fn Per bin of 0.1:n",SIMRC,avg);
  491.     for(i=0; i < 10; i++) printf("%d ",count[i]);
  492.     printf("n");
  493.     exit(1);
  494.     }
  495.  if(argc == 1) {
  496.    printf("Enter the number of messages to simulate: ");
  497.    scanf("%d",&nsimmax);
  498.    printf("Enter  packet loss probability [enter 0.0 for no loss]:");
  499.    scanf("%f",&lossprob);
  500.    printf("Enter packet corruption probability [0.0 for no corruption]:");
  501.    scanf("%f",&corruptprob);
  502.    printf("Enter average time between messages from sender's layer5 [ > 0.0]:");
  503.    scanf("%f",&lambda);
  504.    printf("Enter TRACE:");
  505.    scanf("%d",&TRACE);
  506.  } else {
  507.    if(argc >6) argc=6;
  508.    switch (argc) {
  509.     case 6: TRACE= atoi(argv[5]);
  510.     case 5: lambda = atof(argv[4]);
  511.     case 4: corruptprob = atof(argv[3]);
  512.     case 3: lossprob = atof(argv[2]);
  513.     case 2: nsimmax = atof(argv[1]);
  514.    }
  515.  }
  516.  if(nsimmax <=0 ) {
  517.    printf("nsinmax %d should be >0 n",nsimmax); exit(1);
  518.  }
  519.  if( lossprob <0.0 || lossprob >= 1.0) {
  520.    printf("loss prob %f should be >=0.0 and <1.0n",lossprob); exit(1);
  521.  }
  522.  if( corruptprob <0.0 || corruptprob >= 1.0) {
  523.    printf("corrupt prob %f should be >=0.0 and <1.0n",corruptprob); exit(1);
  524.  }
  525.  if(lambda <= 0 ) {
  526.    printf("average time %f should be >0.0 n",lambda); exit(1);
  527.  }
  528.  
  529.    generate_next_arrival(A);     /* initialize event list */
  530.    if (BIDIRECTIONAL ) generate_next_arrival(B);
  531. }
  532.  
  533. static void simprcont(struct msg mes)
  534. {
  535.   int i;
  536.    for (i=0; i<16; i++) printf("%c", isprint(mes.data[i])?mes.data[i]:'*');
  537.    i = ((mes.data[16]*256 + mes.data[17])*256 + mes.data[18])*256 + mes.data[19];
  538.    printf(" NR: %dn", i);
  539. }
  540.  
  541. static void simprpacket(struct pkt *p)
  542. {
  543.    printf("seq: %d, ack %d, ch: %d ", p->seqnum, p->acknum,  p->checksum);
  544.    simprcont(p->mes);
  545. }
  546.  
  547. /********************* EVENT HANDLINE ROUTINES *******/
  548. /*  The next set of routines handle the event list   */
  549. /*****************************************************/
  550.  
  551. static void generate_next_arrival(int AorB)
  552. {
  553.  float  x;
  554.  struct event *evptr;
  555.  
  556.  x = lambda*(0.5 +simrand() );  /* x is uniform on [0.5*lambda, 1.5*lambda] */
  557.  evptr = (struct event *)malloc(sizeof(struct event));
  558.  evptr->evtime =  simtime + x;
  559.  evptr->evtype =  FROM_LAYER5;
  560.  
  561. /* if (BIDIRECTIONAL && (simrand()>0.5) ) evptr->eventity = B;
  562.  else evptr->eventity = A;
  563. */
  564.  evptr->eventity = AorB;
  565.  if (TRACE>4) printf("          GENERATE NEXT MESSAGE for %c at %fn",
  566.           (evptr->eventity == A)?'A':'B',evptr->evtime);
  567.  insertevent(evptr);
  568. }
  569.  
  570.  
  571. static void insertevent(struct event *p)
  572. {
  573.    struct event *q,*qold;
  574.  
  575. /*   if (TRACE>4) printf("             INSERTEVENT: time: %f,future time: %fn",
  576.                    simtime,p->evtime);*/
  577.  
  578.    q = evlist;     /* q points to header of list in which p struct inserted */
  579.    if (q==NULL) {   /* list is empty */
  580.         evlist=p;
  581.         p->next=NULL;
  582.         p->prev=NULL;
  583.         }
  584.      else {
  585.         for (qold = q; q !=NULL && p->evtime >= q->evtime; q=q->next) qold=q;
  586.         if (q==NULL) {   /* end of list */
  587.              qold->next = p;
  588.              p->prev = qold;
  589.              p->next = NULL;
  590.              }
  591.            else if (q==evlist) { /* front of list */
  592.              p->next=evlist;
  593.              p->prev=NULL;
  594.              p->next->prev=p;
  595.              evlist = p;
  596.              }
  597.            else {     /* middle of list */
  598.              p->next=q;
  599.              p->prev=q->prev;
  600.              q->prev->next=p;
  601.              q->prev=p;
  602.              }
  603.          }
  604. }
  605.  
  606. static void printevlist()  /* currently not called */
  607. {
  608.   struct event *q;
  609.  
  610. /*  printf("--------------  Event List Follows:n");*/
  611.   for(q = evlist; q!=NULL; q=q->next) {
  612.     printf("EV %f, t: %d entity: %c ",q->evtime,q->evtype,
  613.            (q->eventity==A)?'A':'B');
  614.     if(q->evtype == TIMER_INTERRUPT) printf("%dn",q->tnum);
  615.     else if(q->evtype ==FROM_LAYER3) simprpacket(q->pktptr);
  616.     else printf("n");
  617.   }
  618. /*  printf("--------------n");*/
  619. }
  620.  
  621.  
  622. /********************** Student-callable ROUTINES ***********************/
  623.  
  624. static double gettime() { return simtime;}
  625.  
  626. static void onofflayer5(int AorB, int ONorOFF)
  627. {
  628.  if(AorB == A) OOA = ONorOFF;
  629.  else OOB = ONorOFF;
  630. }
  631.  
  632. /* called by students routine to cancel a previously-started timer */
  633. static void stoptimer( int AorB, int tnum)
  634. {
  635.  struct event *q;
  636.  
  637.  if (TRACE>4)
  638.     printf("          STOP TIMER: %c %d at %fn",(AorB==A)?'A':'B', tnum,simtime);
  639.  
  640.  for (q=evlist; q!=NULL ; q = q->next)
  641.     if ( q->evtype==TIMER_INTERRUPT  && q->eventity==AorB && q->tnum == tnum ) {
  642.        /* remove this event */
  643.        if (q->next==NULL && q->prev==NULL)
  644.              evlist=NULL;         /* remove first and only event on list */
  645.           else if (q->next==NULL) /* end of list - there is one in front */
  646.              q->prev->next = NULL;
  647.           else if (q==evlist) { /* front of list - there must be event after */
  648.              q->next->prev=NULL;
  649.              evlist = q->next;
  650.              }
  651.            else {     /* middle of list */
  652.              q->next->prev = q->prev;
  653.              q->prev->next =  q->next;
  654.              }
  655.        free(q);
  656.        return;
  657.      }
  658.  if(AorB==A) {
  659.   nstopA++;
  660.   if(nstopA==1) {
  661.     printf("PANIC cannot stop timer A %d, it is not runningn",tnum);
  662.     printf("       this message is given only oncen");
  663.   }
  664.  } else {
  665.   nstopB++;
  666.   if(nstopB==1) {
  667.     printf("PANIC cannot stop timer B %d, it is not runningn",tnum);
  668.     printf("       this message is given only oncen");
  669.   }
  670.  }
  671. }
  672.  
  673.  
  674. static void starttimer(int AorB, int tnum, float increment)
  675. {
  676.  struct event *q;
  677.  struct event *evptr;
  678.  
  679.  if (TRACE>4)
  680.     printf("          START TIMER: %c %d at %f, incr %f, timeout: %fn",
  681.         (AorB==A)?'A':'B', tnum, simtime, increment, simtime+increment);
  682.  
  683.  /* be nice: check to see if timer is already started, if so, then  warn */
  684.    for (q=evlist; q!=NULL ; q = q->next)  
  685.     if ( q->evtype==TIMER_INTERRUPT  && q->eventity==AorB && q->tnum == tnum ) {
  686.                /* timer is already running */
  687.  if(AorB==A) {
  688.   nrestartA++;
  689.   if(nrestartA==1) {
  690.     printf("PANIC cannot start timer A %d, it is already runningn",tnum);
  691.     printf("       this message is given only oncen");
  692.   }
  693.  } else {
  694.   nrestartB++;
  695.   if(nrestartB==1) {
  696.     printf("PANIC cannot start timer B %d, it is already runningn", tnum);
  697.     printf("       this message is given only oncen");
  698.   }
  699.  }
  700.       return;
  701.       }
  702.  
  703. /* create future event for when timer goes off */
  704.    evptr = (struct event *)malloc(sizeof(struct event));
  705.    evptr->evtime =  simtime + increment;
  706.  
  707.    for (q=evlist; q!=NULL ; q = q->next)
  708.      if ( (q->evtype==TIMER_INTERRUPT  && q->eventity==AorB) )
  709.         if( evptr->evtime == q->evtime) { evptr->evtime += 0.1 ;}
  710.  
  711.    evptr->evtype =  TIMER_INTERRUPT;
  712.    evptr->eventity = AorB;
  713.    evptr->tnum = tnum;
  714.    insertevent(evptr);
  715. }
  716.  
  717.  
  718. /************************** TOLAYER3 ***************/
  719. static void tolayer3(int AorB, struct pkt packet)
  720. {
  721.  struct pkt *mypktptr;
  722.  struct event *evptr, *q;
  723.  double lastime, at;
  724.  float x;
  725.  int i;
  726.  char prAB;
  727.  
  728.  prAB= (AorB==A) ? 'A' : 'B';
  729.  (AorB==A) ? nto3A++ : nto3B++;
  730.  
  731.  if (TRACE>4)  {
  732.    printf("          TOLAYER3 %c: ", prAB);
  733.    simprpacket(&packet);
  734.  }
  735.  
  736. /* make a copy of the packet for the event list  */
  737.  mypktptr = (struct pkt *)malloc(sizeof(struct pkt));
  738.  *mypktptr = packet;
  739.  
  740. /* create future event for arrival of packet at the other side */
  741.   evptr = (struct event *)malloc(sizeof(struct event));
  742.   evptr->evtype =  FROM_LAYER3;   /* packet will pop out from layer3 */
  743.   evptr->eventity = (AorB==A) ? B : A; /* event occurs at other entity */
  744.   evptr->pktptr = mypktptr;       /* save ptr to my copy of packet */
  745. /* finally, compute the arrival time of packet at the other end. */
  746.  lastime = simtime;
  747.  for (q=evlist; q!=NULL ; q = q->next)
  748.      if ( (q->evtype==FROM_LAYER3  && q->eventity==evptr->eventity) )
  749.         lastime = q->evtime;
  750.  at = simtime + 10.0 + 20.0 * simrand();
  751.  if( at < lastime +2.0 ) at = lastime + 2.0; /* maximum 10 packets in pipeline */
  752.  evptr->evtime =  at;
  753.  evptr->tnum = 0;
  754.  
  755.  if (simrand() < lossprob)  {        /* simulate losses: */
  756.      (AorB==A) ? nlostA++ : nlostB++;
  757.      if (TRACE>2) printf("          TOLAYER3 %c: packet being lostn",prAB);
  758.      evptr->tnum = 1; /*other side should drop packet */
  759.  } else if (simrand() < corruptprob)  {         /* simulate corruption: */
  760.     (AorB==A) ? ncorA++ : ncorB++;
  761.     if ( (x = simrand()) < .75) mypktptr->mes.data[0]='Z'; /* corrupt payload*/
  762.     else if (x < .875) mypktptr->seqnum = packet.seqnum+1;
  763.     else mypktptr->acknum = packet.acknum+1;
  764.     if (TRACE>2) printf("          TOLAYER3 %c: packet being corruptedn",prAB);
  765.  }  
  766.  
  767.  if (TRACE>4) printf("          TOLAYER3 %c: arrival on other side %fn",prAB,
  768.        evptr->evtime);
  769.  insertevent(evptr);
  770. }
  771.  
  772. static void tolayer5(int AorB, struct msg mes)
  773. {
  774.   int nr;
  775.   nrec++;
  776. if(TRACE==0 /*&& (nrec%1000) == 0*/) { printf("%8dr",nrec); fflush(stdout);}
  777.   (AorB == A) ? nrecA++ : nrecB++ ;
  778.   nr = ((mes.data[16]*256 + mes.data[17])*256 + mes.data[18])*256 + mes.data[19];
  779.   if ( AorB == A ) {
  780.     if (nr != seqA+1 && okA == 1) {
  781.       printf("PANIC A received message %d should be %dn",nr, seqA+1);
  782.       printf("      this message is given only oncen");
  783.       okA=0;
  784.     }
  785.     seqA++;
  786.   } else {
  787.     if (nr != seqB+1 && okB == 1) {
  788.       printf("PANIC B received message %d should be %dn",nr, seqB+1);
  789.       printf("      this message is given only oncen");
  790.       okB=0;
  791.     }
  792.     seqB++;
  793.   }
  794.   if (TRACE>4) {
  795.      printf("          TOLAYER5 %c: data received: ",(AorB==A)?'A':'B');
  796.      simprcont(mes);
  797.    }
  798. }
  799.  
  800. /************************** MAIN ***************/
  801. main(int argc, char *argv[])
  802. {
  803.    struct event *ep;
  804.    struct msg  msg2give;
  805.    int side;
  806.    int i,j;
  807.  
  808.    init(argc, argv);
  809.    A_init();
  810.    B_init();
  811.    
  812.    while (1) {
  813. /*printevlist();*/
  814.       ep = evlist;            /* get next event to simulate */
  815.       if (ep == NULL) {
  816.            break;
  817.       }
  818.       evlist = evlist->next;        /* remove this event from event list */
  819.       if (evlist!=NULL) evlist->prev = NULL;
  820.       simtime = ep->evtime;        /* update time to next event time */
  821.       side = ep->eventity;
  822.       if (TRACE>=4) {
  823.         printf("nEVENT for %c time: %f type: ",(side==A)?'A':'B',simtime);
  824.         switch (ep->evtype) {
  825.           case TIMER_INTERRUPT: printf("Timerinterrupt %dn",ep->tnum); break;
  826.           case FROM_LAYER5:  printf("Fromlayer5 %sn",
  827.                   (side==A)?((OOA==OFF)?"OFF":"ON"):((OOB==OFF)?"OFF":"ON"));break;
  828.           case FROM_LAYER3:  printf("Fromlayer3n");
  829.                              printf("                      ");
  830.                              simprpacket(ep->pktptr);break;
  831.           default: printf("UNKNOWNn");
  832.         }
  833.       }
  834.  
  835.       if (ep->evtype == FROM_LAYER5 ) {
  836.         if( (side==A && OOA==OFF) || (side==B && OOB==OFF) ) {
  837.           if(evlist == NULL) {
  838.             printf("PANIC layer5 %c message is waiting butn",(side==A)?'A':'B');
  839.             printf("      layer is OFF and no other event is in the list.n");
  840.             printf("      No student code will be called which could switch ONn");
  841.             break;
  842.           } else {    /* put event back in */
  843.             ep->evtime = evlist->evtime + 0.05; /* with delay */
  844.             if( TRACE>=4) {
  845.                printf("                      ");
  846.                printf("message delayed untill %fn",ep->evtime);
  847.             }
  848.             insertevent(ep); ep=NULL; /* it should not be freed */
  849.           }
  850.         } else {
  851.           j = (side == A) ? nsimA : nsimB;
  852.           for (i=0; i<16; i++) msg2give.data[i] = 97 + (j%26);
  853.           msg2give.data[19] = j % 256; j = j/256;
  854.           msg2give.data[18] = j % 256; j = j/256;
  855.           msg2give.data[17] = j % 256; j = j/256;
  856.           msg2give.data[16] = j % 256;
  857.           if (TRACE>4) {
  858.                printf("          MAINLOOP: data given to %c_output: ",
  859.                                       (side == A)?'A':'B');
  860.                simprcont(msg2give);
  861.           }
  862.           if (side == A) nsimA++, A_output(msg2give);  
  863.           else nsimB++, B_output(msg2give);  
  864.           nsim++;
  865.           if(nsim < ( (BIDIRECTIONAL ==0) ? nsimmax : nsimmax-1 ) )
  866.                generate_next_arrival(side); /*  */
  867.         }
  868.       }
  869.  
  870.       else if (ep->evtype ==  FROM_LAYER3) {
  871.         if(ep->tnum == 0) {
  872.           if (side ==A)  A_input(*(ep->pktptr)); /* deliver packet by calling */
  873.           else           B_input(*(ep->pktptr)); /* appropriate entity */
  874.         }
  875.         free(ep->pktptr);          /* free the memory for packet */
  876.       }
  877.  
  878.       else if (ep->evtype ==  TIMER_INTERRUPT) {
  879.             if (side == A) ntoA++, A_timerinterrupt(ep->tnum);
  880.             else ntoB++, B_timerinterrupt(ep->tnum);
  881.       }
  882.  
  883.       else  printf("INTERNAL PANIC: unknown event type n");
  884.  
  885.       if(ep != NULL) free(ep);
  886.    }
  887.  
  888.    printf("n Terminated at time %fn",simtime);
  889.  
  890. if(nsimA==nrecB && nsimB==nrecA && okA==1 && okB==1 && nrestartA==0 && nrestartB == 0
  891.                 && nstopA==0 && nstopB==0 && nsim==nsimmax)
  892.    printf("Everything looks OKnn");
  893. else  printf("Something is wrong, check belownn");
  894.    printf("Requested messages from layer5: %dn",nsimmax);
  895.    printf(" send from layer5   %6d msgs, received at layer5   %6d msgsn",nsim, nrec);
  896.    printf(" send from layer5 A %6d msgs, received at layer5 B %6d msgsn",nsimA, nrecB);
  897.    printf(" send from layer5 B %6d msgs, received at layer5 A %6d msgsn",nsimB, nrecA);
  898.    printf("nOrder of received messages:n");
  899.    printf("   messages received at A are %s ordern",(okA==1)? "in" : "out of");
  900.    printf("   messages received at B are %s ordern",(okB==1)? "in" : "out of");
  901.    printf("nTimer usage:n");
  902.    printf("    timer A is started %d times while already runningn",nrestartA);
  903.    printf("    timer B is started %d times while already runningn",nrestartB);
  904.    printf("    timer A is stopped %d times while not runningn",nstopA);
  905.    printf("    timer B is stopped %d times while not runningn",nstopB);
  906.    printf("    number of timeouts: A %d  B %dn",ntoA,ntoB);
  907.    printf("nStatistics from layer 3:n");
  908.    printf("   send from layer3   %8d pkts, lost %8d, corrupted %8dn",
  909.      nto3A+nto3B, nlostA + nlostB, ncorA + ncorB);
  910.    printf("   send from layer3 A %8d pkts, lost %8d, corrupted %8dn",nto3A,nlostA, ncorA);
  911.    printf("   send from layer3 B %8d pkts, lost %8d, corrupted %8dn",nto3B,nlostB, ncorB);
  912.  
  913.    A_finish(); B_finish();
  914.  
  915. printf("n %d %f %f %f %dn",nsimmax, lossprob,corruptprob, lambda, TRACE);
  916. system("PAUSE");
  917.    return 0;
  918. }