Example #1
0
static errno_t
sbus_introspect_args(FILE *file,
                     enum sbus_arg_type type,
                     const struct sbus_argument *args)
{
    errno_t ret;
    int i;

    if (args == NULL) {
        return EOK;
    }

    for (i = 0; args[i].name != NULL; i++) {
        switch (type) {
        case SBUS_ARG_SIGNAL:
            WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL_ARG,
                          args[i].type, args[i].name);
            break;
        case SBUS_ARG_IN:
            WRITE_OR_FAIL(file, ret, done, FMT_METHOD_ARG,
                          args[i].type, args[i].name, "in");
            break;
        case SBUS_ARG_OUT:
            WRITE_OR_FAIL(file, ret, done, FMT_METHOD_ARG,
                          args[i].type, args[i].name, "out");
            break;
        }
    }

    ret = EOK;

done:
    return ret;
}
Example #2
0
static char *
sbus_introspect(TALLOC_CTX *mem_ctx,
                const char *node,
                const char **nodes,
                struct sbus_interface_list *list)
{
    struct sbus_interface_list *item;
    char *introspection = NULL;
    FILE *memstream;
    char *buffer;
    size_t size;
    errno_t ret;

    memstream = open_memstream(&buffer, &size);
    if (memstream == NULL) {
        goto done;
    }

    WRITE_OR_FAIL(memstream, ret, done, FMT_DOCTYPE);
    WRITE_OR_FAIL(memstream, ret, done, FMT_NODE, node);

    DLIST_FOR_EACH(item, list) {
        ret = sbus_introspect_iface(memstream, item->interface);
        if (ret != EOK) {
            goto done;
        }
    }
Example #3
0
static int
sbus_introspect_iface(FILE *file, struct sbus_interface *iface)
{
    errno_t ret;

    WRITE_OR_FAIL(file, ret, done, FMT_IFACE, iface->name);

    ret = sbus_introspect_annotations(file, false, iface->annotations);
    if (ret != EOK) {
        goto done;
    }

    ret = sbus_introspect_methods(file, iface->methods);
    if (ret != EOK) {
        goto done;
    }

    ret = sbus_introspect_signals(file, iface->signals);
    if (ret != EOK) {
        goto done;
    }

    ret = sbus_introspect_properties(file, iface->properties);
    if (ret != EOK) {
        goto done;
    }

    WRITE_OR_FAIL(file, ret, done, FMT_IFACE_CLOSE);

    ret = EOK;

done:
    return ret;
}
Example #4
0
static errno_t
sbus_introspect_properties(FILE *file,
                           const struct sbus_property *properties)
{
    struct sbus_introspect_property *props;
    const char *mode;
    errno_t ret;
    int len;
    int i;

    if (properties == NULL) {
        return EOK;
    }

    for (len = 0; properties[len].name != NULL ; len++);

    props = talloc_zero_array(NULL, struct sbus_introspect_property, len + 1);
    if (props == NULL) {
        return ENOMEM;
    }

    for (i = 0; properties[i].name != NULL; i++) {
        sbus_introspect_property_set(props, &properties[i]);
    }

    for (i = 0; props[i].name != NULL; i++) {
        mode = sbus_introspect_property_mode(&props[i]);

        if (EMPTY(props[i].annotations)) {
            WRITE_OR_FAIL(file, ret, done, FMT_PROPERTY_EMPTY,
                          props[i].name, props[i].type, mode);
            continue;
        }

        WRITE_OR_FAIL(file, ret, done, FMT_PROPERTY_OPEN,
                      props[i].name, props[i].type, mode);

        ret = sbus_introspect_annotations(file, true, props[i].annotations);
        if (ret != EOK) {
            goto done;
        }

        WRITE_OR_FAIL(file, ret, done, FMT_PROPERTY_CLOSE);
    }

    ret = EOK;

done:
    talloc_free(props);
    return ret;
}
Example #5
0
static errno_t
sbus_introspect_methods(FILE *file,
                        const struct sbus_method *methods)
{
    errno_t ret;
    int i;

    if (methods == NULL) {
        return EOK;
    }

    for (i = 0; methods[i].name != NULL; i++) {
        if (EMPTY(methods[i].annotations)
                && EMPTY(methods[i].arguments->input)
                && EMPTY(methods[i].arguments->output)) {
            WRITE_OR_FAIL(file, ret, done, FMT_METHOD_EMPTY, methods[i].name);
            continue;
        }

        WRITE_OR_FAIL(file, ret, done, FMT_METHOD_OPEN, methods[i].name);

        ret = sbus_introspect_annotations(file, true, methods[i].annotations);
        if (ret != EOK) {
            goto done;
        }

        ret = sbus_introspect_args(file, SBUS_ARG_IN,
                                   methods[i].arguments->input);
        if (ret != EOK) {
            goto done;
        }

        ret = sbus_introspect_args(file, SBUS_ARG_OUT,
                                   methods[i].arguments->output);
        if (ret != EOK) {
            goto done;
        }

        WRITE_OR_FAIL(file, ret, done, FMT_METHOD_CLOSE);
    }

    ret = EOK;

done:
    return ret;
}
Example #6
0
static errno_t
sbus_introspect_signals(FILE *file,
                        const struct sbus_signal *signals)
{
    errno_t ret;
    int i;

    if (signals == NULL) {
        return EOK;
    }

    for (i = 0; signals[i].name != NULL; i++) {
        if (EMPTY(signals[i].annotations) && EMPTY(signals[i].arguments)) {
            WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL_EMPTY, signals[i].name);
            continue;
        }

        WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL_OPEN, signals[i].name);

        ret = sbus_introspect_annotations(file, true, signals[i].annotations);
        if (ret != EOK) {
            goto done;
        }

        ret = sbus_introspect_args(file, SBUS_ARG_SIGNAL, signals[i].arguments);
        if (ret != EOK) {
            goto done;
        }

        WRITE_OR_FAIL(file, ret, done, FMT_SIGNAL_CLOSE);
    }

    ret = EOK;

done:
    return ret;
}
Example #7
0
ssize_t write_crnl(int to_fd, char *buffer, ssize_t len)
{
    char *newline;
    ssize_t r, retval = 0;
    ssize_t count, offset = 0;
    
    for(offset = 0; offset < len; offset += count) {
        // Set the number of characters to write to the number
        // of characters remaining in the buffer.
        count   = len - offset;
        newline = memchr(buffer + offset, '\n', count);

        // Ensure that we write no further than any newline characters.
        if (newline) {
            // Use how far the newline lies beyond the current offset
            // in the buffer, plus one to include the nl.
            count = newline - buffer - offset + 1;
        }

// Macro to automate performing a safe write, deciding whether to return
// based on the return value, and finally increasing the count.
#define WRITE_OR_FAIL(f, b, l) {  \
        r = safe_write(f, b, l);  \
        if (r == -1) return r;    \
        else         retval += r; \
}

        WRITE_OR_FAIL(to_fd, buffer + offset, count);

        if (newline)
            WRITE_OR_FAIL(to_fd, "\r", 1);
#undef WRITE_OR_FAIL
    }
    
    return retval;
}
Example #8
0
static int
sbus_introspect_nodes(FILE *file, const char **nodes)
{
    errno_t ret;
    int i;

    if (nodes == NULL) {
        return EOK;
    }

    for (i = 0; nodes[i] != NULL; i++) {
        WRITE_OR_FAIL(file, ret, done, FMT_CHILD_NODE, nodes[i]);
    }

    ret = EOK;

done:
    return ret;
}
Example #9
0
static errno_t
sbus_introspect_annotations(FILE *file,
                            bool inside,
                            const struct sbus_annotation *annotations)
{
    errno_t ret;
    const char *indent = inside ? "  " : "";
    int i;

    if (annotations == NULL) {
        return EOK;
    }

    for (i = 0; annotations[i].name != NULL; i++) {
        WRITE_OR_FAIL(file, ret, done, FMT_ANNOTATION, indent,
                      annotations[i].name, annotations[i].value);
    }

    ret = EOK;

done:
    return ret;
}
Example #10
0
int fiasco_unpack(struct fiasco * fiasco, const char * dir) {

    int fd = -1;
    char * name = NULL;
    char * layout_name = NULL;
    struct image * image;
    struct image_list * image_list;
    uint32_t size;
    char cwd[256];
    unsigned char buf[4096];

    if ( dir ) {

        memset(cwd, 0, sizeof(cwd));

        if ( ! getcwd(cwd, sizeof(cwd)) ) {
            ERROR_INFO("Cannot store current directory");
            return -1;
        }

        if ( chdir(dir) < 0 ) {
            ERROR_INFO("Cannot change current directory to %s", dir);
            return -1;
        }

    }

    fiasco_print_info(fiasco);

    image_list = fiasco->first;

    while ( image_list ) {

        image = image_list->image;

        name = image_name_alloc_from_values(image);
        if ( ! name )
            return -1;

        printf("\n");
        printf("Unpacking image...\n");
        image_print_info(image);

        if ( image->layout ) {

            layout_name = calloc(1, strlen(name) + strlen(".layout") + 1);
            if ( ! layout_name )
                ALLOC_ERROR_RETURN(-1);

            sprintf(layout_name, "%s.layout", name);

            printf("    Layout file: %s\n", layout_name);

        }

        printf("    Output file: %s\n", name);

        if ( ! simulate ) {
            fd = open(name, O_RDWR|O_CREAT|O_TRUNC, 0644);
            if ( fd < 0 ) {
                ERROR_INFO("Cannot create output file %s", name);
                return -1;
            }
        }

        free(name);

        image_seek(image, 0);
        while ( 1 ) {
            size = image_read(image, buf, sizeof(buf));
            if ( size == 0 )
                break;
            WRITE_OR_FAIL(name, fd, buf, size);
        }

        close(fd);

        if ( image->layout ) {

            if ( ! simulate ) {
                fd = open(layout_name, O_RDWR|O_CREAT|O_TRUNC, 0644);
                if ( fd < 0 ) {
                    ERROR_INFO("Cannot create layout file %s", layout_name);
                    return -1;
                }
            }

            free(layout_name);

            WRITE_OR_FAIL(layout_name, fd, image->layout, (int)strlen(image->layout));

            close(fd);

        }

        image_list = image_list->next;

    }

    if ( dir ) {
        if ( chdir(cwd) < 0 ) {
            ERROR_INFO("Cannot change current directory back to %s", cwd);
            return -1;
        }
    }

    printf("\nDone\n\n");
    return 0;

}
Example #11
0
int fiasco_write_to_file(struct fiasco * fiasco, const char * file) {

    int fd = -1;
    int i;
    int device_count;
    uint32_t size;
    uint32_t length;
    uint16_t hash;
    uint8_t length8;
    char ** device_hwrevs_bufs;
    const char * str;
    const char * type;
    struct image_list * image_list;
    struct image * image;
    unsigned char buf[4096];

    if ( ! fiasco )
        return -1;

    printf("Generating Fiasco image %s...\n", file);

    if ( ! fiasco->first )
        FIASCO_WRITE_ERROR(file, fd, "Nothing to write");

    if ( fiasco->name && strlen(fiasco->name)+1 > UINT8_MAX )
        FIASCO_WRITE_ERROR(file, fd, "Fiasco name string is too long");

    if ( fiasco->swver && strlen(fiasco->swver)+1 > UINT8_MAX )
        FIASCO_WRITE_ERROR(file, fd, "SW version string is too long");

    if ( ! simulate ) {
        fd = open(file, O_RDWR|O_CREAT|O_TRUNC, 0644);
        if ( fd < 0 ) {
            ERROR_INFO("Cannot create file");
            return -1;
        }
    }

    printf("Writing Fiasco header...\n");

    WRITE_OR_FAIL(file, fd, "\xb4", 1); /* signature */

    if ( fiasco->name[0] )
        str = fiasco->name;
    else
        str = "OSSO UART+USB";

    length = 4 + strlen(str) + 3;
    if ( fiasco->swver[0] )
        length += strlen(fiasco->swver) + 3;
    length = htonl(length);
    WRITE_OR_FAIL(file, fd, &length, 4); /* FW header length */

    if ( fiasco->swver[0] )
        length = htonl(2);
    else
        length = htonl(1);
    WRITE_OR_FAIL(file, fd, &length, 4); /* FW header blocks count */

    /* Fiasco name */
    length8 = strlen(str)+1;
    WRITE_OR_FAIL(file, fd, "\xe8", 1);
    WRITE_OR_FAIL(file, fd, &length8, 1);
    WRITE_OR_FAIL(file, fd, str, length8);

    /* SW version */
    if ( fiasco->swver[0] ) {
        printf("Writing SW version: %s\n", fiasco->swver);
        length8 = strlen(fiasco->swver)+1;
        WRITE_OR_FAIL(file, fd, "\x31", 1);
        WRITE_OR_FAIL(file, fd, &length8, 1);
        WRITE_OR_FAIL(file, fd, fiasco->swver, length8);
    };

    printf("\n");

    image_list = fiasco->first;

    while ( image_list ) {

        image = image_list->image;

        if ( ! image )
            FIASCO_WRITE_ERROR(file, fd, "Empty image");

        printf("Writing image...\n");
        image_print_info(image);

        type = image_type_to_string(image->type);

        device_hwrevs_bufs = device_list_alloc_to_bufs(image->devices);

        device_count = 0;
        if ( device_hwrevs_bufs && device_hwrevs_bufs[0] )
            for ( ; device_hwrevs_bufs[device_count]; ++device_count );

        if ( ! type )
            FIASCO_WRITE_ERROR(file, fd, "Unknown image type");

        if ( image->version && strlen(image->version) > UINT8_MAX )
            FIASCO_WRITE_ERROR(file, fd, "Image version string is too long");

        if ( image->layout && strlen(image->layout) > UINT8_MAX )
            FIASCO_WRITE_ERROR(file, fd, "Image layout is too long");

        printf("Writing image header...\n");

        /* signature */
        WRITE_OR_FAIL(file, fd, "T", 1);

        /* number of subsections */
        length8 = device_count+1;
        if ( image->version )
            ++length8;
        if ( image->layout )
            ++length8;
        WRITE_OR_FAIL(file, fd, &length8, 1);

        /* unknown */
        WRITE_OR_FAIL(file, fd, "\x2e\x19\x01\x01\x00", 5);

        /* checksum */
        hash = htons(image->hash);
        WRITE_OR_FAIL(file, fd, &hash, 2);

        /* image type name */
        memset(buf, 0, 12);
        strncpy((char *)buf, type, 12);
        WRITE_OR_FAIL(file, fd, buf, 12);

        /* image size */
        size = htonl(image->size);
        WRITE_OR_FAIL(file, fd, &size, 4);

        /* unknown */
        WRITE_OR_FAIL(file, fd, "\x00\x00\x00\x00", 4);

        /* append version subsection */
        if ( image->version ) {
            WRITE_OR_FAIL(file, fd, "1", 1); /* 1 - version */
            length8 = strlen(image->version)+1;
            WRITE_OR_FAIL(file, fd, &length8, 1);
            WRITE_OR_FAIL(file, fd, image->version, length8);
        }

        /* append device & hwrevs subsection */
        for ( i = 0; i < device_count; ++i ) {
            WRITE_OR_FAIL(file, fd, "2", 1); /* 2 - device & hwrevs */
            WRITE_OR_FAIL(file, fd, &device_hwrevs_bufs[i][0], 1);
            WRITE_OR_FAIL(file, fd, device_hwrevs_bufs[i]+1, ((uint8_t *)(device_hwrevs_bufs[i]))[0]);
        }
        free(device_hwrevs_bufs);

        /* append layout subsection */
        if ( image->layout ) {
            length8 = strlen(image->layout);
            WRITE_OR_FAIL(file, fd, "3", 1); /* 3 - layout */
            WRITE_OR_FAIL(file, fd, &length8, 1);
            WRITE_OR_FAIL(file, fd, image->layout, length8);
        }

        /* dummy byte - end of all subsections */
        WRITE_OR_FAIL(file, fd, "\x00", 1);

        printf("Writing image data...\n");

        image_seek(image, 0);
        while ( 1 ) {
            size = image_read(image, buf, sizeof(buf));
            if ( size == 0 )
                break;
            WRITE_OR_FAIL(file, fd, buf, size);
        }

        image_list = image_list->next;

        if ( image_list )
            printf("\n");

    }

    close(fd);
    printf("\nDone\n\n");
    return 0;

}