static int rotary_child_opts_set(const struct sol_flow_node_type *type, uint16_t child_index, const struct sol_flow_node_options *opts, struct sol_flow_node_options *child_opts) { struct sol_flow_node_type_grove_rotary_sensor_options *container_opts = (struct sol_flow_node_type_grove_rotary_sensor_options *)opts; if (child_index == ROTARY_CONVERTER_NODE_IDX) { struct sol_flow_node_type_grove_rotary_converter_options *converter_opts = (struct sol_flow_node_type_grove_rotary_converter_options *)child_opts; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(child_opts, SOL_FLOW_NODE_TYPE_GROVE_ROTARY_CONVERTER_OPTIONS_API_VERSION, -EINVAL); converter_opts->angular_range = container_opts->angular_range; converter_opts->input_range_mask = container_opts->mask; } else if (child_index == ROTARY_AIO_READER_NODE_IDX) { struct sol_flow_node_type_aio_reader_options *reader_opts = (struct sol_flow_node_type_aio_reader_options *)child_opts; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(child_opts, SOL_FLOW_NODE_TYPE_AIO_READER_OPTIONS_API_VERSION, -EINVAL); reader_opts->raw = container_opts->raw; reader_opts->pin = container_opts->pin ? strdup(container_opts->pin) : NULL; reader_opts->mask = container_opts->mask; reader_opts->poll_timeout = container_opts->poll_timeout; } return 0; }
static int thingspeak_execute_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct thingspeak_execute_data *mdata = data; const struct sol_flow_node_type_thingspeak_talkback_execute_options *opts; int interval; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_THINGSPEAK_TALKBACK_EXECUTE_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_thingspeak_talkback_execute_options *)options; if (!init_talkback(&mdata->talkback, opts->api_key, opts->talkback_id, opts->endpoint, "commands/execute")) return -ENOMEM; if (opts->interval < 1000) { SOL_WRN("Throttling polling interval from %dms to 1000ms to not flood Thingspeak", opts->interval); interval = 1000; } else { interval = opts->interval; } mdata->timeout = sol_timeout_add(interval, thingspeak_execute_poll, mdata); if (!mdata->timeout) { free_talkback(&mdata->talkback); return -ENOMEM; } mdata->node = node; sol_ptr_vector_init(&mdata->pending_conns); return 0; }
static int irange_buffer_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct irange_buffer_data *mdata = data; const struct sol_flow_node_type_int_buffer_options *opts = (const struct sol_flow_node_type_int_buffer_options *)options; mdata->node = node; mdata->cur_len = 0; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK (options, SOL_FLOW_NODE_TYPE_INT_BUFFER_OPTIONS_API_VERSION, -EINVAL); SOL_INT_CHECK(opts->timeout.val, < 0, -EINVAL); SOL_INT_CHECK(opts->samples.val, == 0, -EINVAL); mdata->n_samples = opts->samples.val; mdata->timeout = opts->timeout.val; mdata->normalize_cb = sol_str_table_ptr_lookup_fallback (table, sol_str_slice_from_str(opts->operation), _normalize_mean); mdata->input_queue = calloc(mdata->n_samples, sizeof(*mdata->input_queue)); SOL_NULL_CHECK(mdata->input_queue, -ENOMEM); if (mdata->timeout > 0) mdata->timer = sol_timeout_add(mdata->timeout, _timeout, mdata); return 0; }
/** * this constructor method is called when the node is created. * * The options are checked to see if it conforms to our api by using * the 'sub_api' field. * * The private data is guaranteed to be of size 'struct reader_data'. * * Never send packets from this function as the node is still being * created and there are no connections. */ static int reader_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct reader_data *mdata = data; const struct sol_flow_node_type_custom_node_types_reader_options *opts; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_CUSTOM_NODE_TYPES_READER_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_custom_node_types_reader_options *) options; /* create a 1 second timer where we produce packets. */ mdata->timer = sol_timeout_add(1000, reader_on_timeout, node); /* the initial value comes from options. */ mdata->val = opts->intopt; /* Note that an 'int' port is actually an integer range or a * 'struct sol_irange', as it carries not only the value, but how * to interpret that integer such as minimum and maximum values * (so we can limit to only positive or negative, and smaller * precisions) as well how to increment or decrement the value * (steps). * * In this example we are only interested in the value, thus we * use the simpler packet constructor. */ return sol_flow_send_irange_value_packet(node, SOL_FLOW_NODE_TYPE_CUSTOM_NODE_TYPES_READER__OUT__OUT, mdata->val); }
static int led_setup(struct gtk_common_data *data, const struct sol_flow_node_options *options) { struct gtk_led_data *mdata = (struct gtk_led_data *)data; const struct sol_flow_node_type_gtk_led_options *opts = (const struct sol_flow_node_type_gtk_led_options *)options; struct sol_rgb color; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_GTK_LED_OPTIONS_API_VERSION, -EINVAL); color = opts->rgb; if (sol_rgb_set_max(&color, 255) < 0) { SOL_WRN("Invalid color"); return -EINVAL; } mdata->on = true; mdata->r = color.red; mdata->g = color.green; mdata->b = color.blue; mdata->base.widget = gtk_drawing_area_new(); gtk_widget_set_size_request(mdata->base.widget, LED_VIEW_DIMENSION, LED_VIEW_DIMENSION); g_signal_connect(G_OBJECT(mdata->base.widget), "draw", G_CALLBACK(on_draw_event), mdata); g_object_set(mdata->base.widget, "halign", GTK_ALIGN_CENTER, NULL); return 0; }
static int platform_service_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct platform_service_data *mdata = data; const struct sol_flow_node_type_platform_service_options *opts; SOL_NULL_CHECK_MSG(options, -1, "Platform Service Node: Options not found."); opts = (const struct sol_flow_node_type_platform_service_options *)options; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_PLATFORM_SERVICE_OPTIONS_API_VERSION, -EINVAL); mdata->node = node; if (!opts->name) return 0; mdata->service_name = strdup(opts->name); SOL_NULL_CHECK(mdata->service_name, -ENOMEM); sol_platform_add_service_monitor(on_service_state_changed, mdata->service_name, mdata); mdata->state = sol_platform_get_service_state(mdata->service_name); return sol_flow_send_boolean_packet(node, SOL_FLOW_NODE_TYPE_PLATFORM_SERVICE__OUT__ACTIVE, (mdata->state == SOL_PLATFORM_SERVICE_STATE_ACTIVE)); }
static int map_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct drange_map_data *mdata = data; const struct sol_flow_node_type_float_map_options *opts; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_FLOAT_MAP_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_float_map_options *)options; mdata->use_input_range = opts->use_input_range; mdata->input = opts->input_range; if (!mdata->use_input_range && isgreaterequal(mdata->input.min, mdata->input.max)) { SOL_WRN("Invalid range: input max must to be bigger than min"); return -EINVAL; } mdata->output = opts->output_range; if (isless(mdata->output.min, mdata->output.max)) { mdata->output_value.min = mdata->output.min; mdata->output_value.max = mdata->output.max; } else { mdata->output_value.max = mdata->output.min; mdata->output_value.min = mdata->output.max; } mdata->output_value.step = opts->output_range.step; return 0; }
int boolean_generator_open( struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct boolean_generator_data *mdata = data; const struct sol_flow_node_type_test_boolean_generator_options *opts = (const struct sol_flow_node_type_test_boolean_generator_options *)options; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_TEST_BOOLEAN_GENERATOR_OPTIONS_API_VERSION, -EINVAL); if (opts->sequence == NULL || *opts->sequence == '\0') { SOL_ERR("Option 'sequence' is either NULL or empty."); return -EINVAL; } mdata->it = mdata->sequence = strdup(opts->sequence); SOL_NULL_CHECK(mdata->sequence, -errno); if (opts->interval < 0) SOL_WRN("Option 'interval' < 0, setting it to 0."); mdata->interval = opts->interval >= 0 ? opts->interval : 0; mdata->timer = sol_timeout_add(mdata->interval, timer_tick, node); SOL_NULL_CHECK_GOTO(mdata->timer, error); return 0; error: free(mdata->sequence); return -ENOMEM; }
static int temperature_stts751_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct stts751_data *mdata = data; const struct sol_flow_node_type_stts751_options *opts; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_STTS751_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_stts751_options *)options; mdata->node = node; mdata->i2c = sol_i2c_open(opts->i2c_bus, SOL_I2C_SPEED_10KBIT); SOL_NULL_CHECK_MSG(mdata->i2c, -EINVAL, "Failed to open i2c bus"); mdata->slave = opts->i2c_slave; mdata->resolution = opts->temperature_resolution; if (mdata->resolution < 9 || mdata->resolution > 12) { SOL_WRN("Invalid temperature resolution bits for STTS751 %d. " "Must be between 9 and 12. Falling back to 10.", mdata->resolution); mdata->resolution = 10; } stts751_init(mdata); return 0; }
SOL_API void sol_flow_node_options_del(const struct sol_flow_node_type *type, struct sol_flow_node_options *options) { SOL_NULL_CHECK(type); SOL_FLOW_NODE_OPTIONS_API_CHECK(options, SOL_FLOW_NODE_OPTIONS_API_VERSION); #ifndef SOL_FLOW_NODE_TYPE_DESCRIPTION_ENABLED SOL_WRN("This function needs NODE_DESCRIPTION=y in the build config."); #else SOL_NULL_CHECK(type->description); if (type->description->options) { SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, type->description->options->sub_api); if (type->description->options->members) { const struct sol_flow_node_options_member_description *member; for (member = type->description->options->members; member->name; member++) { if (streq(member->data_type, "string")) { char **s = (char **)((char *)(options) + member->offset); free(*s); } } } } free(options); #endif }
static int led_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct led_7seg_data *mdata = data; const struct sol_flow_node_type_led_7seg_led_options *opts = (const struct sol_flow_node_type_led_7seg_led_options *)options; struct sol_gpio_config gpio_conf = { 0 }; int i; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_LED_7SEG_LED_OPTIONS_API_VERSION, -EINVAL); gpio_conf.api_version = SOL_GPIO_CONFIG_API_VERSION; gpio_conf.dir = SOL_GPIO_DIR_OUT; OPEN_GPIO(0, dp); OPEN_GPIO(1, g); OPEN_GPIO(2, f); OPEN_GPIO(3, e); OPEN_GPIO(4, d); OPEN_GPIO(5, c); OPEN_GPIO(6, b); OPEN_GPIO(7, a); mdata->common_cathode = opts->common_cathode; return 0; port_error: for (i = 0; i < 8; i++) { if (mdata->gpio[i]) sol_gpio_close(mdata->gpio[i]); } return -EIO; }
static int thingspeak_channel_update_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct thingspeak_channel_update_data *mdata = data; const struct sol_flow_node_type_thingspeak_channel_update_options *opts; size_t i; int r; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_THINGSPEAK_CHANNEL_UPDATE_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_thingspeak_channel_update_options *)options; mdata->api_key = strdup(opts->api_key); if (!mdata->api_key) return -ENOMEM; r = asprintf(&mdata->endpoint, "%s/update", opts->endpoint); if (r < 0) { free(mdata->api_key); return -ENOMEM; } for (i = 0; i < ARRAY_SIZE(mdata->fields); i++) mdata->fields[i] = NULL; mdata->status = NULL; mdata->timeout = NULL; sol_ptr_vector_init(&mdata->pending_conns); return 0; }
int blob_validator_open( struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct blob_validator_data *mdata = data; const struct sol_flow_node_type_test_blob_validator_options *opts = (const struct sol_flow_node_type_test_blob_validator_options *)options; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_TEST_BLOB_VALIDATOR_OPTIONS_API_VERSION, -EINVAL); mdata->done = false; if (opts->expected == NULL || *opts->expected == '\0') { SOL_ERR("Option 'expected' is either NULL or empty."); return -EINVAL; } mdata->expected.mem = strdup(opts->expected); SOL_NULL_CHECK(mdata->expected.mem, -errno); mdata->expected.size = strlen(opts->expected); if (opts->expect_terminating_null_byte) mdata->expected.size++; return 0; }
int process_subprocess_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct subprocess_data *mdata = data; struct sol_flow_node_type_process_subprocess_options *opts = (struct sol_flow_node_type_process_subprocess_options *)options; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_PROCESS_SUBPROCESS_OPTIONS_API_VERSION, -EINVAL); mdata->node = node; sol_vector_init(&mdata->write_data, sizeof(struct write_data)); if (pipe2(mdata->pipes.out, O_NONBLOCK | O_CLOEXEC) < 0) { SOL_WRN("Failed to create out pipe"); return -errno; } if (pipe2(mdata->pipes.in, O_NONBLOCK | O_CLOEXEC) < 0) { SOL_WRN("Failed to create in pipe"); goto in_err; } if (pipe2(mdata->pipes.err, O_NONBLOCK | O_CLOEXEC) < 0) { SOL_WRN("Failed to create err pipe"); goto err_err; } mdata->command = strdup(opts->command); SOL_NULL_CHECK_GOTO(mdata->command, flags_err); if (opts->start) { if (setup_watches(mdata) < 0) goto watch_err; mdata->fork_run = sol_platform_linux_fork_run(on_fork, on_fork_exit, mdata); SOL_NULL_CHECK_GOTO(mdata->fork_run, err); } return 0; err: sol_fd_del(mdata->watches.in); sol_fd_del(mdata->watches.err); watch_err: free(mdata->command); flags_err: close(mdata->pipes.err[0]); close(mdata->pipes.err[1]); err_err: close(mdata->pipes.in[0]); close(mdata->pipes.in[1]); in_err: close(mdata->pipes.out[0]); close(mdata->pipes.out[1]); return -errno; }
static int constant_string_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { const struct sol_flow_node_type_constant_string_options *opts; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_CONSTANT_STRING_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_constant_string_options *)options; return sol_flow_send_string_packet(node, SOL_FLOW_NODE_TYPE_CONSTANT_STRING__OUT__OUT, opts->value); }
static int toggle_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct toggle_data *mdata = data; const struct sol_flow_node_type_boolean_toggle_options *opts = (const struct sol_flow_node_type_boolean_toggle_options *)options; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK (options, SOL_FLOW_NODE_TYPE_BOOLEAN_TOGGLE_OPTIONS_API_VERSION, -EINVAL); mdata->state = opts->initial_state; 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; }
int float_validator_open( struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct float_validator_data *mdata = data; const struct sol_flow_node_type_test_float_validator_options *opts = (const struct sol_flow_node_type_test_float_validator_options *)options; const char *it; char *tail; double *val; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_TEST_FLOAT_VALIDATOR_OPTIONS_API_VERSION, -EINVAL); mdata->done = false; if (opts->sequence == NULL || *opts->sequence == '\0') { SOL_ERR("Option 'sequence' is either NULL or empty."); return -EINVAL; } sol_vector_init(&mdata->values, sizeof(double)); it = opts->sequence; do { val = sol_vector_append(&mdata->values); SOL_NULL_CHECK_GOTO(val, no_memory); *val = sol_util_strtod_n(it, &tail, -1, false); if (errno) { SOL_WRN("Failed do convert option 'sequence' to double %s: %d", it, errno); goto error; } if (it == tail) { SOL_WRN("Failed to convert option 'sequence' to double %s", it); errno = EINVAL; goto error; } it = tail; } while (*tail != '\0'); return 0; no_memory: errno = ENOMEM; error: sol_vector_clear(&mdata->values); return -errno; }
static int constant_direction_vector_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { const struct sol_flow_node_type_constant_direction_vector_options *opts; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_CONSTANT_DIRECTION_VECTOR_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_constant_direction_vector_options *)options; return sol_flow_send_direction_vector_packet(node, SOL_FLOW_NODE_TYPE_CONSTANT_DIRECTION_VECTOR__OUT__OUT, &opts->value); return 0; }
static int aio_reader_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { int device, pin; struct aio_data *mdata = data; const struct sol_flow_node_type_aio_reader_options *opts = (const struct sol_flow_node_type_aio_reader_options *)options; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(opts, SOL_FLOW_NODE_TYPE_AIO_READER_OPTIONS_API_VERSION, -EINVAL); mdata->aio = NULL; mdata->is_first = true; mdata->node = node; if (!opts->pin || *opts->pin == '\0') { SOL_WRN("aio: Option 'pin' cannot be neither 'null' nor empty."); return -EINVAL; } if (opts->mask <= 0) { SOL_WRN("aio (%s): Invalid bit mask value=%" PRId32 ".", opts->pin, opts->mask); return -EINVAL; } if (opts->poll_timeout <= 0) { SOL_WRN("aio (%s): Invalid polling time=%" PRId32 ".", opts->pin, opts->poll_timeout); return -EINVAL; } if (opts->raw) { if (sscanf(opts->pin, "%d %d", &device, &pin) == 2) { mdata->aio = sol_aio_open(device, pin, opts->mask); } else { SOL_WRN("aio (%s): 'raw' option was set, but 'pin' value=%s couldn't be parsed as " "\"<device> <pin>\" pair.", opts->pin, opts->pin); } } else { mdata->aio = sol_aio_open_by_label(opts->pin, opts->mask); } SOL_NULL_CHECK_MSG(mdata->aio, -EINVAL, "aio (%s): Couldn't be open. Maybe you used an invalid 'pin'=%s?", opts->pin, opts->pin); mdata->pin = opts->pin ? strdup(opts->pin) : NULL; mdata->mask = (0x01 << opts->mask) - 1; mdata->timer = sol_timeout_add(opts->poll_timeout, _on_reader_timeout, mdata); return 0; }
static int wave_generator_sinusoidal_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct drange_wave_generator_sinusoidal_data *mdata = data; const struct sol_flow_node_type_wave_generator_sinusoidal_options *opts = (const struct sol_flow_node_type_wave_generator_sinusoidal_options *)options; uint32_t tick_start; struct s_state *s_state; struct sol_drange *val; unsigned i; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(opts, SOL_FLOW_NODE_TYPE_WAVE_GENERATOR_SINUSOIDAL_OPTIONS_API_VERSION, -EINVAL); if (islessequal(opts->amplitude.val, 0)) { SOL_ERR("Sinusoidal wave generator's multiplier must be greater " "than zero"); return -EDOM; } if (opts->ticks_per_period.val < 1) { SOL_ERR("Sinusoidal wave generator's ticks_per_period value (%d) cannot" " be less than 1)", opts->ticks_per_period.val); return -EDOM; } if (opts->tick_start.val < 0) { SOL_ERR("Sinusoidal wave generator's tick_start value (%d) cannot" " be less than 0)", opts->tick_start.val); return -EDOM; } mdata->amplitude = opts->amplitude.val; s_state = &mdata->s_state; val = &s_state->val; s_state->did_first = false; val->min = mdata->amplitude * -1.0; val->max = mdata->amplitude; mdata->rad_step = 2 * M_PI / opts->ticks_per_period.val; /* calculating starting val from tick_start */ val->val = 0; tick_start = opts->tick_start.val % opts->ticks_per_period.val; for (i = 0; i < tick_start; i++) sinusoidal_calc_next(mdata); return 0; }
static int hc_sr04_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct hc_sr04_data *mdata = data; const struct sol_flow_node_type_hc_sr04_distance_options *opts; struct sol_gpio_config trig_gpio_conf = { 0 }; struct sol_gpio_config echo_gpio_conf = { 0 }; uint32_t pin; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_HC_SR04_DISTANCE_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_hc_sr04_distance_options *)options; SOL_SET_API_VERSION(trig_gpio_conf.api_version = SOL_GPIO_CONFIG_API_VERSION; )
static int monitor_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { const struct sol_flow_node_type_platform_hostname_options *opts; const struct monitor_node_type *monitor_type = (const struct monitor_node_type *)sol_flow_node_get_type(node); SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_PLATFORM_HOSTNAME_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_platform_hostname_options *)options; if (opts->send_initial_packet) return monitor_type->send_packet(NULL, node); return 0; }
static int writer_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct writer_data *mdata = data; const struct sol_flow_node_type_custom_node_types_writer_options *opts; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_CUSTOM_NODE_TYPES_WRITER_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_custom_node_types_writer_options *) options; if (opts->prefix) mdata->prefix = strdup(opts->prefix); return 0; }
static int empty_reader_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct ipm_data *mdata = data; const struct sol_flow_node_type_ipm_empty_reader_options *opts; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_IPM_EMPTY_READER_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_ipm_empty_reader_options *)options; SOL_INT_CHECK(opts->id, < 1, -EINVAL); SOL_INT_CHECK(opts->id, > (int)sol_ipm_get_max_id(), -EINVAL); mdata->id = opts->id; return sol_ipm_set_receiver(opts->id, empty_receiver, node); }
static int magnetometer_lsm303_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct magnetometer_lsm303_data *mdata = data; const struct sol_flow_node_type_magnetometer_lsm303_options *opts; static const uint8_t mode = LSM303_MAG_DEFAULT_MODE; uint8_t range_bit; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_MAGNETOMETER_LSM303_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_magnetometer_lsm303_options *)options; if (!_get_range_bits_and_gain(opts->scale.val, &range_bit, &mdata->gain_xy, &mdata->gain_z)) { SOL_WRN("Invalid gain. Expected one of 1.3, 1.9, 2.5, 4.0, 4.5, 5.6 or 8.1"); return -EINVAL; } mdata->i2c = sol_i2c_open(opts->i2c_bus.val, SOL_I2C_SPEED_10KBIT); if (!mdata->i2c) { SOL_WRN("Failed to open i2c bus"); return -EINVAL; } if (!sol_i2c_set_slave_address(mdata->i2c, opts->i2c_slave.val)) { SOL_WRN("Failed to set slave at address 0x%02x\n", opts->i2c_slave.val); goto fail; } mdata->slave = opts->i2c_slave.val; if (!sol_i2c_write_register(mdata->i2c, LSM303_MAG_REG_MR_REG_M, &mode, 1)) { SOL_WRN("Could not enable LSM303 magnetometer"); goto fail; } if (!sol_i2c_write_register(mdata->i2c, LSM303_MAG_REG_CRB_REG_M, &range_bit, 1)) { SOL_WRN("Could not set LSM303 magnetometer range"); goto fail; } return 0; fail: sol_i2c_close(mdata->i2c); return -EINVAL; }
static int constant_drange_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { const struct sol_flow_node_type_constant_float_options *opts; struct sol_drange value; int r; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_CONSTANT_FLOAT_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_constant_float_options *)options; r = sol_drange_compose(&opts->value_spec, opts->value, &value); SOL_INT_CHECK(r, < 0, r); return sol_flow_send_drange_packet(node, SOL_FLOW_NODE_TYPE_CONSTANT_FLOAT__OUT__OUT, &value); }
static int random_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct random_node_data *mdata = data; const struct sol_flow_node_type_random_int_options *opts; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_RANDOM_INT_OPTIONS_API_VERSION, -EINVAL); /* TODO find some way to share the same options struct between multiple node types */ opts = (const struct sol_flow_node_type_random_int_options *)options; mdata->engine = sol_random_new(SOL_RANDOM_DEFAULT, opts->seed); SOL_NULL_CHECK(mdata->engine, -EINVAL); return 0; }
int string_uuid_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct string_uuid_data *mdata = data; const struct sol_flow_node_type_string_uuid_options *opts; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK (options, SOL_FLOW_NODE_TYPE_STRING_UUID_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_string_uuid_options *)options; mdata->node = node; mdata->with_hyphens = opts->with_hyphens; mdata->upcase = opts->upcase; return string_uuid_gen(node, data, 0, 0, NULL); }
static int file_reader_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { const struct sol_flow_node_type_file_reader_options *opts = (const struct sol_flow_node_type_file_reader_options *)options; struct file_reader_data *mdata = data; mdata->node = node; SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_FILE_READER_OPTIONS_API_VERSION, -EINVAL); if (opts->path) { mdata->path = strdup(opts->path); SOL_NULL_CHECK(mdata->path, -ENOMEM); } mdata->idler = sol_idle_add(file_reader_open_delayed, mdata); return 0; }