Skip to content
Snippets Groups Projects
Select Git revision
  • 242d7900b84e217a88e652faca3bf3e0cf1ec193
  • main default protected
  • addingScalability
  • Kernel_Module
  • Packaging
  • fixingProjectStructure
  • addingInterProcessCommunication
  • addingServiceFile
  • addingProcesses
9 results

main.c

Blame
  • user avatar
    Chris authored
    242d7900
    History
    main.c 5.04 KiB
    /*
    @file main.c
    @brief empfage daten von prozesse und senden an kernel
    @author Felix Mose, Christoph Schwierz
    @date 2025-02-14
    
    @details
    dieses Programm sucht nach prozessen und öffnet dessen zugehörige pipes
    er liest die Daten aus den Pipes, erstellt packages mit den daten und checksum 
    und sendet diese an den kernel mit einem character device interface
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <string.h>
    #include <errno.h>
    #include <zlib.h>
    
    // static const char *PIPE_ONE = "/tmp/pipeOne";
    // static const char *PIPE_TWO = "/tmp/pipeTwo";
    
    static const char *CHAR_DEV = "/dev/packet_receiver";
    
    // static const char *SENDER_ID = "0x91";
    
    ssize_t read_pipe(int *fd, char *buf, size_t bufSize, const char *pipeName) {
        // Alles mit 0 füllen, um es später einfach als String verarbeiten zu können.
        memset(buf, 0, bufSize);
    
        // Blocking read
        ssize_t bytesRead = read(*fd, buf, bufSize - 1);
        if (bytesRead > 0) {
            // buf[bytesRead] = '\0'; // Schon durch memset garantiert
            return bytesRead;
        }
        if (bytesRead == 0) {
            // EOF -> Schreibseite geschlossen
            printf("Pipe '%s' closed by writer. Reopening...\n", pipeName);
            close(*fd);
    
            // Neu öffnen (blockierend)
            *fd = open(pipeName, O_RDONLY);
            if (*fd == -1) {
                perror("Reopen pipe");
            }
            // bytesRead = 0 bedeutet hier: wir haben keine Daten
            return 0;
        }
    
        // Fehlerfall (bytesRead < 0)
        perror("read pipe");
        return -1;
    }
    
    void build_package(char *package, size_t package_size, const char *payload, int value_id) {
        // Zwischenspeicher für die neue Komponente
        char tmp[128];
        // VALUE_ID=<id> VALUE=<payload>
        snprintf(tmp, sizeof(tmp), " VALUE_ID=%d VALUE=%s", value_id, payload);
    
        // Hänge tmp an package
        strncat(package, tmp, package_size - strlen(package) - 1);
    }
    
    void build_crc_checksum(char *package, size_t package_size) {
        // CRC berechnen
        uLong c = crc32(0L, Z_NULL, 0);
        c = crc32(c, (const Bytef*)package, strlen(package));
    
        char tmp[32];
        // z.B. " CRC=0x1A2B3C4D"
        snprintf(tmp, sizeof(tmp), " CRC=0x%08lX", c);
    
        // ans package anhängen
        strncat(package, tmp, package_size - strlen(package) - 1);
    }
    
    void send_package(const char *package, const int fdCharDev) {
        char transmitBuf[256] = {0};
    
        // Kopiere Package in transmitBuf
        snprintf(transmitBuf, sizeof(transmitBuf), "%s", package);
    
        const ssize_t written = write(fdCharDev, transmitBuf, strlen(transmitBuf));
        if (written < 0) {
            perror("write /dev/packet_receiver");
        } else {
            printf("Wrote %ld bytes to %s\n", written, CHAR_DEV);
        }
    }
    
    // argc = Anzahl Pipes *argv[] Pipe Pfade
    int main(const int argc, char *argv[]) {
        const int num_pipes = argc - 1;
    
        int *fds = calloc(num_pipes, sizeof(int));
        if (!fds) {
            perror("calloc fds");
            return 1;
        }
    
        for (int i = 0; i < num_pipes; i++) {
            const char *pipeName = argv[i + 1];
            // mkfifo() nur ausführen, wenn die Pipes noch nicht existieren,
            // bzw. Fehler ignorieren, falls schon existiert:
            if (mkfifo(pipeName, 0666) < 0 && errno != EEXIST) {
                perror("mkfifo pipe");
                free(fds);
                return 1;
            }
    
            // Pipes blockierend öffnen
            fds[i] = open(pipeName, O_RDONLY);
            if (fds[i] == -1) {
                perror("open pipe for reading");
                free(fds);
                return 1;
            }
        }
    
        // Open the char device for writing
        const int fdCharDev = open(CHAR_DEV, O_WRONLY);
        if (fdCharDev == -1) {
            perror("open /dev/packet_receiver");
            // Aufräumen
            for (int i = 0; i < num_pipes; i++) {
                close(fds[i]);
            }
            free(fds);
            return 1;
        }
        printf("Opened %s for writing.\n", CHAR_DEV);
    
        // Dauerhafte Lese-Schleife
        while (1) {
            char package[256];
            snprintf(package, sizeof(package), "SENDER=0x91");
    
            // Lese von jeder Pipe und ergänze das Package
            for (int i = 0; i < num_pipes; i++) {
                char pipeBuf[128];
    
                const ssize_t ret = read_pipe(&fds[i], pipeBuf, sizeof(pipeBuf), argv[i + 1]);
                if (ret > 0) {
                    // ret Bytes gelesen in pipeBuf -> package anhängen
                    build_package(package, sizeof(package), pipeBuf, i);
                } else if (ret == -1) {
                    // Fehler beim Lesen
                    fprintf(stderr, "Error reading from pipe\n");
                    free(fds);
                    return 1;
                }
            }
            build_crc_checksum(package, sizeof(package));
    
            // Jetzt an /dev/packet_receiver schicken
            if (strlen(package) > 0) {
                send_package(package, fdCharDev);
            }
    
            // Kurze Pause, damit CPU-Last nicht durch
            // Dauerschleife hochgetrieben wird
            usleep(200000); // 200 ms
        }
        // Sollte man jemals aus der while(1)-Schleife ausbrechen:
        for (int i = 0; i < argc; i++) {
            close(fds[i]);
        }
    
        return 0;
    }