seToNc : Serial To Netcat ou comment envoyer via le réseau des informations reçues sur le port série

seToNc : Serial To Netcat ou comment envoyer via le réseau des informations reçues sur le port série

Salut salut!

Je vous présenterai aujourd’hui la programmation d’un petit soft sous linux en C qui permet de récupérer des données envoyées sur le port USB de la machine, de les formater et de les renvoyer sur le réseau (en clair). Commençons donc tout de suite avec une petite description algorithmique:
Le programme s’occupera de créer un processus fils qui éxecutera netcat (outil de communication réseau), le processus père lira la liaison série pour envoyer toutes les données au fils, qui lui enverra le tout sur le réseau. Je me sers des fork() pour créer un processus fils, et des pipes pour communiquer entre ces deux processus, j’utilise ensuite dup2() pour rediriger la lecture standard sur le pipe crée puis la primitive execlp() pour éxecuter une commande. Voici donc le code, séparé dans deux fichiers:

seToNc.c

 /**
 Nom: SerieToNetcat
 Description: Récupère les informations  envoyées
 sur le port série et les renvoie par netcat à l'adresse
 ip via le port donnés en paramêtre.
 **/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int MAX = 300;
pid_t idp;
int fd;
void traiteSig(int);
char readChar();
int main(int argc, char* argv[]) {
    signal(SIGINT, traiteSig);
    int descP[2], next = 1;
    char *msg0 = "Erreur lors de la lecture du port sérien";
    char *msg1 = "Erreur lors du pipen";
    char *msg2 = "Erreur lors du forkn";
    char *msg3 = "Erreur lors de l'execn";
    char buff[10];
   
    //Test d'une bonne utilisation
    if (argc != 3) {
        printf("Usage: setonc ipAddress Portn");
        exit(1);
    }
   
    /* Ouverture de la liaison serie */
    if ( (fd=open("/dev/ttyACM0",O_RDONLY)) == -1 ) {
        printf("%s", msg0);
        exit(1);
    }

    char *ip = argv[1];
    char *port = argv[2];

    //Création du pipe
    int verif = pipe(descP);
    if (verif  ==  -1) {
        printf("%s", msg1);
        exit(1);
    }

    //Création du processus fils, qui lancera netcat
    if ((idp = fork()) == -1 ) {
        printf("%s", msg2);
        exit(2);
    }
    
    //Si le proccessus fils est en run
    if (idp == 0) {
        close(descP[1]); //On ferme l'accès en lecture
        dup2(descP[0], 0);
        execlp("nc", "netcat", ip, port, NULL);
        printf("%s", msg3);
        exit(3);
    }
    else {
        close(descP[0]); //On ferme l'accès en écriture
        //On tourne en boucle pour envoyer les données reçues sur le port série
        while (1) {
            //On récupère les données sur le port série
            buff[0] = readChar(fd);
            next = write(descP[1], buff, 1);
        }
    }
}
void traiteSig(int signal) {
    int code;
    /* Fermeture du port serie */
    close(fd);
    printf("nFin de la connexionn");
    wait(&code);  //Le père attend la fin du processus fils (passé en zombie) pr le killer
    exit(0);
}

Voici le code du fichier readChar.c

#include 
#include 

char readChar(int fd) {
    char c;
    struct termios    termios_p;

    /* Lecture des parametres courants */
    tcgetattr(fd,&termios_p);
    /* On ignore les BREAK et les caracteres avec erreurs de parite */
    termios_p.c_iflag = IGNBRK | IGNPAR;
    /* Pas de mode de sortie particulier */
    termios_p.c_oflag = 0;
    /* Liaison a 9600 bps avec 7 bits de donnees et une parite paire */
    termios_p.c_cflag = B9600 | CS7 | PARENB;
    /* Mode non-canonique avec echo */
    termios_p.c_lflag = ECHO;
    /* Caracteres immediatement disponibles */
    termios_p.c_cc[VMIN] = 1;
    termios_p.c_cc[VTIME] = 0;
    /* Sauvegarde des nouveaux parametres */
    tcsetattr(fd,TCSANOW,&termios_p);
    /* Lecture */
    read(fd,&c,1);
    
    return c;
}

Il suffit alors de taper la commande suivante pour compiler le programme et le tour est joué:

gcc -o seToNc seToNc.c readChar.c

J’essairai par la suite de faire une deuxième version du programme, en utilisant les threads et les sockets ou bien les segments de mémoire partagés. Je ne maîtrise pas encore parfaitement ces notions alors j’y vais petit à petit! En ce qui concerne l’intérêt du programme, il me sert à récupérer des données provenant des montages Arduino que je fais.
Bon codage!

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.

*

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.