Exemple #1
0
static struct server_data *
server_ref(int32_t opt_port)
{
    struct server_data *idata, *sdata = NULL;
    uint16_t i, port;

    port = validate_port(opt_port);

    if (!servers) {
        servers = calloc(1, sizeof(struct sol_ptr_vector));
        SOL_NULL_CHECK(servers, NULL);
        sol_ptr_vector_init(servers);
    }

    SOL_PTR_VECTOR_FOREACH_IDX (servers, idata, i) {
        if (idata->port == port) {
            sdata = idata;
            break;
        }
    }

    if (!sdata) {
        int r;

        sdata = calloc(1, sizeof(struct server_data));
        SOL_NULL_CHECK_GOTO(sdata, err_sdata);

        r = sol_ptr_vector_append(servers, sdata);
        SOL_INT_CHECK_GOTO(r, < 0, err_vec);

        sdata->server = sol_http_server_new(port);
        SOL_NULL_CHECK_GOTO(sdata->server, err_server);

        sdata->port = port;
    }
Exemple #2
0
static bool
thingspeak_channel_update_send(void *data)
{
    struct thingspeak_channel_update_data *mdata = data;
    struct sol_http_param params;
    struct sol_http_client_connection *connection;
    char field_name[] = "fieldX";
    size_t i;
    int r;

    sol_http_param_init(&params);

    if (!sol_http_param_add(&params,
        SOL_HTTP_REQUEST_PARAM_POST_FIELD("api_key", mdata->api_key))) {
        SOL_WRN("Could not add API key");
        goto out;
    }

    if (mdata->status) {
        if (!sol_http_param_add(&params,
            SOL_HTTP_REQUEST_PARAM_POST_FIELD("status", mdata->status))) {
            SOL_WRN("Could not add status field to POST parameters");
            goto out;
        }
    }

    for (i = 0; i < ARRAY_SIZE(mdata->fields); i++) {
        if (!mdata->fields[i])
            continue;

        field_name[sizeof("field") - 1] = i + '1';
        if (!sol_http_param_add(&params,
            SOL_HTTP_REQUEST_PARAM_POST_FIELD(strdupa(field_name), mdata->fields[i]))) {
            SOL_WRN("Could not add status field to POST %s parameters",
                field_name);
            goto out;
        }
    }

    connection = sol_http_client_request(SOL_HTTP_METHOD_POST,
        mdata->endpoint, &params, thingspeak_channel_update_finished, mdata);
    if (!connection) {
        SOL_WRN("Could not create HTTP request");
        goto out;
    }

    r = sol_ptr_vector_append(&mdata->pending_conns, connection);
    if (r < 0) {
        SOL_WRN("Failed to keep pending connection.");
        sol_http_client_connection_cancel(connection);
    }

out:
    sol_http_param_free(&params);

    mdata->timeout = NULL;
    return false;
}
Exemple #3
0
SOL_API char *
sol_arena_strndup(struct sol_arena *arena, const char *str, size_t n)
{
    char *result;
    int r;

    SOL_NULL_CHECK(arena, NULL);
    SOL_NULL_CHECK(str, NULL);
    SOL_INT_CHECK(n, <= 0, NULL);

    result = strndup(str, n);
    SOL_NULL_CHECK(result, NULL);

    r = sol_ptr_vector_append(&arena->str_vector, result);
    if (r < 0) {
        free(result);
        return NULL;
    }

    return result;
}
Exemple #4
0
static bool
thingspeak_execute_poll(void *data)
{
    struct thingspeak_execute_data *mdata = data;
    struct sol_http_param params;
    struct sol_http_client_connection *connection;
    int r;

    sol_http_param_init(&params);
    if (!sol_http_param_add(&params,
        SOL_HTTP_REQUEST_PARAM_POST_FIELD("api_key", mdata->talkback.api_key))) {
        SOL_WRN("Could not set API key");
        mdata->timeout = NULL;
        sol_http_param_free(&params);
        return false;
    }

    connection = sol_http_client_request(SOL_HTTP_METHOD_POST,
        mdata->talkback.endpoint, &params,
        thingspeak_execute_poll_finished, mdata);

    sol_http_param_free(&params);

    if (!connection) {
        SOL_WRN("Could not create HTTP request");
        mdata->timeout = NULL;
        return false;
    }

    r = sol_ptr_vector_append(&mdata->pending_conns, connection);
    if (r < 0) {
        SOL_WRN("Failed to keep pending connection.");
        sol_http_client_connection_cancel(connection);
        return false;
    }

    return true;
}
Exemple #5
0
static int
read_file(void *data, const char *name, const char **buf, size_t *size)
{
    struct runner *r = data;
    struct sol_file_reader *fr = NULL;
    struct sol_str_slice slice;
    char *path;
    int err;

    err = asprintf(&path, "%s/%s", r->dirname, name);
    if (err < 0) {
        err = -ENOMEM;
        goto error;
    }

    fr = sol_file_reader_open(path);
    if (!fr) {
        err = -errno;
        SOL_ERR("Couldn't open input file '%s': %s", path, sol_util_strerrora(errno));
        goto error;
    }

    err = sol_ptr_vector_append(&r->file_readers, fr);
    if (err < 0)
        goto error;

    free(path);
    slice = sol_file_reader_get_all(fr);
    *buf = slice.data;
    *size = slice.len;
    return 0;

error:
    free(path);
    if (fr)
        sol_file_reader_close(fr);
    return err;
}
Exemple #6
0
SOL_API int
sol_arena_slice_sprintf(struct sol_arena *arena, struct sol_str_slice *dst, const char *fmt, ...)
{
    va_list ap;
    char *str;
    int r;

    va_start(ap, fmt);
    r = vasprintf(&str, fmt, ap);
    va_end(ap);
    SOL_INT_CHECK(r, < 0, r);

    dst->data = str;
    dst->len = r;

    r = sol_ptr_vector_append(&arena->str_vector, str);
    if (r < 0) {
        free(str);
        return r;
    }

    return 0;
}
Exemple #7
0
SOL_API int
sol_arena_slice_dup_str_n(struct sol_arena *arena, struct sol_str_slice *dst, const char *str, size_t n)
{
    struct sol_str_slice slice;
    int r;

    SOL_NULL_CHECK(arena, -EINVAL);
    SOL_NULL_CHECK(str, -EINVAL);
    SOL_INT_CHECK(n, <= 0, -EINVAL);

    slice.data = strndup(str, n);
    SOL_NULL_CHECK(slice.data, -errno);

    slice.len = n;

    r = sol_ptr_vector_append(&arena->str_vector, (char *)slice.data);
    if (r < 0) {
        free((char *)slice.data);
        return r;
    }

    *dst = slice;
    return 0;
}
Exemple #8
0
static int
thingspeak_add_in_process(struct sol_flow_node *node, void *data,
    uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet)
{
    struct thingspeak_add_data *mdata = data;
    const char *cmd_str;
    struct sol_http_param params;
    struct sol_http_client_connection *connection;
    int error_code = 0;
    int r;

    r = sol_flow_packet_get_string(packet, &cmd_str);
    if (r < 0) {
        SOL_WRN("Could not get command string from packet");
        return -EINVAL;
    }

    sol_http_param_init(&params);

    if (!sol_http_param_add(&params,
        SOL_HTTP_REQUEST_PARAM_POST_FIELD("api_key", mdata->talkback.api_key))) {
        SOL_WRN("Could not add API key");
        error_code = -ENOMEM;
        goto out;
    }

    if (!sol_http_param_add(&params,
        SOL_HTTP_REQUEST_PARAM_POST_FIELD("command_string", cmd_str))) {
        SOL_WRN("Could not add command string");
        error_code = -ENOMEM;
        goto out;
    }

    if (mdata->position >= 0) {
        char position_str[3 * sizeof(int)];
        char *pos_str;

        r = snprintf(position_str, sizeof(position_str), "%d", mdata->position);
        if (r < 0 || r >= (int)sizeof(position_str)) {
            SOL_WRN("Could not convert position to string");
            error_code = -ENOMEM;
            goto out;
        }

        /* Use pos_str at SOL_HTTP_REQUEST_PARAM_POST_FIELD macro, otherwise
           the compiler will complain about an "always true" comparison.
         */
        pos_str = position_str;
        if (!sol_http_param_add(&params,
            SOL_HTTP_REQUEST_PARAM_POST_FIELD("position", pos_str))) {
            SOL_WRN("Could not add position");
            error_code = -ENOMEM;
            goto out;
        }
    }

    connection = sol_http_client_request(SOL_HTTP_METHOD_POST,
        mdata->talkback.endpoint,
        &params, thingspeak_add_request_finished, mdata);
    if (!connection) {
        SOL_WRN("Could not create HTTP request");
        error_code = -EINVAL;
        goto out;
    }

    r = sol_ptr_vector_append(&mdata->pending_conns, connection);
    if (r < 0) {
        SOL_WRN("Failed to keep pending connection.");
        sol_http_client_connection_cancel(connection);
        error_code = -ENOMEM;
    }

out:
    sol_http_param_free(&params);
    return error_code;
}
Exemple #9
0
static bool
parse_args(int argc, char *argv[])
{
    int opt, err;
    const char known_opts[] = "cho:stI:"
#ifdef SOL_FLOW_INSPECTOR_ENABLED
                              "D"
#endif
                              ;

    sol_ptr_vector_init(&args.fbp_search_paths);

    while ((opt = getopt(argc, argv, known_opts)) != -1) {
        switch (opt) {
        case 'c':
            args.check_only = true;
            break;
        case 's':
            args.provide_sim_nodes = true;
            break;
        case 'h':
            usage(argv[0]);
            exit(EXIT_SUCCESS);
            break;
        case 'o':
            if (args.options_count == MAX_OPTS) {
                printf("Too many options.\n");
                exit(EXIT_FAILURE);
            }
            args.options[args.options_count++] = optarg;
            break;
        case 't':
            args.execute_type = true;
            break;
#ifdef SOL_FLOW_INSPECTOR_ENABLED
        case 'D':
            inspector_init();
            break;
#endif
        case 'I':
            err = sol_ptr_vector_append(&args.fbp_search_paths, optarg);
            if (err < 0) {
                printf("Out of memory\n");
                exit(1);
            }
            break;
        default:
            return false;
        }
    }

    if (optind == argc)
        return false;

    args.name = argv[optind];
    if (args.execute_type) {
        args.provide_sim_nodes = true;
    }

    sol_args_set(argc - optind, &argv[optind]);

    return true;
}
Exemple #10
0
SOL_API struct sol_lwm2m_bootstrap_server *
sol_lwm2m_bootstrap_server_new(uint16_t port, const char **known_clients,
    uint16_t num_sec_modes, ...)
{
    struct sol_lwm2m_bootstrap_server *server;
    struct sol_network_link_addr servaddr = { .family = SOL_NETWORK_FAMILY_INET6,
                                              .port = port };
    int r;
    struct sol_lwm2m_security_psk **known_psks = NULL, *cli_psk;
    struct sol_lwm2m_security_rpk *my_rpk = NULL;
    struct sol_blob **known_pub_keys = NULL, *cli_pub_key;
    enum sol_lwm2m_security_mode *sec_modes;
    enum sol_socket_dtls_cipher *cipher_suites;
    uint16_t i, j;
    va_list ap;

    SOL_LOG_INTERNAL_INIT_ONCE;

    SOL_NULL_CHECK(known_clients, NULL);
    SOL_INT_CHECK(num_sec_modes, == 0, NULL);

    va_start(ap, num_sec_modes);

    cipher_suites = calloc(num_sec_modes, sizeof(enum sol_socket_dtls_cipher));
    SOL_NULL_CHECK_GOTO(cipher_suites, err_va_list);

    sec_modes = calloc(num_sec_modes, sizeof(enum sol_lwm2m_security_mode));
    SOL_NULL_CHECK_GOTO(sec_modes, err_cipher_suites);

    for (i = 0; i < num_sec_modes; i++) {
        sec_modes[i] = va_arg(ap, enum sol_lwm2m_security_mode);
        SOL_EXP_CHECK_GOTO(sec_mode_is_repeated(sec_modes[i], sec_modes, i), err_sec_modes);

        switch (sec_modes[i]) {
        case SOL_LWM2M_SECURITY_MODE_PRE_SHARED_KEY:
            known_psks = va_arg(ap, struct sol_lwm2m_security_psk **);
            SOL_NULL_CHECK_GOTO(known_psks, err_sec_modes);

            cipher_suites[i] = SOL_SOCKET_DTLS_CIPHER_PSK_AES128_CCM8;
            break;
        case SOL_LWM2M_SECURITY_MODE_RAW_PUBLIC_KEY:
            my_rpk = va_arg(ap, struct sol_lwm2m_security_rpk *);
            SOL_NULL_CHECK_GOTO(my_rpk, err_sec_modes);
            known_pub_keys = va_arg(ap, struct sol_blob **);
            SOL_NULL_CHECK_GOTO(known_pub_keys, err_sec_modes);

            cipher_suites[i] = SOL_SOCKET_DTLS_CIPHER_ECDHE_ECDSA_AES128_CCM8;
            break;
        case SOL_LWM2M_SECURITY_MODE_CERTIFICATE:
            SOL_WRN("Certificate security mode is not supported yet.");
            goto err_sec_modes;
        case SOL_LWM2M_SECURITY_MODE_NO_SEC:
            SOL_WRN("Bootstrap Server MUST use DTLS.");
            goto err_sec_modes;
        default:
            SOL_WRN("Unknown DTLS Security Mode: %d", sec_modes[i]);
            goto err_sec_modes;
        }
    }

    server = calloc(1, sizeof(struct sol_lwm2m_bootstrap_server));
    SOL_NULL_CHECK_GOTO(server, err_sec_modes);

    //LWM2M Bootstrap Server MUST always use DTLS
    for (i = 0; i < num_sec_modes; i++) {
        if (sec_modes[i] == SOL_LWM2M_SECURITY_MODE_PRE_SHARED_KEY) {
            sol_vector_init(&server->known_psks, sizeof(sol_lwm2m_security_psk));

            for (j = 0; known_psks[j]; j++) {
                cli_psk = sol_vector_append(&server->known_psks);
                SOL_NULL_CHECK_GOTO(cli_psk, err_copy_keys);
                cli_psk->id = sol_blob_ref(known_psks[j]->id);
                cli_psk->key = sol_blob_ref(known_psks[j]->key);
            }
        } else if (sec_modes[i] == SOL_LWM2M_SECURITY_MODE_RAW_PUBLIC_KEY) {
            sol_ptr_vector_init(&server->known_pub_keys);

            for (j = 0; known_pub_keys[j]; j++) {
                r = sol_ptr_vector_append(&server->known_pub_keys,
                    sol_blob_ref(known_pub_keys[j]));
                SOL_INT_CHECK_GOTO(r, < 0, err_copy_keys);
            }

            server->rpk_pair.private_key = sol_blob_ref(my_rpk->private_key);
            server->rpk_pair.public_key = sol_blob_ref(my_rpk->public_key);
        }
    }
Exemple #11
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;
}