Пример #1
0
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;
}
Пример #2
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;
}
Пример #3
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;
}
Пример #4
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);
}
Пример #5
0
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;
}
Пример #6
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));
}
Пример #7
0
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;
}
Пример #8
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;
}
Пример #9
0
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;
}
Пример #10
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
}
Пример #11
0
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;
}
Пример #12
0
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;
}
Пример #13
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;
}
Пример #14
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;
}
Пример #15
0
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);
}
Пример #16
0
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;
}
Пример #17
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;
}
Пример #18
0
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;
}
Пример #19
0
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;
}
Пример #20
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;
}
Пример #21
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;
}
Пример #22
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; )
Пример #23
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;
}
Пример #24
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;
}
Пример #25
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);
}
Пример #26
0
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;
}
Пример #27
0
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);
}
Пример #28
0
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;
}
Пример #29
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);
}
Пример #30
0
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;
}