コード例 #1
0
ファイル: format.c プロジェクト: Learn-iot/soletta
static int
irange_to_string_convert(struct sol_flow_node *node,
    void *data,
    uint16_t port,
    uint16_t conn_id,
    const struct sol_flow_packet *packet)
{
    int r;
    struct sol_irange in_value;
    struct string_converter *mdata = data;
    struct sol_buffer out = SOL_BUFFER_INIT_EMPTY;

    mdata->node = node;

    r = sol_flow_packet_get_irange(packet, &in_value);
    SOL_INT_CHECK(r, < 0, r);

    r = do_integer_markup(node, mdata->format, in_value, &out);
    SOL_INT_CHECK_GOTO(r, < 0, end);

    r = sol_flow_send_string_slice_packet(node,
        SOL_FLOW_NODE_TYPE_FORMAT_INT_TO_STRING__OUT__OUT,
        sol_buffer_get_slice(&out));

end:
    sol_buffer_fini(&out);
    return r;
}
コード例 #2
0
ファイル: int.c プロジェクト: kalyankondapally/soletta
static int
operator_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet)
{
    struct irange_arithmetic_data *mdata = data;
    struct sol_irange value;
    int r;

    r = sol_flow_packet_get_irange(packet, &value);
    SOL_INT_CHECK(r, < 0, r);

    if (port == 0) {
        if (mdata->var0_initialized &&
            sol_irange_equal(&mdata->var0, &value))
            return 0;
        mdata->var0 = value;
        mdata->var0_initialized = true;
    } else {
        if (mdata->var1_initialized &&
            sol_irange_equal(&mdata->var1, &value))
            return 0;
        mdata->var1 = value;
        mdata->var1_initialized = true;
    }

    if (!(mdata->var0_initialized && mdata->var1_initialized))
        return 0;

    r = mdata->func(&mdata->var0, &mdata->var1, &value);
    if (r < 0) {
        sol_flow_send_error_packet(node, -r, sol_util_strerrora(-r));
        return r;
    }

    return sol_flow_send_irange_packet(node, mdata->port, &value);
}
コード例 #3
0
ファイル: int.c プロジェクト: kalyankondapally/soletta
static int
irange_map_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet)
{
    struct irange_map_data *mdata = data;
    struct sol_irange in_value;
    int32_t out_value;
    int r;

    r = sol_flow_packet_get_irange(packet, &in_value);
    SOL_INT_CHECK(r, < 0, r);

    if (mdata->use_input_range) {
        if (in_value.min >= in_value.max) {
            SOL_WRN("Invalid range: input max must to be bigger than min");
            return -EINVAL;
        }
        r = _map(in_value.val, in_value.min, in_value.max, mdata->output.min,
            mdata->output.max, mdata->output_value.step, &out_value);
    } else
        r = _map(in_value.val, mdata->input.min, mdata->input.max,
            mdata->output.min, mdata->output.max, mdata->output_value.step,
            &out_value);

    SOL_INT_CHECK(r, < 0, r);

    mdata->output_value.val = out_value;

    return sol_flow_send_irange_packet(node,
        SOL_FLOW_NODE_TYPE_INT_MAP__OUT__OUT,
        &mdata->output_value);
}
コード例 #4
0
ファイル: int-validator.c プロジェクト: anselmolsm/soletta
int
int_validator_process(
    struct sol_flow_node *node,
    void *data,
    uint16_t port,
    uint16_t conn_id,
    const struct sol_flow_packet *packet)
{
    struct int_validator_data *mdata = data;
    struct sol_irange val;
    int32_t *op;
    bool match;
    int r;

    if (mdata->done) {
        sol_flow_send_error_packet(node, ECANCELED,
            "Input stream already deviated from expected data, ignoring packets.");
        return 0;
    }
    r = sol_flow_packet_get_irange(packet, &val);
    SOL_INT_CHECK(r, < 0, r);
    op = sol_vector_get(&mdata->values, mdata->next_index);
    match = val.val == *op;
    mdata->next_index++;

    if (mdata->next_index == mdata->values.len || !match) {
        sol_flow_send_boolean_packet(node,
            SOL_FLOW_NODE_TYPE_TEST_INT_VALIDATOR__OUT__OUT, match);
        mdata->done = true;
    }
    return 0;
}
コード例 #5
0
ファイル: unix-socket.c プロジェクト: ChunHungLiu/soletta
static int
int_writer_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet)
{
    struct unix_socket_data *mdata = data;
    struct sol_irange val;
    int r;

    r = sol_flow_packet_get_irange(packet, &val);
    SOL_INT_CHECK(r, < 0, r);

    return unix_socket_write(mdata->un_socket, &val, sizeof(val));
}
コード例 #6
0
ファイル: platform.c プロジェクト: ChunHungLiu/soletta
static int
system_clock_process(struct sol_flow_node *node, void *data, uint16_t port,
    uint16_t conn_id, const struct sol_flow_packet *packet)
{
    struct sol_irange irange;
    int r;

    r = sol_flow_packet_get_irange(packet, &irange);
    SOL_INT_CHECK(r, < 0, r);
    r = sol_platform_set_system_clock(irange.val);
    SOL_INT_CHECK(r, < 0, r);
    return 0;
}
コード例 #7
0
static int
logic_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet)
{
    int r;
    struct sol_irange in_value;

    r = sol_flow_packet_get_irange(packet, &in_value);
    SOL_INT_CHECK(r, < 0, r);

    r = sol_flow_send_boolean_packet(node,
        SOL_FLOW_NODE_TYPE_CUSTOM_NODE_TYPES_LOGIC__IN__IN,
        in_value.val % 2 == 0);

    return 0;
}
コード例 #8
0
ファイル: timer.c プロジェクト: Learn-iot/soletta
static int
timer_interval_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet)
{
    struct timer_data *mdata = data;
    struct sol_irange val;
    int r;

    r = sol_flow_packet_get_irange(packet, &val);
    SOL_INT_CHECK(r, < 0, r);

    if (mdata->interval == val.val)
        return 0;

    mdata->interval = val.val;
    return start_timer(mdata);
}
コード例 #9
0
ファイル: ipm.c プロジェクト: Learn-iot/soletta
static int
int_writer_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet)
{
    struct ipm_data *mdata = data;
    struct sol_blob *blob;
    struct sol_irange in_value;
    int r;

    r = sol_flow_packet_get_irange(packet, &in_value);
    SOL_INT_CHECK(r, < 0, r);

    blob = SOL_BLOB_NEW_DUP(in_value);
    SOL_NULL_CHECK(blob, -ENOMEM);

    SEND_BLOB(blob, mdata->id, node);

    return 0;
}
コード例 #10
0
ファイル: int.c プロジェクト: kalyankondapally/soletta
static int
int_filter_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct  sol_flow_packet *packet)
{
    struct sol_irange value;
    int r;
    struct int_filter_data *mdata = data;

    r = sol_flow_packet_get_irange(packet, &value);
    SOL_INT_CHECK(r, < 0, r);

    if (value.val >= mdata->min && value.val <= mdata->max ) {
        if (mdata->range_override) {
            value.min = mdata->min;
            value.max = mdata->max;
            value.step = 1;
        }
        return sol_flow_send_irange_packet(node, SOL_FLOW_NODE_TYPE_INT_FILTER__OUT__OUT, &value);
    }
    return 0;
}
コード例 #11
0
ファイル: int.c プロジェクト: kalyankondapally/soletta
static int
irange_constrain_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet)
{
    struct irange_constrain_data *mdata = data;
    int r;
    struct sol_irange value;

    r = sol_flow_packet_get_irange(packet, &value);
    SOL_INT_CHECK(r, < 0, r);

    if (!mdata->use_input_range) {
        value.min = mdata->val.min;
        value.max = mdata->val.max;
        value.step = mdata->val.step;
    }

    irange_constrain(&value);
    mdata->val = value;

    return sol_flow_send_irange_packet(node,
        SOL_FLOW_NODE_TYPE_INT_CONSTRAIN__OUT__OUT,
        &mdata->val);
}
コード例 #12
0
ファイル: int.c プロジェクト: kalyankondapally/soletta
static int
not_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet)
{
    int r;
    struct sol_irange in_value;
    struct sol_irange out_value = { .min = INT32_MIN, .step = 1, .max = INT32_MAX };

    r = sol_flow_packet_get_irange(packet, &in_value);
    SOL_INT_CHECK(r, < 0, r);

    out_value.val = ~in_value.val;
    return sol_flow_send_irange_packet(node, SOL_FLOW_NODE_TYPE_INT_BITWISE_NOT__OUT__OUT, &out_value);
}


// =============================================================================
// IRANGE COMPARISON
// =============================================================================

struct irange_comparison_data {
    bool (*func) (int32_t var0, int32_t var1);
    int32_t var0;
    int32_t var1;
    uint16_t port;
    bool var0_initialized : 1;
    bool var1_initialized : 1;
};

static bool
irange_val_equal(int32_t var0, int32_t var1)
{
    return var0 == var1;
}

static int
equal_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct irange_comparison_data *mdata = data;

    mdata->port = SOL_FLOW_NODE_TYPE_INT_EQUAL__OUT__OUT;
    mdata->func = irange_val_equal;

    return 0;
}

static bool
irange_val_less(int32_t var0, int32_t var1)
{
    return var0 < var1;
}

static int
less_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct irange_comparison_data *mdata = data;

    mdata->port = SOL_FLOW_NODE_TYPE_INT_LESS__OUT__OUT;
    mdata->func = irange_val_less;

    return 0;
}

static bool
irange_val_less_or_equal(int32_t var0, int32_t var1)
{
    return var0 <= var1;
}

static int
less_or_equal_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct irange_comparison_data *mdata = data;

    mdata->port = SOL_FLOW_NODE_TYPE_INT_LESS_OR_EQUAL__OUT__OUT;
    mdata->func = irange_val_less_or_equal;

    return 0;
}

static bool
irange_val_greater(int32_t var0, int32_t var1)
{
    return var0 > var1;
}

static int
greater_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct irange_comparison_data *mdata = data;

    mdata->port = SOL_FLOW_NODE_TYPE_INT_GREATER__OUT__OUT;
    mdata->func = irange_val_greater;

    return 0;
}

static bool
irange_val_greater_or_equal(int32_t var0, int32_t var1)
{
    return var0 >= var1;
}

static int
greater_or_equal_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct irange_comparison_data *mdata = data;

    mdata->port = SOL_FLOW_NODE_TYPE_INT_EQUAL__OUT__OUT;
    mdata->func = irange_val_greater_or_equal;

    return 0;
}

static bool
irange_val_not_equal(int32_t var0, int32_t var1)
{
    return var0 != var1;
}

static int
not_equal_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct irange_comparison_data *mdata = data;

    mdata->port = SOL_FLOW_NODE_TYPE_INT_NOT_EQUAL__OUT__OUT;
    mdata->func = irange_val_not_equal;

    return 0;
}

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 irange_comparison_data *mdata = data;
    int r;
    struct sol_irange in_value;
    bool output;

    r = sol_flow_packet_get_irange(packet, &in_value);
    SOL_INT_CHECK(r, < 0, r);

    if (port == 0) {
        mdata->var0_initialized = true;
        mdata->var0 = in_value.val;
    } else if (port == 1) {
        mdata->var1_initialized = true;
        mdata->var1 = in_value.val;
    }

    /* only send something after both variables values are received */
    if (!(mdata->var0_initialized && mdata->var1_initialized))
        return 0;

    output = mdata->func(mdata->var0, mdata->var1);

    return sol_flow_send_boolean_packet(node, mdata->port, output);
}

// =============================================================================
// IRANGE MAP
// =============================================================================


struct irange_map_data {
    struct sol_irange input;
    struct sol_irange output;
    struct sol_irange output_value;
    bool use_input_range : 1;
};

static int
irange_map_open(struct sol_flow_node *node, void *data, const struct sol_flow_node_options *options)
{
    struct irange_map_data *mdata = data;
    const struct sol_flow_node_type_int_map_options *opts;

    SOL_FLOW_NODE_OPTIONS_SUB_API_CHECK(options, SOL_FLOW_NODE_TYPE_INT_MAP_OPTIONS_API_VERSION, -EINVAL);

    opts = (const struct sol_flow_node_type_int_map_options *)options;

    mdata->use_input_range = opts->use_input_range;

    mdata->input = opts->input_range;

    if (!mdata->use_input_range && (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;

    /* We allow output.min > output.max to invert range, but
     * when sending the packet, min and max must to be in correct
     * order */
    if (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;
    }

    if (opts->output_range.step < 1) {
        SOL_WRN("Output step need to be > 0");
        return -EDOM;
    }
    mdata->output_value.step = opts->output_range.step;

    return 0;
}

static int
_map(int64_t in_value, int64_t in_min, int64_t in_max, int64_t out_min, int64_t out_max, int64_t out_step, int32_t *out_value)
{
    int64_t result;

    if ((in_max - in_min) == out_min) {
        SOL_WRN("Input max - input min == output min");
        return -EDOM;
    }

    result = (in_value - in_min) * (out_max - out_min) /
             (in_max - in_min) + out_min;
    result -= (result - out_min) % out_step;
    *out_value = result;

    return 0;
}
コード例 #13
0
ファイル: int.c プロジェクト: kalyankondapally/soletta
static int
two_port_process(struct sol_flow_node *node, void *data, uint16_t port_in, uint16_t port_out, const struct sol_flow_packet *packet, int (*func)(int, int))
{
    struct bitwise_data *mdata = data;
    int r;
    struct sol_irange in_value;
    struct sol_irange out_value = { .min = INT32_MIN, .step = 1, .max = INT32_MAX };

    r = sol_flow_packet_get_irange(packet, &in_value);
    SOL_INT_CHECK(r, < 0, r);

    if (port_in) {
        mdata->in1 = in_value.val;
        mdata->in1_init = true;
    } else {
        mdata->in0 = in_value.val;
        mdata->in0_init = true;
    }

    if (!(mdata->in0_init && mdata->in1_init))
        return 0;

    out_value.val = func(mdata->in0, mdata->in1);
    if (out_value.val == mdata->result && mdata->sent_first)
        return 0;

    mdata->result = out_value.val;
    mdata->sent_first = true;

    return sol_flow_send_irange_packet(node, port_out, &out_value);
}

static int
and_func(int in0, int in1)
{
    return in0 & in1;
}

static int
and_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet)
{
    return two_port_process(node, data, port, SOL_FLOW_NODE_TYPE_INT_BITWISE_AND__OUT__OUT, packet, and_func);
}

static int
or_func(int in0, int in1)
{
    return in0 | in1;
}

static int
or_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet)
{
    return two_port_process(node, data, port, SOL_FLOW_NODE_TYPE_INT_BITWISE_OR__OUT__OUT, packet, or_func);
}

static int
xor_func(int in0, int in1)
{
    return in0 ^ in1;
}

static int
xor_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet)
{
    return two_port_process(node, data, port, SOL_FLOW_NODE_TYPE_INT_BITWISE_XOR__OUT__OUT, packet, xor_func);
}

static int
validate_shift(const struct sol_flow_packet *packet)
{
    struct sol_irange in;
    int r;

    r = sol_flow_packet_get_irange(packet, &in);
    SOL_INT_CHECK(r, < 0, r);
    if ((unsigned)in.val > (sizeof(in.val) * CHAR_BIT - 1) || in.val < 0)
        return -EINVAL;
    return 0;
}

static int
shift_left_func(int in0, int in1)
{
    return in0 << in1;
}

static int
shift_left_process(struct sol_flow_node *node, void *data, uint16_t port, uint16_t conn_id, const struct sol_flow_packet *packet)
{
    int r = 0;

    if (port == SOL_FLOW_NODE_TYPE_INT_SHIFT_LEFT__IN__SHIFT)
        r = validate_shift(packet);
    if (r < 0)
        return r;
    return two_port_process(node, data, port, SOL_FLOW_NODE_TYPE_INT_SHIFT_LEFT__OUT__OUT, packet, shift_left_func);
}
コード例 #14
0
ファイル: inspector.c プロジェクト: ronaldotd/soletta
static void
inspector_show_packet_value(const struct sol_flow_packet *packet)
{
    const struct sol_flow_packet_type *type = sol_flow_packet_get_type(packet);

    if (type == SOL_FLOW_PACKET_TYPE_EMPTY) {
        fputs("<empty>", stdout);
        return;
    } else if (type == SOL_FLOW_PACKET_TYPE_ANY) {
        fputs("<any>", stdout);
        return;
    } else if (type == SOL_FLOW_PACKET_TYPE_ERROR) {
        int code;
        const char *msg;
        if (sol_flow_packet_get_error(packet, &code, &msg) == 0) {
            fprintf(stdout, "<error:%d \"%s\">", code, msg ? msg : "");
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_BOOL) {
        bool v;
        if (sol_flow_packet_get_bool(packet, &v) == 0) {
            fprintf(stdout, "<%s>", v ? "true" : "false");
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_BYTE) {
        unsigned char v;
        if (sol_flow_packet_get_byte(packet, &v) == 0) {
            fprintf(stdout, "<%#x>", v);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_IRANGE) {
        struct sol_irange v;
        if (sol_flow_packet_get_irange(packet, &v) == 0) {
            fprintf(stdout, "<val:%d|min:%d|max:%d|step:%d>",
                    v.val, v.min, v.max, v.step);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_DRANGE) {
        struct sol_drange v;
        if (sol_flow_packet_get_drange(packet, &v) == 0) {
            fprintf(stdout, "<val:%g|min:%g|max:%g|step:%g>",
                    v.val, v.min, v.max, v.step);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_STRING) {
        const char *v;
        if (sol_flow_packet_get_string(packet, &v) == 0) {
            fprintf(stdout, "<\"%s\">", v);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_BLOB) {
        struct sol_blob *v;
        if (sol_flow_packet_get_blob(packet, &v) == 0) {
            fprintf(stdout, "<mem=%p|size=%zd|refcnt=%hu|type=%p|parent=%p>",
                    v->mem, v->size, v->refcnt, v->type, v->parent);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_JSON_OBJECT) {
        struct sol_blob *v;
        if (sol_flow_packet_get_json_object(packet, &v) == 0) {
            fprintf(stdout, "<%.*s>",
                    SOL_STR_SLICE_PRINT(sol_str_slice_from_blob(v)));
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_JSON_ARRAY) {
        struct sol_blob *v;
        if (sol_flow_packet_get_json_array(packet, &v) == 0) {
            fprintf(stdout, "<%.*s>",
                    SOL_STR_SLICE_PRINT(sol_str_slice_from_blob(v)));
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_RGB) {
        struct sol_rgb v;
        if (sol_flow_packet_get_rgb(packet, &v) == 0) {
            fprintf(stdout,
                    "<red=%u|green=%u|blue=%u"
                    "|red_max=%u|green_max=%u|blue_max=%u>",
                    v.red, v.green, v.blue,
                    v.red_max, v.green_max, v.blue_max);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_DIRECTION_VECTOR) {
        struct sol_direction_vector v;
        if (sol_flow_packet_get_direction_vector(packet, &v) == 0) {
            fprintf(stdout,
                    "<x=%g|y=%g|z=%g|min=%g|max=%g>",
                    v.x, v.y, v.z, v.min, v.max);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_LOCATION) {
        struct sol_location v;
        if (sol_flow_packet_get_location(packet, &v) == 0) {
            fprintf(stdout, "<lat=%g|lon=%g|alt=%g>", v.lat, v.lon, v.alt);
            return;
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_TIMESTAMP) {
        struct timespec v;
        if (sol_flow_packet_get_timestamp(packet, &v) == 0) {
            struct tm cur_time;
            char buf[32];
            tzset();
            if (gmtime_r(&v.tv_sec, &cur_time)) {
                if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%SZ",
                             &cur_time) > 0) {
                    fprintf(stdout, "<%s>", buf);
                    return;
                }
            }
        }
    } else if (type == SOL_FLOW_PACKET_TYPE_HTTP_RESPONSE) {
        int code;
        const char *url, *content_type;
        const struct sol_blob *content;
        struct sol_vector headers, cookies;
        if (sol_flow_packet_get_http_response(packet, &code, &url,
                                              &content_type, &content, &cookies, &headers) == 0) {
            fprintf(stdout, "<response_code:%d|content type:%s|url:%s|",
                    code, content_type, url);
            fprintf(stdout, "|cookies: {");
            inpector_print_key_value_array(&cookies);
            fprintf(stdout, "}|headers:{");
            inpector_print_key_value_array(&headers);
            fprintf(stdout,
                    "}|content:{mem=%p|size=%zd|refcnt=%hu|type=%p|parent=%p}>",
                    content->mem, content->size, content->refcnt,
                    content->type, content->parent);
        }
        return;
    }

    fputs("<?>", stdout);
}