SOL_API struct sol_i2c_pending *
sol_i2c_write_quick(struct sol_i2c *i2c, bool rw,
    void (*write_quick_cb)(void *cb_data, struct sol_i2c *i2c, ssize_t status),
    const void *cb_data)
{
    SOL_WRN("Unsupported");
    return NULL;
}
Example #2
0
static bool
_load_mux(const char *name)
{
#ifdef ENABLE_DYNAMIC_MODULES
    int r;
    void *handle;
    char path[PATH_MAX];
    const struct sol_pin_mux *p_sym;

    r = snprintf(path, sizeof(path), "%s/%s.so", PINMUXDIR, name);
    SOL_INT_CHECK(r, >= (int)sizeof(path), false);
    SOL_INT_CHECK(r, < 0, false);

    handle = dlopen(path, RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE);
    if (!handle) {
        SOL_INF("Could not load platform pin multiplexer '%s': %s", path, dlerror());
        return true; // Not find a mux isn't necessarily an error, so we are returning true here
    }

    p_sym = dlsym(handle, "SOL_PIN_MUX");
    if (!p_sym) {
        SOL_WRN("Could not find symbol SOL_PIN_MUX in module '%s': %s", path, dlerror());
        goto error;
    }

    if (p_sym->api_version != SOL_PIN_MUX_API_VERSION) {
        SOL_WRN("Mux '%s' has incorrect api_version: %lu expected %lu", path, p_sym->api_version,
            SOL_PIN_MUX_API_VERSION);
        goto error;
    }

    if (dl_handle)
        dlclose(dl_handle);

    mux = p_sym;
    dl_handle = handle;

    SOL_INF("Loaded pin multiplexer '%s' from '%s'", mux->plat_name, path);
    return true;

error:
    dlclose(handle);
#endif
    return false;
}
Example #3
0
SOL_API int
sol_rgb_set_max(struct sol_rgb *color, uint32_t max_value)
{
    uint64_t val;

    if (!max_value) {
        SOL_WRN("Max value can't be zero");
        return -EINVAL;
    }

    if (!color->red_max || !color->green_max || !color->blue_max) {
        SOL_WRN("Color max values can't be zero.");
        return -EINVAL;
    }

    if (color->red > color->red_max) {
        SOL_WRN("Red component out of range: %" PRId32 " > %" PRId32 ". "
            "Assuming max value.", color->red, color->red_max);
        color->red = color->red_max;
    }
    if (color->green > color->green_max) {
        SOL_WRN("Green component out of range: %" PRId32 " > %" PRId32 ". "
            "Assuming max value.", color->green, color->green_max);
        color->green = color->green_max;
    }
    if (color->blue > color->blue_max) {
        SOL_WRN("Blue component out of range: %" PRId32 " > %" PRId32 ". "
            "Assuming max value.", color->blue, color->blue_max);
        color->blue = color->blue_max;
    }

    val = (uint64_t)color->red * max_value / color->red_max;
    color->red = val;
    color->red_max = max_value;

    val = (uint64_t)color->green * max_value / color->green_max;
    color->green = val;
    color->green_max = max_value;

    val = (uint64_t)color->blue * max_value / color->blue_max;
    color->blue = val;
    color->blue_max = max_value;

    return 0;
}
Example #4
0
int
main(int argc, char *argv[])
{
    struct light_context context = { .resource = &light };
    struct sol_coap_server *server;
    char old_led_state;

    sol_init();

    server = sol_coap_server_new(DEFAULT_UDP_PORT);
    if (!server) {
        SOL_WRN("Could not create a coap server using port %d.", DEFAULT_UDP_PORT);
        return -1;
    }

    if (!sol_coap_server_register_resource(server, &light, server)) {
        SOL_WRN("Could not register resource for the light");
        return -1;
    }

    console_fd = open("/dev/console", O_RDWR);
    if (console_fd < 0) {
        perror("Could not open '/dev/console'");
        return -1;
    }

    if (ioctl(console_fd, KDGETLED, (char *)&old_led_state)) {
        perror("Could not get the keyboard leds state");
        return -1;
    }

    context.server = server;
    sol_timeout_add(5000, update_light, &context);

    sol_run();

    sol_coap_server_unref(server);

    if (ioctl(console_fd, KDSETLED, old_led_state)) {
        perror("Could not return the leds to the old state");
        return -1;
    }

    return 0;
}
Example #5
0
SOL_API struct sol_i2c *
sol_i2c_open_raw(uint8_t bus, enum sol_i2c_speed speed)
{
    int len, dev;
    struct sol_i2c *i2c;
    unsigned long funcs;
    char i2c_dev_path[PATH_MAX];

    SOL_LOG_INTERNAL_INIT_ONCE;

    len = snprintf(i2c_dev_path, sizeof(i2c_dev_path), "/dev/i2c-%u", bus);
    if (len < 0 || len >= PATH_MAX) {
        SOL_WRN("i2c #%u: could not format device path", bus);
        return NULL;
    }

    i2c = calloc(1, sizeof(*i2c));
    if (!i2c) {
        SOL_WRN("i2c #%u: could not allocate i2c context", bus);
        errno = ENOMEM;
        return NULL;
    }

    dev = open(i2c_dev_path, O_RDWR | O_CLOEXEC);
    if (dev < 0) {
        SOL_WRN("i2c #%u: could not open device file", bus);
        goto open_error;
    }
    i2c->bus = bus;
    i2c->dev = dev;

    /* check if the given I2C adapter supports plain-i2c messages */
    if (ioctl(i2c->dev, I2C_FUNCS, &funcs) == -1)
        goto ioctl_error;

    i2c->plain_i2c = (funcs & I2C_FUNC_I2C);

    return i2c;

ioctl_error:
    close(i2c->dev);
open_error:
    free(i2c);
    return NULL;
}
Example #6
0
static void
i2c_read_who_am_i_cb(void *cb_data, struct sol_i2c *i2c, uint8_t reg, uint8_t *data, ssize_t status)
{
    struct gyroscope_l3g4200d_data *mdata = cb_data;

    mdata->i2c_pending = NULL;
    if (status < 0) {
        SOL_WRN("Failed to read i2c register");
        return;
    }

    if (mdata->common.buffer[0] != GYRO_REG_WHO_AM_I_VALUE) {
        SOL_WRN("could not find L3G4200D gyro sensor");
        return;
    }

    gyro_timer_resched(mdata, GYRO_INIT_STEP_TIME, gyro_init_sampling);
}
Example #7
0
/*
 * do things getty would do to spawn a shell, basically become the
 * session leader of the given tty, then make stdio/stdout/stderr use
 * it.
 */
static void
do_shell(const char *tty)
{
    char term_buf[128];
    const char *envp[] = {
        term_buf,
        "HOME=/",
        NULL,
    };
    char tty_path[PATH_MAX];
    pid_t pid, tsid;
    int r;

    SOL_INF("no getty, exec shell: %s", shell);

    r = snprintf(term_buf, sizeof(term_buf), "TERM=%s",
        term ? term : get_term_for_tty(tty));
    if (r < 0 || r >= (int)sizeof(term_buf))
        envp[0] = "TERM=vt102";

    pid = setsid();
    if (pid < 0) {
        int fd;

        SOL_WRN("could not setsid(): %s", sol_util_strerrora(errno));
        pid = getpid();
        fd = open("/dev/tty", O_RDWR | O_NONBLOCK);
        if (fd >= 0) {
            sighandler_t oldsig;
            /* man:tty(4)
             * TIOCNOTTY:
             * Detach the calling process from its controlling terminal.
             *
             * If the process is the session leader, then SIGHUP and
             * SIGCONT signals are sent to the foreground process
             * group and all processes in the current session lose
             * their controlling tty.
             */
            oldsig = signal(SIGHUP, SIG_IGN);
            ioctl(fd, TIOCNOTTY);
            close(fd);
            signal(SIGHUP, oldsig);
        }
    }

    r = snprintf(tty_path, sizeof(tty_path), "/dev/%s", tty);
    SOL_INT_CHECK_GOTO(r, < 0, end);
    SOL_INT_CHECK_GOTO(r, >= (int)sizeof(tty_path), end);

    close(STDIN_FILENO);
    r = open(tty_path, O_RDWR | O_NONBLOCK);
    SOL_INT_CHECK_GOTO(r, < 0, end);

    if (r != 0) {
        r = dup2(r, 0);
        SOL_INT_CHECK_GOTO(r, < 0, end);
    }
Example #8
0
static void
startup(void)
{
    session = sol_bt_enable(enabled, NULL);
    if (!session) {
        SOL_WRN("Couldn't create a Bluetooth session");
        sol_quit_with_code(-ENOMEM);
    }
}
static void
_aio_get_value(struct sol_aio *aio, unsigned int *val)
{
    rewind(aio->fp);

    if (fscanf(aio->fp, "%u", val) < 1) {
        SOL_WRN("AIO #%d,%d: Could not read value.", aio->device, aio->pin);
        *val = -EIO;
    }
}
Example #10
0
static void
i2c_write_ctrl_reg1_cb(void *cb_data, struct sol_i2c *i2c, uint8_t reg, uint8_t *data, ssize_t status)
{
    struct gyroscope_l3g4200d_data *mdata = cb_data;

    mdata->i2c_pending = NULL;
    if (status < 0) {
        SOL_WRN("could not set L3G4200D gyro sensor's sampling rate");
        return;
    }

    mdata->init_sampling_cnt--;

    if (gyro_timer_resched(mdata, GYRO_INIT_STEP_TIME,
                           mdata->init_sampling_cnt ?
                           gyro_init_sampling : gyro_init_range) < 0) {
        SOL_WRN("error in scheduling a L3G4200D gyro's init command");
    }
}
Example #11
0
static void
spi_transfer_initial_reset(void *cb_data, struct sol_spi *spi, const uint8_t *tx, uint8_t *rx, ssize_t status)
{
    struct lcd_strip_lpd8806_data *mdata = cb_data;

    mdata->spi_busy = false;

    if (status < 0)
        SOL_WRN("SPI error when writing initial value of pixels.");
}
Example #12
0
static int
gyro_init(struct gyroscope_l3g4200d_data *mdata)
{
    ssize_t r;
    uint8_t data = 0;

    r = sol_i2c_read_register(mdata->i2c, GYRO_REG_WHO_AM_I, &data, 1);
    if (r < 0) {
        SOL_WRN("Failed to read i2c register");
        return r;
    }
    if (data != GYRO_REG_WHO_AM_I_VALUE) {
        SOL_WRN("could not find L3G4200D gyro sensor");
        return -EIO;
    }

    return gyro_timer_resched(mdata, GYRO_INIT_STEP_TIME,
        gyro_init_sampling, mdata) == 0;
}
Example #13
0
static int
slider_setup(struct gtk_common_data *data,
    const struct sol_flow_node_options *options)
{
    int min = 0;
    int max = 100;
    int step = 1;

    struct gtk_common_data *mdata = (struct gtk_common_data *)data;
    const struct sol_flow_node_type_gtk_slider_options *opts =
        (const struct sol_flow_node_type_gtk_slider_options *)options;

    SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options,
        SOL_FLOW_NODE_TYPE_GTK_SLIDER_OPTIONS_API_VERSION,
        -EINVAL);

    min = opts->range.min;
    max = opts->range.max;
    step = opts->range.step;

    if (min > max) {
        SOL_WRN("invalid range min=%d max=%d for slider id=%s\n",
            min, max, sol_flow_node_get_id(mdata->node));
        return -EINVAL;
    }

    if (step <= 0) {
        SOL_WRN("invalid step=%d for slider id=%s\n",
            step, sol_flow_node_get_id(mdata->node));
        return -EINVAL;
    }

    mdata->widget = gtk_scale_new_with_range
            (GTK_ORIENTATION_HORIZONTAL, min, max, step);
    g_signal_connect(mdata->widget, "value-changed",
        G_CALLBACK(on_slider_changed), mdata);
    g_object_set(mdata->widget, "hexpand", true, NULL);

    // GtkScale natural size is too small, give it a better default.
    gtk_widget_set_size_request(mdata->widget, 300, -1);

    return 0;
}
Example #14
0
static int
accumulator_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    int32_t tmp;
    struct accumulator_data *mdata = data;
    const struct sol_flow_node_type_int_accumulator_options *opts =
        (const struct sol_flow_node_type_int_accumulator_options *)options;

    SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK
        (options, SOL_FLOW_NODE_TYPE_INT_ACCUMULATOR_OPTIONS_API_VERSION, -EINVAL);
    mdata->val = opts->setup_value;

    // Sanitizing options input
    if (mdata->val.max < mdata->val.min) {
        SOL_WRN("Max (%" PRId32 ") should be greater than Min (%" PRId32 "). Switching both values.",
            mdata->val.max, mdata->val.min);
        tmp = mdata->val.max;
        mdata->val.max = mdata->val.min;
        mdata->val.min = tmp;
    }

    if (mdata->val.val > mdata->val.max || mdata->val.val < mdata->val.min) {
        SOL_WRN("Value (%" PRId32 ") should be in %" PRId32 " - %" PRId32 " range,"
            " switching it to %" PRId32 "", mdata->val.val, mdata->val.min,
            mdata->val.max, mdata->val.min);
        mdata->val.val = mdata->val.min;
    }

    if (!mdata->val.step) {
        mdata->val.step = 1;
        SOL_WRN("Step can't be zero. Using (%" PRId32 ") instead.", mdata->val.step);
    } else if (mdata->val.step < 0) {
        mdata->val.step = -mdata->val.step;
        SOL_WRN("Step (-%" PRId32 ") can't be a negative value. Using (%" PRId32 ") instead.",
            mdata->val.step, mdata->val.step);
    }

    mdata->init_val = opts->setup_value.val;

    return sol_flow_send_irange_packet(node,
        SOL_FLOW_NODE_TYPE_INT_ACCUMULATOR__OUT__OUT,
        &mdata->val);
}
Example #15
0
static void
common_close(struct sol_flow_node *node, void *data)
{
    struct update_data *mdata = data;

    if (mdata->handle) {
        if (!sol_update_cancel(mdata->handle))
            SOL_WRN("Could not cancel ongoing task: %p", mdata->handle);
    }
}
Example #16
0
static void
thingspeak_channel_update_queue(struct thingspeak_channel_update_data *mdata)
{
    if (mdata->timeout)
        sol_timeout_del(mdata->timeout);
    mdata->timeout = sol_timeout_add(500, thingspeak_channel_update_send,
        mdata);
    if (!mdata->timeout)
        SOL_WRN("Could not create timeout to update Thingspeak channel");
}
Example #17
0
static void
i2c_write_configuration_cb(void *cb_data, struct sol_i2c *i2c, uint8_t reg,
    uint8_t *data, ssize_t status)
{
    struct stts751_data *mdata = cb_data;

    mdata->i2c_pending = NULL;
    if (status < 0)
        SOL_WRN("Could not enable STTS751 temperature sensor");
}
Example #18
0
static bool
sol_mavlink_fd_handler(void *data, int fd, uint32_t cond)
{
    struct sol_mavlink *mavlink = data;
    mavlink_message_t msg = { 0 };
    mavlink_status_t status;
    uint8_t buf[MAVLINK_MAX_PACKET_LEN] = { 0 };
    int i, res;

    res = recv(mavlink->fd, buf, MAVLINK_MAX_PACKET_LEN, 0);
    if (res == -1) {
        if (errno == EINTR) {
            SOL_INF("Could not read socket, retrying.");
            return true;
        } else {
            SOL_WRN("Could not read socket. %s",
                sol_util_strerrora(errno));
            return false;
        }
    }

    for (i = 0; i < res; ++i) {
        if (!mavlink_parse_char(MAVLINK_COMM_0, buf[i], &msg, &status))
            continue;

        switch (msg.msgid) {
        case MAVLINK_MSG_ID_GPS_RAW_INT:
            sol_mavlink_position_handler(mavlink, &msg);
            break;
        case MAVLINK_MSG_ID_HEARTBEAT:
            sol_mavlink_heartbeat_handler(mavlink, &msg);
            break;
        case MAVLINK_MSG_ID_STATUSTEXT:
            sol_mavlink_statustext_handler(&msg);
            break;
        case MAVLINK_MSG_ID_HOME_POSITION:
            sol_mavlink_home_position_handler(mavlink, &msg);
            break;
        case MAVLINK_MSG_ID_MISSION_ITEM_REACHED:
            sol_mavlink_mission_reached_handler(mavlink);
            break;
        default:
            SOL_INF("Unhandled event, msgid: %d", msg.msgid);
        }
    }

    if (mavlink->status == SOL_MAVLINK_STATUS_FULL_SETUP) {
        mavlink->status = SOL_MAVLINK_STATUS_READY;

        if (CHECK_HANDLER(mavlink, connect))
            HANDLERS(mavlink)->connect((void *)mavlink->data, mavlink);
    }

    return true;
}
SOL_API struct sol_message_digest *
sol_message_digest_new(const struct sol_message_digest_config *config)
{
    const struct sol_message_digest_info *dinfo;
    struct sol_message_digest *handle;
    struct sol_message_digest_common_new_params params;
    struct sol_str_slice algorithm;

    errno = EINVAL;
    SOL_NULL_CHECK(config, NULL);
    SOL_NULL_CHECK(config->on_digest_ready, NULL);
    SOL_NULL_CHECK(config->algorithm, NULL);

#ifndef SOL_NO_API_VERSION
    if (config->api_version != SOL_MESSAGE_DIGEST_CONFIG_API_VERSION) {
        SOL_WRN("sol_message_digest_config->api_version=%" PRIu16 ", "
            "expected version is %" PRIu16 ".",
            config->api_version, SOL_MESSAGE_DIGEST_CONFIG_API_VERSION);
        return NULL;
    }
#endif

    algorithm = sol_str_slice_from_str(config->algorithm);
    if (!sol_str_table_ptr_lookup(_available_digests, algorithm, &dinfo)) {
        SOL_WRN("failed to get digest algorithm \"%s\".",
            config->algorithm);
        return NULL;
    }

    params.config = config;
    params.ops = &dinfo->ops;
    params.context_size = dinfo->context_size;
    params.digest_size = dinfo->digest_size;
    params.context_template = NULL;

    handle = sol_message_digest_common_new(params);
    SOL_NULL_CHECK(handle, NULL);

    dinfo->init(handle);

    return handle;
}
Example #20
0
static int
hostname_start(const struct sol_platform_linux_micro_module *mod, const char *service)
{
    struct sol_file_reader *reader;
    struct sol_str_slice str;
    const char *s, *p, *end;
    int err = 0;

    reader = sol_file_reader_open("/etc/hostname");
    SOL_NULL_CHECK_MSG(reader, -errno, "could not read /etc/hostname");

    str = sol_file_reader_get_all(reader);
    s = p = str.data;
    end = s + str.len;

    for (; s < end; s++) {
        if (!isblank(*s))
            break;
    }

    for (p = end - 1; p > s; p--) {
        if (!isblank(*p))
            break;
    }

    if (s >= p) {
        SOL_WRN("no hostname in /etc/hostname");
        err = -ENOENT;
    } else if (sethostname(s, p - s) < 0) {
        SOL_WRN("could not set hostname: %s", sol_util_strerrora(errno));
        err = -errno;
    }

    sol_file_reader_close(reader);

    if (err == 0)
        sol_platform_linux_micro_inform_service_state(service, SOL_PLATFORM_SERVICE_STATE_ACTIVE);
    else
        sol_platform_linux_micro_inform_service_state(service, SOL_PLATFORM_SERVICE_STATE_FAILED);

    return err;
}
Example #21
0
static bool
watchdog_keep_alive(void *data)
{
    int reply, err;

    SOL_DBG("keep watchdog alive");
    err = ioctl(watchdog_fd, WDIOC_KEEPALIVE, &reply);
    if (reply != WDIOF_KEEPALIVEPING)
        SOL_WRN("unexpected watchdog keepalive reply=%#x, expected=%#x. Ignored.",
            reply, WDIOF_KEEPALIVEPING);
    if (err == 0)
        return true;

    SOL_WRN("failed to keep watchdog alive: %s", sol_util_strerrora(errno));
    close(watchdog_fd);
    watchdog_fd = -1;
    watchdog_timeout = NULL;
    sol_platform_linux_micro_inform_service_state(service_name, SOL_PLATFORM_SERVICE_STATE_FAILED);
    return false;
}
Example #22
0
static void
mark_done(const struct sol_flow_node *node)
{
    struct test_result_data *d = sol_flow_node_get_private_data(node);

    if (!d->done) {
        d->done = true;
        return;
    }
    SOL_WRN("test/result node '%s' got more results than expected", sol_flow_node_get_id(node));
}
Example #23
0
static int
_populate_values(void *data, const char *sequence)
{
    struct byte_validator_data *mdata = data;
    const char *it;
    char *tail;
    unsigned char *val;

    sol_vector_init(&mdata->values, sizeof(unsigned char));
    it = sequence;
    do {
        int int_val;
        val = sol_vector_append(&mdata->values);
        SOL_NULL_CHECK_GOTO(val, no_memory);

        errno = 0;
        int_val = strtol(it, &tail, 10);

        if (errno) {
            SOL_WRN("Failed do convert option 'sequence' to int %s: %d",
                it, errno);
            return -errno;
        }
        if (int_val < 0 || int_val > 255) {
            SOL_WRN("Byte value out of range %d", int_val);
            return -ERANGE;
        }
        if (it == tail) {
            SOL_WRN("Failed to convert option 'sequence' to int %s", it);
            return -EINVAL;
        }
        it = tail;
        *val = int_val;
    } while (*tail != '\0');

    return 0;

no_memory:
    sol_vector_clear(&mdata->values);
    return -ENOMEM;
}
Example #24
0
static void
on_connect(void *data, struct sol_mqtt *mqtt)
{
    if (sol_mqtt_get_connection_status(mqtt) != SOL_MQTT_CONNECTED) {
        SOL_WRN("Unable to connect, retrying...");
        sol_timeout_add(1000, try_reconnect, mqtt);
        return;
    }

    if (sol_mqtt_subscribe(mqtt, topic, SOL_MQTT_QOS_AT_MOST_ONCE))
        SOL_ERR("Unable to subscribe to topic %s", topic);
}
static void
shutdown(void)
{
    if (!did_idle)
        SOL_WRN("failed to do idle");
    if (!did_timeout)
        SOL_WRN("failed to do timeout");
    if (!did_fd)
        SOL_WRN("failed to do fd");

    if (fork_run)
        sol_platform_linux_fork_run_stop(fork_run);

    if (pfd[0] > 0) {
        close(pfd[0]);
        close(pfd[1]);
    }

    if (!did_idle || !did_timeout || !did_fd)
        exit(EXIT_FAILURE);
}
Example #26
0
int
sol_pin_mux_init(void)
{
    sol_log_domain_init_level(SOL_LOG_DOMAIN);

    if (!sol_pin_mux_select_mux(sol_platform_get_board_name())) {
        SOL_WRN("Pin Multiplexer found, but failed to be loaded.");
        return -1;
    }

    return 0;
}
Example #27
0
static void
lsm303_scale_bit_set(struct accelerometer_lsm303_data *mdata)
{
    int r;

    r = sol_i2c_set_slave_address(mdata->i2c, mdata->slave);

    if (r < 0) {
        SOL_WRN("Failed to set slave at address 0x%02x\n", mdata->slave);
        return;
    }

    switch (mdata->scale) {
    case 2:
        mdata->i2c_buffer[0] = 0x00;
        mdata->sensitivity = 1.0 / 1000;
        break;
    case 4:
        mdata->i2c_buffer[0] = 0x01;
        mdata->sensitivity = 2.0 / 1000;
        break;
    case 8:
        mdata->i2c_buffer[0] = 0x02;
        mdata->sensitivity = 4.0 / 1000;
        break;
    case 16:
        mdata->i2c_buffer[0] = 0x03;
        mdata->sensitivity = 12.0 / 1000;
        break;
    default:
        SOL_WRN("Invalid scale. Expected one of 2, 4, 8 or 16");
        return;
    }

    mdata->i2c_pending = sol_i2c_write_register(mdata->i2c,
        LSM303_ACCEL_REG_CTRL_REG4_A, mdata->i2c_buffer, 1,
        lsm303_i2c_write_scale_cb, mdata);
    if (!mdata->i2c_pending)
        SOL_WRN("Could not set scale to LSM303 accelerometer");
}
static void
flow_send_do(struct sol_flow_node *flow, struct flow_static_data *fsd, uint16_t src_idx, uint16_t source_out_port_idx, struct sol_flow_packet *packet)
{
    struct flow_static_type *type = (struct flow_static_type *)flow->type;
    const struct sol_flow_static_conn_spec *spec;
    unsigned int i;
    bool is_error_packet, dispatched;

    is_error_packet = sol_flow_packet_get_type(packet) == SOL_FLOW_PACKET_TYPE_ERROR;
    dispatched = false;

    for (i = type->node_infos[src_idx].first_conn_idx, spec = type->conn_specs + i; spec->src == src_idx; spec++, i++) {
        const struct sol_flow_port_type_in *dst_port_type;
        struct sol_flow_node *dst;
        struct conn_info *ci;

        if (spec->src_port != source_out_port_idx)
            continue;

        dst = fsd->nodes[spec->dst];
        dst_port_type = sol_flow_node_type_get_port_in(dst->type, spec->dst_port);
        ci = &type->conn_infos[i];

        dispatch_process(dst, spec->dst_port, ci->in_conn_id, dst_port_type, packet);
        dispatched = true;
    }

    if (type->ports_out_count > 0) {
        const struct sol_flow_static_port_spec *pspec;
        uint16_t exported_out;
        for (pspec = type->exported_out_specs, exported_out = 0; pspec->node < UINT16_MAX; pspec++, exported_out++) {
            if (pspec->node == src_idx && pspec->port == source_out_port_idx) {
                /* Export the packet. Note that ownership of packet
                 * will pass to the send() function. */
                sol_flow_send_packet(flow, exported_out, packet);
                return;
            }
        }
    }

    if (is_error_packet && !dispatched) {
        const char *msg;
        int code;

        if (sol_flow_packet_get_error(packet, &code, &msg) == 0) {
            SOL_WRN("Error packet \'%d (%s)\' sent from \'%s (%p)\' was not handled", code,
                msg, flow->id, flow);
        }
    }

    sol_flow_packet_del(packet);
}
Example #29
0
SOL_API int
sol_json_token_get_int64(const struct sol_json_token *token, int64_t *value)
{
    SOL_NULL_CHECK(token, -EINVAL);
    SOL_NULL_CHECK(value, -EINVAL);

    *value = 0;

    if (token->start >= token->end) {
        SOL_WRN("invalid token: start=%p, end=%p",
            token->start, token->end);
        return -EINVAL;
    }
    if (sol_json_token_get_type(token) != SOL_JSON_TYPE_NUMBER) {
        SOL_WRN("expected number, got token type '%c' for token \"%.*s\"",
            sol_json_token_get_type(token),
            (int)sol_json_token_get_size(token), token->start);
        return -EINVAL;
    }

    return token_get_int64(token, value);
}
void
sol_worker_thread_impl_feedback(void *handle)
{
    struct sol_worker_thread_posix *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 != pthread_self()) {
        SOL_WRN("trying to feedback from different worker thread %p.", thread);
        return;
    }
    if (sol_worker_thread_lock(thread)) {
        if (!thread->idler)
            thread->idler = sol_idle_add(sol_worker_thread_feedback_dispatch, thread);
        sol_worker_thread_unlock(thread);
    }
}