commit a8ed96cb5f084f0f274435a64254e90bc3321254 Author: Nelson-gitea Date: Thu Mar 5 08:37:38 2026 +0100 Commit initial du projet diff --git a/Codes_source/Couche_2/Capsule1/emetteur/emetteur.ino b/Codes_source/Couche_2/Capsule1/emetteur/emetteur.ino new file mode 100644 index 0000000..4a6afe8 --- /dev/null +++ b/Codes_source/Couche_2/Capsule1/emetteur/emetteur.ino @@ -0,0 +1,69 @@ +#include +#include +#include + +//Déclaration des constantes +//Communication avec le module LoRa +#define RFM95_CS 5 //M5 LoRa +#define RFM95_DIO0 36 //M5 LoRa +RH_RF95 rf95(RFM95_CS, RFM95_DIO0); + +//Constantes d'état +#define EMISSION 0 +#define DELAI 1 + +uint8_t state; //État courant +uint8_t data[16]; //Buffer d'émission + + +void setup() { + M5.begin(); + M5.Power.begin(); + Serial.println("========Emetteur CAP1========"); + M5.Lcd.println("========Emetteur CAP1========"); + + delay(1000); + + if(!rf95.init()){ + Serial.println("Echec de la mise en place"); + M5.Lcd.println("Echec de la mise en place"); + } + else{ + Serial.println("Mise en place reussie !!!"); + M5.Lcd.println("Mise en place reussie !!!"); + //Configuration de la radio + rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128); + rf95.setFrequency(867.8); + state=EMISSION; + } + +} + +void loop() { + switch(state){ + case EMISSION: //Code source à l'état d'émission + Serial.println("EMISSION"); + M5.Lcd.println("EMISSION"); + data[0]=0xAA; + data[1]=0x55; + data[2]=0x25; + data[3]=0x24; + data[4]=0x98; + rf95.send(data,5); //Envoi des données + rf95.waitPacketSent(); + + state=DELAI; + break; + + case DELAI: + Serial.println("DELAI"); + M5.Lcd.println("DELAI"); + delay(1000); + state=EMISSION; + break; + + default: + break; + } + +} diff --git a/Codes_source/Couche_2/Capsule1/recepteur/recepteur.ino b/Codes_source/Couche_2/Capsule1/recepteur/recepteur.ino new file mode 100644 index 0000000..809d756 --- /dev/null +++ b/Codes_source/Couche_2/Capsule1/recepteur/recepteur.ino @@ -0,0 +1,96 @@ +#include +#include +#include + +//Déclaration des constantes +//Communication avec le module LoRa +#define RFM95_CS 5 //M5 LoRa +#define RFM95_DIO0 36 //M5 LoRa +RH_RF95 rf95(RFM95_CS, RFM95_DIO0); + +//Déclaration des constantes +uint8_t state; //État courant + +uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN]; //buffer en reception +uint8_t rxbuflen = sizeof(rxbuf); //taille du buffer en repection +int rxFrames; //Numéro de la trame reçue + +//Constantes d'état +#define ECOUTE 1 +#define TEST_RX 2 //Les différents états +#define AFFICHAGE 3 + +void setup() { + M5.begin(); + M5.Power.begin(); + Serial.println("========Recepteur CAP1========"); + M5.Lcd.println("========Recepteur CAP1========"); + + delay(1000); + + if(!rf95.init()){ + Serial.println("Echec de la mise en place"); + M5.Lcd.println("Echec de la mise en place"); + } + else{ + Serial.println("Mise en place reussie !!!"); + M5.Lcd.println("Mise en place reussie !!!"); + rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128); + rf95.setFrequency(867.8); + + state=ECOUTE; + Serial.println("Boucle principale"); + M5.Lcd.println("Boucle principale"); + rxFrames = 0; + } + +} + +void loop() { + + switch(state){ + + case ECOUTE: + Serial.println("ECOUTE"); + M5.Lcd.println("ECOUTE"); + rf95.setModeRx(); + state=TEST_RX; + break; + + case TEST_RX: + Serial.println("TEST-RX"); + M5.Lcd.println("TEST-RX"); + if(rf95.available()){ + state=AFFICHAGE; + } + //Ajout d'un delai pour laisser le temps de récupérer et d'afficher le message sur l'écran du M5 + delay(2000); + break; + + case AFFICHAGE: + if(rf95.recv(rxbuf, &rxbuflen)){ + rxFrames+=1; + + Serial.println(); + M5.Lcd.println(); + + Serial.printf("AFFICHAGE : Trame[%d] de ", rxFrames); + M5.Lcd.printf("AFFICHAGE : Trame[%d] de ", rxFrames); + + Serial.printf("%d octets : |",rxbuflen); + M5.Lcd.printf("%d octets : |",rxbuflen); + + for(int j=0;j +#include +#include + +//Déclaration des constantes +#define RFM95_CS 5 //M5 LoRa +#define RFM95_DIO0 36 //M5 LoRa +RH_RF95 rf95(RFM95_CS, RFM95_DIO0); + +uint8_t txbuf[RH_RF95_MAX_MESSAGE_LEN]; //Buffer d'emission +uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN], rxbuflen=sizeof(rxbuf); //Buffer de reception +uint8_t state, RxSeq, TxSeq, credit; +uint32_t attente; + +#define E0 0 +#define E1 1 +#define E2 2 +#define E3 3 +#define E4 4 +#define E5 5 + +#define TYPE_DATA 1 +#define TYPE_ACK 2 +#define TIMEOUT_ACK 40 + +#define MAX_CREDIT 5 + +void setup() { + M5.begin(); + M5.Power.begin(); + Serial.println("====Emetteur CAP2===="); + M5.Lcd.println("====Emetteur CAP2===="); + + delay(3000); + + if(!rf95.init()){ + Serial.println("Echec de la mise en place"); + M5.Lcd.println("Echec de la mise en place"); + } + else{ + Serial.println("Mise en place reussie !!!"); + M5.Lcd.println("Mise en place reussie !!!"); + //Configuration de la radio + rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128); + rf95.setFrequency(867.8); + state=E0; + + TxSeq=0; + credit=MAX_CREDIT; + Serial.println("Boucle principale."); + M5.Lcd.println("Boucle principale."); + delay(3000); + } + +} + +void loop() { + + switch(state){ + case E0: //Code source à l'état d'émission + + Serial.printf("EMISSION %d", TxSeq); + Serial.println(); + M5.Lcd.printf("EMISSION %d \n", TxSeq); + Serial.println(); + txbuf[0]=TYPE_DATA; + txbuf[1]=TxSeq; + txbuf[2]=0xAA; + txbuf[3]=0x55; + + rf95.send(txbuf,4); //Envoi des données + rf95.waitPacketSent(); + + credit -=1; + state=E1; + break; + + case E1: + attente = millis()+TIMEOUT_ACK; //Armement du Chien de Garde + state = E2; + break; + + case E2: + rf95.setModeRx(); + state=E3; + break; + + case E3: + if(millis() > attente){ //Test expiration CdG + Serial.println("CDG expire"); + M5.Lcd.println("CDG expire"); + state=E5; //Délais expiré + } + else{ + if(rf95.recv(rxbuf, &rxbuflen)){ + if((rxbuf[0]==TYPE_ACK) && (rxbuf[1]==TxSeq)){ //Reception d'un ACK avec le bon num de séquence + state=E4; + } + else{ + state=E2; + } + } + } + break; + + case E4: + Serial.printf("ACK_RECU [%d] \n", TxSeq); + M5.Lcd.printf("ACK_RECU [%d] \n", TxSeq); + state=E0, TxSeq+=1, credit=5; + break; + + case E5: + Serial.printf("Probleme\n"); + M5.Lcd.printf("Probleme\n"); + if (credit==0){ + Serial.print("ECHEC\n"); + M5.Lcd.print("ECHEC\n"); + state=E0; + credit=MAX_CREDIT; + TxSeq+=1; + } + else{ + Serial.printf("Nouvelle tentative n %d\n", 5-credit); + M5.Lcd.printf("Nouvelle tentative n %d\n", 5-credit); + state=E0; + Serial.println(); + M5.Lcd.println(); + } + break; + + default: + state=E0; + break; + } + +} diff --git a/Codes_source/Couche_2/Capsule2/recepteur/recepteur.ino b/Codes_source/Couche_2/Capsule2/recepteur/recepteur.ino new file mode 100644 index 0000000..3037cce --- /dev/null +++ b/Codes_source/Couche_2/Capsule2/recepteur/recepteur.ino @@ -0,0 +1,114 @@ +#include +#include +#include + +//Déclaration des constantes +#define RFM95_CS 5 //M5 LoRa +#define RFM95_DIO0 36 //M5 LoRa +RH_RF95 rf95(RFM95_CS, RFM95_DIO0); + +uint8_t state; +uint8_t txbuf[RH_RF95_MAX_MESSAGE_LEN]; +uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN]; +uint8_t rxlen=RH_RF95_MAX_MESSAGE_LEN; +uint8_t RxSeq; + +#define E0 0 +#define E1 1 +#define E2 2 +#define E3 3 + +#define TYPE_DATA 1 +#define TYPE_ACK 2 + + +void setup() { + M5.begin(); + M5.Power.begin(); + Serial.println("====Recepteur CAP2===="); + M5.Lcd.println("====Recepteur CAP2===="); + + delay(3000); + + if(!rf95.init()){ + Serial.println("Echec de la mise en place"); + M5.Lcd.println("Echec de la mise en place"); + } + else{ + Serial.println("Mise en place reussie !!!"); + M5.Lcd.println("Mise en place reussie !!!"); + rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128); + rf95.setFrequency(867.8); + + state=E0; + Serial.println("Boucle principale"); + M5.Lcd.println("Boucle principale"); + RxSeq=255; + delay(1000); + } + +} + +void loop() { + + switch(state){ + case E0: + Serial.println("Mode Reception"); + M5.Lcd.println("Mode Reception"); + rf95.setModeRx(); + state=E1; + break; + + case E1: + if(rf95.recv(rxbuf, &rxlen)){ + if(rxbuf[0]==TYPE_DATA){ + state=E2; + } + else{ + state=E0; + } + } + break; + + case E2: + + if(RxSeq!=rxbuf[1]){ + RxSeq=rxbuf[1]; + Serial.printf("[%d] ", RxSeq); + M5.Lcd.printf("[%d] ", RxSeq); + Serial.printf("DATA de %d octets :", rxlen); + M5.Lcd.printf("DATA de %d octets :", rxlen); + Serial.println(); + M5.Lcd.println(); + for(int i=0;i +#include +#include + +//Déclaration des constantes +//Communication avec le module LoRa +#define RFM95_CS 5 //M5 LoRa +#define RFM95_DIO0 36 //M5 LoRa +RH_RF95 rf95(RFM95_CS, RFM95_DIO0); + +//Constantes d'état +#define EMISSION 0 +#define DELAI 1 + +//Variables pour l'état et le buffer +uint8_t state; //État courant +uint8_t txbuf[RH_RF95_MAX_MESSAGE_LEN]; //Buffer d'émission + +//Variables pour la correction d'erreur +uint16_t S, SP; + +//Constantes pour les champs de la trame +#define CHAMP_MIN_PAYLOAD 0 +#define CHAMP_MAX_PAYLOAD 19 +#define CHAMP_MIN_S 20 +#define CHAMP_MIN_SP 22 +#define LONGUEUR_TRAME 24 + +void setup() { + M5.begin(); + M5.Power.begin(); + Serial.println("===Emetteur CAP3 Corr==="); + M5.Lcd.println("===Emetteur CAP3 Corr==="); + + delay(3000); + + if(!rf95.init()){ + Serial.println("Echec de la mise en place"); + M5.Lcd.println("Echec de la mise en place"); + } + else{ + Serial.println("Mise en place reussie !!!"); + M5.Lcd.println("Mise en place reussie !!!"); + //Configuration de la radio + rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128); + rf95.setFrequency(867.8); + state=EMISSION; + } + +} + +void loop() { + switch(state){ + case EMISSION: //Code source à l'état d'émission + Serial.println("EMISSION"); //Trame de 20 octets de payload et 4 octets RS + M5.Lcd.println("EMISSION"); + S=0;SP=0; + + for(int i=CHAMP_MIN_PAYLOAD;i<=CHAMP_MAX_PAYLOAD; i++){ + txbuf[i] = 255; + S+=txbuf[i]; + SP+=txbuf[i]*(i+1); + Serial.printf("|%02X", txbuf[i]); + M5.Lcd.printf("|%02X", txbuf[i]); + } + //Injection des 8 bits de poids faible + //ET logique avec masque (0000 0000 1111 1111) + txbuf[CHAMP_MIN_S] = S & 0x00FF; + + //Injection des 8 bits de poids fort + //ET logique avec masque (1111 1111 0000 0000) + //Puis décalage de 8 bits vers la droite pour pouvoir les coder + //sur un octet + txbuf[CHAMP_MIN_S+1] = (S & 0xFF00) >> 8; + + Serial.printf("|%02X|%02X", txbuf[CHAMP_MIN_S],txbuf[CHAMP_MIN_S+1]); + M5.Lcd.printf("|%02X|%02X", txbuf[CHAMP_MIN_S],txbuf[CHAMP_MIN_S+1]); + + //Même principe que pour S + txbuf[CHAMP_MIN_SP] = SP & 0x00FF; + txbuf[CHAMP_MIN_SP+1] = (SP & 0xFF00) >> 8; + Serial.printf("|%02X|%02X", txbuf[CHAMP_MIN_SP],txbuf[CHAMP_MIN_SP+1]); + M5.Lcd.printf("|%02X|%02X", txbuf[CHAMP_MIN_SP],txbuf[CHAMP_MIN_SP+1]); + + Serial.println(); + M5.Lcd.println(); + + rf95.send(txbuf,LONGUEUR_TRAME); //Envoi des données + rf95.waitPacketSent(); + + state=DELAI; + break; + + case DELAI: + Serial.println("DELAI"); + M5.Lcd.println("DELAI"); + delay(1000); + state=EMISSION; + break; + + default: + break; + } + +} diff --git a/Codes_source/Couche_2/Capsule3/Correction_erreur/recepteur/recepteur.ino b/Codes_source/Couche_2/Capsule3/Correction_erreur/recepteur/recepteur.ino new file mode 100644 index 0000000..b52d479 --- /dev/null +++ b/Codes_source/Couche_2/Capsule3/Correction_erreur/recepteur/recepteur.ino @@ -0,0 +1,160 @@ +#include +#include +#include + +//Déclaration des constantes +#define RFM95_CS 5 //M5 LoRa +#define RFM95_DIO0 36 //M5 LoRa +RH_RF95 rf95(RFM95_CS, RFM95_DIO0); + +uint8_t state; +uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN], rxbuflen=sizeof(rxbuf); +int rxFrames; + +//Variables pour la correction d'erreur +int erreur, rang; +uint16_t Sr,SPr, Sc, SPc; //Sommes et Sommes pondérées calculées et reçues + +//Constantes d'état +#define ECOUTE 1 +#define TEST_RX 2 +#define AFFICHAGE 3 + +//Constantes pour les champs de la trame +#define CHAMP_MIN_PAYLOAD 0 +#define CHAMP_MAX_PAYLOAD 19 +#define CHAMP_MIN_S 20 +#define CHAMP_MIN_SP 22 +#define LONGUEUR_TRAME 24 + + +void setup() { + M5.begin(); + M5.Power.begin(); + Serial.println("===Recepteur CAP3 cor==="); + M5.Lcd.println("===Recepteur CAP3 cor==="); + + delay(3000); + + if(!rf95.init()){ + Serial.println("Echec de la mise en place"); + M5.Lcd.println("Echec de la mise en place"); + } + else{ + Serial.println("Mise en place reussie !!!"); + M5.Lcd.println("Mise en place reussie !!!"); + rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128); + rf95.setFrequency(867.8); + + state=ECOUTE; + delay(2000); + Serial.println("Boucle principale"); + M5.Lcd.println("Boucle principale"); + } + +} + +void loop() { + + + switch(state){ + + case ECOUTE: + Serial.println("ECOUTE"); + M5.Lcd.println("ECOUTE"); + rf95.setModeRx(); + state=TEST_RX; + delay(2000); + break; + + case TEST_RX: + Serial.println("TEST-RX"); + M5.Lcd.println("TEST-RX"); + if(rf95.available()){ + state=AFFICHAGE; + } + break; + + case AFFICHAGE: + + if(rf95.recv(rxbuf, &rxbuflen)){ //récupération de la trame reçue dans rxbuf + + //rxbuflen=23; //Simulation d'erreur de longueur + //rxbuf[16] = 21;//Simulation modification de l'octet 17 + //rxbuf[2] = 8; + + rxFrames+=1; + Serial.printf("[%d] ", rxFrames); + M5.Lcd.printf("[%d] ", rxFrames); + + Serial.printf("%d bytes: ", rxbuflen); + M5.Lcd.printf("%d bytes: ", rxbuflen); + for(int j=0;j +#include +#include + +//Déclaration des constantes +#define RFM95_CS 5 //M5 LoRa +#define RFM95_DIO0 36 //M5 LoRa +RH_RF95 rf95(RFM95_CS, RFM95_DIO0); + +//Variables +uint8_t txbuf[RH_RF95_MAX_MESSAGE_LEN]; +uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN], rxbuflen=sizeof(rxbuf); //Buffer de reception et longueur +uint8_t state, TxSeq, credit; +uint32_t attente; +uint8_t FCS; //Champ de contrôle + +//Constantes d'états +#define E0 0 +#define E1 1 +#define E2 2 +#define E3 3 +#define E4 4 +#define E5 5 + +//Constantes de données et d'acquitement +#define TYPE_DATA 1 +#define TYPE_ACK 2 +#define TIMEOUT_ACK 40 +#define MAX_CREDIT 5 + +//Constantes de champs de trame +#define CHAMP_TYPE 0 +#define CHAMP_NUM_SEQ 1 +#define CHAMP_MIN_PAYLOAD 2 +#define CHAMP_MAX_PAYLOAD 19 +#define CHAMP_FCS_DATA 20 +#define CHAMP_FCS_ACK 2 + + +int erreur_ack=1; + + +void setup() { + M5.begin(); + M5.Power.begin(); + Serial.println("===Emmetteur CAP3 DET==="); + M5.Lcd.println("===Emmetteur CAP3 DET==="); + + delay(3000); + + if(!rf95.init()){ + Serial.println("Echec de la mise en place"); + M5.Lcd.println("Echec de la mise en place"); + } + else{ + Serial.println("Mise en place reussie !!!"); + M5.Lcd.println("Mise en place reussie !!!"); + //Configuration de la radio + rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128); + rf95.setFrequency(867.8); + state=E0; + + TxSeq=0; + credit=MAX_CREDIT; + Serial.println("Boucle principale."); + M5.Lcd.println("Boucle principale."); + delay(3000); + } + +} + +void loop() { + + switch(state){ + case E0: //Code source à l'état d'émission + Serial.printf("EMISSION %d\n\n", TxSeq); + M5.Lcd.printf("EMISSION %d\n\n", TxSeq); + txbuf[CHAMP_TYPE]=TYPE_DATA; + txbuf[CHAMP_NUM_SEQ]=TxSeq; + + //On remplit les 18 octets de payload au max (255) + for (int i=CHAMP_MIN_PAYLOAD;i<=CHAMP_MAX_PAYLOAD;i++){ + txbuf[i]=255; + } + + //Calcul du FCS : XOR + FCS=0; //Champ sur un octet + for(int i=0;i<=CHAMP_MAX_PAYLOAD;i++){ + //XOR des 20 octets de la trame. + FCS=FCS ^ txbuf[i]; + } + //On ajoute le FCS calculé à la fin de la trame + txbuf[CHAMP_FCS_DATA] = FCS; + + //Affichage pour le debug + for(int i=0; i<21; i++){ + Serial.printf("|%02X", txbuf[i]); + M5.Lcd.printf("|%02X", txbuf[i]); + } + Serial.println("|"); + M5.Lcd.println("|"); + + //Envoi des données + rf95.send(txbuf,21); + rf95.waitPacketSent(); + + credit-=1; + state=E1; + break; + + case E1: + attente = millis()+TIMEOUT_ACK; //Armement du Chien de Garde + state = E2; + break; + + case E2: + rf95.setModeRx(); + state=E3; + break; + + case E3: + if(millis() > attente){ //Test expiration CdG + state=E5; //Délais expiré + } + else{ + if(rf95.recv(rxbuf, &rxbuflen)){ + //Simulation d'erreur + + if(erreur_ack%3==0){ + rxbuf[CHAMP_FCS_ACK]=rxbuf[CHAMP_FCS_ACK]+1; + } + erreur_ack+=1; + + //Reception d'un ACK avec le bon num de séquence + if((rxbuf[CHAMP_TYPE]==TYPE_ACK) && (rxbuf[CHAMP_NUM_SEQ]==TxSeq)){ + //Trame reçue sans erreur + if((rxbuf[CHAMP_TYPE] ^ rxbuf[CHAMP_NUM_SEQ])==rxbuf[CHAMP_FCS_ACK]){ + //Affichage de la trame reçue + state=E4; + } + else{ + //Affichage de l'échec + state=E5; + } + } + else{ + //Réécoute + state=E2; + } + } + } + break; + + case E4: + Serial.printf("ACK_RECU [%d] \n", TxSeq); + M5.Lcd.printf("ACK_RECU [%d] \n", TxSeq); + state=E0, TxSeq+=1, credit=MAX_CREDIT; + break; + + case E5: + Serial.print("E5 "); + M5.Lcd.print("E5 "); + if (credit==0){ + Serial.print("ECHEC\n"); + M5.Lcd.print("ECHEC\n"); + credit=MAX_CREDIT; + TxSeq+=1; + } + else{ + Serial.printf("Nouvelle tentative n %d\n", MAX_CREDIT-credit); + M5.Lcd.printf("Nouvelle tentative n %d\n", MAX_CREDIT-credit); + Serial.println(); + M5.Lcd.println(); + } + state=E0; + break; + + default: + state=E0; + break; + } +} diff --git a/Codes_source/Couche_2/Capsule3/Detection_erreur/recepteur/recepteur.ino b/Codes_source/Couche_2/Capsule3/Detection_erreur/recepteur/recepteur.ino new file mode 100644 index 0000000..cd0dcaa --- /dev/null +++ b/Codes_source/Couche_2/Capsule3/Detection_erreur/recepteur/recepteur.ino @@ -0,0 +1,141 @@ +#include +#include +#include + +//Déclaration des constantes +#define RFM95_CS 5 //M5 LoRa +#define RFM95_DIO0 36 //M5 LoRa +RH_RF95 rf95(RFM95_CS, RFM95_DIO0); + +//Variables +uint8_t state; +uint8_t txbuf[RH_RF95_MAX_MESSAGE_LEN]; +uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN], rxbuflen=sizeof(rxbuf); +uint8_t RxSeq; +uint8_t FCSc, FCSr; //Champs de contrôle d'un octet calculé et reçu + +//Constantes d'état +#define E0 0 +#define E1 1 +#define E2 2 +#define E3 3 + +#define TYPE_DATA 1 +#define TYPE_ACK 2 + +//Constantes de champs de trames +#define CHAMP_TYPE 0 +#define CHAMP_NUM_SEQ 1 +#define CHAMP_MIN_PAYLOAD 2 +#define CHAMP_MAX_PAYLOAD 19 +#define CHAMP_FCS_DATA 20 +#define CHAMP_FCS_ACK 2 + +void setup() { + M5.begin(); + M5.Power.begin(); + Serial.println("===Recepteur CAP3 DET==="); + M5.Lcd.println("===Recepteur CAP3 DET==="); + + delay(3000); + + if(!rf95.init()){ + Serial.println("Echec de la mise en place"); + M5.Lcd.println("Echec de la mise en place"); + } + else{ + Serial.println("Mise en place reussie !!!"); + M5.Lcd.println("Mise en place reussie !!!"); + rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128); + rf95.setFrequency(867.8); + + state=E0; + Serial.println("Boucle principale"); + M5.Lcd.println("Boucle principale"); + RxSeq=255; + delay(1000); + } + +} + +void loop() { + switch(state){ + + case E0: //ECOUTE + Serial.println("E0 : Attente Reception \n"); + M5.Lcd.println("E0 : Attente Reception \n"); + rf95.setModeRx(); + state=E1; + break; + + case E1: + if(rf95.recv(rxbuf, &rxbuflen)){ + if(rxbuf[CHAMP_TYPE]==TYPE_DATA){ + //Test si FCS juste + FCSr=rxbuf[CHAMP_FCS_DATA]; //Champ de contrôle reçu + //Calcul du FCS + FCSc=0; + for(int i=0;i<=CHAMP_MAX_PAYLOAD;i++){ + FCSc= FCSc ^ rxbuf[i]; + } + //Mêmes FCS : Trame juste + if(FCSr==FCSc){ + state=E2; + } + //Sinon trame fausse + else{ + Serial.println(); + M5.Lcd.println(); + Serial.printf("Erreur de Trame, FCSr=%d FCSc=%d", FCSr, FCSc); + M5.Lcd.printf("Erreur de Trame, FCSr=%d FCSc=%d", FCSr, FCSc); + Serial.println(); + M5.Lcd.println(); + state=E0; + } + } + else{ + state=E0; + } + } + break; + + case E2: + + if(RxSeq!=rxbuf[CHAMP_NUM_SEQ]){ + RxSeq=rxbuf[CHAMP_NUM_SEQ]; + Serial.printf("Num Seq : [%d] \n", RxSeq); + M5.Lcd.printf("Num Seq : [%d] \n", RxSeq); + Serial.printf("DATA de %d octets :", rxbuflen); + M5.Lcd.printf("DATA de %d octets :", rxbuflen); + Serial.println(); + M5.Lcd.println(); + for(int j=0;j +#include +#include + +//Déclaration des constantes +#define RFM95_CS 5 //M5 LoRa +#define RFM95_DIO0 36 //M5 LoRa +RH_RF95 rf95(RFM95_CS, RFM95_DIO0); + +uint8_t txbuf[RH_RF95_MAX_MESSAGE_LEN]; //Buffer d'emission +uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN], rxbuflen=sizeof(rxbuf); //Buffer de reception +uint8_t state, RxSeq, TxSeq, credit, backoff, NewFrame, EIT; +uint32_t attente; + +//Constantes d'état +#define E0 0 +#define E1 1 +#define E2 2 +#define E3 3 +#define E4 4 +#define E5 5 + +//Constantes de type +#define TYPE_DATA 1 +#define TYPE_ACK 2 +#define TIMEOUT_ACK 70 + +//Constante de crédit +#define MAX_CREDIT 5 + +//Constante d'adresse +#define LOCAL_ADDR 2 +#define SINK_ADDR 0 + +//Constantes d'infos champ de trame +#define F_S_ADDR 0 //Adresse source +#define F_D_ADDR 1 //Adresse destination +#define F_TYPE 2 //Type +#define F_NUM_SEQ 3 //Numéro de séquence +#define F_MIN_PAYLOAD 4 //Indice du debut de payload +#define F_MAX_PAYLOAD 9 //Indice de fin de payload +#define TAILLE_TRAME 10 //Taille de la trame + + + + +void setup() { + M5.begin(); + M5.Power.begin(); + Serial.println("====Emetteur CAP4===="); + M5.Lcd.println("====Emetteur CAP4===="); + + delay(3000); + + if(!rf95.init()){ + Serial.println("Echec de la mise en place"); + M5.Lcd.println("Echec de la mise en place"); + } + else{ + Serial.println("Mise en place reussie !!!"); + M5.Lcd.println("Mise en place reussie !!!"); + //Configuration de la radio + rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128); + rf95.setFrequency(867.8); + state=E0; + + TxSeq=0; + credit=MAX_CREDIT; + Serial.println("Boucle principale."); + M5.Lcd.println("Boucle principale."); + + NewFrame=1; //Initialisation drapeau + randomSeed(analogRead(30)); // Initialisation utilisant la broche GPIO39 (VN) + delay(10000); + } + +} + +void loop() { + + switch(state){ + case E0: //Code source à l'état d'émission + + if(NewFrame==1){ + EIT=random(80,120)*random(80,123); + delay(EIT); //attente pour l'envoi de la nouvelle trame + Serial.printf(" EIT : %d ", EIT); + Serial.println(); + M5.Lcd.printf(" EIT : %d ", EIT); + M5.Lcd.println(); + } + + //Formatage des champs de la trame + txbuf[F_S_ADDR]=LOCAL_ADDR; + txbuf[F_D_ADDR]=SINK_ADDR; + txbuf[F_TYPE]=TYPE_DATA; + txbuf[F_NUM_SEQ]=TxSeq; + + //Ajout de la payload + for(int i=F_MIN_PAYLOAD; i<=F_MAX_PAYLOAD;i++){ + txbuf[i]=random(0, 256); + } + Serial.printf("EMISSION %d", TxSeq); + Serial.println(); + M5.Lcd.printf("EMISSION %d \n", TxSeq); + Serial.println(); + rf95.send(txbuf,TAILLE_TRAME); //Envoi des données + rf95.waitPacketSent(); + + credit -=1; + state=E1; + break; + + case E1: //CdG + attente = millis()+TIMEOUT_ACK; //Armement du Chien de Garde + state = E2; + break; + + case E2: //Mode Réception + rf95.setModeRx(); + state=E3; + break; + + case E3: + if(millis() > attente){ //Test expiration CdG + Serial.println("===CDG expire==="); + M5.Lcd.println("===CDG expire==="); + state=E5; //Délais expiré + } + else{ + if(rf95.recv(rxbuf, &rxbuflen)){ + if((rxbuf[F_TYPE]==TYPE_ACK) && (rxbuf[F_NUM_SEQ]==TxSeq) && (rxbuf[F_D_ADDR]==LOCAL_ADDR)){ + //Reception d'un ACK avec le bon num de séquence et la bonne adresse de destination + state=E4; + } + else{ + state=E2; + } + } + } + break; + + case E4: + Serial.printf("ACK_RECU [%d] \n", TxSeq); + M5.Lcd.printf("ACK_RECU [%d] \n", TxSeq); + state=E0, TxSeq+=1, credit=5; + break; + + case E5: + //Serial.printf("Probleme\n"); + //M5.Lcd.printf("Probleme\n"); + if (credit==0){ + Serial.print("ECHEC\n"); + M5.Lcd.print("ECHEC\n"); + state=E0; + credit=MAX_CREDIT; + TxSeq+=1; + NewFrame=1; + } + else{ + Serial.printf("Collision ? Nouvelle tentative n %d\n", MAX_CREDIT-credit); + M5.Lcd.printf("Collision ? Nouvelle tentative n %d\n", MAX_CREDIT-credit); + state=E0; + NewFrame=0; //Toujours la même trame + backoff=random(80,120)*random(80,123); + delay(backoff); //Attente aléatoire ALOHA + Serial.printf(" backoff : [[%d]] ", backoff); + M5.Lcd.printf(" backoff : [[%d]] ", backoff); + Serial.println(); + M5.Lcd.println(); + } + break; + + default: + state=E0; + break; + } + +} diff --git a/Codes_source/Couche_2/Capsule4/recepteur/recepteur.ino b/Codes_source/Couche_2/Capsule4/recepteur/recepteur.ino new file mode 100644 index 0000000..68c5926 --- /dev/null +++ b/Codes_source/Couche_2/Capsule4/recepteur/recepteur.ino @@ -0,0 +1,133 @@ +#include +#include +#include + +//Déclaration des constantes +#define RFM95_CS 5 //M5 LoRa +#define RFM95_DIO0 36 //M5 LoRa +RH_RF95 rf95(RFM95_CS, RFM95_DIO0); + +uint8_t state; +uint8_t txbuf[RH_RF95_MAX_MESSAGE_LEN]; +uint8_t rxbuf[RH_RF95_MAX_MESSAGE_LEN]; +uint8_t rxlen=RH_RF95_MAX_MESSAGE_LEN; +uint8_t RxSeq; + +//Constantes d'états +#define E0 0 +#define E1 1 +#define E2 2 +#define E3 3 + +//Constante de type +#define TYPE_DATA 1 +#define TYPE_ACK 2 + +//Constate d'adresse +#define LOCAL_ADDR 0 + +//Constantes d'infos champ de trame +#define F_S_ADDR 0 //Adresse source +#define F_D_ADDR 1 //Adresse destination +#define F_TYPE 2 //Type +#define F_NUM_SEQ 3 //Numéro de séquence +#define F_MIN_PAYLOAD 4 //Indice du debut de payload +#define F_MAX_PAYLOAD 5 //Indice de fin de payload +#define TAILLE_ACK 4 //Taille de la trame + + +void setup() { + M5.begin(); + M5.Power.begin(); + Serial.println("====Recepteur CAP4===="); + M5.Lcd.println("====Recepteur CAP4===="); + + delay(3000); + + if(!rf95.init()){ + Serial.println("Echec de la mise en place"); + M5.Lcd.println("Echec de la mise en place"); + } + else{ + Serial.println("Mise en place reussie !!!"); + M5.Lcd.println("Mise en place reussie !!!"); + rf95.setModemConfig(RH_RF95::Bw125Cr45Sf128); + rf95.setFrequency(867.8); + + state=E0; + //Serial.println("Boucle principale"); + //M5.Lcd.println("Boucle principale"); + RxSeq=255; + delay(1000); + } + +} + +void loop() { + + switch(state){ + case E0: + //Serial.println("Mode Reception"); + //M5.Lcd.println("Mode Reception"); + rf95.setModeRx(); + state=E1; + break; + + case E1: + if(rf95.recv(rxbuf, &rxlen)){ + if((rxbuf[F_TYPE]==TYPE_DATA) && (rxbuf[F_D_ADDR]==LOCAL_ADDR)){ + //Réception d'un ACK et pour le récepteur + state=E2; + } + else{ + state=E0; + } + } + break; + + case E2: + + if(RxSeq!=rxbuf[F_NUM_SEQ]){ + M5.Lcd.printf("===Message Recu===\n"); + M5.Lcd.printf("Recu de [%02X]\n",rxbuf[F_S_ADDR]); + RxSeq=rxbuf[F_NUM_SEQ]; + Serial.printf("[%d] ", RxSeq); + M5.Lcd.printf("[%d] ", RxSeq); + Serial.printf("DATA de %d octets :", rxlen); + M5.Lcd.printf("DATA de %d octets :", rxlen); + Serial.println(); + M5.Lcd.println(); + for(int i=0;i +#include +#include "SimpleWiNo.h" +#include + +//Objet Wino +SimpleWiNo wino; + +//Constantes de configuration des noeuds +#define ADRESSE_CLUSTER 0x4A89 +#define ADRESSE_NOEUD 0x0001 +#define CANAL 7 + +//Variables pour le paquet +uint8_t txbuf[40]; +uint8_t packetLen; + +//Constantes de indices de champs du paquet +#define ADRESSE_MULTICAST 0x7878 +#define NB_PAYLOAD 10 + +//Procédure de formatage +void formaterPaquet(uint8_t* longueur, uint8_t donnees[]){ + + *longueur=0; + + //Ajout En-tete + wino.encodeUi16(ADRESSE_MULTICAST, &donnees[*longueur]); + *longueur +=2; + + //Ajout de la payload + for(int i=0; i +#include +#include "SimpleWiNo.h" +#include + +//Objet Wino +SimpleWiNo wino; + +//Constantes de configuration des noeuds +#define ADRESSE_CLUSTER 0x4A89 +#define ADRESSE_NOEUD 0x0003 +#define CANAL 7 + +//Variables pour le paquet +uint8_t rxbuf[40]; +uint8_t packetLen=0; +uint8_t indicePaquet; +uint16_t adresseSource; +uint16_t adresseMulticast; + +//Constantes de indices de champs du paquet +#define ADRESSE_MULTICAST 0x7878 + +//Procédure d'affichage de la payload +//À partir de l'indice de début uniquement +void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){ + + M5.Lcd.printf("Payload : "); + Serial.printf("Payload : "); + for(int i=indiceDebut; i +#include +#include "SimpleWiNo.h" +#include + +//Objet Wino +SimpleWiNo wino; + +//Constantes de configuration des noeuds +#define ADRESSE_CLUSTER 0x4A89 +#define ADRESSE_NOEUD 0x0001 +#define CANAL 7 + +//Variables pour le paquet +uint8_t txbuf[40]; //Buffer d'émission +uint8_t rxbuf[40]; //Buffer de réception +uint8_t packetLenTX; //Longueur du paquet émis +uint8_t packetLenRX; //Longueur du paquet reçu +uint8_t indicePaquetRX; //Indice pour le traitement du paquet reçu +uint16_t adresseSource; //Adresse du noeud source +uint16_t adresseMulticast; //Adresse multicast reçue + +//Constantes de indices de champs du paquet +#define ADRESSE_MULTICAST 0x7878 //Adresse multicast du noeud +#define NB_PAYLOAD 10 //Nombre de données de payload + + +//Procédure de formatage de l'en tête et de la payload +//du paquet en émission +void formaterPaquet(uint8_t* longueur, uint8_t donnees[]){ + + *longueur=0; + + //Ajout En-tete + wino.encodeUi16(ADRESSE_MULTICAST, &donnees[*longueur]); + *longueur +=2; + + //Ajout de la payload + for(int i=0; i +#include +#include "SimpleWiNo.h" +#include + +//Objet Wino +SimpleWiNo wino; + +//Constantes de configuration des noeuds +#define ADRESSE_CLUSTER 0x4A89 +#define ADRESSE_NOEUD 0x0003 +#define CANAL 7 + +//Variables pour le paquet +uint8_t rxbuf[40]; //Buffer de reception +uint8_t packetLen; //Longueur du paquet reçu +uint8_t indicePaquet; //Indice pour le traitement du paquet reçu +uint16_t adresseSource; //Adresse du noeud source +uint16_t adresseMulticast; //Adresse multicast reçue + +//Constantes de indices de champs du paquet +#define ADRESSE_MULTICAST 0x7878 + +//Procédure d'affichage de la payload reçue +//À partir de l'indice de début de payload uniquement +void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){ + + M5.Lcd.printf("Payload : "); + Serial.printf("Payload : "); + for(int i=indiceDebut; i +#include +#include "SimpleWiNo.h" +#include + +//Objet Wino +SimpleWiNo wino; + +//Constantes de configuration des noeuds +#define ADRESSE_CLUSTER 0x4A89 +#define ADRESSE_NOEUD 0x0001 +#define CANAL 7 + +//Variables pour le paquet +uint8_t txbuf[40]; //Buffer d'émission +uint8_t rxbuf[40]; //Buffer de réception +uint8_t packetLenTX; //Longueur du paquet émis +uint8_t packetLenRX; //Longueur du paquet reçu +uint16_t adresseSource; //Adresse du noeud source +uint16_t adresseMulticast; //Adresse multicast reçue + + +//Propriétés du paquet +#define ADRESSE_MULTICAST 0x7878 //Adresse multicast du noeud +#define NB_PAYLOAD 10 //Nombre de données de payload +#define TTL_MAX 7 //Time To Live avant expiration + +//Indices des champs du paquet +#define CHAMP_ADRESSE 0 //position du champ d'adressage +#define CHAMP_TTL 2 //Position du TTL dans le paquet +#define CHAMP_MIN_PAYLOAD 3 //Position du premier octet de la payload + +//Procédure de formatage de l'en tête et de la payload +//du paquet en émission +void formaterPaquet(uint8_t* longueur, uint8_t donnees[]){ + + *longueur=0; + + //Ajout En-tete + wino.encodeUi16(ADRESSE_MULTICAST, &donnees[CHAMP_ADRESSE]); + *longueur +=2; + + //Ajout du TTL + donnees[CHAMP_TTL]=0; + + *longueur+=1; + + //Ajout de la payload + for(int i=0; i +#include +#include "SimpleWiNo.h" +#include + +//Objet Wino +SimpleWiNo wino; + +//Constantes de configuration des noeuds +#define ADRESSE_CLUSTER 0x4A89 +#define ADRESSE_NOEUD 0x0003 +#define CANAL 7 + +//Variables pour le paquet +uint8_t rxbuf[40]; //Buffer de reception +uint8_t packetLen; //Longueur du paquet reçu +uint16_t adresseSource; //Adresse du noeud source +uint16_t adresseMulticast; //Adresse multicast reçue + +//Propriétés du paquet +#define ADRESSE_MULTICAST 0x7878 +#define TTL_MAX 7 //Time To Live avant expiration + +//Indices des champs du paquet +#define CHAMP_ADRESSE 0 //position du champ d'adressage +#define CHAMP_TTL 2 //Position du TTL dans le paquet +#define CHAMP_MIN_PAYLOAD 3 //Position du premier octet de la payload + + +//Procédure d'affichage de la payload reçue +//À partir de l'indice de début de payload uniquement +void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){ + + M5.Lcd.printf("Payload : "); + Serial.printf("Payload : "); + for(int i=indiceDebut; i +#include +#include "SimpleWiNo.h" +#include + +//Objet Wino +SimpleWiNo wino; + +//Constantes de configuration des noeuds +#define ADRESSE_CLUSTER 0x4A89 +#define ADRESSE_NOEUD 0x0001 +#define CANAL 7 +#define DELAI_ENVOI 60000 + +//Variables pour le paquet +uint8_t txbuf[40]; //Buffer d'émission +uint8_t rxbuf[40]; //Buffer de réception +uint8_t packetLenTX; //Longueur du paquet émis +uint8_t packetLenRX; //Longueur du paquet reçu +uint16_t adresseSource; //Adresse du noeud source +uint16_t adresseDestination; //Adresse du noeud source +uint16_t adresseMulticast; //Adresse multicast reçue +uint8_t numSeq=0; + + + +//Propriétés du paquet +#define ADRESSE_MULTICAST 0x7878 //Adresse multicast du noeud +#define NB_PAYLOAD 10 //Nombre de données de payload +#define TTL_MAX 2 //Time To Live avant expiration + +//Indices des champs du paquet +#define CHAMP_ADRESSE_DST 0 //Position de l'adresse de destination +#define CHAMP_TTL 2 //Position du TTL dans le paquet +#define CHAMP_ADRESSE_SRC 3 //Position du champ d'adressage +#define CHAMP_NUM_SEQ 5 //Position du numéro de séquence +#define CHAMP_MIN_PAYLOAD 6 //Position du premier octet de la payload + +//Procédure de formatage de l'en tête et de la payload +//du paquet en émission +void formaterPaquet(uint8_t* longueur, uint8_t donnees[], uint8_t nSeq){ + + *longueur=0; + + //Ajout En-tete + + //Adresse Destination + wino.encodeUi16(ADRESSE_MULTICAST, &donnees[CHAMP_ADRESSE_DST]); + *longueur +=2; + + //Ajout du TTL + donnees[CHAMP_TTL]=0; + *longueur+=1; + + //Adresse Source + wino.encodeUi16(ADRESSE_NOEUD, &donnees[CHAMP_ADRESSE_SRC]); + *longueur +=2; + + //Numéro de séquence + donnees[CHAMP_NUM_SEQ]=nSeq; + *longueur +=1; + + //Ajout de la payload + for(int i=0; i attente){ + Serial.println("====Envoi Paquet===="); + formaterPaquet(&packetLenTX, txbuf, numSeq); + afficherPaquet(packetLenTX, txbuf); + wino.send(0xFFFF, txbuf, packetLenTX); + numSeq+=1; + attente=millis()+DELAI_ENVOI; + } + + + //Test Reception + if(wino.recv(&adresseSource, rxbuf, &packetLenRX) && (adresseSource!=3)){ + //Affichage des éléments du paquet reçu + M5.Lcd.println("=====Reception====="); + Serial.println("=====Reception====="); + //Affichage du noeud source + adresseSource=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_SRC]); + M5.Lcd.printf("Noeud Source : %X \n", adresseSource); + Serial.printf("Noeud Source : %X \n", adresseSource); + //Affichage Adresse Multicast + adresseMulticast=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_DST]); + M5.Lcd.printf("Adresse Multicast : %X \n", adresseMulticast); + Serial.printf("Adresse Multicast : %X \n", adresseMulticast); + //Affichage TTL + M5.Lcd.printf("TTL : %d \n", rxbuf[CHAMP_TTL]); + Serial.printf("TTL : %d \n", rxbuf[CHAMP_TTL]); + //Incrémentation TTL + rxbuf[CHAMP_TTL]+=1; + //Affichage du numéro de séquence + M5.Lcd.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]); + Serial.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]); + //Affichage Payload + afficherPayload(CHAMP_MIN_PAYLOAD, packetLenRX, rxbuf); + + //Test pour la réemission + //Paquet non émis par le noeud + if(adresseSource != ADRESSE_NOEUD){ + //Même adresse multicast et TTL inférieur au max + if((adresseMulticast==ADRESSE_MULTICAST) && (rxbuf[CHAMP_TTL]<=TTL_MAX)){ + M5.Lcd.println("=====Réemission Paquet====="); + Serial.println("=====Réemission Paquet====="); + wino.send(0xFFFF, rxbuf, packetLenRX); + } + } + else{ + M5.Lcd.println("=== Paquet emis par le noeud ==="); + Serial.println("=== Paquet emis par le noeud ==="); + } + } +} diff --git a/Codes_source/Couche_3/Sprint4/NoeudRelais/NoeudRelais.ino b/Codes_source/Couche_3/Sprint4/NoeudRelais/NoeudRelais.ino new file mode 100644 index 0000000..518fe38 --- /dev/null +++ b/Codes_source/Couche_3/Sprint4/NoeudRelais/NoeudRelais.ino @@ -0,0 +1,111 @@ +#include +#include +#include "SimpleWiNo.h" +#include + +//Objet Wino +SimpleWiNo wino; + +//Constantes de configuration des noeuds +#define ADRESSE_CLUSTER 0x4A89 +#define ADRESSE_NOEUD 0x0002 +#define CANAL 7 + +//Variables pour le paquet +uint8_t rxbuf[40]; //Buffer de reception +uint8_t packetLen; //Longueur du paquet reçu +uint16_t adresseSource; //Adresse du noeud source +uint16_t adresseMulticast; //Adresse multicast reçue + +//Propriétés du paquet +#define ADRESSE_MULTICAST 0x7878 +#define TTL_MAX 2 //Time To Live avant expiration + +//Indices des champs du paquet +#define CHAMP_ADRESSE_DST 0 //Position de l'adresse de destination +#define CHAMP_TTL 2 //Position du TTL dans le paquet +#define CHAMP_ADRESSE_SRC 3 //Position du champ d'adressage +#define CHAMP_NUM_SEQ 5 //Position du numéro de séquence +#define CHAMP_MIN_PAYLOAD 6 //Position du premier octet de la payload + + +//Procédure d'affichage de la payload reçue +//À partir de l'indice de début de payload uniquement +void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){ + + M5.Lcd.printf("Payload : "); + Serial.printf("Payload : "); + for(int i=indiceDebut; i +#include +#include "SimpleWiNo.h" +#include + +//Objet Wino +SimpleWiNo wino; + +//Constantes de configuration des noeuds +#define ADRESSE_CLUSTER 0x4A89 +#define ADRESSE_NOEUD 0x0001 +#define CANAL 7 +#define DELAI_ENVOI 60000 + +//Variables pour le paquet +uint8_t txbuf[40]; //Buffer d'émission +uint8_t rxbuf[40]; //Buffer de réception +uint8_t packetLenTX; //Longueur du paquet émis +uint8_t packetLenRX; //Longueur du paquet reçu +uint16_t adresseSource; //Adresse du noeud source +uint16_t adresseDestination; //Adresse du noeud source +uint16_t adresseMulticast; //Adresse multicast reçue +uint8_t numSeq=0; //Numéro de séquence incrémenté pour l'envoi + + +//Variables de mémorisation de l'adresse +//et du numéro de séquence précédent +uint16_t adressePrec=0xFFFF; //Adresse reçue précédement +uint8_t numSeqPrec=255; //Numéro de séquence reçu précédement + + +//Propriétés du paquet +#define ADRESSE_MULTICAST 0x7878 //Adresse multicast du noeud +#define NB_PAYLOAD 10 //Nombre de données de payload +#define TTL_MAX 7 //Time To Live avant expiration + +//Indices des champs du paquet +#define CHAMP_ADRESSE_DST 0 //Position de l'adresse de destination +#define CHAMP_TTL 2 //Position du TTL dans le paquet +#define CHAMP_ADRESSE_SRC 3 //Position du champ d'adressage +#define CHAMP_NUM_SEQ 5 //Position du numéro de séquence +#define CHAMP_MIN_PAYLOAD 6 //Position du premier octet de la payload + +//Procédure de formatage de l'en tête et de la payload +//du paquet en émission +void formaterPaquet(uint8_t* longueur, uint8_t donnees[], uint8_t nSeq){ + + *longueur=0; + + //Ajout En-tete + + //Adresse Destination + wino.encodeUi16(ADRESSE_MULTICAST, &donnees[CHAMP_ADRESSE_DST]); + *longueur +=2; + + //Ajout du TTL + donnees[CHAMP_TTL]=0; + *longueur+=1; + + //Adresse Source + wino.encodeUi16(ADRESSE_NOEUD, &donnees[CHAMP_ADRESSE_SRC]); + *longueur +=2; + + //Numéro de séquence + donnees[CHAMP_NUM_SEQ]=nSeq; + *longueur +=1; + + //Ajout de la payload + for(int i=0; i attente){ + M5.Lcd.println("====Envoi Paquet===="); + Serial.println("====Envoi Paquet===="); + formaterPaquet(&packetLenTX, txbuf, numSeq); + afficherPaquet(packetLenTX, txbuf); + wino.send(0xFFFF, txbuf, packetLenTX); + numSeq+=1; + attente=millis()+DELAI_ENVOI; + } + + //Test Reception + if(wino.recv(&adresseSource, rxbuf, &packetLenRX) && (adresseSource!=3)){ + //Affichage des éléments du paquet reçu + M5.Lcd.println("=====Reception====="); + Serial.println("=====Reception====="); + //Affichage du noeud source + adresseSource=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_SRC]); + M5.Lcd.printf("Noeud Source : %X \n", adresseSource); + Serial.printf("Noeud Source : %X \n", adresseSource); + //Affichage Adresse Multicast + adresseMulticast=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_DST]); + M5.Lcd.printf("Adresse Multicast : %X \n", adresseMulticast); + Serial.printf("Adresse Multicast : %X \n", adresseMulticast); + //Affichage TTL + M5.Lcd.printf("TTL : %d \n", rxbuf[CHAMP_TTL]); + Serial.printf("TTL : %d \n", rxbuf[CHAMP_TTL]); + //Incrémentation TTL + rxbuf[CHAMP_TTL]+=1; + //Affichage du numéro de séquence + M5.Lcd.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]); + Serial.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]); + //Affichage Payload + afficherPayload(CHAMP_MIN_PAYLOAD, packetLenRX, rxbuf); + + //Test pour la réemission + //Le paquet n'a pas été émis par le noeud lui-même + if(adresseSource!=ADRESSE_NOEUD){ + //Même adresse multicast et TTL inférieur au max + if((adresseMulticast==ADRESSE_MULTICAST) && (rxbuf[CHAMP_TTL]<=TTL_MAX)){ + //Test si le paquet n'a pas été déjà reçu + if((adressePrec!=adresseSource) || (numSeqPrec!=rxbuf[CHAMP_NUM_SEQ])){ + M5.Lcd.println("=====Réemission Paquet====="); + Serial.println("=====Réemission Paquet====="); + adressePrec=adresseSource; + numSeqPrec=rxbuf[CHAMP_NUM_SEQ]; + wino.send(0xFFFF, rxbuf, packetLenRX); + } + else{ + M5.Lcd.println("===Déjà Reçu==="); + Serial.println("===Déjà Reçu==="); + } + } + else{ + M5.Lcd.println("Adresse multicast incorecte ou TTL dépassé"); + Serial.println("Adresse multicast incorecte ou TTL dépassé"); + } + } + else{ + M5.Lcd.println("===Paquet émis par le noeud==="); + Serial.println("===Paquet émis par le noeud==="); + } + + } +} diff --git a/Codes_source/Couche_3/Sprint5/NoeudRelais/NoeudRelais.ino b/Codes_source/Couche_3/Sprint5/NoeudRelais/NoeudRelais.ino new file mode 100644 index 0000000..57afc17 --- /dev/null +++ b/Codes_source/Couche_3/Sprint5/NoeudRelais/NoeudRelais.ino @@ -0,0 +1,128 @@ +#include +#include +#include "SimpleWiNo.h" +#include + +//Objet Wino +SimpleWiNo wino; + +//Constantes de configuration des noeuds +#define ADRESSE_CLUSTER 0x4A89 +#define ADRESSE_NOEUD 0x0002 +#define CANAL 7 + +//Variables pour le paquet +uint8_t rxbuf[40]; //Buffer de reception +uint8_t packetLenRX; //Longueur du paquet reçu +uint16_t adresseSource; //Adresse du noeud source +uint16_t adresseMulticast; //Adresse multicast reçue + +//Variables de mémorisation de l'adresse +//et du numéro de séquence précédent +uint16_t adressePrec=0xFFFF; //Adresse reçue précédement +uint8_t numSeqPrec=255; //Numéro de séquence reçu précédement + +//Propriétés du paquet +#define ADRESSE_MULTICAST 0x7878 +#define TTL_MAX 7 //Time To Live avant expiration + +//Indices des champs du paquet (format paquet) +#define CHAMP_ADRESSE_DST 0 //Position de l'adresse de destination +#define CHAMP_TTL 2 //Position du TTL dans le paquet +#define CHAMP_ADRESSE_SRC 3 //Position du champ d'adressage +#define CHAMP_NUM_SEQ 5 //Position du numéro de séquence +#define CHAMP_MIN_PAYLOAD 6 //Position du premier octet de la payload + + +//Procédure d'affichage de la payload reçue +//À partir de l'indice de début de payload uniquement +void afficherPayload(uint8_t indiceDebut, uint8_t longueur, uint8_t donnees[]){ + + M5.Lcd.printf("Payload : "); + Serial.printf("Payload : "); + for(int i=indiceDebut; i +#include +#include "SimpleWiNo.h" +#include + +//Objet Wino +SimpleWiNo wino; + +//Constantes de configuration des noeuds +#define ADRESSE_CLUSTER 0x4A89 +#define ADRESSE_NOEUD 0x0001 +#define CANAL 7 +#define DELAI_ENVOI 60000 + +//Variables pour le paquet +uint8_t txbuf[40]; //Buffer d'émission +uint8_t rxbuf[40]; //Buffer de réception +uint8_t packetLenTX; //Longueur du paquet émis +uint8_t packetLenRX; //Longueur du paquet reçu +uint16_t adresseMacSource; //Adresse de couche 2 du noeud source +uint16_t adresseIpSource; //Adresse de couche 3 du noeud source +uint16_t adresseDestination; //Adresse du noeud source +uint16_t adresseMulticast; //Adresse multicast reçue +uint8_t numSeq=0; //Numéro de séquence incrémenté pour l'envoi + +//Propriétés du paquet +#define ADRESSE_MULTICAST 0x7878 //Adresse multicast du noeud +#define NB_PAYLOAD 10 //Nombre de données de payload +#define TTL_MAX 7 //Time To Live avant expiration + +//Indices des champs du paquet +#define CHAMP_ADRESSE_DST 0 //Position de l'adresse de destination +#define CHAMP_TTL 2 //Position du TTL dans le paquet +#define CHAMP_ADRESSE_SRC 3 //Position du champ d'adressage +#define CHAMP_NUM_SEQ 5 //Position du numéro de séquence +#define CHAMP_MIN_PAYLOAD 6 //Position du premier octet de la payload + +//Mémorisation des paquets + +//Nombre de paquets maximums mémorisables +#define NB_PAQUET_MEM 10 + +//Structure pour l'identification +struct identifiant{ + uint16_t srcAddr; + uint8_t sqn; +}; +typedef struct identifiant IDENTIFIANT; + +uint8_t indiceMemId=0; //Indice pour la mise à jour dans le tableau +IDENTIFIANT idRecu; //Identifiant courant du paquet reçu +IDENTIFIANT tabId[NB_PAQUET_MEM]; //Tableau d'identifiants + +//Procédures pour la mémorisation + +//Initialisation du tableau d'identifiants +void initTabId(IDENTIFIANT tab[]){ + for(int i=0; i attente){ + M5.Lcd.println("====Envoi Paquet===="); + Serial.println("====Envoi Paquet===="); + formaterPaquet(&packetLenTX, txbuf, numSeq); + afficherPaquet(packetLenTX, txbuf); + wino.send(0xFFFF, txbuf, packetLenTX); + numSeq+=1; + attente=millis()+DELAI_ENVOI; + } + + //Test Reception + if(wino.recv(&adresseMacSource, rxbuf, &packetLenRX) && (adresseMacSource!=3)){ + //Affichage des éléments du paquet reçu + M5.Lcd.println("=====Reception====="); + Serial.println("=====Reception====="); + //Affichage du noeud source + adresseIpSource=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_SRC]); + M5.Lcd.printf("MAC SRC : %X | ", adresseMacSource); + Serial.printf("MAC SRC : %X | ", adresseMacSource); + M5.Lcd.printf("IP SRC : %X \n", adresseIpSource); + Serial.printf("IP SRC : %X \n", adresseIpSource); + //Affichage Adresse Multicast + adresseMulticast=wino.decodeUi16(&rxbuf[CHAMP_ADRESSE_DST]); + M5.Lcd.printf("Adresse Multicast : %X \n", adresseMulticast); + Serial.printf("Adresse Multicast : %X \n", adresseMulticast); + //Affichage TTL + M5.Lcd.printf("TTL : %d \n", rxbuf[CHAMP_TTL]); + Serial.printf("TTL : %d \n", rxbuf[CHAMP_TTL]); + //Incrémentation TTL + rxbuf[CHAMP_TTL]+=1; + //Affichage du numéro de séquence + M5.Lcd.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]); + Serial.printf("Num Seq : %d \n", rxbuf[CHAMP_NUM_SEQ]); + //Affichage Payload + afficherPayload(CHAMP_MIN_PAYLOAD, packetLenRX, rxbuf); + + //Test pour la réemission + //Le paquet n'a pas été émis par le noeud lui-même + if(adresseIpSource!=ADRESSE_NOEUD){ + //Même adresse multicast et TTL inférieur au max + if((adresseMulticast==ADRESSE_MULTICAST) && (rxbuf[CHAMP_TTL]<=TTL_MAX)){ + + //Récupération de l'identifiant du paquet recu + idRecu.srcAddr=adresseIpSource; + idRecu.sqn=rxbuf[CHAMP_NUM_SEQ]; + + //Test si le paquet n'a pas déjà été reçu + if(!PaquetDejaRoute(idRecu, tabId)){ + M5.Lcd.println("=====Reemission Paquet====="); + Serial.println("=====Reemission Paquet====="); + //Ajout du nouvel id dans le tableau + ajoutTabId(idRecu, tabId, &indiceMemId); + //Réemission du paquet + wino.send(0xFFFF, rxbuf, packetLenRX); + + //Affichage des id mémorisés + AfficheId(tabId); + } + else{ + M5.Lcd.println("===Deja Recu==="); + Serial.println("===Deja Recu==="); + } + } + else{ + M5.Lcd.println("Adresse multicast incorecte ou TTL depasse"); + Serial.println("Adresse multicast incorecte ou TTL depasse"); + } + } + else{ + M5.Lcd.println("===Paquet emis par le noeud==="); + Serial.println("===Paquet emis par le noeud==="); + } + + } +} diff --git a/Codes_source/Couche_3/Sprint6/NoeudRelais/NoeudRelais.ino b/Codes_source/Couche_3/Sprint6/NoeudRelais/NoeudRelais.ino new file mode 100644 index 0000000..7e12ba8 --- /dev/null +++ b/Codes_source/Couche_3/Sprint6/NoeudRelais/NoeudRelais.ino @@ -0,0 +1,197 @@ +#include +#include +#include "SimpleWiNo.h" +#include + +//Objet Wino +SimpleWiNo wino; + +//Constantes de configuration des noeuds +#define ADRESSE_CLUSTER 0x4A89 +#define ADRESSE_NOEUD 0x0002 +#define CANAL 7 + +//Variables pour le paquet +uint8_t rxbuf[40]; //Buffer de reception +uint8_t packetLenRX; //Longueur du paquet reçu +uint16_t adresseMacSource; //Adresse de couche 2 du noeud source +uint16_t adresseIpSource; //Adresse de couche 3 du noeud source +uint16_t adresseMulticast; //Adresse multicast reçue + + +//Propriétés du paquet +#define ADRESSE_MULTICAST 0x7878 +#define TTL_MAX 7 //Time To Live avant expiration + +//Indices des champs du paquet (format paquet) +#define CHAMP_ADRESSE_DST 0 //Position de l'adresse de destination +#define CHAMP_TTL 2 //Position du TTL dans le paquet +#define CHAMP_ADRESSE_SRC 3 //Position du champ d'adressage +#define CHAMP_NUM_SEQ 5 //Position du numéro de séquence +#define CHAMP_MIN_PAYLOAD 6 //Position du premier octet de la payload + +//Mémorisation des paquets + +//Nombre de paquets maximums mémorisables +#define NB_PAQUET_MEM 10 + +//Structure pour l'identification +struct identifiant{ + uint16_t srcAddr; + uint8_t sqn; +}; +typedef struct identifiant IDENTIFIANT; + +uint8_t indiceMemId=0; //Indice pour la mise à jour dans le tableau +IDENTIFIANT idRecu; //Identifiant courant du paquet reçu +IDENTIFIANT tabId[NB_PAQUET_MEM]; //Tableau d'identifiants + +//Procédures pour la mémorisation + +//Initialisation du tableau d'identifiants +void initTabId(IDENTIFIANT tab[]){ + for(int i=0; i