static int http_composed_client_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct http_composed_client_data *cdata = data; const struct http_composed_client_type *self; const struct http_composed_client_options *opts; const struct http_composed_client_port_out *out; opts = (struct http_composed_client_options *)options; if (opts->url) { cdata->url = strdup(opts->url); SOL_NULL_CHECK(cdata->url, -ENOMEM); } self = (const struct http_composed_client_type *) sol_flow_node_get_type(node); sol_ptr_vector_init(&cdata->pending_conns); cdata->inputs_len = self->ports_in.len - INPUT_FIXED_PORTS_LEN; cdata->inputs = calloc(cdata->inputs_len, sizeof(struct sol_flow_packet *)); SOL_NULL_CHECK_GOTO(cdata->inputs, err); out = sol_vector_get(&self->ports_out, 0); cdata->composed_type = out->base.packet_type; return 0; err: free(cdata->url); return -ENOMEM; }
static int common_get_progress(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet) { struct update_data *mdata = data; struct update_node_type *type; struct sol_irange irange = { .step = 1, .min = 0, .max = 100 }; type = (struct update_node_type *)sol_flow_node_get_type(node); if (mdata->handle) { irange.val = sol_update_get_progress(mdata->handle); if (irange.val >= 0 && irange.val <= 100) sol_flow_send_irange_packet(node, type->progress_port, &irange); else sol_flow_send_error_packet(node, EINVAL, "Could not get progress of task"); } else { SOL_DBG("No current operation in process, ignoring request to get progress"); } return 0; }
static const char * inspector_get_node_typename(const struct sol_flow_node *node) { const struct sol_flow_node_type *type = sol_flow_node_get_type(node); if (!type) return NULL; return type->description ? type->description->name : NULL; }
static void spin_value_changed(GtkWidget *widget, gpointer data) { struct gtk_common_data *mdata = data; const struct float_editor_note_type *float_node; float_node = (const struct float_editor_note_type *)sol_flow_node_get_type(mdata->node); float_node->send_output_packet(mdata); }
static void common_consumed_callback(void *data, uint32_t id, struct sol_blob *message) { struct sol_flow_node *node = data; struct ipm_writer_node_type *type; type = (struct ipm_writer_node_type *)sol_flow_node_get_type(node); sol_flow_send_empty_packet(node, type->consumed_port); }
static int check_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct update_node_type *type; type = (struct update_node_type *)sol_flow_node_get_type(node); type->progress_port = SOL_FLOW_NODE_TYPE_UPDATE_CHECK__OUT__PROGRESS; return 0; }
static int monitor_out_connect(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id) { struct monitor_data *mdata = data; const struct monitor_node_type *monitor_type = (const struct monitor_node_type *)sol_flow_node_get_type(node); mdata->connections++; if (mdata->connections == 1) return monitor_type->monitor_register(node); return 0; }
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 void inspector_show_in_port(const struct sol_flow_node *node, uint16_t port_idx) { const struct sol_flow_port_description *port; port = sol_flow_node_get_description_port_in(sol_flow_node_get_type(node), port_idx); if (port) { if (port->name) { inspector_print_port_name(port_idx, port); if (port->data_type) fprintf(stdout, "(%s)", port->data_type); return; } } fprintf(stdout, "%hu", port_idx); }
static int comparison_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet) { struct timestamp_comparison_data *mdata = data; const struct timestamp_comparison_node_type *type; bool output; if (!two_vars_get_value(mdata, port, packet)) return 0; type = (const struct timestamp_comparison_node_type *) sol_flow_node_get_type(node); output = type->func(&mdata->val[0], &mdata->val[1]); return sol_flow_send_boolean_packet(node, 0, output); }
static int float_editor_setup(struct gtk_common_data *mdata, const struct sol_flow_node_options *options) { const struct float_editor_note_type *float_node; GtkWidget *grid; grid = gtk_grid_new(); gtk_grid_set_column_spacing(GTK_GRID(grid), 4); g_object_set(grid, "halign", GTK_ALIGN_CENTER, NULL); mdata->widget = grid; float_node = (const struct float_editor_note_type *)sol_flow_node_get_type(mdata->node); float_node->setup_widget(mdata); return 0; }
static int magnet_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct iio_direction_vector_data *mdata = data; const struct sol_flow_node_type_iio_magnetometer_options *opts; int device_id, ret; struct iio_node_type *type; type = (struct iio_node_type *)sol_flow_node_get_type(node); SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_IIO_MAGNETOMETER_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_iio_magnetometer_options *)options; mdata->iio_base.buffer_enabled = opts->buffer_size > -1; SOL_SET_API_VERSION(mdata->iio_base.config.api_version = SOL_IIO_CONFIG_API_VERSION; ) if (opts->iio_trigger_name) {
static int pressure_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct iio_double_data *mdata = data; const struct sol_flow_node_type_iio_pressure_sensor_options *opts; int device_id; struct iio_node_type *type; type = (struct iio_node_type *)sol_flow_node_get_type(node); SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_IIO_PRESSURE_SENSOR_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_iio_pressure_sensor_options *)options; mdata->iio_base.buffer_enabled = opts->buffer_size > -1; SOL_SET_API_VERSION(mdata->iio_base.config.api_version = SOL_IIO_CONFIG_API_VERSION; ) if (opts->iio_trigger_name) {
static bool comparison_func(struct irange_comparison_data *mdata, struct sol_flow_node *node, uint16_t port, const struct sol_flow_packet *packet, bool *func_ret) { const struct irange_comparison_node_type *type; int r; r = sol_flow_packet_get_irange_value(packet, &mdata->val[port]); SOL_INT_CHECK(r, < 0, r); mdata->val_initialized[port] = true; if (!(mdata->val_initialized[0] && mdata->val_initialized[1])) return false; type = (const struct irange_comparison_node_type *) sol_flow_node_get_type(node); *func_ret = type->func(mdata->val[0], mdata->val[1]); return true; }
static void inspector_show_out_port(const struct sol_flow_node *node, uint16_t port_idx) { const struct sol_flow_port_description *port; if (port_idx == SOL_FLOW_NODE_PORT_ERROR) { fputs(SOL_FLOW_NODE_PORT_ERROR_NAME, stdout); return; } port = sol_flow_node_get_description_port_out(sol_flow_node_get_type(node), port_idx); if (port) { if (port->name) { inspector_print_port_name(port_idx, port); if (port->data_type) fprintf(stdout, "(%s)", port->data_type); return; } } fprintf(stdout, "%hu", port_idx); }
static int iio_common_tick(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet) { static const char *errmsg = "Could not read channel values"; struct iio_device_config *mdata = data; struct iio_node_type *type; type = (struct iio_node_type *)sol_flow_node_get_type(node); if (mdata->buffer_enabled) { if (sol_iio_device_trigger(mdata->device) < 0) goto error; } else { type->reader_cb(node, mdata->device); } return 0; error: sol_flow_send_error_packet(node, EIO, "%s", errmsg); SOL_WRN("%s reader_cb=%p", errmsg, type->reader_cb); return -EIO; }
static int32_t get_int32_packet_and_log(const struct sol_flow_node *n, uint16_t port, const struct sol_flow_packet *packet) { const struct sol_flow_node_type *type; const struct sol_flow_port_description *port_desc; int32_t value; int err; /* get the struct sol_irange::value member. This function also validates if the * given packet is of requested type (irange), otherise will return an -errno. */ err = sol_flow_packet_get_irange_value(packet, &value); if (err < 0) { fprintf(stderr, "ERROR: could not get irange packet value: %p %s\n", packet, sol_util_strerrora(-err)); return err; } /* log the value to stdout. First we get the node type from * current node (minutes or seconds), then we find the port * description from its index. with that we can get the port name. */ type = sol_flow_node_get_type(n); port_desc = sol_flow_node_get_port_out_description(type, port); if (!port_desc) { fprintf(stderr, "ERROR: no output port description for index %" PRIu16 " of node %p\n", port, n); return -ENOENT; } printf("node type %s port #%" PRIu16 " '%s' (%s): %" PRId32 "\n", type->description->name, port, port_desc->name, port_desc->data_type, value); return value; }
static void iio_direction_vector_reader_cb(void *data, struct sol_iio_device *device) { static const char *errmsg = "Could not read channel buffer values"; struct sol_flow_node *node = data; struct iio_direction_vector_data *mdata = sol_flow_node_get_private_data(node); struct sol_direction_vector out = { .min = mdata->iio_base.out_range.min, .max = mdata->iio_base.out_range.max }; int r; struct iio_node_type *type; type = (struct iio_node_type *)sol_flow_node_get_type(node); r = sol_iio_read_channel_value(mdata->channel_x, &out.x); SOL_INT_CHECK_GOTO(r, < 0, error); r = sol_iio_read_channel_value(mdata->channel_y, &out.y); SOL_INT_CHECK_GOTO(r, < 0, error); r = sol_iio_read_channel_value(mdata->channel_z, &out.z); SOL_INT_CHECK_GOTO(r, < 0, error); SOL_DBG("Before mount_calibration: %f-%f-%f", out.x, out.y, out.z); // mount correction sol_iio_mount_calibration(device, &out); sol_flow_send_direction_vector_packet(node, type->out_port, &out); return; error: sol_flow_send_error_packet_str(node, EIO, errmsg); SOL_WRN("%s", errmsg); } static void iio_double_reader_cb(void *data, struct sol_iio_device *device) { static const char *errmsg = "Could not read channel buffer values"; struct sol_flow_node *node = data; struct iio_double_data *mdata = sol_flow_node_get_private_data(node); struct sol_drange out = { .min = mdata->iio_base.out_range.min, .max = mdata->iio_base.out_range.max, .step = mdata->iio_base.out_range.step }; int r; struct iio_node_type *type; type = (struct iio_node_type *)sol_flow_node_get_type(node); r = sol_iio_read_channel_value(mdata->channel_val, &out.val); SOL_INT_CHECK_GOTO(r, < 0, error); sol_flow_send_drange_value_packet(node, type->out_port, out.val); return; error: sol_flow_send_error_packet_str(node, EIO, errmsg); SOL_WRN("%s", errmsg); } static void iio_color_reader_cb(void *data, struct sol_iio_device *device) { static const char *errmsg = "Could not read channel buffer values"; struct sol_flow_node *node = data; struct iio_color_data *mdata = sol_flow_node_get_private_data(node); struct sol_rgb out = { .red_max = mdata->iio_base.out_range.max, .green_max = mdata->iio_base.out_range.max, .blue_max = mdata->iio_base.out_range.max }; double tmp; int r; struct iio_node_type *type; type = (struct iio_node_type *)sol_flow_node_get_type(node); r = sol_iio_read_channel_value(mdata->channel_red, &tmp); if (r < 0 || tmp < 0 || tmp > UINT32_MAX) goto error; out.red = tmp; r = sol_iio_read_channel_value(mdata->channel_green, &tmp); if (r < 0 || tmp < 0 || tmp > UINT32_MAX) goto error; out.green = tmp; r = sol_iio_read_channel_value(mdata->channel_blue, &tmp); if (r < 0 || tmp < 0 || tmp > UINT32_MAX) goto error; out.blue = tmp; sol_flow_send_rgb_packet(node, type->out_port, &out); return; error: sol_flow_send_error_packet_str(node, EIO, errmsg); SOL_WRN("%s", errmsg); } static bool gyroscope_create_channels(struct iio_direction_vector_data *mdata, int device_id) { mdata->iio_base.device = sol_iio_open(device_id, &mdata->iio_base.config); SOL_NULL_CHECK(mdata->iio_base.device, false); mdata->channel_x = iio_add_channel(mdata->scale.x, mdata->offset.x, "in_anglvel_x", &mdata->iio_base); SOL_NULL_CHECK_GOTO(mdata->channel_x, error); mdata->channel_y = iio_add_channel(mdata->scale.y, mdata->offset.y, "in_anglvel_y", &mdata->iio_base); SOL_NULL_CHECK_GOTO(mdata->channel_y, error); mdata->channel_z = iio_add_channel(mdata->scale.z, mdata->offset.z, "in_anglvel_z", &mdata->iio_base); SOL_NULL_CHECK_GOTO(mdata->channel_z, error); sol_iio_device_start_buffer(mdata->iio_base.device); return true; error: SOL_WRN("Could not create iio/gyroscope node. Failed to open IIO device %d", device_id); sol_iio_close(mdata->iio_base.device); return false; } static int gyroscope_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct iio_direction_vector_data *mdata = data; const struct sol_flow_node_type_iio_gyroscope_options *opts; int device_id, ret; struct iio_node_type *type; type = (struct iio_node_type *)sol_flow_node_get_type(node); SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_IIO_GYROSCOPE_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_iio_gyroscope_options *)options; mdata->iio_base.buffer_enabled = opts->buffer_size > -1; SOL_SET_API_VERSION(mdata->iio_base.config.api_version = SOL_IIO_CONFIG_API_VERSION; ) if (opts->iio_trigger_name) { mdata->iio_base.config.trigger_name = strdup(opts->iio_trigger_name); SOL_NULL_CHECK(mdata->iio_base.config.trigger_name, -ENOMEM); } mdata->iio_base.config.buffer_size = opts->buffer_size; mdata->iio_base.config.sampling_frequency = opts->sampling_frequency; ret = snprintf(mdata->iio_base.config.sampling_frequency_name, sizeof(mdata->iio_base.config.sampling_frequency_name), "%s", "in_anglvel_"); SOL_INT_CHECK_GOTO(ret, >= (int)sizeof(mdata->iio_base.config.sampling_frequency_name), err); SOL_INT_CHECK_GOTO(ret, < 0, err); if (mdata->iio_base.buffer_enabled) { mdata->iio_base.config.sol_iio_reader_cb = type->reader_cb; mdata->iio_base.config.data = node; } mdata->iio_base.use_device_default_scale = opts->use_device_default_scale; mdata->iio_base.use_device_default_offset = opts->use_device_default_offset; mdata->scale = opts->scale; mdata->offset = opts->offset; mdata->iio_base.out_range = opts->out_range; device_id = sol_iio_address_device(opts->iio_device); if (device_id < 0) { SOL_WRN("Could not create iio/gyroscope node. Failed to open IIO device %s", opts->iio_device); goto err; } if (!gyroscope_create_channels(mdata, device_id)) goto err; return 0; err: free((char *)mdata->iio_base.config.trigger_name); return -EINVAL; } static bool magnet_create_channels(struct iio_direction_vector_data *mdata, int device_id) { mdata->iio_base.device = sol_iio_open(device_id, &mdata->iio_base.config); SOL_NULL_CHECK(mdata->iio_base.device, false); mdata->channel_x = iio_add_channel(mdata->scale.x, mdata->offset.x, "in_magn_x", &mdata->iio_base); SOL_NULL_CHECK_GOTO(mdata->channel_x, error); mdata->channel_y = iio_add_channel(mdata->scale.y, mdata->offset.y, "in_magn_y", &mdata->iio_base); SOL_NULL_CHECK_GOTO(mdata->channel_y, error); mdata->channel_z = iio_add_channel(mdata->scale.z, mdata->offset.z, "in_magn_z", &mdata->iio_base); SOL_NULL_CHECK_GOTO(mdata->channel_z, error); sol_iio_device_start_buffer(mdata->iio_base.device); return true; error: SOL_WRN("Could not create iio/magnet node. Failed to open IIO device %d", device_id); sol_iio_close(mdata->iio_base.device); return false; }
static void iio_direction_vector_reader_cb(void *data, struct sol_iio_device *device) { static const char *errmsg = "Could not read channel buffer values"; struct sol_flow_node *node = data; struct iio_direction_vector_data *mdata = sol_flow_node_get_private_data(node); struct sol_direction_vector out = { .min = mdata->iio_base.out_range.min, .max = mdata->iio_base.out_range.max }; int r; struct iio_node_type *type; type = (struct iio_node_type *)sol_flow_node_get_type(node); r = sol_iio_read_channel_value(mdata->channel_x, &out.x); SOL_INT_CHECK_GOTO(r, < 0, error); r = sol_iio_read_channel_value(mdata->channel_y, &out.y); SOL_INT_CHECK_GOTO(r, < 0, error); r = sol_iio_read_channel_value(mdata->channel_z, &out.z); SOL_INT_CHECK_GOTO(r, < 0, error); sol_flow_send_direction_vector_packet(node, type->out_port, &out); return; error: sol_flow_send_error_packet_str(node, EIO, errmsg); SOL_WRN("%s", errmsg); } static void iio_double_reader_cb(void *data, struct sol_iio_device *device) { static const char *errmsg = "Could not read channel buffer values"; struct sol_flow_node *node = data; struct iio_double_data *mdata = sol_flow_node_get_private_data(node); struct sol_drange out = { .min = mdata->iio_base.out_range.min, .max = mdata->iio_base.out_range.max, .step = mdata->iio_base.out_range.step }; int r; struct iio_node_type *type; type = (struct iio_node_type *)sol_flow_node_get_type(node); r = sol_iio_read_channel_value(mdata->channel_val, &out.val); SOL_INT_CHECK_GOTO(r, < 0, error); sol_flow_send_drange_value_packet(node, type->out_port, out.val); return; error: sol_flow_send_error_packet_str(node, EIO, errmsg); SOL_WRN("%s", errmsg); } static void iio_color_reader_cb(void *data, struct sol_iio_device *device) { static const char *errmsg = "Could not read channel buffer values"; struct sol_flow_node *node = data; struct iio_color_data *mdata = sol_flow_node_get_private_data(node); struct sol_rgb out = { .red_max = mdata->iio_base.out_range.max, .green_max = mdata->iio_base.out_range.max, .blue_max = mdata->iio_base.out_range.max }; double tmp; int r; struct iio_node_type *type; type = (struct iio_node_type *)sol_flow_node_get_type(node); r = sol_iio_read_channel_value(mdata->channel_red, &tmp); if (r < 0 || tmp < 0 || tmp > UINT32_MAX) goto error; out.red = tmp; r = sol_iio_read_channel_value(mdata->channel_green, &tmp); if (r < 0 || tmp < 0 || tmp > UINT32_MAX) goto error; out.green = tmp; r = sol_iio_read_channel_value(mdata->channel_blue, &tmp); if (r < 0 || tmp < 0 || tmp > UINT32_MAX) goto error; out.blue = tmp; sol_flow_send_rgb_packet(node, type->out_port, &out); return; error: sol_flow_send_error_packet_str(node, EIO, errmsg); SOL_WRN("%s", errmsg); } static bool gyroscope_create_channels(struct iio_direction_vector_data *mdata, int device_id) { struct sol_iio_channel_config channel_config = SOL_IIO_CHANNEL_CONFIG_INIT; mdata->iio_base.device = sol_iio_open(device_id, &mdata->iio_base.config); SOL_NULL_CHECK(mdata->iio_base.device, false); #define ADD_CHANNEL(_axis) \ if (!mdata->iio_base.use_device_default_scale) \ channel_config.scale = mdata->scale._axis; \ if (!mdata->iio_base.use_device_default_offset) \ channel_config.offset = mdata->offset._axis; \ mdata->channel_ ## _axis = sol_iio_add_channel(mdata->iio_base.device, "in_anglvel_" # _axis, &channel_config); \ SOL_NULL_CHECK_GOTO(mdata->channel_ ## _axis, error); ADD_CHANNEL(x); ADD_CHANNEL(y); ADD_CHANNEL(z); #undef ADD_CHANNEL sol_iio_device_start_buffer(mdata->iio_base.device); return true; error: SOL_WRN("Could not create iio/gyroscope node. Failed to open IIO device %d", device_id); sol_iio_close(mdata->iio_base.device); return false; } static int gyroscope_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct iio_direction_vector_data *mdata = data; const struct sol_flow_node_type_iio_gyroscope_options *opts; int device_id; struct iio_node_type *type; type = (struct iio_node_type *)sol_flow_node_get_type(node); SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_IIO_GYROSCOPE_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_iio_gyroscope_options *)options; mdata->iio_base.buffer_enabled = opts->buffer_size > -1; SOL_SET_API_VERSION(mdata->iio_base.config.api_version = SOL_IIO_CONFIG_API_VERSION; ) if (opts->iio_trigger_name) { mdata->iio_base.config.trigger_name = strdup(opts->iio_trigger_name); SOL_NULL_CHECK(mdata->iio_base.config.trigger_name, -ENOMEM); } mdata->iio_base.config.buffer_size = opts->buffer_size; mdata->iio_base.config.sampling_frequency = opts->sampling_frequency; if (mdata->iio_base.buffer_enabled) { mdata->iio_base.config.sol_iio_reader_cb = type->reader_cb; mdata->iio_base.config.data = node; } mdata->iio_base.use_device_default_scale = opts->use_device_default_scale; mdata->iio_base.use_device_default_offset = opts->use_device_default_offset; mdata->scale = opts->scale; mdata->offset = opts->offset; mdata->iio_base.out_range = opts->out_range; device_id = sol_iio_address_device(opts->iio_device); if (device_id < 0) { SOL_WRN("Could not create iio/gyroscope node. Failed to open IIO device %s", opts->iio_device); goto err; } if (!gyroscope_create_channels(mdata, device_id)) goto err; return 0; err: free((char *)mdata->iio_base.config.trigger_name); return -EINVAL; } static bool magnet_create_channels(struct iio_direction_vector_data *mdata, int device_id) { struct sol_iio_channel_config channel_config = SOL_IIO_CHANNEL_CONFIG_INIT; mdata->iio_base.device = sol_iio_open(device_id, &mdata->iio_base.config); SOL_NULL_CHECK(mdata->iio_base.device, false); #define ADD_CHANNEL(_axis) \ if (!mdata->iio_base.use_device_default_scale) \ channel_config.scale = mdata->scale._axis; \ if (!mdata->iio_base.use_device_default_offset) \ channel_config.offset = mdata->offset._axis; \ mdata->channel_ ## _axis = sol_iio_add_channel(mdata->iio_base.device, "in_magn_" # _axis, &channel_config); \ SOL_NULL_CHECK_GOTO(mdata->channel_ ## _axis, error); ADD_CHANNEL(x); ADD_CHANNEL(y); ADD_CHANNEL(z); #undef ADD_CHANNEL sol_iio_device_start_buffer(mdata->iio_base.device); return true; error: SOL_WRN("Could not create iio/magnet node. Failed to open IIO device %d", device_id); sol_iio_close(mdata->iio_base.device); return false; } static int magnet_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct iio_direction_vector_data *mdata = data; const struct sol_flow_node_type_iio_magnetometer_options *opts; int device_id; struct iio_node_type *type; type = (struct iio_node_type *)sol_flow_node_get_type(node); SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_IIO_MAGNETOMETER_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_iio_magnetometer_options *)options; mdata->iio_base.buffer_enabled = opts->buffer_size > -1; SOL_SET_API_VERSION(mdata->iio_base.config.api_version = SOL_IIO_CONFIG_API_VERSION; ) if (opts->iio_trigger_name) { mdata->iio_base.config.trigger_name = strdup(opts->iio_trigger_name); SOL_NULL_CHECK(mdata->iio_base.config.trigger_name, -ENOMEM); } mdata->iio_base.config.buffer_size = opts->buffer_size; mdata->iio_base.config.sampling_frequency = opts->sampling_frequency; if (mdata->iio_base.buffer_enabled) { mdata->iio_base.config.sol_iio_reader_cb = type->reader_cb; mdata->iio_base.config.data = node; } mdata->iio_base.use_device_default_scale = opts->use_device_default_scale; mdata->iio_base.use_device_default_offset = opts->use_device_default_offset; mdata->scale = opts->scale; mdata->offset = opts->offset; mdata->iio_base.out_range = opts->out_range; device_id = sol_iio_address_device(opts->iio_device); if (device_id < 0) { SOL_WRN("Could not create iio/magnet node. Failed to open IIO device %s", opts->iio_device); goto err; } if (!magnet_create_channels(mdata, device_id)) goto err; return 0; err: free((char *)mdata->iio_base.config.trigger_name); return -EINVAL; } static bool temp_create_channels(struct iio_double_data *mdata, int device_id) { struct sol_iio_channel_config channel_config = SOL_IIO_CHANNEL_CONFIG_INIT; mdata->iio_base.device = sol_iio_open(device_id, &mdata->iio_base.config); SOL_NULL_CHECK(mdata->iio_base.device, false); #define ADD_CHANNEL(_val) \ if (!mdata->iio_base.use_device_default_scale) \ channel_config.scale = mdata->scale; \ if (!mdata->iio_base.use_device_default_offset) \ channel_config.offset = mdata->offset; \ mdata->channel_ ## _val = sol_iio_add_channel(mdata->iio_base.device, "in_temp", &channel_config); \ SOL_NULL_CHECK_GOTO(mdata->channel_ ## _val, error); ADD_CHANNEL(val); #undef ADD_CHANNEL sol_iio_device_start_buffer(mdata->iio_base.device); return true; error: SOL_WRN("Could not create iio/thermometer node. Failed to open" " IIO device %d", device_id); sol_iio_close(mdata->iio_base.device); return false; } static int temperature_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options) { struct iio_double_data *mdata = data; const struct sol_flow_node_type_iio_thermometer_options *opts; int device_id; struct iio_node_type *type; type = (struct iio_node_type *)sol_flow_node_get_type(node); SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_IIO_THERMOMETER_OPTIONS_API_VERSION, -EINVAL); opts = (const struct sol_flow_node_type_iio_thermometer_options *)options; mdata->iio_base.buffer_enabled = opts->buffer_size > -1; SOL_SET_API_VERSION(mdata->iio_base.config.api_version = SOL_IIO_CONFIG_API_VERSION; ) if (opts->iio_trigger_name) { mdata->iio_base.config.trigger_name = strdup(opts->iio_trigger_name); SOL_NULL_CHECK(mdata->iio_base.config.trigger_name, -ENOMEM); } mdata->iio_base.config.buffer_size = opts->buffer_size; mdata->iio_base.config.sampling_frequency = opts->sampling_frequency; if (mdata->iio_base.buffer_enabled) { mdata->iio_base.config.sol_iio_reader_cb = type->reader_cb; mdata->iio_base.config.data = node; } mdata->iio_base.use_device_default_scale = opts->use_device_default_scale; mdata->iio_base.use_device_default_offset = opts->use_device_default_offset; mdata->scale = opts->scale; mdata->offset = opts->offset; mdata->iio_base.out_range = opts->out_range; device_id = sol_iio_address_device(opts->iio_device); if (device_id < 0) { SOL_WRN("Could not create iio/thermometer node. Failed to" " open IIO device %s", opts->iio_device); goto err; } if (!temp_create_channels(mdata, device_id)) goto err; return 0; err: free((char *)mdata->iio_base.config.trigger_name); return -EINVAL; }