WebAssembly Micro Runtime first version

This commit is contained in:
Wang Xin
2019-05-07 10:18:18 +08:00
parent 15aa50914b
commit a75a5f0f41
252 changed files with 33487 additions and 0 deletions

View File

@ -0,0 +1,841 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "attr-container.h"
typedef union jvalue {
bool z;
int8_t b;
uint16_t c;
int16_t s;
int32_t i;
int64_t j;
float f;
double d;
} jvalue;
#define bh_memcpy_s(dest, dlen, src, slen) do { \
int _ret = slen == 0 ? 0 : b_memcpy_s (dest, dlen, src, slen); \
(void)_ret; \
} while (0)
static inline int16_t get_int16(const char *buf)
{
int16_t ret;
bh_memcpy_s(&ret, sizeof(int16_t), buf, sizeof(int16_t));
return ret;
}
static inline uint16_t get_uint16(const char *buf)
{
return get_int16(buf);
}
static inline int32_t get_int32(const char *buf)
{
int32_t ret;
bh_memcpy_s(&ret, sizeof(int32_t), buf, sizeof(int32_t));
return ret;
}
static inline uint32_t get_uint32(const char *buf)
{
return get_int32(buf);
}
static inline int64_t get_int64(const char *buf)
{
int64_t ret;
bh_memcpy_s(&ret, sizeof(int64_t), buf, sizeof(int64_t));
return ret;
}
static inline uint64_t get_uint64(const char *buf)
{
return get_int64(buf);
}
static inline void set_int16(char *buf, int16_t v)
{
bh_memcpy_s(buf, sizeof(int16_t), &v, sizeof(int16_t));
}
static inline void set_uint16(char *buf, uint16_t v)
{
bh_memcpy_s(buf, sizeof(uint16_t), &v, sizeof(uint16_t));
}
static inline void set_int32(char *buf, int32_t v)
{
bh_memcpy_s(buf, sizeof(int32_t), &v, sizeof(int32_t));
}
static inline void set_uint32(char *buf, uint32_t v)
{
bh_memcpy_s(buf, sizeof(uint32_t), &v, sizeof(uint32_t));
}
static inline void set_int64(char *buf, int64_t v)
{
bh_memcpy_s(buf, sizeof(int64_t), &v, sizeof(int64_t));
}
static inline void set_uint64(char *buf, uint64_t v)
{
bh_memcpy_s(buf, sizeof(uint64_t), &v, sizeof(uint64_t));
}
char*
attr_container_get_attr_begin(const attr_container_t *attr_cont,
uint32_t *p_total_length, uint16_t *p_attr_num)
{
char *p = (char*) attr_cont->buf;
uint16_t str_len, attr_num;
uint32_t total_length;
/* skip total length */
total_length = get_uint32(p);
p += sizeof(uint32_t);
if (!total_length)
return NULL;
/* tag length */
str_len = get_uint16(p);
p += sizeof(uint16_t);
if (!str_len)
return NULL;
/* tag content */
p += str_len;
if (p - attr_cont->buf >= total_length)
return NULL;
/* attribute num */
attr_num = get_uint16(p);
p += sizeof(uint16_t);
if (p - attr_cont->buf >= total_length)
return NULL;
if (p_total_length)
*p_total_length = total_length;
if (p_attr_num)
*p_attr_num = attr_num;
/* first attribute */
return p;
}
static char*
attr_container_get_attr_next(const char *curr_attr)
{
char *p = (char*) curr_attr;
uint8_t type;
/* key length and key */
p += sizeof(uint16_t) + get_uint16(p);
type = *p++;
/* Short type to Boolean type */
if (type >= ATTR_TYPE_SHORT && type <= ATTR_TYPE_BOOLEAN) {
p += 1 << (type & 3);
return p;
}
/* String type */
else if (type == ATTR_TYPE_STRING) {
p += sizeof(uint16_t) + get_uint16(p);
return p;
}
/* ByteArray type */
else if (type == ATTR_TYPE_BYTEARRAY) {
p += sizeof(uint32_t) + get_uint32(p);
return p;
}
return NULL;
}
static const char*
attr_container_find_attr(const attr_container_t *attr_cont, const char *key)
{
uint32_t total_length;
uint16_t str_len, attr_num, i;
const char *p = attr_cont->buf;
if (!key)
return NULL;
if (!(p = attr_container_get_attr_begin(attr_cont, &total_length, &attr_num)))
return NULL;
for (i = 0; i < attr_num; i++) {
/* key length */
if (!(str_len = get_uint16(p)))
return NULL;
if (str_len == strlen(key) + 1
&& memcmp(p + sizeof(uint16_t), key, str_len) == 0) {
if (p + sizeof(uint16_t) + str_len - attr_cont->buf >= total_length)
return NULL;
return p;
}
if (!(p = attr_container_get_attr_next(p)))
return NULL;
}
return NULL;
}
char*
attr_container_get_attr_end(const attr_container_t *attr_cont)
{
uint32_t total_length;
uint16_t attr_num, i;
char *p;
if (!(p = attr_container_get_attr_begin(attr_cont, &total_length, &attr_num)))
return NULL;
for (i = 0; i < attr_num; i++)
if (!(p = attr_container_get_attr_next(p)))
return NULL;
return p;
}
static char*
attr_container_get_msg_end(attr_container_t *attr_cont)
{
char *p = attr_cont->buf;
return p + get_uint32(p);
}
uint16_t attr_container_get_attr_num(const attr_container_t *attr_cont)
{
uint16_t str_len;
/* skip total length */
const char *p = attr_cont->buf + sizeof(uint32_t);
str_len = get_uint16(p);
/* skip tag length and tag */
p += sizeof(uint16_t) + str_len;
/* attribute num */
return get_uint16(p);
}
static void attr_container_inc_attr_num(attr_container_t *attr_cont)
{
uint16_t str_len, attr_num;
/* skip total length */
char *p = attr_cont->buf + sizeof(uint32_t);
str_len = get_uint16(p);
/* skip tag length and tag */
p += sizeof(uint16_t) + str_len;
/* attribute num */
attr_num = get_uint16(p) + 1;
set_uint16(p, attr_num);
}
attr_container_t *
attr_container_create(const char *tag)
{
attr_container_t *attr_cont;
int length, tag_length;
char *p;
tag_length = tag ? strlen(tag) + 1 : 1;
length = offsetof(attr_container_t, buf) +
/* total length + tag length + tag + reserved 100 bytes */
sizeof(uint32_t) + sizeof(uint16_t) + tag_length + 100;
if (!(attr_cont = attr_container_malloc(length))) {
attr_container_printf(
"Create attr_container failed: allocate memory failed.\r\n");
return NULL;
}
memset(attr_cont, 0, length);
p = attr_cont->buf;
/* total length */
set_uint32(p, length - offsetof(attr_container_t, buf));
p += 4;
/* tag length, tag */
set_uint16(p, tag_length);
p += 2;
if (tag)
bh_memcpy_s(p, tag_length, tag, tag_length);
return attr_cont;
}
void attr_container_destroy(const attr_container_t *attr_cont)
{
if (attr_cont)
attr_container_free((char*) attr_cont);
}
static bool check_set_attr(attr_container_t **p_attr_cont, const char *key)
{
uint32_t flags;
if (!p_attr_cont || !*p_attr_cont || !key || strlen(key) == 0) {
attr_container_printf(
"Set attribute failed: invalid input arguments.\r\n");
return false;
}
flags = get_uint32((char*) *p_attr_cont);
if (flags & ATTR_CONT_READONLY_SHIFT) {
attr_container_printf(
"Set attribute failed: attribute container is readonly.\r\n");
return false;
}
return true;
}
bool attr_container_set_attr(attr_container_t **p_attr_cont, const char *key,
int type, const void *value, int value_length)
{
attr_container_t *attr_cont, *attr_cont1;
uint16_t str_len;
uint32_t total_length, attr_len;
char *p, *p1, *attr_end, *msg_end, *attr_buf;
if (!check_set_attr(p_attr_cont, key)) {
return false;
}
attr_cont = *p_attr_cont;
p = attr_cont->buf;
total_length = get_uint32(p);
if (!(attr_end = attr_container_get_attr_end(attr_cont))) {
attr_container_printf("Set attr failed: get attr end failed.\r\n");
return false;
}
msg_end = attr_container_get_msg_end(attr_cont);
/* key len + key + '\0' + type */
attr_len = sizeof(uint16_t) + strlen(key) + 1 + 1;
if (type >= ATTR_TYPE_SHORT && type <= ATTR_TYPE_BOOLEAN)
attr_len += 1 << (type & 3);
else if (type == ATTR_TYPE_STRING)
attr_len += sizeof(uint16_t) + value_length;
else if (type == ATTR_TYPE_BYTEARRAY)
attr_len += sizeof(uint32_t) + value_length;
if (!(p = attr_buf = attr_container_malloc(attr_len))) {
attr_container_printf("Set attr failed: allocate memory failed.\r\n");
return false;
}
/* Set the attr buf */
str_len = strlen(key) + 1;
set_uint16(p, str_len);
p += sizeof(uint16_t);
bh_memcpy_s(p, str_len, key, str_len);
p += str_len;
*p++ = type;
if (type >= ATTR_TYPE_SHORT && type <= ATTR_TYPE_BOOLEAN)
bh_memcpy_s(p, 1 << (type & 3), value, 1 << (type & 3));
else if (type == ATTR_TYPE_STRING) {
set_uint16(p, value_length);
p += sizeof(uint16_t);
bh_memcpy_s(p, value_length, value, value_length);
} else if (type == ATTR_TYPE_BYTEARRAY) {
set_uint32(p, value_length);
p += sizeof(uint32_t);
bh_memcpy_s(p, value_length, value, value_length);
}
if ((p = (char*) attr_container_find_attr(attr_cont, key))) {
/* key found */
p1 = attr_container_get_attr_next(p);
if (p1 - p == attr_len) {
bh_memcpy_s(p, attr_len, attr_buf, attr_len);
attr_container_free(attr_buf);
return true;
}
if (p1 - p + msg_end - attr_end >= attr_len) {
memmove(p, p1, attr_end - p1);
bh_memcpy_s(p + (attr_end - p1), attr_len, attr_buf, attr_len);
attr_container_free(attr_buf);
return true;
}
total_length += attr_len + 100;
if (!(attr_cont1 = attr_container_malloc(
offsetof(attr_container_t, buf) + total_length))) {
attr_container_printf(
"Set attr failed: allocate memory failed.\r\n");
attr_container_free(attr_buf);
return false;
}
bh_memcpy_s(attr_cont1, p - (char* )attr_cont, attr_cont,
p - (char* )attr_cont);
bh_memcpy_s((char* )attr_cont1 + (unsigned )(p - (char* )attr_cont),
attr_end - p1, p1, attr_end - p1);
bh_memcpy_s(
(char* )attr_cont1 + (unsigned )(p - (char* )attr_cont)
+ (unsigned )(attr_end - p1), attr_len, attr_buf,
attr_len);
p = attr_cont1->buf;
set_uint32(p, total_length);
*p_attr_cont = attr_cont1;
/* Free original buffer */
attr_container_free(attr_cont);
attr_container_free(attr_buf);
return true;
} else {
/* key not found */
if (msg_end - attr_end >= attr_len) {
bh_memcpy_s(attr_end, msg_end - attr_end, attr_buf, attr_len);
attr_container_inc_attr_num(attr_cont);
attr_container_free(attr_buf);
return true;
}
total_length += attr_len + 100;
if (!(attr_cont1 = attr_container_malloc(
offsetof(attr_container_t, buf) + total_length))) {
attr_container_printf(
"Set attr failed: allocate memory failed.\r\n");
attr_container_free(attr_buf);
return false;
}
bh_memcpy_s(attr_cont1, attr_end - (char* )attr_cont, attr_cont,
attr_end - (char* )attr_cont);
bh_memcpy_s(
(char* )attr_cont1 + (unsigned )(attr_end - (char* )attr_cont),
attr_len, attr_buf, attr_len);
attr_container_inc_attr_num(attr_cont1);
p = attr_cont1->buf;
set_uint32(p, total_length);
*p_attr_cont = attr_cont1;
/* Free original buffer */
attr_container_free(attr_cont);
attr_container_free(attr_buf);
return true;
}
return false;
}
bool attr_container_set_short(attr_container_t **p_attr_cont, const char *key,
short value)
{
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_SHORT, &value, 2);
}
bool attr_container_set_int(attr_container_t **p_attr_cont, const char *key,
int value)
{
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_INT, &value, 4);
}
bool attr_container_set_int64(attr_container_t **p_attr_cont, const char *key,
int64_t value)
{
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_INT64, &value, 8);
}
bool attr_container_set_byte(attr_container_t **p_attr_cont, const char *key,
int8_t value)
{
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_BYTE, &value, 1);
}
bool attr_container_set_uint16(attr_container_t **p_attr_cont, const char *key,
uint16_t value)
{
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_UINT16, &value,
2);
}
bool attr_container_set_float(attr_container_t **p_attr_cont, const char *key,
float value)
{
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_FLOAT, &value, 4);
}
bool attr_container_set_double(attr_container_t **p_attr_cont, const char *key,
double value)
{
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_DOUBLE, &value,
8);
}
bool attr_container_set_bool(attr_container_t **p_attr_cont, const char *key,
bool value)
{
int8_t value1 = value ? 1 : 0;
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_BOOLEAN, &value1,
1);
}
bool attr_container_set_string(attr_container_t **p_attr_cont, const char *key,
const char *value)
{
if (!value) {
attr_container_printf("Set attr failed: invald input arguments.\r\n");
return false;
}
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_STRING, value,
strlen(value) + 1);;
}
bool attr_container_set_bytearray(attr_container_t **p_attr_cont,
const char *key, const int8_t *value, unsigned length)
{
if (!value) {
attr_container_printf("Set attr failed: invald input arguments.\r\n");
return false;
}
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_BYTEARRAY, value,
length);;
}
static const char*
attr_container_get_attr(const attr_container_t *attr_cont, const char *key)
{
const char *attr_addr;
if (!attr_cont || !key) {
attr_container_printf(
"Get attribute failed: invalid input arguments.\r\n");
return NULL;
}
if (!(attr_addr = attr_container_find_attr(attr_cont, key))) {
attr_container_printf("Get attribute failed: lookup key failed.\r\n");
return false;
}
/* key len + key + '\0' */
return attr_addr + 2 + strlen(key) + 1;
}
#define TEMPLATE_ATTR_BUF_TO_VALUE(attr, key, var_name) do {\
jvalue val; \
const char *addr = attr_container_get_attr(attr, key); \
uint8_t type; \
if (!addr) \
return 0; \
val.j = 0; \
type = *(uint8_t*)addr++; \
switch (type) { \
case ATTR_TYPE_SHORT: \
case ATTR_TYPE_INT: \
case ATTR_TYPE_INT64: \
case ATTR_TYPE_BYTE: \
case ATTR_TYPE_UINT16: \
case ATTR_TYPE_FLOAT: \
case ATTR_TYPE_DOUBLE: \
case ATTR_TYPE_BOOLEAN: \
bh_memcpy_s(&val, sizeof(val.var_name), addr, 1 << (type & 3)); \
break; \
case ATTR_TYPE_STRING: \
{ \
unsigned len= get_uint16(addr); \
addr += 2; \
if (len > sizeof(val.var_name)) \
len = sizeof(val.var_name); \
bh_memcpy_s(&val.var_name, sizeof(val.var_name), addr, len); \
break; \
} \
case ATTR_TYPE_BYTEARRAY: \
{ \
unsigned len= get_uint32(addr); \
addr += 4; \
if (len > sizeof(val.var_name)) \
len = sizeof(val.var_name); \
bh_memcpy_s(&val.var_name, sizeof(val.var_name), addr, len); \
break; \
} \
} \
return val.var_name; \
} while (0)
short attr_container_get_as_short(const attr_container_t *attr_cont,
const char *key)
{
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, s);
}
int attr_container_get_as_int(const attr_container_t *attr_cont,
const char *key)
{
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, i);
}
int64_t attr_container_get_as_int64(const attr_container_t *attr_cont,
const char *key)
{
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, j);
}
int8_t attr_container_get_as_byte(const attr_container_t *attr_cont,
const char *key)
{
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, b);
}
uint16_t attr_container_get_as_uint16(const attr_container_t *attr_cont,
const char *key)
{
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, s);
}
float attr_container_get_as_float(const attr_container_t *attr_cont,
const char *key)
{
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, f);
}
double attr_container_get_as_double(const attr_container_t *attr_cont,
const char *key)
{
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, d);
}
bool attr_container_get_as_bool(const attr_container_t *attr_cont,
const char *key)
{
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, z);
}
const int8_t*
attr_container_get_as_bytearray(const attr_container_t *attr_cont,
const char *key, unsigned *array_length)
{
const char *addr = attr_container_get_attr(attr_cont, key);
uint8_t type;
uint32_t length;
if (!addr)
return NULL;
if (!array_length) {
attr_container_printf("Get attribute failed: invalid input arguments.");
return NULL;
}
type = *(uint8_t*) addr++;
switch (type) {
case ATTR_TYPE_SHORT:
case ATTR_TYPE_INT:
case ATTR_TYPE_INT64:
case ATTR_TYPE_BYTE:
case ATTR_TYPE_UINT16:
case ATTR_TYPE_FLOAT:
case ATTR_TYPE_DOUBLE:
case ATTR_TYPE_BOOLEAN:
length = 1 << (type & 3);
break;
case ATTR_TYPE_STRING:
length = get_uint16(addr);
addr += 2;
break;
case ATTR_TYPE_BYTEARRAY:
length = get_uint32(addr);
addr += 4;
break;
default:
return NULL;
}
*array_length = length;
return (const int8_t*) addr;
}
char*
attr_container_get_as_string(const attr_container_t *attr_cont, const char *key)
{
unsigned array_length;
return (char*) attr_container_get_as_bytearray(attr_cont, key,
&array_length);
}
const char*
attr_container_get_tag(const attr_container_t *attr_cont)
{
return attr_cont ?
attr_cont->buf + sizeof(uint32_t) + sizeof(uint16_t) : NULL;
}
bool attr_container_contain_key(const attr_container_t *attr_cont,
const char *key)
{
if (!attr_cont || !key || !strlen(key)) {
attr_container_printf(
"Check contain key failed: invalid input arguments.\r\n");
return false;
}
return attr_container_find_attr(attr_cont, key) ? true : false;
}
unsigned int attr_container_get_serialize_length(
const attr_container_t *attr_cont)
{
const char *p;
if (!attr_cont) {
attr_container_printf(
"Get container serialize length failed: invalid input arguments.\r\n");
return 0;
}
p = attr_cont->buf;
return sizeof(uint16_t) + get_uint32(p);
}
bool attr_container_serialize(char *buf, const attr_container_t *attr_cont)
{
const char *p;
uint16_t flags;
uint32_t length;
if (!buf || !attr_cont) {
attr_container_printf(
"Container serialize failed: invalid input arguments.\r\n");
return false;
}
p = attr_cont->buf;
length = sizeof(uint16_t) + get_uint32(p);
bh_memcpy_s(buf, length, attr_cont, length);
/* Set readonly */
flags = get_uint16((const char*) attr_cont);
set_uint16(buf, flags | (1 << ATTR_CONT_READONLY_SHIFT));
return true;
}
bool attr_container_is_constant(const attr_container_t* attr_cont)
{
uint16_t flags;
if (!attr_cont) {
attr_container_printf(
"Container check const: invalid input arguments.\r\n");
return false;
}
flags = get_uint16((const char*) attr_cont);
return (flags & (1 << ATTR_CONT_READONLY_SHIFT)) ? true : false;
}
void attr_container_dump(const attr_container_t *attr_cont)
{
uint32_t total_length;
uint16_t attr_num, i, type;
const char *p, *tag, *key;
jvalue value;
if (!attr_cont)
return;
tag = attr_container_get_tag(attr_cont);
if (!tag)
return;
attr_container_printf("Attribute container dump:\n");
attr_container_printf("Tag: %s\n", tag);
p = attr_container_get_attr_begin(attr_cont, &total_length, &attr_num);
if (!p)
return;
attr_container_printf("Attribute list:\n");
for (i = 0; i < attr_num; i++) {
key = p + 2;
/* Skip key len and key */
p += 2 + get_uint16(p);
type = *p++;
attr_container_printf(" key: %s", key);
switch (type) {
case ATTR_TYPE_SHORT:
bh_memcpy_s(&value.s, sizeof(int16_t), p, sizeof(int16_t));
attr_container_printf(", type: short, value: 0x%x\n",
value.s & 0xFFFF);
p += 2;
break;
case ATTR_TYPE_INT:
bh_memcpy_s(&value.i, sizeof(int32_t), p, sizeof(int32_t));
attr_container_printf(", type: int, value: 0x%x\n", value.i);
p += 4;
break;
case ATTR_TYPE_INT64:
bh_memcpy_s(&value.j, sizeof(uint64_t), p, sizeof(uint64_t));
attr_container_printf(", type: int64, value: 0x%llx\n", value.j);
p += 8;
break;
case ATTR_TYPE_BYTE:
bh_memcpy_s(&value.b, 1, p, 1);
attr_container_printf(", type: byte, value: 0x%x\n",
value.b & 0xFF);
p++;
break;
case ATTR_TYPE_UINT16:
bh_memcpy_s(&value.c, sizeof(uint16_t), p, sizeof(uint16_t));
attr_container_printf(", type: uint16, value: 0x%x\n", value.c);
p += 2;
break;
case ATTR_TYPE_FLOAT:
bh_memcpy_s(&value.f, sizeof(float), p, sizeof(float));
attr_container_printf(", type: float, value: %f\n", value.f);
p += 4;
break;
case ATTR_TYPE_DOUBLE:
bh_memcpy_s(&value.d, sizeof(double), p, sizeof(double));
attr_container_printf(", type: double, value: %f\n", value.d);
p += 8;
break;
case ATTR_TYPE_BOOLEAN:
bh_memcpy_s(&value.z, 1, p, 1);
attr_container_printf(", type: bool, value: 0x%x\n", value.z);
p++;
break;
case ATTR_TYPE_STRING:
attr_container_printf(", type: string, value: %s\n",
p + sizeof(uint16_t));
p += sizeof(uint16_t) + get_uint16(p);
break;
case ATTR_TYPE_BYTEARRAY:
attr_container_printf(", type: byte array, length: %d\n",
get_uint32(p));
p += sizeof(uint32_t) + get_uint32(p);
break;
}
}
attr_container_printf("\n");
}

View File

@ -0,0 +1,436 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _ATTR_CONTAINER_H_
#define _ATTR_CONTAINER_H_
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <stdbool.h>
#include "bh_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Attribute type */
enum {
ATTR_TYPE_BEGIN = 1,
ATTR_TYPE_SHORT = ATTR_TYPE_BEGIN,
ATTR_TYPE_INT,
ATTR_TYPE_INT64,
ATTR_TYPE_BYTE,
ATTR_TYPE_UINT16,
ATTR_TYPE_FLOAT,
ATTR_TYPE_DOUBLE,
ATTR_TYPE_BOOLEAN,
ATTR_TYPE_STRING,
ATTR_TYPE_BYTEARRAY,
ATTR_TYPE_END = ATTR_TYPE_BYTEARRAY
};
#define ATTR_CONT_READONLY_SHIFT 2
typedef struct attr_container {
/* container flag:
* bit0, bit1 denote the implemenation algorithm, 00: buffer, 01: link list
* bit2 denotes the readonly flag: 1 is readonly and attr cannot be set
*/
char flags[2];
/**
* Buffer format
* for buffer implementation:
* buf length (4 bytes)
* tag length (2 bytes)
* tag
* attr num (2bytes)
* attr[0..n-1]:
* attr key length (2 bytes)
* attr type (1byte)
* attr value (length depends on attr type)
*/
char buf[1];
} attr_container_t;
/**
* Create attribute container
*
* @param tag tag of current attribute container
*
* @return the created attribute container, NULL if failed
*/
attr_container_t *
attr_container_create(const char *tag);
/**
* Destroy attribute container
*
* @param attr_cont the attribute container to destroy
*/
void
attr_container_destroy(const attr_container_t *attr_cont);
/**
* Set short attribute in attribute container
*
* @param p_attr_cont pointer to attribute container to set attribute, and
* return the new attribute container if it is re-created
* @param key the attribute key
* @param value the attribute value
*
* @return true if success, false otherwise
*/
bool
attr_container_set_short(attr_container_t **p_attr_cont, const char *key,
short value);
/**
* Set int attribute in attribute container
*
* @param p_attr_cont pointer to attribute container to set attribute, and
* return the new attribute container if it is re-created
* @param key the attribute key
* @param value the attribute value
*
* @return true if success, false otherwise
*/
bool
attr_container_set_int(attr_container_t **p_attr_cont, const char *key,
int value);
/**
* Set int64 attribute in attribute container
*
* @param p_attr_cont pointer to attribute container to set attribute, and
* return the new attribute container if it is re-created
* @param key the attribute key
* @param value the attribute value
*
* @return true if success, false otherwise
*/
bool
attr_container_set_int64(attr_container_t **p_attr_cont, const char *key,
int64_t value);
/**
* Set byte attribute in attribute container
*
* @param p_attr_cont pointer to attribute container to set attribute, and
* return the new attribute container if it is re-created
* @param key the attribute key
* @param value the attribute value
*
* @return true if success, false otherwise
*/
bool
attr_container_set_byte(attr_container_t **p_attr_cont, const char *key,
int8_t value);
/**
* Set uint16 attribute in attribute container
*
* @param p_attr_cont pointer to attribute container to set attribute, and
* return the new attribute container if it is re-created
* @param key the attribute key
* @param value the attribute value
*
* @return true if success, false otherwise
*/
bool
attr_container_set_uint16(attr_container_t **p_attr_cont, const char *key,
uint16_t value);
/**
* Set float attribute in attribute container
*
* @param p_attr_cont pointer to attribute container to set attribute, and
* return the new attribute container if it is re-created
* @param key the attribute key
* @param value the attribute value
*
* @return true if success, false otherwise
*/
bool
attr_container_set_float(attr_container_t **p_attr_cont, const char *key,
float value);
/**
* Set double attribute in attribute container
*
* @param p_attr_cont pointer to attribute container to set attribute, and
* return the new attribute container if it is re-created
* @param key the attribute key
* @param value the attribute value
*
* @return true if success, false otherwise
*/
bool
attr_container_set_double(attr_container_t **p_attr_cont, const char *key,
double value);
/**
* Set bool attribute in attribute container
*
* @param p_attr_cont pointer to attribute container to set attribute, and
* return the new attribute container if it is re-created
* @param key the attribute key
* @param value the attribute value
*
* @return true if success, false otherwise
*/
bool
attr_container_set_bool(attr_container_t **p_attr_cont, const char *key,
bool value);
/**
* Set string attribute in attribute container
*
* @param p_attr_cont pointer to attribute container to set attribute, and
* return the new attribute container if it is re-created
* @param key the attribute key
* @param value the attribute value
*
* @return true if success, false otherwise
*/
bool
attr_container_set_string(attr_container_t **p_attr_cont, const char *key,
const char *value);
/**
* Set bytearray attribute in attribute container
*
* @param p_attr_cont pointer to attribute container to set attribute, and
* return the new attribute container if it is re-created
* @param key the attribute key
* @param value the bytearray buffer
* @param length the bytearray length
*
* @return true if success, false otherwise
*/
bool
attr_container_set_bytearray(attr_container_t **p_attr_cont, const char *key,
const int8_t *value, unsigned length);
/**
* Get tag of current attribute container
*
* @param attr_cont the attribute container
*
* @return tag of current attribute container
*/
const char*
attr_container_get_tag(const attr_container_t *attr_cont);
/**
* Get attribute number of current attribute container
*
* @param attr_cont the attribute container
*
* @return attribute number of current attribute container
*/
uint16_t
attr_container_get_attr_num(const attr_container_t *attr_cont);
/**
* Whether the attribute container contains an attribute key.
*
* @param attr_cont the attribute container
* @param key the attribute key
*
* @return true if key is contained in message, false otherwise
*/
bool
attr_container_contain_key(const attr_container_t *attr_cont, const char *key);
/**
* Get attribute from attribute container and return it as short value,
* return 0 if attribute isn't found in message.
*
* @param attr_cont the attribute container
* @param key the attribute key
*
* @return the short value of the attribute, 0 if key isn't found
*/
short
attr_container_get_as_short(const attr_container_t *attr_cont, const char *key);
/**
* Get attribute from attribute container and return it as int value,
* return 0 if attribute isn't found in message.
*
* @param attr_cont the attribute container
* @param key the attribute key
*
* @return the int value of the attribute, 0 if key isn't found
*/
int
attr_container_get_as_int(const attr_container_t *attr_cont, const char *key);
/**
* Get attribute from attribute container and return it as int64 value,
* return 0 if attribute isn't found in attribute container.
*
* @param attr_cont the attribute container
* @param key the attribute key
*
* @return the long value of the attribute, 0 if key isn't found
*/
int64_t
attr_container_get_as_int64(const attr_container_t *attr_cont, const char *key);
/**
* Get attribute from attribute container and return it as byte value,
* return 0 if attribute isn't found in attribute container.
*
* @param attr_cont the attribute container
* @param key the attribute key
*
* @return the byte value of the attribute, 0 if key isn't found
*/
int8_t
attr_container_get_as_byte(const attr_container_t *attr_cont, const char *key);
/**
* Get attribute from attribute container and return it as uint16 value,
* return 0 if attribute isn't found in attribute container.
*
* @param attr_cont the attribute container
* @param key the attribute key
*
* @return the char value of the attribute, 0 if key isn't found
*/
uint16_t
attr_container_get_as_uint16(const attr_container_t *attr_cont,
const char *key);
/**
* Get attribute from attribute container and return it as float value,
* return 0 if attribute isn't found in attribute container.
*
* @param attr_cont the attribute container
* @param key the attribute key
*
* @return the float value of the attribute, 0 if key isn't found
*/
float
attr_container_get_as_float(const attr_container_t *attr_cont, const char *key);
/**
* Get attribute from attribute container and return it as double value,
* return 0 if attribute isn't found in attribute container.
*
* @param attr_cont the attribute container
* @param key the attribute key
*
* @return the double value of the attribute, 0 if key isn't found
*/
double
attr_container_get_as_double(const attr_container_t *attr_cont,
const char *key);
/**
* Get attribute from attribute container and return it as bool value,
* return false if attribute isn't found in attribute container.
*
* @param attr_cont the attribute container
* @param key the attribute key
*
* @return the bool value of the attribute, 0 if key isn't found
*/
bool
attr_container_get_as_bool(const attr_container_t *attr_cont, const char *key);
/**
* Get attribute from attribute container and return it as string value,
* return NULL if attribute isn't found in attribute container.
*
* @param attr_cont the attribute container
* @param key the attribute key
*
* @return the string value of the attribute, NULL if key isn't found
*/
char*
attr_container_get_as_string(const attr_container_t *attr_cont,
const char *key);
/**
* Get attribute from attribute container and return it as bytearray value,
* return 0 if attribute isn't found in attribute container.
*
* @param attr_cont the attribute container
* @param key the attribute key
*
* @return the bytearray value of the attribute, NULL if key isn't found
*/
const int8_t*
attr_container_get_as_bytearray(const attr_container_t *attr_cont,
const char *key, unsigned *array_length);
/**
* Get the buffer size of attribute container
*
* @param attr_cont the attribute container
*
* @return the buffer size of attribute container
*/
unsigned
attr_container_get_serialize_length(const attr_container_t *attr_cont);
/**
* Serialize attribute container to a buffer
*
* @param buf the buffer to receive the serialized data
* @param attr_cont the attribute container to be serialized
*
* @return true if success, false otherwise
*/
bool
attr_container_serialize(char *buf, const attr_container_t *attr_cont);
/**
* Whether the attribute container is const, or set attribute isn't supported
*
* @param attr_cont the attribute container
*
* @return true if const, false otherwise
*/
bool
attr_container_is_constant(const attr_container_t* attr_cont);
void
attr_container_dump(const attr_container_t *attr_cont);
#ifndef attr_container_malloc
#define attr_container_malloc wa_malloc
#endif
#ifndef attr_container_free
#define attr_container_free wa_free
#endif
#ifndef attr_container_printf
#define attr_container_printf printf
#endif
#ifdef __cplusplus
} /* end of extern "C" */
#endif
#endif /* end of _ATTR_CONTAINER_H_ */

View File

@ -0,0 +1,23 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set (NATIVE_INTERFACE_DIR ${CMAKE_CURRENT_LIST_DIR})
include_directories(${NATIVE_INTERFACE_DIR})
file (GLOB_RECURSE source_all ${NATIVE_INTERFACE_DIR}/*.c)
set (NATIVE_INTERFACE_SOURCE ${source_all})

View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DEPS_SSG_MICRO_RUNTIME_WASM_POC_APP_LIBS_NATIVE_INTERFACE_NATIVE_INTERFACE_H_
#define DEPS_SSG_MICRO_RUNTIME_WASM_POC_APP_LIBS_NATIVE_INTERFACE_NATIVE_INTERFACE_H_
// note: the bh_plaform.h is the only head file separately
// implemented by both [app] and [native] worlds
#include "bh_platform.h"
#define get_module_inst() \
wasm_runtime_get_current_module_inst()
#define validate_app_addr(offset, size) \
wasm_runtime_validate_app_addr(module_inst, offset, size)
#define addr_app_to_native(offset) \
wasm_runtime_addr_app_to_native(module_inst, offset)
#define addr_native_to_app(ptr) \
wasm_runtime_addr_native_to_app(module_inst, ptr)
#define module_malloc(size) \
wasm_runtime_module_malloc(module_inst, size)
#define module_free(offset) \
wasm_runtime_module_free(module_inst, offset)
char *wa_strdup(const char *);
bool
wasm_response_send(int32 buffer_offset, int size);
void wasm_register_resource(int32 url_offset);
void wasm_post_request(int32 buffer_offset, int size);
void wasm_sub_event(int32 url_offset);
/*
* ************* sensor interfaces *************
*/
bool
wasm_sensor_config(uint32 sensor, int interval, int bit_cfg, int delay);
uint32
wasm_sensor_open(int32 name_offset, int instance);
bool
wasm_sensor_config_with_attr_container(uint32 sensor, int32 buffer_offset,
int len);
bool
wasm_sensor_close(uint32 sensor);
/*
* *** timer interface ***
*/
typedef unsigned int timer_id_t;
timer_id_t wasm_create_timer(int interval, bool is_period, bool auto_start);
void wasm_timer_destory(timer_id_t timer_id);
void wasm_timer_cancel(timer_id_t timer_id);
void wasm_timer_restart(timer_id_t timer_id, int interval);
uint32 wasm_get_sys_tick_ms(void);
#endif /* DEPS_SSG_MICRO_RUNTIME_WASM_POC_APP_LIBS_NATIVE_INTERFACE_NATIVE_INTERFACE_H_ */

View File

@ -0,0 +1,12 @@
Attention:
=======
Only add files are shared by both wasm application and native runtime into this directory!
The c files are both compiled into the the WASM APP and native runtime.
native_interface.h
=============
The interface declaration for the native API which are exposed to the WASM app
Any API in this file should be incuded with EXPORT_WASM_API() somewhere.

View File

@ -0,0 +1,424 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include "native_interface.h"
#include "shared_utils.h"
/* Serialization of request and response message
*
* Choices:
* We considered a few options:
* 1. coap
* 2. flatbuffer
* 3. cbor
* 4. attr-containers of our own
* 5. customized serialization for request/response
*
* Now we choose the #5 mainly because we need to quickly get the URL for dispatching
* and sometimes we want to change the URL in the original packet. the request format:
* fixed part: version: (1 byte), code (1 byte), fmt(2 byte), mid (4 bytes), sender_id(4 bytes), url_len(2 bytes), payload_len(4bytes)
* dynamic part: url (bytes in url_len), payload
*
* response format:
* fixed part: (1 byte), code (1 byte), fmt(2 byte), mid (4 bytes), sender_id(4 bytes), payload_len(4bytes)
* dynamic part: payload
*/
#define REQUES_PACKET_VER 1
#define REQUEST_PACKET_FIX_PART_LEN 18
#define REQUEST_PACKET_URL_OFFSET REQUEST_PACKET_FIX_PART_LEN
#define REQUEST_PACKET_URL_LEN *((uint16*)( (char*) buffer + 12))) //!!! to ensure little endian
#define REQUEST_PACKET_PAYLOAD_LEN *((uint32*)( (char*) buffer + 14))) //!!! to ensure little endian
#define REQUEST_PACKET_URL(buffer) ((char*) buffer + REQUEST_PACKET_URL_OFFSET)
#define REQUEST_PACKET_PAYLOAD(buffer) ((char*) buffer + REQUEST_PACKET_URL_OFFSET + REQUEST_PACKET_URL_LEN(buffer))
#define RESPONSE_PACKET_FIX_PART_LEN 16
char * pack_request(request_t *request, int * size)
{
int url_len = strlen(request->url) + 1;
int len = REQUEST_PACKET_FIX_PART_LEN + url_len + request->payload_len;
char * packet = (char*) wa_malloc(len);
if (packet == NULL)
return NULL;
// TODO: ensure little endian for words and dwords
*packet = REQUES_PACKET_VER;
*((uint8*) (packet + 1)) = request->action;
*((uint16*) (packet + 2)) = htons(request->fmt);
*((uint32*) (packet + 4)) = htonl(request->mid);
*((uint32*) (packet + 8)) = htonl(request->sender);
*((uint16*) (packet + 12)) = htons(url_len);
*((uint32*) (packet + 14)) = htonl(request->payload_len);
strcpy(packet + REQUEST_PACKET_URL_OFFSET, request->url);
memcpy(packet + REQUEST_PACKET_URL_OFFSET + url_len, request->payload,
request->payload_len);
*size = len;
return packet;
}
void free_req_resp_packet(char * packet)
{
wa_free(packet);
}
request_t * unpack_request(char * packet, int size, request_t * request)
{
if (*packet != REQUES_PACKET_VER) {
printf("version fail\n");
return NULL;
}
if (size < REQUEST_PACKET_FIX_PART_LEN) {
printf("size error: %d\n", size);
return NULL;
}
uint16 url_len = ntohs(*((uint16*) (packet + 12)));
uint32 payload_len = ntohl(*((uint32*) (packet + 14)));
if (size != ( REQUEST_PACKET_FIX_PART_LEN + url_len + payload_len)) {
printf("size error: %d, expect: %d\n", size,
REQUEST_PACKET_FIX_PART_LEN + url_len + payload_len);
return NULL;
}
if (*(packet + REQUEST_PACKET_FIX_PART_LEN + url_len - 1) != 0) {
printf("url not end with 0\n");
return NULL;
}
request->action = *((uint8*) (packet + 1));
request->fmt = ntohs(*((uint16*) (packet + 2)));
request->mid = ntohl(*((uint32*) (packet + 4)));
request->sender = ntohl(*((uint32*) (packet + 8)));
request->payload_len = payload_len;
request->url = REQUEST_PACKET_URL(packet);
request->payload = packet + REQUEST_PACKET_URL_OFFSET + url_len;
return request;
}
char * pack_response(response_t *response, int * size)
{
int len = RESPONSE_PACKET_FIX_PART_LEN + response->payload_len;
char * packet = (char*) wa_malloc(len);
if (packet == NULL)
return NULL;
// TODO: ensure little endian for words and dwords
*packet = REQUES_PACKET_VER;
*((uint8*) (packet + 1)) = response->status;
*((uint16*) (packet + 2)) = htons(response->fmt);
*((uint32*) (packet + 4)) = htonl(response->mid);
*((uint32*) (packet + 8)) = htonl(response->reciever);
*((uint32*) (packet + 12)) = htonl(response->payload_len);
memcpy(packet + RESPONSE_PACKET_FIX_PART_LEN, response->payload,
response->payload_len);
*size = len;
return packet;
}
response_t * unpack_response(char * packet, int size, response_t * response)
{
if (*packet != REQUES_PACKET_VER)
return NULL;
if (size < RESPONSE_PACKET_FIX_PART_LEN)
return NULL;
uint32 payload_len = ntohl(*((uint32*) (packet + 12)));
if (size != ( RESPONSE_PACKET_FIX_PART_LEN + payload_len))
return NULL;
response->status = *((uint8*) (packet + 1));
response->fmt = ntohs(*((uint16*) (packet + 2)));
response->mid = ntohl(*((uint32*) (packet + 4)));
response->reciever = ntohl(*((uint32*) (packet + 8)));
response->payload_len = payload_len;
response->payload = packet + RESPONSE_PACKET_FIX_PART_LEN;
return response;
}
request_t *clone_request(request_t *request)
{
/* deep clone */
request_t *req = (request_t *) wa_malloc(sizeof(request_t));
if (req == NULL)
return NULL;
memset(req, 0, sizeof(*req));
req->action = request->action;
req->fmt = request->fmt;
req->url = wa_strdup(request->url);
req->sender = request->sender;
req->mid = request->mid;
if (req->url == NULL)
goto fail;
req->payload_len = request->payload_len;
if (request->payload_len) {
req->payload = (char *) wa_malloc(request->payload_len);
if (!req->payload)
goto fail;
memcpy(req->payload, request->payload, request->payload_len);
} else {
// when payload_len is 0, the payload may be used for carrying some handle or integer
req->payload = request->payload;
}
return req;
fail: request_cleaner(req);
return NULL;
}
void request_cleaner(request_t *request)
{
if (request->url != NULL)
wa_free(request->url);
if (request->payload != NULL && request->payload_len > 0)
wa_free(request->payload);
wa_free(request);
}
void response_cleaner(response_t * response)
{
if (response->payload != NULL && response->payload_len > 0)
wa_free(response->payload);
wa_free(response);
}
response_t * clone_response(response_t * response)
{
response_t *clone = (response_t *) wa_malloc(sizeof(response_t));
if (clone == NULL)
return NULL;
memset(clone, 0, sizeof(*clone));
clone->fmt = response->fmt;
clone->mid = response->mid;
clone->status = response->status;
clone->reciever = response->reciever;
clone->payload_len = response->payload_len;
if (clone->payload_len) {
clone->payload = (char *) wa_malloc(response->payload_len);
if (!clone->payload)
goto fail;
memcpy(clone->payload, response->payload, response->payload_len);
} else {
// when payload_len is 0, the payload may be used for carrying some handle or integer
clone->payload = response->payload;
}
return clone;
fail: response_cleaner(clone);
return NULL;
}
response_t * set_response(response_t * response, int status, int fmt,
const char *payload, int payload_len)
{
response->payload = payload;
response->payload_len = payload_len;
response->status = status;
response->fmt = fmt;
return response;
}
response_t * make_response_for_request(request_t * request,
response_t * response)
{
response->mid = request->mid;
response->reciever = request->sender;
return response;
}
request_t * init_request(request_t * request, char *url, int action, int fmt,
void *payload, int payload_len)
{
static unsigned int mid = 0;
request->url = url;
request->action = action;
request->fmt = fmt;
request->payload = payload;
request->payload_len = payload_len;
request->mid = ++mid;
return request;
}
/*
check if the "url" is starting with "leading_str"
return: 0 - not match; >0 - the offset of matched url, include any "/" at the end
notes:
1. it ensures the leading_str "/abc" can pass "/abc/cde" and "/abc/, but fail "/ab" and "/abcd".
leading_str "/abc/" can pass "/abc"
2. it omit the '/' at the first char
3. it ensure the leading_str "/abc" can pass "/abc?cde
*/
int check_url_start(const char* url, int url_len, const char * leading_str)
{
int offset = 0;
if (*leading_str == '/')
leading_str++;
if (url_len > 0 && *url == '/') {
url_len--;
url++;
offset++;
}
int len = strlen(leading_str);
if (len == 0)
return 0;
// ensure leading_str not end with "/"
if (leading_str[len - 1] == '/') {
len--;
if (len == 0)
return 0;
}
// equal length
if (url_len == len) {
if (memcmp(url, leading_str, url_len) == 0) {
return (offset + len);
} else {
return 0;
}
}
if (url_len < len)
return 0;
else if (memcmp(url, leading_str, len) != 0)
return 0;
else if (url[len] != '/' && url[len] != '?')
return 0;
else
return (offset + len + 1);
}
// * @pattern:
// * sample 1: /abcd, match /abcd only
// * sample 2: /abcd/ match match "/abcd" and "/abcd/*"
// * sample 3: /abcd*, match any url started with "/abcd"
// * sample 4: /abcd/*, exclude "/abcd"
bool match_url(char * pattern, char * matched)
{
if (*pattern == '/')
pattern++;
if (*matched == '/')
matched++;
int matched_len = strlen(matched);
if (matched_len == 0)
return false;
if (matched[matched_len - 1] == '/') {
matched_len--;
if (matched_len == 0)
return false;
}
int len = strlen(pattern);
if (len == 0)
return false;
if (pattern[len - 1] == '/') {
len--;
if (strncmp(pattern, matched, len) != 0)
return false;
if (len == matched_len)
return true;
if (matched_len > len && matched[len] == '/')
return true;
return false;
} else if (pattern[len - 1] == '*') {
if (pattern[len - 2] == '/') {
if (strncmp(pattern, matched, len - 1) == 0)
return true;
else
return false;
} else {
return (strncmp(pattern, matched, len - 1) == 0);
}
} else {
return (strcmp(pattern, matched) == 0);
}
}
/*
* get the value of the key from following format buffer:
* key1=value1;key2=value2;key3=value3
*/
char * find_key_value(char * buffer, int buffer_len, char * key, char * value,
int value_len, char delimiter)
{
char * p = buffer;
int i = 0;
int remaining = buffer_len;
int key_len = strlen(key);
char * item_start = p;
while (*p != 0 && remaining > 0) {
while (*p == ' ' || *p == delimiter) {
p++;
remaining--;
}
if (remaining <= key_len)
return NULL;
// find the key
if (0 == strncmp(p, key, key_len) && p[key_len] == '=') {
p += (key_len + 1);
remaining -= (key_len + 1);
char * v = value;
memset(value, 0, value_len);
value_len--; // ensure last char is 0
while (*p != delimiter && remaining > 0 && value_len > 0) {
*v++ = *p++;
remaining--;
value_len--;
}
return value;
}
// goto next key
while (*p != delimiter && remaining > 0) {
p++;
remaining--;
}
}
return NULL;
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DEPS_IWASM_APP_LIBS_NATIVE_INTERFACE_SENSOR_API_H_
#define DEPS_IWASM_APP_LIBS_NATIVE_INTERFACE_SENSOR_API_H_
#include "bh_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
uint32
wasm_sensor_open(const char* name, int instance);
bool
wasm_sensor_config(uint32 sensor, int interval, int bit_cfg, int delay);
bool
wasm_sensor_config_with_attr_container(uint32 sensor, char * buffer, int len);
bool
wasm_sensor_close(uint32 sensor);
#ifdef __cplusplus
}
#endif
#endif /* DEPS_IWASM_APP_LIBS_NATIVE_INTERFACE_SENSOR_API_H_ */

View File

@ -0,0 +1,97 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef DEPS_SSG_MICRO_RUNTIME_WASM_POC_APP_LIBS_NATIVE_INTERFACE_SHARED_UTILS_H_
#define DEPS_SSG_MICRO_RUNTIME_WASM_POC_APP_LIBS_NATIVE_INTERFACE_SHARED_UTILS_H_
#include "native_interface.h"
#ifdef __cplusplus
extern "C" {
#endif
#define FMT_ATTR_CONTAINER 99
#define FMT_APP_RAW_BINARY 98
typedef struct request {
// message id
uint32 mid;
// url of the request
char *url;
// action of the request, can be PUT/GET/POST/DELETE
int action;
// payload format, currently only support attr_container_t type
int fmt;
// payload of the request, currently only support attr_container_t type
void *payload;
int payload_len;
unsigned long sender;
} request_t;
typedef struct response {
// message id
uint32 mid;
// status of the response
int status;
// payload format
int fmt;
// payload of the response,
void *payload;
int payload_len;
unsigned long reciever;
} response_t;
int check_url_start(const char* url, int url_len, const char * leading_str);
bool match_url(char * pattern, char * matched);
char * find_key_value(char * buffer, int buffer_len, char * key, char * value,
int value_len, char delimiter);
request_t *clone_request(request_t *request);
void request_cleaner(request_t *request);
response_t * clone_response(response_t * response);
void response_cleaner(response_t * response);
response_t * set_response(response_t * response, int status, int fmt,
const char *payload, int payload_len);
response_t * make_response_for_request(request_t * request,
response_t * response);
request_t * init_request(request_t * request, char *url, int action, int fmt,
void *payload, int payload_len);
char * pack_request(request_t *request, int * size);
request_t * unpack_request(char * packet, int size, request_t * request);
char * pack_response(response_t *response, int * size);
response_t * unpack_response(char * packet, int size, response_t * response);
void free_req_resp_packet(char * packet);
#ifdef __cplusplus
}
#endif
#endif /* DEPS_SSG_MICRO_RUNTIME_WASM_POC_APP_LIBS_NATIVE_INTERFACE_SHARED_UTILS_H_ */