#include <stdio.h>
#include <stdlib.h>
#include "reseau.h"
#define SOURCE 26
#define DESTINATION 42
#define MAXRETRANSMISSION 10
#define FEMISSION "flux1.dat"
#define FRECEPTION "flux2.dat"
int erreurcrc=0;
void envoyer(ttrame Trame)
/* Envoie la trame Trame vers la couche physique en rajoutant si nécessaire des erreurs */
{
if ((erreurcrc!=0) && ((rand() % erreurcrc)==0))
{
Trame.CRC++;
envoyer_vers_couche_physique(Trame);
Trame.CRC--;
}
else envoyer_vers_couche_physique(Trame);
return;
}
char entre(int a, int b, int c)
{
return( ((a<=b)&&(b<c)) || ((c<a)&&(a<=b)) || ((b<c)&&(c<a)) );
}
int main(int argc, char **argv)
/* Programme principal, argument optionnel : quantité d'erreurs */
{
int AS,AD;
ttrame buffer[MAXTAILLEFENETRE];
int compteur[MAXTAILLEFENETRE];
int i, numack, ack_attendu=0, trame_a_emettre=0, nbuffer=0;
ttampon TamponEmission, tamponaux;
ttrame Trame;
char recepteur_pret=1;
if (argc>1) erreurcrc=atoi(argv[1]);
fprintf(stderr,"Initialisation du protocole 4, erreurcrc=%d\n",erreurcrc);
initialise_couche_physique(FEMISSION, FRECEPTION);
initialise_couche_reseau(SOURCE, DESTINATION);
while (1)
{
if (recepteur_pret && signale(SIGEMIS) && (nbuffer<MAXTAILLEFENETRE-1))
{
prendre_de_la_couche_reseau(&AS, &AD, &TamponEmission);
construire_trame(trame_a_emettre, AS, AD, TamponEmission, &buffer[trame_a_emettre]);
nbuffer++;
fprintf(stderr,"Envoi de trame %d : %d->%d, %s\n",trame_a_emettre,AS,AD,TamponEmission.info);
envoyer(buffer[trame_a_emettre]);
tempo(trame_a_emettre);
compteur[trame_a_emettre]=MAXRETRANSMISSION;
trame_a_emettre=(trame_a_emettre+1)%MAXTAILLEFENETRE;
}
if (signale(SIGTEMPO))
{
fprintf(stderr,"Timeout\n");
trame_a_emettre=ack_attendu;
for (i=0;i<nbuffer;i++)
{
if (compteur[trame_a_emettre]==0)
{
fprintf(stderr,"Trop d'erreurs de retransmission\n");
return(1);
}
fprintf(stderr,"Renvoi de trame %d : %d->%d, %s\n",trame_a_emettre,AS,AD,buffer[trame_a_emettre].tampon.info);
envoyer(buffer[trame_a_emettre]);
tempo(trame_a_emettre);
compteur[trame_a_emettre]--;
trame_a_emettre=(trame_a_emettre+1)%MAXTAILLEFENETRE;
}
}
if (signale(SIGRECU))
{
prendre_de_la_couche_physique(&Trame);
recuperer_donnees(Trame,&tamponaux,&numack,&AS,&AD);
fprintf(stderr,"ACK RECU %d, ACK ATTENDU %d, TRAME A EMETTRE %d\n",numack,ack_attendu,trame_a_emettre);
while (entre(ack_attendu,numack,trame_a_emettre))
{
fprintf(stderr,"Trame %d acquitee\n",ack_attendu);
nbuffer--;
stoptempo(ack_attendu);
ack_attendu=(ack_attendu+1)%MAXTAILLEFENETRE;
}
switch (tamponaux.info[0])
{
case 'R':{ if (recepteur_pret==0) fprintf(stderr,"RR recu\n"); recepteur_pret=1; break; }
case 'N':{ recepteur_pret=0; fprintf(stderr,"RNR recu\n"); break; }
}
}
}
return(0);
}