Esempio n. 1
0
//! [uart write]
static bool
send_blob(struct sol_blob *blob)
{
    int err;
    bool r = true;

    //Actually write the blob into UART bus
    err = sol_uart_feed(producer, blob);
    if (err < 0) {
        //Oh no, there's no more space left.
        if (err == -ENOSPC) {
            pending_blob = blob;
            printf("No space left in the tx buffer - saving blob for later. Data: %.*s\n",
                SOL_STR_SLICE_PRINT(sol_str_slice_from_blob(pending_blob)));
        } else {
            fprintf(stderr, "Could not not perform an UART write - Reason: %s\n",
                sol_util_strerrora(-r));
            r = false;
            sol_blob_unref(blob);
        }
    } else {
        sol_blob_unref(blob);
        if (blob == pending_blob)
            pending_blob = NULL; //Flag that data production can start once again!
    }

    return r;
}
Esempio n. 2
0
static bool
reply_cb(struct sol_coap_server *server, struct sol_coap_packet *req,
    const struct sol_network_link_addr *cliaddr, void *data)
{
    struct sol_str_slice *path = data;
    static int count;
    struct sol_buffer *buf;
    size_t offset;

    SOL_BUFFER_DECLARE_STATIC(addr, SOL_INET_ADDR_STRLEN);

    if (!req || !cliaddr) //timeout
        return false;

    sol_network_link_addr_to_str(cliaddr, &addr);

    SOL_INF("Got response from %.*s\n", SOL_STR_SLICE_PRINT(sol_buffer_get_slice(&addr)));

    sol_coap_packet_get_payload(req, &buf, &offset);
    SOL_INF("Payload: %.*s\n", (int)(buf->used - offset),
        (char *)sol_buffer_at(buf, offset));

    if (++count == 10)
        disable_observing(req, server, path, cliaddr);

    return true;
}
Esempio n. 3
0
static bool
on_stdin(void *data, int fd, uint32_t flags)
{
    if (flags & (SOL_FD_FLAGS_ERR | SOL_FD_FLAGS_HUP)) {
        fprintf(stderr, "ERROR: Something wrong happened with file descriptor: %d\n", fd);
        goto err;
    }

    if (flags & SOL_FD_FLAGS_IN) {
        int err;

        value.used = 0;
        /* this will loop trying to read as much data as possible to buffer. */
        err = sol_util_load_file_fd_buffer(fd, &value);
        if (err < 0) {
            fprintf(stderr, "ERROR: failed to read from stdin: %s\n", sol_util_strerrora(-err));
            goto err;
        }

        if (value.used == 0) {
            /* no data usually means ^D on the terminal, quit the application */
            puts("no data on stdin, quitting.");
            sol_quit();
        } else {
            printf("Now serving %zd bytes:\n--BEGIN--\n%.*s\n--END--\n",
                value.used, SOL_STR_SLICE_PRINT(sol_buffer_get_slice(&value)));
        }
    }

    return true;

err:
    sol_quit_with_code(EXIT_FAILURE);
    return false;
}
Esempio n. 4
0
static bool
producer_make_data(void *data)
{
    void *v;
    size_t size;
    struct sol_blob *blob;
    struct sol_buffer buf = SOL_BUFFER_INIT_EMPTY;
    static uint16_t packets_created = 0;
    bool keep_running = true;
    int r;

    //Stop the production until the pendind blob is sent
    if (pending_blob) {
        printf("Waiting for blob data: %.*s to be transfered.\n",
            SOL_STR_SLICE_PRINT(sol_str_slice_from_blob(pending_blob)));
        return true;
    }

    packets_created++;

    //Generate data
    if (packets_created != MAX_PACKETS)
        r = sol_util_uuid_gen(true, true, &buf);
    else {
        r = sol_buffer_append_slice(&buf, sol_str_slice_from_str("close"));
        keep_running = false;
    }

    if (r < 0) {
        fprintf(stderr, "Could not create the UUID - Reason: %s\n",
            sol_util_strerrora(-r));
        goto err_exit;
    }

    v = sol_buffer_steal(&buf, &size);

    blob = sol_blob_new(&SOL_BLOB_TYPE_DEFAULT, NULL,
        v, size + 1);

    if (!blob) {
        fprintf(stderr, "Could not alloc memory for the blob\n");
        goto err_exit;
    }

    //Send it
    if (!send_blob(blob))
        goto err_exit;

    if (!keep_running)
        goto exit;
    return true;

err_exit:
    sol_quit();
exit:
    producer_timeout = NULL;
    return false;
}
Esempio n. 5
0
static void
on_feed_done_cb(void *data, struct sol_http_progressive_response *sse, struct sol_blob *blob, int status)
{
    struct sol_str_slice slice = sol_str_slice_from_blob(blob);

    if (sol_str_slice_str_eq(slice, "data: ") || sol_str_slice_str_eq(slice, "\n\n"))
        return;
    if (isspace(slice.data[slice.len - 1]))
        slice.len--;
    printf("Blob data *%.*s* sent\n", SOL_STR_SLICE_PRINT(slice));
}
Esempio n. 6
0
//! [uart write completed]
static void
producer_data_written(void *data, struct sol_uart *uart, struct sol_blob *blob, int status)
{
    struct sol_str_slice slice;

    slice = sol_str_slice_from_blob(blob);

    if (status < 0) {
        fprintf(stderr, "Could not write the UUID %.*s - Reason: %s\n", SOL_STR_SLICE_PRINT(slice),
            sol_util_strerrora(-status));
        sol_quit();
    } else {
        printf("Producer: UUID %.*s written\n", SOL_STR_SLICE_PRINT(slice));
        if (pending_blob) { //If we have a pending blob now it's the time to try to send it!
            if (!send_blob(pending_blob)) {
                fprintf(stderr, "Could not send the pending blob!\n");
                sol_quit();
            }
        }
    }
}
Esempio n. 7
0
static int
extract_bootstrap_client_info(struct sol_coap_packet *req,
    struct sol_str_slice *client_name)
{
    struct sol_str_slice query;
    int r;

    r = sol_coap_find_options(req, SOL_COAP_OPTION_URI_QUERY, &query,
        LWM2M_BOOTSTRAP_QUERY_PARAMS);
    SOL_INT_CHECK(r, < 0, r);

    struct sol_str_slice key, value;
    const char *sep;

    SOL_DBG("Query:%.*s", SOL_STR_SLICE_PRINT(query));
    sep = memchr(query.data, '=', query.len);

    if (!sep) {
        SOL_WRN("Could not find the separator '=' at: %.*s",
            SOL_STR_SLICE_PRINT(query));
        return -EINVAL;
    }

    key.data = query.data;
    key.len = sep - query.data;
    value.data = sep + 1;
    value.len = query.len - key.len - 1;

    if (sol_str_slice_str_eq(key, "ep")) {
        //Required info
        *client_name = value;
    } else {
        SOL_WRN("The client did not provide its name!");
        return -EINVAL;
    }

    return 0;
}
Esempio n. 8
0
//! [uart read]
static ssize_t
consumer_read_available(void *data, struct sol_uart *uart, const struct sol_buffer *buf)
{
    struct sol_str_slice slice = sol_buffer_get_slice(buf);
    char *sep;

    sep = memchr(slice.data, '\0', slice.len);

    if (!sep)
        return 0; //Bytes will not be removed fom the rx buffer

    //Close the UART!
    if (sol_str_slice_str_contains(slice, "close")) {
        sol_uart_close(uart); //This is completely safe
        consumer = NULL;
        printf("\n\n** Consumer **: Received the close command\n\n");
        sol_quit();
    } else {
        printf("\n\n** Consumer ** : Received UUID %.*s\n\n",
            SOL_STR_SLICE_PRINT(slice));
    }

    return slice.len; //slice.len bytes will be removed from the rx buffer
}
Esempio n. 9
0
static int
bootstrap_request(void *data, struct sol_coap_server *coap,
    const struct sol_coap_resource *resource,
    struct sol_coap_packet *req,
    const struct sol_network_link_addr *cliaddr)
{
    struct sol_lwm2m_bootstrap_client_info *bs_cinfo;
    struct sol_lwm2m_bootstrap_server *server = data;
    struct sol_coap_packet *response;
    struct sol_str_slice client_name = SOL_STR_SLICE_EMPTY;
    int r;
    size_t i;
    bool know_client = false;

    SOL_DBG("Client Bootstrap Request received");

    response = sol_coap_packet_new(req);
    SOL_NULL_CHECK(response, -ENOMEM);

    r = extract_bootstrap_client_info(req, &client_name);
    SOL_INT_CHECK_GOTO(r, < 0, err_exit);

    for (i = 0; server->known_clients[i]; i++) {
        if (sol_str_slice_str_eq(client_name, server->known_clients[i]))
            know_client = true;
    }

    if (!know_client) {
        SOL_WRN("Client %.*s bootstrap request received, but this Bootstrap Server"
            " doesn't have Bootstrap Information for this client.",
            SOL_STR_SLICE_PRINT(client_name));
        goto err_exit;
    }

    r = new_bootstrap_client_info(&bs_cinfo, cliaddr, client_name);
    SOL_INT_CHECK_GOTO(r, < 0, err_exit);

    r = sol_ptr_vector_append(&server->clients, bs_cinfo);
    SOL_INT_CHECK_GOTO(r, < 0, err_exit_del_client);


    r = sol_coap_header_set_code(response, SOL_COAP_RESPONSE_CODE_CHANGED);
    SOL_INT_CHECK_GOTO(r, < 0, err_exit_del_client_list);

    SOL_DBG("Client %s bootstrap request received."
        " Bootstrap Process will start now.", bs_cinfo->name);

    r = sol_coap_send_packet(coap, response, cliaddr);
    dispatch_bootstrap_event_to_server(server, bs_cinfo);

    return r;

err_exit_del_client_list:
    sol_ptr_vector_remove(&server->clients, bs_cinfo);
err_exit_del_client:
    bootstrap_client_info_del(bs_cinfo);
err_exit:
    sol_coap_header_set_code(response, SOL_COAP_RESPONSE_CODE_BAD_REQUEST);
    sol_coap_send_packet(coap, response, cliaddr);
    return r;
}
Esempio n. 10
0
static void
inspector_show_packet_value(const struct sol_flow_packet *packet)
{
    const struct sol_flow_packet_type *type = sol_flow_packet_get_type(packet);

    if (type == SOL_FLOW_PACKET_TYPE_EMPTY) {
        fputs("<empty>", stdout);
        return;
    } else if (type == SOL_FLOW_PACKET_TYPE_ANY) {
        fputs("<any>", stdout);
        return;
    } else if (type == SOL_FLOW_PACKET_TYPE_ERROR) {
        int code;
        const char *msg;
        if (sol_flow_packet_get_error(packet, &code, &msg) == 0) {
            fprintf(stdout, "<error:%d \"%s\">", code, msg ? msg : "");
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_BOOL) {
        bool v;
        if (sol_flow_packet_get_bool(packet, &v) == 0) {
            fprintf(stdout, "<%s>", v ? "true" : "false");
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_BYTE) {
        unsigned char v;
        if (sol_flow_packet_get_byte(packet, &v) == 0) {
            fprintf(stdout, "<%#x>", v);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_IRANGE) {
        struct sol_irange v;
        if (sol_flow_packet_get_irange(packet, &v) == 0) {
            fprintf(stdout, "<val:%d|min:%d|max:%d|step:%d>",
                    v.val, v.min, v.max, v.step);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_DRANGE) {
        struct sol_drange v;
        if (sol_flow_packet_get_drange(packet, &v) == 0) {
            fprintf(stdout, "<val:%g|min:%g|max:%g|step:%g>",
                    v.val, v.min, v.max, v.step);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_STRING) {
        const char *v;
        if (sol_flow_packet_get_string(packet, &v) == 0) {
            fprintf(stdout, "<\"%s\">", v);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_BLOB) {
        struct sol_blob *v;
        if (sol_flow_packet_get_blob(packet, &v) == 0) {
            fprintf(stdout, "<mem=%p|size=%zd|refcnt=%hu|type=%p|parent=%p>",
                    v->mem, v->size, v->refcnt, v->type, v->parent);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_JSON_OBJECT) {
        struct sol_blob *v;
        if (sol_flow_packet_get_json_object(packet, &v) == 0) {
            fprintf(stdout, "<%.*s>",
                    SOL_STR_SLICE_PRINT(sol_str_slice_from_blob(v)));
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_JSON_ARRAY) {
        struct sol_blob *v;
        if (sol_flow_packet_get_json_array(packet, &v) == 0) {
            fprintf(stdout, "<%.*s>",
                    SOL_STR_SLICE_PRINT(sol_str_slice_from_blob(v)));
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_RGB) {
        struct sol_rgb v;
        if (sol_flow_packet_get_rgb(packet, &v) == 0) {
            fprintf(stdout,
                    "<red=%u|green=%u|blue=%u"
                    "|red_max=%u|green_max=%u|blue_max=%u>",
                    v.red, v.green, v.blue,
                    v.red_max, v.green_max, v.blue_max);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_DIRECTION_VECTOR) {
        struct sol_direction_vector v;
        if (sol_flow_packet_get_direction_vector(packet, &v) == 0) {
            fprintf(stdout,
                    "<x=%g|y=%g|z=%g|min=%g|max=%g>",
                    v.x, v.y, v.z, v.min, v.max);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_LOCATION) {
        struct sol_location v;
        if (sol_flow_packet_get_location(packet, &v) == 0) {
            fprintf(stdout, "<lat=%g|lon=%g|alt=%g>", v.lat, v.lon, v.alt);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_TIMESTAMP) {
        struct timespec v;
        if (sol_flow_packet_get_timestamp(packet, &v) == 0) {
            struct tm cur_time;
            char buf[32];
            tzset();
            if (gmtime_r(&v.tv_sec, &cur_time)) {
                if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ",
                             &cur_time) > 0) {
                    fprintf(stdout, "<%s>", buf);
                    return;
                }
            }
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_HTTP_RESPONSE) {
        int code;
        const char *url, *content_type;
        const struct sol_blob *content;
        struct sol_vector headers, cookies;
        if (sol_flow_packet_get_http_response(packet, &code, &url,
                                              &content_type, &content, &cookies, &headers) == 0) {
            fprintf(stdout, "<response_code:%d|content type:%s|url:%s|",
                    code, content_type, url);
            fprintf(stdout, "|cookies: {");
            inpector_print_key_value_array(&cookies);
            fprintf(stdout, "}|headers:{");
            inpector_print_key_value_array(&headers);
            fprintf(stdout,
                    "}|content:{mem=%p|size=%zd|refcnt=%hu|type=%p|parent=%p}>",
                    content->mem, content->size, content->refcnt,
                    content->type, content->parent);
        }
        return;
    }

    fputs("<?>", stdout);
}