#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; }