Advertisement
Guest User

Untitled

a guest
Oct 22nd, 2014
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.36 KB | None | 0 0
  1. #include <string.h>
  2.  
  3. /* Statistics
  4.  * Do NOT change the name/declaration of these variables
  5.  * You need to set the value of these variables appropriately within your code.
  6.  * */
  7. int A_application = 0;
  8. int A_transport = 0;
  9. int B_application = 0;
  10. int B_transport = 0;
  11.  
  12. /* Globals
  13.  * Do NOT change the name/declaration of these variables
  14.  * They are set to zero here. You will need to set them (except WINSIZE) to some proper values.
  15.  * */
  16.  
  17. /* @ref Slide 3-63
  18.  * TimeoutInterval = EstimatedRTT + 4*DevRTT
  19.  * Since I don't have specific SampleRTTs I assume DevRTT = EstimatedRTT
  20.  * 5 time units there and back = 10 time units = EstimatedRTT
  21.  * Therefore TIMEOUT = 10 + 4*10 = 50 */
  22. float TIMEOUT = 50.0;
  23.  
  24. int WINSIZE;         //This is supplied as cmd-line parameter; You will need to read this value but do NOT modify it;
  25. int SND_BUFSIZE = 1000; //Sender's Buffer size
  26. int RCV_BUFSIZE = 1000; //Receiver's Buffer size
  27.  
  28. /* Needed variables */
  29. struct pkt* A_buf;
  30. int A_bufindex;
  31. int A_nextavailseqnum;
  32. int A_base;
  33. float *A_timers;
  34. int *A_acks;
  35. float A_timestep;
  36. int *B_acks;
  37. struct msg* B_msgs;
  38. int B_base;
  39.  
  40. /* Need to declare these interface functions to avoid conflicting type warnings */
  41. void tolayer3(int AorB, struct pkt packet);
  42. void starttimer(int AorB, float increment);
  43. void tolayer5(int AorB, char datasent[20]);
  44.  
  45. /* An additional function to evaluate the checksum
  46.  * @ref http://www.tutorialspoint.com/cprogramming/c_bitwise_operators.htm */
  47. int evalchecksum(packet)
  48.   struct pkt packet;
  49. {
  50.     int csum = packet.seqnum;
  51.     csum += packet.acknum;
  52.     int i, j;
  53.    
  54.     for (i=0; i<20; i+=4) {
  55.         for (j=0; j<4; j++) {
  56.             csum += ((int)packet.payload[i+j]) << 8*j;
  57.         }
  58.     }
  59.    
  60.     return (csum ^ 0xFFFFFFFF); //returns the one's complement
  61. }
  62.  
  63. /* @ref Text on pages 223-229 and Figures 3.24 and 3.25 on page 226 */
  64.  
  65. /* Called from layer 5, passed the data to be sent to other side */
  66. void A_output(message)
  67.   struct msg message;
  68. {
  69.     A_application++;
  70.    
  71.     //Buffer the packet
  72.     A_buf[A_bufindex].seqnum = A_bufindex;
  73.     A_buf[A_bufindex].checksum = evalchecksum(A_buf[A_bufindex]);
  74.     memcpy(A_buf[A_bufindex].payload, message.data, 20);
  75.     if (A_nextavailseqnum < (A_base + WINSIZE)) {
  76.         printf("Packet %d is being sent.\n", A_bufindex);
  77.         tolayer3(0, A_buf[A_bufindex]);
  78.         A_timers[A_bufindex] = TIMEOUT;
  79.         A_nextavailseqnum++;
  80.         A_transport++;
  81.     }
  82.     A_bufindex++;
  83. }
  84.  
  85. /* Called from layer 3, when a packet arrives for layer 4 */
  86. void A_input(packet)
  87.   struct pkt packet;
  88. {
  89.     if (evalchecksum(packet) == packet.checksum) {
  90.         printf("Packet %d is ACKed.\n", packet.acknum);
  91.         A_acks[packet.acknum] = 1;
  92.         while (A_acks[A_base]) {
  93.             A_base++;
  94.         }
  95.         A_timers[packet.acknum] = -1.0;
  96.        
  97.         //Send all the packets in the window
  98.         int i;
  99.         for (i=A_nextavailseqnum; (i<A_bufindex && i<(A_base + WINSIZE)); i++) {
  100.             printf("Packet %d is being sent.\n", i);
  101.             tolayer3(0, A_buf[i]);
  102.             A_timers[i] = TIMEOUT;
  103.             A_transport++;
  104.         }
  105.         A_nextavailseqnum = i;
  106.     }
  107. }
  108.  
  109. /* Called when A's timer goes off */
  110. void A_timerinterrupt()
  111. {
  112.     starttimer(0, A_timestep);
  113.     int i;
  114.     for (i=0; i<SND_BUFSIZE; i++) {
  115.         if (A_timers[i] >= 0) {
  116.             A_timers[i] -= A_timestep;
  117.             if (A_timers[i] < 0) {
  118.                 printf("Packet %d timed out! The packet is being resent.\n", i);
  119.                 tolayer3(0, A_buf[i]);
  120.                 A_timers[i] = TIMEOUT;
  121.                 A_transport++;
  122.             }
  123.         }
  124.     }
  125. }
  126.  
  127. /* The following routine will be called once (only) before any other */
  128. /* entity A routines are called. You can use it to do any initialization */
  129. void A_init()
  130. {
  131.     A_buf = malloc(SND_BUFSIZE * sizeof(struct pkt));
  132.     A_bufindex = 1;
  133.     A_nextavailseqnum = 1;
  134.     A_base = 1;
  135.     A_timers = malloc(SND_BUFSIZE);
  136.     A_acks = malloc(SND_BUFSIZE);
  137.     int i;
  138.     for (i=0; i<SND_BUFSIZE; i++) {
  139.         A_timers[i] = -1.0;
  140.         A_acks[i] = 0;
  141.     }
  142.     A_timestep = 5.0; //1 timestep is the average time it takes a packet to go from one side to the other
  143.     starttimer(0, A_timestep);
  144. }
  145.  
  146. /* Note that with simplex transfer from A-to-B, there is no B_output() */
  147. void B_output(message)  /* Needs to be completed only for extra credit */
  148.   struct msg message;
  149. {
  150.    
  151. }
  152.  
  153. /* Called from layer 3, when a packet arrives for layer 4 at B*/
  154. void B_input(packet)
  155.   struct pkt packet;
  156. {
  157.     B_transport++;
  158.     if (evalchecksum(packet) == packet.checksum) {
  159.         printf("Packet %d has been received and it's uncorrupted.\n", packet.seqnum);
  160.        
  161.         //Set up the ACK and send it
  162.         struct pkt ack;
  163.         ack.acknum = packet.seqnum;
  164.         ack.checksum = evalchecksum(ack);
  165.         printf("ACKing packet %d.\n", ack.acknum);
  166.         tolayer3(1, ack);
  167.         B_acks[packet.seqnum] = 1;
  168.        
  169.         //Store message
  170.         memcpy(B_msgs[B_base].data, packet.payload, 20);
  171.         while (B_acks[B_base]) {
  172.             printf("Sending message %d.\n", B_base);
  173.             tolayer5(1, B_msgs[B_base].data);
  174.             B_application++;
  175.             B_base++;
  176.         }
  177.     }
  178.     else {
  179.         printf("A corrupted packet from layer 3 has been received!\n");
  180.     }
  181. }
  182.  
  183. /* Called when B's timer goes off */
  184. void B_timerinterrupt()
  185. {
  186.    
  187. }
  188.  
  189. /* The following routine will be called once (only) before any other */
  190. /* entity B routines are called. You can use it to do any initialization */
  191. void B_init()
  192. {
  193.     B_acks = malloc(RCV_BUFSIZE);
  194.     B_msgs = malloc(RCV_BUFSIZE * sizeof(struct msg));
  195.     B_base = 1;
  196. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement