mirror of
https://github.com/emqx/neuron.git
synced 2026-10-29 23:19:18 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d045d0f22 | ||
|
|
6dc4695974 | ||
|
|
17b89a8145 | ||
|
|
402f30cd19 | ||
|
|
c97f681876 | ||
|
|
f6ddec7e24 | ||
|
|
9f55272665 | ||
|
|
43e6caf76a | ||
|
|
1811c247c6 | ||
|
|
fbc909b4fb | ||
|
|
0d00efae57 | ||
|
|
be39ad0e30 | ||
|
|
9de63c033d | ||
|
|
30916516db | ||
|
|
4c564e0103 | ||
|
|
f7a6599c4e | ||
|
|
3cb7053726 | ||
|
|
c68215db59 | ||
|
|
143edf4e68 | ||
|
|
2e881ed2a0 | ||
|
|
555241aa80 | ||
|
|
2c941f6701 | ||
|
|
9169c57ab0 | ||
|
|
5a688bdbe3 | ||
|
|
bb057f3abc | ||
|
|
5b1cb93ef0 | ||
|
|
a93950ebfc | ||
|
|
0c805c4a95 | ||
|
|
2c885f6ff1 | ||
|
|
23f7e51fcf | ||
|
|
f3966f6c42 | ||
|
|
d21a961d57 | ||
|
|
244e4ea012 | ||
|
|
d6d72da7f3 | ||
|
|
cb7e60f136 | ||
|
|
3c6524f041 | ||
|
|
824888baac | ||
|
|
84edea1983 | ||
|
|
765c54f188 | ||
|
|
0c059f46f4 | ||
|
|
ed4e5ac029 | ||
|
|
c29aaf5ef0 | ||
|
|
b5a449bddb | ||
|
|
44aada7d38 | ||
|
|
720336d12d | ||
|
|
9369ad6379 | ||
|
|
fb3fadf992 | ||
|
|
d6c3336b3a | ||
|
|
3414bb03c7 | ||
|
|
fc46dbf19f | ||
|
|
c41a695f1d | ||
|
|
3ca7bfa522 | ||
|
|
43e81bb5e0 | ||
|
|
f1972717b3 | ||
|
|
57dd824eb4 | ||
|
|
fa91290ada | ||
|
|
2f79a29416 | ||
|
|
8a6a8b6cdb | ||
|
|
138079c2bc | ||
|
|
21f02e50eb | ||
|
|
56f018497d | ||
|
|
b37d8ab2dc | ||
|
|
9db92459d0 | ||
|
|
cfff223907 | ||
|
|
9a63c81c02 | ||
|
|
7698962cc3 | ||
|
|
1e0cf54999 | ||
|
|
b24d3506d4 | ||
|
|
32b7424333 | ||
|
|
a02390be0c | ||
|
|
18684d7e93 | ||
|
|
309610a685 | ||
|
|
6554e901b5 | ||
|
|
0603eff1f2 | ||
|
|
54ecb33fcd | ||
|
|
963acef468 | ||
|
|
9ac6028408 | ||
|
|
9859b2805f | ||
|
|
3442d4a814 | ||
|
|
2acdfcc7ef | ||
|
|
ac9d0011af | ||
|
|
af75cf2dcc | ||
|
|
af6bbf86ed | ||
|
|
661ff5a323 | ||
|
|
5b220cae7d | ||
|
|
7a6dd51747 | ||
|
|
2fcdb66f6f | ||
|
|
c11c51938c | ||
|
|
e09099eedb | ||
|
|
5cf1211437 | ||
|
|
2d873cacc7 | ||
|
|
d8aa593b01 | ||
|
|
052f5c5f98 | ||
|
|
127c1a19c1 | ||
|
|
c6ba1b114a | ||
|
|
f06fd84ba0 | ||
|
|
4a5d32604f | ||
|
|
0e89e61d8c | ||
|
|
d3957d7e32 | ||
|
|
2f2a1eb941 | ||
|
|
abc9df7fc0 | ||
|
|
1f67ee6a8e | ||
|
|
bceb610b6a | ||
|
|
664cd09024 | ||
|
|
f9f86e1f22 | ||
|
|
2a92002eaf | ||
|
|
01a3f20799 | ||
|
|
904a8dda0a | ||
|
|
94bf6a0d40 |
@@ -41,7 +41,7 @@ jobs:
|
||||
|
||||
ut:
|
||||
runs-on: ubuntu-20.04
|
||||
container: ghcr.io/neugates/build:x86_64-main
|
||||
container: ghcr.io/neugates/build:x86_64-v2.10
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -60,25 +60,9 @@ jobs:
|
||||
cd build
|
||||
ctest --output-on-failure
|
||||
|
||||
- name: create cov report
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install lcov
|
||||
mkdir -p cov_report
|
||||
./create_cov_report.sh ut
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
verbose: true
|
||||
fail_ci_if_error: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
directory: ./cov_report/
|
||||
files: ./cov_report/cov-ut.info
|
||||
|
||||
pft:
|
||||
runs-on: ubuntu-20.04
|
||||
container: ghcr.io/neugates/build:x86_64-main
|
||||
container: ghcr.io/neugates/build:x86_64-v2.10
|
||||
strategy:
|
||||
matrix:
|
||||
plugin: [core, ekuiper, modbus, mqtt, azure, metrics]
|
||||
@@ -120,20 +104,4 @@ jobs:
|
||||
pytest -s -v tests/ft/app/"test_azure.py"
|
||||
else
|
||||
pytest -s -v tests/ft/metrics/"test_metrics.py"
|
||||
fi
|
||||
|
||||
- name: create cov report
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install lcov
|
||||
mkdir -p cov_report
|
||||
./create_cov_report.sh ${{ matrix.plugin }}
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
verbose: true
|
||||
fail_ci_if_error: true
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
directory: ./cov_report/
|
||||
files: ./cov_report/cov-${{ matrix.plugin }}.info
|
||||
fi
|
||||
@@ -8,9 +8,9 @@ on:
|
||||
- published
|
||||
|
||||
env:
|
||||
VERSION: 2.10.0
|
||||
VERSION: 2.10.3
|
||||
UI_VERSION: 2.6.1
|
||||
BRANCH: main
|
||||
BRANCH: v2.10
|
||||
|
||||
jobs:
|
||||
cross-build:
|
||||
@@ -21,7 +21,7 @@ jobs:
|
||||
- [aarch64-linux-gnu, aarch64, arm64]
|
||||
- [arm-linux-gnueabihf, armv4, armhf]
|
||||
- [x86_64-linux-gnu, x86_64, amd64]
|
||||
container: ghcr.io/neugates/build:${{ matrix.arch[1] }}-main
|
||||
container: ghcr.io/neugates/build:${{ matrix.arch[1] }}-v2.10
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -64,7 +64,7 @@ jobs:
|
||||
matrix:
|
||||
arch:
|
||||
- [x86_64-linux-gnu, x86_64, amd64]
|
||||
container: ghcr.io/neugates/build:${{ matrix.arch[1] }}-main
|
||||
container: ghcr.io/neugates/build:${{ matrix.arch[1] }}-v2.10
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -166,8 +166,6 @@ file(COPY ${CMAKE_SOURCE_DIR}/dev.conf DESTINATION ${CMAKE_BINARY_DIR}/config)
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/neuron.json DESTINATION ${CMAKE_BINARY_DIR}/config)
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/.gitkeep DESTINATION ${CMAKE_BINARY_DIR}/logs)
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/.gitkeep DESTINATION ${CMAKE_BINARY_DIR}/persistence)
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/neuron.key DESTINATION ${CMAKE_BINARY_DIR}/config)
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/neuron.pem DESTINATION ${CMAKE_BINARY_DIR}/config)
|
||||
file(GLOB SQL_SCHEMAS ${CMAKE_SOURCE_DIR}/persistence/*.sql)
|
||||
file(COPY ${SQL_SCHEMAS} DESTINATION ${CMAKE_BINARY_DIR}/config)
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/default_plugins.json DESTINATION ${CMAKE_BINARY_DIR}/config)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(COMPILER_PREFIX aarch64-linux-gnu)
|
||||
set(CMAKE_SYSTEM_PROCESSOR aarch64)
|
||||
set(LIBRARY_DIR /home/neuron/main/libs)
|
||||
set(LIBRARY_DIR /home/neuron/v2.10/libs)
|
||||
|
||||
set(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(COMPILER_PREFIX arm-linux-gnueabi)
|
||||
set(CMAKE_SYSTEM_PROCESSOR armv5tejl)
|
||||
set(LIBRARY_DIR /home/neuron/main/libs)
|
||||
set(LIBRARY_DIR /home/neuron/v2.10/libs)
|
||||
|
||||
set(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(COMPILER_PREFIX arm-linux-gnueabihf)
|
||||
set(CMAKE_SYSTEM_PROCESSOR armv7l)
|
||||
set(LIBRARY_DIR /home/neuron/main/libs)
|
||||
set(LIBRARY_DIR /home/neuron/v2.10/libs)
|
||||
|
||||
set(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
set(CMAKE_SYSTEM_NAME Linux)
|
||||
set(COMPILER_PREFIX x86_64-linux-gnu)
|
||||
set(CMAKE_SYSTEM_PROCESSOR x86_64)
|
||||
set(LIBRARY_DIR /home/neuron/main/libs)
|
||||
set(LIBRARY_DIR /home/neuron/v2.10/libs)
|
||||
|
||||
set(CMAKE_C_COMPILER ${COMPILER_PREFIX}-gcc)
|
||||
set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}-g++)
|
||||
|
||||
@@ -57,6 +57,10 @@ typedef struct adapter_callbacks {
|
||||
struct {
|
||||
void (*update)(neu_adapter_t *adapter, const char *group,
|
||||
const char *tag, neu_dvalue_t value);
|
||||
void (*update_with_trace)(neu_adapter_t *adapter, const char *group,
|
||||
const char *tag, neu_dvalue_t value,
|
||||
neu_tag_meta_t *metas, int n_meta,
|
||||
void *trace_ctx);
|
||||
void (*update_with_meta)(neu_adapter_t *adapter, const char *group,
|
||||
const char *tag, neu_dvalue_t value,
|
||||
neu_tag_meta_t *metas, int n_meta);
|
||||
|
||||
@@ -134,6 +134,13 @@ int neu_mqtt_client_publish(neu_mqtt_client_t *client, neu_mqtt_qos_e qos,
|
||||
char *topic, uint8_t *payload, uint32_t len,
|
||||
void *data, neu_mqtt_client_publish_cb_t cb);
|
||||
|
||||
int neu_mqtt_client_publish_with_trace(neu_mqtt_client_t *client,
|
||||
neu_mqtt_qos_e qos, char *topic,
|
||||
uint8_t *payload, uint32_t len,
|
||||
void * data,
|
||||
neu_mqtt_client_publish_cb_t cb,
|
||||
const char *traceparent);
|
||||
|
||||
/** Subscribe to `topic` with service quality `qos`.
|
||||
*
|
||||
* This function tries to send a `SUBSCRIBE` packet with the given `qos` and
|
||||
|
||||
@@ -254,6 +254,8 @@ ssize_t neu_conn_recv(neu_conn_t *conn, uint8_t *buf, ssize_t len);
|
||||
ssize_t neu_conn_udp_recvfrom(neu_conn_t *conn, uint8_t *buf, ssize_t len,
|
||||
void *src);
|
||||
|
||||
void neu_conn_clear_recv_buffer(neu_conn_t *conn);
|
||||
|
||||
/**
|
||||
* @brief Specify the client to send data.
|
||||
*
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#define NEU_VERSION_MAJOR 2
|
||||
#define NEU_VERSION_MINOR 10
|
||||
#define NEU_VERSION_FIX 0
|
||||
#define NEU_VERSION_FIX 3
|
||||
|
||||
#define NEU_GET_VERSION_MAJOR(V) ((0xffff0000 & V) >> 16)
|
||||
#define NEU_GET_VERSION_MINOR(V) ((0x0000ff00 & V) >> 8)
|
||||
@@ -53,7 +53,7 @@
|
||||
#define NEU_MSG_MAX_SIZE 2048
|
||||
|
||||
#define NEU_TAG_META_LENGTH 20
|
||||
#define NEU_TAG_META_SIZE 3
|
||||
#define NEU_TAG_META_SIZE 8
|
||||
|
||||
#define NEU_LOG_LEVEL_DEBUG "debug"
|
||||
#define NEU_LOG_LEVEL_INFO "info"
|
||||
|
||||
@@ -83,6 +83,7 @@ typedef enum {
|
||||
NEU_ERR_TAG_DESCRIPTION_TOO_LONG = 2208,
|
||||
NEU_ERR_TAG_PRECISION_INVALID = 2209,
|
||||
NEU_ERR_TAG_EXIST = 2210,
|
||||
NEU_ERR_TAG_DECIMAL_INVALID = 2211,
|
||||
NEU_ERR_TAG_BIAS_INVALID = 2212,
|
||||
|
||||
NEU_ERR_LIBRARY_NOT_FOUND = 2301,
|
||||
|
||||
+81
-11
@@ -37,24 +37,94 @@ typedef enum neu_json_type {
|
||||
NEU_JSON_FLOAT,
|
||||
NEU_JSON_BOOL,
|
||||
NEU_JSON_OBJECT,
|
||||
NEU_JSON_BYTES,
|
||||
NEU_JSON_ARRAY_INT8,
|
||||
NEU_JSON_ARRAY_UINT8,
|
||||
NEU_JSON_ARRAY_INT16,
|
||||
NEU_JSON_ARRAY_UINT16,
|
||||
NEU_JSON_ARRAY_INT32,
|
||||
NEU_JSON_ARRAY_UINT32,
|
||||
NEU_JSON_ARRAY_INT64,
|
||||
NEU_JSON_ARRAY_UINT64,
|
||||
NEU_JSON_ARRAY_FLOAT,
|
||||
NEU_JSON_ARRAY_DOUBLE,
|
||||
NEU_JSON_ARRAY_BOOL,
|
||||
NEU_JSON_VALUE = NEU_JSON_UNDEFINE
|
||||
} neu_json_type_e;
|
||||
|
||||
typedef struct {
|
||||
uint8_t *bytes;
|
||||
int8_t *i8s;
|
||||
uint8_t length;
|
||||
} neu_json_value_array_int8_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t *u8s;
|
||||
uint8_t length;
|
||||
} neu_json_value_bytes_t;
|
||||
} neu_json_value_array_uint8_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t *i16s;
|
||||
uint8_t length;
|
||||
} neu_json_value_array_int16_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t *u16s;
|
||||
uint8_t length;
|
||||
} neu_json_value_array_uint16_t;
|
||||
|
||||
typedef struct {
|
||||
int32_t *i32s;
|
||||
uint8_t length;
|
||||
} neu_json_value_array_int32_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t *u32s;
|
||||
uint8_t length;
|
||||
} neu_json_value_array_uint32_t;
|
||||
|
||||
typedef struct {
|
||||
int64_t *i64s;
|
||||
uint8_t length;
|
||||
} neu_json_value_array_int64_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t *u64s;
|
||||
uint8_t length;
|
||||
} neu_json_value_array_uint64_t;
|
||||
|
||||
typedef struct {
|
||||
float * f32s;
|
||||
uint8_t length;
|
||||
} neu_json_value_array_float_t;
|
||||
|
||||
typedef struct {
|
||||
double *f64s;
|
||||
uint8_t length;
|
||||
} neu_json_value_array_double_t;
|
||||
|
||||
typedef struct {
|
||||
bool * bools;
|
||||
uint8_t length;
|
||||
} neu_json_value_array_bool_t;
|
||||
|
||||
typedef union neu_json_value {
|
||||
int64_t val_int;
|
||||
uint8_t val_bit;
|
||||
float val_float;
|
||||
double val_double;
|
||||
bool val_bool;
|
||||
char * val_str;
|
||||
void * val_object;
|
||||
neu_json_value_bytes_t val_bytes;
|
||||
int64_t val_int;
|
||||
uint8_t val_bit;
|
||||
float val_float;
|
||||
double val_double;
|
||||
bool val_bool;
|
||||
char * val_str;
|
||||
void * val_object;
|
||||
neu_json_value_array_int8_t val_array_int8;
|
||||
neu_json_value_array_uint8_t val_array_uint8;
|
||||
neu_json_value_array_int16_t val_array_int16;
|
||||
neu_json_value_array_uint16_t val_array_uint16;
|
||||
neu_json_value_array_int32_t val_array_int32;
|
||||
neu_json_value_array_uint32_t val_array_uint32;
|
||||
neu_json_value_array_int64_t val_array_int64;
|
||||
neu_json_value_array_uint64_t val_array_uint64;
|
||||
neu_json_value_array_float_t val_array_float;
|
||||
neu_json_value_array_double_t val_array_double;
|
||||
neu_json_value_array_bool_t val_array_bool;
|
||||
} neu_json_value_u;
|
||||
|
||||
typedef enum neu_json_attribute {
|
||||
|
||||
@@ -63,6 +63,7 @@ typedef struct {
|
||||
|
||||
int neu_json_encode_read_resp(void *json_object, void *param);
|
||||
int neu_json_encode_read_resp1(void *json_object, void *param);
|
||||
int neu_json_encode_read_resp2(void *json_object, void *param);
|
||||
int neu_json_encode_read_paginate_resp(void *json_object, void *param);
|
||||
|
||||
typedef struct {
|
||||
|
||||
+157
-6
@@ -675,6 +675,8 @@ typedef struct neu_resp_tag_value {
|
||||
neu_dvalue_t value;
|
||||
} neu_resp_tag_value_t;
|
||||
|
||||
typedef neu_resp_tag_value_t neu_tag_value_t;
|
||||
|
||||
typedef struct neu_resp_tag_value_meta {
|
||||
char tag[NEU_TAG_NAME_LEN];
|
||||
neu_dvalue_t value;
|
||||
@@ -799,6 +801,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
char *driver;
|
||||
char *group;
|
||||
void *trace_ctx;
|
||||
|
||||
neu_reqresp_trans_data_ctx_t *ctx;
|
||||
UT_array * tags; // neu_resp_tag_value_meta_t
|
||||
@@ -959,6 +962,7 @@ static inline void neu_tag_value_to_json(neu_resp_tag_value_meta_t *tag_value,
|
||||
case NEU_TYPE_STRING:
|
||||
case NEU_TYPE_TIME:
|
||||
case NEU_TYPE_DATA_AND_TIME:
|
||||
case NEU_TYPE_ARRAY_CHAR:
|
||||
tag_json->t = NEU_JSON_STR;
|
||||
tag_json->value.val_str = tag_value->value.value.str;
|
||||
break;
|
||||
@@ -967,9 +971,82 @@ static inline void neu_tag_value_to_json(neu_resp_tag_value_meta_t *tag_value,
|
||||
tag_json->value.val_str = (char *) tag_value->value.value.ptr.ptr;
|
||||
break;
|
||||
case NEU_TYPE_BYTES:
|
||||
tag_json->t = NEU_JSON_BYTES;
|
||||
tag_json->value.val_bytes.length = tag_value->value.value.bytes.length;
|
||||
tag_json->value.val_bytes.bytes = tag_value->value.value.bytes.bytes;
|
||||
tag_json->t = NEU_JSON_ARRAY_UINT8;
|
||||
tag_json->value.val_array_uint8.length =
|
||||
tag_value->value.value.bytes.length;
|
||||
tag_json->value.val_array_uint8.u8s =
|
||||
tag_value->value.value.bytes.bytes;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_BOOL:
|
||||
tag_json->t = NEU_JSON_ARRAY_BOOL;
|
||||
tag_json->value.val_array_bool.length =
|
||||
tag_value->value.value.bools.length;
|
||||
tag_json->value.val_array_bool.bools =
|
||||
tag_value->value.value.bools.bools;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT8:
|
||||
tag_json->t = NEU_JSON_ARRAY_INT8;
|
||||
tag_json->value.val_array_int8.length =
|
||||
tag_value->value.value.i8s.length;
|
||||
tag_json->value.val_array_int8.i8s = tag_value->value.value.i8s.i8s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT8:
|
||||
tag_json->t = NEU_JSON_ARRAY_UINT8;
|
||||
tag_json->value.val_array_uint8.length =
|
||||
tag_value->value.value.u8s.length;
|
||||
tag_json->value.val_array_uint8.u8s = tag_value->value.value.u8s.u8s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT16:
|
||||
tag_json->t = NEU_JSON_ARRAY_INT16;
|
||||
tag_json->value.val_array_int16.length =
|
||||
tag_value->value.value.i16s.length;
|
||||
tag_json->value.val_array_int16.i16s = tag_value->value.value.i16s.i16s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT16:
|
||||
tag_json->t = NEU_JSON_ARRAY_UINT16;
|
||||
tag_json->value.val_array_uint16.length =
|
||||
tag_value->value.value.u16s.length;
|
||||
tag_json->value.val_array_uint16.u16s =
|
||||
tag_value->value.value.u16s.u16s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT32:
|
||||
tag_json->t = NEU_JSON_ARRAY_INT32;
|
||||
tag_json->value.val_array_int32.length =
|
||||
tag_value->value.value.i32s.length;
|
||||
tag_json->value.val_array_int32.i32s = tag_value->value.value.i32s.i32s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT32:
|
||||
tag_json->t = NEU_JSON_ARRAY_UINT32;
|
||||
tag_json->value.val_array_uint32.length =
|
||||
tag_value->value.value.u32s.length;
|
||||
tag_json->value.val_array_uint32.u32s =
|
||||
tag_value->value.value.u32s.u32s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT64:
|
||||
tag_json->t = NEU_JSON_ARRAY_INT64;
|
||||
tag_json->value.val_array_int64.length =
|
||||
tag_value->value.value.i64s.length;
|
||||
tag_json->value.val_array_int64.i64s = tag_value->value.value.i64s.i64s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT64:
|
||||
tag_json->t = NEU_JSON_ARRAY_UINT64;
|
||||
tag_json->value.val_array_uint64.length =
|
||||
tag_value->value.value.u64s.length;
|
||||
tag_json->value.val_array_uint64.u64s =
|
||||
tag_value->value.value.u64s.u64s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_FLOAT:
|
||||
tag_json->t = NEU_JSON_ARRAY_FLOAT;
|
||||
tag_json->value.val_array_float.length =
|
||||
tag_value->value.value.f32s.length;
|
||||
tag_json->value.val_array_float.f32s = tag_value->value.value.f32s.f32s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_DOUBLE:
|
||||
tag_json->t = NEU_JSON_ARRAY_DOUBLE;
|
||||
tag_json->value.val_array_double.length =
|
||||
tag_value->value.value.f64s.length;
|
||||
tag_json->value.val_array_double.f64s =
|
||||
tag_value->value.value.f64s.f64s;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -1083,6 +1160,7 @@ neu_tag_value_to_json_paginate(neu_resp_tag_value_meta_paginate_t *tag_value,
|
||||
case NEU_TYPE_STRING:
|
||||
case NEU_TYPE_TIME:
|
||||
case NEU_TYPE_DATA_AND_TIME:
|
||||
case NEU_TYPE_ARRAY_CHAR:
|
||||
tag_json->t = NEU_JSON_STR;
|
||||
tag_json->value.val_str = tag_value->value.value.str;
|
||||
break;
|
||||
@@ -1091,9 +1169,82 @@ neu_tag_value_to_json_paginate(neu_resp_tag_value_meta_paginate_t *tag_value,
|
||||
tag_json->value.val_str = (char *) tag_value->value.value.ptr.ptr;
|
||||
break;
|
||||
case NEU_TYPE_BYTES:
|
||||
tag_json->t = NEU_JSON_BYTES;
|
||||
tag_json->value.val_bytes.length = tag_value->value.value.bytes.length;
|
||||
tag_json->value.val_bytes.bytes = tag_value->value.value.bytes.bytes;
|
||||
tag_json->t = NEU_JSON_ARRAY_UINT8;
|
||||
tag_json->value.val_array_uint8.length =
|
||||
tag_value->value.value.bytes.length;
|
||||
tag_json->value.val_array_uint8.u8s =
|
||||
tag_value->value.value.bytes.bytes;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_BOOL:
|
||||
tag_json->t = NEU_JSON_ARRAY_BOOL;
|
||||
tag_json->value.val_array_bool.length =
|
||||
tag_value->value.value.bools.length;
|
||||
tag_json->value.val_array_bool.bools =
|
||||
tag_value->value.value.bools.bools;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT8:
|
||||
tag_json->t = NEU_JSON_ARRAY_INT8;
|
||||
tag_json->value.val_array_int8.length =
|
||||
tag_value->value.value.i8s.length;
|
||||
tag_json->value.val_array_int8.i8s = tag_value->value.value.i8s.i8s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT8:
|
||||
tag_json->t = NEU_JSON_ARRAY_UINT8;
|
||||
tag_json->value.val_array_uint8.length =
|
||||
tag_value->value.value.u8s.length;
|
||||
tag_json->value.val_array_uint8.u8s = tag_value->value.value.u8s.u8s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT16:
|
||||
tag_json->t = NEU_JSON_ARRAY_INT16;
|
||||
tag_json->value.val_array_int16.length =
|
||||
tag_value->value.value.i16s.length;
|
||||
tag_json->value.val_array_int16.i16s = tag_value->value.value.i16s.i16s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT16:
|
||||
tag_json->t = NEU_JSON_ARRAY_UINT16;
|
||||
tag_json->value.val_array_uint16.length =
|
||||
tag_value->value.value.u16s.length;
|
||||
tag_json->value.val_array_uint16.u16s =
|
||||
tag_value->value.value.u16s.u16s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT32:
|
||||
tag_json->t = NEU_JSON_ARRAY_INT32;
|
||||
tag_json->value.val_array_int32.length =
|
||||
tag_value->value.value.i32s.length;
|
||||
tag_json->value.val_array_int32.i32s = tag_value->value.value.i32s.i32s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT32:
|
||||
tag_json->t = NEU_JSON_ARRAY_UINT32;
|
||||
tag_json->value.val_array_uint32.length =
|
||||
tag_value->value.value.u32s.length;
|
||||
tag_json->value.val_array_uint32.u32s =
|
||||
tag_value->value.value.u32s.u32s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT64:
|
||||
tag_json->t = NEU_JSON_ARRAY_INT64;
|
||||
tag_json->value.val_array_int64.length =
|
||||
tag_value->value.value.i64s.length;
|
||||
tag_json->value.val_array_int64.i64s = tag_value->value.value.i64s.i64s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT64:
|
||||
tag_json->t = NEU_JSON_ARRAY_UINT64;
|
||||
tag_json->value.val_array_uint64.length =
|
||||
tag_value->value.value.u64s.length;
|
||||
tag_json->value.val_array_uint64.u64s =
|
||||
tag_value->value.value.u64s.u64s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_FLOAT:
|
||||
tag_json->t = NEU_JSON_ARRAY_FLOAT;
|
||||
tag_json->value.val_array_float.length =
|
||||
tag_value->value.value.f32s.length;
|
||||
tag_json->value.val_array_float.f32s = tag_value->value.value.f32s.f32s;
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_DOUBLE:
|
||||
tag_json->t = NEU_JSON_ARRAY_DOUBLE;
|
||||
tag_json->value.val_array_double.length =
|
||||
tag_value->value.value.f64s.length;
|
||||
tag_json->value.val_array_double.f64s =
|
||||
tag_value->value.value.f64s.f64s;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -23,6 +23,12 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef enum {
|
||||
NEU_OTEL_STATUS_UNSET = 0,
|
||||
NEU_OTEL_STATUS_OK = 1,
|
||||
NEU_OTEL_STATUS_ERROR = 2,
|
||||
} neu_otel_status_code_e;
|
||||
|
||||
typedef void *neu_otel_trace_ctx;
|
||||
typedef void *neu_otel_scope_ctx;
|
||||
|
||||
@@ -34,11 +40,17 @@ neu_otel_trace_ctx neu_otel_find_trace(void *req_ctx);
|
||||
|
||||
void neu_otel_trace_set_final(neu_otel_trace_ctx ctx);
|
||||
|
||||
void neu_otel_trace_set_expected_span_num(neu_otel_trace_ctx ctx, uint32_t num);
|
||||
uint8_t *neu_otel_get_trace_id(neu_otel_trace_ctx ctx);
|
||||
|
||||
neu_otel_trace_ctx neu_otel_find_trace_by_id(const char *trace_id);
|
||||
|
||||
void neu_otel_free_trace(neu_otel_trace_ctx ctx);
|
||||
|
||||
neu_otel_scope_ctx neu_otel_add_span(neu_otel_trace_ctx ctx);
|
||||
neu_otel_scope_ctx neu_otel_add_span2(neu_otel_trace_ctx ctx,
|
||||
const char * span_name,
|
||||
const char * span_id);
|
||||
|
||||
void neu_otel_scope_set_parent_span_id(neu_otel_scope_ctx ctx,
|
||||
const char * parent_span_id);
|
||||
@@ -63,16 +75,24 @@ void neu_otel_scope_add_span_attr_string(neu_otel_scope_ctx ctx,
|
||||
void neu_otel_scope_add_span_attr_bool(neu_otel_scope_ctx ctx, const char *key,
|
||||
bool val);
|
||||
|
||||
void neu_otel_scope_set_span_start_time(neu_otel_scope_ctx ctx, int64_t ms);
|
||||
void neu_otel_scope_set_span_end_time(neu_otel_scope_ctx ctx, int64_t ms);
|
||||
void neu_otel_scope_set_span_start_time(neu_otel_scope_ctx ctx, int64_t ns);
|
||||
void neu_otel_scope_set_span_end_time(neu_otel_scope_ctx ctx, int64_t ns);
|
||||
|
||||
uint8_t *neu_otel_scope_get_pre_span_id(neu_otel_scope_ctx ctx);
|
||||
|
||||
void neu_otel_scope_set_status_code(neu_otel_scope_ctx ctx,
|
||||
neu_otel_status_code_e code,
|
||||
const char * desc);
|
||||
|
||||
void neu_otel_scope_set_status_code2(neu_otel_scope_ctx ctx,
|
||||
neu_otel_status_code_e code, int errorno);
|
||||
|
||||
int neu_otel_trace_pack_size(neu_otel_trace_ctx ctx);
|
||||
|
||||
int neu_otel_trace_pack(neu_otel_trace_ctx ctx, uint8_t *out);
|
||||
|
||||
void neu_otel_new_span_id(char *id);
|
||||
void neu_otel_new_trace_id(char *id);
|
||||
|
||||
void neu_otel_split_traceparent(const char *in, char *trace_id, char *span_id,
|
||||
uint32_t *flags);
|
||||
|
||||
+118
-16
@@ -52,6 +52,18 @@ typedef enum {
|
||||
NEU_TYPE_PTR = 19,
|
||||
NEU_TYPE_TIME = 20,
|
||||
NEU_TYPE_DATA_AND_TIME = 21,
|
||||
NEU_TYPE_ARRAY_CHAR = 22,
|
||||
NEU_TYPE_ARRAY_INT8 = 23,
|
||||
NEU_TYPE_ARRAY_UINT8 = 24,
|
||||
NEU_TYPE_ARRAY_INT16 = 25,
|
||||
NEU_TYPE_ARRAY_UINT16 = 26,
|
||||
NEU_TYPE_ARRAY_INT32 = 27,
|
||||
NEU_TYPE_ARRAY_UINT32 = 28,
|
||||
NEU_TYPE_ARRAY_INT64 = 29,
|
||||
NEU_TYPE_ARRAY_UINT64 = 30,
|
||||
NEU_TYPE_ARRAY_FLOAT = 31,
|
||||
NEU_TYPE_ARRAY_DOUBLE = 32,
|
||||
NEU_TYPE_ARRAY_BOOL = 33,
|
||||
} neu_type_e;
|
||||
|
||||
inline static const char *neu_type_string(neu_type_e type)
|
||||
@@ -99,6 +111,30 @@ inline static const char *neu_type_string(neu_type_e type)
|
||||
return "NEU_TYPE_TIME";
|
||||
case NEU_TYPE_DATA_AND_TIME:
|
||||
return "NEU_TYPE_DATA_AND_TIME";
|
||||
case NEU_TYPE_ARRAY_CHAR:
|
||||
return "NEU_TYPE_ARRAY_CHAR";
|
||||
case NEU_TYPE_ARRAY_INT8:
|
||||
return "NEU_TYPE_ARRAY_INT8";
|
||||
case NEU_TYPE_ARRAY_UINT8:
|
||||
return "NEU_TYPE_ARRAY_UINT8";
|
||||
case NEU_TYPE_ARRAY_INT16:
|
||||
return "NEU_TYPE_ARRAY_INT16";
|
||||
case NEU_TYPE_ARRAY_UINT16:
|
||||
return "NEU_TYPE_ARRAY_UINT16";
|
||||
case NEU_TYPE_ARRAY_INT32:
|
||||
return "NEU_TYPE_ARRAY_INT32";
|
||||
case NEU_TYPE_ARRAY_UINT32:
|
||||
return "NEU_TYPE_ARRAY_UINT32";
|
||||
case NEU_TYPE_ARRAY_INT64:
|
||||
return "NEU_TYPE_ARRAY_INT64";
|
||||
case NEU_TYPE_ARRAY_UINT64:
|
||||
return "NEU_TYPE_ARRAY_UINT64";
|
||||
case NEU_TYPE_ARRAY_FLOAT:
|
||||
return "NEU_TYPE_ARRAY_FLOAT";
|
||||
case NEU_TYPE_ARRAY_DOUBLE:
|
||||
return "NEU_TYPE_ARRAY_FLOAT";
|
||||
case NEU_TYPE_ARRAY_BOOL:
|
||||
return "NEU_TYPE_ARRAY_BOOL";
|
||||
}
|
||||
|
||||
return "";
|
||||
@@ -110,28 +146,94 @@ typedef struct {
|
||||
uint8_t * ptr;
|
||||
} neu_value_ptr_t;
|
||||
|
||||
#define NEU_VALUE_SIZE 128
|
||||
#define NEU_VALUE_SIZE 1024
|
||||
|
||||
typedef struct {
|
||||
uint8_t bytes[NEU_VALUE_SIZE];
|
||||
uint8_t length;
|
||||
} __attribute__((packed)) neu_value_bytes_t;
|
||||
} neu_value_bytes_t;
|
||||
|
||||
typedef struct {
|
||||
int8_t i8s[NEU_VALUE_SIZE];
|
||||
uint8_t length;
|
||||
} neu_value_array_int8_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t u8s[NEU_VALUE_SIZE];
|
||||
uint8_t length;
|
||||
} neu_value_array_uint8_t;
|
||||
|
||||
typedef struct {
|
||||
int16_t i16s[NEU_VALUE_SIZE];
|
||||
uint8_t length;
|
||||
} neu_value_array_int16_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t u16s[NEU_VALUE_SIZE];
|
||||
uint8_t length;
|
||||
} neu_value_array_uint16_t;
|
||||
|
||||
typedef struct {
|
||||
int32_t i32s[NEU_VALUE_SIZE];
|
||||
uint8_t length;
|
||||
} neu_value_array_int32_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t u32s[NEU_VALUE_SIZE];
|
||||
uint8_t length;
|
||||
} neu_value_array_uint32_t;
|
||||
|
||||
typedef struct {
|
||||
int64_t i64s[NEU_VALUE_SIZE];
|
||||
uint8_t length;
|
||||
} neu_value_array_int64_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t u64s[NEU_VALUE_SIZE];
|
||||
uint8_t length;
|
||||
} neu_value_array_uint64_t;
|
||||
|
||||
typedef struct {
|
||||
float f32s[NEU_VALUE_SIZE];
|
||||
uint8_t length;
|
||||
} neu_value_array_float_t;
|
||||
|
||||
typedef struct {
|
||||
double f64s[NEU_VALUE_SIZE];
|
||||
uint8_t length;
|
||||
} neu_value_array_double_t;
|
||||
|
||||
typedef struct {
|
||||
bool bools[NEU_VALUE_SIZE];
|
||||
uint8_t length;
|
||||
} neu_value_array_bool_t;
|
||||
|
||||
typedef union {
|
||||
bool boolean;
|
||||
int8_t i8;
|
||||
uint8_t u8;
|
||||
int16_t i16;
|
||||
uint16_t u16;
|
||||
int32_t i32;
|
||||
uint32_t u32;
|
||||
int64_t i64;
|
||||
uint64_t u64;
|
||||
float f32;
|
||||
double d64;
|
||||
char str[NEU_VALUE_SIZE];
|
||||
neu_value_bytes_t bytes;
|
||||
neu_value_ptr_t ptr;
|
||||
bool boolean;
|
||||
int8_t i8;
|
||||
uint8_t u8;
|
||||
int16_t i16;
|
||||
uint16_t u16;
|
||||
int32_t i32;
|
||||
uint32_t u32;
|
||||
int64_t i64;
|
||||
uint64_t u64;
|
||||
float f32;
|
||||
double d64;
|
||||
char str[NEU_VALUE_SIZE];
|
||||
neu_value_bytes_t bytes;
|
||||
neu_value_ptr_t ptr;
|
||||
neu_value_array_int8_t i8s;
|
||||
neu_value_array_uint8_t u8s;
|
||||
neu_value_array_int16_t i16s;
|
||||
neu_value_array_uint16_t u16s;
|
||||
neu_value_array_int32_t i32s;
|
||||
neu_value_array_uint32_t u32s;
|
||||
neu_value_array_int64_t i64s;
|
||||
neu_value_array_uint64_t u64s;
|
||||
neu_value_array_float_t f32s;
|
||||
neu_value_array_double_t f64s;
|
||||
neu_value_array_bool_t bools;
|
||||
} neu_value_u;
|
||||
|
||||
static inline char *neu_value_str(neu_type_e type, neu_value_u value)
|
||||
|
||||
@@ -35,6 +35,13 @@ static inline int64_t neu_time_ms()
|
||||
return (int64_t) tv.tv_sec * 1000 + (int64_t) tv.tv_usec / 1000;
|
||||
}
|
||||
|
||||
static inline int64_t neu_time_ns()
|
||||
{
|
||||
struct timespec ts = { 0 };
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
return (int64_t) ts.tv_sec * 1000000000 + (int64_t) ts.tv_nsec;
|
||||
}
|
||||
|
||||
static inline void neu_msleep(unsigned msec)
|
||||
{
|
||||
struct timespec tv = {
|
||||
|
||||
@@ -51,8 +51,6 @@ cp persistence/*.sql ${package_name}/config/
|
||||
cp sdk-zlog.conf ${package_name}/config/
|
||||
cp zlog.conf ${package_name}/config/
|
||||
cp dev.conf ${package_name}/config/
|
||||
cp neuron.key ${package_name}/config/
|
||||
cp neuron.pem ${package_name}/config/
|
||||
cp default_plugins.json ${package_name}/config/
|
||||
cp neuron.json ${package_name}/config/
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
BEGIN TRANSACTION;
|
||||
|
||||
ALTER TABLE tags RENAME TO temp_tags;
|
||||
|
||||
-- add bias column
|
||||
CREATE TABLE
|
||||
IF NOT EXISTS tags (
|
||||
driver_name TEXT NOT NULL,
|
||||
group_name TEXT NOT NULL,
|
||||
name TEXT NULL check (length (name) <= 128),
|
||||
address TEXT NULL check (length (address) <= 128),
|
||||
attribute INTEGER NOT NULL check (attribute BETWEEN 0 AND 15),
|
||||
precision INTEGER NOT NULL check (precision BETWEEN 0 AND 17),
|
||||
decimal REAL NOT NULL,
|
||||
bias REAL NOT NULL check (bias BETWEEN -1000 AND 1000),
|
||||
type INTEGER NOT NULL check (type BETWEEN 0 AND 40),
|
||||
description TEXT NULL check (length (description) <= 512),
|
||||
value TEXT,
|
||||
UNIQUE (driver_name, group_name, name),
|
||||
FOREIGN KEY (driver_name, group_name) REFERENCES groups (driver_name, name) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
|
||||
INSERT INTO tags SELECT * FROM temp_tags;
|
||||
DROP TABLE temp_tags;
|
||||
COMMIT;
|
||||
@@ -314,9 +314,9 @@ static int ekuiper_plugin_request(neu_plugin_t * plugin,
|
||||
NEU_NODE_LINK_STATE_DISCONNECTED == plugin->common.link_state;
|
||||
nng_mtx_unlock(plugin->mtx);
|
||||
|
||||
neu_otel_trace_ctx *trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
if (neu_otel_control_is_started()) {
|
||||
neu_otel_trace_ctx trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
if (neu_otel_control_is_started() && header->ctx) {
|
||||
trace = neu_otel_find_trace(header->ctx);
|
||||
if (trace) {
|
||||
scope = neu_otel_add_span(trace);
|
||||
@@ -330,7 +330,7 @@ static int ekuiper_plugin_request(neu_plugin_t * plugin,
|
||||
}
|
||||
neu_otel_scope_add_span_attr_int(scope, "thread id",
|
||||
(int64_t)(pthread_self()));
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ns());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,8 +339,14 @@ static int ekuiper_plugin_request(neu_plugin_t * plugin,
|
||||
neu_resp_error_t *error = (neu_resp_error_t *) data;
|
||||
plog_debug(plugin, "receive resp errcode: %d", error->error);
|
||||
if (trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", error->error);
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ms());
|
||||
if (error->error != NEU_ERR_SUCCESS) {
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_ERROR,
|
||||
error->error);
|
||||
} else {
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK,
|
||||
error->error);
|
||||
}
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
if (header->ctx) {
|
||||
@@ -361,6 +367,29 @@ static int ekuiper_plugin_request(neu_plugin_t * plugin,
|
||||
|
||||
if (disconnected) {
|
||||
plog_debug(plugin, "not connected");
|
||||
|
||||
neu_otel_trace_ctx trans_trace = NULL;
|
||||
neu_otel_scope_ctx trans_scope = NULL;
|
||||
if (neu_otel_data_is_started() && trans_data->trace_ctx) {
|
||||
trans_trace = neu_otel_find_trace(trans_data->trace_ctx);
|
||||
if (trans_trace) {
|
||||
char new_span_id[36] = { 0 };
|
||||
neu_otel_new_span_id(new_span_id);
|
||||
trans_scope = neu_otel_add_span2(
|
||||
trans_trace, "ekuiper send", new_span_id);
|
||||
neu_otel_scope_add_span_attr_int(trans_scope, "thread id",
|
||||
(int64_t)(pthread_self()));
|
||||
neu_otel_scope_set_status_code2(
|
||||
trans_scope, NEU_OTEL_STATUS_ERROR,
|
||||
NEU_ERR_PLUGIN_DISCONNECTED);
|
||||
neu_otel_scope_set_span_start_time(trans_scope,
|
||||
neu_time_ns());
|
||||
neu_otel_scope_set_span_end_time(trans_scope,
|
||||
neu_time_ns());
|
||||
neu_otel_trace_set_final(trans_trace);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
send_data(plugin, trans_data);
|
||||
}
|
||||
|
||||
+132
-34
@@ -20,6 +20,7 @@
|
||||
#include <nng/nng.h>
|
||||
|
||||
#include "neuron.h"
|
||||
#include "otel/otel_manager.h"
|
||||
#include "json/neu_json_fn.h"
|
||||
#include "json/neu_json_rw.h"
|
||||
|
||||
@@ -34,6 +35,40 @@ static int send_write_tags_req(neu_plugin_t * plugin,
|
||||
bool trace_flag, uint8_t *trace_id,
|
||||
uint8_t *span_id);
|
||||
|
||||
static int hex_char_to_int(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int hex_string_to_binary(const char * hex_string,
|
||||
unsigned char *binary_array, int max_length)
|
||||
{
|
||||
int length = strlen(hex_string);
|
||||
if (length % 2 != 0 || length <= 0)
|
||||
return -1;
|
||||
|
||||
int binary_length = length / 2;
|
||||
if (binary_length > max_length)
|
||||
return -1;
|
||||
|
||||
for (int i = 0; i < binary_length; i++) {
|
||||
int high_nibble = hex_char_to_int(hex_string[2 * i]);
|
||||
int low_nibble = hex_char_to_int(hex_string[2 * i + 1]);
|
||||
if (high_nibble == -1 || low_nibble == -1)
|
||||
return -1;
|
||||
|
||||
binary_array[i] = (high_nibble << 4) | low_nibble;
|
||||
}
|
||||
|
||||
return binary_length;
|
||||
}
|
||||
|
||||
static void byte_to_hex(unsigned char byte, char *hex)
|
||||
{
|
||||
static const char hex_chars[] = "0123456789ABCDEF";
|
||||
@@ -57,39 +92,87 @@ void send_data(neu_plugin_t *plugin, neu_reqresp_trans_data_t *trans_data)
|
||||
.plugin = plugin,
|
||||
.trans_data = trans_data,
|
||||
};
|
||||
rv = neu_json_encode_by_fn(&resp, json_encode_read_resp, &json_str);
|
||||
if (0 != rv) {
|
||||
plog_error(plugin, "fail encode trans data to json");
|
||||
return;
|
||||
|
||||
neu_otel_trace_ctx trans_trace = NULL;
|
||||
neu_otel_scope_ctx trans_scope = NULL;
|
||||
uint8_t * trace_id = NULL;
|
||||
char new_span_id[36] = { 0 };
|
||||
if (neu_otel_data_is_started() && trans_data->trace_ctx) {
|
||||
trans_trace = neu_otel_find_trace(trans_data->trace_ctx);
|
||||
if (trans_trace) {
|
||||
neu_otel_new_span_id(new_span_id);
|
||||
trans_scope =
|
||||
neu_otel_add_span2(trans_trace, "ekuiper send", new_span_id);
|
||||
neu_otel_scope_add_span_attr_int(trans_scope, "thread id",
|
||||
(int64_t)(pthread_self()));
|
||||
neu_otel_scope_set_span_start_time(trans_scope, neu_time_ns());
|
||||
}
|
||||
}
|
||||
|
||||
nng_msg *msg = NULL;
|
||||
size_t json_len = strlen(json_str);
|
||||
rv = nng_msg_alloc(&msg, json_len);
|
||||
if (0 != rv) {
|
||||
plog_error(plugin, "nng cannot allocate msg");
|
||||
do {
|
||||
|
||||
rv = neu_json_encode_by_fn(&resp, json_encode_read_resp, &json_str);
|
||||
if (0 != rv) {
|
||||
plog_error(plugin, "fail encode trans data to json");
|
||||
break;
|
||||
}
|
||||
|
||||
nng_msg *msg = NULL;
|
||||
size_t json_len = strlen(json_str);
|
||||
size_t trace_header_len = 0;
|
||||
if (neu_otel_data_is_started() && trans_data->trace_ctx) {
|
||||
trace_header_len = 26;
|
||||
}
|
||||
|
||||
rv = nng_msg_alloc(&msg, json_len + trace_header_len);
|
||||
if (0 != rv) {
|
||||
plog_error(plugin, "nng cannot allocate msg");
|
||||
free(json_str);
|
||||
break;
|
||||
}
|
||||
|
||||
if (trans_trace) {
|
||||
trace_id = neu_otel_get_trace_id(trans_trace);
|
||||
uint8_t span_id[8] = { 0 };
|
||||
hex_string_to_binary(new_span_id, span_id, 8);
|
||||
uint16_t tarce_header_magic = 0xCE0A;
|
||||
memcpy(nng_msg_body(msg), &tarce_header_magic, 2);
|
||||
memcpy(nng_msg_body(msg) + 2, trace_id, 16);
|
||||
memcpy(nng_msg_body(msg) + 2 + 16, span_id, 8);
|
||||
}
|
||||
|
||||
memcpy(nng_msg_body(msg) + trace_header_len, json_str,
|
||||
json_len); // no null byte
|
||||
plog_debug(plugin, ">> %s", json_str);
|
||||
free(json_str);
|
||||
return;
|
||||
}
|
||||
rv = nng_sendmsg(plugin->sock, msg,
|
||||
NNG_FLAG_NONBLOCK); // TODO: use aio to send message
|
||||
if (0 == rv) {
|
||||
NEU_PLUGIN_UPDATE_METRIC(plugin, NEU_METRIC_SEND_MSGS_TOTAL, 1,
|
||||
NULL);
|
||||
NEU_PLUGIN_UPDATE_METRIC(plugin, NEU_METRIC_SEND_BYTES_5S, json_len,
|
||||
NULL);
|
||||
NEU_PLUGIN_UPDATE_METRIC(plugin, NEU_METRIC_SEND_BYTES_30S,
|
||||
json_len, NULL);
|
||||
NEU_PLUGIN_UPDATE_METRIC(plugin, NEU_METRIC_SEND_BYTES_60S,
|
||||
json_len, NULL);
|
||||
} else {
|
||||
plog_error(plugin, "nng cannot send msg: %s", nng_strerror(rv));
|
||||
nng_msg_free(msg);
|
||||
NEU_PLUGIN_UPDATE_METRIC(plugin, NEU_METRIC_SEND_MSG_ERRORS_TOTAL,
|
||||
1, NULL);
|
||||
}
|
||||
} while (0);
|
||||
|
||||
memcpy(nng_msg_body(msg), json_str, json_len); // no null byte
|
||||
plog_debug(plugin, ">> %s", json_str);
|
||||
free(json_str);
|
||||
rv = nng_sendmsg(plugin->sock, msg,
|
||||
NNG_FLAG_NONBLOCK); // TODO: use aio to send message
|
||||
if (0 == rv) {
|
||||
NEU_PLUGIN_UPDATE_METRIC(plugin, NEU_METRIC_SEND_MSGS_TOTAL, 1, NULL);
|
||||
NEU_PLUGIN_UPDATE_METRIC(plugin, NEU_METRIC_SEND_BYTES_5S, json_len,
|
||||
NULL);
|
||||
NEU_PLUGIN_UPDATE_METRIC(plugin, NEU_METRIC_SEND_BYTES_30S, json_len,
|
||||
NULL);
|
||||
NEU_PLUGIN_UPDATE_METRIC(plugin, NEU_METRIC_SEND_BYTES_60S, json_len,
|
||||
NULL);
|
||||
} else {
|
||||
plog_error(plugin, "nng cannot send msg: %s", nng_strerror(rv));
|
||||
nng_msg_free(msg);
|
||||
NEU_PLUGIN_UPDATE_METRIC(plugin, NEU_METRIC_SEND_MSG_ERRORS_TOTAL, 1,
|
||||
NULL);
|
||||
if (trans_trace) {
|
||||
if (rv == 0) {
|
||||
neu_otel_scope_set_status_code2(trans_scope, NEU_OTEL_STATUS_OK, 0);
|
||||
} else {
|
||||
neu_otel_scope_set_status_code(trans_scope, NEU_OTEL_STATUS_ERROR,
|
||||
nng_strerror(rv));
|
||||
}
|
||||
neu_otel_scope_set_span_end_time(trans_scope, neu_time_ns());
|
||||
neu_otel_trace_set_final(trans_trace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,11 +269,26 @@ static int json_value_to_tag_value(union neu_json_value *req,
|
||||
value->type = NEU_TYPE_BOOL;
|
||||
value->value.boolean = req->val_bool;
|
||||
break;
|
||||
case NEU_JSON_BYTES:
|
||||
value->type = NEU_TYPE_BYTES;
|
||||
value->value.bytes.length = req->val_bytes.length;
|
||||
memcpy(value->value.bytes.bytes, req->val_bytes.bytes,
|
||||
req->val_bytes.length);
|
||||
case NEU_JSON_ARRAY_BOOL:
|
||||
value->type = NEU_TYPE_ARRAY_BOOL;
|
||||
value->value.bools.length = req->val_array_bool.length;
|
||||
for (int i = 0; i < req->val_array_bool.length; i++) {
|
||||
value->value.bools.bools[i] = req->val_array_bool.bools[i];
|
||||
}
|
||||
break;
|
||||
case NEU_JSON_ARRAY_INT64:
|
||||
value->type = NEU_TYPE_ARRAY_INT64;
|
||||
value->value.i64s.length = req->val_array_int64.length;
|
||||
for (int i = 0; i < req->val_array_int64.length; i++) {
|
||||
value->value.i64s.i64s[i] = req->val_array_int64.i64s[i];
|
||||
}
|
||||
break;
|
||||
case NEU_JSON_ARRAY_DOUBLE:
|
||||
value->type = NEU_TYPE_ARRAY_DOUBLE;
|
||||
value->value.f64s.length = req->val_array_double.length;
|
||||
for (int i = 0; i < req->val_array_double.length; i++) {
|
||||
value->value.f64s.f64s[i] = req->val_array_double.f64s[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
|
||||
@@ -190,18 +190,13 @@ static int driver_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group)
|
||||
}
|
||||
} else {
|
||||
char *buf = calloc(1, 1024);
|
||||
int ret = fread(buf, 1024, 1, fp);
|
||||
int ret = fread(buf, 1, 1024, fp);
|
||||
if (ret < 0) {
|
||||
dvalue.type = NEU_TYPE_ERROR;
|
||||
dvalue.value.i32 = NEU_ERR_FILE_READ_FAILURE;
|
||||
} else if (ret < NEU_VALUE_SIZE) {
|
||||
dvalue.type = NEU_TYPE_STRING;
|
||||
strcpy(dvalue.value.str, buf);
|
||||
} else {
|
||||
dvalue.type = NEU_TYPE_PTR;
|
||||
dvalue.value.ptr.type = NEU_TYPE_STRING;
|
||||
dvalue.value.ptr.length = ret;
|
||||
dvalue.value.ptr.ptr = (uint8_t *) strdup(buf);
|
||||
dvalue.type = NEU_TYPE_STRING;
|
||||
strncpy(dvalue.value.str, buf, NEU_VALUE_SIZE - 1);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
@@ -78,6 +78,61 @@
|
||||
"max": 30000
|
||||
}
|
||||
},
|
||||
"device_degrade": {
|
||||
"name": "Device Degradation",
|
||||
"name_zh": "设备降级",
|
||||
"description": "Enable or disable device degradation mechanism",
|
||||
"description_zh": "启用或禁用设备降级机制",
|
||||
"attribute": "required",
|
||||
"type": "map",
|
||||
"default": 0,
|
||||
"valid": {
|
||||
"map": [
|
||||
{
|
||||
"key": "False",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"key": "True",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"degrade_cycle": {
|
||||
"name": "Failure Threshold for Degradation",
|
||||
"name_zh": "降级失败阈值",
|
||||
"description": "The number of consecutive failure cycles required to trigger device degradation",
|
||||
"description_zh": "触发设备降级所需的连续失败周期数",
|
||||
"attribute": "required",
|
||||
"type": "int",
|
||||
"default": 2,
|
||||
"valid": {
|
||||
"min": 1,
|
||||
"max": 65535
|
||||
},
|
||||
"condition": {
|
||||
"field": "device_degrade",
|
||||
"value": 1
|
||||
}
|
||||
},
|
||||
"degrade_time": {
|
||||
"name": "Recovery Time After Degradation",
|
||||
"name_zh": "降级恢复时间",
|
||||
"description": "The time in seconds after which the device recovers from degradation",
|
||||
"description_zh": "设备从降级中恢复所需的时间(单位:秒)",
|
||||
"attribute": "required",
|
||||
"type": "int",
|
||||
"default": 600,
|
||||
"valid": {
|
||||
"min": 1,
|
||||
"max": 65535
|
||||
},
|
||||
"condition": {
|
||||
"field": "device_degrade",
|
||||
"value": 1
|
||||
}
|
||||
},
|
||||
"max_retries": {
|
||||
"name": "Maximum Retry Times",
|
||||
"name_zh": "最大重试次数",
|
||||
@@ -102,6 +157,56 @@
|
||||
"max": 10000
|
||||
}
|
||||
},
|
||||
"endianess": {
|
||||
"name": "Endianess",
|
||||
"name_zh": "字节序",
|
||||
"description": "Tag byte order, ABCD corresponds to 1234",
|
||||
"description_zh": "点位字节序,ABCD 对应 1234",
|
||||
"attribute": "required",
|
||||
"type": "map",
|
||||
"default": 1,
|
||||
"valid": {
|
||||
"map": [
|
||||
{
|
||||
"key": "ABCD",
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"key": "BADC",
|
||||
"value": 2
|
||||
},
|
||||
{
|
||||
"key": "DCBA",
|
||||
"value": 3
|
||||
},
|
||||
{
|
||||
"key": "CDAB",
|
||||
"value": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"address_base": {
|
||||
"name": "Start Address",
|
||||
"name_zh": "开始地址",
|
||||
"description": "Address starts from 1 or 0",
|
||||
"description_zh": "地址从 1 开始或从 0 开始",
|
||||
"attribute": "required",
|
||||
"type": "map",
|
||||
"default": 1,
|
||||
"valid": {
|
||||
"map": [
|
||||
{
|
||||
"key": "Protocol Addresses (Base 0)",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"key": "PLC Addresses (Base 1)",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"interval": {
|
||||
"name": "Send Interval (ms)",
|
||||
"name_zh": "指令发送间隔 (ms)",
|
||||
|
||||
@@ -86,6 +86,61 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"device_degrade": {
|
||||
"name": "Device Degradation",
|
||||
"name_zh": "设备降级",
|
||||
"description": "Enable or disable device degradation mechanism",
|
||||
"description_zh": "启用或禁用设备降级机制",
|
||||
"attribute": "required",
|
||||
"type": "map",
|
||||
"default": 0,
|
||||
"valid": {
|
||||
"map": [
|
||||
{
|
||||
"key": "False",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"key": "True",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"degrade_cycle": {
|
||||
"name": "Failure Threshold for Degradation",
|
||||
"name_zh": "降级失败阈值",
|
||||
"description": "The number of consecutive failure cycles required to trigger device degradation",
|
||||
"description_zh": "触发设备降级所需的连续失败周期数",
|
||||
"attribute": "required",
|
||||
"type": "int",
|
||||
"default": 2,
|
||||
"valid": {
|
||||
"min": 1,
|
||||
"max": 65535
|
||||
},
|
||||
"condition": {
|
||||
"field": "device_degrade",
|
||||
"value": 1
|
||||
}
|
||||
},
|
||||
"degrade_time": {
|
||||
"name": "Recovery Time After Degradation",
|
||||
"name_zh": "降级恢复时间",
|
||||
"description": "The time in seconds after which the device recovers from degradation",
|
||||
"description_zh": "设备从降级中恢复所需的时间(单位:秒)",
|
||||
"attribute": "required",
|
||||
"type": "int",
|
||||
"default": 600,
|
||||
"valid": {
|
||||
"min": 1,
|
||||
"max": 65535
|
||||
},
|
||||
"condition": {
|
||||
"field": "device_degrade",
|
||||
"value": 1
|
||||
}
|
||||
},
|
||||
"max_retries": {
|
||||
"name": "Maximum Retry Times",
|
||||
"name_zh": "最大重试次数",
|
||||
@@ -110,6 +165,56 @@
|
||||
"max": 10000
|
||||
}
|
||||
},
|
||||
"endianess": {
|
||||
"name": "Endianess",
|
||||
"name_zh": "字节序",
|
||||
"description": "Tag byte order, ABCD corresponds to 1234",
|
||||
"description_zh": "点位字节序,ABCD 对应 1234",
|
||||
"attribute": "required",
|
||||
"type": "map",
|
||||
"default": 1,
|
||||
"valid": {
|
||||
"map": [
|
||||
{
|
||||
"key": "ABCD",
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"key": "BADC",
|
||||
"value": 2
|
||||
},
|
||||
{
|
||||
"key": "DCBA",
|
||||
"value": 3
|
||||
},
|
||||
{
|
||||
"key": "CDAB",
|
||||
"value": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"address_base": {
|
||||
"name": "Start Address",
|
||||
"name_zh": "开始地址",
|
||||
"description": "Address starts from 1 or 0",
|
||||
"description_zh": "地址从 1 开始或从 0 开始",
|
||||
"attribute": "required",
|
||||
"type": "map",
|
||||
"default": 1,
|
||||
"valid": {
|
||||
"map": [
|
||||
{
|
||||
"key": "Protocol Addresses (Base 0)",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"key": "PLC Addresses (Base 1)",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"interval": {
|
||||
"name": "Send Interval (ms)",
|
||||
"name_zh": "指令发送间隔 (ms)",
|
||||
|
||||
@@ -66,6 +66,18 @@ typedef enum modbus_area {
|
||||
MODBUS_AREA_HOLD_REGISTER = 4,
|
||||
} modbus_area_e;
|
||||
|
||||
typedef enum modbus_endianess {
|
||||
MODBUS_ABCD = 1,
|
||||
MODBUS_BADC = 2,
|
||||
MODBUS_DCBA = 3,
|
||||
MODBUS_CDAB = 4,
|
||||
} modbus_endianess;
|
||||
|
||||
typedef enum modbus_address_base {
|
||||
base_0 = 0,
|
||||
base_1 = 1,
|
||||
} modbus_address_base;
|
||||
|
||||
struct modbus_header {
|
||||
uint16_t seq;
|
||||
uint16_t protocol;
|
||||
|
||||
@@ -35,7 +35,8 @@ static int tag_cmp_write(neu_tag_sort_elem_t *tag1, neu_tag_sort_elem_t *tag2);
|
||||
static bool tag_sort_write(neu_tag_sort_t *sort, void *tag,
|
||||
void *tag_to_be_sorted);
|
||||
|
||||
int modbus_tag_to_point(const neu_datatag_t *tag, modbus_point_t *point)
|
||||
int modbus_tag_to_point(const neu_datatag_t *tag, modbus_point_t *point,
|
||||
modbus_address_base address_base)
|
||||
{
|
||||
int ret = NEU_ERR_SUCCESS;
|
||||
uint32_t start_address = 0;
|
||||
@@ -47,13 +48,18 @@ int modbus_tag_to_point(const neu_datatag_t *tag, modbus_point_t *point)
|
||||
char area = 0;
|
||||
int n = sscanf(tag->address, "%hhu!%c%u", &point->slave_id, &area,
|
||||
&start_address);
|
||||
if (n != 3 || start_address == 0) {
|
||||
if (n != 3) {
|
||||
return NEU_ERR_TAG_ADDRESS_FORMAT_INVALID;
|
||||
}
|
||||
|
||||
point->start_address = (uint16_t) start_address;
|
||||
if (start_address == 65536 && address_base == 0) {
|
||||
point->start_address = 65535;
|
||||
} else if (start_address == 0 && address_base == 1) {
|
||||
point->start_address = 0;
|
||||
} else {
|
||||
point->start_address = (uint16_t) start_address - address_base;
|
||||
}
|
||||
|
||||
point->start_address -= 1;
|
||||
point->type = tag->type;
|
||||
|
||||
switch (area) {
|
||||
@@ -194,10 +200,11 @@ int modbus_tag_to_point(const neu_datatag_t *tag, modbus_point_t *point)
|
||||
}
|
||||
|
||||
int modbus_write_tag_to_point(const neu_plugin_tag_value_t *tag,
|
||||
modbus_point_write_t * point)
|
||||
modbus_point_write_t * point,
|
||||
modbus_address_base address_base)
|
||||
{
|
||||
int ret = NEU_ERR_SUCCESS;
|
||||
ret = modbus_tag_to_point(tag->tag, &point->point);
|
||||
ret = modbus_tag_to_point(tag->tag, &point->point, address_base);
|
||||
point->value = tag->value;
|
||||
return ret;
|
||||
}
|
||||
@@ -230,7 +237,8 @@ modbus_read_cmd_sort_t *modbus_tag_sort(UT_array *tags, uint16_t max_byte)
|
||||
return sort_result;
|
||||
}
|
||||
|
||||
int cal_n_byte(int type, neu_value_u *value, neu_datatag_addr_option_u option)
|
||||
int cal_n_byte(int type, neu_value_u *value, neu_datatag_addr_option_u option,
|
||||
modbus_endianess endianess, bool default_tag_endian)
|
||||
{
|
||||
int n = 0;
|
||||
switch (type) {
|
||||
@@ -242,6 +250,9 @@ int cal_n_byte(int type, neu_value_u *value, neu_datatag_addr_option_u option)
|
||||
case NEU_TYPE_FLOAT:
|
||||
case NEU_TYPE_UINT32:
|
||||
case NEU_TYPE_INT32:
|
||||
if (default_tag_endian) {
|
||||
modbus_convert_endianess(value, endianess);
|
||||
}
|
||||
n = sizeof(uint32_t);
|
||||
value->u32 = htonl(value->u32);
|
||||
break;
|
||||
@@ -282,7 +293,8 @@ int cal_n_byte(int type, neu_value_u *value, neu_datatag_addr_option_u option)
|
||||
return n;
|
||||
}
|
||||
|
||||
modbus_write_cmd_sort_t *modbus_write_tags_sort(UT_array *tags)
|
||||
modbus_write_cmd_sort_t *modbus_write_tags_sort(UT_array * tags,
|
||||
modbus_endianess endianess)
|
||||
{
|
||||
neu_tag_sort_result_t *result =
|
||||
neu_tag_sort(tags, tag_sort_write, tag_cmp_write);
|
||||
@@ -304,14 +316,17 @@ modbus_write_cmd_sort_t *modbus_write_tags_sort(UT_array *tags)
|
||||
utarray_foreach(result->sorts[i].tags, modbus_point_write_t **, tag_s)
|
||||
{
|
||||
if ((*tag_s)->point.area == MODBUS_AREA_COIL) {
|
||||
n_byte_tag = cal_n_byte((*tag_s)->point.type, &(*tag_s)->value,
|
||||
(*tag_s)->point.option);
|
||||
n_byte_tag =
|
||||
cal_n_byte((*tag_s)->point.type, &(*tag_s)->value,
|
||||
(*tag_s)->point.option, endianess, true);
|
||||
data_bit[k / 8] += ((*tag_s)->value.i8) << k % 8;
|
||||
n_byte += n_byte_tag;
|
||||
k++;
|
||||
} else {
|
||||
n_byte_tag = cal_n_byte((*tag_s)->point.type, &(*tag_s)->value,
|
||||
(*tag_s)->point.option);
|
||||
n_byte_tag =
|
||||
cal_n_byte((*tag_s)->point.type, &(*tag_s)->value,
|
||||
(*tag_s)->point.option, endianess,
|
||||
(*tag_s)->point.option.value32.is_default);
|
||||
memcpy(sort_result->cmd[i].bytes +
|
||||
2 *
|
||||
((*tag_s)->point.start_address -
|
||||
@@ -521,4 +536,26 @@ static bool tag_sort_write(neu_tag_sort_t *sort, void *tag,
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void modbus_convert_endianess(neu_value_u *value, modbus_endianess endianess)
|
||||
{
|
||||
switch (endianess) {
|
||||
case MODBUS_ABCD:
|
||||
break;
|
||||
case MODBUS_CDAB:
|
||||
value->u32 = htonl(value->u32);
|
||||
neu_ntohs_p((uint16_t *) value->bytes.bytes);
|
||||
neu_ntohs_p((uint16_t *) (value->bytes.bytes + 2));
|
||||
break;
|
||||
case MODBUS_BADC:
|
||||
neu_ntohs_p((uint16_t *) value->bytes.bytes);
|
||||
neu_ntohs_p((uint16_t *) (value->bytes.bytes + 2));
|
||||
break;
|
||||
case MODBUS_DCBA:
|
||||
value->u32 = htonl(value->u32);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -45,9 +45,11 @@ typedef struct modbus_point_write {
|
||||
neu_value_u value;
|
||||
} modbus_point_write_t;
|
||||
|
||||
int modbus_tag_to_point(const neu_datatag_t *tag, modbus_point_t *point);
|
||||
int modbus_tag_to_point(const neu_datatag_t *tag, modbus_point_t *point,
|
||||
modbus_address_base address_base);
|
||||
int modbus_write_tag_to_point(const neu_plugin_tag_value_t *tag,
|
||||
modbus_point_write_t * point);
|
||||
modbus_point_write_t * point,
|
||||
modbus_address_base address_base);
|
||||
|
||||
typedef struct modbus_read_cmd {
|
||||
uint8_t slave_id;
|
||||
@@ -80,9 +82,12 @@ typedef struct modbus_write_cmd_sort {
|
||||
} modbus_write_cmd_sort_t;
|
||||
|
||||
modbus_read_cmd_sort_t * modbus_tag_sort(UT_array *tags, uint16_t max_byte);
|
||||
modbus_write_cmd_sort_t *modbus_write_tags_sort(UT_array *tags);
|
||||
modbus_write_cmd_sort_t *modbus_write_tags_sort(UT_array * tags,
|
||||
modbus_endianess endianess);
|
||||
void modbus_tag_sort_free(modbus_read_cmd_sort_t *cs);
|
||||
|
||||
void modbus_convert_endianess(neu_value_u *value, modbus_endianess endianess);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
+126
-48
@@ -23,10 +23,16 @@
|
||||
|
||||
#include "modbus_req.h"
|
||||
|
||||
#define MAX_SLAVES 256
|
||||
|
||||
uint8_t failed_cycles[MAX_SLAVES];
|
||||
bool skip[MAX_SLAVES];
|
||||
|
||||
struct modbus_group_data {
|
||||
UT_array * tags;
|
||||
char * group;
|
||||
modbus_read_cmd_sort_t *cmd_sort;
|
||||
modbus_address_base address_base;
|
||||
};
|
||||
|
||||
struct modbus_write_tags_data {
|
||||
@@ -107,6 +113,8 @@ int modbus_send_msg(void *ctx, uint16_t n_byte, uint8_t *bytes)
|
||||
neu_plugin_t *plugin = (neu_plugin_t *) ctx;
|
||||
int ret = 0;
|
||||
|
||||
neu_conn_clear_recv_buffer(plugin->conn);
|
||||
|
||||
plog_send_protocol(plugin, bytes, n_byte);
|
||||
|
||||
if (plugin->is_server) {
|
||||
@@ -141,7 +149,7 @@ void handle_modbus_error(neu_plugin_t *plugin, struct modbus_group_data *gd,
|
||||
const char *error_message)
|
||||
{
|
||||
modbus_value_handle(plugin, gd->cmd_sort->cmd[cmd_index].slave_id, 0, NULL,
|
||||
error_code);
|
||||
error_code, NULL);
|
||||
if (error_message) {
|
||||
plog_error(plugin, "%s, skip, %hhu!%hu", error_message,
|
||||
gd->cmd_sort->cmd[cmd_index].slave_id,
|
||||
@@ -152,7 +160,8 @@ void handle_modbus_error(neu_plugin_t *plugin, struct modbus_group_data *gd,
|
||||
void finalize_modbus_read_result(neu_plugin_t * plugin,
|
||||
struct modbus_group_data *gd,
|
||||
uint16_t cmd_index, int ret_r, int ret_buf,
|
||||
uint64_t read_tms, int64_t *rtt)
|
||||
uint64_t read_tms, int64_t *rtt,
|
||||
bool *slave_err)
|
||||
{
|
||||
if (ret_r <= 0) {
|
||||
handle_modbus_error(plugin, gd, cmd_index, NEU_ERR_PLUGIN_DISCONNECTED,
|
||||
@@ -166,6 +175,7 @@ void finalize_modbus_read_result(neu_plugin_t * plugin,
|
||||
NEU_ERR_PLUGIN_DEVICE_NOT_RESPONSE,
|
||||
"no modbus response received");
|
||||
*rtt = neu_time_ms() - read_tms;
|
||||
slave_err[gd->cmd_sort->cmd[cmd_index].slave_id] = true;
|
||||
break;
|
||||
case -1:
|
||||
handle_modbus_error(plugin, gd, cmd_index,
|
||||
@@ -185,12 +195,13 @@ void finalize_modbus_read_result(neu_plugin_t * plugin,
|
||||
}
|
||||
} else {
|
||||
*rtt = neu_time_ms() - read_tms;
|
||||
failed_cycles[gd->cmd_sort->cmd[cmd_index].slave_id] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void check_modbus_read_result(neu_plugin_t * plugin,
|
||||
struct modbus_group_data *gd, uint16_t cmd_index,
|
||||
int64_t *rtt)
|
||||
int64_t *rtt, bool *slave_err)
|
||||
{
|
||||
uint16_t response_size = 0;
|
||||
uint64_t read_tms = neu_time_ms();
|
||||
@@ -224,7 +235,7 @@ void check_modbus_read_result(neu_plugin_t * plugin,
|
||||
}
|
||||
|
||||
finalize_modbus_read_result(plugin, gd, cmd_index, ret_r, ret_buf, read_tms,
|
||||
rtt);
|
||||
rtt, slave_err);
|
||||
}
|
||||
|
||||
void update_metrics_after_read(neu_plugin_t *plugin, int64_t rtt,
|
||||
@@ -246,14 +257,53 @@ void update_metrics_after_read(neu_plugin_t *plugin, int64_t rtt,
|
||||
gd->cmd_sort->n_cmd, group->group_name);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint8_t slave_id;
|
||||
uint16_t degrade_time;
|
||||
} degrade_timer_data_t;
|
||||
|
||||
void *degrade_timer(void *arg)
|
||||
{
|
||||
degrade_timer_data_t *data = (degrade_timer_data_t *) arg;
|
||||
|
||||
struct timespec t1 = { .tv_sec = data->degrade_time, .tv_nsec = 0 };
|
||||
struct timespec t2 = { 0 };
|
||||
nanosleep(&t1, &t2);
|
||||
|
||||
skip[data->slave_id] = false;
|
||||
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void set_skip_timer(uint8_t slave_id, uint32_t degrade_time)
|
||||
{
|
||||
degrade_timer_data_t *data =
|
||||
(degrade_timer_data_t *) malloc(sizeof(degrade_timer_data_t));
|
||||
data->slave_id = slave_id;
|
||||
data->degrade_time = degrade_time;
|
||||
|
||||
failed_cycles[slave_id] = 0;
|
||||
|
||||
pthread_t timer_thread;
|
||||
pthread_create(&timer_thread, NULL, degrade_timer, data);
|
||||
|
||||
pthread_detach(timer_thread);
|
||||
}
|
||||
|
||||
int modbus_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group,
|
||||
uint16_t max_byte)
|
||||
{
|
||||
neu_conn_state_t state = { 0 };
|
||||
struct modbus_group_data *gd = NULL;
|
||||
int64_t rtt = NEU_METRIC_LAST_RTT_MS_MAX;
|
||||
struct modbus_group_data *gdt =
|
||||
(struct modbus_group_data *) group->user_data;
|
||||
|
||||
if (group->user_data == NULL) {
|
||||
if (group->user_data == NULL || gdt->address_base != plugin->address_base) {
|
||||
if (group->user_data != NULL) {
|
||||
plugin_group_free(group);
|
||||
}
|
||||
gd = calloc(1, sizeof(struct modbus_group_data));
|
||||
|
||||
group->user_data = gd;
|
||||
@@ -262,8 +312,8 @@ int modbus_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group,
|
||||
|
||||
utarray_foreach(group->tags, neu_datatag_t *, tag)
|
||||
{
|
||||
modbus_point_t *p = calloc(1, sizeof(modbus_point_t));
|
||||
int ret = modbus_tag_to_point(tag, p);
|
||||
modbus_point_t *p = calloc(1, sizeof(modbus_point_t));
|
||||
int ret = modbus_tag_to_point(tag, p, plugin->address_base);
|
||||
if (ret != NEU_ERR_SUCCESS) {
|
||||
plog_error(plugin, "invalid tag: %s, address: %s", tag->name,
|
||||
tag->address);
|
||||
@@ -272,16 +322,43 @@ int modbus_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group,
|
||||
utarray_push_back(gd->tags, &p);
|
||||
}
|
||||
|
||||
gd->group = strdup(group->group_name);
|
||||
gd->cmd_sort = modbus_tag_sort(gd->tags, max_byte);
|
||||
gd->group = strdup(group->group_name);
|
||||
gd->cmd_sort = modbus_tag_sort(gd->tags, max_byte);
|
||||
gd->address_base = plugin->address_base;
|
||||
}
|
||||
|
||||
gd = (struct modbus_group_data *) group->user_data;
|
||||
plugin->plugin_group_data = gd;
|
||||
|
||||
bool slave_err_record[MAX_SLAVES] = { false };
|
||||
|
||||
for (uint16_t i = 0; i < gd->cmd_sort->n_cmd; i++) {
|
||||
plugin->cmd_idx = i;
|
||||
check_modbus_read_result(plugin, gd, i, &rtt);
|
||||
bool slave_err[MAX_SLAVES] = { false };
|
||||
uint8_t slave_id = gd->cmd_sort->cmd[i].slave_id;
|
||||
plugin->cmd_idx = i;
|
||||
|
||||
if (slave_err_record[slave_id] == true) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (plugin->degradation == false || skip[slave_id] == false) {
|
||||
check_modbus_read_result(plugin, gd, i, &rtt, slave_err);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (plugin->degradation) {
|
||||
if (slave_err[slave_id]) {
|
||||
failed_cycles[slave_id]++;
|
||||
slave_err_record[slave_id] = true;
|
||||
}
|
||||
|
||||
if (failed_cycles[slave_id] >= plugin->degrade_cycle) {
|
||||
skip[slave_id] = true;
|
||||
plog_warn(plugin, "Skip slave %hhu", slave_id);
|
||||
set_skip_timer(slave_id, plugin->degrade_time);
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin->interval > 0) {
|
||||
struct timespec t1 = { .tv_sec = plugin->interval / 1000,
|
||||
@@ -297,7 +374,7 @@ int modbus_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group,
|
||||
}
|
||||
|
||||
int modbus_value_handle(void *ctx, uint8_t slave_id, uint16_t n_byte,
|
||||
uint8_t *bytes, int error)
|
||||
uint8_t *bytes, int error, void *trace)
|
||||
{
|
||||
neu_plugin_t * plugin = (neu_plugin_t *) ctx;
|
||||
struct modbus_group_data *gd =
|
||||
@@ -370,6 +447,9 @@ int modbus_value_handle(void *ctx, uint8_t slave_id, uint16_t n_byte,
|
||||
case NEU_TYPE_FLOAT:
|
||||
case NEU_TYPE_INT32:
|
||||
case NEU_TYPE_UINT32:
|
||||
if ((*p_tag)->option.value32.is_default) {
|
||||
modbus_convert_endianess(&dvalue.value, plugin->endianess);
|
||||
}
|
||||
dvalue.value.u32 = ntohl(dvalue.value.u32);
|
||||
break;
|
||||
case NEU_TYPE_DOUBLE:
|
||||
@@ -420,8 +500,14 @@ int modbus_value_handle(void *ctx, uint8_t slave_id, uint16_t n_byte,
|
||||
}
|
||||
}
|
||||
|
||||
plugin->common.adapter_callbacks->driver.update(
|
||||
plugin->common.adapter, gd->group, (*p_tag)->name, dvalue);
|
||||
if (trace) {
|
||||
plugin->common.adapter_callbacks->driver.update_with_trace(
|
||||
plugin->common.adapter, gd->group, (*p_tag)->name, dvalue, NULL,
|
||||
0, trace);
|
||||
} else {
|
||||
plugin->common.adapter_callbacks->driver.update(
|
||||
plugin->common.adapter, gd->group, (*p_tag)->name, dvalue);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -433,15 +519,13 @@ int modbus_value_handle_test(neu_plugin_t *plugin, void *req,
|
||||
(void) req;
|
||||
neu_json_value_u jvalue = { 0 };
|
||||
neu_json_type_e jtype;
|
||||
uint8_t recv_bytes[256] = { 0 };
|
||||
|
||||
switch (point->area) {
|
||||
case MODBUS_AREA_HOLD_REGISTER:
|
||||
case MODBUS_AREA_INPUT_REGISTER:
|
||||
if (n_byte >= point->n_register * 2) {
|
||||
jvalue.val_bytes.bytes =
|
||||
(uint8_t *) malloc(point->n_register * 2 + 1);
|
||||
memcpy(jvalue.val_bytes.bytes, bytes, point->n_register * 2);
|
||||
jvalue.val_bytes.length = point->n_register * 2;
|
||||
memcpy(recv_bytes, bytes, point->n_register * 2);
|
||||
}
|
||||
break;
|
||||
case MODBUS_AREA_COIL:
|
||||
@@ -455,23 +539,20 @@ int modbus_value_handle_test(neu_plugin_t *plugin, void *req,
|
||||
case NEU_TYPE_UINT16: {
|
||||
jtype = NEU_JSON_INT;
|
||||
uint16_t tmp_val16;
|
||||
memcpy(&tmp_val16, jvalue.val_bytes.bytes, sizeof(uint16_t));
|
||||
free(jvalue.val_bytes.bytes);
|
||||
memcpy(&tmp_val16, recv_bytes, sizeof(uint16_t));
|
||||
jvalue.val_int = ntohs(tmp_val16);
|
||||
break;
|
||||
}
|
||||
case NEU_TYPE_INT16: {
|
||||
jtype = NEU_JSON_INT;
|
||||
int16_t tmp_val16;
|
||||
memcpy(&tmp_val16, jvalue.val_bytes.bytes, sizeof(int16_t));
|
||||
free(jvalue.val_bytes.bytes);
|
||||
memcpy(&tmp_val16, recv_bytes, sizeof(int16_t));
|
||||
jvalue.val_int = (int16_t) ntohs(tmp_val16);
|
||||
break;
|
||||
}
|
||||
case NEU_TYPE_FLOAT: {
|
||||
uint32_t tmp_valf;
|
||||
memcpy(&tmp_valf, jvalue.val_bytes.bytes, sizeof(uint32_t));
|
||||
free(jvalue.val_bytes.bytes);
|
||||
memcpy(&tmp_valf, recv_bytes, sizeof(uint32_t));
|
||||
jtype = NEU_JSON_FLOAT;
|
||||
jvalue.val_int = ntohl(tmp_valf);
|
||||
break;
|
||||
@@ -479,23 +560,20 @@ int modbus_value_handle_test(neu_plugin_t *plugin, void *req,
|
||||
case NEU_TYPE_INT32: {
|
||||
jtype = NEU_JSON_INT;
|
||||
int32_t tmp_val32;
|
||||
memcpy(&tmp_val32, jvalue.val_bytes.bytes, sizeof(int32_t));
|
||||
free(jvalue.val_bytes.bytes);
|
||||
memcpy(&tmp_val32, recv_bytes, sizeof(int32_t));
|
||||
jvalue.val_int = (int32_t) ntohl(tmp_val32);
|
||||
break;
|
||||
}
|
||||
case NEU_TYPE_UINT32: {
|
||||
jtype = NEU_JSON_INT;
|
||||
uint32_t tmp_val32;
|
||||
memcpy(&tmp_val32, jvalue.val_bytes.bytes, sizeof(uint32_t));
|
||||
free(jvalue.val_bytes.bytes);
|
||||
memcpy(&tmp_val32, recv_bytes, sizeof(uint32_t));
|
||||
jvalue.val_int = ntohl(tmp_val32);
|
||||
break;
|
||||
}
|
||||
case NEU_TYPE_DOUBLE: {
|
||||
uint64_t tmp_vald;
|
||||
memcpy(&tmp_vald, jvalue.val_bytes.bytes, sizeof(uint64_t));
|
||||
free(jvalue.val_bytes.bytes);
|
||||
memcpy(&tmp_vald, recv_bytes, sizeof(uint64_t));
|
||||
jtype = NEU_JSON_DOUBLE;
|
||||
jvalue.val_int = neu_ntohll(tmp_vald);
|
||||
break;
|
||||
@@ -503,16 +581,14 @@ int modbus_value_handle_test(neu_plugin_t *plugin, void *req,
|
||||
case NEU_TYPE_INT64: {
|
||||
jtype = NEU_JSON_INT;
|
||||
int64_t tmp_val64;
|
||||
memcpy(&tmp_val64, jvalue.val_bytes.bytes, sizeof(int64_t));
|
||||
free(jvalue.val_bytes.bytes);
|
||||
memcpy(&tmp_val64, recv_bytes, sizeof(int64_t));
|
||||
jvalue.val_int = (int64_t) neu_ntohll(tmp_val64);
|
||||
break;
|
||||
}
|
||||
case NEU_TYPE_UINT64: {
|
||||
jtype = NEU_JSON_INT;
|
||||
uint64_t tmp_val64;
|
||||
memcpy(&tmp_val64, jvalue.val_bytes.bytes, sizeof(uint64_t));
|
||||
free(jvalue.val_bytes.bytes);
|
||||
memcpy(&tmp_val64, recv_bytes, sizeof(uint64_t));
|
||||
jvalue.val_int = neu_ntohll(tmp_val64);
|
||||
break;
|
||||
}
|
||||
@@ -522,9 +598,8 @@ int modbus_value_handle_test(neu_plugin_t *plugin, void *req,
|
||||
case MODBUS_AREA_INPUT_REGISTER: {
|
||||
jtype = NEU_JSON_BIT;
|
||||
neu_value16_u v16 = { 0 };
|
||||
v16.value = htons(*(uint16_t *) jvalue.val_bytes.bytes);
|
||||
free(jvalue.val_bytes.bytes);
|
||||
jvalue.val_bit = neu_value16_get_bit(v16, point->option.bit.bit);
|
||||
v16.value = htons(*(uint16_t *) recv_bytes);
|
||||
jvalue.val_bit = neu_value16_get_bit(v16, point->option.bit.bit);
|
||||
break;
|
||||
}
|
||||
case MODBUS_AREA_COIL:
|
||||
@@ -535,10 +610,10 @@ int modbus_value_handle_test(neu_plugin_t *plugin, void *req,
|
||||
break;
|
||||
}
|
||||
case NEU_TYPE_STRING: {
|
||||
jtype = NEU_JSON_STR;
|
||||
size_t str_length = point->n_register * 2;
|
||||
jvalue.val_str = (char *) jvalue.val_bytes.bytes;
|
||||
jvalue.val_str[str_length] = '\0';
|
||||
jtype = NEU_JSON_STR;
|
||||
size_t str_length = point->n_register * 2;
|
||||
jvalue.val_str = calloc(1, str_length + 1);
|
||||
strncpy(jvalue.val_str, (char *) recv_bytes, str_length);
|
||||
|
||||
switch (point->option.string.type) {
|
||||
case NEU_DATATAG_STRING_TYPE_H:
|
||||
@@ -575,7 +650,7 @@ int modbus_test_read_tag(neu_plugin_t *plugin, void *req, neu_datatag_t tag)
|
||||
neu_json_value_u error_value;
|
||||
error_value.val_int = 0;
|
||||
|
||||
int err = modbus_tag_to_point(&tag, &point);
|
||||
int err = modbus_tag_to_point(&tag, &point, plugin->address_base);
|
||||
if (err != NEU_ERR_SUCCESS) {
|
||||
plugin->common.adapter_callbacks->driver.test_read_tag_response(
|
||||
plugin->common.adapter, req, NEU_JSON_INT, NEU_TYPE_ERROR,
|
||||
@@ -615,8 +690,8 @@ int modbus_test_read_tag(neu_plugin_t *plugin, void *req, neu_datatag_t tag)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t convert_value(neu_value_u *value, neu_datatag_t *tag,
|
||||
modbus_point_t *point)
|
||||
static uint8_t convert_value(neu_plugin_t *plugin, neu_value_u *value,
|
||||
neu_datatag_t *tag, modbus_point_t *point)
|
||||
{
|
||||
uint8_t n_byte = 0;
|
||||
switch (tag->type) {
|
||||
@@ -628,6 +703,9 @@ static uint8_t convert_value(neu_value_u *value, neu_datatag_t *tag,
|
||||
case NEU_TYPE_FLOAT:
|
||||
case NEU_TYPE_UINT32:
|
||||
case NEU_TYPE_INT32:
|
||||
if (point->option.value32.is_default) {
|
||||
modbus_convert_endianess(value, plugin->endianess);
|
||||
}
|
||||
value->u32 = htonl(value->u32);
|
||||
n_byte = sizeof(uint32_t);
|
||||
break;
|
||||
@@ -702,10 +780,10 @@ int modbus_write_tag(neu_plugin_t *plugin, void *req, neu_datatag_t *tag,
|
||||
neu_value_u value)
|
||||
{
|
||||
modbus_point_t point = { 0 };
|
||||
int ret = modbus_tag_to_point(tag, &point);
|
||||
int ret = modbus_tag_to_point(tag, &point, plugin->address_base);
|
||||
assert(ret == 0);
|
||||
|
||||
uint8_t n_byte = convert_value(&value, tag, &point);
|
||||
uint8_t n_byte = convert_value(plugin, &value, tag, &point);
|
||||
return write_modbus_point(plugin, req, &point, value, n_byte);
|
||||
}
|
||||
|
||||
@@ -721,12 +799,12 @@ int modbus_write_tags(neu_plugin_t *plugin, void *req, UT_array *tags)
|
||||
utarray_foreach(tags, neu_plugin_tag_value_t *, tag)
|
||||
{
|
||||
modbus_point_write_t *p = calloc(1, sizeof(modbus_point_write_t));
|
||||
ret = modbus_write_tag_to_point(tag, p);
|
||||
ret = modbus_write_tag_to_point(tag, p, plugin->address_base);
|
||||
assert(ret == 0);
|
||||
|
||||
utarray_push_back(gtags->tags, &p);
|
||||
}
|
||||
gtags->cmd_sort = modbus_write_tags_sort(gtags->tags);
|
||||
gtags->cmd_sort = modbus_write_tags_sort(gtags->tags, plugin->endianess);
|
||||
for (uint16_t i = 0; i < gtags->cmd_sort->n_cmd; i++) {
|
||||
ret = write_modbus_points(plugin, >ags->cmd_sort->cmd[i], req);
|
||||
if (ret <= 0) {
|
||||
|
||||
@@ -38,12 +38,17 @@ struct neu_plugin {
|
||||
int client_fd;
|
||||
neu_events_t * events;
|
||||
|
||||
modbus_protocol_e protocol;
|
||||
modbus_protocol_e protocol;
|
||||
modbus_endianess endianess;
|
||||
modbus_address_base address_base;
|
||||
|
||||
uint16_t interval;
|
||||
uint16_t retry_interval;
|
||||
uint16_t max_retries;
|
||||
uint16_t check_header;
|
||||
bool degradation;
|
||||
uint16_t degrade_cycle;
|
||||
uint16_t degrade_time;
|
||||
};
|
||||
|
||||
void modbus_conn_connected(void *data, int fd);
|
||||
@@ -57,7 +62,7 @@ int modbus_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group,
|
||||
uint16_t max_byte);
|
||||
int modbus_send_msg(void *ctx, uint16_t n_byte, uint8_t *bytes);
|
||||
int modbus_value_handle(void *ctx, uint8_t slave_id, uint16_t n_byte,
|
||||
uint8_t *bytes, int error);
|
||||
uint8_t *bytes, int error, void *trace);
|
||||
int modbus_write(neu_plugin_t *plugin, void *req, neu_datatag_t *tag,
|
||||
neu_value_u value, bool response);
|
||||
int modbus_write_tag(neu_plugin_t *plugin, void *req, neu_datatag_t *tag,
|
||||
|
||||
@@ -37,7 +37,6 @@ static int driver_config(neu_plugin_t *plugin, const char *config);
|
||||
static int driver_request(neu_plugin_t *plugin, neu_reqresp_head_t *head,
|
||||
void *data);
|
||||
|
||||
static int driver_tag_validator(const neu_datatag_t *tag);
|
||||
static int driver_validate_tag(neu_plugin_t *plugin, neu_datatag_t *tag);
|
||||
static int driver_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group);
|
||||
static int driver_write(neu_plugin_t *plugin, void *req, neu_datatag_t *tag,
|
||||
@@ -58,7 +57,7 @@ static const neu_plugin_intf_funs_t plugin_intf_funs = {
|
||||
.driver.group_timer = driver_group_timer,
|
||||
.driver.group_sync = driver_group_timer,
|
||||
.driver.write_tag = driver_write,
|
||||
.driver.tag_validator = driver_tag_validator,
|
||||
.driver.tag_validator = NULL,
|
||||
.driver.write_tags = driver_write_tags,
|
||||
.driver.add_tags = NULL,
|
||||
.driver.load_tags = NULL,
|
||||
@@ -168,6 +167,17 @@ static int driver_config(neu_plugin_t *plugin, const char *config)
|
||||
neu_json_elem_t retry_interval = { .name = "retry_interval",
|
||||
.t = NEU_JSON_INT };
|
||||
|
||||
neu_json_elem_t degradation = { .name = "device_degrade",
|
||||
.t = NEU_JSON_INT };
|
||||
neu_json_elem_t degrade_cycle = { .name = "degrade_cycle",
|
||||
.t = NEU_JSON_INT };
|
||||
neu_json_elem_t degrade_time = { .name = "degrade_time",
|
||||
.t = NEU_JSON_INT };
|
||||
|
||||
neu_json_elem_t endianess = { .name = "endianess", .t = NEU_JSON_INT };
|
||||
neu_json_elem_t address_base = { .name = "address_base",
|
||||
.t = NEU_JSON_INT };
|
||||
|
||||
ret = neu_parse_param((char *) config, &err_param, 3, &link, &timeout,
|
||||
&interval);
|
||||
if (ret != 0) {
|
||||
@@ -208,9 +218,35 @@ static int driver_config(neu_plugin_t *plugin, const char *config)
|
||||
retry_interval.v.val_int = 0;
|
||||
}
|
||||
|
||||
ret = neu_parse_param((char *) config, &err_param, 3, °radation,
|
||||
°rade_cycle, °rade_time);
|
||||
if (ret != 0) {
|
||||
free(err_param);
|
||||
degradation.v.val_int = 0;
|
||||
degrade_cycle.v.val_int = 2;
|
||||
degrade_time.v.val_int = 600;
|
||||
}
|
||||
|
||||
ret = neu_parse_param((char *) config, &err_param, 1, &endianess);
|
||||
if (ret != 0) {
|
||||
free(err_param);
|
||||
endianess.v.val_int = MODBUS_ABCD;
|
||||
}
|
||||
|
||||
ret = neu_parse_param((char *) config, &err_param, 1, &address_base);
|
||||
if (ret != 0) {
|
||||
free(err_param);
|
||||
address_base.v.val_int = base_1;
|
||||
}
|
||||
|
||||
param.log = plugin->common.log;
|
||||
plugin->max_retries = max_retries.v.val_int;
|
||||
plugin->retry_interval = retry_interval.v.val_int;
|
||||
plugin->degradation = degradation.v.val_int;
|
||||
plugin->degrade_cycle = degrade_cycle.v.val_int;
|
||||
plugin->degrade_time = degrade_time.v.val_int;
|
||||
plugin->endianess = endianess.v.val_int;
|
||||
plugin->address_base = address_base.v.val_int;
|
||||
|
||||
if (link.v.val_int == 0) {
|
||||
param.type = NEU_CONN_TTY_CLIENT;
|
||||
@@ -279,17 +315,11 @@ static int driver_request(neu_plugin_t *plugin, neu_reqresp_head_t *head,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int driver_tag_validator(const neu_datatag_t *tag)
|
||||
{
|
||||
modbus_point_t point = { 0 };
|
||||
return modbus_tag_to_point(tag, &point);
|
||||
}
|
||||
|
||||
static int driver_validate_tag(neu_plugin_t *plugin, neu_datatag_t *tag)
|
||||
{
|
||||
modbus_point_t point = { 0 };
|
||||
|
||||
int ret = modbus_tag_to_point(tag, &point);
|
||||
int ret = modbus_tag_to_point(tag, &point, plugin->address_base);
|
||||
if (ret == 0) {
|
||||
plog_notice(plugin,
|
||||
"validate tag success, name: %s, address: %s, type: %d, "
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
#include "modbus_req.h"
|
||||
#include "modbus_stack.h"
|
||||
|
||||
#include "otel/otel_manager.h"
|
||||
|
||||
struct modbus_stack {
|
||||
void * ctx;
|
||||
modbus_stack_send send_fn;
|
||||
@@ -35,6 +37,8 @@ struct modbus_stack {
|
||||
|
||||
uint8_t *buf;
|
||||
uint16_t buf_size;
|
||||
|
||||
int64_t sample_mod;
|
||||
};
|
||||
|
||||
modbus_stack_t *modbus_stack_create(void *ctx, modbus_protocol_e protocol,
|
||||
@@ -65,9 +69,10 @@ void modbus_stack_destroy(modbus_stack_t *stack)
|
||||
int modbus_stack_recv(modbus_stack_t *stack, uint8_t slave_id,
|
||||
neu_protocol_unpack_buf_t *buf)
|
||||
{
|
||||
struct modbus_header header = { 0 };
|
||||
struct modbus_code code = { 0 };
|
||||
int ret = 0;
|
||||
struct modbus_header header = { 0 };
|
||||
struct modbus_code code = { 0 };
|
||||
int ret = 0;
|
||||
int64_t ts_start = neu_time_ns();
|
||||
|
||||
if (stack->protocol == MODBUS_PROTOCOL_TCP) {
|
||||
ret = modbus_header_unwrap(buf, &header);
|
||||
@@ -99,6 +104,22 @@ int modbus_stack_recv(modbus_stack_t *stack, uint8_t slave_id,
|
||||
case MODBUS_READ_INPUT:
|
||||
case MODBUS_READ_HOLD_REG:
|
||||
case MODBUS_READ_INPUT_REG: {
|
||||
neu_otel_trace_ctx trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
if (neu_otel_data_is_started()) {
|
||||
trace = neu_otel_find_trace((void *) (intptr_t) stack->read_seq);
|
||||
if (trace) {
|
||||
char new_span_id[36] = { 0 };
|
||||
neu_otel_new_span_id(new_span_id);
|
||||
scope =
|
||||
neu_otel_add_span2(trace, "driver cmd recv", new_span_id);
|
||||
neu_otel_scope_add_span_attr_int(scope, "thread id",
|
||||
(int64_t)(pthread_self()));
|
||||
neu_otel_scope_set_span_start_time(scope, ts_start);
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
}
|
||||
}
|
||||
|
||||
struct modbus_data data = { 0 };
|
||||
uint8_t * bytes = NULL;
|
||||
ret = modbus_data_unwrap(buf, &data);
|
||||
@@ -119,14 +140,14 @@ int modbus_stack_recv(modbus_stack_t *stack, uint8_t slave_id,
|
||||
stack->value_fn(stack->ctx, code.slave_id,
|
||||
header.len - sizeof(struct modbus_code) -
|
||||
sizeof(struct modbus_data),
|
||||
bytes, 0);
|
||||
bytes, 0, (void *) (intptr_t) stack->read_seq);
|
||||
} else {
|
||||
bytes = neu_protocol_unpack_buf(buf, data.n_byte);
|
||||
if (bytes == NULL) {
|
||||
return -1;
|
||||
}
|
||||
stack->value_fn(stack->ctx, code.slave_id, data.n_byte, bytes,
|
||||
0);
|
||||
0, (void *) (intptr_t) stack->read_seq);
|
||||
}
|
||||
break;
|
||||
case MODBUS_PROTOCOL_RTU:
|
||||
@@ -134,7 +155,8 @@ int modbus_stack_recv(modbus_stack_t *stack, uint8_t slave_id,
|
||||
if (bytes == NULL) {
|
||||
return -1;
|
||||
}
|
||||
stack->value_fn(stack->ctx, code.slave_id, data.n_byte, bytes, 0);
|
||||
stack->value_fn(stack->ctx, code.slave_id, data.n_byte, bytes, 0,
|
||||
(void *) (intptr_t) stack->read_seq);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -287,6 +309,7 @@ int modbus_stack_read(modbus_stack_t *stack, uint8_t slave_id,
|
||||
int ret = 0;
|
||||
*response_size = 0;
|
||||
modbus_action_e m_action = MODBUS_ACTION_DEFAULT;
|
||||
int64_t ts_start = neu_time_ns();
|
||||
|
||||
neu_protocol_pack_buf_init(&pbuf, buf, sizeof(buf));
|
||||
|
||||
@@ -331,11 +354,47 @@ int modbus_stack_read(modbus_stack_t *stack, uint8_t slave_id,
|
||||
ret = stack->send_fn(stack->ctx, neu_protocol_pack_buf_used_size(&pbuf),
|
||||
neu_protocol_pack_buf_get(&pbuf));
|
||||
if (ret <= 0 && !is_test) {
|
||||
stack->value_fn(stack->ctx, 0, 0, NULL, NEU_ERR_PLUGIN_DISCONNECTED);
|
||||
stack->value_fn(stack->ctx, 0, 0, NULL, NEU_ERR_PLUGIN_DISCONNECTED,
|
||||
NULL);
|
||||
plog_warn((neu_plugin_t *) stack->ctx, "send read req fail, %hhu!%hu",
|
||||
slave_id, start_address);
|
||||
}
|
||||
} else {
|
||||
if (neu_otel_data_is_started()) {
|
||||
double rate = neu_otel_data_sample_rate();
|
||||
int sample_rate = 0;
|
||||
if (rate > 0.0 && rate <= 1.0) {
|
||||
sample_rate = (int) (1.0 / rate);
|
||||
}
|
||||
if (sample_rate != 0) {
|
||||
stack->sample_mod += 1;
|
||||
if (stack->sample_mod % sample_rate == 0) {
|
||||
char new_trace_id[64] = { 0 };
|
||||
neu_otel_new_trace_id(new_trace_id);
|
||||
const char *trace_state = "span.mytype=data-collection";
|
||||
neu_otel_trace_ctx trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
trace = neu_otel_create_trace(
|
||||
new_trace_id, (void *) (intptr_t) stack->read_seq, 0,
|
||||
trace_state);
|
||||
scope = neu_otel_add_span(trace);
|
||||
neu_otel_scope_set_span_name(scope, "driver cmd send");
|
||||
char new_span_id[36] = { 0 };
|
||||
neu_otel_new_span_id(new_span_id);
|
||||
neu_otel_scope_set_span_id(scope, new_span_id);
|
||||
neu_otel_scope_set_span_flags(scope, 0);
|
||||
neu_otel_scope_set_span_start_time(scope, ts_start);
|
||||
|
||||
neu_otel_scope_add_span_attr_int(scope, "thread id",
|
||||
(int64_t) pthread_self());
|
||||
|
||||
neu_otel_scope_add_span_attr_string(
|
||||
scope, "node",
|
||||
((neu_plugin_t *) stack->ctx)->common.name);
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ typedef struct modbus_stack modbus_stack_t;
|
||||
|
||||
typedef int (*modbus_stack_send)(void *ctx, uint16_t n_byte, uint8_t *bytes);
|
||||
typedef int (*modbus_stack_value)(void *ctx, uint8_t slave_id, uint16_t n_byte,
|
||||
uint8_t *bytes, int error);
|
||||
uint8_t *bytes, int error, void *trace);
|
||||
typedef int (*modbus_stack_write_resp)(void *ctx, void *req, int error);
|
||||
|
||||
typedef enum modbus_protocol {
|
||||
|
||||
@@ -37,7 +37,6 @@ static int driver_config(neu_plugin_t *plugin, const char *config);
|
||||
static int driver_request(neu_plugin_t *plugin, neu_reqresp_head_t *head,
|
||||
void *data);
|
||||
|
||||
static int driver_tag_validator(const neu_datatag_t *tag);
|
||||
static int driver_validate_tag(neu_plugin_t *plugin, neu_datatag_t *tag);
|
||||
static int driver_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group);
|
||||
static int driver_write(neu_plugin_t *plugin, void *req, neu_datatag_t *tag,
|
||||
@@ -60,7 +59,7 @@ static const neu_plugin_intf_funs_t plugin_intf_funs = {
|
||||
.driver.group_timer = driver_group_timer,
|
||||
.driver.group_sync = driver_group_timer,
|
||||
.driver.write_tag = driver_write,
|
||||
.driver.tag_validator = driver_tag_validator,
|
||||
.driver.tag_validator = NULL,
|
||||
.driver.write_tags = driver_write_tags,
|
||||
.driver.test_read_tag = driver_test_read_tag,
|
||||
.driver.add_tags = NULL,
|
||||
@@ -165,6 +164,17 @@ static int driver_config(neu_plugin_t *plugin, const char *config)
|
||||
neu_json_elem_t check_header = { .name = "check_header",
|
||||
.t = NEU_JSON_INT };
|
||||
|
||||
neu_json_elem_t degradation = { .name = "device_degrade",
|
||||
.t = NEU_JSON_INT };
|
||||
neu_json_elem_t degrade_cycle = { .name = "degrade_cycle",
|
||||
.t = NEU_JSON_INT };
|
||||
neu_json_elem_t degrade_time = { .name = "degrade_time",
|
||||
.t = NEU_JSON_INT };
|
||||
|
||||
neu_json_elem_t endianess = { .name = "endianess", .t = NEU_JSON_INT };
|
||||
neu_json_elem_t address_base = { .name = "address_base",
|
||||
.t = NEU_JSON_INT };
|
||||
|
||||
ret = neu_parse_param((char *) config, &err_param, 5, &port, &host, &mode,
|
||||
&timeout, &interval);
|
||||
|
||||
@@ -198,11 +208,37 @@ static int driver_config(neu_plugin_t *plugin, const char *config)
|
||||
check_header.v.val_int = 0;
|
||||
}
|
||||
|
||||
ret = neu_parse_param((char *) config, &err_param, 3, °radation,
|
||||
°rade_cycle, °rade_time);
|
||||
if (ret != 0) {
|
||||
free(err_param);
|
||||
degradation.v.val_int = 0;
|
||||
degrade_cycle.v.val_int = 2;
|
||||
degrade_time.v.val_int = 600;
|
||||
}
|
||||
|
||||
ret = neu_parse_param((char *) config, &err_param, 1, &endianess);
|
||||
if (ret != 0) {
|
||||
free(err_param);
|
||||
endianess.v.val_int = MODBUS_ABCD;
|
||||
}
|
||||
|
||||
ret = neu_parse_param((char *) config, &err_param, 1, &address_base);
|
||||
if (ret != 0) {
|
||||
free(err_param);
|
||||
address_base.v.val_int = base_1;
|
||||
}
|
||||
|
||||
param.log = plugin->common.log;
|
||||
plugin->interval = interval.v.val_int;
|
||||
plugin->max_retries = max_retries.v.val_int;
|
||||
plugin->retry_interval = retry_interval.v.val_int;
|
||||
plugin->check_header = check_header.v.val_int;
|
||||
plugin->degradation = degradation.v.val_int;
|
||||
plugin->degrade_cycle = degrade_cycle.v.val_int;
|
||||
plugin->degrade_time = degrade_time.v.val_int;
|
||||
plugin->endianess = endianess.v.val_int;
|
||||
plugin->address_base = address_base.v.val_int;
|
||||
|
||||
if (mode.v.val_int == 1) {
|
||||
param.type = NEU_CONN_TCP_SERVER;
|
||||
@@ -248,17 +284,11 @@ static int driver_request(neu_plugin_t *plugin, neu_reqresp_head_t *head,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int driver_tag_validator(const neu_datatag_t *tag)
|
||||
{
|
||||
modbus_point_t point = { 0 };
|
||||
return modbus_tag_to_point(tag, &point);
|
||||
}
|
||||
|
||||
static int driver_validate_tag(neu_plugin_t *plugin, neu_datatag_t *tag)
|
||||
{
|
||||
modbus_point_t point = { 0 };
|
||||
|
||||
int ret = modbus_tag_to_point(tag, &point);
|
||||
int ret = modbus_tag_to_point(tag, &point, plugin->address_base);
|
||||
if (ret == 0) {
|
||||
plog_notice(
|
||||
plugin,
|
||||
|
||||
@@ -330,7 +330,8 @@ static int azure_plugin_request(neu_plugin_t *plugin, neu_reqresp_head_t *head,
|
||||
|
||||
switch (head->type) {
|
||||
case NEU_RESP_ERROR:
|
||||
error = handle_write_response(plugin, head->ctx, data);
|
||||
error =
|
||||
handle_write_response(plugin, head->ctx, data, NULL, NULL, NULL);
|
||||
break;
|
||||
case NEU_RESP_READ_GROUP:
|
||||
// error = handle_read_response(plugin, head->ctx, data);
|
||||
|
||||
+292
-290
@@ -1,291 +1,293 @@
|
||||
{
|
||||
"version": {
|
||||
"name": "MQTT Version",
|
||||
"name_zh": "MQTT 版本",
|
||||
"type": "map",
|
||||
"attribute": "optional",
|
||||
"default": 4,
|
||||
"valid": {
|
||||
"map": [
|
||||
{
|
||||
"key": "3.1.1",
|
||||
"value": 4
|
||||
},
|
||||
{
|
||||
"key": "5.0",
|
||||
"value": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"client-id": {
|
||||
"name": "Client ID",
|
||||
"name_zh": "客户端 ID",
|
||||
"type": "string",
|
||||
"attribute": "required",
|
||||
"default": "neuron_${random_str}",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"qos": {
|
||||
"name": "QoS Level",
|
||||
"name_zh": "QoS 等级",
|
||||
"description": "MQTT QoS level for message delivery",
|
||||
"description_zh": "MQTT 消息传输使用的服务质量等级",
|
||||
"type": "map",
|
||||
"attribute": "optional",
|
||||
"default": 0,
|
||||
"valid": {
|
||||
"map": [
|
||||
{
|
||||
"key": "QoS 0",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"key": "QoS 1",
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"key": "QoS 2",
|
||||
"value": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"format": {
|
||||
"name": "Upload Format",
|
||||
"name_zh": "上报数据格式",
|
||||
"description": "JSON format of the data reported. In values-mode, data are split into `values` and `errors` sub objects. In tags-mode, tag data are put in a single array.",
|
||||
"description_zh": "上报数据的 JSON 格式。在 values-format 格式下,数据被分为 `values` 和 `errors` 两个子对象。在 tags-format 格式下,数据被放在一个数组中。",
|
||||
"attribute": "required",
|
||||
"type": "map",
|
||||
"default": 0,
|
||||
"valid": {
|
||||
"map": [
|
||||
{
|
||||
"key": "values-format",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"key": "tags-format",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"write-req-topic": {
|
||||
"name": "Write Request Topic",
|
||||
"name_zh": "写请求主题",
|
||||
"description": "MQTT topic to receive write request messages.",
|
||||
"description_zh": "接收点位写入请求的 MQTT 主题。",
|
||||
"attribute": "required",
|
||||
"type": "string",
|
||||
"default": "/neuron/${random_str}/write/req",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"write-resp-topic": {
|
||||
"name": "Write Response Topic",
|
||||
"name_zh": "写响应主题",
|
||||
"description": "MQTT topic to send write response messages.",
|
||||
"description_zh": "发送点位写入响应的 MQTT 主题。",
|
||||
"attribute": "required",
|
||||
"type": "string",
|
||||
"default": "/neuron/${random_str}/write/resp",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"upload_drv_state": {
|
||||
"name": "Upload Driver State",
|
||||
"name_zh": "驱动状态上报",
|
||||
"attribute": "optional",
|
||||
"type": "bool",
|
||||
"default": false,
|
||||
"valid": {}
|
||||
},
|
||||
"upload_drv_state_topic": {
|
||||
"name": "Status Reporting Topic",
|
||||
"name_zh": "状态上报主题",
|
||||
"attribute": "required",
|
||||
"type": "string",
|
||||
"condition": {
|
||||
"field": "upload_drv_state",
|
||||
"value": true
|
||||
},
|
||||
"default": "/neuron/${random_str}/state/update",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"upload_drv_state_interval": {
|
||||
"name": "Status Reporting Interval(S)",
|
||||
"name_zh": "状态上报间隔(S)",
|
||||
"attribute": "required",
|
||||
"type": "int",
|
||||
"condition": {
|
||||
"field": "upload_drv_state",
|
||||
"value": true
|
||||
},
|
||||
"default": 1,
|
||||
"valid": {
|
||||
"min": 1,
|
||||
"max": 3600
|
||||
}
|
||||
},
|
||||
"offline-cache": {
|
||||
"name": "Offline Data Caching",
|
||||
"name_zh": "离线缓存",
|
||||
"description": "Offline caching switch. Cache MQTT messages when offline, and sync cached messages when back online.",
|
||||
"description_zh": "离线缓存开关。连接断开时缓存 MQTT 消息,连接重建时同步缓存的 MQTT 消息到服务器。",
|
||||
"attribute": "optional",
|
||||
"type": "bool",
|
||||
"default": false,
|
||||
"valid": {}
|
||||
},
|
||||
"cache-mem-size": {
|
||||
"name": "Cache Memory Size (MB)",
|
||||
"name_zh": "缓存内存大小(MB)",
|
||||
"description": "Max in-memory cache size in megabytes when MQTT connection exception occurs. Should be smaller than cache disk size.",
|
||||
"description_zh": "当 MQTT 连接异常时,最大的内存缓存大小(单位:MB)。应该小于缓存磁盘大小。",
|
||||
"type": "int",
|
||||
"attribute": "required",
|
||||
"condition": {
|
||||
"field": "offline-cache",
|
||||
"value": true
|
||||
},
|
||||
"valid": {
|
||||
"min": 1,
|
||||
"max": 1024
|
||||
}
|
||||
},
|
||||
"cache-disk-size": {
|
||||
"name": "Cache Disk Size (MB)",
|
||||
"name_zh": "缓存磁盘大小(MB)",
|
||||
"description": "Max in-disk cache size in megabytes when MQTT connection exception occurs. Should be larger than cache memory size. If nonzero, cache memory size should also be nonzero.",
|
||||
"description_zh": "当 MQTT 连接异常时,最大的磁盘缓存大小(单位:MB)。应该大于缓存内存大小。如果不为 0,缓存内存大小也应该不为 0。",
|
||||
"type": "int",
|
||||
"attribute": "required",
|
||||
"condition": {
|
||||
"field": "offline-cache",
|
||||
"value": true
|
||||
},
|
||||
"valid": {
|
||||
"min": 1,
|
||||
"max": 10240
|
||||
}
|
||||
},
|
||||
"cache-sync-interval": {
|
||||
"name": "Cache Sync Interval (MS)",
|
||||
"name_zh": "缓存消息重传间隔(MS)",
|
||||
"type": "int",
|
||||
"attribute": "required",
|
||||
"condition": {
|
||||
"field": "offline-cache",
|
||||
"value": true
|
||||
},
|
||||
"default": 100,
|
||||
"valid": {
|
||||
"min": 10,
|
||||
"max": 120000
|
||||
}
|
||||
},
|
||||
"host": {
|
||||
"name": "Broker Host",
|
||||
"name_zh": "服务器地址",
|
||||
"attribute": "required",
|
||||
"type": "string",
|
||||
"default": "broker.emqx.io",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"port": {
|
||||
"name": "Broker Port",
|
||||
"name_zh": "服务器端口",
|
||||
"attribute": "required",
|
||||
"type": "int",
|
||||
"default": 1883,
|
||||
"valid": {
|
||||
"min": 1024,
|
||||
"max": 65535
|
||||
}
|
||||
},
|
||||
"username": {
|
||||
"name": "Username",
|
||||
"name_zh": "用户名",
|
||||
"attribute": "optional",
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"password": {
|
||||
"name": "Password",
|
||||
"name_zh": "密码",
|
||||
"attribute": "optional",
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"ssl": {
|
||||
"name": "SSL",
|
||||
"name_zh": "SSL",
|
||||
"description": "Enable SSL connection",
|
||||
"description_zh": "是否启用 SSL 连接",
|
||||
"attribute": "optional",
|
||||
"type": "bool",
|
||||
"default": false,
|
||||
"valid": {}
|
||||
},
|
||||
"ca": {
|
||||
"name": "CA",
|
||||
"name_zh": "CA 证书",
|
||||
"description": "CA certificate which signs the server certificate",
|
||||
"description_zh": "签发服务器证书的 CA 证书",
|
||||
"attribute": "optional",
|
||||
"type": "file",
|
||||
"condition": {
|
||||
"field": "ssl",
|
||||
"value": true
|
||||
},
|
||||
"valid": {
|
||||
"length": 81960
|
||||
}
|
||||
},
|
||||
"cert": {
|
||||
"name": "Client Cert",
|
||||
"name_zh": "客户端证书",
|
||||
"description": "Client x509 certificate when using two way authentication",
|
||||
"description_zh": "使用双向认证时,客户端的 x509 证书",
|
||||
"attribute": "optional",
|
||||
"type": "file",
|
||||
"condition": {
|
||||
"field": "ssl",
|
||||
"value": true
|
||||
},
|
||||
"valid": {
|
||||
"length": 81960
|
||||
}
|
||||
},
|
||||
"key": {
|
||||
"name": "Client Private Key",
|
||||
"name_zh": "客户端私钥",
|
||||
"description": "Client private key when using two way authentication",
|
||||
"description_zh": "使用双向认证时,客户端的私钥",
|
||||
"attribute": "optional",
|
||||
"type": "file",
|
||||
"condition": {
|
||||
"field": "ssl",
|
||||
"value": true
|
||||
},
|
||||
"valid": {
|
||||
"length": 81960
|
||||
}
|
||||
}
|
||||
}
|
||||
"version": {
|
||||
"name": "MQTT Version",
|
||||
"name_zh": "MQTT 版本",
|
||||
"type": "map",
|
||||
"attribute": "optional",
|
||||
"default": 4,
|
||||
"valid": {
|
||||
"map": [
|
||||
{
|
||||
"key": "3.1.1",
|
||||
"value": 4
|
||||
},
|
||||
{
|
||||
"key": "5.0",
|
||||
"value": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"client-id": {
|
||||
"name": "Client ID",
|
||||
"name_zh": "客户端 ID",
|
||||
"type": "string",
|
||||
"attribute": "required",
|
||||
"default": "neuron_${random_str}",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"qos": {
|
||||
"name": "QoS Level",
|
||||
"name_zh": "QoS 等级",
|
||||
"description": "MQTT QoS level for message delivery",
|
||||
"description_zh": "MQTT 消息传输使用的服务质量等级",
|
||||
"type": "map",
|
||||
"attribute": "optional",
|
||||
"default": 0,
|
||||
"valid": {
|
||||
"map": [
|
||||
{
|
||||
"key": "QoS 0",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"key": "QoS 1",
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"key": "QoS 2",
|
||||
"value": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"format": {
|
||||
"name": "Upload Format",
|
||||
"name_zh": "上报数据格式",
|
||||
"description": "JSON format of the data reported. In values-mode, data are split into `values` and `errors` sub objects. In tags-mode, tag data are put in a single array.",
|
||||
"description_zh": "上报数据的 JSON 格式。在 values-format 格式下,数据被分为 `values` 和 `errors` 两个子对象。在 tags-format 格式下,数据被放在一个数组中。",
|
||||
"attribute": "required",
|
||||
"type": "map",
|
||||
"default": 0,
|
||||
"valid": {
|
||||
"map": [
|
||||
{
|
||||
"key": "values-format",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"key": "tags-format",
|
||||
"value": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"write-req-topic": {
|
||||
"name": "Write Request Topic",
|
||||
"name_zh": "写请求主题",
|
||||
"description": "MQTT topic to receive write request messages.",
|
||||
"description_zh": "接收点位写入请求的 MQTT 主题。",
|
||||
"attribute": "required",
|
||||
"type": "string",
|
||||
"default": "/neuron/${random_str}/write/req",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"write-resp-topic": {
|
||||
"name": "Write Response Topic",
|
||||
"name_zh": "写响应主题",
|
||||
"description": "MQTT topic to send write response messages.",
|
||||
"description_zh": "发送点位写入响应的 MQTT 主题。",
|
||||
"attribute": "required",
|
||||
"type": "string",
|
||||
"default": "/neuron/${random_str}/write/resp",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"upload_drv_state": {
|
||||
"name": "Driver Status Report",
|
||||
"name_zh": "驱动状态上报",
|
||||
"description": "Reports status of all the southbound nodes to the specified topic.",
|
||||
"description_zh": "上报所有南向驱动状态到指定的 MQTT 主题。",
|
||||
"attribute": "optional",
|
||||
"type": "bool",
|
||||
"default": false,
|
||||
"valid": {}
|
||||
},
|
||||
"upload_drv_state_topic": {
|
||||
"name": "Status Report Topic",
|
||||
"name_zh": "状态上报主题",
|
||||
"attribute": "required",
|
||||
"type": "string",
|
||||
"condition": {
|
||||
"field": "upload_drv_state",
|
||||
"value": true
|
||||
},
|
||||
"default": "/neuron/${random_str}/state/update",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"upload_drv_state_interval": {
|
||||
"name": "Status Report Interval (Second)",
|
||||
"name_zh": "状态上报间隔(秒)",
|
||||
"attribute": "required",
|
||||
"type": "int",
|
||||
"condition": {
|
||||
"field": "upload_drv_state",
|
||||
"value": true
|
||||
},
|
||||
"default": 1,
|
||||
"valid": {
|
||||
"min": 1,
|
||||
"max": 3600
|
||||
}
|
||||
},
|
||||
"offline-cache": {
|
||||
"name": "Offline Data Caching",
|
||||
"name_zh": "离线缓存",
|
||||
"description": "Offline caching switch. Cache MQTT messages when offline, and sync cached messages when back online.",
|
||||
"description_zh": "离线缓存开关。连接断开时缓存 MQTT 消息,连接重建时同步缓存的 MQTT 消息到服务器。",
|
||||
"attribute": "optional",
|
||||
"type": "bool",
|
||||
"default": false,
|
||||
"valid": {}
|
||||
},
|
||||
"cache-mem-size": {
|
||||
"name": "Cache Memory Size (MB)",
|
||||
"name_zh": "缓存内存大小(MB)",
|
||||
"description": "Max in-memory cache size in megabytes when MQTT connection exception occurs. Should be smaller than cache disk size.",
|
||||
"description_zh": "当 MQTT 连接异常时,最大的内存缓存大小(单位:MB)。应该小于缓存磁盘大小。",
|
||||
"type": "int",
|
||||
"attribute": "required",
|
||||
"condition": {
|
||||
"field": "offline-cache",
|
||||
"value": true
|
||||
},
|
||||
"valid": {
|
||||
"min": 1,
|
||||
"max": 1024
|
||||
}
|
||||
},
|
||||
"cache-disk-size": {
|
||||
"name": "Cache Disk Size (MB)",
|
||||
"name_zh": "缓存磁盘大小(MB)",
|
||||
"description": "Max in-disk cache size in megabytes when MQTT connection exception occurs. Should be larger than cache memory size. If nonzero, cache memory size should also be nonzero.",
|
||||
"description_zh": "当 MQTT 连接异常时,最大的磁盘缓存大小(单位:MB)。应该大于缓存内存大小。如果不为 0,缓存内存大小也应该不为 0。",
|
||||
"type": "int",
|
||||
"attribute": "required",
|
||||
"condition": {
|
||||
"field": "offline-cache",
|
||||
"value": true
|
||||
},
|
||||
"valid": {
|
||||
"min": 1,
|
||||
"max": 10240
|
||||
}
|
||||
},
|
||||
"cache-sync-interval": {
|
||||
"name": "Cache Sync Interval (MS)",
|
||||
"name_zh": "缓存消息重传间隔(MS)",
|
||||
"type": "int",
|
||||
"attribute": "required",
|
||||
"condition": {
|
||||
"field": "offline-cache",
|
||||
"value": true
|
||||
},
|
||||
"default": 100,
|
||||
"valid": {
|
||||
"min": 10,
|
||||
"max": 120000
|
||||
}
|
||||
},
|
||||
"host": {
|
||||
"name": "Broker Host",
|
||||
"name_zh": "服务器地址",
|
||||
"attribute": "required",
|
||||
"type": "string",
|
||||
"default": "broker.emqx.io",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"port": {
|
||||
"name": "Broker Port",
|
||||
"name_zh": "服务器端口",
|
||||
"attribute": "required",
|
||||
"type": "int",
|
||||
"default": 1883,
|
||||
"valid": {
|
||||
"min": 1,
|
||||
"max": 65535
|
||||
}
|
||||
},
|
||||
"username": {
|
||||
"name": "Username",
|
||||
"name_zh": "用户名",
|
||||
"attribute": "optional",
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"password": {
|
||||
"name": "Password",
|
||||
"name_zh": "密码",
|
||||
"attribute": "optional",
|
||||
"type": "string",
|
||||
"default": "",
|
||||
"valid": {
|
||||
"length": 255
|
||||
}
|
||||
},
|
||||
"ssl": {
|
||||
"name": "SSL",
|
||||
"name_zh": "SSL",
|
||||
"description": "Enable SSL connection",
|
||||
"description_zh": "是否启用 SSL 连接",
|
||||
"attribute": "optional",
|
||||
"type": "bool",
|
||||
"default": false,
|
||||
"valid": {}
|
||||
},
|
||||
"ca": {
|
||||
"name": "CA",
|
||||
"name_zh": "CA 证书",
|
||||
"description": "CA certificate which signs the server certificate",
|
||||
"description_zh": "签发服务器证书的 CA 证书",
|
||||
"attribute": "optional",
|
||||
"type": "file",
|
||||
"condition": {
|
||||
"field": "ssl",
|
||||
"value": true
|
||||
},
|
||||
"valid": {
|
||||
"length": 81960
|
||||
}
|
||||
},
|
||||
"cert": {
|
||||
"name": "Client Cert",
|
||||
"name_zh": "客户端证书",
|
||||
"description": "Client x509 certificate when using two way authentication",
|
||||
"description_zh": "使用双向认证时,客户端的 x509 证书",
|
||||
"attribute": "optional",
|
||||
"type": "file",
|
||||
"condition": {
|
||||
"field": "ssl",
|
||||
"value": true
|
||||
},
|
||||
"valid": {
|
||||
"length": 81960
|
||||
}
|
||||
},
|
||||
"key": {
|
||||
"name": "Client Private Key",
|
||||
"name_zh": "客户端私钥",
|
||||
"description": "Client private key when using two way authentication",
|
||||
"description_zh": "使用双向认证时,客户端的私钥",
|
||||
"attribute": "optional",
|
||||
"type": "file",
|
||||
"condition": {
|
||||
"field": "ssl",
|
||||
"value": true
|
||||
},
|
||||
"valid": {
|
||||
"length": 81960
|
||||
}
|
||||
}
|
||||
}
|
||||
+140
-32
@@ -19,6 +19,7 @@
|
||||
|
||||
#include "connection/mqtt_client.h"
|
||||
#include "errcodes.h"
|
||||
#include "otel/otel_manager.h"
|
||||
#include "utils/asprintf.h"
|
||||
#include "version.h"
|
||||
#include "json/neu_json_mqtt.h"
|
||||
@@ -27,6 +28,17 @@
|
||||
#include "mqtt_handle.h"
|
||||
#include "mqtt_plugin.h"
|
||||
|
||||
static void to_traceparent(uint8_t *trace_id, char *span_id, char *out)
|
||||
{
|
||||
int size = 0;
|
||||
size = sprintf(out, "00-");
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
size += sprintf(out + size, "%02x", trace_id[i]);
|
||||
}
|
||||
|
||||
sprintf(out + size, "-%s-01", span_id);
|
||||
}
|
||||
|
||||
static int tag_values_to_json(UT_array *tags, neu_json_read_resp_t *json)
|
||||
{
|
||||
int index = 0;
|
||||
@@ -70,7 +82,7 @@ char *generate_upload_json(neu_plugin_t *plugin, neu_reqresp_trans_data_t *data,
|
||||
neu_json_encode_read_periodic_resp,
|
||||
&json_str);
|
||||
} else if (MQTT_UPLOAD_FORMAT_TAGS == format) { // tags
|
||||
neu_json_encode_with_mqtt(&json, neu_json_encode_read_resp, &header,
|
||||
neu_json_encode_with_mqtt(&json, neu_json_encode_read_resp2, &header,
|
||||
neu_json_encode_read_periodic_resp,
|
||||
&json_str);
|
||||
} else {
|
||||
@@ -217,11 +229,26 @@ static int json_value_to_tag_value(union neu_json_value *req,
|
||||
value->type = NEU_TYPE_BOOL;
|
||||
value->value.boolean = req->val_bool;
|
||||
break;
|
||||
case NEU_JSON_BYTES:
|
||||
value->type = NEU_TYPE_BYTES;
|
||||
value->value.bytes.length = req->val_bytes.length;
|
||||
memcpy(value->value.bytes.bytes, req->val_bytes.bytes,
|
||||
req->val_bytes.length);
|
||||
case NEU_JSON_ARRAY_BOOL:
|
||||
value->type = NEU_TYPE_ARRAY_BOOL;
|
||||
value->value.bools.length = req->val_array_bool.length;
|
||||
for (int i = 0; i < req->val_array_bool.length; i++) {
|
||||
value->value.bools.bools[i] = req->val_array_bool.bools[i];
|
||||
}
|
||||
break;
|
||||
case NEU_JSON_ARRAY_DOUBLE:
|
||||
value->type = NEU_TYPE_ARRAY_DOUBLE;
|
||||
value->value.f64s.length = req->val_array_double.length;
|
||||
for (int i = 0; i < req->val_array_double.length; i++) {
|
||||
value->value.f64s.f64s[i] = req->val_array_double.f64s[i];
|
||||
}
|
||||
break;
|
||||
case NEU_JSON_ARRAY_INT64:
|
||||
value->type = NEU_TYPE_ARRAY_INT64;
|
||||
value->value.i64s.length = req->val_array_int64.length;
|
||||
for (int i = 0; i < req->val_array_int64.length; i++) {
|
||||
value->value.i64s.i64s[i] = req->val_array_int64.i64s[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
@@ -364,6 +391,24 @@ int publish(neu_plugin_t *plugin, neu_mqtt_qos_e qos, char *topic,
|
||||
return rv;
|
||||
}
|
||||
|
||||
int publish_with_trace(neu_plugin_t *plugin, neu_mqtt_qos_e qos, char *topic,
|
||||
char *payload, size_t payload_len,
|
||||
const char *traceparent)
|
||||
{
|
||||
int rv = neu_mqtt_client_publish_with_trace(
|
||||
plugin->client, qos, topic, (uint8_t *) payload, (uint32_t) payload_len,
|
||||
plugin, publish_cb, traceparent);
|
||||
if (0 != rv) {
|
||||
plog_error(plugin, "pub [%s, QoS%d] fail", topic, qos);
|
||||
NEU_PLUGIN_UPDATE_METRIC(plugin, NEU_METRIC_SEND_MSG_ERRORS_TOTAL, 1,
|
||||
NULL);
|
||||
free(payload);
|
||||
rv = NEU_ERR_MQTT_PUBLISH_FAILURE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
void handle_write_req(neu_mqtt_qos_e qos, const char *topic,
|
||||
const uint8_t *payload, uint32_t len, void *data,
|
||||
trace_w3c_t *trace_w3c)
|
||||
@@ -430,7 +475,8 @@ void handle_write_req(neu_mqtt_qos_e qos, const char *topic,
|
||||
}
|
||||
|
||||
int handle_write_response(neu_plugin_t *plugin, neu_json_mqtt_t *mqtt_json,
|
||||
neu_resp_error_t *data)
|
||||
neu_resp_error_t *data, void *trace_scope,
|
||||
void *trace_ctx, char *span_id)
|
||||
{
|
||||
int rv = 0;
|
||||
char *json_str = NULL;
|
||||
@@ -455,9 +501,25 @@ int handle_write_response(neu_plugin_t *plugin, neu_json_mqtt_t *mqtt_json,
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (trace_scope) {
|
||||
neu_otel_scope_add_span_attr_string(trace_scope, "playload", json_str);
|
||||
}
|
||||
|
||||
char trace_parent[128] = { 0 };
|
||||
|
||||
if (trace_ctx && span_id) {
|
||||
uint8_t *trace_id = neu_otel_get_trace_id(trace_ctx);
|
||||
to_traceparent(trace_id, span_id, trace_parent);
|
||||
}
|
||||
|
||||
char * topic = plugin->config.write_resp_topic;
|
||||
neu_mqtt_qos_e qos = plugin->config.qos;
|
||||
rv = publish(plugin, qos, topic, json_str, strlen(json_str));
|
||||
if (trace_ctx != 0 && strlen(trace_parent) != 0) {
|
||||
rv = publish_with_trace(plugin, qos, topic, json_str, strlen(json_str),
|
||||
trace_parent);
|
||||
} else {
|
||||
rv = publish(plugin, qos, topic, json_str, strlen(json_str));
|
||||
}
|
||||
json_str = NULL;
|
||||
|
||||
end:
|
||||
@@ -566,35 +628,81 @@ int handle_trans_data(neu_plugin_t * plugin,
|
||||
{
|
||||
int rv = 0;
|
||||
|
||||
if (NULL == plugin->client) {
|
||||
return NEU_ERR_MQTT_IS_NULL;
|
||||
neu_otel_trace_ctx trans_trace = NULL;
|
||||
neu_otel_scope_ctx trans_scope = NULL;
|
||||
uint8_t * trace_id = NULL;
|
||||
char trace_parent[128] = { 0 };
|
||||
if (neu_otel_data_is_started() && trans_data->trace_ctx) {
|
||||
trans_trace = neu_otel_find_trace(trans_data->trace_ctx);
|
||||
if (trans_trace) {
|
||||
char new_span_id[36] = { 0 };
|
||||
neu_otel_new_span_id(new_span_id);
|
||||
trans_scope =
|
||||
neu_otel_add_span2(trans_trace, "mqtt publish", new_span_id);
|
||||
neu_otel_scope_add_span_attr_int(trans_scope, "thread id",
|
||||
(int64_t)(pthread_self()));
|
||||
neu_otel_scope_set_span_start_time(trans_scope, neu_time_ns());
|
||||
|
||||
trace_id = neu_otel_get_trace_id(trans_trace);
|
||||
|
||||
to_traceparent(trace_id, new_span_id, trace_parent);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == plugin->config.cache &&
|
||||
!neu_mqtt_client_is_connected(plugin->client)) {
|
||||
// cache disable and we are disconnected
|
||||
return NEU_ERR_MQTT_FAILURE;
|
||||
}
|
||||
do {
|
||||
|
||||
const route_entry_t *route = route_tbl_get(
|
||||
&plugin->route_tbl, trans_data->driver, trans_data->group);
|
||||
if (NULL == route) {
|
||||
plog_error(plugin, "no route for driver:%s group:%s",
|
||||
trans_data->driver, trans_data->group);
|
||||
return NEU_ERR_GROUP_NOT_SUBSCRIBE;
|
||||
}
|
||||
if (NULL == plugin->client) {
|
||||
rv = NEU_ERR_MQTT_IS_NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
char *json_str =
|
||||
generate_upload_json(plugin, trans_data, plugin->config.format);
|
||||
if (NULL == json_str) {
|
||||
plog_error(plugin, "generate upload json fail");
|
||||
return NEU_ERR_EINTERNAL;
|
||||
}
|
||||
if (0 == plugin->config.cache &&
|
||||
!neu_mqtt_client_is_connected(plugin->client)) {
|
||||
// cache disable and we are disconnected
|
||||
rv = NEU_ERR_MQTT_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
char * topic = route->topic;
|
||||
neu_mqtt_qos_e qos = plugin->config.qos;
|
||||
rv = publish(plugin, qos, topic, json_str, strlen(json_str));
|
||||
json_str = NULL;
|
||||
const route_entry_t *route = route_tbl_get(
|
||||
&plugin->route_tbl, trans_data->driver, trans_data->group);
|
||||
if (NULL == route) {
|
||||
plog_error(plugin, "no route for driver:%s group:%s",
|
||||
trans_data->driver, trans_data->group);
|
||||
rv = NEU_ERR_GROUP_NOT_SUBSCRIBE;
|
||||
break;
|
||||
}
|
||||
|
||||
char *json_str =
|
||||
generate_upload_json(plugin, trans_data, plugin->config.format);
|
||||
if (NULL == json_str) {
|
||||
plog_error(plugin, "generate upload json fail");
|
||||
rv = NEU_ERR_EINTERNAL;
|
||||
break;
|
||||
}
|
||||
|
||||
char * topic = route->topic;
|
||||
neu_mqtt_qos_e qos = plugin->config.qos;
|
||||
|
||||
if (plugin->config.version == NEU_MQTT_VERSION_V5 && trans_trace) {
|
||||
rv = publish_with_trace(plugin, qos, topic, json_str,
|
||||
strlen(json_str), trace_parent);
|
||||
} else {
|
||||
rv = publish(plugin, qos, topic, json_str, strlen(json_str));
|
||||
}
|
||||
|
||||
json_str = NULL;
|
||||
} while (0);
|
||||
|
||||
if (trans_trace) {
|
||||
if (rv == NEU_ERR_SUCCESS) {
|
||||
neu_otel_scope_set_status_code2(trans_scope, NEU_OTEL_STATUS_OK, 0);
|
||||
} else {
|
||||
neu_otel_scope_set_status_code2(trans_scope, NEU_OTEL_STATUS_ERROR,
|
||||
rv);
|
||||
}
|
||||
neu_otel_scope_set_span_end_time(trans_scope, neu_time_ns());
|
||||
neu_otel_trace_set_final(trans_trace);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -31,12 +31,17 @@ extern "C" {
|
||||
int publish(neu_plugin_t *plugin, neu_mqtt_qos_e qos, char *topic,
|
||||
char *payload, size_t payload_len);
|
||||
|
||||
int publish_with_trace(neu_plugin_t *plugin, neu_mqtt_qos_e qos, char *topic,
|
||||
char *payload, size_t payload_len,
|
||||
const char *traceparent);
|
||||
|
||||
void handle_write_req(neu_mqtt_qos_e qos, const char *topic,
|
||||
const uint8_t *payload, uint32_t len, void *data,
|
||||
trace_w3c_t *trace_w3c);
|
||||
|
||||
int handle_write_response(neu_plugin_t *plugin, neu_json_mqtt_t *mqtt_json,
|
||||
neu_resp_error_t *data);
|
||||
neu_resp_error_t *data, void *trace_scope,
|
||||
void *trace_ctx, char *span_id);
|
||||
|
||||
void handle_read_req(neu_mqtt_qos_e qos, const char *topic,
|
||||
const uint8_t *payload, uint32_t len, void *data,
|
||||
|
||||
@@ -460,14 +460,14 @@ int mqtt_plugin_request(neu_plugin_t *plugin, neu_reqresp_head_t *head,
|
||||
plugin->cache_metric_update_ts = global_timestamp;
|
||||
}
|
||||
|
||||
neu_otel_trace_ctx *trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
if (neu_otel_control_is_started()) {
|
||||
neu_otel_trace_ctx trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
char new_span_id[36] = { 0 };
|
||||
if (neu_otel_control_is_started() && head->ctx) {
|
||||
trace = neu_otel_find_trace(head->ctx);
|
||||
if (trace) {
|
||||
scope = neu_otel_add_span(trace);
|
||||
neu_otel_scope_set_span_name(scope, "mqtt response");
|
||||
char new_span_id[36] = { 0 };
|
||||
neu_otel_new_span_id(new_span_id);
|
||||
neu_otel_scope_set_span_id(scope, new_span_id);
|
||||
uint8_t *p_sp_id = neu_otel_scope_get_pre_span_id(scope);
|
||||
@@ -476,13 +476,14 @@ int mqtt_plugin_request(neu_plugin_t *plugin, neu_reqresp_head_t *head,
|
||||
}
|
||||
neu_otel_scope_add_span_attr_int(scope, "thread id",
|
||||
(int64_t)(pthread_self()));
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ns());
|
||||
}
|
||||
}
|
||||
|
||||
switch (head->type) {
|
||||
case NEU_RESP_ERROR:
|
||||
error = handle_write_response(plugin, head->ctx, data);
|
||||
error = handle_write_response(plugin, head->ctx, data, scope, trace,
|
||||
new_span_id);
|
||||
break;
|
||||
case NEU_RESP_GET_NODES_STATE: {
|
||||
handle_nodes_state(head->ctx, (neu_resp_get_nodes_state_t *) data);
|
||||
@@ -537,8 +538,13 @@ int mqtt_plugin_request(neu_plugin_t *plugin, neu_reqresp_head_t *head,
|
||||
}
|
||||
|
||||
if (trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", error);
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ms());
|
||||
if (error == NEU_ERR_SUCCESS) {
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, 0);
|
||||
} else {
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_ERROR,
|
||||
error);
|
||||
}
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
|
||||
|
||||
@@ -41,43 +41,73 @@ void handle_add_tags(nng_aio *aio)
|
||||
} else if (strlen(req->group) >= NEU_GROUP_NAME_LEN) {
|
||||
CHECK_GROUP_NAME_LENGTH_ERR;
|
||||
} else {
|
||||
int ret = 0;
|
||||
neu_reqresp_head_t header = { 0 };
|
||||
neu_req_add_tag_t cmd = { 0 };
|
||||
header.otel_trace_type = NEU_OTEL_TRACE_TYPE_REST_COMM;
|
||||
|
||||
header.ctx = aio;
|
||||
header.type = NEU_REQ_ADD_TAG;
|
||||
strcpy(cmd.driver, req->node);
|
||||
strcpy(cmd.group, req->group);
|
||||
cmd.n_tag = req->n_tag;
|
||||
cmd.tags = calloc(req->n_tag, sizeof(neu_datatag_t));
|
||||
neu_reqresp_head_t header = { 0 };
|
||||
neu_req_add_tag_t cmd = { 0 };
|
||||
header.otel_trace_type = NEU_OTEL_TRACE_TYPE_REST_COMM;
|
||||
neu_resp_add_tag_t add_resp = { 0 };
|
||||
|
||||
for (int i = 0; i < req->n_tag; i++) {
|
||||
cmd.tags[i].attribute = req->tags[i].attribute;
|
||||
cmd.tags[i].type = req->tags[i].type;
|
||||
cmd.tags[i].precision = req->tags[i].precision;
|
||||
cmd.tags[i].decimal = req->tags[i].decimal;
|
||||
cmd.tags[i].bias = req->tags[i].bias;
|
||||
cmd.tags[i].address = strdup(req->tags[i].address);
|
||||
cmd.tags[i].name = strdup(req->tags[i].name);
|
||||
if (req->tags[i].description != NULL) {
|
||||
cmd.tags[i].description =
|
||||
strdup(req->tags[i].description);
|
||||
} else {
|
||||
cmd.tags[i].description = strdup("");
|
||||
}
|
||||
if (NEU_ATTRIBUTE_STATIC & req->tags[i].attribute) {
|
||||
neu_tag_set_static_value_json(
|
||||
&cmd.tags[i], req->tags[i].t, &req->tags[i].value);
|
||||
if (req->tags[i].type == NEU_TYPE_STRING ||
|
||||
req->tags[i].type == NEU_TYPE_BOOL ||
|
||||
req->tags[i].type == NEU_TYPE_BIT ||
|
||||
req->tags[i].type == NEU_TYPE_TIME ||
|
||||
req->tags[i].type == NEU_TYPE_DATA_AND_TIME) {
|
||||
if (req->tags[i].precision > 0) {
|
||||
add_resp.index = i;
|
||||
add_resp.error = NEU_ERR_TAG_PRECISION_INVALID;
|
||||
break;
|
||||
}
|
||||
if (req->tags[i].decimal > 0) {
|
||||
add_resp.index = i;
|
||||
add_resp.error = NEU_ERR_TAG_DECIMAL_INVALID;
|
||||
break;
|
||||
}
|
||||
if (req->tags[i].bias > 0) {
|
||||
add_resp.index = i;
|
||||
add_resp.error = NEU_ERR_TAG_BIAS_INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = neu_plugin_op(plugin, header, &cmd);
|
||||
if (ret != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, {
|
||||
neu_http_response(aio, NEU_ERR_IS_BUSY, result_error);
|
||||
});
|
||||
if (add_resp.error > 0) {
|
||||
handle_add_tags_resp(aio, &add_resp);
|
||||
} else {
|
||||
header.ctx = aio;
|
||||
header.type = NEU_REQ_ADD_TAG;
|
||||
strcpy(cmd.driver, req->node);
|
||||
strcpy(cmd.group, req->group);
|
||||
cmd.n_tag = req->n_tag;
|
||||
cmd.tags = calloc(req->n_tag, sizeof(neu_datatag_t));
|
||||
|
||||
for (int i = 0; i < req->n_tag; i++) {
|
||||
cmd.tags[i].attribute = req->tags[i].attribute;
|
||||
cmd.tags[i].type = req->tags[i].type;
|
||||
cmd.tags[i].precision = req->tags[i].precision;
|
||||
cmd.tags[i].decimal = req->tags[i].decimal;
|
||||
cmd.tags[i].bias = req->tags[i].bias;
|
||||
cmd.tags[i].address = strdup(req->tags[i].address);
|
||||
cmd.tags[i].name = strdup(req->tags[i].name);
|
||||
if (req->tags[i].description != NULL) {
|
||||
cmd.tags[i].description =
|
||||
strdup(req->tags[i].description);
|
||||
} else {
|
||||
cmd.tags[i].description = strdup("");
|
||||
}
|
||||
if (NEU_ATTRIBUTE_STATIC & req->tags[i].attribute) {
|
||||
neu_tag_set_static_value_json(&cmd.tags[i],
|
||||
req->tags[i].t,
|
||||
&req->tags[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
int ret = neu_plugin_op(plugin, header, &cmd);
|
||||
if (ret != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, {
|
||||
neu_http_response(aio, NEU_ERR_IS_BUSY,
|
||||
result_error);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -108,9 +138,11 @@ void handle_add_gtags(nng_aio *aio)
|
||||
neu_reqresp_head_t header = { 0 };
|
||||
neu_req_add_gtag_t cmd = { 0 };
|
||||
int err_type;
|
||||
header.ctx = aio;
|
||||
header.type = NEU_REQ_ADD_GTAG;
|
||||
header.otel_trace_type = NEU_OTEL_TRACE_TYPE_REST_COMM;
|
||||
int n_tags = 0;
|
||||
neu_resp_add_tag_t add_resp = { 0 };
|
||||
header.ctx = aio;
|
||||
header.type = NEU_REQ_ADD_GTAG;
|
||||
header.otel_trace_type = NEU_OTEL_TRACE_TYPE_REST_COMM;
|
||||
|
||||
if (strlen(req->node) >= NEU_NODE_NAME_LEN) {
|
||||
err_type = NEU_ERR_NODE_NAME_TOO_LONG;
|
||||
@@ -126,58 +158,90 @@ void handle_add_gtags(nng_aio *aio)
|
||||
err_type = NEU_ERR_GROUP_PARAMETER_INVALID;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
strcpy(cmd.driver, req->node);
|
||||
cmd.n_group = req->n_group;
|
||||
cmd.groups = calloc(req->n_group, sizeof(neu_gdatatag_t));
|
||||
|
||||
for (int i = 0; i < req->n_group; i++) {
|
||||
strcpy(cmd.groups[i].group, req->groups[i].group);
|
||||
cmd.groups[i].n_tag = req->groups[i].n_tag;
|
||||
cmd.groups[i].interval = req->groups[i].interval;
|
||||
cmd.groups[i].tags =
|
||||
calloc(cmd.groups[i].n_tag, sizeof(neu_datatag_t));
|
||||
|
||||
for (int j = 0; j < req->groups[i].n_tag; j++) {
|
||||
cmd.groups[i].tags[j].attribute =
|
||||
req->groups[i].tags[j].attribute;
|
||||
cmd.groups[i].tags[j].type = req->groups[i].tags[j].type;
|
||||
cmd.groups[i].tags[j].precision =
|
||||
req->groups[i].tags[j].precision;
|
||||
cmd.groups[i].tags[j].decimal =
|
||||
req->groups[i].tags[j].decimal;
|
||||
cmd.groups[i].tags[j].bias = req->groups[i].tags[j].bias;
|
||||
cmd.groups[i].tags[j].address =
|
||||
strdup(req->groups[i].tags[j].address);
|
||||
cmd.groups[i].tags[j].name =
|
||||
strdup(req->groups[i].tags[j].name);
|
||||
if (req->groups[i].tags[j].description != NULL) {
|
||||
cmd.groups[i].tags[j].description =
|
||||
strdup(req->groups[i].tags[j].description);
|
||||
} else {
|
||||
cmd.groups[i].tags[j].description = strdup("");
|
||||
}
|
||||
if (NEU_ATTRIBUTE_STATIC &
|
||||
req->groups[i].tags[j].attribute) {
|
||||
neu_tag_set_static_value_json(
|
||||
&cmd.groups[i].tags[j], req->groups[i].tags[j].t,
|
||||
&req->groups[i].tags[j].value);
|
||||
if (req->groups[i].tags[j].type == NEU_TYPE_STRING ||
|
||||
req->groups[i].tags[j].type == NEU_TYPE_BOOL ||
|
||||
req->groups[i].tags[j].type == NEU_TYPE_BIT ||
|
||||
req->groups[i].tags[j].type == NEU_TYPE_TIME ||
|
||||
req->groups[i].tags[j].type == NEU_TYPE_DATA_AND_TIME) {
|
||||
if (req->groups[i].tags[j].precision > 0) {
|
||||
add_resp.index = n_tags + j;
|
||||
add_resp.error = NEU_ERR_TAG_PRECISION_INVALID;
|
||||
break;
|
||||
}
|
||||
if (req->groups[i].tags[j].decimal > 0) {
|
||||
add_resp.index = n_tags + j;
|
||||
add_resp.error = NEU_ERR_TAG_DECIMAL_INVALID;
|
||||
break;
|
||||
}
|
||||
if (req->groups[i].tags[j].bias > 0) {
|
||||
add_resp.index = n_tags + j;
|
||||
add_resp.error = NEU_ERR_TAG_BIAS_INVALID;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = neu_plugin_op(plugin, header, &cmd);
|
||||
if (ret != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, {
|
||||
neu_http_response(aio, NEU_ERR_IS_BUSY, result_error);
|
||||
n_tags += req->groups[i].n_tag;
|
||||
}
|
||||
if (add_resp.error > 0) {
|
||||
handle_add_tags_resp(aio, &add_resp);
|
||||
} else {
|
||||
strcpy(cmd.driver, req->node);
|
||||
cmd.n_group = req->n_group;
|
||||
cmd.groups = calloc(req->n_group, sizeof(neu_gdatatag_t));
|
||||
|
||||
for (int i = 0; i < req->n_group; i++) {
|
||||
strcpy(cmd.groups[i].group, req->groups[i].group);
|
||||
cmd.groups[i].n_tag = req->groups[i].n_tag;
|
||||
cmd.groups[i].interval = req->groups[i].interval;
|
||||
cmd.groups[i].tags =
|
||||
calloc(cmd.groups[i].n_tag, sizeof(neu_datatag_t));
|
||||
|
||||
for (int j = 0; j < req->groups[i].n_tag; j++) {
|
||||
cmd.groups[i].tags[j].attribute =
|
||||
req->groups[i].tags[j].attribute;
|
||||
cmd.groups[i].tags[j].type =
|
||||
req->groups[i].tags[j].type;
|
||||
cmd.groups[i].tags[j].precision =
|
||||
req->groups[i].tags[j].precision;
|
||||
cmd.groups[i].tags[j].decimal =
|
||||
req->groups[i].tags[j].decimal;
|
||||
cmd.groups[i].tags[j].bias =
|
||||
req->groups[i].tags[j].bias;
|
||||
cmd.groups[i].tags[j].address =
|
||||
strdup(req->groups[i].tags[j].address);
|
||||
cmd.groups[i].tags[j].name =
|
||||
strdup(req->groups[i].tags[j].name);
|
||||
if (req->groups[i].tags[j].description != NULL) {
|
||||
cmd.groups[i].tags[j].description =
|
||||
strdup(req->groups[i].tags[j].description);
|
||||
} else {
|
||||
cmd.groups[i].tags[j].description = strdup("");
|
||||
}
|
||||
if (NEU_ATTRIBUTE_STATIC &
|
||||
req->groups[i].tags[j].attribute) {
|
||||
neu_tag_set_static_value_json(
|
||||
&cmd.groups[i].tags[j],
|
||||
req->groups[i].tags[j].t,
|
||||
&req->groups[i].tags[j].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ret = neu_plugin_op(plugin, header, &cmd);
|
||||
if (ret != 0) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, {
|
||||
neu_http_response(aio, NEU_ERR_IS_BUSY, result_error);
|
||||
});
|
||||
}
|
||||
goto success;
|
||||
error:
|
||||
NEU_JSON_RESPONSE_ERROR(err_type, {
|
||||
neu_http_response(aio, err_type, result_error);
|
||||
});
|
||||
success:;
|
||||
}
|
||||
goto success;
|
||||
error:
|
||||
NEU_JSON_RESPONSE_ERROR(
|
||||
err_type, { neu_http_response(aio, err_type, result_error); });
|
||||
success:;
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -307,7 +307,7 @@ void handle_get_plugin_schema(nng_aio *aio)
|
||||
return;
|
||||
}
|
||||
|
||||
if (0 > neu_asprintf(&schema_path, "%s/schema/%s.json", g_plugin_dir,
|
||||
if (0 > neu_asprintf(&schema_path, "%s/system/schema/%s.json", g_plugin_dir,
|
||||
schema_name)) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_EINTERNAL, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
@@ -316,7 +316,32 @@ void handle_get_plugin_schema(nng_aio *aio)
|
||||
}
|
||||
|
||||
char *buf = NULL;
|
||||
buf = file_string_read(&len, schema_path);
|
||||
|
||||
buf = file_string_read(&len, schema_path);
|
||||
if (NULL == buf) {
|
||||
free(schema_path);
|
||||
if (0 > neu_asprintf(&schema_path, "%s/custom/schema/%s.json",
|
||||
g_plugin_dir, schema_name)) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_EINTERNAL, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
buf = file_string_read(&len, schema_path);
|
||||
}
|
||||
|
||||
if (NULL == buf) {
|
||||
free(schema_path);
|
||||
if (0 > neu_asprintf(&schema_path, "%s/schema/%s.json", g_plugin_dir,
|
||||
schema_name)) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_EINTERNAL, {
|
||||
neu_http_response(aio, error_code.error, result_error);
|
||||
});
|
||||
return;
|
||||
}
|
||||
buf = file_string_read(&len, schema_path);
|
||||
}
|
||||
|
||||
if (NULL == buf) {
|
||||
nlog_info("open %s error: %d", schema_path, errno);
|
||||
neu_http_not_found(aio, "{\"status\": \"error\"}");
|
||||
|
||||
@@ -41,7 +41,7 @@ void handle_add_plugin(nng_aio *aio)
|
||||
header.ctx = aio;
|
||||
header.type = NEU_REQ_ADD_PLUGIN;
|
||||
header.otel_trace_type = NEU_OTEL_TRACE_TYPE_REST_COMM;
|
||||
strcpy(cmd.library, req->library);
|
||||
strncpy(cmd.library, req->library, NEU_PLUGIN_LIBRARY_LEN);
|
||||
cmd.schema_file = req->schema_file;
|
||||
cmd.so_file = req->so_file;
|
||||
ret = neu_plugin_op(plugin, header, &cmd);
|
||||
@@ -66,7 +66,7 @@ void handle_update_plugin(nng_aio *aio)
|
||||
header.ctx = aio;
|
||||
header.type = NEU_REQ_UPDATE_PLUGIN;
|
||||
header.otel_trace_type = NEU_OTEL_TRACE_TYPE_REST_COMM;
|
||||
strcpy(cmd.library, req->library);
|
||||
strncpy(cmd.library, req->library, NEU_PLUGIN_LIBRARY_LEN);
|
||||
cmd.schema_file = req->schema_file;
|
||||
cmd.so_file = req->so_file;
|
||||
ret = neu_plugin_op(plugin, header, &cmd);
|
||||
|
||||
+33
-20
@@ -174,9 +174,9 @@ static int dashb_plugin_request(neu_plugin_t * plugin,
|
||||
return 0;
|
||||
}
|
||||
|
||||
neu_otel_trace_ctx *trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
if (neu_otel_control_is_started()) {
|
||||
neu_otel_trace_ctx trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
if (neu_otel_control_is_started() && header->ctx) {
|
||||
trace = neu_otel_find_trace(header->ctx);
|
||||
if (trace) {
|
||||
scope = neu_otel_add_span(trace);
|
||||
@@ -190,7 +190,7 @@ static int dashb_plugin_request(neu_plugin_t * plugin,
|
||||
}
|
||||
neu_otel_scope_add_span_attr_int(scope, "thread id",
|
||||
(int64_t)(pthread_self()));
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ns());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,33 +201,39 @@ static int dashb_plugin_request(neu_plugin_t * plugin,
|
||||
neu_http_response(header->ctx, error->error, result_error);
|
||||
});
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", error->error);
|
||||
if (error->error != NEU_ERR_SUCCESS) {
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_ERROR,
|
||||
error->error);
|
||||
} else {
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK,
|
||||
error->error);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NEU_RESP_GET_PLUGIN:
|
||||
handle_get_plugin_resp(header->ctx, (neu_resp_get_plugin_t *) data);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", 0);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, 0);
|
||||
}
|
||||
break;
|
||||
case NEU_RESP_GET_NODE:
|
||||
handle_get_adapter_resp(header->ctx, (neu_resp_get_node_t *) data);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", 0);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, 0);
|
||||
}
|
||||
break;
|
||||
case NEU_RESP_GET_GROUP:
|
||||
handle_get_group_resp(header->ctx, (neu_resp_get_group_t *) data);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", 0);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, 0);
|
||||
}
|
||||
break;
|
||||
case NEU_RESP_GET_DRIVER_GROUP:
|
||||
handle_get_driver_group_resp(header->ctx,
|
||||
(neu_resp_get_driver_group_t *) data);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", 0);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, 0);
|
||||
}
|
||||
break;
|
||||
case NEU_RESP_ADD_TAG:
|
||||
@@ -254,62 +260,69 @@ static int dashb_plugin_request(neu_plugin_t * plugin,
|
||||
case NEU_RESP_GET_TAG:
|
||||
handle_get_tags_resp(header->ctx, (neu_resp_get_tag_t *) data);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", 0);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, 0);
|
||||
}
|
||||
break;
|
||||
case NEU_RESP_GET_SUBSCRIBE_GROUP:
|
||||
handle_grp_get_subscribe_resp(header->ctx,
|
||||
(neu_resp_get_subscribe_group_t *) data);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", 0);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, 0);
|
||||
}
|
||||
break;
|
||||
case NEU_RESP_GET_NODE_SETTING:
|
||||
handle_get_node_setting_resp(header->ctx,
|
||||
(neu_resp_get_node_setting_t *) data);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", 0);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, 0);
|
||||
}
|
||||
break;
|
||||
case NEU_RESP_GET_NODES_STATE:
|
||||
handle_get_nodes_state_resp(header->ctx,
|
||||
(neu_resp_get_nodes_state_t *) data);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", 0);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, 0);
|
||||
}
|
||||
break;
|
||||
case NEU_RESP_GET_NODE_STATE:
|
||||
handle_get_node_state_resp(header->ctx,
|
||||
(neu_resp_get_node_state_t *) data);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", 0);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, 0);
|
||||
}
|
||||
break;
|
||||
case NEU_RESP_READ_GROUP:
|
||||
handle_read_resp(header->ctx, (neu_resp_read_group_t *) data);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", 0);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, 0);
|
||||
}
|
||||
break;
|
||||
case NEU_RESP_READ_GROUP_PAGINATE:
|
||||
handle_read_paginate_resp(header->ctx,
|
||||
(neu_resp_read_group_paginate_t *) data);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", 0);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, 0);
|
||||
}
|
||||
break;
|
||||
case NEU_RESP_TEST_READ_TAG:
|
||||
handle_test_read_tag_resp(header->ctx,
|
||||
(neu_resp_test_read_tag_t *) data);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", 0);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, 0);
|
||||
}
|
||||
break;
|
||||
case NEU_RESP_SCAN_TAGS:
|
||||
handle_scan_tags_resp(header->ctx, (neu_resp_scan_tags_t *) data);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(
|
||||
scope, "error", ((neu_resp_scan_tags_t *) data)->error);
|
||||
if (((neu_resp_scan_tags_t *) data)->error != NEU_ERR_SUCCESS) {
|
||||
neu_otel_scope_set_status_code2(
|
||||
scope, NEU_OTEL_STATUS_ERROR,
|
||||
((neu_resp_scan_tags_t *) data)->error);
|
||||
} else {
|
||||
neu_otel_scope_set_status_code2(
|
||||
scope, NEU_OTEL_STATUS_OK,
|
||||
((neu_resp_scan_tags_t *) data)->error);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -320,7 +333,7 @@ static int dashb_plugin_request(neu_plugin_t * plugin,
|
||||
}
|
||||
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
|
||||
|
||||
+111
-45
@@ -245,7 +245,7 @@ void handle_write(nng_aio *aio)
|
||||
}
|
||||
neu_otel_scope_set_span_flags(scope, flags);
|
||||
neu_otel_scope_set_span_start_time(scope,
|
||||
neu_time_ms());
|
||||
neu_time_ns());
|
||||
|
||||
neu_otel_scope_add_span_attr_int(
|
||||
scope, "thread id", (int64_t) pthread_self());
|
||||
@@ -275,24 +275,24 @@ void handle_write(nng_aio *aio)
|
||||
result_error);
|
||||
});
|
||||
if (neu_otel_control_is_started() && trace_flag) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error type",
|
||||
NEU_ERR_STRING_TOO_LONG);
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_status_code2(
|
||||
scope, NEU_OTEL_STATUS_ERROR, NEU_ERR_STRING_TOO_LONG);
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (req->t == NEU_JSON_BYTES &&
|
||||
req->value.val_bytes.length > NEU_VALUE_SIZE) {
|
||||
if (req->t == NEU_JSON_ARRAY_INT64 &&
|
||||
req->value.val_array_int64.length > 128) {
|
||||
NEU_JSON_RESPONSE_ERROR(NEU_ERR_STRING_TOO_LONG, {
|
||||
neu_http_response(aio, NEU_ERR_STRING_TOO_LONG,
|
||||
result_error);
|
||||
});
|
||||
if (neu_otel_control_is_started() && trace_flag) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error type",
|
||||
NEU_ERR_STRING_TOO_LONG);
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_status_code2(
|
||||
scope, NEU_OTEL_STATUS_ERROR, NEU_ERR_STRING_TOO_LONG);
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
return;
|
||||
@@ -329,23 +329,40 @@ void handle_write(nng_aio *aio)
|
||||
case NEU_JSON_STR:
|
||||
cmd.value.type = NEU_TYPE_STRING;
|
||||
strcpy(cmd.value.value.str, req->value.val_str);
|
||||
|
||||
break;
|
||||
case NEU_JSON_BYTES:
|
||||
cmd.value.type = NEU_TYPE_BYTES;
|
||||
cmd.value.value.bytes.length = req->value.val_bytes.length;
|
||||
memcpy(cmd.value.value.bytes.bytes, req->value.val_bytes.bytes,
|
||||
req->value.val_bytes.length);
|
||||
break;
|
||||
case NEU_JSON_DOUBLE:
|
||||
cmd.value.type = NEU_TYPE_DOUBLE;
|
||||
cmd.value.value.d64 = req->value.val_double;
|
||||
|
||||
break;
|
||||
case NEU_JSON_BOOL:
|
||||
cmd.value.type = NEU_TYPE_BOOL;
|
||||
cmd.value.value.boolean = req->value.val_bool;
|
||||
break;
|
||||
case NEU_JSON_ARRAY_INT64:
|
||||
cmd.value.type = NEU_TYPE_ARRAY_INT64;
|
||||
cmd.value.value.i64s.length = req->value.val_array_int64.length;
|
||||
for (int i = 0; i < req->value.val_array_int64.length; i++) {
|
||||
cmd.value.value.i64s.i64s[i] =
|
||||
req->value.val_array_int64.i64s[i];
|
||||
}
|
||||
break;
|
||||
case NEU_JSON_ARRAY_DOUBLE:
|
||||
cmd.value.type = NEU_TYPE_ARRAY_DOUBLE;
|
||||
cmd.value.value.f64s.length =
|
||||
req->value.val_array_double.length;
|
||||
for (int i = 0; i < req->value.val_array_double.length; i++) {
|
||||
cmd.value.value.f64s.f64s[i] =
|
||||
req->value.val_array_double.f64s[i];
|
||||
}
|
||||
break;
|
||||
case NEU_JSON_ARRAY_BOOL:
|
||||
cmd.value.type = NEU_TYPE_ARRAY_BOOL;
|
||||
cmd.value.value.bools.length = req->value.val_array_bool.length;
|
||||
for (int i = 0; i < req->value.val_array_bool.length; i++) {
|
||||
cmd.value.value.bools.bools[i] =
|
||||
req->value.val_array_bool.bools[i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
@@ -355,7 +372,7 @@ void handle_write(nng_aio *aio)
|
||||
if (neu_otel_control_is_started() && trace_flag) {
|
||||
ret = neu_plugin_op(plugin, header, &cmd);
|
||||
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
} else {
|
||||
ret = neu_plugin_op(plugin, header, &cmd);
|
||||
}
|
||||
@@ -366,8 +383,8 @@ void handle_write(nng_aio *aio)
|
||||
neu_http_response(aio, NEU_ERR_IS_BUSY, result_error);
|
||||
});
|
||||
if (neu_otel_control_is_started() && trace_flag) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error type",
|
||||
NEU_ERR_IS_BUSY);
|
||||
neu_otel_scope_set_status_code2(
|
||||
scope, NEU_OTEL_STATUS_ERROR, NEU_ERR_IS_BUSY);
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
}
|
||||
@@ -377,7 +394,8 @@ void handle_write(nng_aio *aio)
|
||||
NEU_JSON_RESPONSE_ERROR(
|
||||
err_type, { neu_http_response(aio, err_type, result_error); });
|
||||
if (neu_otel_control_is_started() && trace_flag) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error type", err_type);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_ERROR,
|
||||
err_type);
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
|
||||
@@ -432,7 +450,7 @@ void handle_write_tags(nng_aio *aio)
|
||||
}
|
||||
neu_otel_scope_set_span_flags(scope, flags);
|
||||
neu_otel_scope_set_span_start_time(scope,
|
||||
neu_time_ms());
|
||||
neu_time_ns());
|
||||
|
||||
neu_otel_scope_add_span_attr_int(
|
||||
scope, "thread id", (int64_t) pthread_self());
|
||||
@@ -466,7 +484,7 @@ void handle_write_tags(nng_aio *aio)
|
||||
neu_otel_scope_add_span_attr_int(
|
||||
scope, "error type", NEU_ERR_STRING_TOO_LONG);
|
||||
neu_otel_scope_set_span_end_time(scope,
|
||||
neu_time_ms());
|
||||
neu_time_ns());
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
return;
|
||||
@@ -512,13 +530,35 @@ void handle_write_tags(nng_aio *aio)
|
||||
cmd.tags[i].value.value.boolean =
|
||||
req->tags[i].value.val_bool;
|
||||
break;
|
||||
case NEU_JSON_BYTES:
|
||||
cmd.tags[i].value.type = NEU_TYPE_BYTES;
|
||||
cmd.tags[i].value.value.bytes.length =
|
||||
req->tags[i].value.val_bytes.length;
|
||||
memcpy(cmd.tags[i].value.value.bytes.bytes,
|
||||
req->tags[i].value.val_bytes.bytes,
|
||||
req->tags[i].value.val_bytes.length);
|
||||
case NEU_JSON_ARRAY_INT64:
|
||||
cmd.tags[i].value.type = NEU_TYPE_ARRAY_INT64;
|
||||
cmd.tags[i].value.value.i64s.length =
|
||||
req->tags[i].value.val_array_int64.length;
|
||||
for (int k = 0;
|
||||
k < req->tags[i].value.val_array_int64.length; k++) {
|
||||
cmd.tags[i].value.value.i64s.i64s[k] =
|
||||
req->tags[i].value.val_array_int64.i64s[k];
|
||||
}
|
||||
break;
|
||||
case NEU_JSON_ARRAY_DOUBLE:
|
||||
cmd.tags[i].value.type = NEU_TYPE_ARRAY_DOUBLE;
|
||||
cmd.tags[i].value.value.f64s.length =
|
||||
req->tags[i].value.val_array_double.length;
|
||||
for (int k = 0;
|
||||
k < req->tags[i].value.val_array_double.length; k++) {
|
||||
cmd.tags[i].value.value.f64s.f64s[k] =
|
||||
req->tags[i].value.val_array_double.f64s[k];
|
||||
}
|
||||
break;
|
||||
case NEU_JSON_ARRAY_BOOL:
|
||||
cmd.tags[i].value.type = NEU_TYPE_ARRAY_BOOL;
|
||||
cmd.tags[i].value.value.bools.length =
|
||||
req->tags[i].value.val_array_bool.length;
|
||||
for (int k = 0;
|
||||
k < req->tags[i].value.val_array_bool.length; k++) {
|
||||
cmd.tags[i].value.value.bools.bools[k] =
|
||||
req->tags[i].value.val_array_bool.bools[k];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
@@ -530,7 +570,7 @@ void handle_write_tags(nng_aio *aio)
|
||||
|
||||
if (neu_otel_control_is_started() && trace_flag) {
|
||||
ret = neu_plugin_op(plugin, header, &cmd);
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
} else {
|
||||
ret = neu_plugin_op(plugin, header, &cmd);
|
||||
}
|
||||
@@ -541,8 +581,8 @@ void handle_write_tags(nng_aio *aio)
|
||||
neu_http_response(aio, NEU_ERR_IS_BUSY, result_error);
|
||||
});
|
||||
if (neu_otel_control_is_started() && trace_flag) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error type",
|
||||
NEU_ERR_IS_BUSY);
|
||||
neu_otel_scope_set_status_code2(
|
||||
scope, NEU_OTEL_STATUS_ERROR, NEU_ERR_IS_BUSY);
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
}
|
||||
@@ -552,7 +592,8 @@ void handle_write_tags(nng_aio *aio)
|
||||
NEU_JSON_RESPONSE_ERROR(
|
||||
err_type, { neu_http_response(aio, err_type, result_error); });
|
||||
if (neu_otel_control_is_started() && trace_flag) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error type", err_type);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_ERROR,
|
||||
err_type);
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
|
||||
@@ -597,13 +638,38 @@ static void trans(neu_json_write_gtags_req_t *req, neu_req_write_gtags_t *cmd)
|
||||
cmd->groups[i].tags[k].value.value.boolean =
|
||||
req->groups[i].tags[k].value.val_bool;
|
||||
break;
|
||||
case NEU_JSON_BYTES:
|
||||
cmd->groups[i].tags[k].value.type = NEU_TYPE_BYTES;
|
||||
cmd->groups[i].tags[k].value.value.bytes.length =
|
||||
req->groups[i].tags[k].value.val_bytes.length;
|
||||
memcpy(cmd->groups[i].tags[k].value.value.bytes.bytes,
|
||||
req->groups[i].tags[k].value.val_bytes.bytes,
|
||||
req->groups[i].tags[k].value.val_bytes.length);
|
||||
case NEU_JSON_ARRAY_INT64:
|
||||
cmd->groups[i].tags[k].value.type = NEU_TYPE_ARRAY_INT64;
|
||||
cmd->groups[i].tags[k].value.value.i64s.length =
|
||||
req->groups[i].tags[k].value.val_array_int64.length;
|
||||
for (int j = 0;
|
||||
j < req->groups[i].tags[k].value.val_array_int64.length;
|
||||
j++) {
|
||||
cmd->groups[i].tags[k].value.value.i64s.i64s[j] =
|
||||
req->groups[i].tags[k].value.val_array_int64.i64s[j];
|
||||
}
|
||||
break;
|
||||
case NEU_JSON_ARRAY_DOUBLE:
|
||||
cmd->groups[i].tags[k].value.type = NEU_TYPE_ARRAY_DOUBLE;
|
||||
cmd->groups[i].tags[k].value.value.f64s.length =
|
||||
req->groups[i].tags[k].value.val_array_double.length;
|
||||
for (int j = 0;
|
||||
j < req->groups[i].tags[k].value.val_array_double.length;
|
||||
j++) {
|
||||
cmd->groups[i].tags[k].value.value.f64s.f64s[j] =
|
||||
req->groups[i].tags[k].value.val_array_double.f64s[j];
|
||||
}
|
||||
break;
|
||||
case NEU_JSON_ARRAY_BOOL:
|
||||
cmd->groups[i].tags[k].value.type = NEU_TYPE_ARRAY_BOOL;
|
||||
cmd->groups[i].tags[k].value.value.bools.length =
|
||||
req->groups[i].tags[k].value.val_array_bool.length;
|
||||
for (int j = 0;
|
||||
j < req->groups[i].tags[k].value.val_array_bool.length;
|
||||
j++) {
|
||||
cmd->groups[i].tags[k].value.value.bools.bools[j] =
|
||||
req->groups[i].tags[k].value.val_array_bool.bools[j];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
@@ -659,7 +725,7 @@ void handle_write_gtags(nng_aio *aio)
|
||||
}
|
||||
neu_otel_scope_set_span_flags(scope, flags);
|
||||
neu_otel_scope_set_span_start_time(scope,
|
||||
neu_time_ms());
|
||||
neu_time_ns());
|
||||
|
||||
neu_otel_scope_add_span_attr_int(
|
||||
scope, "thread id", (int64_t) pthread_self());
|
||||
@@ -688,7 +754,7 @@ void handle_write_gtags(nng_aio *aio)
|
||||
|
||||
if (neu_otel_control_is_started() && trace_flag) {
|
||||
ret = neu_plugin_op(plugin, header, &cmd);
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
} else {
|
||||
ret = neu_plugin_op(plugin, header, &cmd);
|
||||
}
|
||||
@@ -699,8 +765,8 @@ void handle_write_gtags(nng_aio *aio)
|
||||
neu_http_response(aio, NEU_ERR_IS_BUSY, result_error);
|
||||
});
|
||||
if (neu_otel_control_is_started() && trace_flag) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error type",
|
||||
NEU_ERR_IS_BUSY);
|
||||
neu_otel_scope_set_status_code2(
|
||||
scope, NEU_OTEL_STATUS_ERROR, NEU_ERR_IS_BUSY);
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,8 +25,6 @@ mkdir -p ${neuron_bin}/plugins
|
||||
cp ./neuron ${neuron_bin}/
|
||||
cp config/sdk-zlog.conf ${neuron_bin}/config/zlog.conf
|
||||
cp config/dev.conf ${neuron_bin}/config/
|
||||
cp config/neuron.key ${neuron_bin}/config/
|
||||
cp config/neuron.pem ${neuron_bin}/config/
|
||||
cp config/default_plugins.json ${neuron_bin}/config/
|
||||
cp config/*.sql ${neuron_bin}/config/
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ ssize_t modbus_s_rtu_req(uint8_t *req, uint16_t req_len, uint8_t *res,
|
||||
}
|
||||
|
||||
if (code->slave_id != 1 && code->slave_id != 2 && code->slave_id != 3) {
|
||||
return -1;
|
||||
return -2;
|
||||
}
|
||||
|
||||
switch (code->function) {
|
||||
|
||||
+43
-45
@@ -593,26 +593,6 @@ static int adapter_responseto(neu_adapter_t * adapter,
|
||||
neu_reqresp_head_t *pheader = neu_msg_get_header(msg);
|
||||
strcpy(pheader->sender, adapter->name);
|
||||
|
||||
neu_otel_trace_ctx *trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
if (neu_otel_control_is_started()) {
|
||||
trace = neu_otel_find_trace(header->ctx);
|
||||
if (trace) {
|
||||
scope = neu_otel_add_span(trace);
|
||||
neu_otel_scope_set_span_name(scope, "adapter write tag response");
|
||||
char new_span_id[36] = { 0 };
|
||||
neu_otel_new_span_id(new_span_id);
|
||||
neu_otel_scope_set_span_id(scope, new_span_id);
|
||||
uint8_t *p_sp_id = neu_otel_scope_get_pre_span_id(scope);
|
||||
if (p_sp_id) {
|
||||
neu_otel_scope_set_parent_span_id2(scope, p_sp_id, 8);
|
||||
}
|
||||
neu_otel_scope_add_span_attr_int(scope, "thread id",
|
||||
(int64_t) pthread_self());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ms());
|
||||
}
|
||||
}
|
||||
|
||||
int ret = neu_send_msg_to(adapter->control_fd, &dst, msg);
|
||||
if (0 != ret) {
|
||||
nlog_error("adapter: %s send responseto %s failed, ret: %d, errno: %d",
|
||||
@@ -621,10 +601,6 @@ static int adapter_responseto(neu_adapter_t * adapter,
|
||||
neu_msg_free(msg);
|
||||
}
|
||||
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ms());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -798,8 +774,8 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
case NEU_REQ_WRITE_TAG: {
|
||||
neu_resp_error_t error = { 0 };
|
||||
|
||||
neu_otel_trace_ctx *trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
neu_otel_trace_ctx trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
if (neu_otel_control_is_started()) {
|
||||
trace = neu_otel_find_trace(header->ctx);
|
||||
if (trace) {
|
||||
@@ -814,7 +790,7 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
}
|
||||
neu_otel_scope_add_span_attr_int(scope, "thread id",
|
||||
(int64_t) pthread_self());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ns());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -827,7 +803,13 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
re_flag = true;
|
||||
} else {
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", w_error);
|
||||
if (w_error != NEU_ERR_SUCCESS) {
|
||||
neu_otel_scope_set_status_code2(
|
||||
scope, NEU_OTEL_STATUS_ERROR, w_error);
|
||||
} else {
|
||||
neu_otel_scope_set_status_code2(
|
||||
scope, NEU_OTEL_STATUS_OK, w_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -837,13 +819,13 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
neu_msg_exchange(header);
|
||||
reply(adapter, header, &error);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error",
|
||||
NEU_ERR_GROUP_NOT_ALLOW);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_ERROR,
|
||||
NEU_ERR_GROUP_NOT_ALLOW);
|
||||
}
|
||||
}
|
||||
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
if (!re_flag) {
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
@@ -854,8 +836,8 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
case NEU_REQ_WRITE_TAGS: {
|
||||
neu_resp_error_t error = { 0 };
|
||||
|
||||
neu_otel_trace_ctx *trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
neu_otel_trace_ctx trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
if (neu_otel_control_is_started()) {
|
||||
trace = neu_otel_find_trace(header->ctx);
|
||||
if (trace) {
|
||||
@@ -870,7 +852,7 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
}
|
||||
neu_otel_scope_add_span_attr_int(scope, "thread id",
|
||||
(int64_t) pthread_self());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ns());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -883,8 +865,8 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
neu_msg_exchange(header);
|
||||
reply(adapter, header, &error);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error",
|
||||
NEU_ERR_GROUP_NOT_ALLOW);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_ERROR,
|
||||
NEU_ERR_GROUP_NOT_ALLOW);
|
||||
}
|
||||
} else {
|
||||
int w_error = neu_adapter_driver_write_tags(
|
||||
@@ -894,13 +876,21 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
re_flag = true;
|
||||
} else {
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", w_error);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
if (w_error != NEU_ERR_SUCCESS) {
|
||||
neu_otel_scope_set_status_code2(
|
||||
scope, NEU_OTEL_STATUS_ERROR, w_error);
|
||||
} else {
|
||||
neu_otel_scope_set_status_code2(
|
||||
scope, NEU_OTEL_STATUS_OK, w_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
if (!re_flag) {
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
@@ -911,8 +901,8 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
case NEU_REQ_WRITE_GTAGS: {
|
||||
neu_resp_error_t error = { 0 };
|
||||
|
||||
neu_otel_trace_ctx *trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
neu_otel_trace_ctx trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
if (neu_otel_control_is_started()) {
|
||||
trace = neu_otel_find_trace(header->ctx);
|
||||
if (trace) {
|
||||
@@ -927,7 +917,7 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
}
|
||||
neu_otel_scope_add_span_attr_int(scope, "thread id",
|
||||
(int64_t) pthread_self());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ns());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -941,8 +931,8 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
reply(adapter, header, &error);
|
||||
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error",
|
||||
NEU_ERR_GROUP_NOT_ALLOW);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_ERROR,
|
||||
NEU_ERR_GROUP_NOT_ALLOW);
|
||||
}
|
||||
} else {
|
||||
int w_error = neu_adapter_driver_write_gtags(
|
||||
@@ -952,13 +942,21 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
re_flag = true;
|
||||
} else {
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", w_error);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
if (w_error != NEU_ERR_SUCCESS) {
|
||||
neu_otel_scope_set_status_code2(
|
||||
scope, NEU_OTEL_STATUS_ERROR, w_error);
|
||||
} else {
|
||||
neu_otel_scope_set_status_code2(
|
||||
scope, NEU_OTEL_STATUS_OK, w_error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
if (!re_flag) {
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
|
||||
+438
-2
@@ -49,10 +49,16 @@ struct elem {
|
||||
UT_hash_handle hh;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char key[NEU_GROUP_NAME_LEN];
|
||||
void * trace_ctx;
|
||||
UT_hash_handle hh;
|
||||
} group_trace_t;
|
||||
|
||||
struct neu_driver_cache {
|
||||
pthread_mutex_t mtx;
|
||||
|
||||
struct elem *table;
|
||||
group_trace_t * trace_table;
|
||||
struct elem * table;
|
||||
};
|
||||
|
||||
// static void update_tag_error(neu_driver_cache_t *cache, const char *group,
|
||||
@@ -94,6 +100,16 @@ void neu_driver_cache_destroy(neu_driver_cache_t *cache)
|
||||
}
|
||||
free(elem);
|
||||
}
|
||||
|
||||
group_trace_t *elem1 = NULL;
|
||||
group_trace_t *tmp1 = NULL;
|
||||
|
||||
HASH_ITER(hh, cache->trace_table, elem1, tmp1)
|
||||
{
|
||||
HASH_DEL(cache->trace_table, elem1);
|
||||
free(elem1);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&cache->mtx);
|
||||
|
||||
pthread_mutex_destroy(&cache->mtx);
|
||||
@@ -132,6 +148,52 @@ void neu_driver_cache_add(neu_driver_cache_t *cache, const char *group,
|
||||
pthread_mutex_unlock(&cache->mtx);
|
||||
}
|
||||
|
||||
void neu_driver_cache_update_trace(neu_driver_cache_t *cache, const char *group,
|
||||
void *trace_ctx)
|
||||
{
|
||||
group_trace_t *elem = NULL;
|
||||
char key[NEU_GROUP_NAME_LEN] = { 0 };
|
||||
|
||||
strcpy(key, group);
|
||||
|
||||
pthread_mutex_lock(&cache->mtx);
|
||||
HASH_FIND(hh, cache->trace_table, &key, sizeof(key), elem);
|
||||
|
||||
if (elem == NULL) {
|
||||
elem = calloc(1, sizeof(group_trace_t));
|
||||
|
||||
strcpy(elem->key, group);
|
||||
elem->trace_ctx = trace_ctx;
|
||||
|
||||
HASH_ADD(hh, cache->trace_table, key, sizeof(key), elem);
|
||||
}
|
||||
|
||||
elem->trace_ctx = trace_ctx;
|
||||
|
||||
pthread_mutex_unlock(&cache->mtx);
|
||||
}
|
||||
|
||||
void *neu_driver_cache_get_trace(neu_driver_cache_t *cache, const char *group)
|
||||
{
|
||||
group_trace_t *elem = NULL;
|
||||
char key[NEU_GROUP_NAME_LEN] = { 0 };
|
||||
|
||||
void *trace = NULL;
|
||||
|
||||
strcpy(key, group);
|
||||
|
||||
pthread_mutex_lock(&cache->mtx);
|
||||
HASH_FIND(hh, cache->trace_table, &key, sizeof(key), elem);
|
||||
|
||||
if (elem != NULL) {
|
||||
trace = elem->trace_ctx;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&cache->mtx);
|
||||
|
||||
return trace;
|
||||
}
|
||||
|
||||
void neu_driver_cache_update_change(neu_driver_cache_t *cache,
|
||||
const char *group, const char *tag,
|
||||
int64_t timestamp, neu_dvalue_t value,
|
||||
@@ -173,6 +235,7 @@ void neu_driver_cache_update_change(neu_driver_cache_t *cache,
|
||||
case NEU_TYPE_WORD:
|
||||
case NEU_TYPE_DWORD:
|
||||
case NEU_TYPE_LWORD:
|
||||
case NEU_TYPE_ARRAY_CHAR:
|
||||
if (memcmp(&elem->value_old.value, &value.value,
|
||||
sizeof(value.value)) != 0) {
|
||||
elem->changed = true;
|
||||
@@ -190,6 +253,144 @@ void neu_driver_cache_update_change(neu_driver_cache_t *cache,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_BOOL:
|
||||
if (elem->value_old.value.bools.length !=
|
||||
value.value.bools.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value_old.value.bools.bools,
|
||||
value.value.bools.bools,
|
||||
value.value.bools.length) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT8:
|
||||
if (elem->value_old.value.i8s.length !=
|
||||
value.value.i8s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value_old.value.i8s.i8s,
|
||||
value.value.i8s.i8s,
|
||||
value.value.i8s.length) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT8:
|
||||
if (elem->value_old.value.u8s.length !=
|
||||
value.value.u8s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value_old.value.u8s.u8s,
|
||||
value.value.u8s.u8s,
|
||||
value.value.u8s.length) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT16:
|
||||
if (elem->value_old.value.i16s.length !=
|
||||
value.value.i16s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value_old.value.i16s.i16s,
|
||||
value.value.i16s.i16s,
|
||||
value.value.i16s.length * sizeof(int16_t)) !=
|
||||
0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT16:
|
||||
if (elem->value_old.value.u16s.length !=
|
||||
value.value.u16s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value_old.value.u16s.u16s,
|
||||
value.value.u16s.u16s,
|
||||
value.value.u16s.length * sizeof(uint16_t)) !=
|
||||
0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT32:
|
||||
if (elem->value_old.value.i32s.length !=
|
||||
value.value.i32s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value_old.value.i32s.i32s,
|
||||
value.value.i32s.i32s,
|
||||
value.value.i32s.length * sizeof(int32_t)) !=
|
||||
0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT32:
|
||||
if (elem->value_old.value.u32s.length !=
|
||||
value.value.u32s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value_old.value.u32s.u32s,
|
||||
value.value.u32s.u32s,
|
||||
value.value.u32s.length * sizeof(uint32_t)) !=
|
||||
0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT64:
|
||||
if (elem->value_old.value.i64s.length !=
|
||||
value.value.i64s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value_old.value.i64s.i64s,
|
||||
value.value.i64s.i64s,
|
||||
value.value.i64s.length * sizeof(int64_t)) !=
|
||||
0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT64:
|
||||
if (elem->value_old.value.u64s.length !=
|
||||
value.value.u64s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value_old.value.u64s.u64s,
|
||||
value.value.u64s.u64s,
|
||||
value.value.u64s.length * sizeof(uint64_t)) !=
|
||||
0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_FLOAT:
|
||||
if (elem->value_old.value.f32s.length !=
|
||||
value.value.f32s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value_old.value.f32s.f32s,
|
||||
value.value.f32s.f32s,
|
||||
value.value.f32s.length * sizeof(float)) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_DOUBLE:
|
||||
if (elem->value_old.value.f64s.length !=
|
||||
value.value.f64s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value_old.value.f64s.f64s,
|
||||
value.value.f64s.f64s,
|
||||
value.value.f64s.length * sizeof(double)) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_PTR: {
|
||||
if (elem->value_old.value.ptr.length !=
|
||||
value.value.ptr.length) {
|
||||
@@ -248,6 +449,7 @@ void neu_driver_cache_update_change(neu_driver_cache_t *cache,
|
||||
case NEU_TYPE_WORD:
|
||||
case NEU_TYPE_DWORD:
|
||||
case NEU_TYPE_LWORD:
|
||||
case NEU_TYPE_ARRAY_CHAR:
|
||||
if (memcmp(&elem->value.value, &value.value,
|
||||
sizeof(value.value)) != 0) {
|
||||
elem->changed = true;
|
||||
@@ -265,6 +467,126 @@ void neu_driver_cache_update_change(neu_driver_cache_t *cache,
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_BOOL:
|
||||
if (elem->value.value.bools.length !=
|
||||
value.value.bools.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value.value.bools.bools,
|
||||
value.value.bools.bools,
|
||||
value.value.bools.length) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT8:
|
||||
if (elem->value.value.i8s.length != value.value.i8s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value.value.i8s.i8s, value.value.i8s.i8s,
|
||||
value.value.i8s.length) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT8:
|
||||
if (elem->value.value.u8s.length != value.value.u8s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value.value.u8s.u8s, value.value.u8s.u8s,
|
||||
value.value.u8s.length) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT16:
|
||||
if (elem->value.value.i16s.length != value.value.i16s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(
|
||||
elem->value.value.i16s.i16s, value.value.i16s.i16s,
|
||||
value.value.i16s.length * sizeof(int16_t)) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT16:
|
||||
if (elem->value.value.u16s.length != value.value.u16s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(
|
||||
elem->value.value.u16s.u16s, value.value.u16s.u16s,
|
||||
value.value.u16s.length * sizeof(uint16_t)) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT32:
|
||||
if (elem->value.value.i32s.length != value.value.i32s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(
|
||||
elem->value.value.i32s.i32s, value.value.i32s.i32s,
|
||||
value.value.i32s.length * sizeof(int32_t)) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT32:
|
||||
if (elem->value.value.u32s.length != value.value.u32s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(
|
||||
elem->value.value.u32s.u32s, value.value.u32s.u32s,
|
||||
value.value.u32s.length * sizeof(uint32_t)) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT64:
|
||||
if (elem->value.value.i64s.length != value.value.i64s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(
|
||||
elem->value.value.i64s.i64s, value.value.i64s.i64s,
|
||||
value.value.i64s.length * sizeof(int64_t)) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT64:
|
||||
if (elem->value.value.u64s.length != value.value.u64s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(
|
||||
elem->value.value.u64s.u64s, value.value.u64s.u64s,
|
||||
value.value.u64s.length * sizeof(uint64_t)) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_FLOAT:
|
||||
if (elem->value.value.f32s.length != value.value.f32s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value.value.f32s.f32s,
|
||||
value.value.f32s.f32s,
|
||||
value.value.f32s.length * sizeof(float)) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_DOUBLE:
|
||||
if (elem->value.value.f64s.length != value.value.f64s.length) {
|
||||
elem->changed = true;
|
||||
} else {
|
||||
if (memcmp(elem->value.value.f64s.f64s,
|
||||
value.value.f64s.f64s,
|
||||
value.value.f64s.length * sizeof(double)) != 0) {
|
||||
elem->changed = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_PTR: {
|
||||
if (elem->value.value.ptr.length != value.value.ptr.length) {
|
||||
elem->changed = true;
|
||||
@@ -397,6 +719,7 @@ int neu_driver_cache_meta_get(neu_driver_cache_t *cache, const char *group,
|
||||
case NEU_TYPE_STRING:
|
||||
case NEU_TYPE_TIME:
|
||||
case NEU_TYPE_DATA_AND_TIME:
|
||||
case NEU_TYPE_ARRAY_CHAR:
|
||||
memcpy(value->value.value.str, elem->value.value.str,
|
||||
sizeof(elem->value.value.str));
|
||||
break;
|
||||
@@ -406,6 +729,62 @@ int neu_driver_cache_meta_get(neu_driver_cache_t *cache, const char *group,
|
||||
elem->value.value.bytes.bytes,
|
||||
elem->value.value.bytes.length);
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_BOOL:
|
||||
value->value.value.bools.length = elem->value.value.bools.length;
|
||||
memcpy(value->value.value.bools.bools,
|
||||
elem->value.value.bools.bools,
|
||||
elem->value.value.bools.length);
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT8:
|
||||
value->value.value.i8s.length = elem->value.value.i8s.length;
|
||||
memcpy(value->value.value.i8s.i8s, elem->value.value.i8s.i8s,
|
||||
elem->value.value.i8s.length);
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT8:
|
||||
value->value.value.u8s.length = elem->value.value.u8s.length;
|
||||
memcpy(value->value.value.u8s.u8s, elem->value.value.u8s.u8s,
|
||||
elem->value.value.u8s.length);
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT16:
|
||||
value->value.value.i16s.length = elem->value.value.i16s.length;
|
||||
memcpy(value->value.value.i16s.i16s, elem->value.value.i16s.i16s,
|
||||
elem->value.value.i16s.length * sizeof(int16_t));
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT16:
|
||||
value->value.value.u16s.length = elem->value.value.u16s.length;
|
||||
memcpy(value->value.value.u16s.u16s, elem->value.value.u16s.u16s,
|
||||
elem->value.value.u16s.length * sizeof(uint16_t));
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT32:
|
||||
value->value.value.i32s.length = elem->value.value.i32s.length;
|
||||
memcpy(value->value.value.i32s.i32s, elem->value.value.i32s.i32s,
|
||||
elem->value.value.i32s.length * sizeof(int32_t));
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT32:
|
||||
value->value.value.u32s.length = elem->value.value.u32s.length;
|
||||
memcpy(value->value.value.u32s.u32s, elem->value.value.u32s.u32s,
|
||||
elem->value.value.u32s.length * sizeof(uint32_t));
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT64:
|
||||
value->value.value.i64s.length = elem->value.value.i64s.length;
|
||||
memcpy(value->value.value.i64s.i64s, elem->value.value.i64s.i64s,
|
||||
elem->value.value.i64s.length * sizeof(int64_t));
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT64:
|
||||
value->value.value.u64s.length = elem->value.value.u64s.length;
|
||||
memcpy(value->value.value.u64s.u64s, elem->value.value.u64s.u64s,
|
||||
elem->value.value.u64s.length * sizeof(uint64_t));
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_FLOAT:
|
||||
value->value.value.f32s.length = elem->value.value.f32s.length;
|
||||
memcpy(value->value.value.f32s.f32s, elem->value.value.f32s.f32s,
|
||||
elem->value.value.f32s.length * sizeof(float));
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_DOUBLE:
|
||||
value->value.value.f64s.length = elem->value.value.f64s.length;
|
||||
memcpy(value->value.value.f64s.f64s, elem->value.value.f64s.f64s,
|
||||
elem->value.value.f64s.length * sizeof(double));
|
||||
break;
|
||||
case NEU_TYPE_PTR:
|
||||
value->value.value.ptr.length = elem->value.value.ptr.length;
|
||||
value->value.value.ptr.type = elem->value.value.ptr.type;
|
||||
@@ -481,6 +860,7 @@ int neu_driver_cache_meta_get_changed(neu_driver_cache_t *cache,
|
||||
case NEU_TYPE_STRING:
|
||||
case NEU_TYPE_TIME:
|
||||
case NEU_TYPE_DATA_AND_TIME:
|
||||
case NEU_TYPE_ARRAY_CHAR:
|
||||
memcpy(value->value.value.str, elem->value.value.str,
|
||||
sizeof(elem->value.value.str));
|
||||
break;
|
||||
@@ -490,6 +870,62 @@ int neu_driver_cache_meta_get_changed(neu_driver_cache_t *cache,
|
||||
elem->value.value.bytes.bytes,
|
||||
elem->value.value.bytes.length);
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_BOOL:
|
||||
value->value.value.bools.length = elem->value.value.bools.length;
|
||||
memcpy(value->value.value.bools.bools,
|
||||
elem->value.value.bools.bools,
|
||||
elem->value.value.bools.length);
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT8:
|
||||
value->value.value.i8s.length = elem->value.value.i8s.length;
|
||||
memcpy(value->value.value.i8s.i8s, elem->value.value.i8s.i8s,
|
||||
elem->value.value.i8s.length);
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT8:
|
||||
value->value.value.u8s.length = elem->value.value.u8s.length;
|
||||
memcpy(value->value.value.u8s.u8s, elem->value.value.u8s.u8s,
|
||||
elem->value.value.u8s.length);
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT16:
|
||||
value->value.value.i16s.length = elem->value.value.i16s.length;
|
||||
memcpy(value->value.value.i16s.i16s, elem->value.value.i16s.i16s,
|
||||
elem->value.value.i16s.length * sizeof(int16_t));
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT16:
|
||||
value->value.value.u16s.length = elem->value.value.u16s.length;
|
||||
memcpy(value->value.value.u16s.u16s, elem->value.value.u16s.u16s,
|
||||
elem->value.value.u16s.length * sizeof(uint16_t));
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT32:
|
||||
value->value.value.i32s.length = elem->value.value.i32s.length;
|
||||
memcpy(value->value.value.i32s.i32s, elem->value.value.i32s.i32s,
|
||||
elem->value.value.i32s.length * sizeof(int32_t));
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT32:
|
||||
value->value.value.u32s.length = elem->value.value.u32s.length;
|
||||
memcpy(value->value.value.u32s.u32s, elem->value.value.u32s.u32s,
|
||||
elem->value.value.u32s.length * sizeof(uint32_t));
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT64:
|
||||
value->value.value.i64s.length = elem->value.value.i64s.length;
|
||||
memcpy(value->value.value.i64s.i64s, elem->value.value.i64s.i64s,
|
||||
elem->value.value.i64s.length * sizeof(int64_t));
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT64:
|
||||
value->value.value.u64s.length = elem->value.value.u64s.length;
|
||||
memcpy(value->value.value.u64s.u64s, elem->value.value.u64s.u64s,
|
||||
elem->value.value.u64s.length * sizeof(uint64_t));
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_FLOAT:
|
||||
value->value.value.f32s.length = elem->value.value.f32s.length;
|
||||
memcpy(value->value.value.f32s.f32s, elem->value.value.f32s.f32s,
|
||||
elem->value.value.f32s.length * sizeof(float));
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_DOUBLE:
|
||||
value->value.value.f64s.length = elem->value.value.f64s.length;
|
||||
memcpy(value->value.value.f64s.f64s, elem->value.value.f64s.f64s,
|
||||
elem->value.value.f64s.length * sizeof(double));
|
||||
break;
|
||||
case NEU_TYPE_PTR:
|
||||
value->value.value.ptr.length = elem->value.value.ptr.length;
|
||||
value->value.value.ptr.type = elem->value.value.ptr.type;
|
||||
|
||||
@@ -44,6 +44,11 @@ void neu_driver_cache_update_change(neu_driver_cache_t *cache,
|
||||
void neu_driver_cache_del(neu_driver_cache_t *cache, const char *group,
|
||||
const char *tag);
|
||||
|
||||
void neu_driver_cache_update_trace(neu_driver_cache_t *cache, const char *group,
|
||||
void *trace_ctx);
|
||||
|
||||
void *neu_driver_cache_get_trace(neu_driver_cache_t *cache, const char *group);
|
||||
|
||||
typedef struct {
|
||||
neu_dvalue_t value;
|
||||
int64_t timestamp;
|
||||
|
||||
+229
-16
@@ -104,6 +104,10 @@ static void read_report_group(int64_t timestamp, int64_t timeout,
|
||||
neu_tag_cache_type_e cache_type,
|
||||
neu_driver_cache_t *cache, const char *group,
|
||||
UT_array *tags, UT_array *tag_values);
|
||||
static void update_with_trace(neu_adapter_t *adapter, const char *group,
|
||||
const char *tag, neu_dvalue_t value,
|
||||
neu_tag_meta_t *metas, int n_meta,
|
||||
void *trace_ctx);
|
||||
static void update(neu_adapter_t *adapter, const char *group, const char *tag,
|
||||
neu_dvalue_t value);
|
||||
static void update_im(neu_adapter_t *adapter, const char *group,
|
||||
@@ -161,8 +165,8 @@ static void write_response(neu_adapter_t *adapter, void *r, neu_error error)
|
||||
neu_reqresp_head_t *req = (neu_reqresp_head_t *) r;
|
||||
neu_resp_error_t nerror = { .error = error };
|
||||
|
||||
neu_otel_trace_ctx *trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
neu_otel_trace_ctx trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
if (neu_otel_control_is_started()) {
|
||||
trace = neu_otel_find_trace(req->ctx);
|
||||
if (trace) {
|
||||
@@ -176,7 +180,7 @@ static void write_response(neu_adapter_t *adapter, void *r, neu_error error)
|
||||
}
|
||||
neu_otel_scope_add_span_attr_int(scope, "thread id",
|
||||
(int64_t) pthread_self());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ns());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,13 +203,19 @@ static void write_response(neu_adapter_t *adapter, void *r, neu_error error)
|
||||
|
||||
req->type = NEU_RESP_ERROR;
|
||||
|
||||
nlog_notice("write tag response <%p>", req->ctx);
|
||||
nlog_notice("write tag response start <%p>", req->ctx);
|
||||
|
||||
adapter->cb_funs.response(adapter, req, &nerror);
|
||||
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error", error);
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ms());
|
||||
if (error == NEU_ERR_SUCCESS) {
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_OK, error);
|
||||
} else {
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_ERROR,
|
||||
error);
|
||||
}
|
||||
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,6 +269,18 @@ static void update_with_meta(neu_adapter_t *adapter, const char *group,
|
||||
global_timestamp, n_meta);
|
||||
}
|
||||
|
||||
static void update_with_trace(neu_adapter_t *adapter, const char *group,
|
||||
const char *tag, neu_dvalue_t value,
|
||||
neu_tag_meta_t *metas, int n_meta,
|
||||
void *trace_ctx)
|
||||
{
|
||||
update_with_meta(adapter, group, tag, value, metas, n_meta);
|
||||
if (trace_ctx) {
|
||||
neu_adapter_driver_t *driver = (neu_adapter_driver_t *) adapter;
|
||||
neu_driver_cache_update_trace(driver->cache, group, trace_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void update_im(neu_adapter_t *adapter, const char *group,
|
||||
const char *tag, neu_dvalue_t value,
|
||||
neu_tag_meta_t *metas, int n_meta)
|
||||
@@ -284,8 +306,7 @@ static void update_im(neu_adapter_t *adapter, const char *group,
|
||||
}
|
||||
neu_datatag_t *first = utarray_front(tags);
|
||||
|
||||
if (first == NULL ||
|
||||
!neu_tag_attribute_test(first, NEU_ATTRIBUTE_SUBSCRIBE)) {
|
||||
if (first == NULL) {
|
||||
utarray_free(tags);
|
||||
nlog_debug("update immediately, driver: %s, "
|
||||
"group: %s, tag: %s, type: %s, "
|
||||
@@ -409,6 +430,7 @@ neu_adapter_driver_t *neu_adapter_driver_create()
|
||||
driver->adapter.cb_funs.driver.update = update;
|
||||
driver->adapter.cb_funs.driver.write_response = write_response;
|
||||
driver->adapter.cb_funs.driver.update_im = update_im;
|
||||
driver->adapter.cb_funs.driver.update_with_trace = update_with_trace;
|
||||
driver->adapter.cb_funs.driver.update_with_meta = update_with_meta;
|
||||
driver->adapter.cb_funs.driver.scan_tags_response = scan_tags_response;
|
||||
driver->adapter.cb_funs.driver.test_read_tag_response =
|
||||
@@ -727,7 +749,9 @@ static void fix_value(neu_datatag_t *tag, neu_type_e value_type,
|
||||
case NEU_TYPE_STRING:
|
||||
case NEU_TYPE_TIME:
|
||||
case NEU_TYPE_DATA_AND_TIME:
|
||||
case NEU_TYPE_BYTES:
|
||||
case NEU_TYPE_ARRAY_INT64:
|
||||
case NEU_TYPE_ARRAY_CHAR:
|
||||
case NEU_TYPE_ARRAY_BOOL:
|
||||
break;
|
||||
case NEU_TYPE_BIT:
|
||||
value->type = NEU_TYPE_BIT;
|
||||
@@ -808,6 +832,132 @@ static void fix_value(neu_datatag_t *tag, neu_type_e value_type,
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_BYTES:
|
||||
if (value->type == NEU_TYPE_ARRAY_INT64) {
|
||||
for (int i = 0; i < value->value.i64s.length; i++) {
|
||||
value->value.bytes.bytes[i] =
|
||||
(uint8_t) value->value.i64s.i64s[i];
|
||||
}
|
||||
for (int i = value->value.i64s.length; i < NEU_VALUE_SIZE; i++) {
|
||||
value->value.bytes.bytes[i] = 0;
|
||||
}
|
||||
value->value.bytes.length = value->value.i64s.length;
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT8:
|
||||
if (value->type == NEU_TYPE_ARRAY_INT64) {
|
||||
for (int i = 0; i < value->value.i64s.length; i++) {
|
||||
value->value.i8s.i8s[i] = (int8_t) value->value.i64s.i64s[i];
|
||||
}
|
||||
for (int i = value->value.i64s.length; i < NEU_VALUE_SIZE; i++) {
|
||||
value->value.i8s.i8s[i] = 0;
|
||||
}
|
||||
value->value.i8s.length = value->value.i64s.length;
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT8:
|
||||
if (value->type == NEU_TYPE_ARRAY_INT64) {
|
||||
for (int i = 0; i < value->value.i64s.length; i++) {
|
||||
value->value.u8s.u8s[i] = (uint8_t) value->value.i64s.i64s[i];
|
||||
}
|
||||
for (int i = value->value.i64s.length; i < NEU_VALUE_SIZE; i++) {
|
||||
value->value.u8s.u8s[i] = 0;
|
||||
}
|
||||
value->value.u8s.length = value->value.i64s.length;
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT16:
|
||||
if (value->type == NEU_TYPE_ARRAY_INT64) {
|
||||
for (int i = 0; i < value->value.i64s.length; i++) {
|
||||
value->value.i16s.i16s[i] = (int16_t) value->value.i64s.i64s[i];
|
||||
}
|
||||
for (int i = value->value.i64s.length; i < NEU_VALUE_SIZE; i++) {
|
||||
value->value.i16s.i16s[i] = 0;
|
||||
}
|
||||
value->value.i16s.length = value->value.i64s.length;
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT16:
|
||||
if (value->type == NEU_TYPE_ARRAY_INT64) {
|
||||
for (int i = 0; i < value->value.i64s.length; i++) {
|
||||
value->value.u16s.u16s[i] =
|
||||
(uint16_t) value->value.i64s.i64s[i];
|
||||
}
|
||||
for (int i = value->value.i64s.length; i < NEU_VALUE_SIZE; i++) {
|
||||
value->value.u16s.u16s[i] = 0;
|
||||
}
|
||||
value->value.u16s.length = value->value.i64s.length;
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_INT32:
|
||||
if (value->type == NEU_TYPE_ARRAY_INT64) {
|
||||
for (int i = 0; i < value->value.i64s.length; i++) {
|
||||
value->value.i32s.i32s[i] = (int32_t) value->value.i64s.i64s[i];
|
||||
}
|
||||
for (int i = value->value.i64s.length; i < NEU_VALUE_SIZE; i++) {
|
||||
value->value.i32s.i32s[i] = 0;
|
||||
}
|
||||
value->value.i32s.length = value->value.i64s.length;
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT32:
|
||||
if (value->type == NEU_TYPE_ARRAY_INT64) {
|
||||
for (int i = 0; i < value->value.i64s.length; i++) {
|
||||
value->value.u32s.u32s[i] =
|
||||
(uint32_t) value->value.i64s.i64s[i];
|
||||
}
|
||||
for (int i = value->value.i64s.length; i < NEU_VALUE_SIZE; i++) {
|
||||
value->value.u32s.u32s[i] = 0;
|
||||
}
|
||||
value->value.u32s.length = value->value.i64s.length;
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_UINT64:
|
||||
if (value->type == NEU_TYPE_ARRAY_INT64) {
|
||||
for (int i = 0; i < value->value.i64s.length; i++) {
|
||||
value->value.u64s.u64s[i] =
|
||||
(uint64_t) value->value.i64s.i64s[i];
|
||||
}
|
||||
for (int i = value->value.i64s.length; i < NEU_VALUE_SIZE; i++) {
|
||||
value->value.u64s.u64s[i] = 0;
|
||||
}
|
||||
value->value.u64s.length = value->value.i64s.length;
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_FLOAT:
|
||||
if (value->type == NEU_TYPE_ARRAY_INT64) {
|
||||
|
||||
for (int i = 0; i < value->value.i64s.length; i++) {
|
||||
value->value.f32s.f32s[i] = (float) value->value.i64s.i64s[i];
|
||||
}
|
||||
for (int i = value->value.i64s.length; i < NEU_VALUE_SIZE; i++) {
|
||||
value->value.f32s.f32s[i] = 0;
|
||||
}
|
||||
value->value.f32s.length = value->value.i64s.length;
|
||||
}
|
||||
if (value->type == NEU_TYPE_ARRAY_DOUBLE) {
|
||||
|
||||
for (int i = 0; i < value->value.f64s.length; i++) {
|
||||
value->value.f32s.f32s[i] = (float) value->value.f64s.f64s[i];
|
||||
}
|
||||
for (int i = value->value.f64s.length; i < NEU_VALUE_SIZE; i++) {
|
||||
value->value.f32s.f32s[i] = 0;
|
||||
}
|
||||
value->value.f32s.length = value->value.f64s.length;
|
||||
}
|
||||
break;
|
||||
case NEU_TYPE_ARRAY_DOUBLE:
|
||||
if (value->type == NEU_TYPE_ARRAY_INT64) {
|
||||
|
||||
for (int i = 0; i < value->value.i64s.length; i++) {
|
||||
value->value.f64s.f64s[i] = (double) value->value.i64s.i64s[i];
|
||||
}
|
||||
for (int i = value->value.i64s.length; i < NEU_VALUE_SIZE; i++) {
|
||||
value->value.f64s.f64s[i] = 0;
|
||||
}
|
||||
value->value.f64s.length = value->value.i64s.length;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
@@ -904,7 +1054,8 @@ int check_value_decimal(neu_type_e write_type, double result, int64_t value_min,
|
||||
return NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH;
|
||||
} else if (result < value_min || result > value_max) {
|
||||
return NEU_ERR_PLUGIN_TAG_VALUE_OUT_OF_RANGE;
|
||||
} else if (almost_equal(ceil(result), result, EPSILON)) {
|
||||
} else if (almost_equal(ceil(result), result, EPSILON) ||
|
||||
almost_equal(floor(result), result, EPSILON)) {
|
||||
return NEU_ERR_SUCCESS;
|
||||
} else {
|
||||
return NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH;
|
||||
@@ -954,7 +1105,8 @@ int is_value_in_range(neu_type_e tag_type, int64_t value, double value_d,
|
||||
case NEU_TYPE_UINT64:
|
||||
if (write_type != NEU_TYPE_INT64 && write_type != NEU_TYPE_DOUBLE) {
|
||||
return NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH;
|
||||
} else if (almost_equal(ceil(result), result, EPSILON)) {
|
||||
} else if (almost_equal(ceil(result), result, EPSILON) ||
|
||||
almost_equal(floor(result), result, EPSILON)) {
|
||||
return NEU_ERR_SUCCESS;
|
||||
} else {
|
||||
return NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH;
|
||||
@@ -978,7 +1130,7 @@ int is_value_in_range(neu_type_e tag_type, int64_t value, double value_d,
|
||||
case NEU_TYPE_STRING:
|
||||
case NEU_TYPE_BOOL:
|
||||
case NEU_TYPE_BIT:
|
||||
return NEU_ERR_PARAM_IS_WRONG;
|
||||
return NEU_ERR_TAG_DECIMAL_INVALID;
|
||||
default:
|
||||
return NEU_ERR_SUCCESS;
|
||||
}
|
||||
@@ -1096,6 +1248,7 @@ int neu_adapter_driver_write_tags(neu_adapter_driver_t *driver,
|
||||
(double) cmd->tags[i].value.value.i64;
|
||||
}
|
||||
}
|
||||
|
||||
if (tag->decimal != 0) {
|
||||
cal_decimal(tag->type, cmd->tags[i].value.type,
|
||||
&cmd->tags[i].value.value, tag->decimal);
|
||||
@@ -1212,6 +1365,7 @@ int neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver,
|
||||
(double) cmd->groups[i].tags[k].value.value.i64;
|
||||
}
|
||||
}
|
||||
|
||||
if (tag->decimal != 0) {
|
||||
cal_decimal(tag->type, cmd->groups[i].tags[k].value.type,
|
||||
&cmd->groups[i].tags[k].value.value,
|
||||
@@ -1960,6 +2114,27 @@ static int report_callback(void *usr_data)
|
||||
data->group = strdup(group->name);
|
||||
utarray_new(data->tags, neu_resp_tag_value_meta_icd());
|
||||
|
||||
void *trace_ctx =
|
||||
neu_driver_cache_get_trace(group->driver->cache, group->name);
|
||||
|
||||
neu_otel_trace_ctx trans_trace = NULL;
|
||||
neu_otel_scope_ctx trans_scope = NULL;
|
||||
if (trace_ctx) {
|
||||
data->trace_ctx = trace_ctx;
|
||||
if (neu_otel_data_is_started() && data->trace_ctx) {
|
||||
trans_trace = neu_otel_find_trace(data->trace_ctx);
|
||||
if (trans_trace) {
|
||||
char new_span_id[36] = { 0 };
|
||||
neu_otel_new_span_id(new_span_id);
|
||||
trans_scope =
|
||||
neu_otel_add_span2(trans_trace, "report cb", new_span_id);
|
||||
neu_otel_scope_add_span_attr_int(trans_scope, "thread id",
|
||||
(int64_t)(pthread_self()));
|
||||
neu_otel_scope_set_span_start_time(trans_scope, neu_time_ns());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
read_report_group(global_timestamp,
|
||||
neu_group_get_interval(group->group) *
|
||||
NEU_DRIVER_TAG_CACHE_EXPIRE_TIME,
|
||||
@@ -1970,6 +2145,7 @@ static int report_callback(void *usr_data)
|
||||
pthread_mutex_lock(&group->apps_mtx);
|
||||
|
||||
if (utarray_len(group->apps) > 0) {
|
||||
int app_num = 0;
|
||||
data->ctx = calloc(1, sizeof(neu_reqresp_trans_data_ctx_t));
|
||||
data->ctx->index = utarray_len(group->apps);
|
||||
pthread_mutex_init(&data->ctx->mtx, NULL);
|
||||
@@ -1980,8 +2156,27 @@ static int report_callback(void *usr_data)
|
||||
&group->driver->adapter, &header, data, app->addr) !=
|
||||
0) {
|
||||
neu_trans_data_free(data);
|
||||
if (trans_trace) {
|
||||
neu_otel_scope_add_span_attr_int(trans_scope, app->app,
|
||||
0);
|
||||
}
|
||||
} else {
|
||||
app_num += 1;
|
||||
if (trans_trace) {
|
||||
neu_otel_scope_add_span_attr_int(trans_scope, app->app,
|
||||
1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (trans_trace) {
|
||||
neu_otel_scope_set_span_end_time(trans_scope, neu_time_ns());
|
||||
neu_otel_trace_set_expected_span_num(trans_trace, app_num);
|
||||
if (app_num == 0) {
|
||||
neu_otel_trace_set_final(trans_trace);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
utarray_foreach(data->tags, neu_resp_tag_value_meta_t *, tag_value)
|
||||
{
|
||||
@@ -1992,6 +2187,12 @@ static int report_callback(void *usr_data)
|
||||
utarray_free(data->tags);
|
||||
free(data->group);
|
||||
free(data->driver);
|
||||
|
||||
if (trans_trace) {
|
||||
neu_otel_scope_add_span_attr_int(trans_scope, "no sub app", 1);
|
||||
neu_otel_scope_set_span_end_time(trans_scope, neu_time_ns());
|
||||
neu_otel_trace_set_final(trans_trace);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&group->apps_mtx);
|
||||
@@ -1999,6 +2200,11 @@ static int report_callback(void *usr_data)
|
||||
utarray_free(data->tags);
|
||||
free(data->group);
|
||||
free(data->driver);
|
||||
if (trans_trace) {
|
||||
neu_otel_scope_add_span_attr_int(trans_scope, "no tags", 1);
|
||||
neu_otel_scope_set_span_end_time(trans_scope, neu_time_ns());
|
||||
neu_otel_trace_set_final(trans_trace);
|
||||
}
|
||||
}
|
||||
utarray_free(tags);
|
||||
free(data);
|
||||
@@ -2090,8 +2296,8 @@ static int write_callback(void *usr_data)
|
||||
int64_t s_time = 0;
|
||||
int64_t e_time = 0;
|
||||
|
||||
neu_otel_trace_ctx *trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
neu_otel_trace_ctx trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
if (neu_otel_control_is_started()) {
|
||||
trace =
|
||||
neu_otel_find_trace(((neu_reqresp_head_t *) wtag->req)->ctx);
|
||||
@@ -2131,13 +2337,13 @@ static int write_callback(void *usr_data)
|
||||
}
|
||||
}
|
||||
|
||||
s_time = neu_time_ms();
|
||||
s_time = neu_time_ns();
|
||||
|
||||
if (wtag->single) {
|
||||
group->driver->adapter.module->intf_funs->driver.write_tag(
|
||||
group->driver->adapter.plugin, (void *) wtag->req, wtag->tag,
|
||||
wtag->value);
|
||||
e_time = neu_time_ms();
|
||||
e_time = neu_time_ns();
|
||||
neu_tag_free(wtag->tag);
|
||||
} else {
|
||||
group->driver->adapter.module->intf_funs->driver.write_tags(
|
||||
@@ -2559,6 +2765,13 @@ static void read_group_paginate(int64_t timestamp, int64_t timeout,
|
||||
tag_value.datatag.option = tag->option;
|
||||
memcpy(tag_value.datatag.meta, tag->meta, NEU_TAG_META_LENGTH);
|
||||
|
||||
if (tag->attribute == NEU_ATTRIBUTE_WRITE) {
|
||||
tag_value.value.type = NEU_TYPE_STRING;
|
||||
tag_value.value.value.str[0] = 0;
|
||||
utarray_push_back(tag_values, &tag_value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (neu_driver_cache_meta_get(cache, group, tag->name, &value,
|
||||
tag_value.metas,
|
||||
NEU_TAG_META_SIZE) != 0) {
|
||||
|
||||
+2
-2
@@ -315,8 +315,8 @@ UT_array *neu_group_query_read_tag_paginate(neu_group_t *group,
|
||||
};
|
||||
|
||||
pthread_mutex_lock(&group->mtx);
|
||||
array = filter_tags_by_page(group->tags, is_readable_and_match_query, &q,
|
||||
current_page, page_size, total_count);
|
||||
array = filter_tags_by_page(group->tags, match_query, &q, current_page,
|
||||
page_size, total_count);
|
||||
pthread_mutex_unlock(&group->mtx);
|
||||
|
||||
return array;
|
||||
|
||||
@@ -55,12 +55,11 @@ int neu_plugin_op(neu_plugin_t *plugin, neu_reqresp_head_t head, void *data)
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
|
||||
if (head.otel_trace_type == NEU_OTEL_TRACE_TYPE_REST_COMM) {
|
||||
nng_aio * aio = (nng_aio *) head.ctx;
|
||||
nng_http_req *nng_req = nng_aio_get_input(aio, 0);
|
||||
const char * http_method = nng_http_req_get_method(nng_req);
|
||||
|
||||
if (neu_otel_control_is_started()) {
|
||||
const char *trace_parent =
|
||||
nng_aio * aio = (nng_aio *) head.ctx;
|
||||
nng_http_req *nng_req = nng_aio_get_input(aio, 0);
|
||||
const char * http_method = nng_http_req_get_method(nng_req);
|
||||
const char * trace_parent =
|
||||
nng_http_req_get_header(nng_req, "traceparent");
|
||||
const char *trace_state =
|
||||
nng_http_req_get_header(nng_req, "tracestate");
|
||||
@@ -83,7 +82,7 @@ int neu_plugin_op(neu_plugin_t *plugin, neu_reqresp_head_t head, void *data)
|
||||
neu_otel_scope_set_parent_span_id(scope, span_id);
|
||||
}
|
||||
neu_otel_scope_set_span_flags(scope, flags);
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ns());
|
||||
|
||||
neu_otel_scope_add_span_attr_int(scope, "thread id",
|
||||
(int64_t) pthread_self());
|
||||
@@ -129,7 +128,7 @@ int neu_plugin_op(neu_plugin_t *plugin, neu_reqresp_head_t head, void *data)
|
||||
neu_otel_scope_set_parent_span_id(scope, span_id);
|
||||
}
|
||||
neu_otel_scope_set_span_flags(scope, flags);
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ns());
|
||||
|
||||
neu_otel_scope_add_span_attr_int(scope, "thread id",
|
||||
(int64_t) pthread_self());
|
||||
@@ -168,7 +167,7 @@ int neu_plugin_op(neu_plugin_t *plugin, neu_reqresp_head_t head, void *data)
|
||||
}
|
||||
neu_otel_scope_set_span_flags(scope, flags);
|
||||
neu_otel_scope_set_span_start_time(scope,
|
||||
neu_time_ms());
|
||||
neu_time_ns());
|
||||
|
||||
neu_otel_scope_add_span_attr_int(
|
||||
scope, "thread id", (int64_t) pthread_self());
|
||||
@@ -186,11 +185,11 @@ int neu_plugin_op(neu_plugin_t *plugin, neu_reqresp_head_t head, void *data)
|
||||
head, data);
|
||||
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
|
||||
if (ret != 0) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error type",
|
||||
NEU_ERR_IS_BUSY);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_ERROR,
|
||||
NEU_ERR_IS_BUSY);
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ neu_conn_t *neu_conn_new(neu_conn_param_t *param, void *data,
|
||||
conn->disconnected = disconnected;
|
||||
conn->connected = connected;
|
||||
|
||||
conn->buf_size = 2048;
|
||||
conn->buf_size = 8192;
|
||||
conn->buf = calloc(conn->buf_size, 1);
|
||||
conn->offset = 0;
|
||||
conn->stop = false;
|
||||
@@ -407,6 +407,40 @@ ssize_t neu_conn_send(neu_conn_t *conn, uint8_t *buf, ssize_t len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void neu_conn_clear_recv_buffer(neu_conn_t *conn)
|
||||
{
|
||||
if (!conn->is_connected) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t temp_buf[256];
|
||||
ssize_t ret;
|
||||
|
||||
switch (conn->param.type) {
|
||||
case NEU_CONN_TCP_CLIENT:
|
||||
do {
|
||||
ret = recv(conn->fd, temp_buf, sizeof(temp_buf), MSG_DONTWAIT);
|
||||
|
||||
if (ret > 0) {
|
||||
continue;
|
||||
} else if (ret == 0) {
|
||||
zlog_info(conn->param.log,
|
||||
"Connection closed while clearing buffer.");
|
||||
break;
|
||||
} else if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
break;
|
||||
} else {
|
||||
zlog_error(conn->param.log, "Error clearing buffer: %s",
|
||||
strerror(errno));
|
||||
break;
|
||||
}
|
||||
} while (ret > 0);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ssize_t neu_conn_recv(neu_conn_t *conn, uint8_t *buf, ssize_t len)
|
||||
{
|
||||
ssize_t ret = 0;
|
||||
|
||||
@@ -1601,6 +1601,64 @@ int neu_mqtt_client_publish(neu_mqtt_client_t *client, neu_mqtt_qos_e qos,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int neu_mqtt_client_publish_with_trace(neu_mqtt_client_t *client,
|
||||
neu_mqtt_qos_e qos, char *topic,
|
||||
uint8_t *payload, uint32_t len,
|
||||
void * data,
|
||||
neu_mqtt_client_publish_cb_t cb,
|
||||
const char * traceparent)
|
||||
{
|
||||
int rv = 0;
|
||||
nng_msg *pub_msg = NULL;
|
||||
task_t * task = NULL;
|
||||
|
||||
if (0 != (rv = nng_mqtt_msg_alloc(&pub_msg, 0))) {
|
||||
log(error, "nng_mqtt_msg_alloc fail: %s", nng_strerror(rv));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != (rv = nng_mqtt_msg_set_publish_topic(pub_msg, topic))) {
|
||||
nng_msg_free(pub_msg);
|
||||
log(error, "nng_mqtt_msg_set_publish_topic fail: %s", nng_strerror(rv));
|
||||
return -1;
|
||||
}
|
||||
|
||||
nng_mqtt_msg_set_packet_type(pub_msg, NNG_MQTT_PUBLISH);
|
||||
nng_mqtt_msg_set_publish_payload(pub_msg, (uint8_t *) payload, len);
|
||||
nng_mqtt_msg_set_publish_qos(pub_msg, qos);
|
||||
|
||||
if (client->version == MQTT_PROTOCOL_VERSION_v5) {
|
||||
property *plist = mqtt_property_alloc();
|
||||
property *p = mqtt_property_set_value_strpair(
|
||||
USER_PROPERTY, "traceparent", strlen("traceparent"), traceparent,
|
||||
strlen(traceparent), true);
|
||||
mqtt_property_append(plist, p);
|
||||
nng_mqtt_msg_set_publish_property(pub_msg, plist);
|
||||
}
|
||||
|
||||
nng_mtx_lock(client->mtx);
|
||||
task = client_alloc_task(client);
|
||||
nng_mtx_unlock(client->mtx);
|
||||
|
||||
if (NULL == task) {
|
||||
nng_msg_free(pub_msg);
|
||||
log(error, "client_alloc_task fail");
|
||||
return -1;
|
||||
}
|
||||
|
||||
task->kind = TASK_PUB;
|
||||
task->pub.cb = cb;
|
||||
task->pub.qos = qos;
|
||||
task->pub.topic = topic;
|
||||
task->pub.payload = payload;
|
||||
task->pub.len = len;
|
||||
task->pub.data = data;
|
||||
nng_aio_set_msg(task->aio, pub_msg);
|
||||
nng_send_aio(client->sock, task->aio);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int neu_mqtt_client_subscribe(neu_mqtt_client_t *client, neu_mqtt_qos_e qos,
|
||||
const char *topic, void *data,
|
||||
neu_mqtt_client_subscribe_cb_t cb)
|
||||
|
||||
+80
-18
@@ -71,7 +71,8 @@ static void start_single_adapter(neu_manager_t *manager, const char *name,
|
||||
static char *file_save_tmp(const char *data, const char *suffix);
|
||||
static bool mv_tmp_library_file(neu_plugin_kind_e kind, const char *tmp_path,
|
||||
const char *library);
|
||||
static bool mv_tmp_schema_file(const char *tmp_path, const char *schema);
|
||||
static bool mv_tmp_schema_file(neu_plugin_kind_e kind, const char *tmp_path,
|
||||
const char *schema);
|
||||
|
||||
uint16_t neu_manager_get_port()
|
||||
{
|
||||
@@ -400,7 +401,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mv_tmp_schema_file(schema_tmp_path, schema)) {
|
||||
if (!mv_tmp_schema_file(kind, schema_tmp_path, schema)) {
|
||||
nlog_warn("library %s schema file save schema fail", cmd->library);
|
||||
free(cmd->so_file);
|
||||
free(cmd->schema_file);
|
||||
@@ -661,7 +662,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
break;
|
||||
}
|
||||
|
||||
if (!mv_tmp_schema_file(schema_tmp_path, schema)) {
|
||||
if (!mv_tmp_schema_file(kind, schema_tmp_path, schema)) {
|
||||
nlog_warn("library %s schema file save schema fail", cmd->library);
|
||||
free(cmd->so_file);
|
||||
free(cmd->schema_file);
|
||||
@@ -1051,8 +1052,8 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
case NEU_REQ_GET_TAG:
|
||||
case NEU_REQ_NODE_CTL:
|
||||
case NEU_REQ_ADD_GROUP: {
|
||||
neu_otel_trace_ctx *trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
neu_otel_trace_ctx trace = NULL;
|
||||
neu_otel_scope_ctx scope = NULL;
|
||||
if (neu_otel_control_is_started() &&
|
||||
(NEU_REQ_WRITE_TAG == header->type ||
|
||||
NEU_REQ_WRITE_TAGS == header->type ||
|
||||
@@ -1076,7 +1077,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
}
|
||||
neu_otel_scope_add_span_attr_int(scope, "thread id",
|
||||
(int64_t) pthread_self());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_start_time(scope, neu_time_ns());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1101,8 +1102,8 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
neu_msg_exchange(header);
|
||||
reply(manager, header, &e);
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_add_span_attr_int(scope, "error",
|
||||
NEU_ERR_NODE_NOT_EXIST);
|
||||
neu_otel_scope_set_status_code2(scope, NEU_OTEL_STATUS_ERROR,
|
||||
NEU_ERR_NODE_NOT_EXIST);
|
||||
}
|
||||
} else {
|
||||
forward_msg(manager, header, header->receiver);
|
||||
@@ -1110,7 +1111,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
|
||||
}
|
||||
|
||||
if (neu_otel_control_is_started() && trace) {
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ms());
|
||||
neu_otel_scope_set_span_end_time(scope, neu_time_ns());
|
||||
if (!re_flag) {
|
||||
neu_otel_trace_set_final(trace);
|
||||
}
|
||||
@@ -1537,6 +1538,47 @@ static char *file_save_tmp(const char *data, const char *suffix)
|
||||
return tmp_path;
|
||||
}
|
||||
|
||||
static int copy_file(const char *src, const char *dst)
|
||||
{
|
||||
FILE * source, *destination;
|
||||
char buffer[1024];
|
||||
size_t bytes_read;
|
||||
|
||||
source = fopen(src, "rb");
|
||||
if (source == NULL) {
|
||||
nlog_error("failed to open source file!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
destination = fopen(dst, "wb");
|
||||
if (destination == NULL) {
|
||||
nlog_error("failed to open destination file!");
|
||||
fclose(source);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((bytes_read = fread(buffer, 1, sizeof(buffer), source)) > 0) {
|
||||
if (fwrite(buffer, 1, bytes_read, destination) != bytes_read) {
|
||||
nlog_error("failed to write to destination file!");
|
||||
fclose(source);
|
||||
fclose(destination);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ferror(source)) {
|
||||
nlog_error("error reading source file");
|
||||
fclose(source);
|
||||
fclose(destination);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fclose(source);
|
||||
fclose(destination);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool mv_tmp_library_file(neu_plugin_kind_e kind, const char *tmp_path,
|
||||
const char *library)
|
||||
{
|
||||
@@ -1563,9 +1605,8 @@ static bool mv_tmp_library_file(neu_plugin_kind_e kind, const char *tmp_path,
|
||||
}
|
||||
}
|
||||
|
||||
if (rename(tmp_path, file_name) != 0) {
|
||||
nlog_error("%s rename %s fail, err:%s", tmp_path, file_name,
|
||||
strerror(errno));
|
||||
if (copy_file(tmp_path, file_name) != 0) {
|
||||
nlog_error("%s copy_file %s fail!", tmp_path, file_name);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
@@ -1574,16 +1615,37 @@ static bool mv_tmp_library_file(neu_plugin_kind_e kind, const char *tmp_path,
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool mv_tmp_schema_file(const char *tmp_path, const char *schema)
|
||||
static bool mv_tmp_schema_file(neu_plugin_kind_e kind, const char *tmp_path,
|
||||
const char *schema)
|
||||
{
|
||||
|
||||
char file_name[128] = { 0 };
|
||||
snprintf(file_name, sizeof(file_name), "%s/schema/%s.json", g_plugin_dir,
|
||||
schema);
|
||||
char path_name[128] = { 0 };
|
||||
if (kind == NEU_PLUGIN_KIND_CUSTOM) {
|
||||
snprintf(file_name, sizeof(file_name), "%s/custom/schema/%s.json",
|
||||
g_plugin_dir, schema);
|
||||
snprintf(path_name, sizeof(path_name), "%s/custom/schema",
|
||||
g_plugin_dir);
|
||||
} else if (kind == NEU_PLUGIN_KIND_SYSTEM) {
|
||||
snprintf(file_name, sizeof(file_name), "%s/system/schema/%s.json",
|
||||
g_plugin_dir, schema);
|
||||
snprintf(path_name, sizeof(path_name), "%s/system/schema",
|
||||
g_plugin_dir);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (rename(tmp_path, file_name) != 0) {
|
||||
nlog_error("%s rename %s fail, err:%s", tmp_path, file_name,
|
||||
strerror(errno));
|
||||
struct stat st;
|
||||
|
||||
if (stat(path_name, &st) == -1) {
|
||||
if (mkdir(path_name, 0700) == -1) {
|
||||
nlog_error("%s mkdir fail", path_name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (copy_file(tmp_path, file_name) != 0) {
|
||||
nlog_error("%s copy_file %s fail!", tmp_path, file_name);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
|
||||
@@ -252,6 +252,20 @@ int neu_plugin_manager_del(neu_plugin_manager_t *mgr, const char *plugin_name)
|
||||
HASH_FIND_STR(mgr->plugins, plugin_name, plugin);
|
||||
if (plugin != NULL) {
|
||||
if (plugin->kind != NEU_PLUGIN_KIND_SYSTEM) {
|
||||
|
||||
char so_file_path[128] = { 0 };
|
||||
char schema_file_path[128] = { 0 };
|
||||
snprintf(so_file_path, sizeof(so_file_path), "%s/custom/%s",
|
||||
g_plugin_dir, plugin->lib_name);
|
||||
snprintf(schema_file_path, sizeof(schema_file_path),
|
||||
"%s/custom/schema/%s.json", g_plugin_dir, plugin->schema);
|
||||
if (remove(so_file_path) != 0) {
|
||||
nlog_error("rm %s file fail!", so_file_path);
|
||||
}
|
||||
if (remove(schema_file_path) != 0) {
|
||||
nlog_error("rm %s file fail!", schema_file_path);
|
||||
}
|
||||
|
||||
HASH_DEL(mgr->plugins, plugin);
|
||||
entity_free(plugin);
|
||||
ret = NEU_ERR_SUCCESS;
|
||||
|
||||
+196
-22
@@ -28,6 +28,7 @@
|
||||
#include "plugin.h"
|
||||
#include "utils/http.h"
|
||||
#include "utils/log.h"
|
||||
#include "utils/time.h"
|
||||
#include "utils/utarray.h"
|
||||
#include "utils/uthash.h"
|
||||
|
||||
@@ -35,7 +36,8 @@
|
||||
#include "trace.pb-c.h"
|
||||
|
||||
#define SPAN_ID_LENGTH 16
|
||||
#define SPAN_ID_CHARSET "0123456789abcdef"
|
||||
#define ID_CHARSET "0123456789abcdef"
|
||||
#define TRACE_TIME_OUT (3 * 60 * 1000)
|
||||
|
||||
bool otel_flag = false;
|
||||
char otel_collector_url[128] = { 0 };
|
||||
@@ -50,6 +52,8 @@ typedef struct {
|
||||
uint32_t flags;
|
||||
bool final;
|
||||
size_t span_num;
|
||||
int32_t expected_span_num;
|
||||
int64_t ts;
|
||||
UT_array * scopes;
|
||||
pthread_mutex_t mutex;
|
||||
} trace_ctx_t;
|
||||
@@ -92,6 +96,9 @@ static int hex_char_to_int(char c)
|
||||
static int hex_string_to_binary(const char * hex_string,
|
||||
unsigned char *binary_array, int max_length)
|
||||
{
|
||||
if (hex_string == NULL) {
|
||||
return -1;
|
||||
}
|
||||
int length = strlen(hex_string);
|
||||
if (length % 2 != 0 || length <= 0)
|
||||
return -1;
|
||||
@@ -162,7 +169,12 @@ void neu_otel_free_span(Opentelemetry__Proto__Trace__V1__Span *span)
|
||||
free(span->attributes[i]->value);
|
||||
free(span->attributes[i]);
|
||||
}
|
||||
|
||||
if (span->status) {
|
||||
if (span->status->message) {
|
||||
free(span->status->message);
|
||||
}
|
||||
free(span->status);
|
||||
}
|
||||
free(span->attributes);
|
||||
free(span->name);
|
||||
free(span->trace_id.data);
|
||||
@@ -174,9 +186,24 @@ void neu_otel_free_span(Opentelemetry__Proto__Trace__V1__Span *span)
|
||||
neu_otel_trace_ctx neu_otel_create_trace(const char *trace_id, void *req_ctx,
|
||||
uint32_t flags, const char *tracestate)
|
||||
{
|
||||
trace_ctx_table_ele_t *find = NULL;
|
||||
|
||||
pthread_mutex_lock(&table_mutex);
|
||||
|
||||
HASH_FIND(hh, traces_table, &req_ctx, sizeof(req_ctx), find);
|
||||
|
||||
if (find) {
|
||||
HASH_DEL(traces_table, find);
|
||||
neu_otel_free_trace(find->ctx);
|
||||
free(find);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&table_mutex);
|
||||
|
||||
trace_ctx_t *ctx = calloc(1, sizeof(trace_ctx_t));
|
||||
opentelemetry__proto__trace__v1__traces_data__init(&ctx->trace_data);
|
||||
strncpy((char *) ctx->trace_id, trace_id, 64);
|
||||
ctx->expected_span_num = 0;
|
||||
|
||||
ctx->trace_data.n_resource_spans = 1;
|
||||
ctx->trace_data.resource_spans =
|
||||
@@ -417,6 +444,8 @@ neu_otel_trace_ctx neu_otel_create_trace(const char *trace_id, void *req_ctx,
|
||||
|
||||
ctx->flags = flags;
|
||||
|
||||
ctx->ts = neu_time_ms();
|
||||
|
||||
trace_ctx_table_ele_t *ele = calloc(1, sizeof(trace_ctx_table_ele_t));
|
||||
ele->key = req_ctx;
|
||||
ele->ctx = ctx;
|
||||
@@ -443,7 +472,16 @@ neu_otel_trace_ctx neu_otel_find_trace(void *req_ctx)
|
||||
pthread_mutex_unlock(&table_mutex);
|
||||
|
||||
if (find) {
|
||||
return (void *) find->ctx;
|
||||
if (find->ctx->final &&
|
||||
find->ctx->span_num ==
|
||||
find->ctx->trace_data.resource_spans[0]
|
||||
->scope_spans[0]
|
||||
->n_spans &&
|
||||
find->ctx->expected_span_num <= 0) {
|
||||
return NULL;
|
||||
} else {
|
||||
return (void *) find->ctx;
|
||||
}
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
@@ -455,6 +493,24 @@ void neu_otel_trace_set_final(neu_otel_trace_ctx ctx)
|
||||
trace_ctx->final = true;
|
||||
}
|
||||
|
||||
void neu_otel_trace_set_expected_span_num(neu_otel_trace_ctx ctx, uint32_t num)
|
||||
{
|
||||
trace_ctx_t *trace_ctx = (trace_ctx_t *) ctx;
|
||||
trace_ctx->expected_span_num = num;
|
||||
}
|
||||
|
||||
uint8_t *neu_otel_get_trace_id(neu_otel_trace_ctx ctx)
|
||||
{
|
||||
trace_ctx_t *trace_ctx = (trace_ctx_t *) ctx;
|
||||
pthread_mutex_lock(&trace_ctx->mutex);
|
||||
uint8_t *id = trace_ctx->trace_data.resource_spans[0]
|
||||
->scope_spans[0]
|
||||
->spans[0]
|
||||
->trace_id.data;
|
||||
pthread_mutex_unlock(&trace_ctx->mutex);
|
||||
return id;
|
||||
}
|
||||
|
||||
neu_otel_trace_ctx neu_otel_find_trace_by_id(const char *trace_id)
|
||||
{
|
||||
trace_ctx_table_ele_t *el = NULL, *tmp = NULL;
|
||||
@@ -576,6 +632,84 @@ neu_otel_scope_ctx neu_otel_add_span(neu_otel_trace_ctx ctx)
|
||||
return scope;
|
||||
}
|
||||
|
||||
neu_otel_scope_ctx neu_otel_add_span2(neu_otel_trace_ctx ctx,
|
||||
const char * span_name,
|
||||
const char * span_id)
|
||||
{
|
||||
trace_scope_t *scope = calloc(1, sizeof(trace_scope_t));
|
||||
trace_ctx_t * trace_ctx = (trace_ctx_t *) ctx;
|
||||
pthread_mutex_lock(&trace_ctx->mutex);
|
||||
scope->trace_ctx = ctx;
|
||||
if (trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->n_spans == 0) {
|
||||
trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans =
|
||||
calloc(1, sizeof(Opentelemetry__Proto__Trace__V1__Span *));
|
||||
trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans[0] =
|
||||
calloc(1, sizeof(Opentelemetry__Proto__Trace__V1__Span));
|
||||
|
||||
trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->n_spans = 1;
|
||||
scope->span =
|
||||
trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans[0];
|
||||
scope->span_index = 0;
|
||||
} else {
|
||||
Opentelemetry__Proto__Trace__V1__Span **t_spans =
|
||||
trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans;
|
||||
trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans =
|
||||
calloc(1 +
|
||||
trace_ctx->trace_data.resource_spans[0]
|
||||
->scope_spans[0]
|
||||
->n_spans,
|
||||
sizeof(Opentelemetry__Proto__Trace__V1__Span *));
|
||||
for (size_t i = 0; i <
|
||||
trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->n_spans;
|
||||
i++) {
|
||||
trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans[i] =
|
||||
t_spans[i];
|
||||
}
|
||||
|
||||
free(t_spans);
|
||||
|
||||
trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->spans
|
||||
[trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->n_spans] =
|
||||
calloc(1, sizeof(Opentelemetry__Proto__Trace__V1__Span));
|
||||
scope->span = trace_ctx->trace_data.resource_spans[0]
|
||||
->scope_spans[0]
|
||||
->spans[trace_ctx->trace_data.resource_spans[0]
|
||||
->scope_spans[0]
|
||||
->n_spans];
|
||||
trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->n_spans += 1;
|
||||
|
||||
scope->span_index =
|
||||
trace_ctx->trace_data.resource_spans[0]->scope_spans[0]->n_spans -
|
||||
1;
|
||||
}
|
||||
|
||||
opentelemetry__proto__trace__v1__span__init(scope->span);
|
||||
scope->span->kind =
|
||||
OPENTELEMETRY__PROTO__TRACE__V1__SPAN__SPAN_KIND__SPAN_KIND_SERVER;
|
||||
uint8_t *t_id = calloc(1, 16);
|
||||
hex_string_to_binary((char *) trace_ctx->trace_id, t_id, 16);
|
||||
scope->span->trace_id.data = t_id;
|
||||
scope->span->trace_id.len = 16;
|
||||
scope->span->flags = trace_ctx->flags;
|
||||
neu_otel_scope_set_span_name(scope, span_name);
|
||||
neu_otel_scope_set_span_id(scope, span_id);
|
||||
if (scope->span_index != 0) {
|
||||
neu_otel_scope_set_parent_span_id2(
|
||||
scope,
|
||||
trace_ctx->trace_data.resource_spans[0]
|
||||
->scope_spans[0]
|
||||
->spans[scope->span_index - 1]
|
||||
->span_id.data,
|
||||
trace_ctx->trace_data.resource_spans[0]
|
||||
->scope_spans[0]
|
||||
->spans[scope->span_index - 1]
|
||||
->span_id.len);
|
||||
}
|
||||
utarray_push_back(trace_ctx->scopes, &scope);
|
||||
pthread_mutex_unlock(&trace_ctx->mutex);
|
||||
return scope;
|
||||
}
|
||||
|
||||
void neu_otel_scope_set_parent_span_id(neu_otel_scope_ctx ctx,
|
||||
const char * parent_span_id)
|
||||
{
|
||||
@@ -746,31 +880,63 @@ void neu_otel_scope_add_span_attr_bool(neu_otel_scope_ctx ctx, const char *key,
|
||||
free(t_kvs);
|
||||
}
|
||||
|
||||
void neu_otel_scope_set_span_start_time(neu_otel_scope_ctx ctx, int64_t ms)
|
||||
void neu_otel_scope_set_span_start_time(neu_otel_scope_ctx ctx, int64_t ns)
|
||||
{
|
||||
trace_scope_t *scope = (trace_scope_t *) ctx;
|
||||
scope->span->start_time_unix_nano = ((uint64_t) ms) * 1000000;
|
||||
scope->span->start_time_unix_nano = ((uint64_t) ns);
|
||||
}
|
||||
void neu_otel_scope_set_span_end_time(neu_otel_scope_ctx ctx, int64_t ms)
|
||||
void neu_otel_scope_set_span_end_time(neu_otel_scope_ctx ctx, int64_t ns)
|
||||
|
||||
{
|
||||
trace_scope_t *scope = (trace_scope_t *) ctx;
|
||||
scope->span->end_time_unix_nano = ((uint64_t) ms) * 1000000;
|
||||
scope->span->end_time_unix_nano = ((uint64_t) ns);
|
||||
trace_ctx_t *trace_ctx = (trace_ctx_t *) scope->trace_ctx;
|
||||
trace_ctx->span_num += 1;
|
||||
trace_ctx->expected_span_num -= 1;
|
||||
}
|
||||
|
||||
void neu_otel_scope_set_status_code(neu_otel_scope_ctx ctx,
|
||||
neu_otel_status_code_e code,
|
||||
const char * desc)
|
||||
{
|
||||
trace_scope_t *scope = (trace_scope_t *) ctx;
|
||||
scope->span->status =
|
||||
calloc(1, sizeof(Opentelemetry__Proto__Trace__V1__Status));
|
||||
opentelemetry__proto__trace__v1__status__init(scope->span->status);
|
||||
scope->span->status->code =
|
||||
(Opentelemetry__Proto__Trace__V1__Status__StatusCode) code;
|
||||
scope->span->status->message = strdup(desc);
|
||||
}
|
||||
|
||||
void neu_otel_scope_set_status_code2(neu_otel_scope_ctx ctx,
|
||||
neu_otel_status_code_e code, int errorno)
|
||||
{
|
||||
trace_scope_t *scope = (trace_scope_t *) ctx;
|
||||
scope->span->status =
|
||||
calloc(1, sizeof(Opentelemetry__Proto__Trace__V1__Status));
|
||||
opentelemetry__proto__trace__v1__status__init(scope->span->status);
|
||||
char *error_buf = calloc(1, 16);
|
||||
sprintf(error_buf, "%d", errorno);
|
||||
scope->span->status->code =
|
||||
(Opentelemetry__Proto__Trace__V1__Status__StatusCode) code;
|
||||
scope->span->status->message = error_buf;
|
||||
}
|
||||
|
||||
uint8_t *neu_otel_scope_get_pre_span_id(neu_otel_scope_ctx ctx)
|
||||
{
|
||||
trace_scope_t *scope = (trace_scope_t *) ctx;
|
||||
trace_ctx_t * trace_ctx = (trace_ctx_t *) scope->trace_ctx;
|
||||
pthread_mutex_lock(&trace_ctx->mutex);
|
||||
if (scope->span_index <= 0) {
|
||||
pthread_mutex_unlock(&trace_ctx->mutex);
|
||||
return NULL;
|
||||
}
|
||||
return trace_ctx->trace_data.resource_spans[0]
|
||||
->scope_spans[0]
|
||||
->spans[scope->span_index - 1]
|
||||
->span_id.data;
|
||||
uint8_t *id = trace_ctx->trace_data.resource_spans[0]
|
||||
->scope_spans[0]
|
||||
->spans[scope->span_index - 1]
|
||||
->span_id.data;
|
||||
pthread_mutex_unlock(&trace_ctx->mutex);
|
||||
return id;
|
||||
}
|
||||
|
||||
int neu_otel_trace_pack_size(neu_otel_trace_ctx ctx)
|
||||
@@ -789,20 +955,20 @@ int neu_otel_trace_pack(neu_otel_trace_ctx ctx, uint8_t *out)
|
||||
|
||||
void neu_otel_new_span_id(char *id)
|
||||
{
|
||||
static uint64_t counter = 0;
|
||||
uint64_t timestamp = time(NULL);
|
||||
uint64_t random = rand();
|
||||
|
||||
uint64_t combined = (timestamp << 24) | (counter << 12) | random;
|
||||
counter++;
|
||||
|
||||
int64_t p_id = (int64_t) pthread_self();
|
||||
for (int i = SPAN_ID_LENGTH - 1; i >= 0; i--) {
|
||||
id[i] = SPAN_ID_CHARSET[combined % 16];
|
||||
combined /= 16;
|
||||
int64_t rand_id = (int64_t) rand() + neu_time_ns() + p_id;
|
||||
id[i] = ID_CHARSET[rand_id % 16];
|
||||
}
|
||||
id[SPAN_ID_LENGTH] = '\0';
|
||||
}
|
||||
|
||||
void neu_otel_new_trace_id(char *id)
|
||||
{
|
||||
neu_otel_new_span_id(id);
|
||||
neu_otel_new_span_id(id + SPAN_ID_LENGTH);
|
||||
}
|
||||
|
||||
void neu_otel_split_traceparent(const char *in, char *trace_id, char *span_id,
|
||||
uint32_t *flags)
|
||||
{
|
||||
@@ -854,7 +1020,8 @@ static int otel_timer_cb(void *data)
|
||||
el->ctx->span_num ==
|
||||
el->ctx->trace_data.resource_spans[0]
|
||||
->scope_spans[0]
|
||||
->n_spans) {
|
||||
->n_spans &&
|
||||
el->ctx->expected_span_num <= 0) {
|
||||
int data_size = neu_otel_trace_pack_size(el->ctx);
|
||||
|
||||
uint8_t *data_buf = calloc(1, data_size);
|
||||
@@ -867,7 +1034,14 @@ static int otel_timer_cb(void *data)
|
||||
HASH_DEL(traces_table, el);
|
||||
neu_otel_free_trace(el->ctx);
|
||||
free(el);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (neu_time_ms() - el->ctx->ts >= TRACE_TIME_OUT) {
|
||||
nlog_debug("trace:%s time out", (char *) el->ctx->trace_id);
|
||||
HASH_DEL(traces_table, el);
|
||||
neu_otel_free_trace(el->ctx);
|
||||
free(el);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -888,7 +1062,7 @@ void neu_otel_start()
|
||||
param.usr_data = NULL;
|
||||
|
||||
param.second = 0;
|
||||
param.millisecond = 100;
|
||||
param.millisecond = 80;
|
||||
param.cb = otel_timer_cb;
|
||||
param.type = NEU_EVENT_TIMER_BLOCK;
|
||||
|
||||
|
||||
+174
-8
@@ -291,6 +291,53 @@ int neu_json_encode_read_resp1(void *json_object, void *param)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_encode_read_resp2(void *json_object, void *param)
|
||||
{
|
||||
int ret = 0;
|
||||
neu_json_read_resp_t *resp = (neu_json_read_resp_t *) param;
|
||||
|
||||
void * tag_array = neu_json_array();
|
||||
neu_json_read_resp_tag_t *p_tag = resp->tags;
|
||||
for (int i = 0; i < resp->n_tag; i++) {
|
||||
neu_json_elem_t tag_elems[2 + NEU_TAG_META_SIZE] = { 0 };
|
||||
|
||||
tag_elems[0].name = "name";
|
||||
tag_elems[0].t = NEU_JSON_STR;
|
||||
tag_elems[0].v.val_str = p_tag->name;
|
||||
|
||||
if (p_tag->error != 0) {
|
||||
tag_elems[1].name = "error";
|
||||
tag_elems[1].t = NEU_JSON_INT;
|
||||
tag_elems[1].v.val_int = p_tag->error;
|
||||
} else {
|
||||
tag_elems[1].name = "value";
|
||||
tag_elems[1].t = p_tag->t;
|
||||
tag_elems[1].v = p_tag->value;
|
||||
tag_elems[1].precision = p_tag->precision;
|
||||
}
|
||||
|
||||
for (int k = 0; k < p_tag->n_meta; k++) {
|
||||
tag_elems[2 + k].name = p_tag->metas[k].name;
|
||||
tag_elems[2 + k].t = p_tag->metas[k].t;
|
||||
tag_elems[2 + k].v = p_tag->metas[k].value;
|
||||
}
|
||||
|
||||
tag_array =
|
||||
neu_json_encode_array(tag_array, tag_elems, 2 + p_tag->n_meta);
|
||||
p_tag++;
|
||||
}
|
||||
|
||||
neu_json_elem_t resp_elems[] = { {
|
||||
.name = "tags",
|
||||
.t = NEU_JSON_OBJECT,
|
||||
.v.val_object = tag_array,
|
||||
} };
|
||||
ret = neu_json_encode_field(json_object, resp_elems,
|
||||
NEU_JSON_ELEM_SIZE(resp_elems));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int neu_json_decode_write_req(char *buf, neu_json_write_req_t **result)
|
||||
{
|
||||
void *json_obj = neu_json_decode_new(buf);
|
||||
@@ -383,8 +430,47 @@ void neu_json_decode_write_req_free(neu_json_write_req_t *req)
|
||||
if (req->t == NEU_JSON_STR) {
|
||||
free(req->value.val_str);
|
||||
}
|
||||
if (req->t == NEU_JSON_BYTES && req->value.val_bytes.length > 0) {
|
||||
free(req->value.val_bytes.bytes);
|
||||
if (req->t == NEU_JSON_ARRAY_INT8 && req->value.val_array_int8.length > 0) {
|
||||
free(req->value.val_array_int8.i8s);
|
||||
}
|
||||
if (req->t == NEU_JSON_ARRAY_UINT8 &&
|
||||
req->value.val_array_uint8.length > 0) {
|
||||
free(req->value.val_array_uint8.u8s);
|
||||
}
|
||||
if (req->t == NEU_JSON_ARRAY_INT16 &&
|
||||
req->value.val_array_int16.length > 0) {
|
||||
free(req->value.val_array_int16.i16s);
|
||||
}
|
||||
if (req->t == NEU_JSON_ARRAY_UINT16 &&
|
||||
req->value.val_array_uint16.length > 0) {
|
||||
free(req->value.val_array_uint16.u16s);
|
||||
}
|
||||
if (req->t == NEU_JSON_ARRAY_INT32 &&
|
||||
req->value.val_array_int32.length > 0) {
|
||||
free(req->value.val_array_int32.i32s);
|
||||
}
|
||||
if (req->t == NEU_JSON_ARRAY_UINT32 &&
|
||||
req->value.val_array_uint32.length > 0) {
|
||||
free(req->value.val_array_uint32.u32s);
|
||||
}
|
||||
if (req->t == NEU_JSON_ARRAY_INT64 &&
|
||||
req->value.val_array_int64.length > 0) {
|
||||
free(req->value.val_array_int64.i64s);
|
||||
}
|
||||
if (req->t == NEU_JSON_ARRAY_UINT64 &&
|
||||
req->value.val_array_uint64.length > 0) {
|
||||
free(req->value.val_array_uint64.u64s);
|
||||
}
|
||||
if (req->t == NEU_JSON_ARRAY_FLOAT &&
|
||||
req->value.val_array_float.length > 0) {
|
||||
free(req->value.val_array_float.f32s);
|
||||
}
|
||||
if (req->t == NEU_JSON_ARRAY_DOUBLE &&
|
||||
req->value.val_array_double.length > 0) {
|
||||
free(req->value.val_array_double.f64s);
|
||||
}
|
||||
if (req->t == NEU_JSON_ARRAY_BOOL && req->value.val_array_bool.length > 0) {
|
||||
free(req->value.val_array_bool.bools);
|
||||
}
|
||||
|
||||
free(req);
|
||||
@@ -502,9 +588,49 @@ void neu_json_decode_write_tags_req_free(neu_json_write_tags_req_t *req)
|
||||
if (req->tags[i].t == NEU_JSON_STR) {
|
||||
free(req->tags[i].value.val_str);
|
||||
}
|
||||
if (req->tags[i].t == NEU_JSON_BYTES &&
|
||||
req->tags[i].value.val_bytes.length > 0) {
|
||||
free(req->tags[i].value.val_bytes.bytes);
|
||||
if (req->tags[i].t == NEU_JSON_ARRAY_INT8 &&
|
||||
req->tags[i].value.val_array_int8.length > 0) {
|
||||
free(req->tags[i].value.val_array_int8.i8s);
|
||||
}
|
||||
if (req->tags[i].t == NEU_JSON_ARRAY_UINT8 &&
|
||||
req->tags[i].value.val_array_uint8.length > 0) {
|
||||
free(req->tags[i].value.val_array_uint8.u8s);
|
||||
}
|
||||
if (req->tags[i].t == NEU_JSON_ARRAY_INT16 &&
|
||||
req->tags[i].value.val_array_int16.length > 0) {
|
||||
free(req->tags[i].value.val_array_int16.i16s);
|
||||
}
|
||||
if (req->tags[i].t == NEU_JSON_ARRAY_UINT16 &&
|
||||
req->tags[i].value.val_array_uint16.length > 0) {
|
||||
free(req->tags[i].value.val_array_uint16.u16s);
|
||||
}
|
||||
if (req->tags[i].t == NEU_JSON_ARRAY_INT32 &&
|
||||
req->tags[i].value.val_array_int32.length > 0) {
|
||||
free(req->tags[i].value.val_array_int32.i32s);
|
||||
}
|
||||
if (req->tags[i].t == NEU_JSON_ARRAY_UINT32 &&
|
||||
req->tags[i].value.val_array_uint32.length > 0) {
|
||||
free(req->tags[i].value.val_array_uint32.u32s);
|
||||
}
|
||||
if (req->tags[i].t == NEU_JSON_ARRAY_INT64 &&
|
||||
req->tags[i].value.val_array_int64.length > 0) {
|
||||
free(req->tags[i].value.val_array_int64.i64s);
|
||||
}
|
||||
if (req->tags[i].t == NEU_JSON_ARRAY_UINT64 &&
|
||||
req->tags[i].value.val_array_uint64.length > 0) {
|
||||
free(req->tags[i].value.val_array_uint64.u64s);
|
||||
}
|
||||
if (req->tags[i].t == NEU_JSON_ARRAY_FLOAT &&
|
||||
req->tags[i].value.val_array_float.length > 0) {
|
||||
free(req->tags[i].value.val_array_float.f32s);
|
||||
}
|
||||
if (req->tags[i].t == NEU_JSON_ARRAY_DOUBLE &&
|
||||
req->tags[i].value.val_array_double.length > 0) {
|
||||
free(req->tags[i].value.val_array_double.f64s);
|
||||
}
|
||||
if (req->tags[i].t == NEU_JSON_ARRAY_BOOL &&
|
||||
req->tags[i].value.val_array_bool.length > 0) {
|
||||
free(req->tags[i].value.val_array_bool.bools);
|
||||
}
|
||||
}
|
||||
free(req->tags);
|
||||
@@ -1170,9 +1296,49 @@ void neu_json_decode_write_gtags_req_free(neu_json_write_gtags_req_t *req)
|
||||
if (req->groups[i].tags[k].t == NEU_JSON_STR) {
|
||||
free(req->groups[i].tags[k].value.val_str);
|
||||
}
|
||||
if (req->groups[i].tags[k].t == NEU_JSON_BYTES &&
|
||||
req->groups[i].tags[k].value.val_bytes.length > 0) {
|
||||
free(req->groups[i].tags[k].value.val_bytes.bytes);
|
||||
if (req->groups[i].tags[k].t == NEU_JSON_ARRAY_INT8 &&
|
||||
req->groups[i].tags[k].value.val_array_int8.length > 0) {
|
||||
free(req->groups[i].tags[k].value.val_array_int8.i8s);
|
||||
}
|
||||
if (req->groups[i].tags[k].t == NEU_JSON_ARRAY_UINT8 &&
|
||||
req->groups[i].tags[k].value.val_array_uint8.length > 0) {
|
||||
free(req->groups[i].tags[k].value.val_array_uint8.u8s);
|
||||
}
|
||||
if (req->groups[i].tags[k].t == NEU_JSON_ARRAY_INT16 &&
|
||||
req->groups[i].tags[k].value.val_array_int16.length > 0) {
|
||||
free(req->groups[i].tags[k].value.val_array_int16.i16s);
|
||||
}
|
||||
if (req->groups[i].tags[k].t == NEU_JSON_ARRAY_UINT16 &&
|
||||
req->groups[i].tags[k].value.val_array_uint16.length > 0) {
|
||||
free(req->groups[i].tags[k].value.val_array_uint16.u16s);
|
||||
}
|
||||
if (req->groups[i].tags[k].t == NEU_JSON_ARRAY_INT32 &&
|
||||
req->groups[i].tags[k].value.val_array_int32.length > 0) {
|
||||
free(req->groups[i].tags[k].value.val_array_int32.i32s);
|
||||
}
|
||||
if (req->groups[i].tags[k].t == NEU_JSON_ARRAY_UINT32 &&
|
||||
req->groups[i].tags[k].value.val_array_uint32.length > 0) {
|
||||
free(req->groups[i].tags[k].value.val_array_uint32.u32s);
|
||||
}
|
||||
if (req->groups[i].tags[k].t == NEU_JSON_ARRAY_INT64 &&
|
||||
req->groups[i].tags[k].value.val_array_int64.length > 0) {
|
||||
free(req->groups[i].tags[k].value.val_array_int64.i64s);
|
||||
}
|
||||
if (req->groups[i].tags[k].t == NEU_JSON_ARRAY_UINT64 &&
|
||||
req->groups[i].tags[k].value.val_array_uint64.length > 0) {
|
||||
free(req->groups[i].tags[k].value.val_array_uint64.u64s);
|
||||
}
|
||||
if (req->groups[i].tags[k].t == NEU_JSON_ARRAY_FLOAT &&
|
||||
req->groups[i].tags[k].value.val_array_float.length > 0) {
|
||||
free(req->groups[i].tags[k].value.val_array_float.f32s);
|
||||
}
|
||||
if (req->groups[i].tags[k].t == NEU_JSON_ARRAY_DOUBLE &&
|
||||
req->groups[i].tags[k].value.val_array_double.length > 0) {
|
||||
free(req->groups[i].tags[k].value.val_array_double.f64s);
|
||||
}
|
||||
if (req->groups[i].tags[k].t == NEU_JSON_ARRAY_BOOL &&
|
||||
req->groups[i].tags[k].value.val_array_bool.length > 0) {
|
||||
free(req->groups[i].tags[k].value.val_array_bool.bools);
|
||||
}
|
||||
}
|
||||
if (req->groups[i].n_tag > 0) {
|
||||
|
||||
@@ -319,6 +319,7 @@ int neu_http_response(nng_aio *aio, neu_err_code_e code, char *content)
|
||||
case NEU_ERR_TAG_ADDRESS_FORMAT_INVALID:
|
||||
case NEU_ERR_TAG_DESCRIPTION_TOO_LONG:
|
||||
case NEU_ERR_TAG_PRECISION_INVALID:
|
||||
case NEU_ERR_TAG_DECIMAL_INVALID:
|
||||
case NEU_ERR_TAG_NAME_TOO_LONG:
|
||||
case NEU_ERR_TAG_ADDRESS_TOO_LONG:
|
||||
case NEU_ERR_PLUGIN_TAG_TYPE_MISMATCH:
|
||||
|
||||
+180
-14
@@ -128,15 +128,125 @@ static json_t *encode_object(json_t *object, neu_json_elem_t ele)
|
||||
case NEU_JSON_BOOL:
|
||||
json_object_set_new(ob, ele.name, json_boolean(ele.v.val_bool));
|
||||
break;
|
||||
case NEU_JSON_BYTES: {
|
||||
void *bytes = json_array();
|
||||
case NEU_JSON_ARRAY_BOOL: {
|
||||
void *array = json_array();
|
||||
|
||||
for (int i = 0; i < ele.v.val_bytes.length; i++) {
|
||||
json_array_append_new(bytes,
|
||||
json_integer(ele.v.val_bytes.bytes[i]));
|
||||
for (int i = 0; i < ele.v.val_array_bool.length; i++) {
|
||||
json_array_append_new(array,
|
||||
json_boolean(ele.v.val_array_bool.bools[i]));
|
||||
}
|
||||
|
||||
json_object_set_new(ob, ele.name, bytes);
|
||||
json_object_set_new(ob, ele.name, array);
|
||||
break;
|
||||
}
|
||||
case NEU_JSON_ARRAY_INT8: {
|
||||
void *array = json_array();
|
||||
|
||||
for (int i = 0; i < ele.v.val_array_int8.length; i++) {
|
||||
json_array_append_new(array,
|
||||
json_integer(ele.v.val_array_int8.i8s[i]));
|
||||
}
|
||||
|
||||
json_object_set_new(ob, ele.name, array);
|
||||
break;
|
||||
}
|
||||
case NEU_JSON_ARRAY_UINT8: {
|
||||
void *array = json_array();
|
||||
|
||||
for (int i = 0; i < ele.v.val_array_uint8.length; i++) {
|
||||
json_array_append_new(array,
|
||||
json_integer(ele.v.val_array_uint8.u8s[i]));
|
||||
}
|
||||
|
||||
json_object_set_new(ob, ele.name, array);
|
||||
break;
|
||||
}
|
||||
case NEU_JSON_ARRAY_INT16: {
|
||||
void *array = json_array();
|
||||
|
||||
for (int i = 0; i < ele.v.val_array_int16.length; i++) {
|
||||
json_array_append_new(array,
|
||||
json_integer(ele.v.val_array_int16.i16s[i]));
|
||||
}
|
||||
|
||||
json_object_set_new(ob, ele.name, array);
|
||||
break;
|
||||
}
|
||||
case NEU_JSON_ARRAY_UINT16: {
|
||||
void *array = json_array();
|
||||
|
||||
for (int i = 0; i < ele.v.val_array_uint16.length; i++) {
|
||||
json_array_append_new(array,
|
||||
json_integer(ele.v.val_array_uint16.u16s[i]));
|
||||
}
|
||||
|
||||
json_object_set_new(ob, ele.name, array);
|
||||
break;
|
||||
}
|
||||
case NEU_JSON_ARRAY_INT32: {
|
||||
void *array = json_array();
|
||||
|
||||
for (int i = 0; i < ele.v.val_array_int32.length; i++) {
|
||||
json_array_append_new(array,
|
||||
json_integer(ele.v.val_array_int32.i32s[i]));
|
||||
}
|
||||
|
||||
json_object_set_new(ob, ele.name, array);
|
||||
break;
|
||||
}
|
||||
case NEU_JSON_ARRAY_UINT32: {
|
||||
void *array = json_array();
|
||||
|
||||
for (int i = 0; i < ele.v.val_array_uint32.length; i++) {
|
||||
json_array_append_new(array,
|
||||
json_integer(ele.v.val_array_uint32.u32s[i]));
|
||||
}
|
||||
|
||||
json_object_set_new(ob, ele.name, array);
|
||||
break;
|
||||
}
|
||||
case NEU_JSON_ARRAY_INT64: {
|
||||
void *array = json_array();
|
||||
|
||||
for (int i = 0; i < ele.v.val_array_int64.length; i++) {
|
||||
json_array_append_new(array,
|
||||
json_integer(ele.v.val_array_int64.i64s[i]));
|
||||
}
|
||||
|
||||
json_object_set_new(ob, ele.name, array);
|
||||
break;
|
||||
}
|
||||
case NEU_JSON_ARRAY_UINT64: {
|
||||
void *array = json_array();
|
||||
|
||||
for (int i = 0; i < ele.v.val_array_uint64.length; i++) {
|
||||
json_array_append_new(array,
|
||||
json_integer(ele.v.val_array_uint64.u64s[i]));
|
||||
}
|
||||
|
||||
json_object_set_new(ob, ele.name, array);
|
||||
break;
|
||||
}
|
||||
case NEU_JSON_ARRAY_FLOAT: {
|
||||
void *array = json_array();
|
||||
|
||||
for (int i = 0; i < ele.v.val_array_float.length; i++) {
|
||||
json_array_append_new(array,
|
||||
json_real(ele.v.val_array_float.f32s[i]));
|
||||
}
|
||||
|
||||
json_object_set_new(ob, ele.name, array);
|
||||
break;
|
||||
}
|
||||
case NEU_JSON_ARRAY_DOUBLE: {
|
||||
void *array = json_array();
|
||||
|
||||
for (int i = 0; i < ele.v.val_array_double.length; i++) {
|
||||
json_array_append_new(array,
|
||||
json_real(ele.v.val_array_double.f64s[i]));
|
||||
}
|
||||
|
||||
json_object_set_new(ob, ele.name, array);
|
||||
break;
|
||||
}
|
||||
case NEU_JSON_OBJECT:
|
||||
@@ -177,7 +287,20 @@ static int decode_object(json_t *root, neu_json_elem_t *ele)
|
||||
} else if (json_is_integer(ob)) {
|
||||
ele->t = NEU_JSON_INT;
|
||||
} else if (json_is_array(ob)) {
|
||||
ele->t = NEU_JSON_BYTES;
|
||||
json_t *value = NULL;
|
||||
int index = 0;
|
||||
ele->t = NEU_JSON_ARRAY_INT64;
|
||||
json_array_foreach(ob, index, value)
|
||||
{
|
||||
if (json_is_real(value)) {
|
||||
ele->t = NEU_JSON_ARRAY_DOUBLE;
|
||||
break;
|
||||
}
|
||||
if (json_is_boolean(value)) {
|
||||
ele->t = NEU_JSON_ARRAY_BOOL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,19 +340,62 @@ static int decode_object(json_t *root, neu_json_elem_t *ele)
|
||||
case NEU_JSON_BOOL:
|
||||
ele->v.val_bool = json_boolean_value(ob);
|
||||
break;
|
||||
case NEU_JSON_BYTES: {
|
||||
case NEU_JSON_ARRAY_BOOL: {
|
||||
json_t *value = NULL;
|
||||
|
||||
ele->v.val_bytes.length = json_array_size(ob);
|
||||
if (ele->v.val_bytes.length > 0) {
|
||||
ele->v.val_array_bool.length = json_array_size(ob);
|
||||
if (ele->v.val_array_bool.length > 0) {
|
||||
int index = 0;
|
||||
|
||||
ele->v.val_bytes.bytes =
|
||||
calloc(ele->v.val_bytes.length, sizeof(uint8_t));
|
||||
ele->v.val_array_bool.bools =
|
||||
calloc(ele->v.val_array_bool.length, sizeof(bool));
|
||||
json_array_foreach(ob, index, value)
|
||||
{
|
||||
ele->v.val_bytes.bytes[index] =
|
||||
(uint8_t) json_integer_value(value);
|
||||
ele->v.val_array_bool.bools[index] = json_boolean_value(value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NEU_JSON_ARRAY_INT64: {
|
||||
json_t *value = NULL;
|
||||
|
||||
ele->v.val_array_int64.length = json_array_size(ob);
|
||||
if (ele->v.val_array_int64.length > 0) {
|
||||
int index = 0;
|
||||
|
||||
ele->v.val_array_int64.i64s =
|
||||
calloc(ele->v.val_array_int64.length, sizeof(int64_t));
|
||||
json_array_foreach(ob, index, value)
|
||||
{
|
||||
if (json_is_real(value)) {
|
||||
ele->v.val_array_int64.i64s[index] =
|
||||
(int64_t) json_real_value(value);
|
||||
} else {
|
||||
ele->v.val_array_int64.i64s[index] =
|
||||
json_integer_value(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NEU_JSON_ARRAY_DOUBLE: {
|
||||
json_t *value = NULL;
|
||||
|
||||
ele->v.val_array_double.length = json_array_size(ob);
|
||||
if (ele->v.val_array_double.length > 0) {
|
||||
int index = 0;
|
||||
|
||||
ele->v.val_array_double.f64s =
|
||||
calloc(ele->v.val_array_double.length, sizeof(double));
|
||||
json_array_foreach(ob, index, value)
|
||||
{
|
||||
if (json_is_integer(value)) {
|
||||
ele->v.val_array_double.f64s[index] =
|
||||
(double) json_integer_value(value);
|
||||
} else {
|
||||
ele->v.val_array_double.f64s[index] =
|
||||
json_real_value(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
+45
-7
@@ -43,6 +43,46 @@ static struct public_key_store key_store;
|
||||
static char neuron_private_key[2048] = { 0 };
|
||||
static char neuron_public_key[2048] = { 0 };
|
||||
|
||||
static const char *private_key_content =
|
||||
"-----BEGIN RSA PRIVATE KEY-----\n"
|
||||
"MIIEpAIBAAKCAQEAzrO7FUz4GGKl4nP5lwKMh5uageJAAHnLZpVxTR1wXA9E870s\n"
|
||||
"U03gHnPWsh2bXCCx85ymYaiu/5VlptgnU0rQB1I3xGRG8eHmHPrhHNWDRKpY6oY8\n"
|
||||
"AnTPqXvfa/Z4u+njJzDSqi4qM8Gwfqlgpjlg8DUF+sheLx8hL+x9XFzovTxafrmy\n"
|
||||
"JRRAVQTkhB7esKKqRF8BMjdOdYZxJEv9jxa0BwXcjprPDlj5TV6k3wJqbq4UtnEE\n"
|
||||
"VbjEQKqFVkfY4FuJ5NSPHpGEix94PGQGRsiWkGX0vx5udHJ0SlXM6qpMLny18FhW\n"
|
||||
"bwKNX3urc3mImn/j3zcJ5x1d+FlXAXs1NBSeTQIDAQABAoIBAQDJOT8PZXbAhohn\n"
|
||||
"A/AeimS0P08S0mbsD6VroGBEajxP4q2FeswD7PQZsTt4+kmcTlfuiLmQqN50AcSL\n"
|
||||
"wDHIbDRIbEnN7rECGKAj5jfwEgtQdWVKKpOQ8JaYr/a466BtjyuLo4PyGC8NY6mm\n"
|
||||
"JM3qBEHSlkvT7+uAhBWSye7gU7JfRPoCeFRpaMMC3Ad0DaIt/Pdt9CddNwj56+9j\n"
|
||||
"gl//blNnBImjvA7/kh9gL69SYVrQoG9vm/UgFbdIwd+w2hhhpx6kuHjRJ21xIV/y\n"
|
||||
"Yh9k4QhPr7zIkhQ8yn11ZhyZkMC8XAMy7NKCmAFIPNJ8jwvgBkunPEk2aYBeDUaq\n"
|
||||
"a30VwlIhAoGBAOnm8DW5DROcfSj4Q8zsvgmvhGM0zzF5zmA+4E+tEbf4t6sDUjSs\n"
|
||||
"ADo2EaiJZz75vLsD7UZHKzFEV/wnuT7SiNCbrJafx8Tp2UgijTkW8gEhAWREJDn5\n"
|
||||
"FS375RKFdEcpmVHWgsuz4z/0L3BGxmyYWQxx5pD2NL49ZpTIHAHm/XETAoGBAOI6\n"
|
||||
"8Y08TmM2bnXbL/MggYMJlqOyv27ueVYz9of3FYFAMIe7ebSgrlSCOwsoDZYmegBM\n"
|
||||
"OrowR3AAnoP4fjGNbIPjNYbiv1qLOdtnvPxYotEz+ZaUBSn9V/gUEVFlgrKxgTKr\n"
|
||||
"sqi/QMyyJplBTUkUuqYRDuv6TZ3OWKiDUoXTdv8fAoGBAIbbyf+PlESMY3Vtvtm2\n"
|
||||
"XdODyRbR6ewiyKShW/9UT/T8iBknrwwDZ5YoeoHrxwV+RBynpPRyMCsVto0B8kKQ\n"
|
||||
"bKWqPBYURb/4/Hgkw7v4yMtx1jWTPDfYryd2JptJKsOk7mtK/Nqp+wpypa9cfyc5\n"
|
||||
"p44PVdqauco96Jk7zzohjlrVAoGAfjQDrJaH5DDpTjYIeckYdtFSh9+fi3LdnYk/\n"
|
||||
"bnoYNRJqAE5Fhs5ccih0Z7TgX3L3fFMKL/Pe5kxyIYzuWRZcAvctVSIJPamNjShB\n"
|
||||
"9UQ9EBe+lJHej54VBP+s6YuHbcg4GtxNvnVy4L5Bah1T0AEQXrQFbv8jbXU/YEJi\n"
|
||||
"NuXQ7GECgYA0UNvuZxVSDn8fBxARcX3ub5aok5owdLL3SOCPMpNrmOBQj8iJGT+5\n"
|
||||
"nv7fH1TWVh9yUdRwhd81s5H/PO3/myLmgq0TcPvewtEEwY+++QpsYZwHTDXgxbbw\n"
|
||||
"++lmJali4fzmd/72JqocGABYhZFt0jbcQ1QEcqUYcD380+cNVZPO+w==\n"
|
||||
"-----END RSA PRIVATE KEY-----\n";
|
||||
|
||||
const char *public_key_content =
|
||||
"-----BEGIN PUBLIC KEY-----\n"
|
||||
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzrO7FUz4GGKl4nP5lwKM\n"
|
||||
"h5uageJAAHnLZpVxTR1wXA9E870sU03gHnPWsh2bXCCx85ymYaiu/5VlptgnU0rQ\n"
|
||||
"B1I3xGRG8eHmHPrhHNWDRKpY6oY8AnTPqXvfa/Z4u+njJzDSqi4qM8Gwfqlgpjlg\n"
|
||||
"8DUF+sheLx8hL+x9XFzovTxafrmyJRRAVQTkhB7esKKqRF8BMjdOdYZxJEv9jxa0\n"
|
||||
"BwXcjprPDlj5TV6k3wJqbq4UtnEEVbjEQKqFVkfY4FuJ5NSPHpGEix94PGQGRsiW\n"
|
||||
"kGX0vx5udHJ0SlXM6qpMLny18FhWbwKNX3urc3mImn/j3zcJ5x1d+FlXAXs1NBSe\n"
|
||||
"TQIDAQAB\n"
|
||||
"-----END PUBLIC KEY-----\n";
|
||||
|
||||
static int find_key(const char *name)
|
||||
{
|
||||
for (int i = 0; i < key_store.size; i++) {
|
||||
@@ -95,15 +135,13 @@ static char *load_key(const char *dir, char *name)
|
||||
|
||||
static void load_neuron_key(const char *dir_path)
|
||||
{
|
||||
char *content = load_key(dir_path, "neuron.key");
|
||||
assert(content != NULL);
|
||||
|
||||
strncpy(neuron_private_key, content, sizeof(neuron_private_key) - 1);
|
||||
(void) dir_path;
|
||||
strncpy(neuron_private_key, private_key_content,
|
||||
sizeof(neuron_private_key) - 1);
|
||||
|
||||
content = load_key(dir_path, "neuron.pem");
|
||||
assert(content != NULL);
|
||||
|
||||
strncpy(neuron_public_key, content, sizeof(neuron_public_key) - 1);
|
||||
strncpy(neuron_public_key, public_key_content,
|
||||
sizeof(neuron_public_key) - 1);
|
||||
}
|
||||
|
||||
static void scanf_key(const char *dir_path)
|
||||
|
||||
@@ -159,6 +159,7 @@ class Mocker:
|
||||
|
||||
def recv(self):
|
||||
msg = self.sock.recv()
|
||||
msg = msg[26:]
|
||||
return json.loads(msg.decode())
|
||||
|
||||
def send(self, data):
|
||||
|
||||
@@ -387,6 +387,14 @@ test_input_bit = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "addre
|
||||
test_input_register_bit = {"driver": "modbus-tcp", "group": "group", "tag": "tag", "address": "1!30010.0",
|
||||
"attribute": config.NEU_TAG_ATTRIBUTE_READ, "type": config.NEU_TYPE_BIT, "precision": 0, "decimal": 0, "bias": 0.0}
|
||||
|
||||
hold_int16_slave255_1 = [{"name": "hold_int16_255_1", "address": "255!400001",
|
||||
"attribute": config.NEU_TAG_ATTRIBUTE_RW_SUBSCRIBE, "type": config.NEU_TYPE_INT16}]
|
||||
hold_int16_slave255_2 = [{"name": "hold_int16_255_2", "address": "255!400003",
|
||||
"attribute": config.NEU_TAG_ATTRIBUTE_RW_SUBSCRIBE, "type": config.NEU_TYPE_INT16}]
|
||||
hold_int16_slave100_1 = [{"name": "hold_int16_100_1", "address": "100!400001",
|
||||
"attribute": config.NEU_TAG_ATTRIBUTE_RW_SUBSCRIBE, "type": config.NEU_TYPE_INT16}]
|
||||
hold_int16_slave100_2 = [{"name": "hold_int16_100_2", "address": "100!400003",
|
||||
"attribute": config.NEU_TAG_ATTRIBUTE_RW_SUBSCRIBE, "type": config.NEU_TYPE_INT16}]
|
||||
|
||||
class TestModbus:
|
||||
|
||||
@@ -1608,3 +1616,146 @@ class TestModbus:
|
||||
|
||||
assert 200 == response.status_code
|
||||
assert error.NEU_ERR_SUCCESS == response.json()['error']
|
||||
|
||||
@description(given="created modbus node with degradation", when="trigger degradation, read tags", then="success")
|
||||
def test_modbus_degradation(self, param):
|
||||
response = api.add_node(node=param[0]+"_degradation", plugin=param[1])
|
||||
assert 200 == response.status_code
|
||||
if param[0] == 'modbus-tcp':
|
||||
api.modbus_tcp_node_setting(
|
||||
node=param[0]+"_degradation", port=tcp_port, device_degrade=1)
|
||||
elif param[0] == 'modbus-rtu':
|
||||
api.modbus_rtu_node_setting(
|
||||
node=param[0]+"_degradation", port=rtu_port, device_degrade=1)
|
||||
else:
|
||||
pytest.skip("modbus rtu tty pass")
|
||||
response = api.add_group(node=param[0]+"_degradation", group='group')
|
||||
assert 200 == response.status_code
|
||||
|
||||
api.add_tags_check(node=param[0]+"_degradation",
|
||||
group='group', tags=hold_int16)
|
||||
api.add_tags_check(node=param[0]+"_degradation",
|
||||
group='group', tags=hold_int16_slave100_1)
|
||||
api.add_tags_check(node=param[0]+"_degradation",
|
||||
group='group', tags=hold_int16_slave100_2)
|
||||
api.add_tags_check(node=param[0]+"_degradation",
|
||||
group='group', tags=hold_int16_slave255_1)
|
||||
api.add_tags_check(node=param[0]+"_degradation",
|
||||
group='group', tags=hold_int16_slave255_2)
|
||||
time.sleep(3)
|
||||
assert 1 == api.read_tag(
|
||||
node=param[0]+"_degradation", group='group', tag=hold_int16[0]['name'])
|
||||
|
||||
@description(given="endianness in node configuration, without endianness in tag", when="write and read tag", then="write/read success")
|
||||
def test_write_read_endianness_node(self, param):
|
||||
if param[0] != 'modbus-tcp':
|
||||
pytest.skip("test modbus tcp only")
|
||||
response = api.add_node(node=param[0]+"_ABCD", plugin=param[1])
|
||||
assert 200 == response.status_code
|
||||
api.modbus_tcp_node_setting_endian(
|
||||
node=param[0]+"_ABCD", port=tcp_port, endianness=4)
|
||||
api.add_tags_check(node=param[0]+"_ABCD", group='group', tags=hold_uint32)
|
||||
api.write_tag_check(
|
||||
node=param[0]+"_ABCD", group='group', tag=hold_uint32[0]['name'], value=0x31323334)
|
||||
time.sleep(0.3)
|
||||
assert 0x31323334 == api.read_tag(
|
||||
node=param[0]+"_ABCD", group='group', tag=hold_uint32[0]['name'])
|
||||
|
||||
response = api.modbus_tcp_node_setting_endian(
|
||||
node=param[0]+"_ABCD", port=tcp_port, endianness=1)
|
||||
time.sleep(0.3)
|
||||
assert 0x33343132 == api.read_tag(
|
||||
node=param[0]+"_ABCD", group='group', tag=hold_uint32[0]['name'])
|
||||
|
||||
response = api.modbus_tcp_node_setting_endian(
|
||||
node=param[0]+"_ABCD", port=tcp_port, endianness=2)
|
||||
time.sleep(0.3)
|
||||
assert 0x34333231 == api.read_tag(
|
||||
node=param[0]+"_ABCD", group='group', tag=hold_uint32[0]['name'])
|
||||
|
||||
response = api.modbus_tcp_node_setting_endian(
|
||||
node=param[0]+"_ABCD", port=tcp_port, endianness=3)
|
||||
time.sleep(0.3)
|
||||
assert 0x32313433 == api.read_tag(
|
||||
node=param[0]+"_ABCD", group='group', tag=hold_uint32[0]['name'])
|
||||
|
||||
@description(given="endianness in tag, without endianness in node configuration", when="write and read tag", then="write/read success")
|
||||
def test_write_read_endianness_tag(self, param):
|
||||
if param[0] != 'modbus-tcp':
|
||||
pytest.skip("test modbus tcp only")
|
||||
api.modbus_tcp_node_setting_endian(
|
||||
node=param[0]+"_ABCD", port=tcp_port, endianness=1)
|
||||
time.sleep(0.3)
|
||||
api.add_tags_check(node=param[0]+"_ABCD", group='group', tags=hold_uint32_LL)
|
||||
api.add_tags_check(node=param[0]+"_ABCD", group='group', tags=hold_uint32_LB)
|
||||
api.add_tags_check(node=param[0]+"_ABCD", group='group', tags=hold_uint32_BL)
|
||||
api.add_tags_check(node=param[0]+"_ABCD", group='group', tags=hold_uint32_BB)
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_LL[0]['name'])
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_LB[0]['name'])
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_BL[0]['name'])
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_BB[0]['name'])
|
||||
|
||||
api.modbus_tcp_node_setting_endian(
|
||||
node=param[0]+"_ABCD", port=tcp_port, endianness=4)
|
||||
time.sleep(0.3)
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_LL[0]['name'])
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_LB[0]['name'])
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_BL[0]['name'])
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_BB[0]['name'])
|
||||
|
||||
api.modbus_tcp_node_setting_endian(
|
||||
node=param[0]+"_ABCD", port=tcp_port, endianness=2)
|
||||
time.sleep(0.3)
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_LL[0]['name'])
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_LB[0]['name'])
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_BL[0]['name'])
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_BB[0]['name'])
|
||||
|
||||
api.modbus_tcp_node_setting_endian(
|
||||
node=param[0]+"_ABCD", port=tcp_port, endianness=3)
|
||||
time.sleep(0.3)
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_LL[0]['name'])
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_LB[0]['name'])
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_BL[0]['name'])
|
||||
assert 12345678 == api.read_tag(
|
||||
node=param[0], group='group', tag=hold_uint32_BB[0]['name'])
|
||||
|
||||
@description(given="created modbus node", when="set modbus start base to 0", then="set success and read/write success")
|
||||
def test_set_modbus_start_base(self, param):
|
||||
assert 1 == api.read_tag(
|
||||
node=param[0], group='group', tag=coil_bit_1[0]['name'])
|
||||
assert 0 == api.read_tag(
|
||||
node=param[0], group='group', tag=coil_bit_2[0]['name'])
|
||||
assert 1 == api.read_tag(
|
||||
node=param[0], group='group', tag=coil_bit_3[0]['name'])
|
||||
|
||||
if param[0] == 'modbus-rtu':
|
||||
api.modbus_rtu_node_setting_base(
|
||||
node=param[0], port=rtu_port, base=0)
|
||||
elif param[0] == 'modbus-tcp':
|
||||
api.modbus_tcp_node_setting_base(
|
||||
node=param[0], port=tcp_port, base=0)
|
||||
else:
|
||||
pytest.skip()
|
||||
time.sleep(0.3)
|
||||
assert 0 == api.read_tag(
|
||||
node=param[0], group='group', tag=coil_bit_1[0]['name'])
|
||||
assert 1 == api.read_tag(
|
||||
node=param[0], group='group', tag=coil_bit_2[0]['name'])
|
||||
assert 0 == api.read_tag(
|
||||
node=param[0], group='group', tag=coil_bit_3[0]['name'])
|
||||
@@ -339,16 +339,20 @@ def prgfile_process(driver):
|
||||
# plugin setting
|
||||
|
||||
|
||||
def modbus_tcp_node_setting(node, port, connection_mode=0, transport_mode=0, interval=0, host='127.0.0.1', timeout=3000, max_retries=2, retry_interval=1):
|
||||
def modbus_tcp_node_setting(node, port, connection_mode=0, transport_mode=0, interval=0, host='127.0.0.1', timeout=3000, max_retries=2, retry_interval=1,
|
||||
device_degrade=0, degrade_cycle=1, degrade_time=600):
|
||||
return node_setting(node, json={"connection_mode": connection_mode, "transport_mode": transport_mode, "interval": interval,
|
||||
"host": host, "port": port, "timeout": timeout, "max_retries": max_retries, "retry_interval": retry_interval})
|
||||
"host": host, "port": port, "timeout": timeout, "max_retries": max_retries, "retry_interval": retry_interval,
|
||||
"device_degrade": device_degrade, "degrade_cycle": degrade_cycle, "degrade_time": degrade_time})
|
||||
|
||||
|
||||
def modbus_rtu_node_setting(node, port=502, connection_mode=0, transport_mode=0, interval=0, host='127.0.0.1', timeout=3000, max_retries=2, retry_interval=1, link=1, device="", stop=0, parity=0, baud=4, data=3):
|
||||
def modbus_rtu_node_setting(node, port=502, connection_mode=0, transport_mode=0, interval=0, host='127.0.0.1', timeout=3000, max_retries=2, retry_interval=1, link=1, device="", stop=0, parity=0, baud=4, data=3,
|
||||
device_degrade=0, degrade_cycle=1, degrade_time=600):
|
||||
return node_setting(node, json={"connection_mode": connection_mode, "transport_mode": transport_mode,
|
||||
"interval": interval, "host": host, "port": port, "timeout": timeout,
|
||||
"max_retries": max_retries, "retry_interval": retry_interval, "link": link, "device": device, "stop": stop,
|
||||
"parity": parity, "baud": baud, "data": data})
|
||||
"parity": parity, "baud": baud, "data": data,
|
||||
"device_degrade": device_degrade, "degrade_cycle": degrade_cycle, "degrade_time": degrade_time})
|
||||
|
||||
|
||||
def modbus_tcp_node_setting_endian(node, port, connection_mode=0, transport_mode=0, interval=0, host='127.0.0.1', timeout=3000, max_retries=2, retry_interval=1, endianness=1):
|
||||
|
||||
@@ -45,6 +45,19 @@ NEU_TYPE_LWORD = 18
|
||||
NEU_TYPE_PTR = 19
|
||||
NEU_TYPE_TIME = 20
|
||||
NEU_TYPE_DATA_AND_TIME = 21
|
||||
NEU_TYPE_ARRAY_CHAR = 22
|
||||
NEU_TYPE_ARRAY_INT8 = 23
|
||||
NEU_TYPE_ARRAY_UINT8 = 24
|
||||
NEU_TYPE_ARRAY_INT16 = 25
|
||||
NEU_TYPE_ARRAY_UINT16 = 26
|
||||
NEU_TYPE_ARRAY_INT32 = 27
|
||||
NEU_TYPE_ARRAY_UINT32 = 28
|
||||
NEU_TYPE_ARRAY_INT64 = 29
|
||||
NEU_TYPE_ARRAY_UINT64 = 30
|
||||
NEU_TYPE_ARRAY_FLOAT = 31
|
||||
NEU_TYPE_ARRAY_DOUBLE = 32
|
||||
NEU_TYPE_ARRAY_BOOL = 33
|
||||
NEU_TYPE_CUSTOM = 40
|
||||
|
||||
NEU_BAUD_115200 = 0
|
||||
NEU_BAUD_57600 = 1
|
||||
|
||||
@@ -53,6 +53,7 @@ NEU_ERR_TAG_ADDRESS_TOO_LONG = 2207
|
||||
NEU_ERR_TAG_DESCRIPTION_TOO_LONG = 2208
|
||||
NEU_ERR_TAG_PRECISION_INVALID = 2209
|
||||
NEU_ERR_TAG_EXIST = 2210
|
||||
NEU_ERR_TAG_DECIMAL_INVALID = 2211
|
||||
NEU_ERR_TAG_BIAS_INVALID = 2212
|
||||
|
||||
NEU_ERR_LIBRARY_NOT_FOUND = 2301
|
||||
|
||||
@@ -463,19 +463,12 @@ class TestPersist:
|
||||
|
||||
@description(given="upload pem in certs", when="login", then="success")
|
||||
def test_jwt(self):
|
||||
if not os.path.exists('./build/certs/'):
|
||||
os.makedirs('./build/certs/')
|
||||
|
||||
shutil.copyfile('./build/config/neuron.pem', './build/certs/neuron.pem')
|
||||
|
||||
p = process.NeuronProcess()
|
||||
p.start()
|
||||
|
||||
response = api.login()
|
||||
assert 200 == response.status_code
|
||||
|
||||
shutil.rmtree('./build/certs/')
|
||||
|
||||
p.stop()
|
||||
|
||||
@description(given="new schema", when="upload schema , restart and add tags", then="success")
|
||||
|
||||
@@ -916,3 +916,34 @@ class TestTag:
|
||||
api.del_tags(
|
||||
node="modbus-tcp", group="group1", tags=[tag["name"]]
|
||||
)
|
||||
|
||||
@description(given="node and group", when="add string tag with decimal", then="add fail")
|
||||
def test_add_string_tag_with_decimal(self):
|
||||
string_decimal = [{"name": "string_decimal", "address": "1!400001.10",
|
||||
"attribute": NEU_TAG_ATTRIBUTE_RW, "type": NEU_TYPE_STRING, "decimal": 0.1}]
|
||||
response = api.add_tags(node="modbus-tcp", group="group1", tags=string_decimal)
|
||||
assert 400 == response.status_code
|
||||
assert NEU_ERR_TAG_DECIMAL_INVALID == response.json()['error']
|
||||
|
||||
@description(given="node and group", when="add string gtags with decimal", then="add fail")
|
||||
def test_add_string_tag_with_decimal(self):
|
||||
response = api.add_gtags(
|
||||
node='modbus-tcp',
|
||||
groups=[
|
||||
{"group": "group_ok","interval": 3000,
|
||||
"tags": [{
|
||||
"name": "tag_string_ok",
|
||||
"address": "1!400001.10",
|
||||
"attribute": 3,
|
||||
"type": NEU_TYPE_STRING}]},
|
||||
{"group": "group123","interval": 3000,
|
||||
"tags": [{
|
||||
"name": "tag_string_decimal",
|
||||
"address": "1!400001.10",
|
||||
"attribute": 3,
|
||||
"type": NEU_TYPE_STRING,
|
||||
"decimal": 0.01}]}
|
||||
])
|
||||
assert 400 == response.status_code
|
||||
assert NEU_ERR_TAG_DECIMAL_INVALID == response.json()['error']
|
||||
assert 1 == response.json()['index']
|
||||
|
||||
@@ -19,8 +19,6 @@ target_include_directories(http_test PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/plugins/restful)
|
||||
target_link_libraries(http_test neuron-base gtest_main gtest jansson nng)
|
||||
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/neuron.key DESTINATION ${UT_DIRECTORY}/config)
|
||||
file(COPY ${CMAKE_SOURCE_DIR}/neuron.pem DESTINATION ${UT_DIRECTORY}/config)
|
||||
add_executable(jwt_test jwt_test.cc)
|
||||
target_include_directories(jwt_test PRIVATE
|
||||
${CMAKE_SOURCE_DIR}/src
|
||||
|
||||
Reference in New Issue
Block a user