Esempio n. 1
0
SOL_API size_t
sol_json_calculate_escaped_string_len(const char *str)
{
    size_t len = 0;

    SOL_NULL_CHECK(str, 0);

    for (; *str; str++) {
        if (memchr(sol_json_escapable_chars, *str, sizeof(sol_json_escapable_chars)))
            len++;
        len++;
    }
    return len + 1;
}
void
sol_worker_thread_impl_feedback(void *handle)
{
    struct sol_worker_thread_glib *thread = handle;

    SOL_NULL_CHECK(thread);
    SOL_NULL_CHECK(thread->config.feedback);

    if (sol_worker_thread_impl_cancel_check(thread)) {
        SOL_WRN("worker thread %p is not running.", thread);
        return;
    }
    if (thread->thread != g_thread_self()) {
        SOL_WRN("trying to feedback from different worker thread %p.", thread);
        return;
    }

    g_mutex_lock(&thread->lock);
    if (!thread->idler)
        thread->idler = sol_idle_add(sol_worker_thread_feedback_dispatch,
            thread);
    g_mutex_unlock(&thread->lock);
}
Esempio n. 3
0
static int
http_composed_client_simple_process(struct sol_flow_node *node, void *data, uint16_t port,
    uint16_t conn_id, const struct sol_flow_packet *packet)
{
    struct http_composed_client_data *hdata = data;

    if (hdata->inputs[port])
        sol_flow_packet_del(hdata->inputs[port]);

    hdata->inputs[port] = sol_flow_packet_dup(packet);
    SOL_NULL_CHECK(hdata->inputs[port], -ENOMEM);

    return 0;
}
Esempio n. 4
0
static int
udev_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct udev_data *mdata = data;
    struct udev_device *device;
    bool value;
    const struct sol_flow_node_type_udev_boolean_options *opts =
        (const struct sol_flow_node_type_udev_boolean_options *)options;

    SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options,
        SOL_FLOW_NODE_TYPE_UDEV_BOOLEAN_OPTIONS_API_VERSION, -EINVAL);

    mdata->udev = udev_new();
    SOL_NULL_CHECK(mdata->udev, -EINVAL);

    mdata->monitor = udev_monitor_new_from_netlink(mdata->udev, "udev");
    if (!mdata->monitor) {
        SOL_WRN("Fail on create the udev monitor");
        goto monitor_error;
    }

    if (udev_monitor_enable_receiving(mdata->monitor) < 0) {
        SOL_WRN("error: unable to subscribe to udev events");
        goto receive_error;
    }

    mdata->addr = strdup(opts->address);

    mdata->node = node;
    mdata->watch = sol_fd_add(udev_monitor_get_fd(mdata->monitor),
        SOL_FD_FLAGS_IN | SOL_FD_FLAGS_ERR | SOL_FD_FLAGS_HUP,
        _on_event, mdata);

    device = udev_device_new_from_syspath(mdata->udev, mdata->addr);
    if (device) {
        value = true;
        udev_device_unref(device);
    } else {
        value = false;
    }

    return sol_flow_send_boolean_packet(node,
        SOL_FLOW_NODE_TYPE_UDEV_BOOLEAN__OUT__OUT, value);

receive_error:
    mdata->monitor = udev_monitor_unref(mdata->monitor);
monitor_error:
    mdata->udev = udev_unref(mdata->udev);
    return -EINVAL;
}
Esempio n. 5
0
SOL_API enum sol_gpio_direction
sol_gpio_direction_from_str(const char *direction)
{
    static const struct sol_str_table table[] = {
        SOL_STR_TABLE_ITEM("out", SOL_GPIO_DIR_OUT),
        SOL_STR_TABLE_ITEM("in", SOL_GPIO_DIR_IN),
        { }
    };

    SOL_NULL_CHECK(direction, SOL_GPIO_DIR_OUT);

    return sol_str_table_lookup_fallback(table,
        sol_str_slice_from_str(direction), SOL_GPIO_DIR_OUT);
}
Esempio n. 6
0
SOL_API void
sol_arena_del(struct sol_arena *arena)
{
    char *s;
    uint16_t i;

    SOL_NULL_CHECK(arena);

    SOL_PTR_VECTOR_FOREACH_IDX (&arena->str_vector, s, i)
        free(s);

    sol_ptr_vector_clear(&arena->str_vector);
    free(arena);
}
Esempio n. 7
0
static int
setup_watches(struct subprocess_data *mdata)
{
    mdata->watches.in = sol_fd_add(mdata->pipes.in[0], SOL_FD_FLAGS_IN | SOL_FD_FLAGS_ERR, on_in_read, mdata);
    SOL_NULL_CHECK(mdata->watches.in, -1);

    mdata->watches.err = sol_fd_add(mdata->pipes.err[0], SOL_FD_FLAGS_IN | SOL_FD_FLAGS_ERR, on_err_read, mdata);
    if (!mdata->watches.err) {
        sol_fd_del(mdata->watches.in);
        return -1;
    }

    return 0;
}
Esempio n. 8
0
SOL_API bool
sol_fd_add_flags(struct sol_fd *handle, uint32_t flags)
{
    uint32_t f;

    SOL_NULL_CHECK(handle, false);

    f = mainloop_impl->fd_get_flags(handle);

    if (flags & f)
        return true;

    return mainloop_impl->fd_set_flags(handle, mainloop_impl->fd_get_flags(handle) | flags);
}
Esempio n. 9
0
static void
thingspeak_channel_update_finished(void *data,
    struct sol_http_client_connection *connection,
    struct sol_http_response *response)
{
    struct thingspeak_channel_update_data *mdata = data;

    SOL_NULL_CHECK(response);

    if (!strncmp(response->content.data, "0", response->content.used)) {
        sol_flow_send_error_packet(mdata->node, EINVAL,
            "Could not update Thingspeak channel");
    }
}
Esempio n. 10
0
static void
aio_close(struct sol_flow_node *node, void *data)
{
    struct aio_data *mdata = data;

    SOL_NULL_CHECK(mdata);

    free(mdata->pin);

    if (mdata->aio)
        sol_aio_close(mdata->aio);
    if (mdata->timer)
        sol_timeout_del(mdata->timer);
}
Esempio n. 11
0
static int
hostname_send(const void *hostname, struct sol_flow_node *node)
{
    int r;

    if (!hostname) {
        hostname = sol_platform_get_hostname();
        SOL_NULL_CHECK(hostname, -ECANCELED);
    }

    r = sol_flow_send_string_packet(node, 0, hostname);
    SOL_INT_CHECK(r, < 0, r);
    return 0;
}
Esempio n. 12
0
SOL_API enum sol_uart_stop_bits
sol_uart_stop_bits_from_str(const char *stop_bits)
{
    static const struct sol_str_table table[] = {
        SOL_STR_TABLE_ITEM("stopbits-1", SOL_UART_STOP_BITS_ONE),
        SOL_STR_TABLE_ITEM("stopbits-2", SOL_UART_STOP_BITS_TWO),
        { }
    };

    SOL_NULL_CHECK(stop_bits, SOL_UART_STOP_BITS_ONE);

    return sol_str_table_lookup_fallback(table,
        sol_str_slice_from_str(stop_bits), SOL_UART_STOP_BITS_ONE);
}
Esempio n. 13
0
SOL_API int
sol_buffer_append_from_base16(struct sol_buffer *buf, const struct sol_str_slice slice, enum sol_decode_case decode_case)
{
    char *p;
    size_t new_size;
    ssize_t decoded_size, r;
    const size_t nul_size = nul_byte_size(buf);
    int err;

    SOL_NULL_CHECK(buf, -EINVAL);

    if (slice.len == 0)
        return 0;

    decoded_size = sol_util_base16_calculate_decoded_len(slice);
    if (decoded_size < 0)
        return decoded_size;

    err = sol_util_size_add(buf->used, decoded_size, &new_size);
    if (err < 0)
        return err;

    if (nul_size) {
        err = sol_util_size_add(new_size, nul_size, &new_size);
        if (err < 0)
            return err;
    }

    err = sol_buffer_ensure(buf, new_size);
    if (err < 0)
        return err;

    p = sol_buffer_at_end(buf);
    r = sol_util_base16_decode(p, decoded_size, slice, decode_case);
    if (r != decoded_size) {
        if (nul_size)
            sol_buffer_ensure_nul_byte(buf);
        if (r < 0)
            return r;
        else
            return -EINVAL;
    }

    buf->used += decoded_size;

    if (nul_size)
        return sol_buffer_ensure_nul_byte(buf);
    return 0;
}
Esempio n. 14
0
SOL_API int
sol_buffer_append_as_base64(struct sol_buffer *buf, const struct sol_str_slice slice, const char base64_map[SOL_STATIC_ARRAY_SIZE(65)])
{
    char *p;
    size_t new_size;
    ssize_t encoded_size, r;
    const size_t nul_size = nul_byte_size(buf);
    int err;

    SOL_NULL_CHECK(buf, -EINVAL);

    if (slice.len == 0)
        return 0;

    encoded_size = sol_util_base64_calculate_encoded_len(slice, base64_map);
    if (encoded_size < 0)
        return encoded_size;

    err = sol_util_size_add(buf->used, encoded_size, &new_size);
    if (err < 0)
        return err;

    if (nul_size) {
        err = sol_util_size_add(new_size, nul_size, &new_size);
        if (err < 0)
            return err;
    }

    err = sol_buffer_ensure(buf, new_size);
    if (err < 0)
        return err;

    p = sol_buffer_at_end(buf);
    r = sol_util_base64_encode(p, encoded_size, slice, base64_map);
    if (r != encoded_size) {
        if (nul_size)
            sol_buffer_ensure_nul_byte(buf);
        if (r < 0)
            return r;
        else
            return -EINVAL;
    }

    buf->used += encoded_size;

    if (nul_size)
        return sol_buffer_ensure_nul_byte(buf);
    return 0;
}
Esempio n. 15
0
ssize_t
sol_util_fill_buffer(const int fd, struct sol_buffer *buffer, const size_t size)
{
    size_t bytes_read = 0, s;
    unsigned int retry = 0;
    ssize_t ret;

    SOL_NULL_CHECK(buffer, -EINVAL);

    if (sol_util_size_add(buffer->used, size, &s) < 0)
        return -EOVERFLOW;

    ret = sol_buffer_ensure(buffer, s);
    if (ret < 0)
        return ret;

    do {
        ret = read(fd, (char *)buffer->data + buffer->used + bytes_read,
            size - bytes_read);
        if (ret < 0) {
            retry++;
            if (retry >= SOL_UTIL_MAX_READ_ATTEMPTS)
                break;

            if (errno == EINTR || errno == EAGAIN) {
                continue;
            } else
                break;
        }

        retry = 0; //We only count consecutive failures
        bytes_read += (size_t)ret;
    } while (ret && bytes_read < size);

    buffer->used += bytes_read;

    if (ret > 0)
        ret = bytes_read;

    if (!(buffer->flags & SOL_BUFFER_FLAGS_NO_NUL_BYTE)) {
        if (buffer->used == buffer->capacity)
            SOL_WRN("sol_buffer %p asks for terminating NUL byte, but doesn't have space for it",
                buffer);
        else
            *((char *)buffer->data + buffer->used) = '\0';
    }

    return ret;
}
Esempio n. 16
0
SOL_API struct sol_i2c_pending *
sol_i2c_read_register_multiple(struct sol_i2c *i2c, uint8_t reg, uint8_t *data,
    size_t count, uint8_t times, void (*read_reg_multiple_cb)(void *cb_data,
    struct sol_i2c *i2c, uint8_t reg, uint8_t *data, ssize_t status),
    const void *cb_data)
{
    qm_rc_t ret;

    errno = EINVAL;
    SOL_NULL_CHECK(i2c, NULL);
    SOL_NULL_CHECK(data, NULL);
    SOL_INT_CHECK(count, == 0, NULL);

    if (qm_i2c_get_status(i2c->bus) != QM_I2C_IDLE) {
        errno = EBUSY;
        return NULL;
    }

    i2c->xfer.type = READ_REG_MULTIPLE;
    i2c->xfer.rw_reg = read_reg_multiple_cb;
    i2c->xfer.user_data = cb_data;
    i2c->xfer.data = data;
    i2c->xfer.length = count;
    i2c->xfer.multiple_count = times;
    i2c->xfer.multiple_done = 1;
    i2c->xfer.reg = reg;
    i2c->xfer.status = 0;

    ret = begin_transfer(i2c->bus, i2c->slave_addr, i2c->bus, &i2c->xfer.reg, 1,
        data, i2c->xfer.length, false);
    errno = EINVAL;
    SOL_EXP_CHECK(ret != QM_RC_OK, NULL);

    errno = 0;
    return (struct sol_i2c_pending *)i2c;
}
Esempio n. 17
0
SOL_API enum sol_uart_parity
sol_uart_parity_from_str(const char *parity)
{
    static const struct sol_str_table table[] = {
        SOL_STR_TABLE_ITEM("none", SOL_UART_PARITY_NONE),
        SOL_STR_TABLE_ITEM("even", SOL_UART_PARITY_EVEN),
        SOL_STR_TABLE_ITEM("odd", SOL_UART_PARITY_ODD),
        { }
    };

    SOL_NULL_CHECK(parity, SOL_UART_PARITY_NONE);

    return sol_str_table_lookup_fallback(table,
        sol_str_slice_from_str(parity), SOL_UART_PARITY_NONE);
}
Esempio n. 18
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;
}
Esempio n. 19
0
SOL_API enum sol_oic_map_loop_reason
sol_oic_map_loop_init(const struct sol_oic_map_reader *map, struct sol_oic_map_reader *iterator, struct sol_oic_repr_field *repr)
{
    SOL_NULL_CHECK(map, SOL_OIC_MAP_LOOP_ERROR);
    SOL_NULL_CHECK(iterator, SOL_OIC_MAP_LOOP_ERROR);
    SOL_NULL_CHECK(repr, SOL_OIC_MAP_LOOP_ERROR);

#if __STDC_VERSION__ >= 201112L
    static_assert(sizeof(*iterator) == sizeof(CborValue),
        "struct sol_oic_map_reader size must be at least the same size of "
        "CborValue struct defined in cbor.h header2");
#endif

    if (!cbor_value_is_map((CborValue *)map))
        return SOL_OIC_MAP_LOOP_ERROR;

    if (cbor_value_enter_container((CborValue *)map, (CborValue *)iterator) != CborNoError)
        return SOL_OIC_MAP_LOOP_ERROR;

    /* Initialize repr with harmless data so cleanup works. */
    repr->type = SOL_OIC_REPR_TYPE_BOOLEAN;
    repr->key = NULL;
    return SOL_OIC_MAP_LOOP_OK;
}
Esempio n. 20
0
SOL_API bool
sol_http_param_add_copy(struct sol_http_params *params,
    struct sol_http_param_value value)
{
    struct sol_http_param_value *ptr;
    int r;

    SOL_NULL_CHECK(params, -EINVAL);

#ifndef SOL_NO_API_VERSION
    if (params->api_version != SOL_HTTP_PARAM_API_VERSION) {
        SOL_ERR("API version mistmatch; expected %u, got %u",
            SOL_HTTP_PARAM_API_VERSION, params->api_version);
        return false;
    }
#endif

    if (!params->arena) {
        params->arena = sol_arena_new();
        SOL_NULL_CHECK(params->arena, false);
    }

    if (value.type == SOL_HTTP_PARAM_QUERY_PARAM ||
        value.type == SOL_HTTP_PARAM_COOKIE ||
        value.type == SOL_HTTP_PARAM_POST_FIELD ||
        value.type == SOL_HTTP_PARAM_HEADER) {
        if (value.value.key_value.key.len) {
            r = sol_arena_slice_dup(params->arena, &value.value.key_value.key,
                value.value.key_value.key);
            SOL_INT_CHECK(r, < 0, false);
        }
        if (value.value.key_value.value.len) {
            r = sol_arena_slice_dup(params->arena, &value.value.key_value.value,
                value.value.key_value.value);
            SOL_INT_CHECK(r, < 0, false);
        }
Esempio n. 21
0
SOL_API enum sol_gpio_drive
sol_gpio_drive_from_str(const char *drive)
{
    static const struct sol_str_table table[] = {
        SOL_STR_TABLE_ITEM("none", SOL_GPIO_DRIVE_NONE),
        SOL_STR_TABLE_ITEM("up", SOL_GPIO_DRIVE_PULL_UP),
        SOL_STR_TABLE_ITEM("down", SOL_GPIO_DRIVE_PULL_DOWN),
        { }
    };

    SOL_NULL_CHECK(drive, SOL_GPIO_DRIVE_NONE);

    return sol_str_table_lookup_fallback(table,
        sol_str_slice_from_str(drive), SOL_GPIO_DRIVE_NONE);
}
Esempio n. 22
0
static int
flow_delay_send(struct sol_flow_node *flow, struct flow_static_data *fsd)
{
    if (!fsd->delay_send) {
        /* We want to ensure that all packets will be processed in the
         * main loop iteration immediately following the current one, even
         * when the system is loaded enough that it barely has any idle time,
         * thus a timeout with a 0 value instead of an idler.
         */
        fsd->delay_send = sol_timeout_add(0, flow_send_idle, flow);
        SOL_NULL_CHECK(fsd->delay_send, -ENOMEM);
    }

    return 0;
}
Esempio n. 23
0
SOL_API int
sol_buffer_insert_vprintf(struct sol_buffer *buf, size_t pos, const char *fmt, va_list args)
{
    char *s;
    ssize_t len;
    struct sol_str_slice slice;
    int r;

    SOL_NULL_CHECK(buf, -EINVAL);
    SOL_NULL_CHECK(fmt, -EINVAL);
    SOL_INT_CHECK(pos, > buf->used, -EINVAL);

    if (pos == buf->used)
        return sol_buffer_append_vprintf(buf, fmt, args);

    len = vasprintf(&s, fmt, args);
    if (len < 0)
        return -errno;

    slice = SOL_STR_SLICE_STR(s, len);
    r = sol_buffer_insert_slice(buf, pos, slice);
    free(s);
    return r;
}
Esempio n. 24
0
static int
start_timer(struct timer_data *mdata)
{
    if (mdata->timer) {
        sol_timeout_del(mdata->timer);
        mdata->timer = NULL;
    }

    if (mdata->interval < 1)
        return 0;

    mdata->timer = sol_timeout_add(mdata->interval, timer_tick, mdata);
    SOL_NULL_CHECK(mdata->timer, -errno);
    return 0;
}
Esempio n. 25
0
int
process_subprocess_signal_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id,
    const struct sol_flow_packet *packet)
{
    struct subprocess_data *mdata = data;
    int32_t value;
    int ret;

    SOL_NULL_CHECK(mdata->fork_run, -EINVAL);
    ret = sol_flow_packet_get_irange_value(packet, &value);
    SOL_INT_CHECK(ret, < 0, ret);

    sol_platform_linux_fork_run_send_signal(mdata->fork_run, value);

    return 0;
}
Esempio n. 26
0
static int
locale_send(struct sol_flow_node *node, enum sol_platform_locale_category category, const char *locale)
{
    if (category == SOL_PLATFORM_LOCALE_UNKNOWN && !locale) {
        locale_monitor_unregister(node);
        return sol_flow_send_error_packet(node, ECANCELED,
            "Something wrong happened with the locale monitor,"
            "stoping to monitor locale changes");
    }

    if (!locale) {
        locale = sol_platform_get_locale(category);
        SOL_NULL_CHECK(locale, -EINVAL);
    }
    return sol_flow_send_string_packet(node, (int)category, locale);
}
Esempio n. 27
0
SOL_API enum sol_gpio_edge
sol_gpio_edge_from_str(const char *edge)
{
    static const struct sol_str_table table[] = {
        SOL_STR_TABLE_ITEM("none", SOL_GPIO_EDGE_NONE),
        SOL_STR_TABLE_ITEM("rising", SOL_GPIO_EDGE_RISING),
        SOL_STR_TABLE_ITEM("falling", SOL_GPIO_EDGE_FALLING),
        SOL_STR_TABLE_ITEM("any", SOL_GPIO_EDGE_BOTH),
        { }
    };

    SOL_NULL_CHECK(edge, SOL_GPIO_EDGE_NONE);

    return sol_str_table_lookup_fallback(table,
        sol_str_slice_from_str(edge), SOL_GPIO_EDGE_NONE);
}
static bool
get_local_address(struct sol_network_link_addr *addr)
{
    uip_ds6_addr_t *dsaddr;

    dsaddr = uip_ds6_get_global(-1);
    if (!dsaddr)
        dsaddr = uip_ds6_get_link_local(-1);
    SOL_NULL_CHECK(dsaddr, false);

    addr->family = SOL_NETWORK_FAMILY_INET6;
    addr->port = 0;
    memcpy(&addr->addr.in6, &dsaddr->ipaddr, sizeof(addr->addr.in6));

    return true;
}
Esempio n. 29
0
static bool
setup_data_stream(struct sol_mavlink *mavlink)
{
    mavlink_message_t msg = { 0 };
    uint8_t buf[MAVLINK_MAX_PACKET_LEN];
    uint16_t len;

    SOL_NULL_CHECK(mavlink, false);

    mavlink_msg_request_data_stream_pack
        (0, 0, &msg, mavlink->sysid, mavlink->compid,
        MAV_DATA_STREAM_ALL, 1, 1);

    len = mavlink_msg_to_send_buffer(buf, &msg);
    return write(mavlink->fd, buf, len) == len;
}
Esempio n. 30
0
SOL_API enum sol_uart_data_bits
sol_uart_data_bits_from_str(const char *data_bits)
{
    static const struct sol_str_table table[] = {
        SOL_STR_TABLE_ITEM("databits-8", SOL_UART_DATA_BITS_8),
        SOL_STR_TABLE_ITEM("databits-7", SOL_UART_DATA_BITS_7),
        SOL_STR_TABLE_ITEM("databits-6", SOL_UART_DATA_BITS_6),
        SOL_STR_TABLE_ITEM("databits-5", SOL_UART_DATA_BITS_5),
        { }
    };

    SOL_NULL_CHECK(data_bits, SOL_UART_DATA_BITS_8);

    return sol_str_table_lookup_fallback(table,
        sol_str_slice_from_str(data_bits), SOL_UART_DATA_BITS_8);
}