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); }
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; }
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; }
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); }
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); }
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; }
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); }
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"); } }
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); }
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; }
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); }
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; }
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; }
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; }
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; }
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); }
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; }
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; }
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); }
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); }
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; }
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; }
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; }
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; }
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); }
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; }
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; }
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); }