mirror of
https://github.com/emqx/neuron.git
synced 2026-10-28 22:59:34 +08:00
Add api: get plugin schema & config node
check the param according to the schema
This commit is contained in:
+4
-2
@@ -71,6 +71,7 @@ endif()
|
||||
|
||||
# define neuron executalbe program
|
||||
aux_source_directory(src/parser NEURON_SRC_PARSE)
|
||||
aux_source_directory(src/schema NEURON_SRC_SCHEMA)
|
||||
set(NEURON_SOURCES
|
||||
src/main.c
|
||||
src/config.c
|
||||
@@ -92,7 +93,7 @@ set(NEURON_SOURCES
|
||||
|
||||
set(NEURON_INCLUDE_DIRECTORIES include src plugins)
|
||||
add_executable(neuron)
|
||||
target_sources(neuron PRIVATE ${NEURON_SOURCES} ${NEURON_SRC_PARSE})
|
||||
target_sources(neuron PRIVATE ${NEURON_SOURCES} ${NEURON_SRC_PARSE} ${NEURON_SRC_SCHEMA})
|
||||
target_include_directories(neuron PRIVATE ${NEURON_INCLUDE_DIRECTORIES})
|
||||
if(APPLE)
|
||||
target_link_libraries(neuron nng::nng jansson yaml neuron-base)
|
||||
@@ -128,8 +129,9 @@ target_include_directories(neuron-base
|
||||
target_link_libraries(neuron-base vector-static csptr jansson crypto
|
||||
${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
#copy yaml to build
|
||||
#copy file for run and unit test
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/neuron.yaml DESTINATION ${CMAKE_BINARY_DIR})
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/plugin_param_schema.json DESTINATION ${CMAKE_BINARY_DIR})
|
||||
|
||||
# define for plugins
|
||||
add_subdirectory(plugins/sample)
|
||||
|
||||
@@ -72,6 +72,7 @@ typedef enum neu_reqresp_type {
|
||||
NEU_REQRESP_DATATAGS,
|
||||
NEU_REQRESP_SELF_NODE_ID,
|
||||
NEU_REQRESP_NODE_ID,
|
||||
NEU_REQRESP_NODE_SETTING,
|
||||
} neu_reqresp_type_e;
|
||||
|
||||
typedef uint32_t neu_node_id_t;
|
||||
@@ -260,6 +261,12 @@ typedef struct neu_represp_node_id {
|
||||
neu_node_id_t node_id;
|
||||
} neu_reqresp_node_id_t;
|
||||
|
||||
/* NEU_REQRESP_NODE_SETTING */
|
||||
typedef struct neu_cmd_node_setting {
|
||||
neu_node_id_t node_id;
|
||||
const char * setting;
|
||||
} neu_cmd_node_setting_t;
|
||||
|
||||
typedef struct neu_request {
|
||||
uint32_t req_id;
|
||||
neu_reqresp_type_e req_type;
|
||||
@@ -304,7 +311,7 @@ typedef struct neu_event_reply {
|
||||
*/
|
||||
typedef enum neu_config_type {
|
||||
NEU_CONFIG_UNKNOW,
|
||||
NEU_CONFIG_ADDRESS,
|
||||
NEU_CONFIG_SETTING,
|
||||
} neu_config_type_e;
|
||||
|
||||
typedef struct neu_config {
|
||||
|
||||
@@ -133,6 +133,9 @@ int neu_plugin_tag_count_by_attribute(neu_taggrp_config_t *grp_config,
|
||||
neu_datatag_table_t *tag_table,
|
||||
neu_attributetype_e attribute);
|
||||
|
||||
intptr_t neu_plugin_node_config_setting(neu_plugin_t *plugin,
|
||||
neu_node_id_t node_id,
|
||||
const char * setting);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ mqtt:
|
||||
clean_session: 1
|
||||
broker:
|
||||
connection: tcp://
|
||||
host: localhost
|
||||
host: broker.emqx.io
|
||||
port: 1883
|
||||
web:
|
||||
host: 0.0.0.0
|
||||
|
||||
@@ -539,7 +539,8 @@ static int modbus_tcp_config(neu_plugin_t *plugin, neu_config_t *configs)
|
||||
(void) plugin;
|
||||
int ret = 0;
|
||||
|
||||
log_info("modbus config.............");
|
||||
log_info("modbus config............. type: %d, config: %s", configs->type,
|
||||
configs->buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -122,4 +122,26 @@ void handle_get_adapter(nng_aio *aio)
|
||||
index += 1;
|
||||
}
|
||||
vector_uninit(&nodes);
|
||||
}
|
||||
|
||||
void handle_node_setting(nng_aio *aio)
|
||||
{
|
||||
neu_plugin_t *plugin = neu_rest_get_plugin();
|
||||
|
||||
REST_PROCESS_HTTP_REQUEST(
|
||||
aio, neu_parse_node_setting_req_t, neu_parse_decode_node_setting, {
|
||||
char * config_buf = calloc(req_data_size + 1, sizeof(char));
|
||||
intptr_t err = 0;
|
||||
|
||||
memcpy(config_buf, req_data, req_data_size);
|
||||
err = neu_plugin_node_config_setting(plugin, req->node_id,
|
||||
config_buf);
|
||||
free(config_buf);
|
||||
|
||||
if (err != 0) {
|
||||
http_bad_request(aio, "{\"error\": 1}");
|
||||
} else {
|
||||
http_ok(aio, "{\"error\": 0}");
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -25,5 +25,6 @@ void handle_add_adapter(nng_aio *aio);
|
||||
void handle_del_adapter(nng_aio *aio);
|
||||
void handle_update_adapter(nng_aio *aio);
|
||||
void handle_get_adapter(nng_aio *aio);
|
||||
void handle_node_setting(nng_aio *aio);
|
||||
|
||||
#endif
|
||||
@@ -89,6 +89,12 @@ struct neu_rest_handler cors_handler[] = {
|
||||
{
|
||||
.url = "/api/v2/subscribe",
|
||||
},
|
||||
{
|
||||
.url = "/api/v2/plugin/schema",
|
||||
},
|
||||
{
|
||||
.url = "/api/v2/node/setting",
|
||||
},
|
||||
};
|
||||
|
||||
struct neu_rest_handler api_handlers[] = {
|
||||
@@ -244,6 +250,18 @@ struct neu_rest_handler api_handlers[] = {
|
||||
.url = "/api/v2/subscribe",
|
||||
.value.handler = handle_grp_get_subscribe,
|
||||
},
|
||||
{
|
||||
.method = NEU_REST_METHOD_GET,
|
||||
.type = NEU_REST_HANDLER_FUNCTION,
|
||||
.url = "/api/v2/schema/plugin",
|
||||
.value.handler = handle_get_plugin_schema,
|
||||
},
|
||||
{
|
||||
.method = NEU_REST_METHOD_POST,
|
||||
.type = NEU_REST_HANDLER_FUNCTION,
|
||||
.url = "/api/v2/node/setting",
|
||||
.value.handler = handle_node_setting,
|
||||
},
|
||||
};
|
||||
|
||||
void neu_rest_web_handler(const struct neu_rest_handler **handlers,
|
||||
|
||||
@@ -100,4 +100,21 @@ void handle_login(nng_aio *aio)
|
||||
void handle_logout(nng_aio *aio)
|
||||
{
|
||||
(void) aio;
|
||||
}
|
||||
|
||||
void handle_get_plugin_schema(nng_aio *aio)
|
||||
{
|
||||
char buf[4096] = { 0 };
|
||||
FILE *fp = fopen("./plugin_param_schema.json", "r");
|
||||
|
||||
if (fp == NULL) {
|
||||
log_info("open ./plugin_param_schema.json error: %d", errno);
|
||||
http_not_found(aio, "{\"status\": \"error\"}");
|
||||
return;
|
||||
}
|
||||
|
||||
fread(buf, 1, sizeof(buf), fp);
|
||||
fclose(fp);
|
||||
|
||||
http_ok(aio, buf);
|
||||
}
|
||||
@@ -26,5 +26,6 @@ void handle_get_ttys(nng_aio *aio);
|
||||
void handle_ping(nng_aio *aio);
|
||||
void handle_login(nng_aio *aio);
|
||||
void handle_logout(nng_aio *aio);
|
||||
void handle_get_plugin_schema(nng_aio *aio);
|
||||
|
||||
#endif
|
||||
+33
-12
@@ -125,7 +125,6 @@ struct neu_adapter {
|
||||
uint32_t new_req_id;
|
||||
plugin_id_t plugin_id;
|
||||
plugin_kind_e plugin_kind;
|
||||
char * plugin_lib_name;
|
||||
void * plugin_lib; // handle of dynamic lib
|
||||
neu_plugin_module_t *plugin_module;
|
||||
neu_plugin_t * plugin;
|
||||
@@ -705,6 +704,16 @@ static int adapter_command(neu_adapter_t *adapter, neu_request_t *cmd,
|
||||
break;
|
||||
}
|
||||
|
||||
case NEU_REQRESP_NODE_SETTING: {
|
||||
ADAPTER_RESP_CODE(adapter, cmd, intptr_t, neu_cmd_node_setting_t, rv,
|
||||
NEU_REQRESP_ERR_CODE, p_result, {
|
||||
ret = neu_manager_adapter_config_setting(
|
||||
adapter->manager, req_cmd->node_id,
|
||||
req_cmd->setting);
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
rv = -1;
|
||||
break;
|
||||
@@ -888,14 +897,10 @@ neu_adapter_t *neu_adapter_create(neu_adapter_info_t *info,
|
||||
adapter->plugin_kind = info->plugin_kind;
|
||||
adapter->manager = manager;
|
||||
|
||||
adapter->plugin_lib_name = strdup(info->plugin_lib_name);
|
||||
if (adapter->name == NULL || adapter->plugin_lib_name == NULL) {
|
||||
if (adapter->name == NULL || info->plugin_lib_name == NULL) {
|
||||
if (adapter->name != NULL) {
|
||||
free(adapter->name);
|
||||
}
|
||||
if (adapter->plugin_lib_name != NULL) {
|
||||
free(adapter->plugin_lib_name);
|
||||
}
|
||||
nng_mtx_free(adapter->mtx);
|
||||
free(adapter);
|
||||
log_error("Failed duplicate string for create adapter");
|
||||
@@ -904,11 +909,11 @@ neu_adapter_t *neu_adapter_create(neu_adapter_info_t *info,
|
||||
|
||||
void * handle;
|
||||
neu_plugin_module_t *plugin_module;
|
||||
handle = load_plugin_library(adapter->plugin_lib_name, adapter->plugin_kind,
|
||||
&plugin_module);
|
||||
handle = load_plugin_library((char *) info->plugin_lib_name,
|
||||
adapter->plugin_kind, &plugin_module);
|
||||
if (handle == NULL) {
|
||||
neu_panic("Can't to load library(%s) for plugin(%s)",
|
||||
adapter->plugin_lib_name, adapter->name);
|
||||
info->plugin_lib_name, adapter->name);
|
||||
}
|
||||
|
||||
neu_plugin_t *plugin;
|
||||
@@ -954,9 +959,6 @@ void neu_adapter_destroy(neu_adapter_t *adapter)
|
||||
if (adapter->name != NULL) {
|
||||
free(adapter->name);
|
||||
}
|
||||
if (adapter->plugin_lib_name != NULL) {
|
||||
free(adapter->plugin_lib_name);
|
||||
}
|
||||
nng_mtx_free(adapter->mtx);
|
||||
free(adapter);
|
||||
return;
|
||||
@@ -1061,4 +1063,23 @@ plugin_id_t neu_adapter_get_plugin_id(neu_adapter_t *adapter)
|
||||
}
|
||||
|
||||
return adapter->plugin_id;
|
||||
}
|
||||
|
||||
int neu_adapter_config(neu_adapter_t *adapter, neu_config_t *config)
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
if (adapter == NULL) {
|
||||
log_error("Config adapter with NULL adapter");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (adapter->plugin_module != NULL) {
|
||||
const neu_plugin_intf_funs_t *intf_funs;
|
||||
|
||||
intf_funs = adapter->plugin_module->intf_funs;
|
||||
intf_funs->config(adapter->plugin, config);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
@@ -38,5 +38,6 @@ nng_socket neu_adapter_get_sock(neu_adapter_t *adapter);
|
||||
adapter_id_t neu_adapter_get_id(neu_adapter_t *adapter);
|
||||
adapter_type_e neu_adapter_get_type(neu_adapter_t *adapter);
|
||||
plugin_id_t neu_adapter_get_plugin_id(neu_adapter_t *adapter);
|
||||
int neu_adapter_config(neu_adapter_t *adapter, neu_config_t *config);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -422,3 +422,19 @@ int neu_plugin_tag_count_by_attribute(neu_taggrp_config_t *grp_config,
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
intptr_t neu_plugin_node_config_setting(neu_plugin_t *plugin,
|
||||
neu_node_id_t node_id,
|
||||
const char * setting)
|
||||
{
|
||||
intptr_t errorcode = -1;
|
||||
neu_cmd_node_setting_t node_setting = { 0 };
|
||||
|
||||
node_setting.node_id = node_id;
|
||||
node_setting.setting = setting;
|
||||
|
||||
PLUGIN_CALL_CMD(plugin, NEU_REQRESP_NODE_SETTING, node_setting, intptr_t,
|
||||
{ errorcode = (intptr_t) resp; })
|
||||
|
||||
return errorcode;
|
||||
}
|
||||
@@ -1776,3 +1776,34 @@ neu_datatag_table_t *neu_manager_get_datatag_tbl(neu_manager_t *manager,
|
||||
|
||||
return tag_table;
|
||||
}
|
||||
|
||||
int neu_manager_adapter_config_setting(neu_manager_t *manager,
|
||||
neu_node_id_t node_id,
|
||||
const char * config)
|
||||
{
|
||||
adapter_id_t adapter_id = { 0 };
|
||||
adapter_reg_entity_t *reg_entity = NULL;
|
||||
int ret = 0;
|
||||
neu_config_t neu_config = { .type = NEU_CONFIG_SETTING };
|
||||
|
||||
nng_mtx_lock(manager->adapters_mtx);
|
||||
|
||||
adapter_id = neu_manager_adapter_id_from_node_id(manager, node_id);
|
||||
reg_entity = find_reg_adapter_by_id(&manager->reg_adapters, adapter_id);
|
||||
|
||||
if (reg_entity == NULL) {
|
||||
log_error("Can't find matched src registered adapter");
|
||||
nng_mtx_unlock(manager->adapters_mtx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
neu_config.buf_len = strlen(config);
|
||||
neu_config.buf = strdup(config);
|
||||
|
||||
ret = neu_adapter_config(reg_entity->adapter, &neu_config);
|
||||
nng_mtx_unlock(manager->adapters_mtx);
|
||||
|
||||
free(neu_config.buf);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -64,4 +64,8 @@ neu_node_id_t neu_manager_adapter_id_to_node_id(neu_manager_t *manager,
|
||||
adapter_id_t adapter_id);
|
||||
adapter_id_t neu_manager_adapter_id_from_node_id(neu_manager_t *manager,
|
||||
neu_node_id_t node_id);
|
||||
int neu_manager_adapter_config_setting(neu_manager_t *manager,
|
||||
neu_node_id_t node_id,
|
||||
const char * config);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -17,11 +17,14 @@
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils/json.h"
|
||||
|
||||
#include "neu_json_fn.h"
|
||||
#include "neu_json_param.h"
|
||||
|
||||
int neu_json_encode_by_fn(void *param, neu_json_encode_fn fn, char **result)
|
||||
{
|
||||
@@ -73,4 +76,34 @@ int neu_parse_encode_error(void *json_object, void *param)
|
||||
};
|
||||
|
||||
return neu_json_encode_field(json_object, elems, 1);
|
||||
}
|
||||
|
||||
int neu_parse_param(char *buf, char **err_param, int n, neu_json_elem_t *ele,
|
||||
...)
|
||||
{
|
||||
void * json = neu_json_decode_new(buf);
|
||||
neu_json_elem_t params_ele = { .name = "params", .t = NEU_JSON_OBJECT };
|
||||
va_list ap;
|
||||
int ret = 0;
|
||||
|
||||
if (neu_json_decode_value(json, ¶ms_ele) != 0) {
|
||||
neu_json_decode_free(json);
|
||||
*err_param = strdup("params");
|
||||
return -1;
|
||||
}
|
||||
|
||||
va_start(ap, ele);
|
||||
for (int i = 0; i < n; i++) {
|
||||
neu_json_elem_t *tmp_ele = va_arg(ap, neu_json_elem_t *);
|
||||
if (neu_json_decode_value(params_ele.v.object, tmp_ele) != 0) {
|
||||
*err_param = strdup(tmp_ele->name);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
va_end(ap);
|
||||
|
||||
neu_json_decode_free(json);
|
||||
return ret;
|
||||
}
|
||||
@@ -184,3 +184,32 @@ int neu_parse_encode_get_nodes(void *json_object, void *param)
|
||||
|
||||
return neu_json_encode_field(json_object, elems, 1);
|
||||
}
|
||||
|
||||
int neu_parse_decode_node_setting(char * buf,
|
||||
neu_parse_node_setting_req_t **result)
|
||||
{
|
||||
neu_parse_node_setting_req_t *req =
|
||||
calloc(1, sizeof(neu_parse_node_setting_req_t));
|
||||
neu_json_elem_t elem[] = {
|
||||
{
|
||||
.name = "node_id",
|
||||
.t = NEU_JSON_INT,
|
||||
},
|
||||
};
|
||||
|
||||
int ret = neu_json_decode(buf, NEU_JSON_ELEM_SIZE(elem), elem);
|
||||
if (ret != 0) {
|
||||
free(req);
|
||||
return -1;
|
||||
}
|
||||
req->node_id = elem[0].v.val_int;
|
||||
|
||||
*result = req;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void neu_parse_decode_node_setting_free(neu_parse_node_setting_req_t *req)
|
||||
{
|
||||
free(req);
|
||||
}
|
||||
@@ -73,6 +73,13 @@ int neu_parse_decode_update_node(char * buf,
|
||||
neu_parse_update_node_req_t **result);
|
||||
void neu_parse_decode_update_node_free(neu_parse_update_node_req_t *req);
|
||||
|
||||
typedef struct {
|
||||
uint32_t node_id;
|
||||
} neu_parse_node_setting_req_t;
|
||||
int neu_parse_decode_node_setting(char * buf,
|
||||
neu_parse_node_setting_req_t **result);
|
||||
void neu_parse_decode_node_setting_free(neu_parse_node_setting_req_t *req);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* NEURON IIoT System for Industry 4.0
|
||||
* Copyright (C) 2020-2021 EMQ Technologies Co., Ltd All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**/
|
||||
|
||||
#ifndef _NEU_JSON_PARAM_H
|
||||
#define _NEU_JSON_PARAM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "utils/json.h"
|
||||
|
||||
int neu_parse_param(char *buf, char **err_param, int n, neu_json_elem_t *ele,
|
||||
...);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,218 @@
|
||||
/**
|
||||
* NEURON IIoT System for Industry 4.0
|
||||
* Copyright (C) 2020-2021 EMQ Technologies Co., Ltd All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**/
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "neu_log.h"
|
||||
#include "schema.h"
|
||||
#include "utils/json.h"
|
||||
|
||||
struct neu_schema_valid {
|
||||
void *json;
|
||||
char *content;
|
||||
};
|
||||
|
||||
static bool valid_init(void *json, neu_json_elem_t *ele, char *name);
|
||||
static int valid_int(neu_schema_valid_t *v, void *value, char *name);
|
||||
static int valid_real(neu_schema_valid_t *v, void *value, char *name);
|
||||
static int valid_string(neu_schema_valid_t *v, void *value, char *name);
|
||||
static int valid_enum(neu_schema_valid_t *v, void *value, char *name);
|
||||
|
||||
neu_schema_valid_t *neu_schema_load(char *buf, char *plugin)
|
||||
{
|
||||
void * json = neu_json_decode_new(buf);
|
||||
neu_json_elem_t elem = { .name = plugin, .t = NEU_JSON_OBJECT };
|
||||
int ret = 0;
|
||||
neu_schema_valid_t *st = NULL;
|
||||
|
||||
assert(json != NULL);
|
||||
ret = neu_json_decode_value(json, &elem);
|
||||
if (ret != 0) {
|
||||
neu_json_decode_free(json);
|
||||
return st;
|
||||
}
|
||||
|
||||
st = calloc(1, sizeof(neu_schema_valid_t));
|
||||
st->json = json;
|
||||
neu_json_encode(json, &st->content);
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
void neu_schema_free(neu_schema_valid_t *v)
|
||||
{
|
||||
neu_json_decode_free(v->json);
|
||||
free(v->content);
|
||||
free(v);
|
||||
}
|
||||
|
||||
int neu_schema_valid_param(neu_schema_valid_t *v, void *value, char *name,
|
||||
neu_schema_valid_type_e type)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
switch (type) {
|
||||
case NEU_SCHEMA_VALID_INT:
|
||||
ret = valid_int(v, value, name);
|
||||
break;
|
||||
case NEU_SCHEMA_VALID_REAL:
|
||||
ret = valid_real(v, value, name);
|
||||
break;
|
||||
case NEU_SCHEMA_VALID_STRING:
|
||||
ret = valid_string(v, value, name);
|
||||
break;
|
||||
case NEU_SCHEMA_VALID_ENUM:
|
||||
ret = valid_enum(v, value, name);
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_schema_valid_tag_type(neu_schema_valid_t *v, uint8_t t)
|
||||
{
|
||||
int size = neu_json_decode_array_size(v->content, "tag_type");
|
||||
|
||||
if (size <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
neu_json_elem_t e = { .name = NULL, .t = NEU_JSON_INT };
|
||||
if (neu_json_decode_array(v->content, "tag_type", i, 1, &e) == 0) {
|
||||
if (t == e.v.val_int) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static bool valid_init(void *json, neu_json_elem_t *vele, char *name)
|
||||
{
|
||||
neu_json_elem_t ele = { .name = name, .t = NEU_JSON_OBJECT };
|
||||
|
||||
vele->name = "valid";
|
||||
vele->t = NEU_JSON_OBJECT;
|
||||
|
||||
return neu_json_decode_value(json, &ele) == 0 &&
|
||||
neu_json_decode_value(ele.v.object, vele) == 0;
|
||||
}
|
||||
|
||||
static int valid_int(neu_schema_valid_t *v, void *value, char *name)
|
||||
{
|
||||
neu_json_elem_t valid_ele = { 0 };
|
||||
neu_json_elem_t min_ele = { .name = "min", .t = NEU_JSON_INT };
|
||||
neu_json_elem_t max_ele = { .name = "max", .t = NEU_JSON_INT };
|
||||
int64_t * vv = (int64_t *) value;
|
||||
|
||||
if (!valid_init(v->json, &valid_ele, name)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (neu_json_decode_value(valid_ele.v.object, &min_ele) != 0 ||
|
||||
neu_json_decode_value(valid_ele.v.object, &max_ele) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*vv >= min_ele.v.val_int && *vv <= max_ele.v.val_int) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int valid_real(neu_schema_valid_t *v, void *value, char *name)
|
||||
{
|
||||
neu_json_elem_t valid_ele = { 0 };
|
||||
neu_json_elem_t min_ele = { .name = "min", .t = NEU_JSON_DOUBLE };
|
||||
neu_json_elem_t max_ele = { .name = "max", .t = NEU_JSON_DOUBLE };
|
||||
double * vv = (double *) value;
|
||||
|
||||
if (!valid_init(v->json, &valid_ele, name)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (neu_json_decode_value(valid_ele.v.object, &min_ele) != 0 ||
|
||||
neu_json_decode_value(valid_ele.v.object, &max_ele) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*vv >= min_ele.v.val_int && *vv <= max_ele.v.val_int) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int valid_string(neu_schema_valid_t *v, void *value, char *name)
|
||||
{
|
||||
neu_json_elem_t valid_ele = { 0 };
|
||||
neu_json_elem_t len_ele = { .name = "length", .t = NEU_JSON_INT };
|
||||
char * vv = (char *) value;
|
||||
|
||||
if (!valid_init(v->json, &valid_ele, name)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (neu_json_decode_value(valid_ele.v.object, &len_ele) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((uint64_t) len_ele.v.val_int >= strlen(vv)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int valid_enum(neu_schema_valid_t *v, void *value, char *name)
|
||||
{
|
||||
neu_json_elem_t valid_ele = { 0 };
|
||||
char * valid_content = NULL;
|
||||
int64_t * vv = (int64_t *) value;
|
||||
int size = 0;
|
||||
|
||||
if (!valid_init(v->json, &valid_ele, name)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
neu_json_encode(valid_ele.v.object, &valid_content);
|
||||
size = neu_json_decode_array_size(valid_content, "value");
|
||||
if (size <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
neu_json_elem_t ve = { .name = NULL, .t = NEU_JSON_INT };
|
||||
if (neu_json_decode_array(valid_content, "value", i, 1, &ve) == 0) {
|
||||
if (ve.v.val_int == *vv) {
|
||||
free(valid_content);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(valid_content);
|
||||
return -1;
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* NEURON IIoT System for Industry 4.0
|
||||
* Copyright (C) 2020-2021 EMQ Technologies Co., Ltd All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
**/
|
||||
|
||||
#ifndef _NEU_SCHEMA_H_
|
||||
#define _NEU_SCHEMA_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum neu_schema_valid_type {
|
||||
NEU_SCHEMA_VALID_INT,
|
||||
NEU_SCHEMA_VALID_REAL,
|
||||
NEU_SCHEMA_VALID_STRING,
|
||||
NEU_SCHEMA_VALID_ENUM,
|
||||
} neu_schema_valid_type_e;
|
||||
|
||||
typedef struct neu_schema_valid neu_schema_valid_t;
|
||||
|
||||
neu_schema_valid_t *neu_schema_load(char *buf, char *plugin);
|
||||
void neu_schema_free(neu_schema_valid_t *v);
|
||||
int neu_schema_valid_param(neu_schema_valid_t *v, void *value, char *name,
|
||||
neu_schema_valid_type_e);
|
||||
int neu_schema_valid_tag_type(neu_schema_valid_t *v, uint8_t t);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -287,3 +287,28 @@ int neu_json_encode(void *json_object, char **str)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *neu_json_decode_new(char *buf)
|
||||
{
|
||||
json_error_t error;
|
||||
json_t * root = json_loads(buf, 0, &error);
|
||||
|
||||
if (root == NULL) {
|
||||
log_error(
|
||||
"json load error, line: %d, column: %d, position: %d, info: %s",
|
||||
error.line, error.column, error.position, error.text);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
void neu_json_decode_free(void *ob)
|
||||
{
|
||||
json_decref(ob);
|
||||
}
|
||||
|
||||
int neu_json_decode_value(void *object, neu_json_elem_t *ele)
|
||||
{
|
||||
return decode_object(object, ele);
|
||||
}
|
||||
+7
-4
@@ -56,10 +56,13 @@ typedef struct neu_json_elem {
|
||||
|
||||
#define NEU_JSON_ELEM_SIZE(elems) sizeof(elems) / sizeof(neu_json_elem_t)
|
||||
|
||||
int neu_json_decode(char *buf, int size, neu_json_elem_t *ele);
|
||||
int neu_json_decode_array_size(char *buf, char *child);
|
||||
int neu_json_decode_array(char *buf, char *name, int index, int size,
|
||||
neu_json_elem_t *ele);
|
||||
int neu_json_decode(char *buf, int size, neu_json_elem_t *ele);
|
||||
int neu_json_decode_array_size(char *buf, char *child);
|
||||
int neu_json_decode_array(char *buf, char *name, int index, int size,
|
||||
neu_json_elem_t *ele);
|
||||
void *neu_json_decode_new(char *buf);
|
||||
void neu_json_decode_free(void *ob);
|
||||
int neu_json_decode_value(void *object, neu_json_elem_t *ele);
|
||||
|
||||
void *neu_json_encode_new();
|
||||
void neu_json_encode_free(void *json_object);
|
||||
|
||||
@@ -13,7 +13,7 @@ TEST(JsonTest, DecodeField)
|
||||
|
||||
result = neu_config_get_value((char *) "./neuron.yaml", 3, (char *) "mqtt",
|
||||
(char *) "broker", (char *) "host");
|
||||
EXPECT_STREQ("localhost", result);
|
||||
EXPECT_STREQ("broker.emqx.io", result);
|
||||
free(result);
|
||||
|
||||
result = neu_config_get_value((char *) "./neuron.yaml", 3, (char *) "mqtt",
|
||||
|
||||
Reference in New Issue
Block a user