#include <stdio.h>
#include <string.h>
#include "reseau.h"
time_t dt[MAXTAILLEFENETRE];
static int asource,adest;
static char *femission, *freception;
void prendre_de_la_couche_reseau(int *AS, int *AD, ttampon *T)
/* Lecture des données sur stdin, on quitte s'il n'y a plus rien à lire */
{
if (fgets(T->info,MAXTAILLETAMPON,stdin)==NULL)
{
printf("Plus de donnees a envoyer\n");
exit(0);
}
T->taille=strlen(T->info);
*AS=asource;
*AD=adest;
return;
}
void construire_trame(int num, int AS, int AD, ttampon T, ttrame *Trame)
/* Construit la trame à partir du tampon, du numéro de séquence et des adresses,
et insère le CRC */
{
Trame->num=num;
Trame->AS=AS;
Trame->AD=AD;
Trame->tampon=T;
Trame->CRC=calcule_CRC(*Trame);
return;
}
void envoyer_vers_couche_physique(ttrame Trame)
/* Envoie la trame sur le support physique */
{
FILE *f;
while ((f=fopen(femission,"ab"))==NULL);
fwrite(&Trame,sizeof(ttrame),1,f);
fclose(f);
return;
}
void prendre_de_la_couche_physique(ttrame *Trame)
/* Récupère la trame sur le support physique */
{
FILE *f, *temp;
char auxnom[15]="tmp";
ttrame aux;
while ((f=fopen(freception,"rb"))==NULL);
fread(Trame,sizeof(ttrame),1,f);
strcat(auxnom,freception);
temp=fopen(auxnom,"wb");
while (fread(&aux,sizeof(ttrame),1,f)>0)
fwrite(&aux,sizeof(ttrame),1,temp);
fclose(f);
fclose(temp);
remove(freception);
rename(auxnom,freception);
return;
}
void recuperer_donnees(ttrame Trame, ttampon *T, int *num, int *AS, int *AD)
/* Extraire le tampon, le numéro de séquence et les adresses de la trame */
{
*T=Trame.tampon;
*num=Trame.num;
*AS=Trame.AS;
*AD=Trame.AD;
return;
}
void envoyer_vers_couche_reseau(ttampon T, int AS, int AD)
/* Affichage des données sur stdout */
{
int i;
for (i=0; i<T.taille; i++) printf("%c", T.info[i]);
fflush(stdout);
return;
}
void attendre(int signal)
/* Attend un ou des signaux */
{
while (!signale(signal));
return;
}
char signale(int signal)
/* Renvoie 1 si un des signaux passés en paramètre est émis
SIGRECU : une trame sans erreurs qui nous est destinée est arrivée
SIGTEMPO : timeout
SIGEMIS : il reste des données à envoyer */
{
int i;
time_t aux;
FILE *fic, *temp;
ttrame Trame;
char auxnom[15]="tmp";
ttrame aux2;
if (signal & SIGRECU)
if ((fic=fopen(freception,"rb"))!=NULL)
{
if (fread(&Trame,sizeof(ttrame),1,fic)==1)
{
if ((Trame.AD==asource) && (calcule_CRC(Trame)==Trame.CRC)) return(1);
else
{
strcat(auxnom,freception);
temp=fopen(auxnom,"wb");
while (fread(&aux2,sizeof(ttrame),1,fic)>0)
fwrite(&aux2,sizeof(ttrame),1,temp);
fclose(fic);
fclose(temp);
remove(freception);
rename(auxnom,freception);
}
}
fclose(fic);
}
if (signal & SIGTEMPO)
{
aux=time(NULL);
for (i=0;i<MAXTAILLEFENETRE;i++)
if ((dt[i]!=0) && (difftime(aux,dt[i])>=TIMEOUT)) return(1);
}
if (signal & SIGEMIS)
if (!feof(stdin)) return(1);
return(0);
}
char calcule_CRC(ttrame Trame)
/* Calcul du CRC de la trame, le CRC est ici un caractère de parité */
{
int i;
char resultat=0;
char *p=(char *)&Trame;
for (i=0; i<sizeof(ttrame)-sizeof(char); i++)
resultat=(resultat & !*(p+i)) | (!resultat & *(p+i));
return(resultat);
}
void tempo(int numseq)
/* Déclenche le temporisateur de la trame numseq */
{
dt[numseq]=time(NULL);
return;
}
void stoptempo(int numseq)
/* Stoppe le temporisateur de la trame numseq */
{
dt[numseq]=0;
return;
}
void initialise_couche_physique(char *emission, char *reception)
/* Initialise la couche physique, les paramètres sont les fichiers d'échange */
{
femission=emission;
freception=reception;
remove(femission);
remove(freception);
return;
}
void initialise_couche_reseau(int source, int destination)
/* Initialise la couche réseau, les paramètres sont les adresses de la connection */
{
asource=source;
adest=destination;
return;
}