/* called from layer 3, when a packet arrives for layer 4 */ void A_input(struct pkt packet) { printf("CCH> A_input> Got packet\n"); // isChecksumValid if(pkt_checksum_valid(&packet)) { printf("CCH> A_input> Valid checksum\n"); // isACK if(strncmp(packet.payload, ACK, strlen(ACK)) == 0) { if(packet.acknum == last_pkt->seqnum) { printf("CCH> A_input> Received valid ACK\n"); last_ack = &packet; stoptimer(A); } else { // We received an ACK we don't care about printf("CCH> A_input> Received invalid ACK (ignoring)\n"); } // isNACK } else if (strncmp(packet.payload, NACK, strlen(ACK)) == 0) { printf("CCH> A_input> Received NACK\n"); send_pkt(A, last_pkt); } else { // Message stoptimer(A); tolayer5(A, packet.payload); } } else { printf("CCH> A_input> Invalid checksum\n"); send_nack(A, &packet); stoptimer(A); starttimer(A, TIMEOUT); return; } }
/* called from layer 3, when a packet arrives for layer 4 at B*/ void B_input(struct pkt packet) { printf("CCH> B_input> Got packet\n"); // Send ACK send_ack(B, &packet); // Pass message to layer 5 tolayer5(B, packet.payload); }
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 } }
/* * 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); } }
/* 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); }
/* * 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); }
/*Function send packets to layer5, using the value returned by function returnNextMaximumContiguousSequenceAcknowledged()*/ void sendMessagestoLayer5(int tillThisPacket) { int startOfWindow = receiverBase; while (startOfWindow <= tillThisPacket) { if (ackSent[startOfWindow] != 2) { tolayer5(B, receiverBuffer[startOfWindow].data); //printf("#B SIDE : Printing Packet payload Sent Above %s with a size of %zu\n", // receiverBuffer[startOfWindow].data,sizeof(receiverBuffer[startOfWindow].data)); //printf("Previous Receiver Base value is : %d and New receiver base value is %d\n",receiverBase,receiverBase+1); receiverBase++; //every time you send a message, increment receiver base ackSent[startOfWindow] = 2; } startOfWindow++; } }