void B_input(struct pkt packet)
{

	//struct pkt new_packet_b;
	int my_checksum=0;
	B_transport++;

	my_checksum=packet.seqnum+packet.acknum;
	for(int i=0;i<20;i++)
		my_checksum+=packet.payload[i];
	memset(new_packet_b.payload,'\0',20);

	if(expectedseqno==0)
	{
		new_packet_b.seqnum=-1;
		new_packet_b.acknum=1;

		new_packet_b.checksum=new_packet_b.acknum+new_packet_b.seqnum;
		for(int i=0;i<20;i++)
			new_packet_b.checksum+=new_packet_b.payload[i];
	}

	if((my_checksum==packet.checksum )&& (packet.seqnum ==expectedseqno))//reject out of order packets
	{

		tolayer5(1,packet.payload);
		B_application++;
		new_packet_b.acknum=1;

		new_packet_b.seqnum=expectedseqno;
		new_packet_b.checksum=new_packet_b.acknum+new_packet_b.seqnum;
		for(int i=0;i<20;i++)
			new_packet_b.checksum+=new_packet_b.payload[i];
		tolayer3(1,new_packet_b);

		expectedseqno++;


	}
	else
	{


		tolayer3(1,new_packet_b);//to tell sender which packet is needed

	}


}
/*Sender State that handles acknowledgment*/
void A_Receiver_State(struct pkt packet)
{
	bool corrupt = isPacketCorrupt(packet.checksum,packet.seqnum,packet.acknum,packet.payload);
		int acknum = packet.acknum;

		if(!corrupt)
		{
			base = acknum+1;

			int endOfWindow = base +windowSize;
			//send all packets from nextseq to end of new windowsize which are in buffer
			while(nextSequenceNum<endOfWindow && nextSequenceNum<senderPacketCounter)
			{
					tolayer3(A,senderBuffer[nextSequenceNum]);
					nextSequenceNum++;
			}

			if(base==nextSequenceNum) //All acknowledgements have been have been received
			{
			stoptimer(A);
			}

			//one ack have been received, thus send one packet from new window
			else
			{
			stoptimer(A);
			starttimer(A,timeout);
			}
		}
}
示例#3
0
/*
 * B_input(packet),where packet is a structure of type pkt. This routine 
 * will be called whenever a packet sent from the A-side (i.e., as a result 
 * of a tolayer3() being done by a A-side procedure) arrives at the B-side. 
 * packet is the (possibly corrupted) packet sent from the A-side.
 */
void B_input(struct pkt packet) {
  struct pkt ack;
  if (iscorrupt(packet)) {
    return;
  }
  
  if (packet.acknum == DATAACK) {  
    if (!iscorrupt(packet) && packet.seqnum != Bexpectedseqnum) { //wrong seq num
      ack = Bpastack;
      tolayer3(BEntity,ack); 
      return;
    }
    if (!iscorrupt(packet) && packet.seqnum == Bexpectedseqnum) { //right seqnum
      ack.checksum = 0;
      ack.seqnum = packet.seqnum;
      ack.acknum = ACK;
      memcpy(ack.payload,packet.payload,MESSAGE_LENGTH);
      ack.checksum = genchecksum(ack);
      Bpastack = ack;
      tolayer3(BEntity,ack); 
      struct msg message;
      memcpy(message.data,packet.payload,MESSAGE_LENGTH); 
      tolayer5(BEntity,message);
      Bexpectedseqnum++;
      return; 
    }
  }
////new stuff  
  if (packet.acknum == ACK) {
    if (Bbase >= (packet.seqnum + 1)) {
      if (packet.seqnum + 1 == Bnextseqnum) {
	stopTimer(BEntity);
      }
      return;
    }
    Bbase = packet.seqnum + 1;
    if (Bbase == Bnextseqnum) {
      stopTimer(BEntity);
    }
    else {
      stopTimer(BEntity);
      startTimer(BEntity,TIMERAMT);
    }
  }
////old stuff  
  
}
/*Initial state of receiver side*/
void B_Initial_State(struct pkt packet)
{
	struct msg message;

	createMessageforLayer5(&packet,&message);

	bool corrupt = isPacketCorrupt(packet.checksum,packet.seqnum,packet.acknum,message.data);
	int seqnum = packet.seqnum;

	struct pkt datapacket; //creating packet containing acknowledgment
	int checksum=0;

	if(!corrupt && seqnum==expectedSeqNum)
	{
		int ack=expectedSeqNum; //send ack for received packet
		createDataPacket(&datapacket,0,ack,checksum,"");
		createCheckSum(&datapacket); //set checksum
		datapacket.acknum = expectedSeqNum; //re assigning value for correctness

		tolayer3(B,datapacket);
		tolayer5(B,message.data);

		int i;
					for(i=0;i<20;i++)
					{
						printf("%c",message.data[i]);
					}

					printf("\n");
		
		
		//printf("\nB SIDE : Printing Packet payload Sent Above %s\n",message.data);
		//printf("\nB SIDE : Printing Acknum %d sent from B to A \n",datapacket.acknum);

		//incrementing the expected sequence number
		expectedSeqNum++;
	}

	else //send previous acknowledgment
	{
				int ack =expectedSeqNum-1;
				createDataPacket(&datapacket,0,ack,checksum,"");
				createCheckSum(&datapacket); //set checksum
				datapacket.acknum = expectedSeqNum-1; //reassign for correctness
				tolayer3(B,datapacket);
	}
}
示例#5
0
void send_nack(int caller, struct pkt *pkt_to_nack)
{
    int seqnum = pkt_to_nack->seqnum;
    char msg[MSGSIZE] = {'N','A','C','K',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    struct pkt *nack_pkt = make_pkt(seqnum, msg);
    nack_pkt->acknum = 0;
    tolayer3(caller, *nack_pkt);
}
示例#6
0
struct pkt send_packet(int target, int seq, int ack, char* payload)
{
  struct pkt packet_out;
  packet_out = make_packet(seq, ack, payload);
  printf("%c: Sending packet (%d, %d, %d ,'%s')\n",(target == 0) ? 'A' : 'B' ,packet_out.seqnum, packet_out.acknum, packet_out.checksum, packet_out.payload);
  stats.packets_sent++;
  tolayer3(target, packet_out); //send out the built packet from A
  return packet_out;
}
示例#7
0
/*
 * A_timerinterrupt()  This routine will be called when A's timer expires 
 * (thus generating a timer interrupt). You'll probably want to use this 
 * routine to control the retransmission of packets. See starttimer() 
 * and stoptimer() in the writeup for how the timer is started and stopped.
 */
void A_timerinterrupt() {
  int i;
  for (i = Abase; i < (Anextseqnum - Abase - 1), i < (Abase + WINDOW_SIZE); i++) {
    if (Aglobalarray[i] == NULL) {
      //removed timer here
      return;
    }
    tolayer3(AEntity, *Aglobalarray[i]);
  }
  startTimer(AEntity, TIMERAMT);
  return;
}  
/*Initial Sender State*/
void A_Initial_State()
{
	//printf("before if loop nextseq %d, base+window %d\n",nextSequenceNum,(base+windowSize));
		if(nextSequenceNum<(base+windowSize))
		{
			//printf("Entered if loop\n");
			tolayer3(A,senderBuffer[nextSequenceNum]);
			if(base==nextSequenceNum)
				starttimer(A,timeout);
			nextSequenceNum++;
		}

}
/*Function sends packets in between the window base and (nextSeqNum-1)
 * It is called during timeout of oldest unAcknowledged packet*/
void reSendAllIntermediatePackets()
{
	int i;
	int tempBase =base;
	int msgCount = nextSequenceNum-base-1; //number of packets to be sent
	//printf("msgcount value %d\n",msgCount);
	for(i=0;i<msgCount;i++)
	{
		//printf("tempBase value %d\n",tempBase);
		tolayer3(A,senderBuffer[tempBase]);
		//printf("^^^^^^^^^^^^^^^^^^^^^ RESENT MESSAGES %s\n",senderBuffer[tempBase].payload);
		tempBase++;
	}
}
示例#10
0
/*
 * B_timerinterrupt()  This routine will be called when B's timer expires 
 * (thus generating a timer interrupt). You'll probably want to use this 
 * routine to control the retransmission of packets. See starttimer() 
 * and stoptimer() in the writeup for how the timer is started and stopped.
 */
void  B_timerinterrupt() {
  ////new stuff
  int i;
  for (i = Bbase; i < (Bnextseqnum - Bbase - 1), i < (Bbase + WINDOW_SIZE); i++) {
    if (Bglobalarray[i] == NULL) {
      //removed timer here
      return;
    }
    tolayer3(BEntity, *Bglobalarray[i]);
  }
  startTimer(BEntity, TIMERAMT);
  return;
  ////old stuff
}
/* called when A's timer goes off */
void A_timerinterrupt() //ram's comment - changed the return type to void.
{
	//printf("\n in A_timerinterrupt.. Calling startimer");
	starttimer(0,TIMEOUT);
	timer_A_started=1;
	int i;

	for(i=base;i<nextseqnum;i++)// send packets in window
	{
		tolayer3(0,my_packet[i]);
		A_transport++;
	}

}
/*Initial state of receiver side*/
void B_Initial_State(struct pkt packet) {
	struct msg message;

	createMessageforLayer5(&packet, &message);

	bool corrupt = isPacketCorrupt(packet.checksum, packet.seqnum,
			packet.acknum, message.data);
	int seqnum = packet.seqnum;

	struct pkt datapacket; //creating packet containing acknowledgment
	int checksum = 0;

	if (!corrupt) {

		//send ack for all packets lying under below range
		if (seqnum >= (receiverBase - receiverWindowSize)
				&& seqnum <= (receiverBase + receiverWindowSize - 1)) {

			int ack = seqnum; //send ack for received packet
			createDataPacket(&datapacket, 0, ack, checksum, "");
			createCheckSum(&datapacket); //set checksum
			datapacket.acknum = seqnum; //re assigning value for correctness

			tolayer3(B, datapacket); //this is done irrespective of any action

			//printf("\nB SIDE : Printing Acknum %d sent from B to A \n",
				//	datapacket.acknum);

			B_StoreMessageInReceiverBuffer(seqnum, &message); //marks AckSent as true

		}

		//for values lying under current window
		if (seqnum >= receiverBase
				&& seqnum <= (receiverBase + receiverWindowSize - 1)) {

			/* Handling data sent to layer5*/
			int returnVal = returnNextMaximumContiguousSequenceAcknowledged(B);

			if (returnVal != -1) {
				sendMessagestoLayer5(returnVal);
			}

		}

	} //Un_corrupt packet Loop Ends

}
/*Function sends packet with "Id" nextSeqNumber, Also add event to timer List*/
void A_sendPacket(int sequence) {

	insertLinkedList(sequence, get_sim_time());

	tolayer3(A, senderBuffer[sequence]);

	//printf("Packet sent from A to B Sequence Number : %d \n",sequence);

	if (nextSequenceNum == base) //whenever it starts fresh after receiving all Acks, start the timer
		{
		//printf("TIMER HAS BEEN STARTED at %f\n",get_sim_time());
		//stoptimer(A);
		starttimer(A, timeout);
		}

}
示例#14
0
/* called when A's timer goes off */
void A_timerinterrupt(void)
{
  int i;

  if (TRACE > 0)
    printf("----A: time out,resend packets!\n");

  for(i=0; i<windowcount; i++) {

    if (TRACE > 0)
      printf ("---A: resending packet %d\n", (buffer[(windowfirst+i) % WINDOWSIZE]).seqnum);

    tolayer3(A,buffer[(windowfirst+i) % WINDOWSIZE]);
    packets_resent++;
    if (i==0) starttimer(A,RTT);
  }
}       
示例#15
0
void A_output(struct msg message) {
  Atemp = (struct pkt*) malloc(sizeof(struct pkt));
  memcpy(Atemp->payload,message.data,MESSAGE_LENGTH);
  Atemp->seqnum = Anextseqnum;
  Atemp->acknum = DATAACK;
  Atemp->checksum = 0;
  Atemp->checksum = genchecksum(*Atemp);
  Aglobalarray[Anextseqnum] = Atemp;
  if (Anextseqnum < (Abase + WINDOW_SIZE)) { //(!getTimerStatus( AEntity )) { //will succeed if timer is off
    tolayer3(AEntity,*Atemp);
    if (Abase == Anextseqnum) {
      startTimer(AEntity,TIMERAMT);
    }
  }
  Anextseqnum++;
  return;
}
示例#16
0
/* called from layer 3, when a packet arrives for layer 4 at B*/
void B_input(struct pkt packet)
{
  struct pkt sendpkt;
  int i;

  /* if not corrupted and received packet is in order */
  if  ( (!IsCorrupted(packet))  && (packet.seqnum == expectedseqnum) ) {
    if (TRACE > 0)
      printf("----B: packet %d is correctly received, send ACK!\n",packet.seqnum);
    packets_received++;

    /* deliver to receiving application */
    tolayer5(B, packet.payload);

    /* send an ACK for the received packet */
    sendpkt.acknum = expectedseqnum;

    /* update state variables */
    expectedseqnum = (expectedseqnum + 1) % SEQSPACE;        
  }
  else {
    /* packet is corrupted or out of order resend last ACK */
    if (TRACE > 0) 
      printf("----B: packet corrupted or not expected sequence number, resend ACK!\n");
    if (expectedseqnum == 0)
      sendpkt.acknum = SEQSPACE - 1;
    else
      sendpkt.acknum = expectedseqnum - 1;
  }

  /* create packet */
  sendpkt.seqnum = B_nextseqnum;
  B_nextseqnum = (B_nextseqnum + 1) % 2;
    
  /* we don't have any data to send.  fill payload with 0's */
  for ( i=0; i<20 ; i++ ) 
    sendpkt.payload[i] = '0';  

  /* computer checksum */
  sendpkt.checksum = ComputeChecksum(sendpkt); 

  /* send out packet */
  tolayer3 (B, sendpkt);
}
示例#17
0
/* called from layer 5 (application layer), passed the message to be sent to other side */
void A_output(struct msg message)
{
  struct pkt sendpkt;
  int i;

  /* if not blocked waiting on ACK */
  if ( windowcount < WINDOWSIZE) {
    if (TRACE > 1)
      printf("----A: New message arrives, send window is not full, send new messge to layer3!\n");

    /* create packet */
    sendpkt.seqnum = A_nextseqnum;
    sendpkt.acknum = NOTINUSE;
    for ( i=0; i<20 ; i++ ) 
      sendpkt.payload[i] = message.data[i];
    sendpkt.checksum = ComputeChecksum(sendpkt); 

    /* put packet in window buffer */
    /* windowlast will always be 0 for alternating bit; but not for GoBackN */
    windowlast = (windowlast + 1) % WINDOWSIZE; 
    buffer[windowlast] = sendpkt;
    windowcount++;

    /* send out packet */
    if (TRACE > 0)
      printf("Sending packet %d to layer 3\n", sendpkt.seqnum);
    tolayer3 (A, sendpkt);

    /* start timer if first packet in window */
    if (windowcount == 1)
      starttimer(A,RTT);

    /* get next sequence number, wrap back to 0 */
    A_nextseqnum = (A_nextseqnum + 1) % SEQSPACE;  
  }
  /* if blocked,  window is full */
  else {
    if (TRACE > 0)
      printf("----A: New message arrives, send window is full\n");
    window_full++;
  }
}
/* called from layer 5, passed the data to be sent to other side */
void A_output(struct msg message) //ram's comment - students can change the return type of the function from struct to pointers if necessary
{



	//Buffer 1000 packets, used it to send when window moves ahead
	if(SND_BUFSIZE<1000)
	{
		A_application++;

		strncpy(buffer[SND_BUFSIZE].data, message.data,20);
		SND_BUFSIZE++;
	}

	if(nextseqnum<(base+WINSIZE)){


		struct pkt packet_a;
		strncpy(packet_a.payload,buffer[nextseqnum].data,20);

		packet_a.seqnum=nextseqnum;
		packet_a.acknum=-1;//it is not acknowledgment
		packet_a.checksum=packet_a.seqnum+packet_a.acknum;
		for(int i=0;i<20;i++)
			packet_a.checksum+=packet_a.payload[i];

		my_packet[my_packet_no++]=packet_a;
		tolayer3(0,packet_a);
		A_transport++;


		if(base==nextseqnum)
		{

			starttimer(0,TIMEOUT);
			timer_A_started=1;
		}
		nextseqnum++;
	}


}
示例#19
0
/*
 * Just like A_output, but residing on the B side.  USED only when the 
 * implementation is bi-directional.
 */
void B_output(struct msg message)  {
//////new stuff
  Btemp = (struct pkt*) malloc(sizeof(struct pkt));
  memcpy(Btemp->payload,message.data,MESSAGE_LENGTH);
  Btemp->seqnum = Bnextseqnum;
  Btemp->acknum = DATAACK;
  Btemp->checksum = 0;
  Btemp->checksum = genchecksum(*Btemp);
  Bglobalarray[Bnextseqnum] = Btemp;
  if (Bnextseqnum < (Bbase + WINDOW_SIZE)) { //(!getTimerStatus( AEntity )) { //will succeed if timer is off
    tolayer3(BEntity,*Btemp);
    if (Bbase == Bnextseqnum) {
      startTimer(BEntity,TIMERAMT);
    }
  }
  Bnextseqnum++;
  return;
/////old stuff  

}
示例#20
0
文件: student2B.c 项目: byliuyang/ABP
/*
 * B_input(packet),where packet is a structure of type pkt. This routine 
 * will be called whenever a packet sent from the A-side (i.e., as a result 
 * of a tolayer3() being done by a A-side procedure) arrives at the B-side. 
 * packet is the (possibly corrupted) packet sent from the A-side.
 */
void B_input(struct pkt packet) {
	struct msg message; // Store message retrived from network
	struct pkt ack; // Store ack packet

    // Pass message to layer 5 when it not corrupted and when it has expected seqnum
	if (not_corrupted(packet) && (packet.seqnum == rev_seqnum)) {
		strncpy(message.data, packet.payload, MESSAGE_LENGTH);
		tolayer5(BEntity, message);

		// Make ack message
		ack = prepare_pkt(1, rev_seqnum, NULL);
		// flip expected sequence number of packet
		rev_seqnum = !rev_seqnum;
	} else {
		// Make ack message
		ack = prepare_pkt(1, !rev_seqnum, NULL);
	}
	// Send ack message
	tolayer3(BEntity, ack);
}
示例#21
0
void send_pkt(int caller, struct pkt *pkt_to_send)
{
    tolayer3(caller, *pkt_to_send);
    starttimer(caller, TIMEOUT);
}
/* called from layer 3, when a packet arrives for layer 4 */
void A_input(struct pkt packet)
{
	/*printf("\nIn a_input");
	printf("\n Packet details- seqnum %d acknum %d checksum  %d payload %s \n", packet.seqnum, 
packet.acknum, packet.checksum, packet.payload);*/
	int my_checksum=packet.seqnum+packet.acknum;
	for(int i=0;i<20;i++)

		my_checksum+=packet.payload[i];
	//if ((my_checksum==packet.checksum))
	if ((my_checksum==packet.checksum) )
	{

		if(base != (packet.seqnum+1))
		{
			base=packet.seqnum+1;//move window ahead

			if(base==nextseqnum)
			{
				if(timer_A_started==1)
				{
					stoptimer(0);
					timer_A_started=0;
				}
			}
			else
			{
				if(timer_A_started==1)
				{

					stoptimer(0);
					timer_A_started=0;
				}

				starttimer(0,TIMEOUT);
				timer_A_started=1;
			}
		}
		//transmit all buffered packets if are in window
		int buf_index=base;

		while((nextseqnum<(base+WINSIZE)) && (nextseqnum< SND_BUFSIZE)){


			printf("\n**********Sending packet in A_input");
			struct pkt packet_a;
			strncpy(packet_a.payload,buffer[nextseqnum].data,20);

			packet_a.seqnum=nextseqnum;
			packet_a.acknum=-1;//it is not acknowledgment
			packet_a.checksum=packet_a.seqnum+packet_a.acknum;
			for(int i=0;i<20;i++)
				packet_a.checksum+=packet_a.payload[i];

			my_packet[my_packet_no++]=packet_a;
			tolayer3(0,packet_a);
			A_transport++;
			if(base==nextseqnum)
			{
				//printf("\nCalling startimer");
				starttimer(0,TIMEOUT);
				timer_A_started=1;
			}
			nextseqnum++;
		}

	}
}