Skip to content
Snippets Groups Projects
frontend_nodes.c 3.71 KiB
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <err.h>
#include <inttypes.h>

#include "frontend_nodes.h"
#include "config.h"

/* Get the block_id, type_id and name of
 * all of the nodes in the current comp_graph.
 *
 * Returns 0 on success, 1 on error
 *
 * node_data and num_nodes are out-pointers.
 * node_data must be a pointer to NULL
 * num_nodes must be a pointer to zero
 * 
 */
int frontend_getnodes(
        struct backend_conn * conn,
        struct frontend_node_data ** node_data,
        size_t * num_nodes) {
    if ((node_data == NULL) || (num_nodes == NULL)) {
        return 1;
    }

    if ((*node_data != NULL) || (*num_nodes != 0)) {
        return 1;
    }

    char msg[64] = "";
    int written;

    snprintf(msg, 64, "getnodes\n");

    if((written = ucart_backendWrite(conn, msg)) < 0) {
        return 1;
    }

    size_t pendingResponses = 1;
    char * response;

    while (pendingResponses) {
        response = ucart_backendGetline(conn);
        if (response == NULL) {
            warnx("Line not returned from backend");
            return 1;
        }

        if (strncmp(response, "getnodes", 8) != 0) {
            continue;
        }

        size_t num_nodes_ret = 0;
        size_t offset = 0;

        sscanf(response, "getnodes %lu %n", &num_nodes_ret,  (int * )&offset);
        response += offset;

        /* Resize if necessary */
        if (num_nodes_ret != *num_nodes) {
            *num_nodes = num_nodes_ret;
            *node_data = realloc(*node_data, sizeof(**node_data) * (*num_nodes));
            if (!*node_data) {
                return 1;
            }
        }

        struct frontend_node_data * arr = *node_data;
        for (size_t i = 0; i < *num_nodes; ++i) {
            sscanf(response, "%" SCNd16 " %n", &arr[i].block, (int*)&offset);
#if FRONTEND_DEBUG_PRINT == 1
            printf("found block %d\n", arr[i].block);
#endif 
            response += offset;
        }

        for (size_t i = 0; i < *num_nodes; ++i) {
            sscanf(response, "%" SCNd16 " %n", &arr[i].type, (int*)&offset);
#if FRONTEND_DEBUG_PRINT == 1
            printf("found type %d\n", arr[i].type);
#endif 
            response += offset;
        }

        for (size_t i = 0; i < *num_nodes; ++i) {
            char tmp_name[512];
            sscanf(response, " '%[^\t\n']' %n", (char *)&tmp_name, (int *)&offset);
            arr[i].name = malloc(sizeof(*arr[i].name) * strlen(tmp_name) + 1);
            strcpy((char*)arr[i].name, tmp_name);
#if FRONTEND_DEBUG_PRINT == 1
            printf("found name '%s'\n", arr[i].name);
#endif
            response += offset;
        }
        pendingResponses--;
    }
    
    return 0;
}

/* Set the value of block.param
 *
 * Returns 0 on success, 1 on error
 */
int frontend_addnode(
        struct backend_conn * conn,
        struct frontend_node_data * node_data) {
    
    char msg[16 + strlen(node_data->name)];
    int written;

    snprintf(msg, 16 + strlen(node_data->name), "addnode %" PRId16 " %s\n", node_data->type, node_data->name);

    if((written = ucart_backendWrite(conn, msg)) < 0) {
        return 1;
    }

    size_t pendingResponses = 1;
    char * response;

    while (pendingResponses) {
        response = ucart_backendGetline(conn);
        if (response == NULL) {
            warnx("Line not returned from backend");
            return 1;
        }

        if (strncmp(response, "addnode", 7) != 0) {
            continue;
        }

        sscanf(response, "addnode %" SCNd16, &node_data->block);

        pendingResponses--;
    }
    
    return 0;
}

void frontend_free_node_data(
        struct frontend_node_data *nd,
        size_t num_nodes)
{
    for (size_t i = 0; i < num_nodes; i++) {
        free(nd[i].name);
    }
    free(nd);
}