Compare commits

...
128 Commits
Author SHA1 Message Date
fengzeroz c0cfdb3170 Merge pull request #2017 from fengzeroz/v2.4
V2.4
2024-05-23 15:50:29 +08:00
fengzero 6af9485b23 merge conn to 2.4 2024-05-23 07:49:59 +00:00
fengzero bf8ea4cfef Revert "test"
This reverts commit 06e50c174b.
2024-05-23 07:47:54 +00:00
fengzeroz 3ff8ad64da Merge pull request #2012 from fengzeroz/v2.4
test
2024-05-21 10:16:39 +08:00
fengzero 06e50c174b test 2024-05-21 02:16:08 +00:00
fengzeroz 29b10bdd31 Merge pull request #2006 from fengzeroz/v2.4
version: 2.4.13
2024-05-20 14:09:22 +08:00
fengzero ef808f878e version: 2.4.13 2024-05-20 06:08:38 +00:00
fengzeroz e631cfad24 Merge pull request #1970 from fengzeroz/v2.4
version: 2.4.12
2024-04-29 15:15:07 +08:00
fengzero 26628d623a version: 2.4.12 2024-04-29 07:14:25 +00:00
fengzeroz b491fecc92 Merge pull request #1587 from fengzeroz/v2.4
version: 2.4.11
2023-10-11 15:10:21 +08:00
fengzero c49f034cd5 version: 2.4.11 2023-10-11 07:09:57 +00:00
fengzeroz 3c7709f4ae Merge pull request #1454 from hxy7yx/v2.4
(file):add error code for reading empty files
2023-08-15 15:16:13 +08:00
hxy7yx 0bf8b7903f (file):add error code for reading empty files 2023-08-15 14:45:06 +08:00
fengzeroz ccb6a62366 Merge pull request #1413 from eeff/v2.4
Pick to 2.4 fix(persist): refresh node and tag count when deleting nodes and groups
2023-07-25 14:46:05 +08:00
eeff 0a21862ac6 fix(persist): refresh node and tag count when deleting nodes and groups 2023-07-25 11:50:18 +08:00
lxm 36cb4f6f3d Merge pull request #1407 from eeff/v2.4
Pick to 2.4 fix: persist node_count and tag_count to signed number
2023-07-24 17:33:58 +08:00
eeff 1efcf861fe fix: persist node_count and tag_count to signed number 2023-07-21 16:37:42 +08:00
lxm 70c3f60ca3 Merge pull request #1404 from lixiumei123/v2.4
version:2.4.10
2023-07-20 16:36:36 +08:00
liyuxi 525723ce2b version:2.4.10 2023-07-20 08:09:28 +00:00
lxm 835cb6bef0 Merge pull request #1401 from fengzeroz/v2.4
fix(driver): if the state of the node was stopped before restart, sto…
2023-07-20 11:21:24 +08:00
fengzero 563b9152bc fix(driver): if the state of the node was stopped before restart, stop the node 2023-07-19 06:46:56 +00:00
eeff 7088a3a1fc Merge pull request #1388 from eeff/v2.4
Pick to v2.4 feat: add persister utilities for getting node/tag count
2023-07-12 15:07:22 +08:00
eeff 87e967b75c feat: add persister utilities for getting node/tag count 2023-07-11 15:39:25 +08:00
lxm be841977b9 Merge pull request #1387 from lixiumei123/v2.4
[v2.4]fix tags with write-only attribute will send read commands
2023-07-10 16:06:49 +08:00
liyuxi 65fff4f60a fix tags with write-only attribute will send read commands 2023-07-10 06:04:54 +00:00
fengzeroz d8edb81d5a Merge pull request #1361 from hxy7yx/v2.4
exclude license when downloading logs
2023-07-03 13:51:14 +08:00
lxm 1d3e929cd8 Merge pull request #1364 from lixiumei123/v2.4
version:2.4.9
2023-06-28 14:55:13 +08:00
liyuxi 43f3f482ee version:2.4.9 2023-06-28 05:43:35 +00:00
hxy7yx 66aa3f96d3 exclude license when downloading logs 2023-06-28 09:51:34 +08:00
fengzero f24b7c0ae5 improve(connection): donot close fd if tty read returns 0 2023-06-26 07:20:35 +00:00
fengzeroz 6a8eb564be Merge pull request #1351 from fengzeroz/v2.4
fix(connection): check result of recv
2023-06-21 17:02:04 +08:00
fengzero 03fa5acf45 fix(connection): check result of recv 2023-06-21 08:55:23 +00:00
fengzeroz bfc14549a9 Merge pull request #1348 from fengzeroz/v2.4
fix(driver): delay write tag
2023-06-21 15:05:19 +08:00
fengzero b2647cc091 fix(driver): delay write tag 2023-06-21 06:18:20 +00:00
fengzeroz de5a085339 Merge pull request #1345 from fengzeroz/v2.4
chore(log): connection log
2023-06-20 17:35:10 +08:00
fengzero 19d8cb10ca chore(log): connection log 2023-06-20 09:30:13 +00:00
fengzero 971b1cf621 Revert "fix(ekuiper): check ip address listenable"
This reverts commit 3f1595c8c1.
2023-06-16 10:53:19 +00:00
fengzeroz ad733be727 Merge pull request #1338 from fengzeroz/v2.4
fix(connection): connection cannot be recovered when the line is abno…
2023-06-16 10:15:51 +08:00
fengzero adc131570a fix(connection): connection cannot be recovered when the line is abnormal 2023-06-15 10:17:14 +00:00
fengzeroz 8fe052364d Merge pull request #1326 from eeff/v2.4
fix(ekuiper): check ip address listenable
2023-06-15 09:49:43 +08:00
eeff 3f1595c8c1 fix(ekuiper): check ip address listenable 2023-06-14 17:41:59 +08:00
lxm 695c17627e Merge pull request #1319 from lixiumei123/v2.4
version:2.4.8
2023-06-09 17:00:18 +08:00
liyuxi aa293a7c56 version:2.4.8 2023-06-09 07:46:28 +00:00
fengzeroz e30d9599a8 Merge pull request #1312 from hxy7yx/v2.4
Login interface verifies password length
2023-06-07 17:58:00 +08:00
hxy7yx 4ba50cfc7c Login interface verifies password length 2023-06-07 15:53:54 +08:00
fengzeroz 3c176bc0c5 Merge pull request #1311 from fengzeroz/v2.4
Revert "chore(event): exit if error occurs"
2023-06-07 15:41:41 +08:00
fengzero 5427c304c8 Revert "chore(event): exit if error occurs"
This reverts commit 96f98d15b9.
2023-06-07 07:34:17 +00:00
fengzeroz 454a49f7fb Merge pull request #1305 from fengzeroz/v2.4
fix(connection): do not call connected in recv
2023-06-05 11:23:26 +08:00
fengzero 738c406e06 fix(connection): do not call connected in recv 2023-06-05 03:09:48 +00:00
fengzeroz 49c0253909 Merge pull request #1303 from lixiumei123/v2.4
fix(file plugin):too long file length leads to crash
2023-06-01 18:13:43 +08:00
liyuxi e57f141606 fix(file plugin):too long file length leads to crash 2023-06-01 10:05:15 +00:00
fengzeroz cee2260cfd Merge pull request #1302 from fengzeroz/v2.4
fix(connection): disconnect if decode fail
2023-06-01 17:40:12 +08:00
fengzero 2f2fc27b49 fix(connection): disconnect if decode fail 2023-06-01 09:35:09 +00:00
fengzeroz 8d8afa3c84 Merge pull request #1299 from fengzeroz/v2.4
fix(connection): disconnect if decode fail
2023-05-31 10:03:49 +08:00
fengzero d868b77154 fix(connection): disconnect if decode fail 2023-05-31 01:46:18 +00:00
fengzeroz 71bf03badb Merge pull request #1296 from fengzeroz/v2.4
fix cppcheck
2023-05-30 16:50:00 +08:00
fengzero 18bb90b3cf fix cppcheck 2023-05-30 08:22:20 +00:00
fengzeroz 49257b850b Merge pull request #1295 from fengzeroz/v2.4
chore(event): exit if error occurs
2023-05-30 14:04:25 +08:00
fengzero 96f98d15b9 chore(event): exit if error occurs 2023-05-30 06:03:32 +00:00
fengzeroz b87fee91c1 Merge pull request #1291 from fengzeroz/v2.4
chore(type): fix compile error in arm64-musl
2023-05-26 17:38:04 +08:00
fengzero b8a49073ca chore(type): fix compile error in arm64-musl 2023-05-26 09:29:09 +00:00
fengzeroz 746e010e7e Merge pull request #1289 from fengzeroz/v2.4
version: 2.4.7
2023-05-26 15:29:07 +08:00
fengzero 2a292c11f1 version: 2.4.7 2023-05-26 07:26:26 +00:00
hxy7yx b7c35347e2 Merge pull request #1285 from hxy7yx/v2.4
Add node type to /api/v2/metrics
2023-05-24 09:22:32 +08:00
hxy7yx 8dfdcee740 Add node type to /api/v2/metrics 2023-05-23 18:26:44 +08:00
fengzeroz 7166b68293 Merge pull request #1278 from lixiumei123/v2.4
chore(file plugin):update log level
2023-05-19 16:44:11 +08:00
liyuxi c48aebce8d chore(file plugin):update log level 2023-05-19 08:34:33 +00:00
fengzeroz 7dd05b453b Merge pull request #1280 from fengzeroz/v2.4
update log level
2023-05-19 16:14:08 +08:00
fengzero c88b60c8c3 fix(daemon): log format 2023-05-19 08:06:05 +00:00
fengzero 0b75c2afb0 chore(adapter): log level 2023-05-19 08:06:05 +00:00
fengzero 58960f4be6 chore(base): log level 2023-05-19 08:06:05 +00:00
fengzero c9c35e02c6 chore(connection): log level 2023-05-19 08:06:05 +00:00
fengzero e5e421f257 chore(manager): log level 2023-05-19 08:06:05 +00:00
fengzero 4d4887a6e3 chore(event): log level 2023-05-19 08:06:05 +00:00
fengzero d57b95b0a1 chore(log): default notice 2023-05-19 08:06:05 +00:00
fengzeroz c1cafe3fc7 Merge pull request #1276 from hxy7yx/v2.4
chore(modbus):improve log
2023-05-19 16:05:31 +08:00
hxy7yx cdbb511140 chore(modbus):improve log 2023-05-18 15:50:55 +08:00
hxy7yx d2b96f5ca8 Revert "chore(modbus):improve log"
This reverts commit 369e49f7ce.
2023-05-18 15:34:09 +08:00
hxy7yx 6bdf31b660 chore(modbus):improve log 2023-05-18 14:55:31 +08:00
hxy7yx 369e49f7ce chore(modbus):improve log 2023-05-18 14:30:32 +08:00
fengzeroz a2c81d3572 Merge pull request #1273 from eeff/v2.4
Pick to 2.4: update mqtt, monitor, ekuiper, restful log level
2023-05-18 12:32:06 +08:00
fengzeroz d3f0b52fb2 Merge pull request #1274 from fengzeroz/v2.4
chore(log): limit string length
2023-05-17 18:27:10 +08:00
fengzero 82fe13876f chore(log): limit string length 2023-05-17 10:02:00 +00:00
eeff ed01dd060a chore(restful): update log level 2023-05-17 17:34:58 +08:00
eeff f69328e01a chore(ekuiper): update log level 2023-05-17 17:34:58 +08:00
eeff e33d331ee3 chore(monitor): update log level 2023-05-17 17:34:55 +08:00
eeff 542624189a chore(mqtt): update log level 2023-05-17 17:34:11 +08:00
fengzeroz 90e7b0ec03 Merge pull request #1271 from fengzeroz/v2.4
chore: log type & value
2023-05-17 16:44:00 +08:00
fengzero 30579ef578 chore: log type & value 2023-05-17 08:36:31 +00:00
fengzeroz bc44bfeda1 Merge pull request #1268 from fengzeroz/v2.4
type: get value
2023-05-17 11:39:16 +08:00
fengzero 73efd03cfa type: get value 2023-05-17 03:38:30 +00:00
fengzeroz 60c707cdde Merge pull request #1267 from fengzeroz/v2.4
packed neu_value_u
2023-05-16 20:23:29 +08:00
fengzero 10b317c0d7 packed neu_value_u 2023-05-16 12:22:55 +00:00
fengzeroz 3d9ac43d42 Merge pull request #1263 from fengzeroz/v2.4
version: 2.4.6
2023-05-15 14:54:42 +08:00
fengzero 3605e132cc version: 2.4.6 2023-05-15 06:54:11 +00:00
fengzeroz 163475f9a9 Merge pull request #1262 from fengzeroz/v2.4
manager nng: set sendtimeout
2023-05-15 10:46:14 +08:00
fengzero d2cd9267bc manager nng: set sendtimeout 2023-05-15 02:45:00 +00:00
fengzeroz 6d6af8be93 Merge pull request #1261 from fengzeroz/v2.4
improve: nng buf size
2023-05-12 18:21:26 +08:00
fengzero fddad11a5f improve: nng buf size 2023-05-12 10:20:13 +00:00
fengzeroz 56e45ae77e Merge pull request #1260 from fengzeroz/v2.4
improve(driver): drive reads and writes in a single thread
2023-05-12 16:05:36 +08:00
fengzero edd1d5eee0 improve(driver): drive reads and writes in a single thread 2023-05-12 08:04:51 +00:00
fengzeroz ebf9d92315 Merge pull request #1258 from eeff/v2.4
Pick to 2.4 chore: fix mqtt log
2023-05-11 14:27:26 +08:00
eeff 5fcd8d2d03 chore: fix mqtt log 2023-05-11 10:51:25 +08:00
fengzeroz 6ad096315f Merge pull request #1256 from fengzeroz/v2.4
protocol buf: unpack buf size
2023-05-10 16:30:45 +08:00
fengzero 8f98ab9d6f protocol buf: unpack buf size 2023-05-10 08:30:13 +00:00
fengzeroz ebfb31d672 Merge pull request #1255 from fengzeroz/v2.4
protocol buf: use all buf
2023-05-10 16:26:23 +08:00
fengzero e691099640 protocol buf: use all buf 2023-05-10 08:24:45 +00:00
fengzeroz e9505e14cd Merge pull request #1252 from lixiumei123/v2.4
fix(dlt645):fix the connection status
2023-05-08 15:38:10 +08:00
liyuxi 2555525445 fix(dlt645):fix the connection status 2023-05-08 07:16:51 +00:00
fengzeroz ab8da34a6d Merge pull request #1250 from eeff/v2.4
Pick to 2.4 feat: add SQL schema migrating MQTT upload-topic to subscription parameter
2023-05-08 14:52:17 +08:00
eeff 899081fc03 fix(core): subscription parameter memory leak 2023-05-08 14:41:39 +08:00
eeff ebb969af8f feat: add SQL schema migrating MQTT upload-topic to subscription parameters 2023-05-08 14:41:39 +08:00
fengzeroz 4a56ba1a3a Merge pull request #1249 from fengzeroz/v2.4
fix(connection): recv errorno check
2023-05-08 14:22:18 +08:00
fengzero 069786f6c0 fix(connection): recv errorno check 2023-05-08 03:35:31 +00:00
fengzeroz a548a57d11 Merge pull request #1245 from fengzeroz/v2.4
version: 2.4.5
2023-05-06 14:37:38 +08:00
fengzero 37f45d4b3a version: 2.4.5 2023-05-06 06:37:15 +00:00
fengzeroz 3a1a0fab3a Merge pull request #1244 from fengzeroz/v2.4
fix clang format
2023-05-06 14:21:47 +08:00
fengzero 10eec9446a fix clang format 2023-05-06 06:21:24 +00:00
fengzeroz 2df3f79536 Merge pull request #1243 from fengzeroz/v2.4
fix(mips): link atomic
2023-05-06 14:20:47 +08:00
fengzero f23c5a5cb8 fix(mips): link atomic 2023-05-06 06:20:24 +00:00
fengzeroz eadcdf5fa1 Merge pull request #1242 from fengzeroz/v2.4
fix(mips): compile error
2023-05-06 14:00:15 +08:00
fengzero d1dd7008e6 fix(mips): compile error 2023-05-06 05:59:50 +00:00
fengzeroz b0b6a08702 Merge pull request #1241 from eeff/v2.4
Pick to 2.4 feat(mqtt): use write-req-topic and write-resp-topic
2023-05-06 13:52:00 +08:00
eeff 77e25d532b feat(mqtt): use write-req-topic and write-resp-topic 2023-05-06 10:43:22 +08:00
eeff d1d5b95a6a feat: add mqtt client unsubscribe method 2023-05-06 10:43:22 +08:00
eeff 125324546f feat(mqtt): add write request/response topic config 2023-05-06 10:43:22 +08:00
fengzeroz 0556e30343 Merge pull request #1238 from fengzeroz/v2.4
chore(error): device not response
2023-05-04 11:41:33 +08:00
fengzero 97e8febf91 chore(error): device not response 2023-05-04 03:22:30 +00:00
55 changed files with 1841 additions and 637 deletions
+2 -2
View File
@@ -8,8 +8,8 @@ on:
- published
env:
VERSION: 2.4.4
UI_VERSION: 2.4.3
VERSION: 2.4.13
UI_VERSION: 2.4.8
BRANCH: v2.4
jobs:
+4 -1
View File
@@ -16,4 +16,7 @@ tmp
*.deb
*.rpm
neuron-sdk
.vscode
.vscode
log.html
output.xml
report.html
+1 -1
View File
@@ -32,7 +32,7 @@ if(NOT DISABLE_WERROR)
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -g")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O1")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS} -O0")
if(NOT DISABLE_ASAN)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS} -fsanitize=address")
+4
View File
@@ -17,3 +17,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
link_directories(${CMAKE_STAGING_PREFIX})
if(CMAKE_SYSTEM_PROCESSOR MATCHES "mips32")
link_libraries(atomic)
endif()
+4 -1
View File
@@ -71,4 +71,7 @@ ${NEU_ERR_PLUGIN_TAG_VALUE_EXPIRED} 3008
${NEU_ERR_PLUGIN_PROTOCOL_DECODE_FAILURE} 3009
${NEU_ERR_PLUGIN_NOT_RUNNING} 3010
${NEU_ERR_PLUGIN_TAG_NOT_READY} 3011
${NEU_ERR_PLUGIN_PACKET_OUT_OF_ORDER} 3012
${NEU_ERR_PLUGIN_PACKET_OUT_OF_ORDER} 3012
${NEU_ERR_PLUGIN_NAME_TOO_LONG} 3013
${NEU_ERR_PLUGIN_NOT_FOUND} 3014
${NEU_ERR_PLUGIN_DEVICE_NOT_RESPONSE} 3015
+2 -2
View File
@@ -207,8 +207,8 @@ typedef struct neu_resp_error {
} neu_resp_error_t;
typedef struct {
char node[NEU_NODE_NAME_LEN];
bool auto_start;
char node[NEU_NODE_NAME_LEN];
neu_node_running_state_e state;
} neu_req_node_init_t, neu_req_node_uninit_t, neu_resp_node_uninit_t;
typedef struct neu_req_add_plugin {
+2
View File
@@ -114,6 +114,8 @@ 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);
int neu_mqtt_client_unsubscribe(neu_mqtt_client_t *client, const char *topic);
#ifdef __cplusplus
}
#endif
@@ -30,6 +30,7 @@ typedef enum neu_conn_type {
NEU_CONN_TCP_CLIENT,
NEU_CONN_UDP,
NEU_CONN_TTY_CLIENT,
NEU_CONN_UDP_TO,
} neu_conn_type_e;
typedef enum neu_conn_tty_baud {
@@ -103,6 +104,12 @@ typedef struct neu_conn_param {
uint16_t timeout; // millisecond
} udp;
struct {
char * src_ip;
uint16_t src_port;
uint16_t timeout; // millisecond
} udpto;
struct {
char * device;
neu_conn_tty_data_e data;
@@ -231,6 +238,8 @@ int neu_conn_tcp_server_close_client(neu_conn_t *conn, int fd);
* less than or equal to 0 fails.
*/
ssize_t neu_conn_send(neu_conn_t *conn, uint8_t *buf, ssize_t len);
ssize_t neu_conn_udp_sendto(neu_conn_t *conn, uint8_t *buf, ssize_t len,
void *dst);
/**
* @brief Receive data via connection read.
@@ -242,6 +251,8 @@ ssize_t neu_conn_send(neu_conn_t *conn, uint8_t *buf, ssize_t len);
* received, less than or equal to 0 fails.
*/
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);
/**
* @brief Specify the client to send data.
@@ -32,23 +32,19 @@ neu_conn_eth_t *neu_conn_eth_init(const char *interface, void *ctx);
int neu_conn_eth_uninit(neu_conn_eth_t *conn);
int neu_conn_eth_check_interface(const char *interface);
void neu_conn_eth_get_mac(neu_conn_eth_t *conn, uint8_t *mac);
int neu_conn_eth_size();
typedef void (*neu_conn_eth_msg_callback)(neu_conn_eth_t *conn, void *ctx,
uint16_t protocol, uint16_t n_byte,
uint8_t *bytes, uint8_t src_mac[6]);
int neu_conn_eth_register_lldp(neu_conn_eth_t *conn, const char *device,
neu_conn_eth_msg_callback callback);
int neu_conn_eth_unregister_lldp(neu_conn_eth_t *conn, const char *device);
typedef struct neu_conn_eth_sub neu_conn_eth_sub_t;
neu_conn_eth_sub_t *neu_conn_eth_register(neu_conn_eth_t *conn,
uint16_t protocol, uint8_t mac[6],
neu_conn_eth_sub_t *neu_conn_eth_register(neu_conn_eth_t *conn, uint8_t mac[6],
neu_conn_eth_msg_callback callback);
int neu_conn_eth_unregister(neu_conn_eth_t *conn, neu_conn_eth_sub_t *sub);
int neu_conn_eth_send(neu_conn_eth_t *conn, uint8_t dst_mac[6],
uint16_t protocol, uint16_t n_byte, uint8_t *bytes);
int neu_conn_eth_send(neu_conn_eth_t *conn, uint16_t protocol, uint16_t n_byte,
uint8_t *bytes);
#endif
@@ -0,0 +1,25 @@
/**
* NEURON IIoT System for Industry 4.0
* Copyright (C) 2020-2023 EMQ Technologies Co., Ltd All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
#ifndef NEURON_CONNECTION_SMART_LINK_H
#define NEURON_CONNECTION_SMART_LINK_H
int neu_conn_smart_link_auto_set(const char *dev_path);
#endif
+3 -1
View File
@@ -113,6 +113,7 @@ typedef enum {
NEU_ERR_PLUGIN_PACKET_OUT_OF_ORDER = 3012,
NEU_ERR_PLUGIN_NAME_TOO_LONG = 3013,
NEU_ERR_PLUGIN_NOT_FOUND = 3014,
NEU_ERR_PLUGIN_DEVICE_NOT_RESPONSE = 3015,
NEU_ERR_MQTT_FAILURE = 4000,
NEU_ERR_MQTT_NO_CERTFILESET = 4001,
@@ -132,10 +133,11 @@ typedef enum {
NEU_ERR_MQTT_SUSPENDED = 4015,
NEU_ERR_MQTT_PUBLISH_OVER_LENGTH = 4016,
NEU_ERR_FILE_TOO_LONG = 4100,
NEU_ERR_STRING_TOO_LONG = 4100,
NEU_ERR_FILE_OPEN_FAILURE = 4101,
NEU_ERR_FILE_READ_FAILURE = 4102,
NEU_ERR_FILE_WRITE_FAILURE = 4103,
NEU_ERR_FILE_READ_NULL = 4104,
NEU_ERR_PLUGIN_ERROR_START = 10000,
NEU_ERR_PLUGIN_ERROR_END = 20000,
+2
View File
@@ -95,6 +95,8 @@ int neu_persister_create(const char *schema_dir);
void neu_persister_destroy();
sqlite3 *neu_persister_get_db();
int neu_persister_node_count();
int neu_persister_tag_count();
/**
* Persist nodes.
+203 -1
View File
@@ -28,6 +28,7 @@ extern "C" {
#include <netinet/in.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
typedef enum {
NEU_TYPE_INT8 = 1,
@@ -109,7 +110,80 @@ typedef union {
double d64;
char str[NEU_VALUE_SIZE];
uint8_t bytes[NEU_VALUE_SIZE];
} neu_value_u;
} __attribute__((packed)) neu_value_u;
static inline char *neu_value_str(neu_type_e type, neu_value_u value)
{
static __thread char str[32] = { 0 };
switch (type) {
case NEU_TYPE_INT8:
snprintf(str, sizeof(str), "type: %s, value: %i", neu_type_string(type),
value.i8);
break;
case NEU_TYPE_UINT8:
snprintf(str, sizeof(str), "type: %s, value: %u", neu_type_string(type),
value.u8);
break;
case NEU_TYPE_INT16:
snprintf(str, sizeof(str), "type: %s, value: %i", neu_type_string(type),
value.i16);
break;
case NEU_TYPE_WORD:
case NEU_TYPE_UINT16:
snprintf(str, sizeof(str), "type: %s, value: %u", neu_type_string(type),
value.u16);
break;
case NEU_TYPE_INT32:
snprintf(str, sizeof(str), "type: %s, value: %i", neu_type_string(type),
value.i32);
break;
case NEU_TYPE_DWORD:
case NEU_TYPE_UINT32:
snprintf(str, sizeof(str), "type: %s, value: %u", neu_type_string(type),
value.u32);
break;
case NEU_TYPE_INT64: {
long long int i = value.i64;
snprintf(str, sizeof(str), "type: %s, value: %lld",
neu_type_string(type), i);
break;
}
case NEU_TYPE_LWORD:
case NEU_TYPE_UINT64: {
long long unsigned int i = value.u64;
snprintf(str, sizeof(str), "type: %s, value: %llu",
neu_type_string(type), i);
break;
}
case NEU_TYPE_FLOAT:
snprintf(str, sizeof(str), "type: %s, value: %f", neu_type_string(type),
value.f32);
break;
case NEU_TYPE_DOUBLE:
snprintf(str, sizeof(str), "type: %s, value: %f", neu_type_string(type),
value.d64);
break;
case NEU_TYPE_BIT:
snprintf(str, sizeof(str), "type: %s, value: %u", neu_type_string(type),
value.u8);
break;
case NEU_TYPE_BOOL:
snprintf(str, sizeof(str), "type: %s, value: %u", neu_type_string(type),
value.boolean);
break;
case NEU_TYPE_STRING: {
snprintf(str, sizeof(str), "type: %s, value: %c%c%c",
neu_type_string(type), value.str[0], value.str[1],
value.str[2]);
break;
}
default:
break;
}
return str;
}
typedef struct {
neu_type_e type;
@@ -443,6 +517,134 @@ static inline void neu_htons_p(uint16_t *pu)
neu_ntohs_p(pu);
}
static inline uint16_t neu_get_u16(uint8_t *bytes)
{
uint16_t ret = 0;
uint8_t *t = NULL;
t = (uint8_t *) &ret;
t[0] = bytes[0];
t[1] = bytes[1];
return ret;
}
static inline int16_t neu_get_i16(uint8_t *bytes)
{
int16_t ret = 0;
uint8_t *t = NULL;
t = (uint8_t *) &ret;
t[0] = bytes[0];
t[1] = bytes[1];
return ret;
}
static inline uint32_t neu_get_u32(uint8_t *bytes)
{
uint32_t ret = 0;
uint8_t *t = NULL;
t = (uint8_t *) &ret;
t[0] = bytes[0];
t[1] = bytes[1];
t[2] = bytes[2];
t[3] = bytes[3];
return ret;
}
static inline int32_t neu_get_i32(uint8_t *bytes)
{
int32_t ret = 0;
uint8_t *t = NULL;
t = (uint8_t *) &ret;
t[0] = bytes[0];
t[1] = bytes[1];
t[2] = bytes[2];
t[3] = bytes[3];
return ret;
}
static inline float neu_get_f32(uint8_t *bytes)
{
float ret = 0;
uint8_t *t = NULL;
t = (uint8_t *) &ret;
t[0] = bytes[0];
t[1] = bytes[1];
t[2] = bytes[2];
t[3] = bytes[3];
return ret;
}
static inline uint64_t neu_get_u64(uint8_t *bytes)
{
uint64_t ret = 0;
uint8_t *t = NULL;
t = (uint8_t *) &ret;
t[0] = bytes[0];
t[1] = bytes[1];
t[2] = bytes[2];
t[3] = bytes[3];
t[4] = bytes[4];
t[5] = bytes[5];
t[6] = bytes[6];
t[7] = bytes[7];
return ret;
}
static inline int64_t neu_get_i64(uint8_t *bytes)
{
int64_t ret = 0;
uint8_t *t = NULL;
t = (uint8_t *) &ret;
t[0] = bytes[0];
t[1] = bytes[1];
t[2] = bytes[2];
t[3] = bytes[3];
t[4] = bytes[4];
t[5] = bytes[5];
t[6] = bytes[6];
t[7] = bytes[7];
return ret;
}
static inline double neu_get_f64(uint8_t *bytes)
{
double ret = 0;
uint8_t *t = NULL;
t = (uint8_t *) &ret;
t[0] = bytes[0];
t[1] = bytes[1];
t[2] = bytes[2];
t[3] = bytes[3];
t[4] = bytes[4];
t[5] = bytes[5];
t[6] = bytes[6];
t[7] = bytes[7];
return ret;
}
#ifdef __cplusplus
}
#endif
+12
View File
@@ -192,4 +192,16 @@ neu_protocol_unpack_buf_used_size(neu_protocol_unpack_buf_t *buf)
return buf->offset;
}
inline static void
neu_protocol_unpack_buf_use_all(neu_protocol_unpack_buf_t *buf)
{
buf->offset = buf->size;
}
inline static uint16_t
neu_protocol_unpack_buf_size(neu_protocol_unpack_buf_t *buf)
{
return buf->size;
}
#endif
+10
View File
@@ -26,6 +26,7 @@ extern "C" {
#include <stdint.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
static inline int64_t neu_time_ms()
{
@@ -34,6 +35,15 @@ static inline int64_t neu_time_ms()
return (int64_t) tv.tv_sec * 1000 + (int64_t) tv.tv_usec / 1000;
}
static inline void neu_msleep(unsigned msec)
{
struct timespec tv = {
.tv_sec = msec / 1000,
.tv_nsec = (msec % 1000) * 1000000,
};
nanosleep(&tv, NULL);
}
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,59 @@
/**
* NEURON IIoT System for Industry 4.0
* Copyright (C) 2020-2023 EMQ Technologies Co., Ltd All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
BEGIN TRANSACTION;
-- for backward compatibility with version 2.3,
-- migrate MQTT plugin upload-topic to subscription parameters.
WITH
topics AS (
SELECT
name AS app,
json_extract(json(setting), '$.params.upload-topic') AS topic
FROM
nodes
JOIN settings
WHERE
name = node_name
AND plugin_name = 'MQTT'
)
UPDATE
subscriptions
SET
params = (
SELECT
json_object('params', json_object('topic', topic)) AS params
FROM
topics
WHERE
topics.app = subscriptions.app_name
AND topics.topic NOT NULL
)
WHERE
EXISTS (
SELECT
topic
FROM
topics
WHERE
topics.app = subscriptions.app_name
AND topics.topic NOT NULL
AND subscriptions.params IS NULL
);
COMMIT;
+11 -11
View File
@@ -34,8 +34,8 @@ static neu_plugin_t *ekuiper_plugin_open(void)
neu_plugin_common_init(&plugin->common);
zlog_info(neuron, "success to create plugin: %s",
neu_plugin_module.module_name);
zlog_notice(neuron, "success to create plugin: %s",
neu_plugin_module.module_name);
return plugin;
}
@@ -44,8 +44,8 @@ static int ekuiper_plugin_close(neu_plugin_t *plugin)
int rv = 0;
free(plugin);
zlog_info(neuron, "success to free plugin: %s",
neu_plugin_module.module_name);
zlog_notice(neuron, "success to free plugin: %s",
neu_plugin_module.module_name);
return rv;
}
@@ -91,7 +91,7 @@ static int ekuiper_plugin_init(neu_plugin_t *plugin)
plugin->recv_aio = recv_aio;
plog_info(plugin, "plugin initialized");
plog_notice(plugin, "plugin initialized");
return rv;
}
@@ -104,7 +104,7 @@ static int ekuiper_plugin_uninit(neu_plugin_t *plugin)
free(plugin->host);
free(plugin->url);
plog_info(plugin, "plugin uninitialized");
plog_notice(plugin, "plugin uninitialized");
return rv;
}
@@ -172,7 +172,7 @@ static int parse_config(neu_plugin_t *plugin, const char *setting,
*host_p = host.v.val_str;
*port_p = port.v.val_int;
plog_info(plugin, "config host:%s port:%" PRIu16, *host_p, *port_p);
plog_notice(plugin, "config host:%s port:%" PRIu16, *host_p, *port_p);
return 0;
@@ -201,7 +201,7 @@ static int ekuiper_plugin_config(neu_plugin_t *plugin, const char *setting)
goto error;
}
plog_info(plugin, "config success");
plog_notice(plugin, "config success");
free(plugin->host);
plugin->host = host;
@@ -220,7 +220,7 @@ static int ekuiper_plugin_config(neu_plugin_t *plugin, const char *setting)
error:
free(url);
free(host);
plog_info(plugin, "config failure");
plog_error(plugin, "config failure");
return rv;
}
@@ -239,7 +239,7 @@ static int ekuiper_plugin_request(neu_plugin_t * plugin,
switch (header->type) {
case NEU_RESP_ERROR: {
neu_resp_error_t *error = (neu_resp_error_t *) data;
plog_info(plugin, "receive resp errcode: %d", error->error);
plog_debug(plugin, "receive resp errcode: %d", error->error);
break;
}
case NEU_REQRESP_TRANS_DATA: {
@@ -259,7 +259,7 @@ static int ekuiper_plugin_request(neu_plugin_t * plugin,
case NEU_REQ_UNSUBSCRIBE_GROUP:
break;
default:
plog_notice(plugin, "unsupported request type: %d", header->type);
plog_warn(plugin, "unsupported request type: %d", header->type);
break;
}
+2 -1
View File
@@ -15,7 +15,8 @@
"type": "int",
"default": 512,
"valid": {
"min": 1
"min": 1,
"max": 512
}
}
}
+26 -10
View File
@@ -74,6 +74,9 @@ static neu_plugin_t *driver_open(void)
static int driver_close(neu_plugin_t *plugin)
{
plog_notice(plugin, "close and free `%s` plugin success",
plugin->common.name);
free(plugin);
return 0;
@@ -81,8 +84,9 @@ static int driver_close(neu_plugin_t *plugin)
static int driver_init(neu_plugin_t *plugin)
{
plugin->events = neu_event_new();
plugin->common.link_state = NEU_NODE_LINK_STATE_CONNECTED;
plugin->events = neu_event_new();
plog_notice(plugin, "initialize `%s` plugin success", plugin->common.name);
return 0;
}
@@ -90,21 +94,27 @@ static int driver_init(neu_plugin_t *plugin)
static int driver_uninit(neu_plugin_t *plugin)
{
neu_event_close(plugin->events);
plog_info(plugin, "node; file uininit ok");
plog_notice(plugin, "uninitialize `%s` plugin success",
plugin->common.name);
return 0;
}
static int driver_start(neu_plugin_t *plugin)
{
(void) plugin;
plugin->common.link_state = NEU_NODE_LINK_STATE_CONNECTED;
plog_notice(plugin, "start `%s` plugin success", plugin->common.name);
return 0;
}
static int driver_stop(neu_plugin_t *plugin)
{
(void) plugin;
plugin->common.link_state = NEU_NODE_LINK_STATE_DISCONNECTED;
plog_notice(plugin, "stop `%s` plugin success", plugin->common.name);
return 0;
}
@@ -116,12 +126,13 @@ static int driver_config(neu_plugin_t *plugin, const char *config)
int ret = neu_parse_param((char *) config, &err_param, 1, &file_length);
if (ret != 0) {
plog_warn(plugin, "config:%s, decode error: %s", config, err_param);
plog_error(plugin, "config:%s, decode error: %s", config, err_param);
free(err_param);
return -1;
}
plugin->file_length = file_length.v.val_int;
plugin->file_length = file_length.v.val_int;
plugin->common.link_state = NEU_NODE_LINK_STATE_CONNECTED;
return 0;
}
@@ -138,8 +149,8 @@ static int driver_request(neu_plugin_t *plugin, neu_reqresp_head_t *head,
static int driver_validate_tag(neu_plugin_t *plugin, neu_datatag_t *tag)
{
plog_debug(plugin, "validate tag success, name:%s, address:%s,type:%d ",
tag->name, tag->address, tag->type);
plog_notice(plugin, "validate tag success, name:%s, address:%s, type:%d ",
tag->name, tag->address, tag->type);
return 0;
}
@@ -152,5 +163,10 @@ 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,
neu_value_u value)
{
return file_write(plugin, req, tag, value);
int ret = file_write(plugin, req, tag, value);
plog_notice(plugin, "write response, ret: %d, tag_name: %s, type: %d", ret,
tag->name, tag->type);
return ret;
}
+40 -10
View File
@@ -62,7 +62,7 @@ int file_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group)
}
if ((f = fopen(tag->address, "rb+")) == NULL) {
nlog_error("open file:%s", tag->address);
nlog_warn("fail open to read and write file: %s", tag->address);
dvalue.type = NEU_TYPE_ERROR;
dvalue.value.i32 = NEU_ERR_FILE_OPEN_FAILURE;
goto dvalue_result;
@@ -71,8 +71,11 @@ int file_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group)
fseek(f, 0, SEEK_END);
int size = ftell(f);
if (size >= length) {
nlog_warn(
"the file length exceeds the set value, file: %s, length: %d",
tag->address, size);
dvalue.type = NEU_TYPE_ERROR;
dvalue.value.i32 = NEU_ERR_FILE_TOO_LONG;
dvalue.value.i32 = NEU_ERR_STRING_TOO_LONG;
fclose(f);
goto dvalue_result;
@@ -81,9 +84,23 @@ int file_group_timer(neu_plugin_t *plugin, neu_plugin_group_t *group)
fseek(f, 0, SEEK_SET);
int ret = fread(buf, sizeof(char), length, f);
if (ret == 0) {
nlog_error("read file failed:%s", tag->address);
if (feof(f)) {
nlog_warn("file is empty:%s", tag->address);
dvalue.type = NEU_TYPE_ERROR;
dvalue.value.i32 = NEU_ERR_FILE_READ_NULL;
} else if (ferror(f)) {
nlog_warn("read file failed: %s", tag->address);
clearerr(f);
dvalue.type = NEU_TYPE_ERROR;
dvalue.value.i32 = NEU_ERR_FILE_READ_FAILURE;
}
fclose(f);
goto dvalue_result;
} else if (ret >= NEU_VALUE_SIZE) {
nlog_warn("the file length exceeds the maximum, file: %s, ret: %d",
tag->address, ret);
dvalue.type = NEU_TYPE_ERROR;
dvalue.value.i32 = NEU_ERR_FILE_READ_FAILURE;
dvalue.value.i32 = NEU_ERR_STRING_TOO_LONG;
fclose(f);
goto dvalue_result;
@@ -121,19 +138,32 @@ static void plugin_group_free(neu_plugin_group_t *pgp)
int file_write(neu_plugin_t *plugin, void *req, neu_datatag_t *tag,
neu_value_u value)
{
FILE *fp = fopen(tag->address, "w");
int ret = 0;
FILE *fp = NULL;
int ret = 0;
int length = strlen(value.str);
if (length >= NEU_VALUE_SIZE) {
nlog_warn("write file exceeds the maximum value, file: %s, length: %d",
tag->address, length);
ret = NEU_ERR_STRING_TOO_LONG;
if (0 == fwrite(value.str, sizeof(char), strlen(value.str), fp)) {
nlog_error("write file failed:%s", tag->address);
ret = NEU_ERR_FILE_WRITE_FAILURE;
goto dvalue_result;
}
fp = fopen(tag->address, "w");
if (0 == fwrite(value.str, sizeof(char), strlen(value.str), fp)) {
nlog_warn("write file failed: %s", tag->address);
ret = NEU_ERR_FILE_WRITE_FAILURE;
fclose(fp);
goto dvalue_result;
}
fclose(fp);
neu_datatag_string_ltoh(value.str, strlen(value.str));
dvalue_result:
fclose(fp);
plugin->common.adapter_callbacks->driver.write_response(
plugin->common.adapter, req, ret);
+19 -6
View File
@@ -91,12 +91,14 @@ static int driver_init(neu_plugin_t *plugin)
plugin->events = neu_event_new();
plugin->stack = modbus_stack_create((void *) plugin, modbus_send_msg,
modbus_value_handle, modbus_write_resp);
plog_notice(plugin, "%s init success", plugin->common.name);
return 0;
}
static int driver_uninit(neu_plugin_t *plugin)
{
plog_notice(plugin, "%s uninit start", plugin->common.name);
if (plugin->conn != NULL) {
neu_conn_destory(plugin->conn);
}
@@ -107,7 +109,7 @@ static int driver_uninit(neu_plugin_t *plugin)
neu_event_close(plugin->events);
plog_info(plugin, "node: modbus uninit ok");
plog_notice(plugin, "%s uninit success", plugin->common.name);
return 0;
}
@@ -115,12 +117,14 @@ static int driver_uninit(neu_plugin_t *plugin)
static int driver_start(neu_plugin_t *plugin)
{
neu_conn_start(plugin->conn);
plog_notice(plugin, "%s start success", plugin->common.name);
return 0;
}
static int driver_stop(neu_plugin_t *plugin)
{
neu_conn_stop(plugin->conn);
plog_notice(plugin, "%s stop success", plugin->common.name);
return 0;
}
@@ -137,8 +141,8 @@ static int driver_config(neu_plugin_t *plugin, const char *config)
neu_parse_param((char *) config, &err_param, 3, &port, &host, &timeout);
if (ret != 0) {
plog_warn(plugin, "config: %s, decode error: %s", (char *) config,
err_param);
plog_error(plugin, "config: %s, decode error: %s", (char *) config,
err_param);
free(err_param);
free(host.v.val_str);
return -1;
@@ -150,8 +154,9 @@ static int driver_config(neu_plugin_t *plugin, const char *config)
param.params.tcp_client.port = port.v.val_int;
param.params.tcp_client.timeout = timeout.v.val_int;
plog_info(plugin, "config: host: %s, port: %" PRId64 ", timeout: %" PRId64,
host.v.val_str, port.v.val_int, timeout.v.val_int);
plog_notice(plugin,
"config: host: %s, port: %" PRId64 ", timeout: %" PRId64,
host.v.val_str, port.v.val_int, timeout.v.val_int);
plugin->common.link_state = NEU_NODE_LINK_STATE_DISCONNECTED;
if (plugin->conn != NULL) {
@@ -181,13 +186,21 @@ static int driver_validate_tag(neu_plugin_t *plugin, neu_datatag_t *tag)
int ret = modbus_tag_to_point(tag, &point);
if (ret == 0) {
plog_debug(
plog_notice(
plugin,
"validate tag success, name: %s, address: %s, type: %d, slave id: "
"%d, start address: %d, n register: %d, area: %s",
tag->name, tag->address, tag->type, point.slave_id,
point.start_address, point.n_register,
modbus_area_to_str(point.area));
} else {
plog_error(
plugin,
"validate tag error, name: %s, address: %s, type: %d, slave id: "
"%d, start address: %d, n register: %d, area: %s",
tag->name, tag->address, tag->type, point.slave_id,
point.start_address, point.n_register,
modbus_area_to_str(point.area));
}
return ret;
+31 -5
View File
@@ -109,8 +109,8 @@ static int response(nng_aio *aio, char *content, enum nng_http_status status)
nng_http_res_set_status(res, status);
nng_http_req *nng_req = nng_aio_get_input(aio, 0);
nlog_notice("%s %s [%d]", nng_http_req_get_method(nng_req),
nng_http_req_get_uri(nng_req), status);
nlog_info("%s %s [%d]", nng_http_req_get_method(nng_req),
nng_http_req_get_uri(nng_req), status);
nng_aio_set_output(aio, 0, res);
nng_aio_finish(aio, 0);
@@ -159,7 +159,14 @@ static inline void gen_global_metrics(const neu_metrics_t *metrics,
static inline void
gen_single_node_metrics(const neu_node_metrics_t *node_metrics, FILE *stream)
{
fprintf(stream,
"# HELP node_type Driver(1) or APP(2)\n"
"# TYPE node_type gauge\n"
"node_type{node=\"%s\"} %d\n",
node_metrics->name, node_metrics->type);
neu_metric_entry_t *e = NULL;
HASH_LOOP(hh, node_metrics->entries, e)
{
fprintf(stream,
@@ -208,9 +215,28 @@ static void gen_all_node_metrics(const neu_metrics_t *metrics, int type_filter,
neu_group_metrics_t *g = NULL;
neu_node_metrics_t * n = NULL;
bool commented = false;
HASH_LOOP(hh, metrics->node_metrics, n)
{
if (!(type_filter & n->type)) {
continue;
}
if (!commented) {
commented = true;
fprintf(stream,
"# HELP node_type Driver(1) or APP(2)\n"
"# TYPE node_type gauge\n");
}
fprintf(stream, "node_type{node=\"%s\"} %d\n", n->name, n->type);
}
n = NULL;
HASH_LOOP(hh, metrics->registered_metrics, r)
{
bool commented = false;
commented = false;
HASH_LOOP(hh, metrics->node_metrics, n)
{
if (!(type_filter & n->type)) {
@@ -282,8 +308,8 @@ void handle_get_metric(nng_aio *aio)
const char *cat_param = neu_http_get_param(aio, "category", &cat_param_len);
if (NULL != cat_param &&
!parse_metrics_catgory(cat_param, cat_param_len, &cat)) {
plog_info(plugin, "invalid metrics category: %.*s", (int) cat_param_len,
cat_param);
plog_error(plugin, "invalid metrics category: %.*s",
(int) cat_param_len, cat_param);
status = NNG_HTTP_STATUS_BAD_REQUEST;
goto end;
}
+17 -16
View File
@@ -37,15 +37,15 @@ static void connect_cb(void *data)
{
neu_plugin_t *plugin = data;
plugin->common.link_state = NEU_NODE_LINK_STATE_CONNECTED;
plog_info(plugin, "plugin `%s` connected", neu_plugin_module.module_name);
plog_notice(plugin, "plugin `%s` connected", neu_plugin_module.module_name);
}
static void disconnect_cb(void *data)
{
neu_plugin_t *plugin = data;
plugin->common.link_state = NEU_NODE_LINK_STATE_DISCONNECTED;
plog_info(plugin, "plugin `%s` disconnected",
neu_plugin_module.module_name);
plog_notice(plugin, "plugin `%s` disconnected",
neu_plugin_module.module_name);
}
static nng_http_server *server_init()
@@ -54,7 +54,7 @@ static nng_http_server *server_init()
nng_http_server *server = NULL;
const char * host_port = "http://0.0.0.0:7000";
nlog_info("monitor bind url: %s", host_port);
nlog_notice("monitor bind url: %s", host_port);
int ret = nng_url_parse(&url, host_port);
if (0 != ret) {
@@ -179,7 +179,7 @@ static inline void stop_heartbeart_timer(neu_plugin_t *plugin)
if (plugin->heartbeat_timer) {
neu_event_del_timer(plugin->events, plugin->heartbeat_timer);
plugin->heartbeat_timer = NULL;
plog_info(plugin, "heartbeat timer stopped");
plog_notice(plugin, "heartbeat timer stopped");
}
}
@@ -219,7 +219,7 @@ end:
}
plugin->heartbeat_timer = timer;
plog_info(plugin, "start_hearbeat_timer interval: %" PRIu64, interval);
plog_notice(plugin, "start_hearbeat_timer interval: %" PRIu64, interval);
return 0;
}
@@ -286,8 +286,8 @@ static int monitor_plugin_close(neu_plugin_t *plugin)
nng_http_server_stop(plugin->api_server);
nng_http_server_release(plugin->api_server);
pthread_mutex_destroy(&plugin->mutex);
plog_info(plugin, "Success to free plugin: %s",
neu_plugin_module.module_name);
plog_notice(plugin, "Success to free plugin: %s",
neu_plugin_module.module_name);
free(plugin);
return rv;
@@ -298,7 +298,7 @@ static int monitor_plugin_init(neu_plugin_t *plugin)
int rv = 0;
(void) plugin;
plog_info(plugin, "Initialize plugin: %s", neu_plugin_module.module_name);
plog_notice(plugin, "Initialize plugin: %s", neu_plugin_module.module_name);
return rv;
}
@@ -308,7 +308,8 @@ static int monitor_plugin_uninit(neu_plugin_t *plugin)
uninit_timers_and_mqtt(plugin);
plog_info(plugin, "Uninitialize plugin: %s", neu_plugin_module.module_name);
plog_notice(plugin, "Uninitialize plugin: %s",
neu_plugin_module.module_name);
return rv;
}
@@ -372,7 +373,7 @@ static int monitor_plugin_config(neu_plugin_t *plugin, const char *setting)
memmove(plugin->config, &config, sizeof(config));
// `config` moved, do not call monitor_config_fini
plog_info(plugin, "config plugin `%s` success", plugin_name);
plog_notice(plugin, "config plugin `%s` success", plugin_name);
return 0;
error:
@@ -423,7 +424,7 @@ static int monitor_plugin_start(neu_plugin_t *plugin)
const char *plugin_name = neu_plugin_module.module_name;
if (NULL == plugin->mqtt_client) {
plog_info(plugin, "mqtt client is NULL");
plog_notice(plugin, "mqtt client is NULL");
goto end;
}
@@ -443,7 +444,7 @@ static int monitor_plugin_start(neu_plugin_t *plugin)
end:
if (0 == rv) {
plugin->started = true;
plog_info(plugin, "start plugin `%s` success", plugin_name);
plog_notice(plugin, "start plugin `%s` success", plugin_name);
} else {
plog_error(plugin, "start plugin `%s` failed, error %d", plugin_name,
rv);
@@ -456,13 +457,13 @@ static int monitor_plugin_stop(neu_plugin_t *plugin)
{
if (plugin->mqtt_client) {
neu_mqtt_client_close(plugin->mqtt_client);
plog_info(plugin, "mqtt client closed");
plog_notice(plugin, "mqtt client closed");
}
stop_heartbeart_timer(plugin);
plugin->started = false;
plog_info(plugin, "stop plugin `%s` success",
neu_plugin_module.module_name);
plog_notice(plugin, "stop plugin `%s` success",
neu_plugin_module.module_name);
return 0;
}
+40 -34
View File
@@ -75,12 +75,12 @@ static inline int parse_ssl_params(neu_plugin_t *plugin, const char *setting,
// ssl, optional
int ret = neu_parse_param(setting, NULL, 1, ssl);
if (0 != ret) {
plog_info(plugin, "setting no ssl");
plog_notice(plugin, "setting no ssl");
return 0;
}
if (false == ssl->v.val_bool) {
plog_info(plugin, "setting ssl disabled");
plog_notice(plugin, "setting ssl disabled");
return 0;
}
@@ -93,7 +93,7 @@ static inline int parse_ssl_params(neu_plugin_t *plugin, const char *setting,
// cert, optional
ret = neu_parse_param(setting, NULL, 1, cert);
if (0 != ret) {
plog_info(plugin, "setting no cert");
plog_notice(plugin, "setting no cert");
return 0;
}
@@ -110,7 +110,7 @@ static inline int parse_ssl_params(neu_plugin_t *plugin, const char *setting,
// keypass, optional
ret = neu_parse_param(setting, NULL, 1, keypass);
if (0 != ret) {
plog_info(plugin, "setting no keypass");
plog_notice(plugin, "setting no keypass");
} else if (0 == strlen(keypass->v.val_str)) {
plog_error(plugin, "setting invalid keypass");
return -1;
@@ -280,13 +280,13 @@ int monitor_config_parse(neu_plugin_t *plugin, const char *setting,
// username, optional
ret = neu_parse_param(setting, NULL, 1, &username);
if (0 != ret) {
plog_info(plugin, "setting no username");
plog_notice(plugin, "setting no username");
}
// password, optional
ret = neu_parse_param(setting, NULL, 1, &password);
if (0 != ret) {
plog_info(plugin, "setting no password");
plog_notice(plugin, "setting no password");
}
ret = parse_ssl_params(plugin, setting, &ssl, &ca, &cert, &key, &keypass);
@@ -313,48 +313,54 @@ int monitor_config_parse(neu_plugin_t *plugin, const char *setting,
config->key = key.v.val_str;
config->keypass = keypass.v.val_str;
plog_info(plugin, "config client-id : %s", config->client_id);
plog_info(plugin, "config event-topic-prefix: %s",
config->event_topic_prefix);
plog_info(plugin, "config heartbeat-interval: %" PRIu64,
config->heartbeat_interval);
plog_info(plugin, "config heartbeat-topic : %s", config->heartbeat_topic);
plog_info(plugin, "config host : %s", config->host);
plog_info(plugin, "config port : %" PRIu16, config->port);
plog_notice(plugin, "config client-id : %s", config->client_id);
plog_notice(plugin, "config event-topic-prefix: %s",
config->event_topic_prefix);
plog_notice(plugin, "config heartbeat-interval: %" PRIu64,
config->heartbeat_interval);
plog_notice(plugin, "config heartbeat-topic : %s",
config->heartbeat_topic);
plog_notice(plugin, "config host : %s", config->host);
plog_notice(plugin, "config port : %" PRIu16, config->port);
if (config->username) {
plog_info(plugin, "config username : %s", config->username);
plog_notice(plugin, "config username : %s", config->username);
}
if (config->password) {
plog_info(plugin, "config password : %s",
0 == strlen(config->password) ? "" : placeholder);
plog_notice(plugin, "config password : %s",
0 == strlen(config->password) ? "" : placeholder);
}
if (config->ca) {
plog_info(plugin, "config ca : %s", placeholder);
plog_notice(plugin, "config ca : %s", placeholder);
}
if (config->cert) {
plog_info(plugin, "config cert : %s", placeholder);
plog_notice(plugin, "config cert : %s", placeholder);
}
if (config->key) {
plog_info(plugin, "config key : %s", placeholder);
plog_notice(plugin, "config key : %s", placeholder);
}
if (config->keypass) {
plog_info(plugin, "config keypass : %s", placeholder);
plog_notice(plugin, "config keypass : %s", placeholder);
}
plog_info(plugin, "node add event topic : %s", config->node_add_topic);
plog_info(plugin, "node del event topic : %s", config->node_del_topic);
plog_info(plugin, "node ctl event topic : %s", config->node_ctl_topic);
plog_info(plugin, "node setting event topic : %s",
config->node_setting_topic);
plog_info(plugin, "group add topic : %s", config->group_add_topic);
plog_info(plugin, "group del topic : %s", config->group_del_topic);
plog_info(plugin, "group update topic : %s",
config->group_update_topic);
plog_info(plugin, "tag add topic : %s", config->tag_add_topic);
plog_info(plugin, "tag del topic : %s", config->tag_del_topic);
plog_info(plugin, "tag update topic : %s",
config->tag_update_topic);
plog_notice(plugin, "node add event topic : %s",
config->node_add_topic);
plog_notice(plugin, "node del event topic : %s",
config->node_del_topic);
plog_notice(plugin, "node ctl event topic : %s",
config->node_ctl_topic);
plog_notice(plugin, "node setting event topic : %s",
config->node_setting_topic);
plog_notice(plugin, "group add topic : %s",
config->group_add_topic);
plog_notice(plugin, "group del topic : %s",
config->group_del_topic);
plog_notice(plugin, "group update topic : %s",
config->group_update_topic);
plog_notice(plugin, "tag add topic : %s", config->tag_add_topic);
plog_notice(plugin, "tag del topic : %s", config->tag_del_topic);
plog_notice(plugin, "tag update topic : %s",
config->tag_update_topic);
return 0;
+25 -1
View File
@@ -57,6 +57,30 @@
]
}
},
"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/${node-name}/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/${node-name}/write/resp",
"valid": {
"length": 255
}
},
"offline-cache": {
"name": "Offline Data Caching",
"name_zh": "离线缓存",
@@ -218,4 +242,4 @@
"length": 256
}
}
}
}
+78 -39
View File
@@ -17,6 +17,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
#include "utils/asprintf.h"
#include "json/json.h"
#include "json/neu_json_param.h"
@@ -71,12 +72,12 @@ static inline int parse_ssl_params(neu_plugin_t *plugin, const char *setting,
// ssl, optional
int ret = neu_parse_param(setting, NULL, 1, ssl);
if (0 != ret) {
plog_info(plugin, "setting no ssl");
plog_notice(plugin, "setting no ssl");
return 0;
}
if (false == ssl->v.val_bool) {
plog_info(plugin, "setting ssl disabled");
plog_notice(plugin, "setting ssl disabled");
return 0;
}
@@ -89,7 +90,7 @@ static inline int parse_ssl_params(neu_plugin_t *plugin, const char *setting,
// cert, optional
ret = neu_parse_param(setting, NULL, 1, cert);
if (0 != ret) {
plog_info(plugin, "setting no cert");
plog_notice(plugin, "setting no cert");
return 0;
}
@@ -106,7 +107,7 @@ static inline int parse_ssl_params(neu_plugin_t *plugin, const char *setting,
// keypass, optional
ret = neu_parse_param(setting, NULL, 1, keypass);
if (0 != ret) {
plog_info(plugin, "setting no keypass");
plog_notice(plugin, "setting no keypass");
} else if (0 == strlen(keypass->v.val_str)) {
plog_error(plugin, "setting invalid keypass");
return -1;
@@ -127,7 +128,7 @@ static int parse_cache_params(neu_plugin_t *plugin, const char *setting,
// offline-cache flag, optional
ret = neu_parse_param(setting, NULL, 1, offline_cache);
if (0 != ret) {
plog_info(plugin, "setting no offline cache flag");
plog_notice(plugin, "setting no offline cache flag");
flag_present = false; // `offline-cache` not present in setting
}
@@ -203,6 +204,18 @@ int mqtt_config_parse(neu_plugin_t *plugin, const char *setting,
.attribute = NEU_JSON_ATTRIBUTE_OPTIONAL, // for backward compatibility
};
neu_json_elem_t format = { .name = "format", .t = NEU_JSON_INT };
neu_json_elem_t write_req_topic = {
.name = "write-req-topic",
.t = NEU_JSON_STR,
.v.val_str = NULL,
.attribute = NEU_JSON_ATTRIBUTE_OPTIONAL, // for backward compatibility
};
neu_json_elem_t write_resp_topic = {
.name = "write-resp-topic",
.t = NEU_JSON_STR,
.v.val_str = NULL,
.attribute = NEU_JSON_ATTRIBUTE_OPTIONAL, // for backward compatibility
};
neu_json_elem_t offline_cache = { .name = "offline-cache",
.t = NEU_JSON_BOOL };
neu_json_elem_t cache_mem_size = { .name = "cache-mem-size",
@@ -224,8 +237,8 @@ int mqtt_config_parse(neu_plugin_t *plugin, const char *setting,
return -1;
}
ret = neu_parse_param(setting, &err_param, 5, &client_id, &format, &qos,
&host, &port);
ret = neu_parse_param(setting, &err_param, 7, &client_id, &qos, &format,
&write_req_topic, &write_resp_topic, &host, &port);
if (0 != ret) {
plog_error(plugin, "parsing setting fail, key: `%s`", err_param);
goto error;
@@ -251,6 +264,22 @@ int mqtt_config_parse(neu_plugin_t *plugin, const char *setting,
goto error;
}
// write request topic
if (NULL == write_req_topic.v.val_str &&
0 > neu_asprintf(&write_req_topic.v.val_str, "/neuron/%s/write/req",
plugin->common.name)) {
plog_error(plugin, "setting write request topic error");
goto error;
}
// write response topic
if (NULL == write_resp_topic.v.val_str &&
0 > neu_asprintf(&write_resp_topic.v.val_str, "/neuron/%s/write/resp",
plugin->common.name)) {
plog_error(plugin, "setting write response topic error");
goto error;
}
// offline cache
ret = parse_cache_params(plugin, setting, &offline_cache, &cache_mem_size,
&cache_disk_size);
@@ -273,13 +302,13 @@ int mqtt_config_parse(neu_plugin_t *plugin, const char *setting,
// username, optional
ret = neu_parse_param(setting, NULL, 1, &username);
if (0 != ret) {
plog_info(plugin, "setting no username");
plog_notice(plugin, "setting no username");
}
// password, optional
ret = neu_parse_param(setting, NULL, 1, &password);
if (0 != ret) {
plog_info(plugin, "setting no password");
plog_notice(plugin, "setting no password");
}
ret = parse_ssl_params(plugin, setting, &ssl, &ca, &cert, &key, &keypass);
@@ -287,55 +316,63 @@ int mqtt_config_parse(neu_plugin_t *plugin, const char *setting,
goto error;
}
config->client_id = client_id.v.val_str;
config->qos = qos.v.val_int;
config->format = format.v.val_int;
config->cache = offline_cache.v.val_bool;
config->cache_mem_size = cache_mem_size.v.val_int * MB;
config->cache_disk_size = cache_disk_size.v.val_int * MB;
config->host = host.v.val_str;
config->port = port.v.val_int;
config->username = username.v.val_str;
config->password = password.v.val_str;
config->ca = ca.v.val_str;
config->cert = cert.v.val_str;
config->key = key.v.val_str;
config->keypass = keypass.v.val_str;
config->client_id = client_id.v.val_str;
config->qos = qos.v.val_int;
config->format = format.v.val_int;
config->write_req_topic = write_req_topic.v.val_str;
config->write_resp_topic = write_resp_topic.v.val_str;
config->cache = offline_cache.v.val_bool;
config->cache_mem_size = cache_mem_size.v.val_int * MB;
config->cache_disk_size = cache_disk_size.v.val_int * MB;
config->host = host.v.val_str;
config->port = port.v.val_int;
config->username = username.v.val_str;
config->password = password.v.val_str;
config->ca = ca.v.val_str;
config->cert = cert.v.val_str;
config->key = key.v.val_str;
config->keypass = keypass.v.val_str;
plog_info(plugin, "config client-id : %s", config->client_id);
plog_info(plugin, "config qos : %d", config->qos);
plog_info(plugin, "config format : %s",
mqtt_upload_format_str(config->format));
plog_info(plugin, "config cache : %zu", config->cache);
plog_info(plugin, "config cache-mem-size : %zu", config->cache_mem_size);
plog_info(plugin, "config cache-disk-size: %zu", config->cache_disk_size);
plog_info(plugin, "config host : %s", config->host);
plog_info(plugin, "config port : %" PRIu16, config->port);
plog_notice(plugin, "config client-id : %s", config->client_id);
plog_notice(plugin, "config qos : %d", config->qos);
plog_notice(plugin, "config format : %s",
mqtt_upload_format_str(config->format));
plog_notice(plugin, "config write-req-topic : %s", config->write_req_topic);
plog_notice(plugin, "config write-resp-topic: %s",
config->write_resp_topic);
plog_notice(plugin, "config cache : %zu", config->cache);
plog_notice(plugin, "config cache-mem-size : %zu", config->cache_mem_size);
plog_notice(plugin, "config cache-disk-size : %zu",
config->cache_disk_size);
plog_notice(plugin, "config host : %s", config->host);
plog_notice(plugin, "config port : %" PRIu16, config->port);
if (config->username) {
plog_info(plugin, "config username : %s", config->username);
plog_notice(plugin, "config username : %s", config->username);
}
if (config->password) {
plog_info(plugin, "config password : %s",
0 == strlen(config->password) ? "" : placeholder);
plog_notice(plugin, "config password : %s",
0 == strlen(config->password) ? "" : placeholder);
}
if (config->ca) {
plog_info(plugin, "config ca : %s", placeholder);
plog_notice(plugin, "config ca : %s", placeholder);
}
if (config->cert) {
plog_info(plugin, "config cert : %s", placeholder);
plog_notice(plugin, "config cert : %s", placeholder);
}
if (config->key) {
plog_info(plugin, "config key : %s", placeholder);
plog_notice(plugin, "config key : %s", placeholder);
}
if (config->keypass) {
plog_info(plugin, "config keypass : %s", placeholder);
plog_notice(plugin, "config keypass : %s", placeholder);
}
return 0;
error:
free(err_param);
free(write_req_topic.v.val_str);
free(write_resp_topic.v.val_str);
free(host.v.val_str);
free(username.v.val_str);
free(password.v.val_str);
@@ -349,6 +386,8 @@ error:
void mqtt_config_fini(mqtt_config_t *config)
{
free(config->client_id);
free(config->write_req_topic);
free(config->write_resp_topic);
free(config->host);
free(config->username);
free(config->password);
+16 -14
View File
@@ -48,20 +48,22 @@ static inline const char *mqtt_upload_format_str(mqtt_upload_format_e f)
}
typedef struct {
char * client_id; // client id
mqtt_upload_format_e format; // upload format
neu_mqtt_qos_e qos; // message QoS
size_t cache; // cache enable flag
size_t cache_mem_size; // cache memory size in bytes
size_t cache_disk_size; // cache disk size in bytes
char * host; // broker host
uint16_t port; // broker port
char * username; // user name
char * password; // user password
char * ca; // CA
char * cert; // client cert
char * key; // client key
char * keypass; // client key password
char * client_id; // client id
neu_mqtt_qos_e qos; // message QoS
mqtt_upload_format_e format; // upload format
char * write_req_topic; // write request topic
char * write_resp_topic; // write response topic
size_t cache; // cache enable flag
size_t cache_mem_size; // cache memory size in bytes
size_t cache_disk_size; // cache disk size in bytes
char * host; // broker host
uint16_t port; // broker port
char * username; // user name
char * password; // user password
char * ca; // CA
char * cert; // client cert
char * key; // client key
char * keypass; // client key password
} mqtt_config_t;
int mqtt_config_parse(neu_plugin_t *plugin, const char *setting,
+9 -9
View File
@@ -194,8 +194,8 @@ static char *generate_write_resp_json(neu_plugin_t * plugin,
static inline int send_read_req(neu_plugin_t *plugin, neu_json_mqtt_t *mqtt,
neu_json_read_req_t *req)
{
plog_info(plugin, "read uuid:%s, group:%s, node:%s", mqtt->uuid, req->group,
req->node);
plog_notice(plugin, "read uuid:%s, group:%s, node:%s", mqtt->uuid,
req->group, req->node);
neu_reqresp_head_t header = { 0 };
header.ctx = mqtt;
@@ -214,8 +214,8 @@ static inline int send_read_req(neu_plugin_t *plugin, neu_json_mqtt_t *mqtt,
static int send_write_req(neu_plugin_t *plugin, neu_json_mqtt_t *mqtt,
neu_json_write_req_t *req)
{
plog_info(plugin, "write uuid:%s, group:%s, node:%s", mqtt->uuid,
req->group, req->node);
plog_notice(plugin, "write uuid:%s, group:%s, node:%s", mqtt->uuid,
req->group, req->node);
neu_reqresp_head_t header = { 0 };
neu_req_write_tag_t cmd = { 0 };
@@ -373,7 +373,7 @@ int handle_write_response(neu_plugin_t *plugin, neu_json_mqtt_t *mqtt_json,
goto end;
}
char * topic = plugin->write_resp_topic;
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));
json_str = NULL;
@@ -538,8 +538,8 @@ int handle_subscribe_group(neu_plugin_t *plugin, neu_req_subscribe_t *sub_info)
goto end;
}
plog_info(plugin, "route driver:%s group:%s to topic:%s", sub_info->driver,
sub_info->group, topic.v.val_str);
plog_notice(plugin, "route driver:%s group:%s to topic:%s",
sub_info->driver, sub_info->group, topic.v.val_str);
end:
free(sub_info->params);
@@ -550,7 +550,7 @@ int handle_unsubscribe_group(neu_plugin_t * plugin,
neu_req_unsubscribe_t *unsub_info)
{
route_tbl_del(&plugin->route_tbl, unsub_info->driver, unsub_info->group);
plog_info(plugin, "del route driver:%s group:%s", unsub_info->driver,
unsub_info->group);
plog_notice(plugin, "del route driver:%s group:%s", unsub_info->driver,
unsub_info->group);
return 0;
}
+87 -92
View File
@@ -18,6 +18,7 @@
**/
#include "utils/asprintf.h"
#include "utils/time.h"
#include "mqtt_config.h"
#include "mqtt_handle.h"
@@ -29,15 +30,15 @@ static void connect_cb(void *data)
{
neu_plugin_t *plugin = data;
plugin->common.link_state = NEU_NODE_LINK_STATE_CONNECTED;
plog_info(plugin, "plugin `%s` connected", neu_plugin_module.module_name);
plog_notice(plugin, "plugin `%s` connected", neu_plugin_module.module_name);
}
static void disconnect_cb(void *data)
{
neu_plugin_t *plugin = data;
plugin->common.link_state = NEU_NODE_LINK_STATE_DISCONNECTED;
plog_info(plugin, "plugin `%s` disconnected",
neu_plugin_module.module_name);
plog_notice(plugin, "plugin `%s` disconnected",
neu_plugin_module.module_name);
}
static neu_plugin_t *mqtt_plugin_open(void)
@@ -50,7 +51,7 @@ static neu_plugin_t *mqtt_plugin_open(void)
static int mqtt_plugin_close(neu_plugin_t *plugin)
{
const char *name = neu_plugin_module.module_name;
plog_info(plugin, "success to free plugin:%s", name);
plog_notice(plugin, "success to free plugin:%s", name);
free(plugin);
return NEU_ERR_SUCCESS;
@@ -58,8 +59,8 @@ static int mqtt_plugin_close(neu_plugin_t *plugin)
static int mqtt_plugin_init(neu_plugin_t *plugin)
{
plog_info(plugin, "initialize plugin `%s` success",
neu_plugin_module.module_name);
plog_notice(plugin, "initialize plugin `%s` success",
neu_plugin_module.module_name);
neu_adapter_register_metric_cb_t register_metric =
plugin->common.adapter_callbacks->register_metric;
register_metric(plugin->common.adapter, NEU_METRIC_CACHED_MSGS_NUM,
@@ -81,15 +82,11 @@ static int mqtt_plugin_uninit(neu_plugin_t *plugin)
plugin->read_req_topic = NULL;
free(plugin->read_resp_topic);
plugin->read_resp_topic = NULL;
free(plugin->write_req_topic);
plugin->write_req_topic = NULL;
free(plugin->write_resp_topic);
plugin->write_resp_topic = NULL;
route_tbl_free(plugin->route_tbl);
plog_info(plugin, "uninitialize plugin `%s` success",
neu_plugin_module.module_name);
plog_notice(plugin, "uninitialize plugin `%s` success",
neu_plugin_module.module_name);
return NEU_ERR_SUCCESS;
}
@@ -159,6 +156,65 @@ static int config_mqtt_client(neu_plugin_t *plugin, neu_mqtt_client_t *client,
return rv;
}
static int create_topic(neu_plugin_t *plugin)
{
if (plugin->read_req_topic) {
// topics already created
return 0;
}
neu_asprintf(&plugin->read_req_topic, "/neuron/%s/read/req",
plugin->common.name);
if (NULL == plugin->read_req_topic) {
return -1;
}
neu_asprintf(&plugin->read_resp_topic, "/neuron/%s/read/resp",
plugin->common.name);
if (NULL == plugin->read_resp_topic) {
free(plugin->read_req_topic);
plugin->read_req_topic = NULL;
return -1;
}
return 0;
}
static int subscribe(neu_plugin_t *plugin, const mqtt_config_t *config)
{
if (0 != create_topic(plugin)) {
plog_error(plugin, "create topics fail");
return NEU_ERR_EINTERNAL;
}
if (0 !=
neu_mqtt_client_subscribe(plugin->client, config->qos,
plugin->read_req_topic, plugin,
handle_read_req)) {
plog_error(plugin, "subscribe [%s] fail", plugin->read_req_topic);
return NEU_ERR_MQTT_SUBSCRIBE_FAILURE;
}
if (0 !=
neu_mqtt_client_subscribe(plugin->client, config->qos,
config->write_req_topic, plugin,
handle_write_req)) {
plog_error(plugin, "subscribe [%s] fail",
plugin->config.write_req_topic);
return NEU_ERR_MQTT_SUBSCRIBE_FAILURE;
}
return 0;
}
static int unsubscribe(neu_plugin_t *plugin, const mqtt_config_t *config)
{
neu_mqtt_client_unsubscribe(plugin->client, plugin->read_req_topic);
neu_mqtt_client_unsubscribe(plugin->client, config->write_req_topic);
neu_msleep(100); // wait for message completion
return 0;
}
static int mqtt_plugin_config(neu_plugin_t *plugin, const char *setting)
{
int rv = 0;
@@ -181,7 +237,8 @@ static int mqtt_plugin_config(neu_plugin_t *plugin, const char *setting)
}
} else if (neu_mqtt_client_is_open(plugin->client)) {
started = true;
rv = neu_mqtt_client_close(plugin->client);
unsubscribe(plugin, &plugin->config);
rv = neu_mqtt_client_close(plugin->client);
if (0 != rv) {
plog_error(plugin, "neu_mqtt_client_close fail");
rv = NEU_ERR_EINTERNAL;
@@ -195,10 +252,15 @@ static int mqtt_plugin_config(neu_plugin_t *plugin, const char *setting)
goto error;
}
if (started && 0 != neu_mqtt_client_open(plugin->client)) {
plog_error(plugin, "neu_mqtt_client_open fail");
rv = NEU_ERR_MQTT_CONNECT_FAILURE;
goto error;
if (started) {
if (0 != neu_mqtt_client_open(plugin->client)) {
plog_error(plugin, "neu_mqtt_client_open fail");
rv = NEU_ERR_MQTT_CONNECT_FAILURE;
goto error;
}
if (0 != (rv = subscribe(plugin, &config))) {
goto error;
}
}
if (plugin->config.host) {
@@ -207,61 +269,15 @@ static int mqtt_plugin_config(neu_plugin_t *plugin, const char *setting)
}
memmove(&plugin->config, &config, sizeof(config));
plog_info(plugin, "config plugin `%s` success", plugin_name);
plog_notice(plugin, "config plugin `%s` success", plugin_name);
return 0;
error:
plog_info(plugin, "config plugin `%s` fail", plugin_name);
plog_error(plugin, "config plugin `%s` fail", plugin_name);
mqtt_config_fini(&config);
return rv;
}
static int create_topic(neu_plugin_t *plugin)
{
if (plugin->read_req_topic) {
// topics already created
return 0;
}
neu_asprintf(&plugin->read_req_topic, "/neuron/%s/read/req",
plugin->common.name);
if (NULL == plugin->read_req_topic) {
return -1;
}
neu_asprintf(&plugin->read_resp_topic, "/neuron/%s/read/resp",
plugin->common.name);
if (NULL == plugin->read_resp_topic) {
free(plugin->read_req_topic);
plugin->read_req_topic = NULL;
return -1;
}
neu_asprintf(&plugin->write_req_topic, "/neuron/%s/write/req",
plugin->common.name);
if (NULL == plugin->write_req_topic) {
free(plugin->read_req_topic);
plugin->read_req_topic = NULL;
free(plugin->read_resp_topic);
plugin->read_resp_topic = NULL;
return -1;
}
neu_asprintf(&plugin->write_resp_topic, "/neuron/%s/write/resp",
plugin->common.name);
if (NULL == plugin->write_resp_topic) {
free(plugin->read_req_topic);
plugin->read_req_topic = NULL;
free(plugin->read_resp_topic);
plugin->read_resp_topic = NULL;
free(plugin->write_req_topic);
plugin->write_req_topic = NULL;
return -1;
}
return 0;
}
static int mqtt_plugin_start(neu_plugin_t *plugin)
{
int rv = 0;
@@ -279,33 +295,11 @@ static int mqtt_plugin_start(neu_plugin_t *plugin)
goto end;
}
if (0 != create_topic(plugin)) {
plog_error(plugin, "create topics fail");
rv = NEU_ERR_EINTERNAL;
goto end;
}
if (0 !=
neu_mqtt_client_subscribe(plugin->client, plugin->config.qos,
plugin->read_req_topic, plugin,
handle_read_req)) {
plog_error(plugin, "subscribe [%s] fail", plugin->read_req_topic);
rv = NEU_ERR_MQTT_SUBSCRIBE_FAILURE;
goto end;
}
if (0 !=
neu_mqtt_client_subscribe(plugin->client, plugin->config.qos,
plugin->write_req_topic, plugin,
handle_write_req)) {
plog_error(plugin, "subscribe [%s] fail", plugin->write_req_topic);
rv = NEU_ERR_MQTT_SUBSCRIBE_FAILURE;
goto end;
}
rv = subscribe(plugin, &plugin->config);
end:
if (0 == rv) {
plog_info(plugin, "start plugin `%s` success", plugin_name);
plog_notice(plugin, "start plugin `%s` success", plugin_name);
} else {
plog_error(plugin, "start plugin `%s` failed, error %d", plugin_name,
rv);
@@ -317,12 +311,13 @@ end:
static int mqtt_plugin_stop(neu_plugin_t *plugin)
{
if (plugin->client) {
unsubscribe(plugin, &plugin->config);
neu_mqtt_client_close(plugin->client);
plog_info(plugin, "mqtt client closed");
plog_notice(plugin, "mqtt client closed");
}
plog_info(plugin, "stop plugin `%s` success",
neu_plugin_module.module_name);
plog_notice(plugin, "stop plugin `%s` success",
neu_plugin_module.module_name);
return NEU_ERR_SUCCESS;
}
-2
View File
@@ -49,8 +49,6 @@ struct neu_plugin {
int64_t cache_metric_update_ts;
char * read_req_topic;
char * read_resp_topic;
char * write_req_topic;
char * write_resp_topic;
route_entry_t * route_tbl;
};
+2 -1
View File
@@ -63,7 +63,8 @@ void handle_logs_files(nng_aio *aio)
rv = system("rm -rf /tmp/neuron_debug.tar.gz");
nlog_warn("remove old neuron_debug.tar.gz, rv: %d", rv);
/* tar the neuron directory */
rv = system("tar -zcvf /tmp/neuron_debug.tar.gz ../neuron");
rv = system("tar -zcvf /tmp/neuron_debug.tar.gz "
"--exclude='persistence/neuron.lic' ../neuron");
if (rv == -1) {
nlog_error("failed to create neuron_debug.tar.gz, rv: %d", rv);
NEU_JSON_RESPONSE_ERROR(NEU_ERR_COMMAND_EXECUTION_FAILED, {
+10 -2
View File
@@ -54,12 +54,20 @@ void handle_login(nng_aio *aio)
aio, neu_json_login_req_t, neu_json_decode_login_req, {
neu_json_login_resp_t login_resp = { 0 };
neu_user_t * user = neu_load_user(req->name);
int pass_len = strlen(req->pass);
if (NULL == user) {
nlog_warn("could not find user `%s`", req->name);
nlog_error("could not find user `%s`", req->name);
NEU_JSON_RESPONSE_ERROR(NEU_ERR_INVALID_USER_OR_PASSWORD, {
neu_http_response(aio, error_code.error, result_error);
});
} else if (pass_len < NEU_USER_PASSWORD_MIN_LEN ||
pass_len > NEU_USER_PASSWORD_MAX_LEN) {
nlog_error("user `%s` password too short or too long",
req->name);
NEU_JSON_RESPONSE_ERROR(NEU_ERR_INVALID_PASSWORD_LEN, {
neu_http_response(aio, error_code.error, result_error);
});
} else if (neu_user_check_password(user, req->pass)) {
char *token = NULL;
@@ -81,7 +89,7 @@ void handle_login(nng_aio *aio)
jwt_free_str(token);
free(result);
} else {
nlog_warn("user `%s` password check fail", req->name);
nlog_error("user `%s` password check fail", req->name);
NEU_JSON_RESPONSE_ERROR(NEU_ERR_INVALID_USER_OR_PASSWORD, {
neu_http_response(aio, error_code.error, result_error);
});
+6 -8
View File
@@ -55,7 +55,7 @@ static nng_http_server *server_init()
nng_http_server *server;
snprintf(host_port, sizeof(host_port), "http://0.0.0.0:7000");
nlog_info("bind url: %s", host_port);
nlog_notice("bind url: %s", host_port);
int ret = nng_url_parse(&url, host_port);
if (ret != 0) {
@@ -105,7 +105,7 @@ static neu_plugin_t *dashb_plugin_open(void)
goto server_init_fail;
}
nlog_info("Success to create plugin: %s", neu_plugin_module.module_name);
nlog_notice("Success to create plugin: %s", neu_plugin_module.module_name);
return plugin;
server_init_fail:
@@ -121,13 +121,11 @@ static int dashb_plugin_close(neu_plugin_t *plugin)
{
int rv = 0;
nlog_info("Success to before free plugin: %s",
neu_plugin_module.module_name);
nng_http_server_stop(plugin->server);
nng_http_server_release(plugin->server);
free(plugin);
nlog_info("Success to free plugin: %s", neu_plugin_module.module_name);
nlog_notice("Success to free plugin: %s", neu_plugin_module.module_name);
return rv;
}
@@ -139,7 +137,7 @@ static int dashb_plugin_init(neu_plugin_t *plugin)
rv = neu_jwt_init(g_config_dir);
nlog_info("Initialize plugin: %s", neu_plugin_module.module_name);
nlog_notice("Initialize plugin: %s", neu_plugin_module.module_name);
return rv;
}
@@ -149,7 +147,7 @@ static int dashb_plugin_uninit(neu_plugin_t *plugin)
(void) plugin;
nlog_info("Uninitialize plugin: %s", neu_plugin_module.module_name);
nlog_notice("Uninitialize plugin: %s", neu_plugin_module.module_name);
return rv;
}
@@ -160,7 +158,7 @@ static int dashb_plugin_config(neu_plugin_t *plugin, const char *configs)
(void) plugin;
(void) configs;
nlog_info("config plugin: %s", neu_plugin_module.module_name);
nlog_notice("config plugin: %s", neu_plugin_module.module_name);
return rv;
}
+18 -7
View File
@@ -58,7 +58,6 @@ void handle_write(nng_aio *aio)
NEU_PROCESS_HTTP_REQUEST_VALIDATE_JWT(
aio, neu_json_write_req_t, neu_json_decode_write_req, {
int ret = 0;
neu_reqresp_head_t header = { 0 };
neu_req_write_tag_t cmd = { 0 };
@@ -75,8 +74,13 @@ void handle_write(nng_aio *aio)
cmd.value.value.u64 = req->value.val_int;
break;
case NEU_JSON_STR:
cmd.value.type = NEU_TYPE_STRING;
strcpy(cmd.value.value.str, req->value.val_str);
if (strlen(req->value.val_str) >= NEU_VALUE_SIZE) {
cmd.value.type = NEU_TYPE_ERROR;
cmd.value.value.i32 = NEU_ERR_STRING_TOO_LONG;
} else {
cmd.value.type = NEU_TYPE_STRING;
strcpy(cmd.value.value.str, req->value.val_str);
}
break;
case NEU_JSON_DOUBLE:
cmd.value.type = NEU_TYPE_DOUBLE;
@@ -91,11 +95,18 @@ void handle_write(nng_aio *aio)
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 (cmd.value.type == NEU_TYPE_ERROR) {
NEU_JSON_RESPONSE_ERROR(NEU_ERR_STRING_TOO_LONG, {
neu_http_response(aio, NEU_ERR_STRING_TOO_LONG,
result_error);
});
} else {
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);
});
}
}
})
}
+11 -10
View File
@@ -124,8 +124,8 @@ neu_adapter_t *neu_adapter_create(neu_adapter_info_t *info)
rv = nng_pair1_open(&adapter->sock);
assert(rv == 0);
nng_socket_set_int(adapter->sock, NNG_OPT_RECVBUF, 128);
nng_socket_set_int(adapter->sock, NNG_OPT_SENDBUF, 128);
nng_socket_set_int(adapter->sock, NNG_OPT_RECVBUF, 8192);
nng_socket_set_int(adapter->sock, NNG_OPT_SENDBUF, 8192);
nng_socket_set_ms(adapter->sock, NNG_OPT_SENDTIMEO, 1000);
nng_socket_get_int(adapter->sock, NNG_OPT_RECVFD, &adapter->recv_fd);
@@ -181,13 +181,13 @@ neu_adapter_t *neu_adapter_create(neu_adapter_info_t *info)
timer_level.usr_data = (void *) adapter;
adapter->timer_lev = neu_event_add_timer(adapter->events, timer_level);
nlog_info("Success to create adapter: %s", adapter->name);
nlog_notice("Success to create adapter: %s", adapter->name);
adapter_storage_state(adapter->name, adapter->state);
return adapter;
}
void neu_adapter_init(neu_adapter_t *adapter, bool auto_start)
void neu_adapter_init(neu_adapter_t *adapter, neu_node_running_state_e state)
{
neu_reqresp_head_t header = { .type = NEU_REQ_NODE_INIT };
neu_req_node_init_t init = { 0 };
@@ -197,8 +197,8 @@ void neu_adapter_init(neu_adapter_t *adapter, bool auto_start)
strcpy(header.receiver, "manager");
strcpy(init.node, adapter->name);
init.auto_start = auto_start;
init_msg = neu_msg_gen(&header, &init);
init.state = state;
init_msg = neu_msg_gen(&header, &init);
nng_sendmsg(adapter->sock, init_msg, 0);
}
@@ -371,8 +371,8 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
nng_recvmsg(adapter->sock, &msg, 0);
header = (neu_reqresp_head_t *) nng_msg_body(msg);
nlog_debug("adapter(%s) recv msg from: %s, type: %s", adapter->name,
header->sender, neu_reqresp_type_string(header->type));
nlog_info("adapter(%s) recv msg from: %s, type: %s", adapter->name,
header->sender, neu_reqresp_type_string(header->type));
switch (header->type) {
case NEU_RESP_GET_DRIVER_GROUP:
@@ -755,9 +755,10 @@ static int adapter_loop(enum neu_event_io_type type, int fd, void *usr_data)
strcpy(name, adapter->name);
strcpy(receiver, header->receiver);
if (nng_sendmsg(adapter->sock, uninit_msg, 0) == 0) {
nlog_warn("%s send uninit msg to %s", name, receiver);
nlog_notice("%s send uninit msg to %s", name, receiver);
} else {
nng_msg_free(uninit_msg);
nlog_error("%s send uninit msg to %s failed", name, receiver);
}
break;
}
@@ -822,7 +823,7 @@ int neu_adapter_uninit(neu_adapter_t *adapter)
neu_event_del_timer(adapter->events, adapter->timer_lev);
nlog_info("Stop the adapter(%s)", adapter->name);
nlog_notice("Stop the adapter(%s)", adapter->name);
return 0;
}
+1 -1
View File
@@ -64,7 +64,7 @@ typedef struct adapter_msg_handler {
} adapter_msg_handler_t;
neu_adapter_t *neu_adapter_create(neu_adapter_info_t *info);
void neu_adapter_init(neu_adapter_t *adapter, bool auto_start);
void neu_adapter_init(neu_adapter_t *adapter, neu_node_running_state_e state);
int neu_adapter_start(neu_adapter_t *adapter);
int neu_adapter_start_single(neu_adapter_t *adapter);
+79 -8
View File
@@ -19,6 +19,7 @@
#include <assert.h>
#include <math.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stdlib.h>
#include <nng/nng.h>
@@ -37,15 +38,24 @@
#include "errcodes.h"
#include "tag.h"
typedef struct to_be_write_tag {
neu_datatag_t *tag;
neu_value_u value;
void * req;
} to_be_write_tag_t;
typedef struct group {
char *name;
int64_t timestamp;
neu_group_t *group;
UT_array * static_tags;
int64_t timestamp;
neu_group_t * group;
UT_array * static_tags;
UT_array * wt_tags;
pthread_mutex_t wt_mtx;
neu_event_timer_t *report;
neu_event_timer_t *read;
neu_event_timer_t *write;
neu_plugin_group_t grp;
neu_adapter_driver_t *driver;
@@ -64,6 +74,7 @@ struct neu_adapter_driver {
static int report_callback(void *usr_data);
static int read_callback(void *usr_data);
static int write_callback(void *usr_data);
static void read_group(int64_t timestamp, int64_t timeout,
neu_driver_cache_t *cache, const char *group,
UT_array *tags, neu_resp_tag_value_t *datas);
@@ -74,6 +85,7 @@ static void update(neu_adapter_t *adapter, const char *group, const char *tag,
neu_dvalue_t value);
static void write_response(neu_adapter_t *adapter, void *r, neu_error error);
static group_t *find_group(neu_adapter_driver_t *driver, const char *name);
static void store_write_tag(group_t *group, to_be_write_tag_t *tag);
static void write_response(neu_adapter_t *adapter, void *r, neu_error error)
{
@@ -122,7 +134,7 @@ static void update(neu_adapter_t *adapter, const char *group, const char *tag,
&driver->adapter, NEU_METRIC_TAG_READ_ERRORS_TOTAL,
NEU_TYPE_ERROR == value.type, NULL);
}
nlog_debug(
nlog_info(
"update driver: %s, group: %s, tag: %s, type: %s, timestamp: %" PRId64,
driver->adapter.name, group, tag, neu_type_string(value.type),
global_timestamp);
@@ -175,6 +187,7 @@ int neu_adapter_driver_uninit(neu_adapter_driver_t *driver)
neu_adapter_del_timer((neu_adapter_t *) driver, el->report);
neu_event_del_timer(driver->driver_events, el->read);
neu_event_del_timer(driver->driver_events, el->write);
if (el->grp.group_free != NULL) {
el->grp.group_free(&el->grp);
}
@@ -182,7 +195,13 @@ int neu_adapter_driver_uninit(neu_adapter_driver_t *driver)
free(el->name);
utarray_free(el->grp.tags);
utarray_foreach(el->wt_tags, to_be_write_tag_t *, tag)
{
neu_tag_free(tag->tag);
}
utarray_free(el->static_tags);
utarray_free(el->wt_tags);
neu_group_destroy(el->group);
free(el);
}
@@ -414,8 +433,12 @@ void neu_adapter_driver_write_tag(neu_adapter_driver_t *driver,
driver->adapter.cb_funs.response(&driver->adapter, req, &error);
free(req);
} else {
driver->adapter.module->intf_funs->driver.write_tag(
driver->adapter.plugin, (void *) req, tag, cmd->value.value);
to_be_write_tag_t wtag = { 0 };
wtag.req = (void *) req;
wtag.value = cmd->value.value;
wtag.tag = neu_tag_dup(tag);
store_write_tag(g, &wtag);
}
neu_tag_free(tag);
@@ -429,6 +452,7 @@ void neu_adapter_driver_write_tag(neu_adapter_driver_t *driver,
int neu_adapter_driver_add_group(neu_adapter_driver_t *driver, const char *name,
uint32_t interval)
{
UT_icd icd = { sizeof(to_be_write_tag_t), NULL, NULL, NULL };
group_t *find = NULL;
int ret = NEU_ERR_GROUP_EXIST;
@@ -443,6 +467,10 @@ int neu_adapter_driver_add_group(neu_adapter_driver_t *driver, const char *name,
.type = NEU_EVENT_TIMER_NOBLOCK,
};
pthread_mutex_init(&find->wt_mtx, NULL);
utarray_new(find->wt_tags, &icd);
find->driver = driver;
find->name = strdup(name);
find->group = neu_group_new(name, interval);
@@ -456,6 +484,11 @@ int neu_adapter_driver_add_group(neu_adapter_driver_t *driver, const char *name,
param.cb = read_callback;
find->read = neu_event_add_timer(driver->driver_events, param);
param.second = 0;
param.millisecond = 100;
param.cb = write_callback;
find->write = neu_event_add_timer(driver->driver_events, param);
REGISTER_GROUP_METRIC(&driver->adapter, find->name,
NEU_METRIC_GROUP_TAGS_TOTAL,
neu_group_tag_size(find->group));
@@ -514,6 +547,7 @@ int neu_adapter_driver_del_group(neu_adapter_driver_t *driver, const char *name)
neu_adapter_del_timer((neu_adapter_t *) driver, find->report);
neu_event_del_timer(driver->driver_events, find->read);
neu_event_del_timer(driver->driver_events, find->write);
if (find->grp.group_free != NULL) {
find->grp.group_free(&find->grp);
}
@@ -530,11 +564,18 @@ int neu_adapter_driver_del_group(neu_adapter_driver_t *driver, const char *name)
neu_driver_cache_del(driver->cache, name, tag->name);
}
utarray_foreach(find->wt_tags, to_be_write_tag_t *, tag)
{
neu_tag_free(tag->tag);
}
utarray_free(find->static_tags);
utarray_free(find->grp.tags);
utarray_free(find->wt_tags);
neu_group_destroy(find->group);
free(find);
pthread_mutex_destroy(&find->wt_mtx);
neu_adapter_del_group_metrics(&driver->adapter, name);
ret = NEU_ERR_SUCCESS;
}
@@ -881,7 +922,30 @@ static void group_change(void *arg, int64_t timestamp, UT_array *static_tags,
group->static_tags = static_tags;
group->grp = grp;
nlog_notice("group: %s changed", group->name);
nlog_notice("group: %s changed, timestamp: %" PRIi64, group->name,
timestamp);
}
static int write_callback(void *usr_data)
{
group_t * group = (group_t *) usr_data;
neu_node_running_state_e state = group->driver->adapter.state;
if (state != NEU_NODE_RUNNING_STATE_RUNNING) {
return 0;
}
pthread_mutex_lock(&group->wt_mtx);
utarray_foreach(group->wt_tags, to_be_write_tag_t *, wtag)
{
group->driver->adapter.module->intf_funs->driver.write_tag(
group->driver->adapter.plugin, (void *) wtag->req, wtag->tag,
wtag->value);
neu_tag_free(wtag->tag);
}
utarray_clear(group->wt_tags);
pthread_mutex_unlock(&group->wt_mtx);
return 0;
}
static int read_callback(void *usr_data)
@@ -927,7 +991,7 @@ static int read_report_group(int64_t timestamp, int64_t timeout,
if (neu_tag_attribute_test(tag, NEU_ATTRIBUTE_SUBSCRIBE)) {
if (neu_driver_cache_get_changed(cache, group, tag->name, &value) !=
0) {
nlog_debug("tag: %s not changed", tag->name);
nlog_info("tag: %s not changed", tag->name);
continue;
}
} else {
@@ -1199,3 +1263,10 @@ static void read_group(int64_t timestamp, int64_t timeout,
}
}
}
static void store_write_tag(group_t *group, to_be_write_tag_t *tag)
{
pthread_mutex_lock(&group->wt_mtx);
utarray_push_back(group->wt_tags, tag);
pthread_mutex_unlock(&group->wt_mtx);
}
+1 -1
View File
@@ -125,7 +125,7 @@ int adapter_load_setting(const char *node, char **setting)
{
int rv = neu_persister_load_node_setting(node, (const char **) setting);
if (0 != rv) {
nlog_info("load %s setting fail", node);
nlog_error("load %s setting fail", node);
return -1;
}
+2 -1
View File
@@ -286,7 +286,8 @@ static void split_static_array(tag_elem_t *tags, UT_array **static_tags,
{
if (neu_tag_attribute_test(el->tag, NEU_ATTRIBUTE_STATIC)) {
utarray_push_back(*static_tags, el->tag);
} else {
} else if (neu_tag_attribute_test(el->tag, NEU_ATTRIBUTE_SUBSCRIBE) ||
neu_tag_attribute_test(el->tag, NEU_ATTRIBUTE_READ)) {
utarray_push_back(*other_tags, el->tag);
}
}
+1 -1
View File
@@ -189,7 +189,7 @@ static inline void metrics_unregister_entry(const char *name)
HASH_FIND_STR(g_metrics_.registered_metrics, name, e);
if (0 == --e->value) {
HASH_DEL(g_metrics_.registered_metrics, e);
nlog_info("del entry:%s", e->name);
nlog_notice("del entry:%s", e->name);
neu_metric_entry_free(e);
}
}
+256 -59
View File
@@ -33,6 +33,10 @@
#include "connection/neu_connection.h"
#ifndef CMSPAR
#define CMSPAR 010000000000 /* mark or space (stick) parity */
#endif
struct tcp_client {
int fd;
struct sockaddr_in client;
@@ -43,6 +47,7 @@ struct neu_conn {
void * data;
bool is_connected;
bool stop;
bool connection_ok;
neu_conn_callback connected;
neu_conn_callback disconnected;
@@ -213,10 +218,10 @@ int neu_conn_tcp_server_accept(neu_conn_t *conn)
conn->connected(conn->data, fd);
conn->callback_trigger = true;
zlog_info(conn->param.log, "%s:%d accpet new client: %s:%d, fd: %d",
conn->param.params.tcp_server.ip,
conn->param.params.tcp_server.port, inet_ntoa(client.sin_addr),
ntohs(client.sin_port), fd);
zlog_notice(conn->param.log, "%s:%d accpet new client: %s:%d, fd: %d",
conn->param.params.tcp_server.ip,
conn->param.params.tcp_server.port, inet_ntoa(client.sin_addr),
ntohs(client.sin_port), fd);
pthread_mutex_unlock(&conn->mtx);
@@ -233,6 +238,8 @@ int neu_conn_tcp_server_close_client(neu_conn_t *conn, int fd)
conn->disconnected(conn->data, fd);
conn_tcp_server_del_client(conn, fd);
conn->offset = 0;
memset(conn->buf, 0, conn->buf_size);
pthread_mutex_unlock(&conn->mtx);
return 0;
@@ -312,6 +319,7 @@ ssize_t neu_conn_send(neu_conn_t *conn, uint8_t *buf, ssize_t len)
if (conn->is_connected) {
switch (conn->param.type) {
case NEU_CONN_UDP_TO:
case NEU_CONN_TCP_SERVER:
assert(false);
break;
@@ -334,8 +342,14 @@ ssize_t neu_conn_send(neu_conn_t *conn, uint8_t *buf, ssize_t len)
conn->fd, len, ret, strerror(errno), errno);
}
if (ret == -1 && errno != EAGAIN) {
conn_disconnect(conn);
if (ret == -1) {
if (errno != EAGAIN) {
conn_disconnect(conn);
} else {
if (conn->connection_ok == true) {
conn_disconnect(conn);
}
}
}
if (ret > 0 && conn->callback_trigger == false) {
@@ -346,6 +360,7 @@ ssize_t neu_conn_send(neu_conn_t *conn, uint8_t *buf, ssize_t len)
if (ret > 0) {
conn->state.send_bytes += ret;
conn->connection_ok = true;
}
pthread_mutex_unlock(&conn->mtx);
@@ -364,6 +379,7 @@ ssize_t neu_conn_recv(neu_conn_t *conn, uint8_t *buf, ssize_t len)
}
switch (conn->param.type) {
case NEU_CONN_UDP_TO:
case NEU_CONN_TCP_SERVER:
zlog_fatal(conn->param.log, "neu_conn_recv cann't recv tcp server msg");
assert(1 == 0);
@@ -391,19 +407,126 @@ ssize_t neu_conn_recv(neu_conn_t *conn, uint8_t *buf, ssize_t len)
}
break;
}
if (conn->param.type == NEU_CONN_TTY_CLIENT) {
if (ret == -1) {
zlog_error(
conn->param.log,
"tty conn fd: %d, recv buf len %zd, ret: %zd, errno: %s(%d)",
conn->fd, len, ret, strerror(errno), errno);
conn_disconnect(conn);
}
} else {
if (ret <= 0) {
zlog_error(conn->param.log,
"conn fd: %d, recv buf len %zd, ret: %zd, errno: %s(%d)",
conn->fd, len, ret, strerror(errno), errno);
if (ret == 0 || (ret == -1 && errno != EAGAIN)) {
conn_disconnect(conn);
}
}
}
pthread_mutex_unlock(&conn->mtx);
if (ret > 0) {
conn->state.recv_bytes += ret;
}
return ret;
}
ssize_t neu_conn_udp_sendto(neu_conn_t *conn, uint8_t *buf, ssize_t len,
void *dst)
{
ssize_t ret = 0;
pthread_mutex_lock(&conn->mtx);
if (conn->stop) {
pthread_mutex_unlock(&conn->mtx);
return ret;
}
if (!conn->is_connected) {
conn_connect(conn);
}
if (conn->is_connected) {
switch (conn->param.type) {
case NEU_CONN_TCP_CLIENT:
case NEU_CONN_TCP_SERVER:
case NEU_CONN_TTY_CLIENT:
case NEU_CONN_UDP:
assert(false);
break;
case NEU_CONN_UDP_TO:
if (conn->block) {
ret = sendto(conn->fd, buf, len, MSG_NOSIGNAL,
(struct sockaddr *) dst, sizeof(struct sockaddr));
} else {
ret = sendto(conn->fd, buf, len, MSG_NOSIGNAL | MSG_DONTWAIT,
(struct sockaddr *) dst, sizeof(struct sockaddr));
}
break;
}
if (ret != len) {
zlog_error(
conn->param.log,
"conn udp fd: %d, sendto (%s:%d) buf len: %zd, ret: %zd, "
"errno: %s(%d)",
conn->fd, inet_ntoa(((struct sockaddr_in *) dst)->sin_addr),
htons(((struct sockaddr_in *) dst)->sin_port), len, ret,
strerror(errno), errno);
}
if (ret == -1 && errno != EAGAIN) {
conn_disconnect(conn);
}
if (ret > 0 && conn->callback_trigger == false) {
conn->connected(conn->data, conn->fd);
conn->callback_trigger = true;
}
}
if (ret > 0) {
conn->state.send_bytes += ret;
}
pthread_mutex_unlock(&conn->mtx);
return ret;
}
ssize_t neu_conn_udp_recvfrom(neu_conn_t *conn, uint8_t *buf, ssize_t len,
void *src)
{
ssize_t ret = 0;
socklen_t addr_len = sizeof(struct sockaddr_in);
pthread_mutex_lock(&conn->mtx);
if (conn->stop) {
pthread_mutex_unlock(&conn->mtx);
return ret;
}
switch (conn->param.type) {
case NEU_CONN_TCP_SERVER:
case NEU_CONN_TCP_CLIENT:
case NEU_CONN_TTY_CLIENT:
case NEU_CONN_UDP:
assert(1 == 0);
break;
case NEU_CONN_UDP_TO:
ret =
recvfrom(conn->fd, buf, len, 0, (struct sockaddr *) src, &addr_len);
break;
}
if (ret <= 0) {
zlog_error(conn->param.log,
"conn fd: %d, recv buf len %zd, ret: %zd, errno: %s(%d)",
"conn udp fd: %d, recv buf len %zd, ret: %zd, errno: %s(%d)",
conn->fd, len, ret, strerror(errno), errno);
}
if (errno == EPIPE || ret == -1 || ret == 0) {
conn_disconnect(conn);
}
if (ret > 0 && conn->callback_trigger == false) {
conn->connected(conn->data, conn->fd);
conn->callback_trigger = true;
if (ret == 0 || (ret == -1 && errno != EAGAIN)) {
conn_disconnect(conn);
}
}
pthread_mutex_unlock(&conn->mtx);
@@ -453,6 +576,9 @@ static void conn_free_param(neu_conn_t *conn)
free(conn->param.params.udp.src_ip);
free(conn->param.params.udp.dst_ip);
break;
case NEU_CONN_UDP_TO:
free(conn->param.params.udpto.src_ip);
break;
case NEU_CONN_TTY_CLIENT:
free(conn->param.params.tty_client.device);
break;
@@ -499,6 +625,12 @@ static void conn_init_param(neu_conn_t *conn, neu_conn_param_t *param)
conn->param.params.udp.timeout = param->params.udp.timeout;
conn->block = conn->param.params.udp.timeout > 0;
break;
case NEU_CONN_UDP_TO:
conn->param.params.udpto.src_ip = strdup(param->params.udpto.src_ip);
conn->param.params.udpto.src_port = param->params.udpto.src_port;
conn->param.params.udpto.timeout = param->params.udpto.timeout;
conn->block = conn->param.params.udpto.timeout > 0;
break;
case NEU_CONN_TTY_CLIENT:
conn->param.params.tty_client.device =
strdup(param->params.tty_client.device);
@@ -548,9 +680,9 @@ static void conn_tcp_server_listen(neu_conn_t *conn)
conn->tcp_server.is_listen = true;
conn->param.params.tcp_server.start_listen(conn->data, fd);
zlog_info(conn->param.log, "tcp server listen %s:%d success, fd: %d",
conn->param.params.tcp_server.ip,
conn->param.params.tcp_server.port, fd);
zlog_notice(conn->param.log, "tcp server listen %s:%d success, fd: %d",
conn->param.params.tcp_server.ip,
conn->param.params.tcp_server.port, fd);
}
}
@@ -558,9 +690,9 @@ static void conn_tcp_server_stop(neu_conn_t *conn)
{
if (conn->param.type == NEU_CONN_TCP_SERVER &&
conn->tcp_server.is_listen == true) {
zlog_info(conn->param.log, "tcp server close %s:%d, fd: %d",
conn->param.params.tcp_server.ip,
conn->param.params.tcp_server.port, conn->fd);
zlog_notice(conn->param.log, "tcp server close %s:%d, fd: %d",
conn->param.params.tcp_server.ip,
conn->param.params.tcp_server.port, conn->fd);
conn->param.params.tcp_server.stop_listen(conn->data, conn->fd);
@@ -620,9 +752,9 @@ static void conn_connect(neu_conn_t *conn)
conn->is_connected = false;
return;
} else {
zlog_info(conn->param.log, "connect %s:%d success",
conn->param.params.tcp_client.ip,
conn->param.params.tcp_client.port);
zlog_notice(conn->param.log, "connect %s:%d success",
conn->param.params.tcp_client.ip,
conn->param.params.tcp_client.port);
conn->is_connected = true;
conn->fd = fd;
}
@@ -675,18 +807,65 @@ static void conn_connect(neu_conn_t *conn)
conn->is_connected = false;
return;
} else {
zlog_info(conn->param.log, "connect %s:%d success",
conn->param.params.udp.dst_ip,
conn->param.params.udp.dst_port);
zlog_notice(conn->param.log, "connect %s:%d success",
conn->param.params.udp.dst_ip,
conn->param.params.udp.dst_port);
conn->is_connected = true;
conn->fd = fd;
}
break;
}
case NEU_CONN_UDP_TO: {
if (conn->block) {
struct timeval tv = {
.tv_sec = conn->param.params.udpto.timeout / 1000,
.tv_usec = (conn->param.params.udpto.timeout % 1000) * 1000,
};
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
} else {
fd = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
}
int so_broadcast = 1;
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &so_broadcast,
sizeof(so_broadcast));
struct sockaddr_in local = {
.sin_family = AF_INET,
.sin_port = htons(conn->param.params.udpto.src_port),
.sin_addr.s_addr = inet_addr(conn->param.params.udpto.src_ip),
};
ret = bind(fd, (struct sockaddr *) &local, sizeof(struct sockaddr_in));
if (ret != 0) {
close(fd);
zlog_error(conn->param.log, "bind %s:%d error: %s(%d)",
conn->param.params.udpto.src_ip,
conn->param.params.udpto.src_port, strerror(errno),
errno);
conn->is_connected = false;
return;
}
conn->is_connected = true;
conn->fd = fd;
break;
}
case NEU_CONN_TTY_CLIENT: {
struct termios tty_opt = { 0 };
#ifdef NEU_SMART_LINK
#include "connection/neu_smart_link.h"
ret =
neu_conn_smart_link_auto_set(conn->param.params.tty_client.device);
zlog_notice(conn->param.log, "smart link ret: %d", ret);
if (ret > 0) {
fd = ret;
}
#else
fd = open(conn->param.params.tty_client.device, O_RDWR | O_NOCTTY, 0);
#endif
if (fd <= 0) {
zlog_error(conn->param.log, "open %s error: %s(%d)",
conn->param.params.tty_client.device, strerror(errno),
@@ -842,6 +1021,15 @@ static void conn_connect(neu_conn_t *conn)
static void conn_disconnect(neu_conn_t *conn)
{
conn->is_connected = false;
conn->connection_ok = false;
if (conn->callback_trigger == true) {
conn->disconnected(conn->data, conn->fd);
conn->callback_trigger = false;
}
conn->offset = 0;
memset(conn->buf, 0, conn->buf_size);
switch (conn->param.type) {
case NEU_CONN_TCP_SERVER:
for (int i = 0; i < conn->param.params.tcp_server.max_link; i++) {
@@ -854,6 +1042,7 @@ static void conn_disconnect(neu_conn_t *conn)
break;
case NEU_CONN_TCP_CLIENT:
case NEU_CONN_UDP:
case NEU_CONN_UDP_TO:
case NEU_CONN_TTY_CLIENT:
if (conn->fd > 0) {
close(conn->fd);
@@ -861,14 +1050,6 @@ static void conn_disconnect(neu_conn_t *conn)
}
break;
}
conn->is_connected = false;
if (conn->callback_trigger == true) {
conn->disconnected(conn->data, conn->fd);
conn->callback_trigger = false;
}
conn->offset = 0;
memset(conn->buf, 0, conn->buf_size);
}
static void conn_tcp_server_add_client(neu_conn_t *conn, int fd,
@@ -936,18 +1117,15 @@ int neu_conn_stream_consume(neu_conn_t *conn, void *context,
if (used == 0) {
break;
} else if (used == -1) {
memset(conn->buf, 0, conn->buf_size);
conn->offset = 0;
neu_conn_disconnect(conn);
break;
} else {
conn->offset -= used;
memmove(conn->buf, conn->buf + used, conn->offset);
neu_protocol_unpack_buf_init(&protocol_buf, conn->buf,
conn->offset);
}
}
if (conn->offset != 0) {
conn->offset -= neu_protocol_unpack_buf_used_size(&protocol_buf);
memmove(conn->buf,
conn->buf +
neu_protocol_unpack_buf_used_size(&protocol_buf),
conn->offset);
}
}
return ret;
@@ -968,18 +1146,15 @@ int neu_conn_stream_tcp_server_consume(neu_conn_t *conn, int fd, void *context,
if (used == 0) {
break;
} else if (used == -1) {
memset(conn->buf, 0, conn->buf_size);
conn->offset = 0;
neu_conn_tcp_server_close_client(conn, fd);
break;
} else {
conn->offset -= used;
memmove(conn->buf, conn->buf + used, conn->offset);
neu_protocol_unpack_buf_init(&protocol_buf, conn->buf,
conn->offset);
}
}
if (conn->offset != 0) {
conn->offset -= neu_protocol_unpack_buf_used_size(&protocol_buf);
memmove(conn->buf,
conn->buf +
neu_protocol_unpack_buf_used_size(&protocol_buf),
conn->offset);
}
}
return ret;
}
@@ -997,9 +1172,20 @@ int neu_conn_wait_msg(neu_conn_t *conn, void *context, uint16_t n_byte,
neu_protocol_unpack_buf_init(&pbuf, conn->buf, conn->offset);
neu_buf_result_t result = fn(context, &pbuf);
if (result.need > 0) {
assert(result.need <= conn->buf_size - conn->offset);
ret = neu_conn_recv(conn, conn->buf + conn->offset, result.need);
if (result.need <= conn->buf_size - conn->offset) {
ret =
neu_conn_recv(conn, conn->buf + conn->offset, result.need);
} else {
zlog_error(conn->param.log,
"no enough recv buf, need: %" PRIu16
" , buf size: %" PRIu16 " offset: %" PRIu16,
result.need, conn->buf_size, conn->offset);
return -1;
}
} else if (result.need == 0) {
return result.used;
} else {
neu_conn_disconnect(conn);
return result.used;
}
}
@@ -1021,9 +1207,20 @@ int neu_conn_tcp_server_wait_msg(neu_conn_t *conn, int fd, void *context,
neu_buf_result_t result = fn(context, &pbuf);
if (result.need > 0) {
assert(result.need <= conn->buf_size - conn->offset);
ret = neu_conn_tcp_server_recv(conn, fd, conn->buf + conn->offset,
result.need);
if (result.need <= conn->buf_size - conn->offset) {
ret = neu_conn_tcp_server_recv(
conn, fd, conn->buf + conn->offset, result.need);
} else {
zlog_error(conn->param.log,
"no enough recv buf, need: %" PRIu16
" , buf size: %" PRIu16 " offset: %" PRIu16,
result.need, conn->buf_size, conn->offset);
return -1;
}
} else if (result.need == 0) {
return result.used;
} else {
neu_conn_tcp_server_close_client(conn, fd);
return result.used;
}
}
+114 -207
View File
@@ -17,6 +17,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
@@ -32,6 +33,7 @@
#include "connection/neu_connection_eth.h"
#include "event/event.h"
#include "type.h"
#include "utils/log.h"
#include "utils/utextend.h"
@@ -39,13 +41,12 @@
#define ETH_P_LLDP 0x88CC
#endif
typedef struct neu_conn_eth_sub {
uint16_t protocol;
char mac[ETH_ALEN];
} callback_elem_key_t;
struct neu_conn_eth_sub {
uint8_t mac[6];
};
typedef struct {
callback_elem_key_t key;
char mac[20];
neu_conn_eth_msg_callback callback;
@@ -53,8 +54,6 @@ typedef struct {
} callback_elem_t;
typedef struct {
char device[NEU_NODE_NAME_LEN];
neu_conn_eth_msg_callback callback;
UT_hash_handle hh;
@@ -64,20 +63,16 @@ typedef struct interface_conn {
char * interface;
neu_events_t *events;
uint8_t count;
uint8_t buf[1500];
int lldp_fd;
int profinet_fd;
int vlan_fd;
uint8_t mac[ETH_ALEN];
neu_event_io_t *profinet_event;
neu_event_io_t *lldp_event;
neu_event_io_t *vlan_event;
lldp_callback_elem_t *lldp_callbacks;
callback_elem_t * callbacks;
pthread_mutex_t mtx;
callback_elem_t *callbacks;
pthread_mutex_t mtx;
} interface_conn_t;
static pthread_mutex_t mtx = { 0 };
@@ -91,13 +86,25 @@ struct neu_conn_eth {
};
static int get_mac(neu_conn_eth_t *conn, const char *interface);
static int init_socket(const char *interface, uint16_t protocol);
static int init_socket(const char *interface, uint16_t protocol,
uint8_t mac[6]);
static int uninit_socket(int fd);
static int lldp_msg_cb(enum neu_event_io_type type, int fd, void *usr_data);
static int eth_msg_cb(enum neu_event_io_type type, int fd, void *usr_data);
static int eth_msg_cb(enum neu_event_io_type type, int fd, void *usr_data);
static uint8_t pf_dcp_broadcast[ETH_ALEN] = {
0x01, 0x0e, 0xcf, 0x00, 0x00, 0x01
};
static char *lldp_parse_port_id(uint16_t n_byte, uint8_t *bytes);
int neu_conn_eth_size()
{
int ret = 0;
for (int i = 0; i < interface_max; i++) {
ret += in_conns[i].count;
}
return ret;
}
neu_conn_eth_t *neu_conn_eth_init(const char *interface, void *ctx)
{
@@ -126,17 +133,19 @@ neu_conn_eth_t *neu_conn_eth_init(const char *interface, void *ctx)
if (in_conns[i].interface == NULL) {
neu_event_io_param_t param = { 0 };
pthread_mutex_init(&in_conns[i].mtx, NULL);
conn_eth->ic = &in_conns[i];
in_conns[i].interface = strdup(interface);
in_conns[i].events = neu_event_new();
in_conns[i].count += 1;
in_conns[i].profinet_fd = init_socket(interface, 0x8892);
in_conns[i].lldp_fd = init_socket(interface, ETH_P_LLDP);
in_conns[i].vlan_fd = init_socket(interface, 0x8100);
get_mac(conn_eth, interface);
pthread_mutex_init(&in_conns[i].mtx, NULL);
conn_eth->ic = &in_conns[i];
in_conns[i].profinet_fd =
init_socket(interface, 0x8892, in_conns[i].mac);
// in_conns[i].vlan_fd =
// init_socket(interface, 0x8100, in_conns[i].mac);
param.fd = in_conns[i].profinet_fd;
param.usr_data = (void *) conn_eth;
@@ -145,17 +154,11 @@ neu_conn_eth_t *neu_conn_eth_init(const char *interface, void *ctx)
in_conns[i].profinet_event =
neu_event_add_io(in_conns[i].events, param);
param.fd = in_conns[i].lldp_fd;
param.cb = lldp_msg_cb;
// param.fd = in_conns[i].vlan_fd;
// param.cb = eth_msg_cb;
in_conns[i].lldp_event =
neu_event_add_io(in_conns[i].events, param);
param.fd = in_conns[i].vlan_fd;
param.cb = eth_msg_cb;
in_conns[i].vlan_event =
neu_event_add_io(in_conns[i].events, param);
// in_conns[i].vlan_event =
// neu_event_add_io(in_conns[i].events, param);
break;
}
@@ -174,16 +177,15 @@ int neu_conn_eth_uninit(neu_conn_eth_t *conn)
conn->ic->count -= 1;
if (conn->ic->count == 0) {
neu_event_del_io(conn->ic->events, conn->ic->profinet_event);
neu_event_del_io(conn->ic->events, conn->ic->lldp_event);
neu_event_del_io(conn->ic->events, conn->ic->vlan_event);
// neu_event_del_io(conn->ic->events, conn->ic->vlan_event);
neu_event_close(conn->ic->events);
uninit_socket(conn->ic->profinet_fd);
uninit_socket(conn->ic->lldp_fd);
uninit_socket(conn->ic->vlan_fd);
// uninit_socket(conn->ic->vlan_fd);
free(conn->ic->interface);
conn->ic->interface = NULL;
pthread_mutex_destroy(&conn->ic->mtx);
}
pthread_mutex_unlock(&mtx);
@@ -201,43 +203,46 @@ void neu_conn_eth_get_mac(neu_conn_eth_t *conn, uint8_t *mac)
int neu_conn_eth_check_interface(const char *interface)
{
struct ifreq ifr = { 0 };
int fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
int fd = socket(PF_PACKET, SOCK_RAW, ETH_P_IPV6);
int ret = -1;
if (fd <= 0) {
return -1;
}
strcpy(ifr.ifr_name, interface);
ret = ioctl(fd, SIOCGIFHWADDR, &ifr);
if (ret != 0) {
return -1;
}
close(fd);
return ret;
}
neu_conn_eth_sub_t *neu_conn_eth_register(neu_conn_eth_t *conn,
uint16_t protocol, uint8_t mac[6],
neu_conn_eth_sub_t *neu_conn_eth_register(neu_conn_eth_t *conn, uint8_t xmac[6],
neu_conn_eth_msg_callback callback)
{
callback_elem_key_t key = { 0 };
neu_conn_eth_sub_t *sub = NULL;
callback_elem_t * elem = NULL;
char tmp_mac[20] = { 0 };
neu_conn_eth_sub_t *sub = NULL;
callback_elem_t * elem = NULL;
key.protocol = protocol;
memcpy(key.mac, mac, ETH_ALEN);
snprintf(tmp_mac, sizeof(tmp_mac), "%X:%X:%X-%X:%X:%X", xmac[0], xmac[1],
xmac[2], xmac[3], xmac[4], xmac[5]);
pthread_mutex_lock(&conn->ic->mtx);
HASH_FIND(hh, conn->ic->callbacks, &key, sizeof(callback_elem_key_t), elem);
HASH_FIND_STR(conn->ic->callbacks, tmp_mac, elem);
if (elem == NULL) {
elem = calloc(1, sizeof(callback_elem_t));
sub = calloc(1, sizeof(neu_conn_eth_sub_t));
elem->key.protocol = protocol;
memcpy(key.mac, mac, ETH_ALEN);
elem->callback = callback;
memcpy(elem->mac, tmp_mac, sizeof(elem->mac));
memcpy(sub->mac, mac, ETH_ALEN);
sub->protocol = protocol;
memcpy(sub->mac, xmac, ETH_ALEN);
HASH_ADD(hh, conn->ic->callbacks, key, sizeof(callback_elem_key_t),
elem);
HASH_ADD_STR(conn->ic->callbacks, mac, elem);
}
pthread_mutex_unlock(&conn->ic->mtx);
@@ -247,15 +252,15 @@ neu_conn_eth_sub_t *neu_conn_eth_register(neu_conn_eth_t *conn,
int neu_conn_eth_unregister(neu_conn_eth_t *conn, neu_conn_eth_sub_t *sub)
{
callback_elem_key_t key = { 0 };
callback_elem_t * elem = NULL;
char tmp_mac[20] = { 0 };
callback_elem_t *elem = NULL;
key.protocol = sub->protocol;
memcpy(key.mac, sub->mac, ETH_ALEN);
snprintf(tmp_mac, sizeof(tmp_mac), "%X:%X:%X-%X:%X:%X", sub->mac[0],
sub->mac[1], sub->mac[2], sub->mac[3], sub->mac[4], sub->mac[5]);
pthread_mutex_lock(&conn->ic->mtx);
HASH_FIND(hh, conn->ic->callbacks, &key, sizeof(callback_elem_key_t), elem);
HASH_FIND_STR(conn->ic->callbacks, tmp_mac, elem);
if (elem != NULL) {
HASH_DEL(conn->ic->callbacks, elem);
free(elem);
@@ -268,61 +273,17 @@ int neu_conn_eth_unregister(neu_conn_eth_t *conn, neu_conn_eth_sub_t *sub)
return 0;
}
int neu_conn_eth_register_lldp(neu_conn_eth_t *conn, const char *device,
neu_conn_eth_msg_callback callback)
int neu_conn_eth_send(neu_conn_eth_t *conn, uint16_t protocol, uint16_t n_byte,
uint8_t *bytes)
{
lldp_callback_elem_t *elem = NULL;
int ret = 0;
pthread_mutex_lock(&conn->ic->mtx);
HASH_FIND_STR(conn->ic->lldp_callbacks, device, elem);
if (elem != NULL) {
ret = -1;
} else {
elem = calloc(1, sizeof(lldp_callback_elem_t));
elem->callback = callback;
strcpy(elem->device, device);
HASH_ADD_STR(conn->ic->lldp_callbacks, device, elem);
}
pthread_mutex_unlock(&conn->ic->mtx);
return ret;
}
int neu_conn_eth_unregister_lldp(neu_conn_eth_t *conn, const char *device)
{
lldp_callback_elem_t *elem = NULL;
pthread_mutex_lock(&conn->ic->mtx);
HASH_FIND_STR(conn->ic->lldp_callbacks, device, elem);
if (elem != NULL) {
HASH_DEL(conn->ic->lldp_callbacks, elem);
free(elem);
}
pthread_mutex_unlock(&conn->ic->mtx);
return 0;
}
int neu_conn_eth_send(neu_conn_eth_t *conn, uint8_t dst_mac[6],
uint16_t protocol, uint16_t n_byte, uint8_t *bytes)
{
int fd = 0;
int ret = 0;
struct ethhdr *ehdr = (struct ethhdr *) bytes;
(void) dst_mac;
int fd = 0;
int ret = 0;
switch (protocol) {
case ETH_P_LLDP:
case 0x8892:
fd = conn->ic->profinet_fd;
break;
case ETH_P_LLDP:
fd = conn->ic->lldp_fd;
break;
case 0x8100:
fd = conn->ic->vlan_fd;
break;
@@ -331,8 +292,6 @@ int neu_conn_eth_send(neu_conn_eth_t *conn, uint8_t dst_mac[6],
break;
}
memcpy(ehdr->h_source, conn->ic->mac, ETH_ALEN);
ret = send(fd, bytes, n_byte, 0);
return ret;
}
@@ -353,20 +312,22 @@ static int get_mac(neu_conn_eth_t *conn, const char *interface)
return ret;
}
static int init_socket(const char *interface, uint16_t protocol)
static int init_socket(const char *interface, uint16_t protocol, uint8_t mac[6])
{
struct ifreq ifr = { 0 };
struct sockaddr_ll sll = { 0 };
struct packet_mreq mreq = { 0 };
const uint8_t pn_mcast_addr[ETH_ALEN] = {
0x01, 0x0e, 0xcf, 0x00, 0x00, 0x00
};
int fd = socket(PF_PACKET, SOCK_RAW, htons(protocol));
int ret = 0;
int ret = 1;
assert(fd > 0);
setsockopt(fd, SOL_SOCKET, SO_DONTROUTE, &ret, sizeof(ret));
(void) mac;
(void) pn_mcast_addr;
strcpy(ifr.ifr_name, interface);
if (ioctl(fd, SIOCGIFINDEX, &ifr) != 0) {
close(fd);
@@ -376,25 +337,12 @@ static int init_socket(const char *interface, uint16_t protocol)
sll.sll_family = AF_PACKET;
sll.sll_ifindex = ifr.ifr_ifindex;
sll.sll_protocol = htons(protocol);
mreq.mr_ifindex = ifr.ifr_ifindex;
mreq.mr_type = PACKET_HOST | PACKET_MR_MULTICAST;
mreq.mr_alen = ETH_ALEN;
memcpy(mreq.mr_address, pn_mcast_addr, ETH_ALEN);
ifr.ifr_flags = 0;
ioctl(fd, SIOCGIFFLAGS, &ifr);
bind(fd, (struct sockaddr *) &sll, sizeof(sll));
if (protocol == 0x8892) {
ret = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mreq,
sizeof(mreq));
assert(ret == 0);
}
ret = bind(fd, (struct sockaddr *) &sll, sizeof(sll));
assert(ret == 0);
return fd;
}
static int uninit_socket(int fd)
{
close(fd);
@@ -408,27 +356,53 @@ static int eth_msg_cb(enum neu_event_io_type type, int fd, void *usr_data)
switch (type) {
case NEU_EVENT_IO_READ: {
callback_elem_key_t key = { 0 };
callback_elem_t * elem = NULL;
memset(conn->ic->buf, 0, sizeof(conn->ic->buf));
int ret = recv(fd, conn->ic->buf, sizeof(conn->ic->buf), 0);
callback_elem_t *elem = NULL;
uint8_t buf[1500] = { 0 };
int ret = recv(fd, buf, 1500, 0);
if (ret < ETH_HLEN) {
nlog_warn("eth recv length < %d msg", ETH_HLEN);
return 0;
}
struct ethhdr *ehdr = (struct ethhdr *) conn->ic->buf;
struct ethhdr *ehdr = (struct ethhdr *) buf;
ehdr->h_proto = ntohs(ehdr->h_proto);
key.protocol = ntohs(ehdr->h_proto);
memcpy(key.mac, ehdr->h_source, ETH_ALEN);
if (ehdr->h_proto != 0x8100 && ehdr->h_proto != 0x8892) {
return 0;
}
HASH_FIND(hh, conn->ic->callbacks, &key, sizeof(key), elem);
if (memcmp(ehdr->h_dest, pf_dcp_broadcast, ETH_ALEN) == 0) {
callback_elem_t *tmp = NULL;
if (elem != NULL) {
elem->callback(conn, conn->ctx, key.protocol, ret - ETH_HLEN,
conn->ic->buf + ETH_HLEN, ehdr->h_source);
HASH_ITER(hh, conn->ic->callbacks, elem, tmp)
{
elem->callback(conn, conn->ctx, ehdr->h_proto, ret - ETH_HLEN,
buf + ETH_HLEN, ehdr->h_source);
}
} else {
if (memcmp(ehdr->h_dest, conn->ic->mac, ETH_ALEN) != 0) {
return 0;
}
char tmp_mac[20] = { 0 };
snprintf(tmp_mac, sizeof(tmp_mac), "%X:%X:%X-%X:%X:%X",
ehdr->h_source[0], ehdr->h_source[1], ehdr->h_source[2],
ehdr->h_source[3], ehdr->h_source[4], ehdr->h_source[5]);
HASH_FIND_STR(conn->ic->callbacks, tmp_mac, elem);
if (elem != NULL) {
elem->callback(conn, conn->ctx, ehdr->h_proto, ret - ETH_HLEN,
buf + ETH_HLEN, ehdr->h_source);
} else {
memset(tmp_mac, 0, sizeof(tmp_mac));
snprintf(tmp_mac, sizeof(tmp_mac), "0:0:0-0:0:0");
HASH_FIND_STR(conn->ic->callbacks, tmp_mac, elem);
if (elem != NULL) {
elem->callback(conn, conn->ctx, ehdr->h_proto,
ret - ETH_HLEN, buf + ETH_HLEN,
ehdr->h_source);
}
}
}
break;
@@ -442,70 +416,3 @@ static int eth_msg_cb(enum neu_event_io_type type, int fd, void *usr_data)
return 0;
}
static int lldp_msg_cb(enum neu_event_io_type type, int fd, void *usr_data)
{
neu_conn_eth_t *conn = (neu_conn_eth_t *) usr_data;
int ret = 0;
char * port_id = NULL;
switch (type) {
case NEU_EVENT_IO_READ:
memset(conn->ic->buf, 0, sizeof(conn->ic->buf));
ret = recv(fd, conn->ic->buf, sizeof(conn->ic->buf), 0);
port_id = lldp_parse_port_id(ret - sizeof(struct ethhdr),
conn->ic->buf + sizeof(struct ethhdr));
if (port_id != NULL) {
lldp_callback_elem_t *elem = NULL;
struct ethhdr * ehdr = (struct ethhdr *) conn->ic->buf;
HASH_FIND_STR(conn->ic->callbacks, port_id, elem);
if (elem != NULL) {
elem->callback(
conn, conn->ctx, ETH_P_LLDP, ret - sizeof(struct ethhdr),
conn->ic->buf + sizeof(struct ethhdr), ehdr->h_source);
}
}
break;
case NEU_EVENT_IO_CLOSED:
case NEU_EVENT_IO_HUP:
nlog_warn("eth conn lldp error type: %d, fd: %d(%s)", type, fd,
conn->ic->interface);
break;
}
return 0;
}
struct lldp_tvl {
uint16_t type : 7;
uint16_t length : 9;
} __attribute__((packed));
#define END_OF_LLDPDU_TLV_TYPE 0x00
#define CHASSIS_ID_TLV_TYPE 0x01
#define PORT_ID_TLV_TYPE 0x02
#define TIME_TO_LIVE_TLV_TYPE 0x03
static char *lldp_parse_port_id(uint16_t n_byte, uint8_t *bytes)
{
struct lldp_tvl *tvl = (struct lldp_tvl *) bytes;
if (n_byte < sizeof(struct lldp_tvl) + tvl->length) {
return NULL;
}
if (tvl->type == PORT_ID_TLV_TYPE) {
static __thread char port_id[NEU_NODE_NAME_LEN] = { 0 };
uint8_t * data = (uint8_t *) &tvl[1];
strncpy(port_id, (char *) data + 1, tvl->length - 1);
return port_id;
} else {
return lldp_parse_port_id(
n_byte - sizeof(struct lldp_tvl) - tvl->length,
bytes + sizeof(struct lldp_tvl) + tvl->length);
}
}
+133 -11
View File
@@ -33,6 +33,7 @@
#include "connection/mqtt_client.h"
#include "event/event.h"
#include "utils/asprintf.h"
#include "utils/time.h"
#include "utils/utextend.h"
#include "utils/uthash.h"
#include "utils/utlist.h"
@@ -68,6 +69,7 @@ typedef struct {
typedef enum {
TASK_PUB,
TASK_SUB,
TASK_UNSUB,
TASK_RECV,
} task_kind_e;
@@ -133,7 +135,8 @@ static inline void tasks_free(task_t *tasks);
static void task_cb(void *arg);
static void task_handle_pub(task_t *task, neu_mqtt_client_t *client);
static void task_handle_sub(task_t *task, neu_mqtt_client_t *client);
static void task_handle_recv(task_t *task, neu_mqtt_client_t *client);
static void task_handle_unsub(task_t *task, neu_mqtt_client_t *client);
static void task_handle_recv(task_t *task, neu_mqtt_client_t *client);
static subscription_t * subscription_new(neu_mqtt_client_t *client,
neu_mqtt_qos_e qos, const char *topic,
@@ -221,6 +224,8 @@ static void task_cb(void *arg)
task_handle_pub(task, client);
} else if (TASK_SUB == task->kind) {
task_handle_sub(task, client);
} else if (TASK_UNSUB == task->kind) {
task_handle_unsub(task, client);
} else if (TASK_RECV == task->kind) {
task_handle_recv(task, client);
} else {
@@ -282,19 +287,54 @@ static void task_handle_sub(task_t *task, neu_mqtt_client_t *client)
}
rc = nng_mqtt_msg_get_suback_return_codes(msg, &n);
log(info, "recv SUBACK return_code:%d", *rc);
log(debug, "recv SUBACK return_code:%d", *rc);
rv = 0x80 == *rc ? -1 : 0;
task->sub->ack = true;
client->suback_count += 1;
end:
// TODO: handle retry subscribe on failure
log(info, "sub [%s, QoS%d], %s", task->sub->topic, task->sub->qos,
log(notice, "sub [%s, QoS%d], %s", task->sub->topic, task->sub->qos,
(0 == rv) ? "OK" : "FAIL");
nng_msg_free(msg);
return;
}
static void task_handle_unsub(task_t *task, neu_mqtt_client_t *client)
{
int rv = 0;
nng_msg *msg = NULL;
nng_aio *aio = task->aio;
if (0 != (rv = nng_aio_result(aio))) {
log(error, "send UNSUBSCRIBE error: %s", nng_strerror(rv));
goto end;
}
msg = nng_aio_get_msg(aio);
if (NULL == msg) {
rv = -1;
goto end;
}
nng_mqtt_packet_type pt = nng_mqtt_msg_get_packet_type(msg);
if (NNG_MQTT_UNSUBACK != pt) {
log(error, "recv packet type:%d, expect UNSUBACK packet", pt);
rv = -1;
goto end;
}
end:
if (task->sub) {
log(notice, "unsub [%s, QoS%d], %s", task->sub->topic, task->sub->qos,
(0 == rv) ? "OK" : "FAIL");
} else {
log(notice, "unsub %s", (0 == rv) ? "OK" : "FAIL");
}
nng_msg_free(msg);
return;
}
static void task_handle_recv(task_t *task, neu_mqtt_client_t *client)
{
(void) client;
@@ -391,7 +431,7 @@ static void connect_cb(nng_pipe p, nng_pipe_ev ev, void *arg)
neu_mqtt_client_connection_cb_t cb = NULL;
void * data = NULL;
log(info, "mqtt client connected");
log(notice, "mqtt client connected");
nng_mtx_lock(client->mtx);
// start receiving
@@ -417,7 +457,7 @@ static void disconnect_cb(nng_pipe p, nng_pipe_ev ev, void *arg)
neu_mqtt_client_connection_cb_t cb = NULL;
void * data = NULL;
log(info, "mqtt client disconnected");
log(notice, "mqtt client disconnected");
nng_mtx_lock(client->mtx);
client->connected = false;
cb = client->disconnect_cb;
@@ -471,7 +511,7 @@ static void recv_cb(void *arg)
uint8_t qos = nng_mqtt_msg_get_publish_qos(msg);
(void) payload;
log(info, "recv [%.*s, QoS%d] %" PRIu32 " bytes", (unsigned) topic_len,
log(debug, "recv [%.*s, QoS%d] %" PRIu32 " bytes", (unsigned) topic_len,
topic, (int) qos, payload_len);
// find matching subscription
@@ -525,7 +565,7 @@ static inline task_t *client_alloc_task(neu_mqtt_client_t *client)
// the task queue length should be a small number due to reuse
// log info every time the task queue length increments by 32
if (0 == (client->task_count & (32 - 1))) {
log(info, "task queue length: %zu", client->task_count);
log(debug, "task queue length: %zu", client->task_count);
}
return task;
@@ -535,7 +575,7 @@ static inline void client_free_task(neu_mqtt_client_t *client, task_t *task)
{
nng_aio_set_msg(task->aio, NULL);
if (TASK_SUB == task->kind) {
if (TASK_SUB == task->kind || TASK_UNSUB == task->kind) {
subscription_free(task->sub);
} else if (TASK_RECV == task->kind) {
subscription_free(task->recv.sub);
@@ -569,6 +609,16 @@ static inline void client_add_subscription(neu_mqtt_client_t *client,
HASH_ADD_STR(client->subscriptions, topic, sub);
}
static inline void client_del_subscription(neu_mqtt_client_t *client,
subscription_t * sub)
{
HASH_DEL(client->subscriptions, sub);
if (sub->ack) {
client->suback_count -= 1;
}
subscription_free(sub);
}
static int client_send_sub_msg(neu_mqtt_client_t *client,
subscription_t * subscription)
{
@@ -606,6 +656,38 @@ static int client_send_sub_msg(neu_mqtt_client_t *client,
return 0;
}
static int client_send_unsub_msg(neu_mqtt_client_t *client,
subscription_t * subscription)
{
int rv = 0;
nng_msg *sub_msg = NULL;
if ((rv = nng_mqtt_msg_alloc(&sub_msg, 0)) != 0) {
log(error, "nng_mqtt_msg_alloc fail: %s", nng_strerror(rv));
return -1;
}
nng_mqtt_topic mqtt_topic = { .buf = (uint8_t *) subscription->topic,
.length = strlen(subscription->topic) };
nng_mqtt_msg_set_packet_type(sub_msg, NNG_MQTT_UNSUBSCRIBE);
nng_mqtt_msg_set_unsubscribe_topics(sub_msg, &mqtt_topic, 1);
task_t *task = client_alloc_task(client);
if (NULL == task) {
log(error, "client_alloc_task fail");
nng_msg_free(sub_msg);
return -1;
}
task->kind = TASK_UNSUB;
task->sub = subscription ? subscription_ref(subscription) : NULL;
nng_aio_set_msg(task->aio, sub_msg);
nng_send_aio(client->sock, task->aio);
return 0;
}
static inline void client_start_recv(neu_mqtt_client_t *client)
{
if (client->recv_aio && !client->receiving) {
@@ -935,7 +1017,7 @@ int neu_mqtt_client_set_tls(neu_mqtt_client_t *client, const char *ca,
if (NULL == ca) {
// disable tls
log(info, "tls disabled");
log(debug, "tls disabled");
if (client->tls_cfg) {
nng_tls_config_free(client->tls_cfg);
client->tls_cfg = NULL;
@@ -995,7 +1077,7 @@ int neu_mqtt_client_set_cache_size(neu_mqtt_client_t *client,
if (0 == mem_size_bytes && 0 == db_size_bytes) {
// disable cache
log(info, "cache disabled");
log(debug, "cache disabled");
if (client->sqlite_cfg) {
nng_mqtt_free_sqlite_opt(client->sqlite_cfg);
client->sqlite_cfg = NULL;
@@ -1163,7 +1245,7 @@ int neu_mqtt_client_close(neu_mqtt_client_t *client)
// wait for all tasks
while (client_task_free_list_len(client) != client->task_count) {
nng_mtx_unlock(client->mtx);
nng_msleep(100);
neu_msleep(100);
nng_mtx_lock(client->mtx);
}
client->open = false;
@@ -1261,3 +1343,43 @@ error:
subscription_free(subscription);
return -1;
}
int neu_mqtt_client_unsubscribe(neu_mqtt_client_t *client, const char *topic)
{
int rv = 0;
subscription_t *subscription = NULL;
nng_mtx_lock(client->mtx);
if (NULL == client->recv_aio) {
if ((rv = nng_aio_alloc(&client->recv_aio, recv_cb, client)) != 0) {
log(error, "nng_aio_alloc fail: %s", nng_strerror(rv));
goto error;
}
if (client->connected) {
// connect_cb already fired, then start receiving
client_start_recv(client);
}
}
HASH_FIND_STR(client->subscriptions, topic, subscription);
if (client->connected) {
// send a unsubscribe message even subscription is NULL
if (client_send_unsub_msg(client, subscription) < 0) {
log(error, "client_send_unsub_msg fail");
goto error;
}
}
if (subscription) {
client_del_subscription(client, subscription);
}
nng_mtx_unlock(client->mtx);
return 0;
error:
nng_mtx_unlock(client->mtx);
return -1;
}
+286
View File
@@ -0,0 +1,286 @@
#include <errno.h>
#include <fcntl.h>
#include <linux/serial.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <termios.h>
#include <unistd.h>
#include <jansson.h>
#include "json/json.h"
#include "connection/neu_smart_link.h"
#define DEVICE_CONF_PATH "/etc/config/device.conf"
#define SERIAL_CONF_PATH "/etc/config/serial.conf"
#define SMART_LINK_PATH "/dev/smartlink"
#define TYPE 'S'
#define UART_RS232 _IOWR(TYPE, 1, int)
#define UART_RS485 _IOWR(TYPE, 0, int)
enum SERIAL_MODE { SM_RS232, SM_RS422, SM_RS485 };
static int get_port(const char *path);
static int get_port_property(int port, int *mode, int *baudrate);
static int read_file(const char *path, char **buf);
static int set_serial_mode(const char *dev_path, int baudrate, int mode);
int neu_conn_smart_link_auto_set(const char *dev_path)
{
int mode = 0;
int baudrate = 0;
int port = get_port(dev_path);
if (port <= 0) {
return -1;
}
printf("get port %d\n", port);
int ret = get_port_property(port, &mode, &baudrate);
if (ret != 0) {
return -1;
}
printf("get port property %d %d\n", mode, baudrate);
ret = set_serial_mode(dev_path, baudrate, mode);
return ret;
}
static int read_file(const char *path, char **buf)
{
FILE *fp = NULL;
fp = fopen(path, "r");
if (fp == NULL) {
return -1;
}
fseek(fp, 0, SEEK_END);
int size = ftell(fp);
rewind(fp);
*buf = calloc(1, size + 1);
if (*buf == NULL) {
fclose(fp);
return -1;
}
int ret = fread(*buf, 1, size, fp);
if (ret != size) {
fclose(fp);
free(*buf);
return -1;
}
fclose(fp);
return ret;
}
static int get_port(const char *dev_path)
{
json_t * root = NULL;
json_error_t error;
char * buf = NULL;
int ret = read_file(DEVICE_CONF_PATH, &buf);
if (ret <= 0) {
return -1;
}
root = json_loads(buf, JSON_DECODE_ANY, &error);
if (root == NULL) {
free(buf);
return -1;
}
neu_json_elem_t e_tty = {
.name = "tty_name",
.t = NEU_JSON_OBJECT,
};
ret = neu_json_decode_value(root, &e_tty);
if (ret != 0 || json_is_array((json_t *) e_tty.v.val_object) == false) {
free(buf);
json_decref(root);
return -1;
}
int index = 0;
json_t *e_dev = NULL;
json_array_foreach(e_tty.v.val_object, index, e_dev)
{
neu_json_elem_t e_dd = {
.name = "device",
.t = NEU_JSON_STR,
};
ret = neu_json_decode_value(e_dev, &e_dd);
if (ret != 0) {
free(buf);
json_decref(root);
return -1;
}
if (strcmp(e_dd.v.val_str, dev_path) == 0) {
neu_json_elem_t e_port = {
.name = "port",
.t = NEU_JSON_INT,
};
ret = neu_json_decode_value(e_dev, &e_port);
if (ret != 0) {
free(buf);
json_decref(root);
return -1;
}
free(buf);
json_decref(root);
free(e_dd.v.val_str);
return e_port.v.val_int;
}
free(e_dd.v.val_str);
}
free(buf);
json_decref(root);
return -1;
}
static int get_port_property(int port, int *mode, int *baudrate)
{
json_t * root = NULL;
json_error_t error;
char * buf = NULL;
int ret = read_file(SERIAL_CONF_PATH, &buf);
if (ret <= 0) {
return -1;
}
root = json_loads(buf, JSON_DECODE_ANY, &error);
if (root == NULL) {
free(buf);
return -1;
}
json_t *e_port = json_array_get(root, port - 1);
if (e_port == NULL) {
json_decref(root);
free(buf);
return -1;
}
neu_json_elem_t elems[] = {
{
.name = "mode",
.t = NEU_JSON_INT,
},
{
.name = "baudrate",
.t = NEU_JSON_INT,
},
};
ret = neu_json_decode_by_json(e_port, NEU_JSON_ELEM_SIZE(elems), elems);
if (ret != 0) {
free(buf);
json_decref(root);
return -1;
}
*mode = elems[0].v.val_int;
*baudrate = elems[1].v.val_int;
json_decref(root);
free(buf);
return 0;
}
static int set_serial_mode(const char *dev_path, int baudrate, int mode)
{
static pthread_mutex_t mode_switch_mtx = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_lock(&mode_switch_mtx);
int serial_fd, switch_fd;
int tty_num, para;
int ret = -1;
struct serial_rs485 conf;
conf.flags &= !SER_RS485_ENABLED;
switch (baudrate) {
case 38400:
conf.delay_rts_after_send = 1;
break;
case 57600:
conf.delay_rts_after_send = 4;
break;
case 115200:
conf.delay_rts_after_send = 6;
break;
default:
conf.delay_rts_after_send = 0;
break;
}
if ((serial_fd = open(dev_path, O_RDWR | O_NOCTTY)) < 0) {
fprintf(stderr, "open %s failed, fd: %d, strerr: %s\n", dev_path,
serial_fd, strerror(errno));
goto out;
}
if (mode != SM_RS232) {
if (ioctl(serial_fd, TIOCMGET, &para) != 0) {
fprintf(stderr, "ioctl failed, strerr: %s\n", strerror(errno));
goto out2;
}
if (mode == SM_RS422) {
para |= TIOCM_DTR;
conf.flags |= SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND;
} else if (mode == SM_RS485) {
para &= ~TIOCM_DTR;
conf.flags |= SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND;
}
if (ioctl(serial_fd, TIOCMSET, &para) != 0) {
fprintf(stderr, "ioctl failed, strerr: %s\n", strerror(errno));
goto out2;
}
}
ioctl(serial_fd, TIOCSRS485, &conf);
if ((switch_fd = open(SMART_LINK_PATH, O_RDWR)) < 0) {
fprintf(stderr, "open %s failed, ret: %d, strerr: %s\n",
SMART_LINK_PATH, switch_fd, strerror(errno));
goto out2;
}
sscanf(dev_path, "%*[a-zA-Z/]%d", &tty_num);
printf("tty_num: %d\n", tty_num);
if (mode == SM_RS232) {
ret = ioctl(switch_fd, UART_RS232, tty_num);
} else {
ret = ioctl(switch_fd, UART_RS485, tty_num);
}
if (ret < 0) {
fprintf(stderr, "ioctl failed, ret: %d, strerr: %s\n", ret,
strerror(errno));
}
close(switch_fd);
ret = serial_fd;
pthread_mutex_unlock(&mode_switch_mtx);
return ret;
out2:
close(serial_fd);
serial_fd = -1;
out:
pthread_mutex_unlock(&mode_switch_mtx);
return ret;
}
+19 -9
View File
@@ -97,8 +97,9 @@ neu_manager_t *neu_manager_create()
rv = nng_listen(manager->socket, url, NULL, 0);
assert(rv == 0);
nng_socket_set_int(manager->socket, NNG_OPT_RECVBUF, 2048);
nng_socket_set_int(manager->socket, NNG_OPT_SENDBUF, 2048);
nng_socket_set_int(manager->socket, NNG_OPT_RECVBUF, 8192);
nng_socket_set_int(manager->socket, NNG_OPT_SENDBUF, 8292);
nng_socket_set_ms(manager->socket, NNG_OPT_SENDTIMEO, 1000);
nng_socket_get_int(manager->socket, NNG_OPT_RECVFD, &param.fd);
manager->loop = neu_event_add_io(manager->events, param);
@@ -135,6 +136,7 @@ neu_manager_t *neu_manager_create()
manager->timer_timestamp =
neu_event_add_timer(manager->events, timestamp_timer_param);
nlog_notice("manager start");
return manager;
}
@@ -177,7 +179,7 @@ void neu_manager_destroy(neu_manager_t *manager)
neu_event_close(manager->events);
free(manager);
nlog_warn("manager exit");
nlog_notice("manager exit");
}
const char *neu_manager_get_url()
@@ -228,8 +230,8 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
header = (neu_reqresp_head_t *) nng_msg_body(msg);
nlog_debug("manager recv msg from: %s to %s, type: %s", header->sender,
header->receiver, neu_reqresp_type_string(header->type));
nlog_info("manager recv msg from: %s to %s, type: %s", header->sender,
header->receiver, neu_reqresp_type_string(header->type));
switch (header->type) {
case NEU_REQRESP_TRANS_DATA: {
neu_reqresp_trans_data_t *cmd = (neu_reqresp_trans_data_t *) &header[1];
@@ -253,7 +255,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
utarray_foreach(pipes, nng_pipe *, pipe)
{
forward_msg_dup(manager, msg, *pipe);
nlog_info("forward license update to pipe: %d", pipe->id);
nlog_notice("forward license update to pipe: %d", pipe->id);
}
utarray_free(pipes);
@@ -265,10 +267,14 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
neu_node_manager_update(manager->node_manager, init->node, pipe);
if (init->auto_start) {
if (init->state == NEU_NODE_RUNNING_STATE_STOPPED ||
init->state == NEU_NODE_RUNNING_STATE_RUNNING) {
neu_adapter_t *adapter =
neu_node_manager_find(manager->node_manager, init->node);
neu_adapter_start(adapter);
if (init->state == NEU_NODE_RUNNING_STATE_STOPPED) {
neu_adapter_stop(adapter);
}
}
nlog_notice("bind node %s to pipe(%d)", init->node, pipe.id);
@@ -482,6 +488,8 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
forward_msg(manager, msg, cmd->app);
manager_storage_subscribe(manager, cmd->app, cmd->driver,
cmd->group, cmd->params);
} else {
free(cmd->params);
}
header->type = NEU_RESP_ERROR;
@@ -727,8 +735,9 @@ inline static void forward_msg_dup(neu_manager_t *manager, nng_msg *msg,
nng_msg_dup(&out_msg, msg);
nng_msg_set_pipe(out_msg, pipe);
if (nng_sendmsg(manager->socket, out_msg, 0) == 0) {
nlog_debug("forward msg to pipe %d", pipe.id);
nlog_info("forward msg to pipe %d", pipe.id);
} else {
nlog_warn("forward msg to pipe %d fail", pipe.id);
nng_msg_free(out_msg);
}
}
@@ -742,8 +751,9 @@ inline static void forward_msg(neu_manager_t *manager, nng_msg *msg,
nng_msg_dup(&out_msg, msg);
nng_msg_set_pipe(out_msg, pipe);
if (nng_sendmsg(manager->socket, out_msg, 0) == 0) {
nlog_debug("forward msg to %s", node);
nlog_info("forward msg to %s", node);
} else {
nlog_warn("forward msg to pipe (%s)%d fail", node, pipe.id);
nng_msg_free(out_msg);
}
}
+6 -3
View File
@@ -43,7 +43,8 @@ UT_array *neu_manager_get_plugins(neu_manager_t *manager)
}
int neu_manager_add_node(neu_manager_t *manager, const char *node_name,
const char *plugin_name, bool start)
const char * plugin_name,
neu_node_running_state_e state)
{
neu_adapter_t * adapter = NULL;
neu_plugin_instance_t instance = { 0 };
@@ -77,7 +78,7 @@ int neu_manager_add_node(neu_manager_t *manager, const char *node_name,
adapter = neu_adapter_create(&adapter_info);
neu_node_manager_add(manager->node_manager, adapter);
neu_adapter_init(adapter, start);
neu_adapter_init(adapter, state);
return NEU_ERR_SUCCESS;
}
@@ -324,8 +325,10 @@ int neu_manager_send_subscribe(neu_manager_t *manager, const char *app,
nng_msg_set_pipe(out_msg, pipe);
if (nng_sendmsg(manager->socket, out_msg, 0) == 0) {
nlog_info("send %s to %s", neu_reqresp_type_string(header.type), app);
nlog_notice("send %s to %s", neu_reqresp_type_string(header.type), app);
} else {
nlog_warn("send %s to %s failed", neu_reqresp_type_string(header.type),
app);
free(cmd.params);
nng_msg_free(out_msg);
}
+2 -1
View File
@@ -52,7 +52,8 @@ int neu_manager_del_plugin(neu_manager_t *manager, const char *plugin);
UT_array *neu_manager_get_plugins(neu_manager_t *manager);
int neu_manager_add_node(neu_manager_t *manager, const char *node_name,
const char *plugin_name, bool start);
const char * plugin_name,
neu_node_running_state_e state);
int neu_manager_del_node(neu_manager_t *manager, const char *node_name);
UT_array *neu_manager_get_nodes(neu_manager_t *manager, neu_node_type_e type,
const char *plugin, const char *node);
+9 -10
View File
@@ -96,7 +96,7 @@ int manager_load_plugin(neu_manager_t *manager)
{
rv = neu_manager_add_plugin(manager, *name);
const char *ok_or_err = (0 == rv) ? "success" : "fail";
nlog_info("load plugin %s, lib:%s", ok_or_err, *name);
nlog_notice("load plugin %s, lib:%s", ok_or_err, *name);
}
utarray_foreach(plugin_infos, char **, name) { free(*name); }
@@ -118,13 +118,12 @@ int manager_load_node(neu_manager_t *manager)
utarray_foreach(node_infos, neu_persist_node_info_t *, node_info)
{
rv = neu_manager_add_node(
manager, node_info->name, node_info->plugin_name,
node_info->state == NEU_NODE_RUNNING_STATE_RUNNING);
rv = neu_manager_add_node(manager, node_info->name,
node_info->plugin_name, node_info->state);
const char *ok_or_err = (0 == rv) ? "success" : "fail";
nlog_info("load adapter %s type:%d, name:%s plugin:%s state:%d",
ok_or_err, node_info->type, node_info->name,
node_info->plugin_name, node_info->state);
nlog_notice("load adapter %s type:%d, name:%s plugin:%s state:%d",
ok_or_err, node_info->type, node_info->name,
node_info->plugin_name, node_info->state);
}
utarray_free(node_infos);
@@ -151,9 +150,9 @@ int manager_load_subscribe(neu_manager_t *manager)
info->driver_name, info->group_name,
info->params);
const char *ok_or_err = (0 == rv) ? "success" : "fail";
nlog_info("%s load subscription app:%s driver:%s grp:%s",
ok_or_err, node->node, info->driver_name,
info->group_name);
nlog_notice("%s load subscription app:%s driver:%s grp:%s",
ok_or_err, node->node, info->driver_name,
info->group_name);
if (0 == rv) {
neu_manager_send_subscribe(manager, node->node,
info->driver_name,
+2
View File
@@ -129,6 +129,8 @@ int neuron_already_running()
snprintf(buf, sizeof(buf), "%ld", (long) getpid());
size = write(fd, buf, strlen(buf) + 1);
nlog_warn("write %s, error %s(%d)", NEURON_DAEMON_LOCK_FNAME,
strerror(errno), errno);
assert(size != -1);
return 0;
+11 -10
View File
@@ -205,19 +205,20 @@ neu_event_timer_t *neu_event_add_timer(neu_events_t * events,
ret = epoll_ctl(events->epoll_fd, EPOLL_CTL_ADD, timer_fd, &event);
zlog_info(neuron,
"add timer, second: %" PRId64 ", millisecond: %" PRId64
", timer: %d in epoll %d, "
"ret: %d",
timer.second, timer.millisecond, timer_fd, events->epoll_fd, ret);
zlog_notice(neuron,
"add timer, second: %" PRId64 ", millisecond: %" PRId64
", timer: %d in epoll %d, "
"ret: %d",
timer.second, timer.millisecond, timer_fd, events->epoll_fd,
ret);
return timer_ctx;
}
int neu_event_del_timer(neu_events_t *events, neu_event_timer_t *timer)
{
zlog_info(neuron, "del timer: %d from epoll: %d", timer->fd,
events->epoll_fd);
zlog_notice(neuron, "del timer: %d from epoll: %d", timer->fd,
events->epoll_fd);
timer->stop = true;
nng_mtx_lock(timer->mtx);
@@ -251,8 +252,8 @@ neu_event_io_t *neu_event_add_io(neu_events_t *events, neu_event_io_param_t io)
ret = epoll_ctl(events->epoll_fd, EPOLL_CTL_ADD, io.fd, &event);
nlog_info("add io, fd: %d, epoll: %d, ret: %d", io.fd, events->epoll_fd,
ret);
nlog_notice("add io, fd: %d, epoll: %d, ret: %d", io.fd, events->epoll_fd,
ret);
return io_ctx;
}
@@ -260,7 +261,7 @@ neu_event_io_t *neu_event_add_io(neu_events_t *events, neu_event_io_param_t io)
int neu_event_del_io(neu_events_t *events, neu_event_io_t *io)
{
struct event_data *data = (struct event_data *) io->event_data;
zlog_info(neuron, "del io: %d from epoll: %d", io->fd, events->epoll_fd);
zlog_notice(neuron, "del io: %d from epoll: %d", io->fd, events->epoll_fd);
epoll_ctl(events->epoll_fd, EPOLL_CTL_DEL, io->fd, NULL);
switch (data->type) {
+1 -1
View File
@@ -34,7 +34,7 @@ static bool exit_flag = false;
static neu_manager_t *g_manager = NULL;
zlog_category_t * neuron = NULL;
bool disable_jwt = false;
int default_log_level = ZLOG_LEVEL_INFO;
int default_log_level = ZLOG_LEVEL_NOTICE;
int64_t global_timestamp = 0;
+2 -1
View File
@@ -199,7 +199,8 @@ int neu_json_tag_check_type(neu_json_tag_t *tag)
return NEU_JSON_BOOL == tag->t;
case NEU_TYPE_BYTES:
case NEU_TYPE_STRING:
return NEU_JSON_STR == tag->t;
return NEU_JSON_STR == tag->t &&
strlen(tag->value.val_str) <= NEU_VALUE_SIZE;
}
} else {
// non-static tag should have no initial value
+117 -17
View File
@@ -25,6 +25,7 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
@@ -49,9 +50,12 @@
#define PATH_MAX_SIZE 128
static const char *plugin_file = "persistence/plugins.json";
static const char *db_file = "persistence/sqlite.db";
static sqlite3 * global_db = NULL;
static const char *plugin_file = "persistence/plugins.json";
static const char *db_file = "persistence/sqlite.db";
static sqlite3 * global_db = NULL;
pthread_rwlock_t global_rwlock = PTHREAD_RWLOCK_INITIALIZER;
static int global_node_count = 0;
static int global_tag_count = 0;
static inline bool ends_with(const char *str, const char *suffix)
{
@@ -383,8 +387,8 @@ static int apply_schema_file(sqlite3 *db, const char *dir, const char *file)
end:
if (0 == rv) {
nlog_info("success apply schema `%s`, version=`%s` description=`%s`",
path, version, description);
nlog_notice("success apply schema `%s`, version=`%s` description=`%s`",
path, version, description);
} else {
nlog_error("fail apply schema `%s`, version=`%s` description=`%s`",
path, version, description);
@@ -441,7 +445,7 @@ static int apply_schemas(sqlite3 *db, const char *dir)
return NEU_ERR_EINTERNAL;
}
nlog_info("schema head version=%s", version ? version : "none");
nlog_notice("schema head version=%s", version ? version : "none");
if (dirty) {
nlog_error("database is dirty, need manual intervention");
@@ -474,6 +478,44 @@ static int apply_schemas(sqlite3 *db, const char *dir)
return rv;
}
static inline int node_count_load()
{
int rv = 0;
sqlite3_stmt *stmt = NULL;
char * query = "select count(*) from nodes";
if (SQLITE_OK == sqlite3_prepare_v2(global_db, query, -1, &stmt, NULL) &&
SQLITE_ROW == sqlite3_step(stmt)) {
pthread_rwlock_wrlock(&global_rwlock);
global_node_count = sqlite3_column_int(stmt, 0);
pthread_rwlock_unlock(&global_rwlock);
} else {
rv = -1;
}
sqlite3_finalize(stmt);
return rv;
}
static inline int tag_count_load()
{
int rv = 0;
sqlite3_stmt *stmt = NULL;
char * query = "select count(*) from tags";
if (SQLITE_OK == sqlite3_prepare_v2(global_db, query, -1, &stmt, NULL) &&
SQLITE_ROW == sqlite3_step(stmt)) {
pthread_rwlock_wrlock(&global_rwlock);
global_tag_count = sqlite3_column_int(stmt, 0);
pthread_rwlock_unlock(&global_rwlock);
} else {
rv = -1;
}
sqlite3_finalize(stmt);
return rv;
}
int neu_persister_create(const char *schema_dir)
{
int rv = sqlite3_open(db_file, &global_db);
@@ -506,6 +548,12 @@ int neu_persister_create(const char *schema_dir)
return -1;
}
if (0 != node_count_load() || 0 != tag_count_load()) {
nlog_fatal("load node/tag count fail");
sqlite3_close(global_db);
return -1;
}
return 0;
}
@@ -514,6 +562,36 @@ sqlite3 *neu_persister_get_db()
return global_db;
}
static inline void node_count_add(int n)
{
pthread_rwlock_wrlock(&global_rwlock);
global_node_count += n;
pthread_rwlock_unlock(&global_rwlock);
}
int neu_persister_node_count()
{
pthread_rwlock_rdlock(&global_rwlock);
int cnt = global_node_count;
pthread_rwlock_unlock(&global_rwlock);
return cnt;
}
static inline void tag_count_add(int n)
{
pthread_rwlock_wrlock(&global_rwlock);
global_tag_count += n;
pthread_rwlock_unlock(&global_rwlock);
}
int neu_persister_tag_count()
{
pthread_rwlock_rdlock(&global_rwlock);
int cnt = global_tag_count;
pthread_rwlock_unlock(&global_rwlock);
return cnt;
}
void neu_persister_destroy()
{
sqlite3_close(global_db);
@@ -521,10 +599,15 @@ void neu_persister_destroy()
int neu_persister_store_node(neu_persist_node_info_t *info)
{
return execute_sql(global_db,
"INSERT INTO nodes (name, type, state, plugin_name) "
"VALUES (%Q, %i, %i, %Q)",
info->name, info->type, info->state, info->plugin_name);
int rv =
execute_sql(global_db,
"INSERT INTO nodes (name, type, state, plugin_name) "
"VALUES (%Q, %i, %i, %Q)",
info->name, info->type, info->state, info->plugin_name);
if (0 == rv) {
node_count_add(1);
}
return rv;
}
static UT_icd node_info_icd = {
@@ -585,8 +668,13 @@ int neu_persister_delete_node(const char *node_name)
{
// rely on foreign key constraints to remove settings, groups, tags and
// subscriptions
return execute_sql(global_db, "DELETE FROM nodes WHERE name=%Q;",
node_name);
int rv =
execute_sql(global_db, "DELETE FROM nodes WHERE name=%Q;", node_name);
if (0 == rv) {
node_count_add(-1);
tag_count_load();
}
return rv;
}
int neu_persister_update_node(const char *node_name, const char *new_name)
@@ -716,6 +804,9 @@ int neu_persister_store_tag(const char *driver_name, const char *group_name,
tag->attribute, tag->precision, tag->type,
tag->decimal, tag->description, val_str);
if (0 == rv) {
tag_count_add(1);
}
free(val_str);
return rv;
}
@@ -821,11 +912,12 @@ int neu_persister_store_tags(const char *driver_name, const char *group_name,
goto error;
}
tag_count_add(n);
sqlite3_finalize(stmt);
return 0;
error:
nlog_info("rollback transaction");
nlog_warn("rollback transaction");
sqlite3_exec(global_db, "ROLLBACK", NULL, NULL, NULL);
sqlite3_finalize(stmt);
free(val_str);
@@ -926,10 +1018,14 @@ int neu_persister_update_tag_value(const char * driver_name,
int neu_persister_delete_tag(const char *driver_name, const char *group_name,
const char *tag_name)
{
return execute_sql(
int rv = execute_sql(
global_db,
"DELETE FROM tags WHERE driver_name=%Q AND group_name=%Q AND name=%Q",
driver_name, group_name, tag_name);
if (0 == rv) {
tag_count_add(-1);
}
return rv;
}
int neu_persister_store_subscription(const char *app_name,
@@ -1101,9 +1197,13 @@ error:
int neu_persister_delete_group(const char *driver_name, const char *group_name)
{
// rely on foreign key constraints to delete tags and subscriptions
return execute_sql(global_db,
"DELETE FROM groups WHERE driver_name=%Q AND name=%Q",
driver_name, group_name);
int rv = execute_sql(global_db,
"DELETE FROM groups WHERE driver_name=%Q AND name=%Q",
driver_name, group_name);
if (0 == rv) {
tag_count_load();
}
return rv;
}
int neu_persister_store_node_setting(const char *node_name, const char *setting)
+2
View File
@@ -295,6 +295,8 @@ int neu_http_response(nng_aio *aio, neu_err_code_e code, char *content)
case NEU_ERR_MQTT_CONNECT_FAILURE:
case NEU_ERR_MQTT_SUBSCRIBE_FAILURE:
case NEU_ERR_MQTT_PUBLISH_FAILURE:
case NEU_ERR_STRING_TOO_LONG:
case NEU_ERR_FILE_WRITE_FAILURE:
status = NNG_HTTP_STATUS_OK;
break;
case NEU_ERR_EINTERNAL:
+1 -1
View File
@@ -1 +1 @@
2.4.4
2.4.13