Compare commits

...
162 Commits
Author SHA1 Message Date
fengzeroz ee9da15891 Merge pull request #2739 from vulgraph/backport/CVE-2024-10964-v2.6
v2.6: bound plugin-library copy (CVE-2024-10964)
2026-09-24 09:39:39 +08:00
xiang.zhou 80caae1095 plugin:buffer overflow
(cherry picked from commit 3e3a583d72)
2026-04-24 00:27:38 +08:00
fengzeroz ec00415177 Merge pull request #2555 from fengzeroz/v2.6
#2501: Prevent the creation of monitor node
2025-08-27 17:24:18 +08:00
fengzero ae36da9c94 #2501: Prevent the creation of monitor node 2025-08-27 09:23:33 +00:00
fengzeroz 2225e71b66 Merge pull request #2488 from hxy7yx/v2.6-1
[v2.6]feat(modbus):support endianess of 8-Byte data
2025-06-16 10:55:26 +08:00
hxy7yx 1f37d12c8e feat(modbus):support endianess of 8-Byte data 2025-06-15 06:10:48 -07:00
fengzeroz 80bdc5bf1e Merge pull request #2209 from fengzeroz/v2.6
ci: clang-format
2024-09-09 11:11:45 +08:00
fengzero c656eb1775 ci: clang-format 2024-09-09 03:01:03 +00:00
fengzeroz 77e4cf67d9 Merge pull request #2188 from hxy7yx/v2.6-1
[v2.6]chore(mqtt): add reason for connection & disconnection
2024-08-20 16:19:00 +08:00
hxy7yx c5510e22af chore(mqtt): add reason for connection & disconnection 2024-08-20 14:44:59 +08:00
fengzeroz 91776516b1 Merge pull request #2180 from fengzeroz/v2.6
version: 2.6.9
2024-08-15 13:52:21 +08:00
fengzero 46b5a3b61a version: 2.6.9 2024-08-15 05:49:02 +00:00
fengzeroz b5bc952543 Merge pull request #2179 from hxy7yx/v2.6-1
[v2.6]guard against empty mqtt subscription topic
2024-08-15 10:02:31 +08:00
hxy7yx f5976f95dc guard against empty mqtt subscription topic 2024-08-14 14:31:49 +08:00
fengzeroz cd9da5afef Merge pull request #2124 from eeff/v2.6
Pick to v2.6 chore: add error code `NEU_ERR_BODY_TOO_BIG`
2024-07-01 11:14:26 +08:00
fengzeroz 1c7bd2193a Merge pull request #2125 from fengzeroz/v2.6
version: 2.6.8
2024-07-01 11:14:02 +08:00
fengzero 36b5e491e4 version: 2.6.8 2024-07-01 03:13:20 +00:00
eeff 642e832d5c chore: add error code NEU_ERR_BODY_TOO_BIG 2024-07-01 10:59:36 +08:00
fengzeroz b46ef37d51 Merge pull request #2117 from fengzeroz/v2.6
fix(core): ready to running
2024-06-25 10:45:27 +08:00
fengzero 04d2a78e7a fix(core): ready to running 2024-06-25 02:44:49 +00:00
fengzeroz 841680a00e Merge pull request #2097 from eeff/v2.6
Pick to v2.6 feat(core): add `interval` field to struct neu_plugin_group
2024-06-13 15:25:12 +08:00
eeff 691c51bcb1 feat(core): add interval field to struct neu_plugin_group 2024-06-13 15:13:16 +08:00
fengzeroz 2dce709f2d Merge pull request #2030 from eeff/v2.6
Pick to v2.6 fix: reset metrics when node stopped
2024-05-28 15:03:54 +08:00
eeff d28f4430d9 fix: start/stop group timer when driver started/stopped 2024-05-28 14:46:47 +08:00
eeff 6a810d616b feat: add metric type no reset flag 2024-05-28 14:33:18 +08:00
eeff 801d369d6a fix(restful): force clean stale rolling metrics 2024-05-28 14:32:45 +08:00
eeff 5179001d32 refactor(metrics): add lock to avoid data race 2024-05-28 14:29:58 +08:00
eeff 889f69b57d fix: rolling counter integer overflow 2024-05-28 14:29:16 +08:00
eeff 7790b2cdd2 fix(metrics): correct registered rolling counter entry ref count 2024-05-28 14:28:50 +08:00
eeff 9ed033ee84 feat(metrics): support distribution counter 2024-05-28 14:28:22 +08:00
eeff fb8463d9bf test: rolling counter unit tests 2024-05-28 14:25:27 +08:00
eeff ce8b1612d4 feat: add rolling counter utility 2024-05-28 14:22:21 +08:00
hxy 8d372d3e13 Merge pull request #2025 from hxy7yx/v2.6-1
Revert "test"
2024-05-24 18:22:29 +08:00
hxy7yx f91b937b18 Revert "test"
This reverts commit 3ad51811ff.
2024-05-24 18:21:04 +08:00
hxy 555707c666 Merge pull request #2024 from hxy7yx/v2.6-1
test
2024-05-24 18:08:10 +08:00
hxy7yx 3ad51811ff test 2024-05-24 18:06:47 +08:00
fengzeroz 92d4ee84d9 Merge pull request #1962 from fengzeroz/v2.6
fix json parse string
2024-04-25 13:54:41 +08:00
fengzero 5f5e9ac123 fix json parse string 2024-04-25 05:31:01 +00:00
fengzeroz 0a54b13022 Merge pull request #1955 from hxy7yx/v2.6-1
locating core dump files
2024-04-22 09:36:42 +08:00
hxy7yx 527b434374 locating core dump files, adapting to NeuronEX 2024-04-19 17:59:33 +08:00
fengzeroz 66c373e539 Merge pull request #1928 from fengzeroz/v2.6
version: 2.6.7
2024-03-27 14:57:39 +08:00
fengzero 2821d91247 version: 2.6.7 2024-03-27 06:57:08 +00:00
fengzeroz 374dfa13d4 Merge pull request #1927 from eeff/v2.6
Pick to v2.6 fix(ekuiper): memory leak and data race
2024-03-27 10:01:35 +08:00
eeff 45b3aeda9a fix(ekuiper): check received aio data race 2024-03-26 22:10:06 +08:00
eeff e1429d95c8 fix(ekuiper): configuration validation 2024-03-26 22:10:00 +08:00
eeff 62da33b352 fix(ekuiper): json parser memory leak 2024-03-26 22:09:55 +08:00
fengzeroz eff4bc7886 Merge pull request #1917 from fengzeroz/v2.6
fix(conn): check offset reset
2024-03-21 09:44:22 +08:00
fengzero bef72d2f2b fix(conn): check offset reset 2024-03-21 01:36:48 +00:00
fengzeroz a7da8ec66c Merge pull request #1908 from hxy7yx/v2.6-1
plugin(modbus): fix invalid message check
2024-03-14 16:56:16 +08:00
hxy7yx eeeca7144b plugin(modbus): fix invalid message check 2024-03-14 16:55:53 +08:00
fengzeroz b8890b708a Merge pull request #1903 from hxy7yx/v2.6-1
plugin(modbus): fix modbus rtu slave check
2024-03-13 16:31:48 +08:00
hxy7yx f0fbfa6500 plugin(modbus): fix modbus rtu slave check 2024-03-13 16:19:33 +08:00
fengzeroz 07ff0444ac Merge pull request #1896 from fengzeroz/v2.6
rm atomic
2024-03-11 10:22:35 +08:00
fengzero f9e3e6b9e8 rm atomic 2024-03-11 02:21:28 +00:00
fengzeroz 0fe5c37dcd Merge pull request #1887 from fengzeroz/v2.6
version: 2.6.6
2024-03-08 14:14:29 +08:00
fengzero 7498cf9399 version: 2.6.6 2024-03-08 06:13:49 +00:00
fengzeroz feacf066cc Merge pull request #1871 from eeff/v2.6
Pick to v2.6 fix: notify north app about driver group deletion
2024-03-06 09:42:57 +08:00
eeff 8b11ae008e fix(ekuiper): handle NEU_REQ_DEL_GROUP 2024-03-05 18:09:19 +08:00
eeff a6e190b349 fix(mqtt): handle NEU_REQ_DEL_GROUP 2024-03-05 18:08:30 +08:00
eeff 108a9d3e57 fix(core): notify app about driver group deletion 2024-03-05 18:08:30 +08:00
fengzeroz dd2d535c55 Merge pull request #1868 from gc87/type_ptr-leak-v2.6
[v2.6]fix(driver): neu_type_ptr leak
2024-03-05 09:54:02 +08:00
gc87 dcbd9ebd87 fix(driver): neu_type_ptr leak 2024-03-04 22:26:45 +08:00
fengzeroz 2a5d3b7443 Merge pull request #1863 from eeff/v2.6
Pick to v2.6 chore: remove useless code
2024-02-27 10:28:35 +08:00
eeff 83f544a506 chore: remove useless code 2024-02-26 23:32:42 +08:00
fengzeroz 1f11c23d59 Merge pull request #1835 from hxy7yx/v2.6-1
remove api: file
2024-01-31 17:37:36 +08:00
fengzeroz 9d5f20c77a Merge pull request #1837 from eeff/v2.6
Pick to v2.6 build: cmake link libatomic
2024-01-31 17:37:20 +08:00
eeff 8bdc80bf86 build: cmake link libatomic 2024-01-31 17:33:14 +08:00
hxy7yx 166efb1e90 remove api: file 2024-01-31 15:14:25 +08:00
fengzeroz f879058d27 Merge pull request #1829 from ZhouBox/v2.6
[v2.6]judge cache type when report group
2024-01-29 14:37:04 +08:00
xiang.zhou 556b1f7ceb feat:judge cache type when report group 2024-01-29 14:19:18 +08:00
fengzeroz 0f45692205 Merge pull request #1826 from fengzeroz/v2.6
version: 2.6.5
2024-01-26 13:53:59 +08:00
fengzero d94aa03f89 version: 2.6.5 2024-01-26 05:53:03 +00:00
fengzeroz 8d6723bf0e Merge pull request #1801 from fengzeroz/v2.6
version: 2.6.4
2024-01-05 09:50:11 +08:00
fengzero 4693d2d368 version: 2.6.4 2024-01-05 01:49:40 +00:00
fengzeroz 57a0bcd75f Merge pull request #1789 from hxy7yx/v2.6-1
increase the size of EVENT_SIZE
2024-01-03 10:03:44 +08:00
hxy7yx 88532f8401 increase the size of EVENT_SIZE 2024-01-02 18:06:04 +08:00
fengzeroz 338216e5f4 Merge pull request #1785 from fengzeroz/v2.6
msg q
2023-12-29 15:47:34 +08:00
fengzero 87cf190da4 msg q 2023-12-29 06:53:57 +00:00
fengzeroz fa051f068c Merge pull request #1781 from fengzeroz/v2.6
lock tag table
2023-12-29 11:06:31 +08:00
fengzero 531c918b10 lock tag table 2023-12-29 02:02:24 +00:00
fengzeroz 8bad15fffa Merge pull request #1778 from fengzeroz/v2.6
fix event leak
2023-12-25 11:04:07 +08:00
fengzero 65d8fd00ab Revert "x"
This reverts commit 37b0659207.
2023-12-25 02:50:31 +00:00
fengzero 4a7b4ec527 event log 2023-12-25 02:46:49 +00:00
fengzero 9e20cf05e5 fix(event): timer/io index set 2023-12-25 02:43:14 +00:00
fengzero 37b0659207 x 2023-12-25 02:43:14 +00:00
fengzeroz 80a3baf7d7 Merge pull request #1775 from eeff/v2.6
Pick to v2.6 fix(core): replace path separator char in adapter log category
2023-12-22 14:50:43 +08:00
eeff 7043c1b4a6 fix(core): replace path separator char in adapter log category 2023-12-22 14:48:11 +08:00
fengzeroz 1c5bf86297 Merge pull request #1752 from gc87/fix-write-float-tags
[v2.6]fix: write tags api int->float type
2023-12-15 09:30:04 +08:00
gc87 697633fd3c fix: write tags api int->float type 2023-12-14 11:36:09 +08:00
fengzeroz eeb73c22a5 Merge pull request #1749 from fengzeroz/v2.6
event: log
2023-12-12 15:30:02 +08:00
fengzero 0e9c33bdde event: log 2023-12-12 07:22:11 +00:00
fengzeroz e89bd94d81 Merge pull request #1745 from fengzeroz/v2.6
fix write tag
2023-12-12 10:14:22 +08:00
fengzero 74538cc804 fix write tag 2023-12-12 02:13:41 +00:00
fengzeroz b223aec78a Merge pull request #1742 from fengzeroz/v2.6
fix write tag in arm64
2023-12-11 18:26:35 +08:00
fengzero 7c5b1114c7 fix write tag in arm64 2023-12-11 10:25:48 +00:00
fengzeroz 288c2a2c4d Merge pull request #1741 from fengzeroz/v2.6
fix write tag in arm64
2023-12-11 18:23:15 +08:00
fengzero 972b311a79 fix write tag in arm64 2023-12-11 10:22:36 +00:00
fengzeroz 9de2ceb232 Merge pull request #1739 from fengzeroz/v2.6
reg sigkill
2023-12-11 17:06:31 +08:00
fengzero 9155532e62 reg sigkill 2023-12-11 09:03:20 +00:00
fengzeroz 8afa18df91 Merge pull request #1726 from eeff/v2.6
Pick to v2.6: fix(mqtt): memory double free and leak
2023-12-07 14:40:54 +08:00
eeff 9f01e71053 refactor(mqtt): reduce write req handler duplicate code 2023-12-07 14:38:05 +08:00
eeff 5f9614848c fix(mqtt): memory double free and leak 2023-12-07 14:37:36 +08:00
fengzeroz cca3ab6670 Merge pull request #1725 from fengzeroz/v2.6
fix(conn): block link abnormal connection
2023-12-07 11:14:18 +08:00
fengzero f397afa4fa fix(conn): block link abnormal connection 2023-12-07 03:08:25 +00:00
fengzeroz 2e04cd4887 Merge pull request #1721 from emqx/revert-1717-write_tags_int2d64-v26
Revert "[v2.6]fix: write tags api int->double type"
2023-12-06 16:45:22 +08:00
Gao Chun 8d71afb543 Revert "[v2.6]fix: write tags api int->double type" 2023-12-06 16:44:24 +08:00
fengzeroz be8548813c Merge pull request #1717 from gc87/write_tags_int2d64-v26
[v2.6]fix: write tags api int->double type
2023-12-06 15:45:42 +08:00
gc87 413d48c580 fix: write tags api int->double type 2023-12-06 15:06:20 +08:00
fengzeroz 137ff855d0 Merge pull request #1716 from eeff/v2.6
fix(core): memory corruption
2023-12-06 14:39:15 +08:00
eeff d260740a1b fix(core): memory corruption 2023-12-06 14:36:08 +08:00
fengzeroz ab7d6c4b52 Merge pull request #1710 from eeff/v2.6
Pick to v2.6 fix(core): send unsubscribe group message when deleting app
2023-12-04 17:45:33 +08:00
eeff 33c566ce8a fix(core): send unsubscribe group message when deleting app 2023-12-04 17:44:29 +08:00
fengzeroz 6ea4464a0d Merge pull request #1706 from fengzeroz/v2.6
version: 2.6.3
2023-12-01 17:15:19 +08:00
fengzeroz 83e798874d Merge pull request #1707 from eeff/v2.6
Pick to V2.6 refactor: send msg by pointer
2023-12-01 17:12:39 +08:00
eeff 08712028fb fix: memory used after free 2023-12-01 17:04:07 +08:00
eeff 271faf34a0 refactor: send msg by pointer 2023-12-01 17:04:07 +08:00
eeff af379b1048 refactor: add neu_msg_t for internal messaging 2023-12-01 17:04:07 +08:00
fengzero ccade70b2c version: 2.6.3 2023-12-01 07:06:07 +00:00
fengzeroz ec62065b78 Merge pull request #1698 from eeff/eeff/fix
Pick to v2.6 fix(core): send correct node name when del node
2023-11-27 09:55:47 +08:00
eeff 59220b12a4 fix(core): send correct node name when del node 2023-11-24 16:26:33 +08:00
fengzeroz 242770fb64 Merge pull request #1693 from fengzeroz/v2.6
default group interval 1000
2023-11-23 11:31:56 +08:00
fengzero ac08674550 default group interval 1000 2023-11-23 03:15:04 +00:00
fengzeroz 9ff2bdeb8c Merge pull request #1690 from eeff/v2.6
Pick to v2.6 feat: syslog message add priority
2023-11-23 09:55:33 +08:00
eeff 3eddbd09e1 feat: syslog message add priority 2023-11-22 11:36:52 +08:00
fengzeroz e088de9dbf Merge pull request #1685 from eeff/v2.6
Pick to v2.6 fix: pid file work around fs.protected_regular
2023-11-22 10:07:01 +08:00
eeff f80df71d67 fix: pid file work around fs.protected_regular 2023-11-21 14:42:26 +08:00
fengzeroz d98d344bf0 Merge pull request #1683 from fengzeroz/v2.6
event: size 1024
2023-11-21 14:14:51 +08:00
fengzero 45a89ec1d8 event: size 1024 2023-11-21 06:13:46 +00:00
fengzeroz 4e0b307923 Merge pull request #1681 from fengzeroz/v2.6
chore(log): default size
2023-11-21 13:46:16 +08:00
fengzero c0d7795da8 chore(log): default size 2023-11-21 03:42:15 +00:00
fengzeroz 4da4f3e7e0 Merge pull request #1678 from eeff/v2.6
Pick v2.6 refactor: reduce message size
2023-11-20 14:06:17 +08:00
eeff 4c1bb772e7 refactor: reduce write gtags message size 2023-11-20 11:56:34 +08:00
eeff 5f818d792c refactor: reduce write tags message size 2023-11-20 11:56:34 +08:00
eeff cddd225c84 refactor: reduce write tag messages size 2023-11-20 11:56:34 +08:00
eeff 14e45c8ccc refactor: reduce read group message size 2023-11-20 11:56:34 +08:00
eeff a194e07cee refactor: reduce trans data message size 2023-11-20 11:56:34 +08:00
eeff ca09852279 refactor: move request and response types into separate header 2023-11-20 11:32:59 +08:00
fengzeroz b6a5c00b98 Merge pull request #1674 from hxy7yx/v2.6-1
delete user error and password error code
2023-11-16 03:28:05 -06:00
hxy7yx 5041a32238 delete user error and password error code 2023-11-16 17:26:46 +08:00
fengzeroz b7484b6f9d Merge pull request #1673 from hxy7yx/v2.6-1
merge user&password error code
2023-11-16 03:17:07 -06:00
hxy7yx cc906a0a88 merge user&password error code 2023-11-16 17:16:15 +08:00
fengzeroz 83ba53d235 Merge pull request #1663 from fengzeroz/v2.6
chore(log): type con
2023-11-10 04:45:57 -06:00
fengzero e094664006 chore(log): type con 2023-11-10 10:44:51 +00:00
fengzeroz 7bf9a013d4 Merge pull request #1661 from fengzeroz/v2.6
log: only update core level
2023-11-10 04:41:18 -06:00
fengzero f10090d18c log: only update core level 2023-11-10 10:08:57 +00:00
fengzeroz 3a1a1521dd Merge pull request #1660 from fengzeroz/v2.6
log: reduce alloc
2023-11-10 03:58:15 -06:00
fengzero 52f87be032 chore: remove neuron in description 2023-11-10 09:50:53 +00:00
fengzero de31fb549f log: reduce alloc 2023-11-10 09:46:24 +00:00
fengzeroz 8ada62e80d Merge pull request #1659 from fengzeroz/v2.6
fix(log): protocol log
2023-11-10 02:47:56 -06:00
fengzero 52a92fa9d7 fix(log): protocol log 2023-11-10 08:39:35 +00:00
fengzeroz d43fcb2fc5 Merge pull request #1657 from fengzeroz/v2.6
driver: report trans data immeditely when subscribe
2023-11-10 01:41:03 -06:00
fengzero 5863dee984 driver: report trans data immeditely when subscribe 2023-11-10 07:25:34 +00:00
fengzeroz 086d47a84a Merge pull request #1656 from fengzeroz/v2.6
improve: core/adapter log level
2023-11-10 00:40:34 -06:00
fengzero eda15d1886 improve: core/adapter log level 2023-11-10 06:31:45 +00:00
fengzeroz c771d8e814 Merge pull request #1651 from fengzeroz/v2.6
fix(core): free tags after free req
2023-11-08 00:03:59 -06:00
fengzero 7d8b348458 fix(core): free tags after free req 2023-11-08 06:02:42 +00:00
fengzeroz a5015e4f50 Merge pull request #1649 from fengzeroz/v2.6
core: msg dup
2023-11-07 21:42:24 -06:00
fengzero b792cdf79d core: msg dup 2023-11-08 03:41:31 +00:00
fengzeroz 06e4782d6d Merge pull request #1647 from eeff/v2.6
Pick to v2.6 feat: add error code `NEU_ERR_LICENSE_TOKEN_NOT_FOUND`
2023-11-06 21:39:10 -06:00
eeff 03e835760b feat: add error code NEU_ERR_LICENSE_TOKEN_NOT_FOUND 2023-11-07 11:37:09 +08:00
fengzeroz 7795bdbd9e Merge pull request #1645 from eeff/v2.6
Pick to v2.6 fix: utarray_steal dangling pointer
2023-11-06 01:26:48 -06:00
eeff 92558c6e29 fix: utarray_steal dangling pointer 2023-11-06 15:18:57 +08:00
74 changed files with 3503 additions and 2646 deletions
+3 -3
View File
@@ -9,16 +9,16 @@ on:
jobs:
clang_format_check:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
# checkout
- uses: actions/checkout@v2
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Run clang-format style check for C/C++ programs.
uses: DoozyX/clang-format-lint-action@v0.12
uses: DoozyX/clang-format-lint-action@v0.18
with:
source: 'src plugins include tests'
exclude: 'include/neuron/utils/uthash.h include/neuron/utils/utarray.h include/neuron/utils/utlist.h include/neuron/utils/zlog.h'
+8 -8
View File
@@ -8,13 +8,13 @@ on:
- published
env:
VERSION: 2.6.2
UI_VERSION: 2.6.2
VERSION: 2.6.9
UI_VERSION: 2.6.3
BRANCH: v2.6
jobs:
cross-build:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
strategy:
matrix:
arch:
@@ -52,14 +52,14 @@ jobs:
run: |
./package-sdk.sh -p ${{ matrix.arch[2] }} -n neuron-sdk-$VERSION
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: neuron-sdk
name: neuron-sdk-${{ matrix.arch[2] }}
path: |
neuron-sdk-*.tar.gz
build-debug-sdk:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
strategy:
matrix:
arch:
@@ -83,7 +83,7 @@ jobs:
run: |
./package-sdk.sh -p ${{ matrix.arch[2] }} -n neuron-sdk-debug-$VERSION
- uses: actions/upload-artifact@v3
- uses: actions/upload-artifact@v4
with:
name: neuron-sdk
path: |
@@ -102,7 +102,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
name: neuron-sdk
+2 -1
View File
@@ -74,6 +74,7 @@ set(NEURON_BASE_SOURCES
src/base/tag_sort.c
src/base/group.c
src/base/metrics.c
src/base/msg.c
src/base/template.c
src/connection/connection.c
src/connection/connection_eth.c
@@ -122,13 +123,13 @@ set(NEURON_SOURCES
src/core/node_manager.c
src/core/template_manager.c
src/core/storage.c
src/adapter/msg_q.c
src/adapter/storage.c
src/adapter/adapter.c
src/adapter/driver/cache.c
src/adapter/driver/driver.c
plugins/restful/handle.c
plugins/restful/log_handle.c
plugins/restful/file_handle.c
plugins/restful/metric_handle.c
plugins/restful/normal_handle.c
plugins/restful/rw_handle.c
+3 -3
View File
@@ -6,10 +6,10 @@ file perms = 666
stdout_format = "%d:%ms [%V] [%c] %f:%L %m%n"
file_format = "%d:%ms [%V] %f:%L %m%n"
syslog = "%d:%ms %H neuron[%p]: [%V] [%c] %f:%L %m%n"
syslog = "<P>%d:%ms %H neuron[%p]: [%V] [%c] %f:%L %m%n"
[rules]
*.* "./logs/%c.log", 50MB * 1 ~ "./logs/%c.#2s.log"; file_format
*.* "./logs/%c.log", 25MB * 1 ~ "./logs/%c.#2r.log"; file_format
*.* >stdout; stdout_format
*.* $remote_syslog; syslog
*.* $remote_syslog,"%V"; syslog
+2 -2
View File
@@ -9,12 +9,12 @@ Suite Teardown Stop Neuronx
login with invalid username, it should return failure
POST /api/v2/login {"name":"admin1", "pass": "0000"}
Integer response status 401
Integer $.error ${NEU_ERR_INVALID_USER}
Integer $.error ${NEU_ERR_INVALID_USER_OR_PASSWORD}
login with invalid password, it should return failure
POST /api/v2/login {"name":"admin", "pass": "2333"}
Integer response status 401
Integer $.error ${NEU_ERR_INVALID_PASSWORD}
Integer $.error ${NEU_ERR_INVALID_USER_OR_PASSWORD}
login with username and password, it should return success
POST /api/v2/login {"name":"admin", "pass": "0000"}
+2 -1057
View File
File diff suppressed because it is too large Load Diff
+3
View File
@@ -85,4 +85,7 @@ typedef enum {
NEU_TAG_CACHE_TYPE_NEVER,
} neu_tag_cache_type_e;
// forward declaration for neu_adapter_t
typedef struct neu_adapter neu_adapter_t;
#endif
+2 -2
View File
@@ -47,8 +47,7 @@ typedef enum {
NEU_ERR_COMMAND_EXECUTION_FAILED = 1014,
NEU_ERR_IP_ADDRESS_INVALID = 1015,
NEU_ERR_IP_ADDRESS_IN_USE = 1016,
NEU_ERR_INVALID_USER = 1017,
NEU_ERR_INVALID_PASSWORD = 1018,
NEU_ERR_BODY_TOO_BIG = 1017,
NEU_ERR_NODE_EXIST = 2002,
NEU_ERR_NODE_NOT_EXIST = 2003,
@@ -102,6 +101,7 @@ typedef enum {
NEU_ERR_LICENSE_TOKEN_NOT_MATCH = 2406,
NEU_ERR_LICENSE_BAD_CLOCK = 2407,
NEU_ERR_LICENSE_MODULE_INVALID = 2408,
NEU_ERR_LICENSE_TOKEN_NOT_FOUND = 2409,
NEU_ERR_TEMPLATE_EXIST = 2500,
NEU_ERR_TEMPLATE_NOT_FOUND = 2501,
+218 -20
View File
@@ -26,27 +26,37 @@ extern "C" {
#include <stdint.h>
#include <pthread.h>
#include "define.h"
#include "type.h"
#include "utils/rolling_counter.h"
#include "utils/utextend.h"
#include "utils/uthash.h"
// forward declaration for neu_adapter_t
typedef struct neu_adapter neu_adapter_t;
extern int64_t global_timestamp;
typedef enum {
NEU_METRIC_TYPE_COUNTER,
NEU_METRIC_TYPE_GAUAGE,
NEU_METRIC_TYPE_COUNTER_SET,
NEU_METRIC_TYPE_ROLLING_COUNTER,
NEU_METRIC_TYPE_FLAG_NO_RESET = 0x80,
} neu_metric_type_e;
#define NEU_METRIC_TYPE_MASK 0x0F
// node running state
#define NEU_METRIC_RUNNING_STATE "running_state"
#define NEU_METRIC_RUNNING_STATE_TYPE NEU_METRIC_TYPE_GAUAGE
#define NEU_METRIC_RUNNING_STATE_TYPE \
(NEU_METRIC_TYPE_GAUAGE | NEU_METRIC_TYPE_FLAG_NO_RESET)
#define NEU_METRIC_RUNNING_STATE_HELP "Node running state"
// node link state
#define NEU_METRIC_LINK_STATE "link_state"
#define NEU_METRIC_LINK_STATE_TYPE NEU_METRIC_TYPE_GAUAGE
#define NEU_METRIC_LINK_STATE_TYPE \
(NEU_METRIC_TYPE_GAUAGE | NEU_METRIC_TYPE_FLAG_NO_RESET)
#define NEU_METRIC_LINK_STATE_HELP "Node link state"
// last round trip time in millisends
@@ -82,13 +92,15 @@ typedef enum {
// maintained by neuron core
// number of tags in group
#define NEU_METRIC_TAGS_TOTAL "tags_total"
#define NEU_METRIC_TAGS_TOTAL_TYPE NEU_METRIC_TYPE_GAUAGE
#define NEU_METRIC_TAGS_TOTAL_TYPE \
(NEU_METRIC_TYPE_GAUAGE | NEU_METRIC_TYPE_FLAG_NO_RESET)
#define NEU_METRIC_TAGS_TOTAL_HELP "Total number of tags in the node"
// maintained by neuron core
// number of tags in group
#define NEU_METRIC_GROUP_TAGS_TOTAL "group_tags_total"
#define NEU_METRIC_GROUP_TAGS_TOTAL_TYPE NEU_METRIC_TYPE_GAUAGE
#define NEU_METRIC_GROUP_TAGS_TOTAL_TYPE \
(NEU_METRIC_TYPE_GAUAGE | NEU_METRIC_TYPE_FLAG_NO_RESET)
#define NEU_METRIC_GROUP_TAGS_TOTAL_HELP "Total number of tags in the group"
// number of messages sent in last group timer
@@ -143,11 +155,12 @@ typedef enum {
// metric entry
typedef struct {
const char * name; // NOTE: should points to string literal
const char * help; // NOTE: should points to string literal
neu_metric_type_e type; //
uint64_t value; //
UT_hash_handle hh; // ordered by name
const char * name; // NOTE: should points to string literal
const char * help; // NOTE: should points to string literal
neu_metric_type_e type; //
uint64_t value; //
neu_rolling_counter_t *rcnt; //
UT_hash_handle hh; // ordered by name
} neu_metric_entry_t;
// group metrics
@@ -159,6 +172,7 @@ typedef struct {
// node metrics
typedef struct {
pthread_mutex_t lock; // spin lock
neu_node_type_e type; // node type
char * name; // node name
neu_metric_entry_t * entries; // node metric entries
@@ -190,9 +204,34 @@ typedef struct {
neu_metric_entry_t *registered_metrics;
} neu_metrics_t;
void neu_metrics_init();
void neu_metrics_add_node(const neu_adapter_t *adapter);
void neu_metrics_del_node(const neu_adapter_t *adapter);
int neu_metrics_register_entry(const char *name, const char *help,
neu_metric_type_e type);
void neu_metrics_unregister_entry(const char *name);
typedef void (*neu_metrics_cb_t)(const neu_metrics_t *metrics, void *data);
void neu_metrics_visist(neu_metrics_cb_t cb, void *data);
static inline bool neu_metric_type_is_counter(neu_metric_type_e type)
{
return NEU_METRIC_TYPE_COUNTER == (type & NEU_METRIC_TYPE_MASK);
}
static inline bool neu_metric_type_is_rolling_counter(neu_metric_type_e type)
{
return NEU_METRIC_TYPE_ROLLING_COUNTER == (type & NEU_METRIC_TYPE_MASK);
}
static inline bool neu_metric_type_no_reset(neu_metric_type_e type)
{
return NEU_METRIC_TYPE_FLAG_NO_RESET & type;
}
static inline const char *neu_metric_type_str(neu_metric_type_e type)
{
if (NEU_METRIC_TYPE_COUNTER == type) {
if (neu_metric_type_is_counter(type)) {
return "counter";
} else {
return "gauge";
@@ -205,6 +244,9 @@ int neu_metric_entries_add(neu_metric_entry_t **entries, const char *name,
static inline void neu_metric_entry_free(neu_metric_entry_t *entry)
{
if (neu_metric_type_is_rolling_counter(entry->type)) {
neu_rolling_counter_free(entry->rcnt);
}
free(entry);
}
@@ -218,22 +260,41 @@ static inline void neu_group_metrics_free(neu_group_metrics_t *group_metrics)
HASH_ITER(hh, group_metrics->entries, e, tmp)
{
HASH_DEL(group_metrics->entries, e);
neu_metrics_unregister_entry(e->name);
neu_metric_entry_free(e);
}
free(group_metrics->name);
free(group_metrics);
}
static inline neu_node_metrics_t *
neu_node_metrics_new(neu_adapter_t *adapter, neu_node_type_e type, char *name)
{
neu_node_metrics_t *node_metrics =
(neu_node_metrics_t *) calloc(1, sizeof(*node_metrics));
if (NULL != node_metrics) {
pthread_mutex_init(&node_metrics->lock, NULL);
node_metrics->type = type;
node_metrics->name = name;
node_metrics->adapter = adapter;
// neu_metrics_add_node(adapter);
}
return node_metrics;
}
static inline void neu_node_metrics_free(neu_node_metrics_t *node_metrics)
{
if (NULL == node_metrics) {
return;
}
pthread_mutex_destroy(&node_metrics->lock);
neu_metric_entry_t *e = NULL, *etmp = NULL;
HASH_ITER(hh, node_metrics->entries, e, etmp)
{
HASH_DEL(node_metrics->entries, e);
neu_metrics_unregister_entry(e->name);
neu_metric_entry_free(e);
}
@@ -247,15 +308,152 @@ static inline void neu_node_metrics_free(neu_node_metrics_t *node_metrics)
free(node_metrics);
}
void neu_metrics_init();
void neu_metrics_add_node(const neu_adapter_t *adapter);
void neu_metrics_del_node(const neu_adapter_t *adapter);
int neu_metrics_register_entry(const char *name, const char *help,
neu_metric_type_e type);
void neu_metrics_unregister_entry(const char *name);
static inline int neu_node_metrics_add(neu_node_metrics_t *node_metrics,
const char *group_name, const char *name,
const char *help, neu_metric_type_e type,
uint64_t init)
{
int rv = 0;
typedef void (*neu_metrics_cb_t)(const neu_metrics_t *metrics, void *data);
void neu_metrics_visist(neu_metrics_cb_t cb, void *data);
if (0 > neu_metrics_register_entry(name, help, type)) {
return -1;
}
pthread_mutex_lock(&node_metrics->lock);
if (NULL == group_name) {
rv = neu_metric_entries_add(&node_metrics->entries, name, help, type,
init);
} else {
neu_group_metrics_t *group_metrics = NULL;
HASH_FIND_STR(node_metrics->group_metrics, group_name, group_metrics);
if (NULL != group_metrics) {
rv = neu_metric_entries_add(&group_metrics->entries, name, help,
type, init);
} else {
group_metrics =
(neu_group_metrics_t *) calloc(1, sizeof(*group_metrics));
if (NULL != group_metrics &&
NULL != (group_metrics->name = strdup(group_name))) {
HASH_ADD_STR(node_metrics->group_metrics, name, group_metrics);
rv = neu_metric_entries_add(&group_metrics->entries, name, help,
type, init);
} else {
free(group_metrics);
rv = -1;
}
}
}
pthread_mutex_unlock(&node_metrics->lock);
if (0 != rv) {
neu_metrics_unregister_entry(name);
}
return rv;
}
static inline int neu_node_metrics_update(neu_node_metrics_t *node_metrics,
const char * group,
const char *metric_name, uint64_t n)
{
neu_metric_entry_t *entry = NULL;
pthread_mutex_lock(&node_metrics->lock);
if (NULL == group) {
HASH_FIND_STR(node_metrics->entries, metric_name, entry);
} else if (NULL != node_metrics->group_metrics) {
neu_group_metrics_t *g = NULL;
HASH_FIND_STR(node_metrics->group_metrics, group, g);
if (NULL != g) {
HASH_FIND_STR(g->entries, metric_name, entry);
}
}
if (NULL == entry) {
pthread_mutex_unlock(&node_metrics->lock);
return -1;
}
if (neu_metric_type_is_counter(entry->type)) {
entry->value += n;
} else if (neu_metric_type_is_rolling_counter(entry->type)) {
entry->value =
neu_rolling_counter_inc(entry->rcnt, global_timestamp, n);
} else {
entry->value = n;
}
pthread_mutex_unlock(&node_metrics->lock);
return 0;
}
static inline void neu_node_metrics_reset(neu_node_metrics_t *node_metrics)
{
neu_metric_entry_t *entry = NULL;
pthread_mutex_lock(&node_metrics->lock);
HASH_LOOP(hh, node_metrics->entries, entry)
{
if (!neu_metric_type_no_reset(entry->type)) {
entry->value = 0;
if (neu_metric_type_is_rolling_counter(entry->type)) {
neu_rolling_counter_reset(entry->rcnt);
}
}
}
neu_group_metrics_t *g = NULL;
HASH_LOOP(hh, node_metrics->group_metrics, g)
{
HASH_LOOP(hh, g->entries, entry)
{
if (!neu_metric_type_no_reset(entry->type)) {
entry->value = 0;
if (neu_metric_type_is_rolling_counter(entry->type)) {
neu_rolling_counter_reset(entry->rcnt);
}
}
}
}
pthread_mutex_unlock(&node_metrics->lock);
}
static inline int
neu_node_metrics_update_group(neu_node_metrics_t *node_metrics,
const char * group_name,
const char * new_group_name)
{
int rv = -1;
neu_group_metrics_t *group_metrics = NULL;
pthread_mutex_lock(&node_metrics->lock);
HASH_FIND_STR(node_metrics->group_metrics, group_name, group_metrics);
if (NULL != group_metrics) {
char *name = strdup(new_group_name);
if (NULL != name) {
HASH_DEL(node_metrics->group_metrics, group_metrics);
free(group_metrics->name);
group_metrics->name = name;
HASH_ADD_STR(node_metrics->group_metrics, name, group_metrics);
rv = 0;
}
}
pthread_mutex_unlock(&node_metrics->lock);
return rv;
}
static inline void neu_node_metrics_del_group(neu_node_metrics_t *node_metrics,
const char * group_name)
{
neu_group_metrics_t *gm = NULL;
pthread_mutex_lock(&node_metrics->lock);
HASH_FIND_STR(node_metrics->group_metrics, group_name, gm);
if (NULL != gm) {
HASH_DEL(node_metrics->group_metrics, gm);
neu_group_metrics_free(gm);
}
pthread_mutex_unlock(&node_metrics->lock);
}
#ifdef __cplusplus
}
+1129
View File
File diff suppressed because it is too large Load Diff
+9 -1
View File
@@ -36,6 +36,14 @@ extern "C" {
#define NEURON_PLUGIN_VER_1_0 100
#define NEURON_PLUGIN_VER_2_0 200
#define NEU_PLUGIN_REGISTER_METRIC(plugin, name, init) \
plugin->common.adapter_callbacks->register_metric( \
plugin->common.adapter, name, name##_HELP, name##_TYPE, init)
#define NEU_PLUGIN_UPDATE_METRIC(plugin, name, val, grp) \
plugin->common.adapter_callbacks->update_metric(plugin->common.adapter, \
name, val, grp)
extern int64_t global_timestamp;
typedef struct neu_plugin_common {
@@ -46,7 +54,6 @@ typedef struct neu_plugin_common {
char name[NEU_NODE_NAME_LEN];
neu_node_link_state_e link_state;
char log_level[NEU_LOG_LEVEL_LEN];
zlog_category_t *log;
} neu_plugin_common_t;
@@ -61,6 +68,7 @@ struct neu_plugin_group {
void * user_data;
neu_plugin_group_free group_free;
uint32_t interval;
};
typedef int (*neu_plugin_tag_validator_t)(const neu_datatag_t *tag);
+5
View File
@@ -44,6 +44,10 @@ typedef enum {
NEU_DATATAG_ENDIAN_BL32 = 5, // #BL 2,1,4,3
NEU_DATATAG_ENDIAN_L64 = 6, // #L 8,7,6,5,4,3,2,1
NEU_DATATAG_ENDIAN_B64 = 7, // #B 1,2,3,4,5,6,7,8
NEU_DATATAG_ENDIAN_LL64 = 8,
NEU_DATATAG_ENDIAN_LB64 = 9,
NEU_DATATAG_ENDIAN_BB64 = 10,
NEU_DATATAG_ENDIAN_BL64 = 11,
} neu_datatag_endian_e;
typedef enum {
@@ -62,6 +66,7 @@ typedef union {
} value32;
struct {
neu_datatag_endian_e endian;
bool is_default;
} value64;
struct {
uint16_t length;
+36
View File
@@ -498,6 +498,42 @@ static inline uint64_t neu_htonll(uint64_t u)
return ret;
}
static inline uint64_t neu_htonlb(uint64_t u)
{
uint8_t *in = (uint8_t *) &u;
uint64_t out = 0;
uint8_t *out_bytes = (uint8_t *) &out;
out_bytes[0] = in[1];
out_bytes[1] = in[0];
out_bytes[2] = in[3];
out_bytes[3] = in[2];
out_bytes[4] = in[5];
out_bytes[5] = in[4];
out_bytes[6] = in[7];
out_bytes[7] = in[6];
return out;
}
static inline uint64_t neu_htonbl(uint64_t u)
{
uint8_t *in = (uint8_t *) &u;
uint64_t out = 0;
uint8_t *out_bytes = (uint8_t *) &out;
out_bytes[0] = in[6];
out_bytes[1] = in[7];
out_bytes[2] = in[4];
out_bytes[3] = in[5];
out_bytes[4] = in[2];
out_bytes[5] = in[3];
out_bytes[6] = in[0];
out_bytes[7] = in[1];
return out;
}
static inline uint64_t neu_ntohll(uint64_t u)
{
return neu_htonll(u);
+70 -42
View File
@@ -21,11 +21,36 @@ config_ **/
#define _NEU_LOG_H_
#include <inttypes.h>
#include <memory.h>
#include "utils/zlog.h"
#include "define.h"
extern zlog_category_t *neuron;
inline static const char *log_level_to_str(int level)
{
switch (level) {
case ZLOG_LEVEL_FATAL:
return NEU_LOG_LEVEL_FATAL;
case ZLOG_LEVEL_ERROR:
return NEU_LOG_LEVEL_ERROR;
case ZLOG_LEVEL_WARN:
return NEU_LOG_LEVEL_WARN;
case ZLOG_LEVEL_NOTICE:
return NEU_LOG_LEVEL_NOTICE;
case ZLOG_LEVEL_INFO:
return NEU_LOG_LEVEL_INFO;
case ZLOG_LEVEL_DEBUG:
return NEU_LOG_LEVEL_DEBUG;
default:
return "UNKNOWN";
}
}
#define nlog_level_change(level) zlog_level_switch(neuron, level)
#define nlog_fatal(...) \
zlog(neuron, __FILE__, sizeof(__FILE__) - 1, __func__, \
sizeof(__func__) - 1, __LINE__, ZLOG_LEVEL_FATAL, __VA_ARGS__)
@@ -64,50 +89,53 @@ extern zlog_category_t *neuron;
zlog((plugin)->common.log, __FILE__, sizeof(__FILE__) - 1, __func__, \
sizeof(__func__) - 1, __LINE__, ZLOG_LEVEL_DEBUG, __VA_ARGS__)
#define plog_send_protocol(plugin, bytes, n_byte) \
uint16_t log_protocol_buf_size = n_byte * 5 + 20; \
char * log_protocol_buf = calloc(log_protocol_buf_size, 1); \
int log_offset = 0; \
uint16_t tmp_n_byte = n_byte; \
log_offset = snprintf(log_protocol_buf, log_protocol_buf_size, ">>(%d)", \
tmp_n_byte); \
for (int i = 0; i < n_byte; i++) { \
log_offset += snprintf(log_protocol_buf + log_offset, \
log_protocol_buf_size - log_offset, \
" 0x%02hhX", (bytes)[i]); \
} \
plog_debug(plugin, "%s", log_protocol_buf); \
free(log_protocol_buf);
enum neu_protocol_log_type {
NEU_PROTOCOL_SEND,
NEU_PROTOCOL_RECV,
};
#define plog_recv_protocol(plugin, bytes, n_byte) \
uint16_t log_protocol_buf_size = n_byte * 5 + 20; \
char * log_protocol_buf = calloc(log_protocol_buf_size, 1); \
int log_offset = 0; \
uint16_t tmp_n_byte = n_byte; \
log_offset = snprintf(log_protocol_buf, log_protocol_buf_size, "<<(%d)", \
tmp_n_byte); \
for (int i = 0; i < n_byte; i++) { \
log_offset += snprintf(log_protocol_buf + log_offset, \
log_protocol_buf_size - log_offset, \
" 0x%02hhX", (bytes)[i]); \
} \
plog_debug(plugin, "%s", log_protocol_buf); \
free(log_protocol_buf);
inline static void zlog_protocol(zlog_category_t *log, uint8_t *bytes,
uint16_t n_byte,
enum neu_protocol_log_type type)
{
static __thread char buf[2048] = { 0 };
int offset = 0;
#define zlog_recv_protocol(log, bytes, n_byte) \
uint16_t log_protocol_buf_size = n_byte * 5 + 20; \
char * log_protocol_buf = calloc(log_protocol_buf_size, 1); \
int log_offset = 0; \
uint16_t tmp_n_byte = n_byte; \
log_offset = snprintf(log_protocol_buf, log_protocol_buf_size, "<<(%d)", \
tmp_n_byte); \
for (int i = 0; i < n_byte; i++) { \
log_offset += snprintf(log_protocol_buf + log_offset, \
log_protocol_buf_size - log_offset, \
" 0x%02hhX", (bytes)[i]); \
} \
zlog_debug(log, "%s", log_protocol_buf); \
free(log_protocol_buf);
memset(buf, 0, sizeof(buf));
if (type == NEU_PROTOCOL_SEND) {
offset = snprintf(buf, sizeof(buf) - 1, ">>(%d)", n_byte);
} else {
offset = snprintf(buf, sizeof(buf) - 1, "<<(%d)", n_byte);
}
for (int i = 0; i < n_byte; i++) {
if (sizeof(buf) > (size_t) offset && sizeof(buf) - offset > 10) {
int s_ret = snprintf(buf + offset, sizeof(buf) - offset - 1,
" 0x%02hhX", bytes[i]);
if (s_ret > 0) {
offset += s_ret;
} else {
break;
}
} else {
break;
}
}
zlog_debug(log, "%s", buf);
}
#define zlog_send_protocol(log, bytes, n_byte) \
zlog_protocol(log, (uint8_t *) bytes, n_byte, NEU_PROTOCOL_SEND)
#define zlog_recv_protocol(log, bytes, n_byte) \
zlog_protocol(log, (uint8_t *) bytes, n_byte, NEU_PROTOCOL_RECV)
#define plog_recv_protocol(plugin, bytes, n_byte) \
zlog_recv_protocol((plugin)->common.log, bytes, n_byte)
#define plog_send_protocol(plugin, bytes, n_byte) \
zlog_send_protocol((plugin)->common.log, bytes, n_byte)
void remove_logs(const char *node);
+115
View File
@@ -0,0 +1,115 @@
/**
* NEURON IIoT System for Industry 4.0
* Copyright (C) 2020-2024 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_UTILS_ROLLING_COUNTER_H
#define NEURON_UTILS_ROLLING_COUNTER_H
#ifdef __cplusplus
extern "C" {
#endif
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
/** Rolling counter.
*
* This counter is for counting values within some latest time span, like
* network bytes sent within the last 5 seconds etc.
*/
typedef struct {
uint64_t val; // accumulator
uint64_t ts; // head time stamp in milliseconds
uint32_t res : 21; // time resolution in milliseconds
uint32_t hd : 5; // head position
uint32_t n : 6; // number of counters
uint32_t counts[]; // bins of counters
} neu_rolling_counter_t;
/** Create rolling counter.
*
* @param span time span in milliseconds
*/
static inline neu_rolling_counter_t *neu_rolling_counter_new(unsigned span)
{
unsigned n = span <= 6000 ? 4 : span <= 32000 ? 8 : span <= 64000 ? 16 : 32;
assert(span / n < (1 << 22)); // should not overflow ti
neu_rolling_counter_t *counter = (neu_rolling_counter_t *) calloc(
1, sizeof(*counter) + sizeof(counter->counts[0]) * n);
if (counter) {
counter->res = span / n;
counter->n = n;
}
return counter;
}
/** Destructs the rolling counter.
*/
static inline void neu_rolling_counter_free(neu_rolling_counter_t *counter)
{
if (counter) {
free(counter);
}
}
/** Increment the rolling counter and return the value;
*
* @param ts time stamp in milliseconds, should be monotonic
* @param dt delta value to increment by
*/
static inline uint64_t neu_rolling_counter_inc(neu_rolling_counter_t *counter,
uint64_t ts, unsigned dt)
{
uint64_t step = (ts - counter->ts) / counter->res;
for (unsigned i = 0; i < step && i < counter->n; ++i) {
counter->hd = (counter->hd + 1) & (counter->n - 1);
counter->val -= counter->counts[counter->hd];
counter->counts[counter->hd] = 0;
}
counter->val += dt;
counter->counts[counter->hd] += dt;
counter->ts += step * counter->res;
return counter->val;
}
/** Reset the counter.
*/
static inline void neu_rolling_counter_reset(neu_rolling_counter_t *counter)
{
counter->val = 0;
counter->hd = 0;
memset(counter->counts, 0, counter->n * sizeof(counter->counts[0]));
}
/** Return the counter value.
*
* NOTE: may return stale value if the counter is not updated frequent enough.
*/
static inline uint64_t neu_rolling_counter_value(neu_rolling_counter_t *counter)
{
return counter->val;
}
#ifdef __cplusplus
}
#endif
#endif
+1
View File
@@ -48,6 +48,7 @@ static inline void *utarray_steal(UT_array *array)
void *data = array->d;
array->i = 0;
array->n = 0;
array->d = NULL;
return data;
}
+11 -15
View File
@@ -185,7 +185,8 @@ int json_decode_write_req(char *buf, size_t len, json_write_req_t **result)
json_obj = neu_json_decode_newb(buf, len);
if (NULL == json_obj) {
goto decode_fail;
free(req);
return -1;
}
neu_json_elem_t req_elems[] = {
@@ -208,27 +209,20 @@ int json_decode_write_req(char *buf, size_t len, json_write_req_t **result)
};
ret = neu_json_decode_by_json(json_obj, NEU_JSON_ELEM_SIZE(req_elems),
req_elems);
if (ret != 0) {
goto decode_fail;
}
req->node_name = req_elems[0].v.val_str;
req->group_name = req_elems[1].v.val_str;
req->tag_name = req_elems[2].v.val_str;
req->t = req_elems[3].t;
req->value = req_elems[3].v;
*result = req;
goto decode_exit;
decode_fail:
free(req);
ret = -1;
decode_exit:
if (json_obj != NULL) {
neu_json_decode_free(json_obj);
if (0 == ret) {
*result = req;
} else {
json_decode_write_req_free(req);
ret = -1;
}
neu_json_decode_free(json_obj);
return ret;
}
@@ -243,6 +237,8 @@ void json_decode_write_req_free(json_write_req_t *req)
free(req->tag_name);
if (req->t == NEU_JSON_STR) {
free(req->value.val_str);
} else if (req->t == NEU_JSON_BYTES) {
free(req->value.val_bytes.bytes);
}
free(req);
+54 -50
View File
@@ -114,10 +114,9 @@ static int ekuiper_plugin_uninit(neu_plugin_t *plugin)
return rv;
}
static int ekuiper_plugin_start(neu_plugin_t *plugin)
static inline int start(neu_plugin_t *plugin, const char *url)
{
int rv = 0;
char *url = plugin->url ? plugin->url : EKUIPER_PLUGIN_URL; // default url
int rv = 0;
rv = nng_pair0_open(&plugin->sock);
if (rv != 0) {
@@ -143,16 +142,43 @@ static int ekuiper_plugin_start(neu_plugin_t *plugin)
return rv;
}
nng_mtx_lock(plugin->mtx);
while (plugin->receiving) {
nng_mtx_unlock(plugin->mtx);
nng_msleep(10);
nng_mtx_lock(plugin->mtx);
}
plugin->receiving = true;
nng_recv_aio(plugin->sock, plugin->recv_aio);
nng_mtx_unlock(plugin->mtx);
return NEU_ERR_SUCCESS;
}
static int ekuiper_plugin_start(neu_plugin_t *plugin)
{
int rv = 0;
char *url = plugin->url ? plugin->url : EKUIPER_PLUGIN_URL; // default url
rv = start(plugin, url);
if (rv != 0) {
return rv;
}
plugin->started = true;
plog_notice(plugin, "start successfully");
return NEU_ERR_SUCCESS;
}
static int ekuiper_plugin_stop(neu_plugin_t *plugin)
static inline void stop(neu_plugin_t *plugin)
{
nng_close(plugin->sock);
}
static int ekuiper_plugin_stop(neu_plugin_t *plugin)
{
stop(plugin);
plugin->started = false;
plog_notice(plugin, "stop successfully");
return NEU_ERR_SUCCESS;
@@ -201,41 +227,6 @@ error:
return -1;
}
static inline int check_url_listenable(neu_plugin_t *plugin, const char *url,
const char *host, uint16_t port)
{
if (NULL != plugin->host && // already configured and
port == plugin->port && // port is the same, then if
(0 == strcmp(plugin->host, host) // 1. host is the same
|| 0 == strcmp("0.0.0.0", host) // 2. to bind to any address
|| 0 == strcmp("0.0.0.0", plugin->host) // 3. bound to any address
)) {
// early return, no need check url is listenable
return 0;
}
nng_socket sock = NNG_SOCKET_INITIALIZER;
int rv = nng_pair0_open(&sock);
if (0 != rv) {
plog_error(plugin, "nng_pair0_open: %s", nng_strerror(rv));
return NEU_ERR_EINTERNAL;
}
if (0 != (rv = nng_listen(sock, url, NULL, 0))) {
plog_error(plugin, "nng_listen: %s", nng_strerror(rv));
if (NNG_EADDRINVAL == rv) {
rv = NEU_ERR_IP_ADDRESS_INVALID;
} else if (NNG_EADDRINUSE == rv) {
rv = NEU_ERR_IP_ADDRESS_IN_USE;
} else {
rv = NEU_ERR_EINTERNAL;
}
}
nng_close(sock);
return rv;
}
static int ekuiper_plugin_config(neu_plugin_t *plugin, const char *setting)
{
int rv = 0;
@@ -255,23 +246,31 @@ static int ekuiper_plugin_config(neu_plugin_t *plugin, const char *setting)
goto error;
}
if (0 != (rv = check_url_listenable(plugin, url, host, port))) {
if (plugin->started) {
stop(plugin);
}
// check we could start the plugin with the new setting
if (0 != (rv = start(plugin, url))) {
// recover with old setting
if (plugin->started && 0 != start(plugin, plugin->url)) {
plog_warn(plugin, "restart host:%s port:%" PRIu16 " fail",
plugin->host, plugin->port);
}
goto error;
}
if (!plugin->started) {
stop(plugin);
}
plog_notice(plugin, "config success");
free(plugin->host);
free(plugin->url);
plugin->host = host;
plugin->port = port;
free(plugin->url);
plugin->url = url;
if (plugin->started) {
// restart service
ekuiper_plugin_stop(plugin);
ekuiper_plugin_start(plugin);
}
plugin->url = url;
return rv;
@@ -310,12 +309,17 @@ static int ekuiper_plugin_request(neu_plugin_t * plugin,
}
break;
}
case NEU_REQRESP_NODE_DELETED: {
break;
}
case NEU_REQ_UPDATE_NODE: {
break;
}
case NEU_REQ_UPDATE_GROUP: {
break;
}
case NEU_REQ_DEL_GROUP:
break;
case NEU_REQ_SUBSCRIBE_GROUP:
case NEU_REQ_UPDATE_SUBSCRIBE_GROUP: {
neu_req_subscribe_t *sub_info = data;
@@ -347,8 +351,8 @@ const neu_plugin_module_t neu_plugin_module = {
.version = NEURON_PLUGIN_VER_1_0,
.schema = "ekuiper",
.module_name = "eKuiper",
.module_descr = "Neuron and LF Edge eKuiper integration plugin",
.module_descr_zh = "Neuron 和 LF Edge eKuiper 一体化插件",
.module_descr = "LF Edge eKuiper integration plugin",
.module_descr_zh = "LF Edge eKuiper 一体化插件",
.intf_funs = &plugin_intf_funs,
.kind = NEU_PLUGIN_KIND_SYSTEM,
.type = NEU_NA_TYPE_APP,
+1
View File
@@ -37,6 +37,7 @@ struct neu_plugin {
nng_socket sock;
nng_mtx * mtx;
bool started;
bool receiving;
nng_aio * recv_aio;
char * host;
uint16_t port;
+11 -3
View File
@@ -86,6 +86,9 @@ void recv_data_callback(void *arg)
rv = nng_aio_result(plugin->recv_aio);
if (0 != rv) {
plog_error(plugin, "nng_recv error: %s", nng_strerror(rv));
nng_mtx_lock(plugin->mtx);
plugin->receiving = false;
nng_mtx_unlock(plugin->mtx);
return;
}
@@ -123,9 +126,9 @@ int write_data(neu_plugin_t *plugin, json_write_req_t *write_req)
header.ctx = NULL;
header.type = NEU_REQ_WRITE_TAG;
strcpy(cmd.driver, write_req->node_name);
strcpy(cmd.group, write_req->group_name);
strcpy(cmd.tag, write_req->tag_name);
cmd.driver = write_req->node_name;
cmd.group = write_req->group_name;
cmd.tag = write_req->tag_name;
switch (write_req->t) {
case NEU_JSON_INT:
@@ -156,5 +159,10 @@ int write_data(neu_plugin_t *plugin, json_write_req_t *write_req)
}
ret = neu_plugin_op(plugin, header, &cmd);
if (0 == ret) {
write_req->node_name = NULL; // ownership moved
write_req->group_name = NULL; // ownership moved
write_req->tag_name = NULL; // ownership moved
}
return ret;
}
+32 -3
View File
@@ -18,11 +18,11 @@
},
{
"type": 7,
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|)$"
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|#BB|#BL|#LL|#LB|)$"
},
{
"type": 8,
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|)$"
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|#BB|#BL|#LL|#LB|)$"
},
{
"type": 9,
@@ -30,7 +30,7 @@
},
{
"type": 10,
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|)$"
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|#BB|#BL|#LL|#LB|)$"
},
{
"type": 11,
@@ -106,6 +106,35 @@
"max": 10000
}
},
"endianess_64": {
"name": "Endianess of 8-Byte Data",
"name_zh": "8 字节数据字节序",
"description": "Tag byte order, applicable to int64, uint64 and double types",
"description_zh": "点位字节序,适用于 int64,uint64 和 double 类型",
"attribute": "required",
"type": "map",
"default": 1,
"valid": {
"map": [
{
"key": "12 34 56 78",
"value": 1
},
{
"key": "21 43 65 87",
"value": 2
},
{
"key": "87 65 43 21",
"value": 3
},
{
"key": "78 56 34 12",
"value": 4
}
]
}
},
"interval": {
"name": "Send Interval",
"name_zh": "指令发送间隔",
+32 -3
View File
@@ -18,11 +18,11 @@
},
{
"type": 7,
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|)$"
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|#BB|#BL|#LL|#LB|)$"
},
{
"type": 8,
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|)$"
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|#BB|#BL|#LL|#LB|)$"
},
{
"type": 9,
@@ -30,7 +30,7 @@
},
{
"type": 10,
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|)$"
"regex": "^[0-9]+![3-4][0-9]+(#B|#L|#BB|#BL|#LL|#LB|)$"
},
{
"type": 11,
@@ -93,6 +93,35 @@
"max": 10000
}
},
"endianess_64": {
"name": "Endianess of 8-Byte Data",
"name_zh": "8 字节数据字节序",
"description": "Tag byte order, applicable to int64, uint64 and double types",
"description_zh": "点位字节序,适用于 int64,uint64 和 double 类型",
"attribute": "required",
"type": "map",
"default": 1,
"valid": {
"map": [
{
"key": "12 34 56 78",
"value": 1
},
{
"key": "21 43 65 87",
"value": 2
},
{
"key": "87 65 43 21",
"value": 3
},
{
"key": "78 56 34 12",
"value": 4
}
]
}
},
"interval": {
"name": "Send Interval",
"name_zh": "指令发送间隔",
+7
View File
@@ -66,6 +66,13 @@ typedef enum modbus_area {
MODBUS_AREA_HOLD_REGISTER = 4,
} modbus_area_e;
typedef enum modbus_endianess_64 {
MODBUS_LL = 1, // 12 34 56 78
MODBUS_LB = 2, // 21 43 65 87
MODBUS_BB = 3, // 87 65 43 21
MODBUS_BL = 4, // 78 56 34 12
} modbus_endianess_64;
struct modbus_header {
uint16_t seq;
uint16_t protocol;
+34 -6
View File
@@ -221,7 +221,8 @@ modbus_read_cmd_sort_t *modbus_tag_sort(UT_array *tags, uint16_t max_byte)
return sort_result;
}
int cal_n_byte(int type, neu_value_u *value, neu_datatag_addr_option_u option)
int cal_n_byte(int type, neu_value_u *value, neu_datatag_addr_option_u option,
modbus_endianess_64 endianess_64, bool default_tag_endian_64)
{
int n = 0;
switch (type) {
@@ -240,6 +241,9 @@ int cal_n_byte(int type, neu_value_u *value, neu_datatag_addr_option_u option)
case NEU_TYPE_DOUBLE:
case NEU_TYPE_INT64:
case NEU_TYPE_UINT64:
if (default_tag_endian_64) {
modbus_convert_endianess_64(value, endianess_64);
}
n = sizeof(uint64_t);
value->u64 = neu_htonll(value->u64);
break;
@@ -273,7 +277,8 @@ int cal_n_byte(int type, neu_value_u *value, neu_datatag_addr_option_u option)
return n;
}
modbus_write_cmd_sort_t *modbus_write_tags_sort(UT_array *tags)
modbus_write_cmd_sort_t *
modbus_write_tags_sort(UT_array *tags, modbus_endianess_64 endianess_64)
{
neu_tag_sort_result_t *result =
neu_tag_sort(tags, tag_sort_write, tag_cmp_write);
@@ -295,14 +300,17 @@ modbus_write_cmd_sort_t *modbus_write_tags_sort(UT_array *tags)
utarray_foreach(result->sorts[i].tags, modbus_point_write_t **, tag_s)
{
if ((*tag_s)->point.area == MODBUS_AREA_COIL) {
n_byte_tag = cal_n_byte((*tag_s)->point.type, &(*tag_s)->value,
(*tag_s)->point.option);
n_byte_tag =
cal_n_byte((*tag_s)->point.type, &(*tag_s)->value,
(*tag_s)->point.option, endianess_64, true);
data_bit[k / 8] += ((*tag_s)->value.i8) << k % 8;
n_byte += n_byte_tag;
k++;
} else {
n_byte_tag = cal_n_byte((*tag_s)->point.type, &(*tag_s)->value,
(*tag_s)->point.option);
n_byte_tag =
cal_n_byte((*tag_s)->point.type, &(*tag_s)->value,
(*tag_s)->point.option, endianess_64,
(*tag_s)->point.option.value64.is_default);
memcpy(sort_result->cmd[i].bytes +
2 *
((*tag_s)->point.start_address -
@@ -512,4 +520,24 @@ static bool tag_sort_write(neu_tag_sort_t *sort, void *tag,
}
return true;
}
void modbus_convert_endianess_64(neu_value_u * value,
modbus_endianess_64 endianess_64)
{
switch (endianess_64) {
case MODBUS_LL:
break;
case MODBUS_BB:
value->u64 = neu_htonll(value->u64);
break;
case MODBUS_LB:
value->u64 = neu_htonlb(value->u64);
break;
case MODBUS_BL:
value->u64 = neu_htonbl(value->u64);
break;
default:
break;
}
}
+7 -3
View File
@@ -79,9 +79,13 @@ typedef struct modbus_write_cmd_sort {
modbus_write_cmd_t *cmd;
} modbus_write_cmd_sort_t;
modbus_read_cmd_sort_t * modbus_tag_sort(UT_array *tags, uint16_t max_byte);
modbus_write_cmd_sort_t *modbus_write_tags_sort(UT_array *tags);
void modbus_tag_sort_free(modbus_read_cmd_sort_t *cs);
modbus_read_cmd_sort_t *modbus_tag_sort(UT_array *tags, uint16_t max_byte);
modbus_write_cmd_sort_t *
modbus_write_tags_sort(UT_array *tags, modbus_endianess_64 endianess_64);
void modbus_tag_sort_free(modbus_read_cmd_sort_t *cs);
void modbus_convert_endianess_64(neu_value_u * value,
modbus_endianess_64 endianess_64);
#ifdef __cplusplus
}
+9 -2
View File
@@ -402,6 +402,10 @@ int modbus_value_handle(void *ctx, uint8_t slave_id, uint16_t n_byte,
case NEU_TYPE_DOUBLE:
case NEU_TYPE_INT64:
case NEU_TYPE_UINT64:
if ((*p_tag)->option.value64.is_default) {
modbus_convert_endianess_64(&dvalue.value,
plugin->endianess_64);
}
dvalue.value.u64 = neu_ntohll(dvalue.value.u64);
break;
case NEU_TYPE_BIT: {
@@ -476,6 +480,9 @@ int modbus_write(neu_plugin_t *plugin, void *req, neu_datatag_t *tag,
case NEU_TYPE_DOUBLE:
case NEU_TYPE_INT64:
case NEU_TYPE_UINT64:
if (tag->option.value64.is_default) {
modbus_convert_endianess_64(&value, plugin->endianess_64);
}
value.u64 = neu_htonll(value.u64);
n_byte = sizeof(uint64_t);
break;
@@ -543,7 +550,7 @@ int modbus_write_tags(neu_plugin_t *plugin, void *req, UT_array *tags)
utarray_push_back(gtags->tags, &p);
}
gtags->cmd_sort = modbus_write_tags_sort(gtags->tags);
gtags->cmd_sort = modbus_write_tags_sort(gtags->tags, plugin->endianess_64);
for (uint16_t i = 0; i < gtags->cmd_sort->n_cmd; i++) {
uint16_t response_size = 0;
@@ -698,7 +705,7 @@ static int process_protocol_buf(neu_plugin_t *plugin, uint8_t slave_id,
plog_recv_protocol(plugin, recv_buf, ret);
}
neu_protocol_unpack_buf_init(&pbuf, recv_buf, ret);
int ret_s = modbus_stack_recv(plugin->stack, 0, &pbuf);
int ret_s = modbus_stack_recv(plugin->stack, slave_id, &pbuf);
if (ret_s == MODBUS_DEVICE_ERR) {
ret = ret_s;
} else {
+2
View File
@@ -43,6 +43,8 @@ struct neu_plugin {
uint16_t interval;
uint16_t retry_interval;
uint16_t max_retries;
modbus_endianess_64 endianess_64;
};
void modbus_conn_connected(void *data, int fd);
+10
View File
@@ -167,6 +167,9 @@ static int driver_config(neu_plugin_t *plugin, const char *config)
neu_json_elem_t retry_interval = { .name = "retry_interval",
.t = NEU_JSON_INT };
neu_json_elem_t endianess_64 = { .name = "endianess_64",
.t = NEU_JSON_INT };
ret = neu_parse_param((char *) config, &err_param, 3, &link, &timeout,
&interval);
if (ret != 0) {
@@ -206,9 +209,16 @@ static int driver_config(neu_plugin_t *plugin, const char *config)
retry_interval.v.val_int = 0;
}
ret = neu_parse_param((char *) config, &err_param, 1, &endianess_64);
if (ret != 0) {
free(err_param);
endianess_64.v.val_int = MODBUS_LL;
}
param.log = plugin->common.log;
plugin->max_retries = max_retries.v.val_int;
plugin->retry_interval = retry_interval.v.val_int;
plugin->endianess_64 = endianess_64.v.val_int;
if (link.v.val_int == 0) {
param.type = NEU_CONN_TTY_CLIENT;
+30 -14
View File
@@ -84,10 +84,8 @@ int modbus_stack_recv(modbus_stack_t *stack, uint8_t slave_id,
return -1;
}
if (stack->protocol == MODBUS_PROTOCOL_TCP) {
if (code.slave_id != slave_id) {
return -1;
}
if (code.slave_id != slave_id) {
return -1;
}
switch (code.function) {
@@ -102,18 +100,36 @@ int modbus_stack_recv(modbus_stack_t *stack, uint8_t slave_id,
return -1;
}
if (stack->protocol == MODBUS_PROTOCOL_TCP && data.n_byte == 0xff) {
bytes = neu_protocol_unpack_buf(buf,
header.len -
sizeof(struct modbus_code) -
sizeof(struct modbus_data));
stack->value_fn(stack->ctx, code.slave_id,
header.len - sizeof(struct modbus_code) -
sizeof(struct modbus_data),
bytes, 0);
} else {
switch (stack->protocol) {
case MODBUS_PROTOCOL_TCP:
if (data.n_byte == 0xff) {
bytes = neu_protocol_unpack_buf(buf,
header.len -
sizeof(struct modbus_code) -
sizeof(struct modbus_data));
if (bytes == NULL) {
return -1;
}
stack->value_fn(stack->ctx, code.slave_id,
header.len - sizeof(struct modbus_code) -
sizeof(struct modbus_data),
bytes, 0);
} else {
bytes = neu_protocol_unpack_buf(buf, data.n_byte);
if (bytes == NULL) {
return -1;
}
stack->value_fn(stack->ctx, code.slave_id, data.n_byte, bytes,
0);
}
break;
case MODBUS_PROTOCOL_RTU:
bytes = neu_protocol_unpack_buf(buf, data.n_byte);
if (bytes == NULL) {
return -1;
}
stack->value_fn(stack->ctx, code.slave_id, data.n_byte, bytes, 0);
break;
}
break;
+9
View File
@@ -158,6 +158,8 @@ static int driver_config(neu_plugin_t *plugin, const char *config)
neu_json_elem_t max_retries = { .name = "max_retries", .t = NEU_JSON_INT };
neu_json_elem_t retry_interval = { .name = "retry_interval",
.t = NEU_JSON_INT };
neu_json_elem_t endianess_64 = { .name = "endianess_64",
.t = NEU_JSON_INT };
ret = neu_parse_param((char *) config, &err_param, 5, &port, &host, &mode,
&timeout, &interval);
@@ -186,10 +188,17 @@ static int driver_config(neu_plugin_t *plugin, const char *config)
retry_interval.v.val_int = 0;
}
ret = neu_parse_param((char *) config, &err_param, 1, &endianess_64);
if (ret != 0) {
free(err_param);
endianess_64.v.val_int = MODBUS_LL;
}
param.log = plugin->common.log;
plugin->interval = interval.v.val_int;
plugin->max_retries = max_retries.v.val_int;
plugin->retry_interval = retry_interval.v.val_int;
plugin->endianess_64 = endianess_64.v.val_int;
if (mode.v.val_int == 1) {
param.type = NEU_CONN_TCP_SERVER;
+2 -2
View File
@@ -402,7 +402,7 @@ static const neu_plugin_intf_funs_t plugin_intf_funs = {
#define DEFAULT_MONITOR_PLUGIN_DESCR \
"Builtin plugin for Neuron monitoring and alerting"
#define DEFAULT_MONITOR_PLUGIN_DESCR_ZH "Neuron内置监控与告警插件"
#define DEFAULT_MONITOR_PLUGIN_DESCR_ZH "内置监控与告警插件"
const neu_plugin_module_t neu_plugin_module = {
.version = NEURON_PLUGIN_VER_1_0,
@@ -414,7 +414,7 @@ const neu_plugin_module_t neu_plugin_module = {
.kind = NEU_PLUGIN_KIND_SYSTEM,
.type = NEU_NA_TYPE_APP,
.display = true,
.single = false,
.single = true,
.single_name = "monitor",
};
+1
View File
@@ -401,6 +401,7 @@ int mqtt_config_parse(neu_plugin_t *plugin, const char *setting,
error:
free(err_param);
free(client_id.v.val_str);
free(write_req_topic.v.val_str);
free(write_resp_topic.v.val_str);
free(host.v.val_str);
+63 -61
View File
@@ -138,10 +138,13 @@ static inline int send_read_req(neu_plugin_t *plugin, neu_json_mqtt_t *mqtt,
header.ctx = mqtt;
header.type = NEU_REQ_READ_GROUP;
neu_req_read_group_t cmd = { 0 };
strcpy(cmd.driver, req->node);
strcpy(cmd.group, req->group);
cmd.sync = req->sync;
cmd.driver = req->node;
cmd.group = req->group;
cmd.sync = req->sync;
req->node = NULL; // ownership moved
req->group = NULL; // ownership moved
if (0 != neu_plugin_op(plugin, header, &cmd)) {
neu_req_read_group_fini(&cmd);
plog_error(plugin, "neu_plugin_op(NEU_REQ_READ_GROUP) fail");
return -1;
}
@@ -149,6 +152,38 @@ static inline int send_read_req(neu_plugin_t *plugin, neu_json_mqtt_t *mqtt,
return 0;
}
static int json_value_to_tag_value(union neu_json_value *req,
enum neu_json_type t, neu_dvalue_t *value)
{
switch (t) {
case NEU_JSON_INT:
value->type = NEU_TYPE_INT64;
value->value.u64 = req->val_int;
break;
case NEU_JSON_STR:
value->type = NEU_TYPE_STRING;
strncpy(value->value.str, req->val_str, sizeof(value->value.str));
break;
case NEU_JSON_DOUBLE:
value->type = NEU_TYPE_DOUBLE;
value->value.d64 = req->val_double;
break;
case NEU_JSON_BOOL:
value->type = NEU_TYPE_BOOL;
value->value.boolean = req->val_bool;
break;
case NEU_JSON_BYTES:
value->type = NEU_TYPE_BYTES;
value->value.bytes.length = req->val_bytes.length;
memcpy(value->value.bytes.bytes, req->val_bytes.bytes,
req->val_bytes.length);
break;
default:
return -1;
}
return 0;
}
static int send_write_tag_req(neu_plugin_t *plugin, neu_json_mqtt_t *mqtt,
neu_json_write_req_t *req)
{
@@ -161,34 +196,11 @@ static int send_write_tag_req(neu_plugin_t *plugin, neu_json_mqtt_t *mqtt,
header.ctx = mqtt;
header.type = NEU_REQ_WRITE_TAG;
strcpy(cmd.driver, req->node);
strcpy(cmd.group, req->group);
strcpy(cmd.tag, req->tag);
cmd.driver = req->node;
cmd.group = req->group;
cmd.tag = req->tag;
switch (req->t) {
case NEU_JSON_INT:
cmd.value.type = NEU_TYPE_INT64;
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);
break;
case NEU_JSON_DOUBLE:
cmd.value.type = NEU_TYPE_DOUBLE;
cmd.value.value.d64 = req->value.val_double;
break;
case NEU_JSON_BOOL:
cmd.value.type = NEU_TYPE_BOOL;
cmd.value.value.boolean = req->value.val_bool;
break;
case NEU_JSON_BYTES:
cmd.value.type = NEU_TYPE_BYTES;
cmd.value.value.bytes.length = req->value.val_bytes.length;
memcpy(cmd.value.value.bytes.bytes, req->value.val_bytes.bytes,
req->value.val_bytes.length);
break;
default:
if (0 != json_value_to_tag_value(&req->value, req->t, &cmd.value)) {
plog_error(plugin, "invalid tag value type: %d", req->t);
return -1;
}
@@ -198,6 +210,9 @@ static int send_write_tag_req(neu_plugin_t *plugin, neu_json_mqtt_t *mqtt,
return -1;
}
req->node = NULL; // ownership moved
req->group = NULL; // ownership moved
req->tag = NULL; // ownership moved
return 0;
}
@@ -221,42 +236,19 @@ static int send_write_tags_req(neu_plugin_t *plugin, neu_json_mqtt_t *mqtt,
};
neu_req_write_tags_t cmd = { 0 };
strcpy(cmd.driver, req->node);
strcpy(cmd.group, req->group);
cmd.n_tag = req->n_tag;
cmd.tags = calloc(cmd.n_tag, sizeof(neu_resp_tag_value_t));
cmd.driver = req->node;
cmd.group = req->group;
cmd.n_tag = req->n_tag;
cmd.tags = calloc(cmd.n_tag, sizeof(neu_resp_tag_value_t));
if (NULL == cmd.tags) {
return -1;
}
for (int i = 0; i < cmd.n_tag; i++) {
strcpy(cmd.tags[i].tag, req->tags[i].tag);
switch (req->tags[i].t) {
case NEU_JSON_INT:
cmd.tags[i].value.type = NEU_TYPE_INT64;
cmd.tags[i].value.value.u64 = req->tags[i].value.val_int;
break;
case NEU_JSON_STR:
cmd.tags[i].value.type = NEU_TYPE_STRING;
strcpy(cmd.tags[i].value.value.str, req->tags[i].value.val_str);
break;
case NEU_JSON_DOUBLE:
cmd.tags[i].value.type = NEU_TYPE_DOUBLE;
cmd.tags[i].value.value.d64 = req->tags[i].value.val_double;
break;
case NEU_JSON_BOOL:
cmd.tags[i].value.type = NEU_TYPE_BOOL;
cmd.tags[i].value.value.boolean = req->tags[i].value.val_bool;
break;
case NEU_JSON_BYTES:
cmd.tags[i].value.type = NEU_TYPE_BYTES;
cmd.tags[i].value.value.bytes.length =
req->tags[i].value.val_bytes.length;
memcpy(cmd.tags[i].value.value.bytes.bytes,
req->tags[i].value.val_bytes.bytes,
req->tags[i].value.val_bytes.length);
break;
default:
if (0 !=
json_value_to_tag_value(&req->tags[i].value, req->tags[i].t,
&cmd.tags[i].value)) {
plog_error(plugin, "invalid tag value type: %d", req->tags[i].t);
free(cmd.tags);
return -1;
@@ -269,6 +261,9 @@ static int send_write_tags_req(neu_plugin_t *plugin, neu_json_mqtt_t *mqtt,
return -1;
}
req->node = NULL; // ownership moved
req->group = NULL; // ownership moved
return 0;
}
@@ -481,7 +476,6 @@ int handle_read_response(neu_plugin_t *plugin, neu_json_mqtt_t *mqtt_json,
end:
neu_json_decode_mqtt_req_free(mqtt_json);
free(data->tags);
return rv;
}
@@ -607,6 +601,14 @@ int handle_unsubscribe_group(neu_plugin_t * plugin,
return 0;
}
int handle_del_group(neu_plugin_t *plugin, neu_req_del_group_t *req)
{
route_tbl_del(&plugin->route_tbl, req->driver, req->group);
plog_notice(plugin, "del route driver:%s group:%s", req->driver,
req->group);
return 0;
}
int handle_update_group(neu_plugin_t *plugin, neu_req_update_group_t *req)
{
route_tbl_update_group(&plugin->route_tbl, req->driver, req->group,
+1
View File
@@ -49,6 +49,7 @@ int handle_unsubscribe_group(neu_plugin_t * plugin,
neu_req_unsubscribe_t *unsub_info);
int handle_update_group(neu_plugin_t *plugin, neu_req_update_group_t *req);
int handle_del_group(neu_plugin_t *plugin, neu_req_del_group_t *cmd);
int handle_update_driver(neu_plugin_t *plugin, neu_req_update_node_t *req);
int handle_del_driver(neu_plugin_t *plugin, neu_reqresp_node_deleted_t *req);
+5 -2
View File
@@ -368,6 +368,9 @@ static int mqtt_plugin_request(neu_plugin_t *plugin, neu_reqresp_head_t *head,
case NEU_REQ_UPDATE_GROUP:
error = handle_update_group(plugin, data);
break;
case NEU_REQ_DEL_GROUP:
error = handle_del_group(plugin, data);
break;
case NEU_REQ_UPDATE_NODE:
error = handle_update_driver(plugin, data);
break;
@@ -393,8 +396,8 @@ static const neu_plugin_intf_funs_t plugin_intf_funs = {
.request = mqtt_plugin_request,
};
#define DESCRIPTION "Neuron northbound MQTT plugin bases on NanoSDK."
#define DESCRIPTION_ZH "基于 NanoSDK 的 Neuron 北向应用 MQTT 插件"
#define DESCRIPTION "Northbound MQTT plugin bases on NanoSDK."
#define DESCRIPTION_ZH "基于 NanoSDK 的北向应用 MQTT 插件"
const neu_plugin_module_t neu_plugin_module = {
.version = NEURON_PLUGIN_VER_1_0,
+8 -7
View File
@@ -330,11 +330,11 @@ void handle_get_node_state_resp(nng_aio *aio, neu_resp_get_node_state_t *state)
neu_json_get_node_state_resp_t res = { 0 };
char * result = NULL;
res.link = state->state.link;
res.running = state->state.running;
res.rtt = state->rtt;
res.log_level = state->state.log_level;
strcpy(res.core_level, state->core_level);
res.link = state->state.link;
res.running = state->state.running;
res.rtt = state->rtt;
res.log_level = (char *) log_level_to_str(state->state.log_level);
res.core_level = (char *) log_level_to_str(state->core_level);
neu_json_encode_by_fn(&res, neu_json_encode_get_node_state_resp, &result);
@@ -359,10 +359,11 @@ void handle_get_nodes_state_resp(nng_aio * aio,
states_res.nodes[index].running = state->state.running;
states_res.nodes[index].link = state->state.link;
states_res.nodes[index].rtt = state->rtt;
states_res.nodes[index].log_level = state->state.log_level;
states_res.nodes[index].log_level =
(char *) log_level_to_str(state->state.log_level);
}
strcpy(states_res.core_level, states->core_level);
states_res.core_level = (char *) log_level_to_str(states->core_level);
neu_json_encode_by_fn(&states_res, neu_json_encode_get_nodes_state_resp,
&result);
-191
View File
@@ -1,191 +0,0 @@
/**
* NEURON IIoT System for Industry 4.0
* Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <nng/nng.h>
#include <nng/supplemental/http/http.h>
#include "define.h"
#include "handle.h"
#include "utils/http.h"
#include "plugin.h"
#include "utils/log.h"
#include "json/neu_json_error.h"
#include "json/neu_json_fn.h"
#include "file_handle.h"
#include "log_handle.h"
#include "parser/neu_json_file.h"
void handle_file_info(nng_aio *aio)
{
char dir_path[128] = { 0 };
int n_file = 0;
struct dirent *files = { 0 };
char * f_name[256] = { 0 };
char c_time[32] = { 0 };
char m_time[32] = { 0 };
neu_json_get_file_list_resp_t file_resp = { 0 };
char * result = NULL;
NEU_VALIDATE_JWT(aio);
if (neu_http_get_param_str(aio, "dir_path", dir_path, sizeof(dir_path)) <=
0) {
NEU_JSON_RESPONSE_ERROR(NEU_ERR_PARAM_IS_WRONG, {
neu_http_response(aio, error_code.error, result_error);
});
return;
}
/*check whether the directory exists*/
if (0 != access(dir_path, F_OK)) {
NEU_JSON_RESPONSE_ERROR(NEU_ERR_FILE_NOT_EXIST, {
neu_http_response(aio, error_code.error, result_error);
});
return;
}
/*open directory*/
DIR *dir = opendir(dir_path);
if (dir == NULL) {
nlog_error("open a directory failed");
NEU_JSON_RESPONSE_ERROR(NEU_ERR_FILE_OPEN_FAILURE, {
neu_http_response(aio, error_code.error, result_error);
});
return;
}
/*read directory*/
while ((files = readdir(dir)) != NULL) {
if (strcmp(files->d_name, ".") == 0 ||
strcmp(files->d_name, "..") == 0) {
continue;
}
f_name[n_file] = files->d_name;
++n_file;
}
/*handle response*/
file_resp.n_file = n_file;
file_resp.file = calloc(file_resp.n_file, sizeof(neu_json_get_file_resp_t));
for (int i = 0; i < file_resp.n_file; i++) {
char file_path[512] = { 0 };
struct stat statbuf;
sprintf(file_path, "%s/%s", dir_path, f_name[i]);
stat(file_path, &statbuf);
strncpy(c_time, ctime(&statbuf.st_ctim.tv_sec),
strlen(ctime(&statbuf.st_ctim.tv_sec)) - 1);
strncpy(m_time, ctime(&statbuf.st_mtim.tv_sec),
strlen(ctime(&statbuf.st_mtim.tv_sec)) - 1);
file_resp.file[i].name = f_name[i];
file_resp.file[i].size = statbuf.st_size;
file_resp.file[i].ctime = c_time;
file_resp.file[i].mtime = m_time;
}
neu_json_encode_by_fn(&file_resp, neu_json_encode_get_file_list_resp,
&result);
closedir(dir);
neu_http_ok(aio, result);
free(result);
free(file_resp.file);
return;
}
void handle_download_file(nng_aio *aio)
{
char file_name[NEU_FILE_PATH_LEN] = { 0 };
char file_path[256] = { 0 };
char http_resp[256] = { 0 };
int rv = 0;
void * file_data = NULL;
size_t file_len = 0;
char * p = NULL;
NEU_VALIDATE_JWT(aio);
if (neu_http_get_param_str(aio, "file_path", file_path,
sizeof(file_path)) <= 0) {
NEU_JSON_RESPONSE_ERROR(NEU_ERR_PARAM_IS_WRONG, {
neu_http_response(aio, error_code.error, result_error);
});
return;
}
/*check whether the file exists*/
rv = access(file_path, F_OK);
if (0 != rv) {
NEU_JSON_RESPONSE_ERROR(NEU_ERR_FILE_NOT_EXIST, {
neu_http_response(aio, error_code.error, result_error);
});
return;
}
/*read file content*/
rv = read_file(file_path, &file_data, &file_len);
if (0 != rv) {
NEU_JSON_RESPONSE_ERROR(
rv, { neu_http_response(aio, error_code.error, result_error); });
return;
}
/*extract file name*/
p = strchr(file_path, '/');
while (strchr(p, '/') != NULL) {
p = strchr(p, '/') + 1;
}
if (p != NULL) {
strcpy(file_name, p);
}
/*handle http response*/
sprintf(http_resp, "%s%s", "attachment; filename=", file_name);
rv = neu_http_response_file(aio, file_data, file_len, http_resp);
free(file_data);
nlog_notice("download file %s, rv: %d", file_name, rv);
}
-19
View File
@@ -26,7 +26,6 @@
#include "adapter_handle.h"
#include "datatag_handle.h"
#include "file_handle.h"
#include "global_config_handle.h"
#include "group_config_handle.h"
#include "log_handle.h"
@@ -111,12 +110,6 @@ static struct neu_http_handler cors_handler[] = {
{
.url = "/api/v2/log/level",
},
{
.url = "/api/v2/file",
},
{
.url = "/api/v2/file/info",
},
{
.url = "/api/v2/global/config",
},
@@ -377,18 +370,6 @@ static struct neu_http_handler rest_handlers[] = {
.url = "/api/v2/version",
.value.handler = handle_get_version,
},
{
.method = NEU_HTTP_METHOD_GET,
.type = NEU_HTTP_HANDLER_FUNCTION,
.url = "/api/v2/file",
.value.handler = handle_download_file,
},
{
.method = NEU_HTTP_METHOD_GET,
.type = NEU_HTTP_HANDLER_FUNCTION,
.url = "/api/v2/file/info",
.value.handler = handle_file_info,
},
{
.method = NEU_HTTP_METHOD_GET,
.type = NEU_HTTP_HANDLER_FUNCTION,
+21 -51
View File
@@ -113,78 +113,48 @@ void handle_log_level(nng_aio *aio)
NEU_PROCESS_HTTP_REQUEST_VALIDATE_JWT(
aio, neu_json_update_log_level_req_t,
neu_json_decode_update_log_level_req, {
int ret = 0;
neu_reqresp_head_t header = { 0 };
neu_req_update_log_level_t cmd = { 0 };
int log_level;
neu_reqresp_head_t header = { 0 };
neu_req_update_log_level_t cmd = { 0 };
int log_level = -1;
if (0 == strcmp(req->log_level, NEU_LOG_LEVEL_DEBUG)) {
log_level = ZLOG_LEVEL_DEBUG;
strcpy(cmd.log_level, NEU_LOG_LEVEL_DEBUG);
} else if (0 == strcmp(req->log_level, NEU_LOG_LEVEL_INFO)) {
log_level = ZLOG_LEVEL_INFO;
strcpy(cmd.log_level, NEU_LOG_LEVEL_INFO);
} else if (0 == strcmp(req->log_level, NEU_LOG_LEVEL_NOTICE)) {
log_level = ZLOG_LEVEL_NOTICE;
strcpy(cmd.log_level, NEU_LOG_LEVEL_NOTICE);
} else if (0 == strcmp(req->log_level, NEU_LOG_LEVEL_WARN)) {
log_level = ZLOG_LEVEL_WARN;
strcpy(cmd.log_level, NEU_LOG_LEVEL_WARN);
} else if (0 == strcmp(req->log_level, NEU_LOG_LEVEL_ERROR)) {
log_level = ZLOG_LEVEL_ERROR;
strcpy(cmd.log_level, NEU_LOG_LEVEL_ERROR);
} else if (0 == strcmp(req->log_level, NEU_LOG_LEVEL_FATAL)) {
log_level = ZLOG_LEVEL_FATAL;
strcpy(cmd.log_level, NEU_LOG_LEVEL_FATAL);
} else {
strcpy(cmd.log_level, "unknow");
nlog_error(
"Failed to modify log_level of the node, node_name:%s, ",
req->node_name);
nlog_error("Failed to modify log_level of the node, "
"node_name:%s, log_level: %s",
req->node_name, req->log_level);
}
if (log_level == -1) {
NEU_JSON_RESPONSE_ERROR(NEU_ERR_PARAM_IS_WRONG, {
neu_http_response(aio, error_code.error, result_error);
});
goto end;
}
if (req->core) {
zlog_category_t *neuron = zlog_get_category("neuron");
ret = zlog_level_switch(neuron, log_level);
} else {
header.ctx = aio;
header.type = NEU_REQ_UPDATE_LOG_LEVEL;
cmd.core = req->core;
cmd.log_level = log_level;
if (req->node_name != NULL) {
strcpy(cmd.node, req->node_name);
}
int ret = neu_plugin_op(plugin, header, &cmd);
if (ret != 0) {
nlog_error(
"Failed to modify log_level of the core, ret: %d", ret);
NEU_JSON_RESPONSE_ERROR(NEU_ERR_EINTERNAL, {
neu_http_response(aio, error_code.error, result_error);
NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, {
neu_http_response(aio, NEU_ERR_IS_BUSY, result_error);
});
goto end;
}
}
if (req->node_name) {
zlog_category_t *ct = zlog_get_category(req->node_name);
strcpy(cmd.node, req->node_name);
ret = zlog_level_switch(ct, log_level);
if (ret != 0) {
nlog_error(
"Failed to modify log_level of the node, node_name:%s, "
"ret: %d,",
req->node_name, ret);
NEU_JSON_RESPONSE_ERROR(0, {
neu_http_response(aio, error_code.error, result_error);
});
goto end;
}
}
header.ctx = aio;
header.type = NEU_REQ_UPDATE_LOG_LEVEL;
cmd.core = req->core;
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);
});
}
end:;
})
}
+31 -4
View File
@@ -19,8 +19,11 @@
#include <stdio.h>
#include <pthread.h>
#include "define.h"
#include "metrics.h"
#include "plugin.h"
#include "utils/asprintf.h"
#include "utils/http.h"
#include "utils/http_handler.h"
@@ -155,8 +158,8 @@ static inline void gen_global_metrics(const neu_metrics_t *metrics,
metrics->south_disconnected_nodes);
}
static inline void
gen_single_node_metrics(const neu_node_metrics_t *node_metrics, FILE *stream)
static inline void gen_single_node_metrics(neu_node_metrics_t *node_metrics,
FILE * stream)
{
fprintf(stream,
"# HELP node_type Driver(1) or APP(2)\n"
@@ -166,8 +169,13 @@ gen_single_node_metrics(const neu_node_metrics_t *node_metrics, FILE *stream)
neu_metric_entry_t *e = NULL;
pthread_mutex_lock(&node_metrics->lock);
HASH_LOOP(hh, node_metrics->entries, e)
{
if (neu_metric_type_is_rolling_counter(e->type)) {
// force clean stale value
e->value = neu_rolling_counter_inc(e->rcnt, global_timestamp, 0);
}
fprintf(stream,
"# HELP %s %s\n# TYPE %s %s\n%s{node=\"%s\"} %" PRIu64 "\n",
e->name, e->help, e->name, neu_metric_type_str(e->type),
@@ -179,6 +187,11 @@ gen_single_node_metrics(const neu_node_metrics_t *node_metrics, FILE *stream)
{
HASH_LOOP(hh, g->entries, e)
{
if (neu_metric_type_is_rolling_counter(e->type)) {
// force clean stale value
e->value =
neu_rolling_counter_inc(e->rcnt, global_timestamp, 0);
}
fprintf(stream,
"# HELP %s %s\n# TYPE %s %s\n%s{node=\"%s\",group=\"%s\"} "
"%" PRIu64 "\n",
@@ -186,6 +199,7 @@ gen_single_node_metrics(const neu_node_metrics_t *node_metrics, FILE *stream)
e->name, node_metrics->name, g->name, e->value);
}
}
pthread_mutex_unlock(&node_metrics->lock);
}
static inline bool has_entry(neu_node_metrics_t *node_metrics, const char *name)
@@ -207,7 +221,7 @@ static inline bool has_entry(neu_node_metrics_t *node_metrics, const char *name)
return false;
}
static void gen_all_node_metrics(const neu_metrics_t *metrics, int type_filter,
static void gen_all_node_metrics(neu_metrics_t *metrics, int type_filter,
FILE *stream)
{
neu_metric_entry_t * e = NULL, *r = NULL;
@@ -252,11 +266,18 @@ static void gen_all_node_metrics(const neu_metrics_t *metrics, int type_filter,
r->help, r->name, neu_metric_type_str(r->type));
}
pthread_mutex_lock(&n->lock);
HASH_FIND_STR(n->entries, r->name, e);
if (e) {
if (neu_metric_type_is_rolling_counter(e->type)) {
// force clean stale value
e->value =
neu_rolling_counter_inc(e->rcnt, global_timestamp, 0);
}
fprintf(stream, "%s{node=\"%s\"} %" PRIu64 "\n", e->name,
n->name, e->value);
pthread_mutex_unlock(&n->lock);
continue;
}
@@ -264,11 +285,17 @@ static void gen_all_node_metrics(const neu_metrics_t *metrics, int type_filter,
{
HASH_FIND_STR(g->entries, r->name, e);
if (e) {
if (neu_metric_type_is_rolling_counter(e->type)) {
// force clean stale value
e->value = neu_rolling_counter_inc(e->rcnt,
global_timestamp, 0);
}
fprintf(stream,
"%s{node=\"%s\",group=\"%s\"} %" PRIu64 "\n",
e->name, n->name, g->name, e->value);
}
}
pthread_mutex_unlock(&n->lock);
}
}
}
@@ -280,7 +307,7 @@ struct context {
const char *node;
};
static void gen_node_metrics(const neu_metrics_t *metrics, struct context *ctx)
static void gen_node_metrics(neu_metrics_t *metrics, struct context *ctx)
{
if (ctx->node[0]) {
neu_node_metrics_t *n = NULL;
+4 -4
View File
@@ -58,7 +58,7 @@ void handle_login(nng_aio *aio)
if (NULL == user) {
nlog_error("could not find user `%s`", req->name);
NEU_JSON_RESPONSE_ERROR(NEU_ERR_INVALID_USER, {
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 ||
@@ -90,7 +90,7 @@ void handle_login(nng_aio *aio)
free(result);
} else {
nlog_error("user `%s` password check fail", req->name);
NEU_JSON_RESPONSE_ERROR(NEU_ERR_INVALID_PASSWORD, {
NEU_JSON_RESPONSE_ERROR(NEU_ERR_INVALID_USER_OR_PASSWORD, {
neu_http_response(aio, error_code.error, result_error);
});
}
@@ -114,10 +114,10 @@ void handle_password(nng_aio *aio)
rv = NEU_ERR_INVALID_PASSWORD_LEN;
} else if (NULL == (user = neu_load_user(req->name))) {
nlog_error("could not find user `%s`", req->name);
rv = NEU_ERR_INVALID_USER;
rv = NEU_ERR_INVALID_USER_OR_PASSWORD;
} else if (!neu_user_check_password(user, req->old_pass)) {
nlog_error("user `%s` password check fail", req->name);
rv = NEU_ERR_INVALID_PASSWORD;
rv = NEU_ERR_INVALID_USER_OR_PASSWORD;
} else if (0 !=
(rv = neu_user_update_password(user, req->new_pass))) {
nlog_error("user `%s` update password fail", req->name);
+1 -1
View File
@@ -40,7 +40,7 @@ void handle_add_plugin(nng_aio *aio)
header.ctx = aio;
header.type = NEU_REQ_ADD_PLUGIN;
strcpy(cmd.library, req->library);
strncpy(cmd.library, req->library, NEU_PLUGIN_LIBRARY_LEN);
ret = neu_plugin_op(plugin, header, &cmd);
if (ret != 0) {
NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, {
+27 -14
View File
@@ -41,11 +41,14 @@ void handle_read(nng_aio *aio)
header.ctx = aio;
header.type = NEU_REQ_READ_GROUP;
strcpy(cmd.driver, req->node);
strcpy(cmd.group, req->group);
cmd.sync = req->sync;
ret = neu_plugin_op(plugin, header, &cmd);
cmd.driver = req->node;
cmd.group = req->group;
cmd.sync = req->sync;
req->node = NULL;
req->group = NULL;
ret = neu_plugin_op(plugin, header, &cmd);
if (ret != 0) {
neu_req_read_group_fini(&cmd);
NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, {
neu_http_response(aio, NEU_ERR_IS_BUSY, result_error);
});
@@ -87,9 +90,12 @@ void handle_write(nng_aio *aio)
header.ctx = aio;
header.type = NEU_REQ_WRITE_TAG;
strcpy(cmd.driver, req->node);
strcpy(cmd.group, req->group);
strcpy(cmd.tag, req->tag);
cmd.driver = req->node;
cmd.group = req->group;
cmd.tag = req->tag;
req->node = NULL; // ownership moved
req->group = NULL; // ownership moved
req->tag = NULL; // ownership moved
switch (req->t) {
case NEU_JSON_INT:
@@ -121,6 +127,7 @@ void handle_write(nng_aio *aio)
int ret = neu_plugin_op(plugin, header, &cmd);
if (ret != 0) {
neu_req_write_tag_fini(&cmd);
NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, {
neu_http_response(aio, NEU_ERR_IS_BUSY, result_error);
});
@@ -155,17 +162,19 @@ void handle_write_tags(nng_aio *aio)
header.ctx = aio;
header.type = NEU_REQ_WRITE_TAGS;
strcpy(cmd.driver, req->node);
strcpy(cmd.group, req->group);
cmd.n_tag = req->n_tag;
cmd.tags = calloc(cmd.n_tag, sizeof(neu_resp_tag_value_t));
cmd.driver = req->node;
cmd.group = req->group;
cmd.n_tag = req->n_tag;
cmd.tags = calloc(cmd.n_tag, sizeof(neu_resp_tag_value_t));
req->node = NULL; // ownership moved
req->group = NULL; // ownership moved
for (int i = 0; i < cmd.n_tag; i++) {
strcpy(cmd.tags[i].tag, req->tags[i].tag);
switch (req->tags[i].t) {
case NEU_JSON_INT:
cmd.tags[i].value.type = NEU_TYPE_INT64;
cmd.tags[i].value.value.u64 = req->tags[i].value.val_int;
cmd.tags[i].value.value.i64 = req->tags[i].value.val_int;
break;
case NEU_JSON_STR:
cmd.tags[i].value.type = NEU_TYPE_STRING;
@@ -197,6 +206,7 @@ void handle_write_tags(nng_aio *aio)
int ret = neu_plugin_op(plugin, header, &cmd);
if (ret != 0) {
neu_req_write_tags_fini(&cmd);
NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, {
neu_http_response(aio, NEU_ERR_IS_BUSY, result_error);
});
@@ -206,11 +216,13 @@ void handle_write_tags(nng_aio *aio)
static void trans(neu_json_write_gtags_req_t *req, neu_req_write_gtags_t *cmd)
{
strcpy(cmd->driver, req->node);
cmd->driver = req->node;
req->node = NULL; // ownership moved
cmd->n_group = req->n_group;
cmd->groups = calloc(cmd->n_group, sizeof(neu_req_gtag_group_t));
for (int i = 0; i < cmd->n_group; i++) {
strcpy(cmd->groups[i].group, req->groups[i].group);
cmd->groups[i].group = req->groups[i].group;
req->groups[i].group = NULL; // ownership moved
cmd->groups[i].n_tag = req->groups[i].n_tag;
cmd->groups[i].tags =
calloc(cmd->groups[i].n_tag, sizeof(neu_resp_tag_value_t));
@@ -274,6 +286,7 @@ void handle_write_gtags(nng_aio *aio)
int ret = neu_plugin_op(plugin, header, &cmd);
if (ret != 0) {
neu_req_write_gtags_fini(&cmd);
NEU_JSON_RESPONSE_ERROR(NEU_ERR_IS_BUSY, {
neu_http_response(aio, NEU_ERR_IS_BUSY, result_error);
});
+189 -461
View File
File diff suppressed because it is too large Load Diff
+12 -5
View File
@@ -26,6 +26,7 @@
#include "adapter_info.h"
#include "core/manager.h"
#include "msg_q.h"
struct neu_adapter {
char *name;
@@ -33,23 +34,21 @@ struct neu_adapter {
neu_node_running_state_e state;
char log_level[NEU_LOG_LEVEL_LEN];
adapter_callbacks_t cb_funs;
void * handle;
neu_plugin_module_t *module;
neu_plugin_t * plugin;
uint8_t buf[NEU_MSG_MAX_SIZE];
uint8_t recv_buf[NEU_MSG_MAX_SIZE];
neu_event_io_t *control_io;
neu_event_io_t *trans_data_io;
int control_fd;
int trans_data_fd;
adapter_msg_q_t *msg_q;
pthread_t consumer_tid;
uint16_t trans_data_port;
neu_events_t *events;
@@ -59,6 +58,7 @@ struct neu_adapter {
// metrics
neu_node_metrics_t *metrics;
int log_level;
};
typedef void (*adapter_handler)(neu_adapter_t * adapter,
@@ -98,6 +98,13 @@ neu_node_state_t neu_adapter_get_state(neu_adapter_t *adapter);
int neu_adapter_validate_tag(neu_adapter_t *adapter, neu_datatag_t *tag);
static inline void neu_adapter_reset_metrics(neu_adapter_t *adapter)
{
if (NULL != adapter->metrics) {
neu_node_metrics_reset(adapter->metrics);
}
}
int neu_adapter_register_group_metric(neu_adapter_t *adapter,
const char *group_name, const char *name,
const char *help, neu_metric_type_e type,
+309 -216
View File
@@ -81,6 +81,9 @@ struct neu_adapter_driver {
};
static int report_callback(void *usr_data);
static void report_to_app(neu_adapter_driver_t *driver, group_t *group,
struct sockaddr_in dst);
static int read_callback(void *usr_data);
static int write_callback(void *usr_data);
static void read_group(int64_t timestamp, int64_t timeout,
@@ -88,6 +91,7 @@ static void read_group(int64_t timestamp, int64_t timeout,
neu_driver_cache_t *cache, const char *group,
UT_array *tags, UT_array *tag_values);
static void read_report_group(int64_t timestamp, int64_t timeout,
neu_tag_cache_type_e cache_type,
neu_driver_cache_t *cache, const char *group,
UT_array *tags, UT_array *tag_values);
static void update(neu_adapter_t *adapter, const char *group, const char *tag,
@@ -99,20 +103,30 @@ static void update_with_meta(neu_adapter_t *adapter, const char *group,
const char *tag, neu_dvalue_t value,
neu_tag_meta_t *metas, int n_meta);
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 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 inline void start_group_timer(neu_adapter_driver_t *driver,
group_t * grp);
static inline void stop_group_timer(neu_adapter_driver_t *driver, group_t *grp);
static void write_response(neu_adapter_t *adapter, void *r, neu_error error)
{
neu_reqresp_head_t *req = (neu_reqresp_head_t *) r;
neu_resp_error_t nerror = { .error = error };
if (NEU_REQ_WRITE_TAG == req->type) {
neu_req_write_tag_fini((neu_req_write_tag_t *) &req[1]);
} else if (NEU_REQ_WRITE_TAGS == req->type) {
neu_req_write_tags_fini((neu_req_write_tags_t *) &req[1]);
} else if (NEU_REQ_WRITE_GTAGS == req->type) {
neu_req_write_gtags_fini((neu_req_write_gtags_t *) &req[1]);
}
req->type = NEU_RESP_ERROR;
nlog_notice("write tag response <%p>", req->ctx);
adapter->cb_funs.response(adapter, req, &nerror);
free(req);
}
static void update_with_meta(neu_adapter_t *adapter, const char *group,
@@ -169,9 +183,7 @@ static void update_im(neu_adapter_t *adapter, const char *group,
const char *tag, neu_dvalue_t value,
neu_tag_meta_t *metas, int n_meta)
{
neu_adapter_driver_t * driver = (neu_adapter_driver_t *) adapter;
static __thread uint8_t buf[1024] = { 0 };
neu_reqresp_head_t * header = (neu_reqresp_head_t *) buf;
neu_adapter_driver_t *driver = (neu_adapter_driver_t *) adapter;
if (tag == NULL || value.type == NEU_TYPE_ERROR) {
nlog_warn("update_im tag is null or value is error %d",
@@ -207,17 +219,19 @@ static void update_im(neu_adapter_t *adapter, const char *group,
driver->adapter.name, group, tag, neu_type_string(value.type),
global_timestamp);
memset(buf, 0, sizeof(buf));
header->type = NEU_REQRESP_TRANS_DATA;
neu_reqresp_head_t header = {
.type = NEU_REQRESP_TRANS_DATA,
};
neu_reqresp_trans_data_t *data =
calloc(1, sizeof(neu_reqresp_trans_data_t));
strcpy(data->driver, driver->adapter.name);
strcpy(data->group, group);
data->driver = strdup(driver->adapter.name);
data->group = strdup(group);
utarray_new(data->tags, neu_resp_tag_value_meta_icd());
read_report_group(global_timestamp, 0, driver->cache, group, tags,
data->tags);
read_report_group(global_timestamp, 0,
neu_adapter_get_tag_cache_type(&driver->adapter),
driver->cache, group, tags, data->tags);
if (utarray_len(data->tags) > 0) {
group_t *find = NULL;
@@ -225,29 +239,34 @@ static void update_im(neu_adapter_t *adapter, const char *group,
if (find != NULL) {
pthread_mutex_lock(&find->apps_mtx);
data->ctx = calloc(1, sizeof(neu_reqresp_trans_data_ctx_t));
data->ctx->index = utarray_len(find->apps);
if (data->ctx->index > 0) {
if (utarray_len(find->apps) > 0) {
data->ctx = calloc(1, sizeof(neu_reqresp_trans_data_ctx_t));
data->ctx->index = utarray_len(find->apps);
pthread_mutex_init(&data->ctx->mtx, NULL);
utarray_foreach(find->apps, sub_app_t *, app)
{
if (driver->adapter.cb_funs.responseto(
&driver->adapter, header, data, app->addr) <= 0) {
&driver->adapter, &header, data, app->addr) != 0) {
neu_trans_data_free(data);
}
}
} else {
utarray_free(data->tags);
free(data->ctx);
free(data->group);
free(data->driver);
}
pthread_mutex_unlock(&find->apps_mtx);
} else {
utarray_free(data->tags);
free(data->group);
free(data->driver);
}
} else {
utarray_free(data->tags);
free(data->group);
free(data->driver);
}
utarray_free(tags);
@@ -308,9 +327,7 @@ int neu_adapter_driver_uninit(neu_adapter_driver_t *driver)
HASH_DEL(driver->groups, el);
neu_adapter_driver_try_del_tag(driver, neu_group_tag_size(el->group));
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);
stop_group_timer(driver, el);
if (el->grp.group_free != NULL) {
el->grp.group_free(&el->grp);
}
@@ -333,34 +350,67 @@ int neu_adapter_driver_uninit(neu_adapter_driver_t *driver)
return 0;
}
static inline void start_group_timer(neu_adapter_driver_t *driver, group_t *grp)
{
uint32_t interval = neu_group_get_interval(grp->group);
neu_event_timer_param_t param = {
.second = interval / 1000,
.millisecond = interval % 1000,
.usr_data = (void *) grp,
.type = NEU_EVENT_TIMER_NOBLOCK,
};
param.type = driver->adapter.module->timer_type;
param.cb = read_callback;
grp->read = neu_event_add_timer(driver->driver_events, param);
struct timespec t1 = {
.tv_sec = 0,
.tv_nsec = 1000 * 1000 * 20,
};
struct timespec t2 = { 0 };
nanosleep(&t1, &t2);
param.type = NEU_EVENT_TIMER_NOBLOCK;
param.cb = report_callback;
grp->report = neu_adapter_add_timer((neu_adapter_t *) driver, param);
param.second = 0;
param.millisecond = 3;
param.cb = write_callback;
grp->write = neu_event_add_timer(driver->driver_events, param);
}
void neu_adapter_driver_start_group_timer(neu_adapter_driver_t *driver)
{
group_t *el = NULL, *tmp = NULL;
HASH_ITER(hh, driver->groups, el, tmp)
{
uint32_t interval = neu_group_get_interval(el->group);
neu_event_timer_param_t param = {
.second = interval / 1000,
.millisecond = interval % 1000,
.usr_data = el,
.type = NEU_EVENT_TIMER_NOBLOCK,
};
start_group_timer(driver, el);
neu_adapter_update_group_metric(
&driver->adapter, neu_group_get_name(el->group),
NEU_METRIC_GROUP_TAGS_TOTAL, neu_group_tag_size(el->group));
}
param.type = driver->adapter.module->timer_type;
param.cb = read_callback;
el->read = neu_event_add_timer(driver->driver_events, param);
driver->adapter.cb_funs.update_metric(
&driver->adapter, NEU_METRIC_TAGS_TOTAL, driver->tag_cnt, NULL);
}
struct timespec t1 = {
.tv_sec = 0,
.tv_nsec = 1000 * 1000 * 20,
};
struct timespec t2 = { 0 };
nanosleep(&t1, &t2);
param.type = NEU_EVENT_TIMER_NOBLOCK;
param.cb = report_callback;
el->report = neu_adapter_add_timer((neu_adapter_t *) driver, param);
static inline void stop_group_timer(neu_adapter_driver_t *driver, group_t *grp)
{
if (grp->report) {
neu_adapter_del_timer((neu_adapter_t *) driver, grp->report);
grp->report = NULL;
}
if (grp->read) {
neu_event_del_timer(driver->driver_events, grp->read);
grp->read = NULL;
}
if (grp->write) {
neu_event_del_timer(driver->driver_events, grp->write);
grp->write = NULL;
}
}
@@ -368,13 +418,7 @@ void neu_adapter_driver_stop_group_timer(neu_adapter_driver_t *driver)
{
group_t *el = NULL, *tmp = NULL;
HASH_ITER(hh, driver->groups, el, tmp)
{
neu_adapter_del_timer((neu_adapter_t *) driver, el->report);
el->report = NULL;
neu_event_del_timer(driver->driver_events, el->read);
el->read = NULL;
}
HASH_ITER(hh, driver->groups, el, tmp) { stop_group_timer(driver, el); }
}
void neu_adapter_driver_read_group(neu_adapter_driver_t *driver,
@@ -385,6 +429,7 @@ void neu_adapter_driver_read_group(neu_adapter_driver_t *driver,
if (g == NULL) {
neu_resp_error_t error = { .error = NEU_ERR_GROUP_NOT_EXIST };
req->type = NEU_RESP_ERROR;
neu_req_read_group_fini(cmd);
driver->adapter.cb_funs.response(&driver->adapter, req, &error);
return;
}
@@ -437,10 +482,13 @@ void neu_adapter_driver_read_group(neu_adapter_driver_t *driver,
driver->cache, cmd->group, tags, resp.tags);
}
strcpy(resp.driver, cmd->driver);
strcpy(resp.group, cmd->group);
resp.driver = cmd->driver;
resp.group = cmd->group;
cmd->driver = NULL; // ownership moved
cmd->group = NULL; // ownership moved
utarray_free(tags);
neu_req_read_group_fini(cmd);
req->type = NEU_RESP_READ_GROUP;
driver->adapter.cb_funs.response(&driver->adapter, req, &resp);
@@ -526,9 +574,17 @@ static void fix_value(neu_datatag_t *tag, neu_type_e value_type,
case NEU_TYPE_LWORD:
switch (tag->option.value64.endian) {
case NEU_DATATAG_ENDIAN_B64:
case NEU_DATATAG_ENDIAN_BB64:
value->value.u64 = neu_ntohll(value->value.u64);
break;
case NEU_DATATAG_ENDIAN_LB64:
value->value.u64 = neu_htonlb(value->value.u64);
break;
case NEU_DATATAG_ENDIAN_BL64:
value->value.u64 = neu_htonbl(value->value.u64);
break;
case NEU_DATATAG_ENDIAN_L64:
case NEU_DATATAG_ENDIAN_LL64:
default:
break;
}
@@ -544,20 +600,62 @@ static void cal_decimal(neu_type_e tag_type, neu_type_e value_type,
{
switch (tag_type) {
case NEU_TYPE_INT8:
case NEU_TYPE_UINT8:
if (value_type == NEU_TYPE_DOUBLE) {
value->i8 = (int8_t) round(value->d64 / decimal);
} else {
value->i8 = (int8_t) round(value->i64 / decimal);
}
break;
case NEU_TYPE_INT16:
case NEU_TYPE_UINT16:
if (value_type == NEU_TYPE_DOUBLE) {
value->i16 = (int16_t) round(value->d64 / decimal);
} else {
value->i16 = (int16_t) round(value->i64 / decimal);
}
break;
case NEU_TYPE_INT32:
case NEU_TYPE_UINT32:
if (value_type == NEU_TYPE_DOUBLE) {
value->i32 = (int32_t) round(value->d64 / decimal);
} else {
value->i32 = (int32_t) round(value->i64 / decimal);
}
break;
case NEU_TYPE_INT64:
case NEU_TYPE_UINT64:
if (value_type == NEU_TYPE_DOUBLE) {
value->i64 = (int64_t) round(value->d64 / decimal);
} else {
value->i64 = (int64_t) round(value->i64 / decimal);
}
break;
case NEU_TYPE_UINT8:
if (value_type == NEU_TYPE_DOUBLE) {
value->u8 = (uint8_t) round(value->d64 / decimal);
} else {
value->u8 = (uint8_t) round(value->u64 / decimal);
}
break;
case NEU_TYPE_UINT16:
case NEU_TYPE_WORD:
if (value_type == NEU_TYPE_DOUBLE) {
value->u16 = (uint16_t) round(value->d64 / decimal);
} else {
value->u16 = (uint16_t) round(value->u64 / decimal);
}
break;
case NEU_TYPE_UINT32:
case NEU_TYPE_LWORD:
if (value_type == NEU_TYPE_DOUBLE) {
value->u32 = (uint32_t) round(value->d64 / decimal);
} else {
value->u32 = (uint32_t) round(value->u64 / decimal);
}
break;
case NEU_TYPE_UINT64:
case NEU_TYPE_DWORD:
if (value_type == NEU_TYPE_INT64 || value_type == NEU_TYPE_LWORD) {
value->u64 = value->u64 / decimal;
} else if (value_type == NEU_TYPE_DOUBLE) {
if (value_type == NEU_TYPE_DOUBLE) {
value->u64 = (uint64_t) round(value->d64 / decimal);
} else {
value->u64 = (uint64_t) round(value->u64 / decimal);
}
break;
case NEU_TYPE_FLOAT:
@@ -575,25 +673,18 @@ static void cal_decimal(neu_type_e tag_type, neu_type_e value_type,
}
}
static void free_tags(neu_req_write_tags_t *cmd)
{
free(cmd->tags);
}
void neu_adapter_driver_write_tags(neu_adapter_driver_t *driver,
neu_reqresp_head_t * req)
{
neu_req_write_tags_t *cmd = (neu_req_write_tags_t *) &req[1];
if (driver->adapter.state != NEU_NODE_RUNNING_STATE_RUNNING) {
free_tags(cmd);
driver->adapter.cb_funs.driver.write_response(
&driver->adapter, req, NEU_ERR_PLUGIN_NOT_RUNNING);
return;
}
if (driver->adapter.module->intf_funs->driver.write_tags == NULL) {
free_tags(cmd);
driver->adapter.cb_funs.driver.write_response(
&driver->adapter, req, NEU_ERR_PLUGIN_NOT_SUPPORT_WRITE_TAGS);
return;
@@ -602,11 +693,8 @@ void neu_adapter_driver_write_tags(neu_adapter_driver_t *driver,
group_t *g = find_group(driver, cmd->group);
if (g == NULL) {
neu_resp_error_t error = { .error = NEU_ERR_GROUP_NOT_EXIST };
req->type = NEU_RESP_ERROR;
free_tags(cmd);
driver->adapter.cb_funs.response(&driver->adapter, req, &error);
free(req);
driver->adapter.cb_funs.driver.write_response(&driver->adapter, req,
NEU_ERR_GROUP_NOT_EXIST);
return;
}
@@ -614,16 +702,13 @@ void neu_adapter_driver_write_tags(neu_adapter_driver_t *driver,
UT_icd icd = { sizeof(neu_plugin_tag_value_t), NULL, NULL, NULL };
utarray_new(tags, &icd);
for (int i = 0; i < cmd->n_tag; i++) {
neu_plugin_tag_value_t tv = { 0 };
neu_datatag_t *tag = neu_group_find_tag(g->group, cmd->tags[i].tag);
if (tag != NULL && neu_tag_attribute_test(tag, NEU_ATTRIBUTE_WRITE) &&
neu_tag_attribute_test(tag, NEU_ATTRIBUTE_STATIC) == false) {
tv.tag = neu_tag_dup(tag);
if (tag->type == NEU_TYPE_FLOAT || tag->type == NEU_TYPE_DOUBLE) {
if (cmd->tags[i].value.type == NEU_TYPE_INT64) {
tv.value.d64 = (double) tv.value.i64;
cmd->tags[i].value.value.d64 =
(double) cmd->tags[i].value.value.i64;
}
}
if (tag->decimal != 0) {
@@ -632,7 +717,10 @@ void neu_adapter_driver_write_tags(neu_adapter_driver_t *driver,
}
fix_value(tag, cmd->tags[i].value.type, &cmd->tags[i].value);
tv.value = cmd->tags[i].value.value;
neu_plugin_tag_value_t tv = {
.tag = neu_tag_dup(tag),
.value = cmd->tags[i].value.value,
};
utarray_push_back(tags, &tv);
}
if (tag != NULL) {
@@ -641,11 +729,8 @@ void neu_adapter_driver_write_tags(neu_adapter_driver_t *driver,
}
if (utarray_len(tags) != (unsigned int) cmd->n_tag) {
neu_resp_error_t error = { .error = NEU_ERR_TAG_NOT_EXIST };
req->type = NEU_RESP_ERROR;
free_tags(cmd);
driver->adapter.cb_funs.response(&driver->adapter, req, &error);
free(req);
driver->adapter.cb_funs.driver.write_response(&driver->adapter, req,
NEU_ERR_TAG_NOT_EXIST);
utarray_foreach(tags, neu_plugin_tag_value_t *, tv)
{
neu_tag_free(tv->tag);
@@ -660,7 +745,6 @@ void neu_adapter_driver_write_tags(neu_adapter_driver_t *driver,
wtag.tvs = tags;
store_write_tag(g, &wtag);
free_tags(cmd);
}
void neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver,
@@ -670,20 +754,12 @@ void neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver,
group_t * first_g = NULL;
if (driver->adapter.state != NEU_NODE_RUNNING_STATE_RUNNING) {
for (int i = 0; i < cmd->n_group; i++) {
free(cmd->groups[i].tags);
}
free(cmd->groups);
driver->adapter.cb_funs.driver.write_response(
&driver->adapter, req, NEU_ERR_PLUGIN_NOT_RUNNING);
return;
}
if (driver->adapter.module->intf_funs->driver.write_tags == NULL) {
for (int i = 0; i < cmd->n_group; i++) {
free(cmd->groups[i].tags);
}
free(cmd->groups);
driver->adapter.cb_funs.driver.write_response(
&driver->adapter, req, NEU_ERR_PLUGIN_NOT_SUPPORT_WRITE_TAGS);
return;
@@ -693,14 +769,8 @@ void neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver,
group_t *g = find_group(driver, cmd->groups[i].group);
if (g == NULL) {
neu_resp_error_t error = { .error = NEU_ERR_GROUP_NOT_EXIST };
req->type = NEU_RESP_ERROR;
for (int x = 0; x < cmd->n_group; x++) {
free(cmd->groups[x].tags);
}
free(cmd->groups);
driver->adapter.cb_funs.response(&driver->adapter, req, &error);
free(req);
driver->adapter.cb_funs.driver.write_response(
&driver->adapter, req, NEU_ERR_GROUP_NOT_EXIST);
return;
}
@@ -717,20 +787,16 @@ void neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver,
group_t *g = find_group(driver, cmd->groups[i].group);
for (int k = 0; k < cmd->groups[i].n_tag; k++) {
neu_plugin_tag_value_t tv = { 0 };
neu_datatag_t *tag =
neu_group_find_tag(g->group, cmd->groups[i].tags[k].tag);
if (tag != NULL &&
neu_tag_attribute_test(tag, NEU_ATTRIBUTE_WRITE) &&
neu_tag_attribute_test(tag, NEU_ATTRIBUTE_STATIC) == false) {
tv.tag = neu_tag_dup(tag);
if (tag->type == NEU_TYPE_FLOAT ||
tag->type == NEU_TYPE_DOUBLE) {
if (cmd->groups[i].tags[k].value.type == NEU_TYPE_INT64) {
tv.value.d64 = (double) tv.value.u64;
cmd->groups[i].tags[k].value.value.d64 =
(double) cmd->groups[i].tags[k].value.value.i64;
}
}
if (tag->decimal != 0) {
@@ -741,7 +807,10 @@ void neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver,
fix_value(tag, cmd->groups[i].tags[k].value.type,
&cmd->groups[i].tags[k].value);
tv.value = cmd->groups[i].tags[k].value.value;
neu_plugin_tag_value_t tv = {
tv.tag = neu_tag_dup(tag),
tv.value = cmd->groups[i].tags[k].value.value,
};
utarray_push_back(tags, &tv);
}
if (tag != NULL) {
@@ -756,14 +825,8 @@ void neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver,
}
if (utarray_len(tags) != (unsigned int) n_tag) {
neu_resp_error_t error = { .error = NEU_ERR_TAG_NOT_EXIST };
req->type = NEU_RESP_ERROR;
for (int i = 0; i < cmd->n_group; i++) {
free(cmd->groups[i].tags);
}
free(cmd->groups);
driver->adapter.cb_funs.response(&driver->adapter, req, &error);
free(req);
driver->adapter.cb_funs.driver.write_response(&driver->adapter, req,
NEU_ERR_TAG_NOT_EXIST);
utarray_foreach(tags, neu_plugin_tag_value_t *, tv)
{
neu_tag_free(tv->tag);
@@ -778,10 +841,6 @@ void neu_adapter_driver_write_gtags(neu_adapter_driver_t *driver,
wtag.tvs = tags;
store_write_tag(first_g, &wtag);
for (int i = 0; i < cmd->n_group; i++) {
free(cmd->groups[i].tags);
}
free(cmd->groups);
}
void neu_adapter_driver_write_tag(neu_adapter_driver_t *driver,
@@ -797,20 +856,15 @@ void neu_adapter_driver_write_tag(neu_adapter_driver_t *driver,
group_t * g = find_group(driver, cmd->group);
if (g == NULL) {
neu_resp_error_t error = { .error = NEU_ERR_GROUP_NOT_EXIST };
req->type = NEU_RESP_ERROR;
driver->adapter.cb_funs.response(&driver->adapter, req, &error);
free(req);
driver->adapter.cb_funs.driver.write_response(&driver->adapter, req,
NEU_ERR_GROUP_NOT_EXIST);
return;
}
neu_datatag_t *tag = neu_group_find_tag(g->group, cmd->tag);
if (tag == NULL) {
neu_resp_error_t error = { .error = NEU_ERR_TAG_NOT_EXIST };
req->type = NEU_RESP_ERROR;
driver->adapter.cb_funs.response(&driver->adapter, req, &error);
free(req);
driver->adapter.cb_funs.driver.write_response(&driver->adapter, req,
NEU_ERR_TAG_NOT_EXIST);
} else {
if ((tag->attribute & NEU_ATTRIBUTE_WRITE) != NEU_ATTRIBUTE_WRITE) {
driver->adapter.cb_funs.driver.write_response(
@@ -837,10 +891,8 @@ void neu_adapter_driver_write_tag(neu_adapter_driver_t *driver,
neu_tag_set_static_value(tag, &cmd->value.value);
neu_group_update_tag(g->group, tag);
adapter_storage_update_tag_value(cmd->driver, cmd->group, tag);
neu_resp_error_t error = { .error = NEU_ERR_SUCCESS };
req->type = NEU_RESP_ERROR;
driver->adapter.cb_funs.response(&driver->adapter, req, &error);
free(req);
driver->adapter.cb_funs.driver.write_response(&driver->adapter, req,
NEU_ERR_SUCCESS);
} else {
to_be_write_tag_t wtag = { 0 };
wtag.single = true;
@@ -871,13 +923,6 @@ int neu_adapter_driver_add_group(neu_adapter_driver_t *driver, const char *name,
if (find == NULL) {
find = calloc(1, sizeof(group_t));
neu_event_timer_param_t param = {
.second = interval / 1000,
.millisecond = interval % 1000,
.usr_data = (void *) find,
.type = NEU_EVENT_TIMER_NOBLOCK,
};
pthread_mutex_init(&find->wt_mtx, NULL);
pthread_mutex_init(&find->apps_mtx, NULL);
@@ -888,28 +933,13 @@ int neu_adapter_driver_add_group(neu_adapter_driver_t *driver, const char *name,
find->name = strdup(name);
find->group = neu_group_new(name, interval);
find->grp.group_name = strdup(name);
find->grp.interval = interval;
neu_group_split_static_tags(find->group, &find->static_tags,
&find->grp.tags);
param.type = driver->adapter.module->timer_type;
param.cb = read_callback;
find->read = neu_event_add_timer(driver->driver_events, param);
struct timespec t1 = {
.tv_sec = 0,
.tv_nsec = 1000 * 1000 * 20,
};
struct timespec t2 = { 0 };
nanosleep(&t1, &t2);
param.type = NEU_EVENT_TIMER_NOBLOCK;
param.cb = report_callback;
find->report = neu_adapter_add_timer((neu_adapter_t *) driver, param);
param.second = 0;
param.millisecond = 3;
param.cb = write_callback;
find->write = neu_event_add_timer(driver->driver_events, param);
if (NEU_NODE_RUNNING_STATE_RUNNING == driver->adapter.state) {
start_group_timer(driver, find);
}
REGISTER_GROUP_METRIC(&driver->adapter, find->name,
NEU_METRIC_GROUP_TAGS_TOTAL,
@@ -953,11 +983,14 @@ int neu_adapter_driver_update_group(neu_adapter_driver_t *driver,
return NEU_ERR_GROUP_EXIST;
}
}
} else if (neu_group_get_interval(find->group) == interval) {
return 0; // no change
}
// stop the timer first to avoid race condition
neu_adapter_del_timer((neu_adapter_t *) driver, find->report);
neu_event_del_timer(driver->driver_events, find->read);
if (NEU_NODE_RUNNING_STATE_RUNNING == driver->adapter.state) {
stop_group_timer(driver, find);
}
// a diminutive value should keep the interval untouched
if (interval < NEU_GROUP_INTERVAL_LIMIT) {
@@ -977,7 +1010,6 @@ int neu_adapter_driver_update_group(neu_adapter_driver_t *driver,
find->grp.group_name = new_name_cp2;
neu_adapter_metric_update_group_name((neu_adapter_t *) driver, name,
new_name);
find->timestamp = global_timestamp; // trigger group_change
HASH_ADD_STR(driver->groups, name, find);
} else {
free(new_name_cp1);
@@ -986,31 +1018,14 @@ int neu_adapter_driver_update_group(neu_adapter_driver_t *driver,
}
}
neu_event_timer_param_t param = {
.second = interval / 1000,
.millisecond = interval % 1000,
.usr_data = (void *) find,
.type = NEU_EVENT_TIMER_NOBLOCK,
};
find->timestamp = global_timestamp; // trigger group_change
find->grp.interval = interval;
neu_group_set_interval(find->group, interval);
// restore the timers
param.type = driver->adapter.module->timer_type;
param.cb = read_callback;
find->read = neu_event_add_timer(driver->driver_events, param);
struct timespec t1 = {
.tv_sec = 0,
.tv_nsec = 1000 * 1000 * 20,
};
struct timespec t2 = { 0 };
nanosleep(&t1, &t2);
param.type = NEU_EVENT_TIMER_NOBLOCK;
param.cb = report_callback;
find->report = neu_adapter_add_timer((neu_adapter_t *) driver, param);
if (NEU_NODE_RUNNING_STATE_RUNNING == driver->adapter.state) {
start_group_timer(driver, find);
}
return ret;
}
@@ -1026,9 +1041,10 @@ int neu_adapter_driver_del_group(neu_adapter_driver_t *driver, const char *name)
neu_adapter_driver_try_del_tag(driver, neu_group_tag_size(find->group));
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 (NEU_NODE_RUNNING_STATE_RUNNING == driver->adapter.state) {
stop_group_timer(driver, find);
}
if (find->grp.group_free != NULL) {
find->grp.group_free(&find->grp);
}
@@ -1206,8 +1222,8 @@ int neu_adapter_driver_add_tag(neu_adapter_driver_t *driver, const char *group,
HASH_FIND_STR(driver->groups, group, find);
if (find == NULL) {
neu_adapter_driver_add_group(driver, group, 100);
adapter_storage_add_group(driver->adapter.name, group, 100);
neu_adapter_driver_add_group(driver, group, 1000);
adapter_storage_add_group(driver->adapter.name, group, 1000);
}
HASH_FIND_STR(driver->groups, group, find);
assert(find != NULL);
@@ -1387,18 +1403,12 @@ UT_array *neu_adapter_driver_get_ptag(neu_adapter_driver_t *driver,
return tags;
}
static int report_callback(void *usr_data)
static void report_to_app(neu_adapter_driver_t *driver, group_t *group,
struct sockaddr_in dst)
{
group_t * group = (group_t *) usr_data;
static __thread uint8_t buf[1024] = { 0 };
neu_reqresp_head_t * header = (neu_reqresp_head_t *) buf;
neu_node_running_state_e state = group->driver->adapter.state;
if (state != NEU_NODE_RUNNING_STATE_RUNNING) {
return 0;
}
memset(buf, 0, sizeof(buf));
header->type = NEU_REQRESP_TRANS_DATA;
neu_reqresp_head_t header = {
.type = NEU_REQRESP_TRANS_DATA,
};
UT_array *tags =
neu_adapter_driver_get_read_tag(group->driver, group->name);
@@ -1406,14 +1416,15 @@ static int report_callback(void *usr_data)
neu_reqresp_trans_data_t *data =
calloc(1, sizeof(neu_reqresp_trans_data_t));
strcpy(data->driver, group->driver->adapter.name);
strcpy(data->group, group->name);
data->driver = strdup(group->driver->adapter.name);
data->group = strdup(group->name);
utarray_new(data->tags, neu_resp_tag_value_meta_icd());
read_report_group(global_timestamp,
neu_group_get_interval(group->group) *
NEU_DRIVER_TAG_CACHE_EXPIRE_TIME,
group->driver->cache, group->name, tags, data->tags);
read_group(global_timestamp,
neu_group_get_interval(group->group) *
NEU_DRIVER_TAG_CACHE_EXPIRE_TIME,
neu_adapter_get_tag_cache_type(&driver->adapter), driver->cache,
group->name, tags, data->tags);
nlog_info("report group: %s, all tags: %d, report tags: %d", group->name,
utarray_len(tags), utarray_len(data->tags));
@@ -1421,27 +1432,88 @@ static int report_callback(void *usr_data)
pthread_mutex_lock(&group->apps_mtx);
data->ctx = calloc(1, sizeof(neu_reqresp_trans_data_ctx_t));
data->ctx->index = utarray_len(group->apps);
data->ctx->index = 1;
if (data->ctx->index > 0) {
pthread_mutex_init(&data->ctx->mtx, NULL);
pthread_mutex_init(&data->ctx->mtx, NULL);
utarray_foreach(group->apps, sub_app_t *, app)
{
if (group->driver->adapter.cb_funs.responseto(
&group->driver->adapter, header, data, app->addr) <=
0) {
neu_trans_data_free(data);
}
}
} else {
utarray_free(data->tags);
free(data->ctx);
if (driver->adapter.cb_funs.responseto(&driver->adapter, &header, data,
dst) != 0) {
neu_trans_data_free(data);
}
pthread_mutex_unlock(&group->apps_mtx);
} else {
utarray_free(data->tags);
free(data->group);
free(data->driver);
}
utarray_free(tags);
free(data);
}
static int report_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;
}
neu_reqresp_head_t header = {
.type = NEU_REQRESP_TRANS_DATA,
};
UT_array *tags =
neu_adapter_driver_get_read_tag(group->driver, group->name);
neu_reqresp_trans_data_t *data =
calloc(1, sizeof(neu_reqresp_trans_data_t));
data->driver = strdup(group->driver->adapter.name);
data->group = strdup(group->name);
utarray_new(data->tags, neu_resp_tag_value_meta_icd());
read_report_group(global_timestamp,
neu_group_get_interval(group->group) *
NEU_DRIVER_TAG_CACHE_EXPIRE_TIME,
neu_adapter_get_tag_cache_type(&group->driver->adapter),
group->driver->cache, group->name, tags, data->tags);
nlog_info("report group: %s, all tags: %d, report tags: %d", group->name,
utarray_len(tags), utarray_len(data->tags));
if (utarray_len(data->tags) > 0) {
pthread_mutex_lock(&group->apps_mtx);
if (utarray_len(group->apps) > 0) {
data->ctx = calloc(1, sizeof(neu_reqresp_trans_data_ctx_t));
data->ctx->index = utarray_len(group->apps);
pthread_mutex_init(&data->ctx->mtx, NULL);
utarray_foreach(group->apps, sub_app_t *, app)
{
if (group->driver->adapter.cb_funs.responseto(
&group->driver->adapter, &header, data, app->addr) !=
0) {
neu_trans_data_free(data);
}
}
} else {
utarray_foreach(data->tags, neu_resp_tag_value_meta_t *, tag_value)
{
if (tag_value->value.type == NEU_TYPE_PTR) {
free(tag_value->value.value.ptr.ptr);
}
}
utarray_free(data->tags);
free(data->group);
free(data->driver);
}
pthread_mutex_unlock(&group->apps_mtx);
} else {
utarray_free(data->tags);
free(data->group);
free(data->driver);
}
utarray_free(tags);
free(data);
@@ -1497,6 +1569,7 @@ static void group_change(void *arg, int64_t timestamp, UT_array *static_tags,
neu_plugin_group_t grp = {
.group_name = strdup(group->name),
.interval = neu_group_get_interval(group->group),
.tags = NULL,
.group_free = NULL,
.user_data = NULL,
@@ -1580,6 +1653,7 @@ static int read_callback(void *usr_data)
}
static void read_report_group(int64_t timestamp, int64_t timeout,
neu_tag_cache_type_e cache_type,
neu_driver_cache_t *cache, const char *group,
UT_array *tags, UT_array *tag_values)
{
@@ -1661,9 +1735,17 @@ static void read_report_group(int64_t timestamp, int64_t timeout,
case NEU_TYPE_UINT64:
switch (tag->option.value64.endian) {
case NEU_DATATAG_ENDIAN_B64:
case NEU_DATATAG_ENDIAN_BB64:
value.value.value.u64 = neu_htonll(value.value.value.u64);
break;
case NEU_DATATAG_ENDIAN_LB64:
value.value.value.u64 = neu_htonlb(value.value.value.u64);
break;
case NEU_DATATAG_ENDIAN_BL64:
value.value.value.u64 = neu_htonbl(value.value.value.u64);
break;
case NEU_DATATAG_ENDIAN_L64:
case NEU_DATATAG_ENDIAN_LL64:
default:
break;
}
@@ -1672,7 +1754,8 @@ static void read_report_group(int64_t timestamp, int64_t timeout,
break;
}
if (!neu_tag_attribute_test(tag, NEU_ATTRIBUTE_STATIC) &&
if (cache_type != NEU_TAG_CACHE_TYPE_NEVER &&
!neu_tag_attribute_test(tag, NEU_ATTRIBUTE_STATIC) &&
(timestamp - value.timestamp) > timeout && timeout > 0) {
tag_value.value.type = NEU_TYPE_ERROR;
tag_value.value.value.i32 = NEU_ERR_PLUGIN_TAG_VALUE_EXPIRED;
@@ -1812,9 +1895,17 @@ static void read_group(int64_t timestamp, int64_t timeout,
case NEU_TYPE_UINT64:
switch (tag->option.value64.endian) {
case NEU_DATATAG_ENDIAN_B64:
case NEU_DATATAG_ENDIAN_BB64:
value.value.value.u64 = neu_htonll(value.value.value.u64);
break;
case NEU_DATATAG_ENDIAN_LB64:
value.value.value.u64 = neu_htonlb(value.value.value.u64);
break;
case NEU_DATATAG_ENDIAN_BL64:
value.value.value.u64 = neu_htonbl(value.value.value.u64);
break;
case NEU_DATATAG_ENDIAN_L64:
case NEU_DATATAG_ENDIAN_LL64:
default:
break;
}
@@ -1928,6 +2019,8 @@ void neu_adapter_driver_subscribe(neu_adapter_driver_t *driver,
utarray_push_back(find->apps, &sub_app);
pthread_mutex_unlock(&find->apps_mtx);
report_to_app(driver, find, sub_app.addr);
}
void neu_adapter_driver_unsubscribe(neu_adapter_driver_t * driver,
+116
View File
@@ -0,0 +1,116 @@
/**
* NEURON IIoT System for Industry 4.0
* Copyright (C) 2020-2024 EMQ Technologies Co., Ltd All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
#include <pthread.h>
#include "utils/log.h"
#include "utils/utextend.h"
#include "msg_q.h"
struct item {
neu_msg_t * msg;
struct item *prev, *next;
};
struct adapter_msg_q {
struct item *list;
uint32_t max;
uint32_t current;
char * name;
pthread_mutex_t mtx;
pthread_cond_t cond;
};
adapter_msg_q_t *adapter_msg_q_new(const char *name, uint32_t size)
{
struct adapter_msg_q *q = calloc(1, sizeof(struct adapter_msg_q));
pthread_mutex_init(&q->mtx, NULL);
pthread_cond_init(&q->cond, NULL);
q->max = size;
q->name = strdup(name);
q->current = 0;
return q;
}
void adapter_msg_q_free(adapter_msg_q_t *q)
{
struct item *tmp = NULL, *elt = NULL;
nlog_warn("app: %s, drop %u msg", q->name, q->current);
pthread_mutex_destroy(&q->mtx);
pthread_cond_destroy(&q->cond);
DL_FOREACH_SAFE(q->list, elt, tmp)
{
DL_DELETE(q->list, elt);
neu_reqresp_head_t *header = neu_msg_get_header(elt->msg);
neu_trans_data_free((neu_reqresp_trans_data_t *) &header[1]);
neu_msg_free(elt->msg);
free(elt);
}
free(q->name);
free(q);
}
int adapter_msg_q_push(adapter_msg_q_t *q, neu_msg_t *msg)
{
int ret = -1;
pthread_mutex_lock(&q->mtx);
if (q->current < q->max) {
q->current += 1;
struct item *elt = calloc(1, sizeof(struct item));
elt->msg = msg;
DL_APPEND(q->list, elt);
ret = 0;
}
pthread_mutex_unlock(&q->mtx);
if (ret == -1) {
nlog_warn("app: %s, msg q is full, %u(%u)", q->name, q->current,
q->max);
} else {
pthread_cond_signal(&q->cond);
}
return ret;
}
uint32_t adapter_msg_q_pop(adapter_msg_q_t *q, neu_msg_t **p_data)
{
uint32_t ret = 0;
pthread_mutex_lock(&q->mtx);
while (q->current == 0) {
pthread_cond_wait(&q->cond, &q->mtx);
}
struct item *elt = DL_LAST(q->list);
if (elt != NULL) {
DL_DELETE(q->list, elt);
*p_data = elt->msg;
free(elt);
q->current -= 1;
ret = q->current;
}
pthread_mutex_unlock(&q->mtx);
return ret;
}
@@ -1,6 +1,6 @@
/**
* NEURON IIoT System for Industry 4.0
* Copyright (C) 2020-2022 EMQ Technologies Co., Ltd All rights reserved.
* Copyright (C) 2020-2024 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
@@ -17,12 +17,20 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
#ifndef _NEU_FILE_HANDLE_H_
#define _NEU_FILE_HANDLE_H_
#ifndef ADAPTER_MSG_Q_H
#define ADAPTER_MSG_Q_H
#include <nng/nng.h>
#include <stdint.h>
void handle_download_file(nng_aio *aio);
void handle_file_info(nng_aio *aio);
#include "base/msg_internal.h"
#include "msg.h"
typedef struct adapter_msg_q adapter_msg_q_t;
adapter_msg_q_t *adapter_msg_q_new(const char *name, uint32_t size);
void adapter_msg_q_free(adapter_msg_q_t *q);
int adapter_msg_q_push(adapter_msg_q_t *q, neu_msg_t *msg);
uint32_t adapter_msg_q_pop(adapter_msg_q_t *q, neu_msg_t **p_data);
#endif
+23 -2
View File
@@ -16,6 +16,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**/
#include <pthread.h>
#include <string.h>
#include <sys/time.h>
@@ -38,7 +39,8 @@ struct neu_group {
tag_elem_t *tags;
uint32_t interval;
int64_t timestamp;
int64_t timestamp;
pthread_mutex_t mtx;
};
static UT_array *to_array(tag_elem_t *tags);
@@ -53,6 +55,7 @@ neu_group_t *neu_group_new(const char *name, uint32_t interval)
group->name = strdup(name);
group->interval = interval;
pthread_mutex_init(&group->mtx, NULL);
return group;
}
@@ -61,6 +64,7 @@ void neu_group_destroy(neu_group_t *group)
{
tag_elem_t *el = NULL, *tmp = NULL;
pthread_mutex_lock(&group->mtx);
HASH_ITER(hh, group->tags, el, tmp)
{
HASH_DEL(group->tags, el);
@@ -68,7 +72,9 @@ void neu_group_destroy(neu_group_t *group)
neu_tag_free(el->tag);
free(el);
}
pthread_mutex_unlock(&group->mtx);
pthread_mutex_destroy(&group->mtx);
free(group->name);
free(group);
}
@@ -118,8 +124,10 @@ int neu_group_add_tag(neu_group_t *group, const neu_datatag_t *tag)
{
tag_elem_t *el = NULL;
pthread_mutex_lock(&group->mtx);
HASH_FIND_STR(group->tags, tag->name, el);
if (el != NULL) {
pthread_mutex_unlock(&group->mtx);
return NEU_ERR_TAG_NAME_CONFLICT;
}
@@ -129,6 +137,7 @@ int neu_group_add_tag(neu_group_t *group, const neu_datatag_t *tag)
HASH_ADD_STR(group->tags, name, el);
update_timestamp(group);
pthread_mutex_unlock(&group->mtx);
return 0;
}
@@ -138,6 +147,7 @@ int neu_group_update_tag(neu_group_t *group, const neu_datatag_t *tag)
tag_elem_t *el = NULL;
int ret = NEU_ERR_TAG_NOT_EXIST;
pthread_mutex_lock(&group->mtx);
HASH_FIND_STR(group->tags, tag->name, el);
if (el != NULL) {
neu_tag_copy(el->tag, tag);
@@ -145,6 +155,7 @@ int neu_group_update_tag(neu_group_t *group, const neu_datatag_t *tag)
update_timestamp(group);
ret = NEU_ERR_SUCCESS;
}
pthread_mutex_unlock(&group->mtx);
return ret;
}
@@ -154,6 +165,7 @@ int neu_group_del_tag(neu_group_t *group, const char *tag_name)
tag_elem_t *el = NULL;
int ret = NEU_ERR_TAG_NOT_EXIST;
pthread_mutex_lock(&group->mtx);
HASH_FIND_STR(group->tags, tag_name, el);
if (el != NULL) {
HASH_DEL(group->tags, el);
@@ -164,15 +176,18 @@ int neu_group_del_tag(neu_group_t *group, const char *tag_name)
update_timestamp(group);
ret = NEU_ERR_SUCCESS;
}
pthread_mutex_unlock(&group->mtx);
return ret;
}
UT_array *neu_group_get_tag(const neu_group_t *group)
UT_array *neu_group_get_tag(neu_group_t *group)
{
UT_array *array = NULL;
pthread_mutex_lock(&group->mtx);
array = to_array(group->tags);
pthread_mutex_unlock(&group->mtx);
return array;
}
@@ -182,6 +197,7 @@ UT_array *neu_group_query_tag(neu_group_t *group, const char *name)
tag_elem_t *el = NULL, *tmp = NULL;
UT_array * array = NULL;
pthread_mutex_lock(&group->mtx);
utarray_new(array, neu_tag_get_icd());
HASH_ITER(hh, group->tags, el, tmp)
{
@@ -189,6 +205,7 @@ UT_array *neu_group_query_tag(neu_group_t *group, const char *name)
utarray_push_back(array, el->tag);
}
}
pthread_mutex_unlock(&group->mtx);
return array;
}
@@ -197,7 +214,9 @@ UT_array *neu_group_get_read_tag(neu_group_t *group)
{
UT_array *array = NULL;
pthread_mutex_lock(&group->mtx);
array = to_read_array(group->tags);
pthread_mutex_unlock(&group->mtx);
return array;
}
@@ -216,10 +235,12 @@ neu_datatag_t *neu_group_find_tag(neu_group_t *group, const char *tag)
tag_elem_t * find = NULL;
neu_datatag_t *result = NULL;
pthread_mutex_lock(&group->mtx);
HASH_FIND_STR(group->tags, tag, find);
if (find != NULL) {
result = neu_tag_dup(find->tag);
}
pthread_mutex_unlock(&group->mtx);
return result;
}
+1 -1
View File
@@ -38,7 +38,7 @@ int neu_group_update(neu_group_t *group, uint32_t interval);
int neu_group_add_tag(neu_group_t *group, const neu_datatag_t *tag);
int neu_group_update_tag(neu_group_t *group, const neu_datatag_t *tag);
int neu_group_del_tag(neu_group_t *group, const char *tag_name);
UT_array * neu_group_get_tag(const neu_group_t *group);
UT_array * neu_group_get_tag(neu_group_t *group);
UT_array * neu_group_query_tag(neu_group_t *group, const char *name);
UT_array * neu_group_get_read_tag(neu_group_t *group);
uint16_t neu_group_tag_size(const neu_group_t *group);
+64 -12
View File
@@ -189,16 +189,17 @@ static unsigned cpu_usage()
return (double) work / total * 100.0 * sysconf(_SC_NPROCESSORS_CONF);
}
static bool has_core_dumps()
static bool has_core_dump_in_dir(const char *dir, const char *prefix)
{
DIR *dp = opendir("core");
if (NULL == dp) {
DIR *dp = opendir(dir);
if (dp == NULL) {
return false;
}
bool found = false;
for (struct dirent *de = NULL; NULL != (de = readdir(dp));) {
if (0 == strncmp("core", de->d_name, 4)) {
struct dirent *de;
bool found = false;
while ((de = readdir(dp)) != NULL) {
if (strncmp(prefix, de->d_name, strlen(prefix)) == 0) {
found = true;
break;
}
@@ -208,6 +209,46 @@ static bool has_core_dumps()
return found;
}
static char *get_core_dir(const char *core_pattern)
{
char *last_slash = strrchr(core_pattern, '/');
if (last_slash != NULL) {
static char core_dir[256];
ptrdiff_t path_length = last_slash - core_pattern + 1;
strncpy(core_dir, core_pattern, path_length);
core_dir[path_length] = '\0';
return core_dir;
}
return NULL;
}
static bool has_core_dumps()
{
if (has_core_dump_in_dir("core", "core-neuron")) {
return true;
}
FILE *fp = fopen("/proc/sys/kernel/core_pattern", "r");
if (fp == NULL) {
return false;
}
char core_pattern[256];
if (fgets(core_pattern, sizeof(core_pattern), fp) == NULL) {
fclose(fp);
return false;
}
fclose(fp);
char *core_dir =
(core_pattern[0] == '|') ? "/var/crash/" : get_core_dir(core_pattern);
if (core_dir == NULL) {
return false;
}
return has_core_dump_in_dir(core_dir, "core-neuron");
}
static inline void metrics_unregister_entry(const char *name)
{
neu_metric_entry_t *e = NULL;
@@ -239,10 +280,19 @@ int neu_metric_entries_add(neu_metric_entry_t **entries, const char *name,
return -1;
}
entry->name = name;
entry->type = type;
entry->help = help;
entry->value = init;
if (NEU_METRIC_TYPE_ROLLING_COUNTER == type) {
// only allocate rolling counter for nonzero time span
if (init > 0 && NULL == (entry->rcnt = neu_rolling_counter_new(init))) {
free(entry);
return -1;
}
} else {
entry->value = init;
}
entry->name = name;
entry->type = type;
entry->help = help;
HASH_ADD_STR(*entries, name, entry);
return 0;
}
@@ -279,9 +329,11 @@ int neu_metrics_register_entry(const char *name, const char *help,
neu_metric_entry_t *e = NULL;
pthread_rwlock_wrlock(&g_metrics_mtx_);
// use `value` field as reference counter, initialize to zero
// and we don't need to allocate rolling counter for register entries
rv = neu_metric_entries_add(&g_metrics_.registered_metrics, name, help,
type, 1);
if (1 == rv) {
type, 0);
if (-1 != rv) {
HASH_FIND_STR(g_metrics_.registered_metrics, name, e);
++e->value;
rv = 0;
+68
View File
@@ -0,0 +1,68 @@
/**
* 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.
**/
#include "msg.h"
#include "utils/log.h"
#include "msg_internal.h"
void neu_msg_gen(neu_reqresp_head_t *header, void *data)
{
size_t data_size = neu_reqresp_size(header->type);
assert(header->len >= sizeof(neu_reqresp_head_t) + data_size);
memcpy((uint8_t *) &header[1], data, data_size);
}
neu_reqresp_head_t *neu_msg_dup(neu_reqresp_head_t *header)
{
neu_reqresp_head_t *new_header = calloc(1, header->len);
*new_header = *header;
switch (new_header->type) {
case NEU_REQ_WRITE_TAG: {
neu_req_write_tag_t *wt = (neu_req_write_tag_t *) &header[1];
neu_req_write_tag_t *new_wt = (neu_req_write_tag_t *) &new_header[1];
*new_wt = *wt;
break;
}
case NEU_REQ_WRITE_TAGS: {
neu_req_write_tags_t *wts = (neu_req_write_tags_t *) &header[1];
neu_req_write_tags_t *new_wts = (neu_req_write_tags_t *) &new_header[1];
*new_wts = *wts;
break;
}
case NEU_REQ_WRITE_GTAGS: {
neu_req_write_gtags_t *wgts = (neu_req_write_gtags_t *) &header[1];
neu_req_write_gtags_t *new_wgts =
(neu_req_write_gtags_t *) &new_header[1];
*new_wgts = *wgts;
break;
}
default:
nlog_warn("unsupport msg type %d", new_header->type);
assert(false);
}
memcpy(&new_header[1], &header[1], header->len - sizeof(*header));
return new_header;
}
+293
View File
@@ -0,0 +1,293 @@
/**
* 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_MSG_INTERNAL_H
#define NEURON_MSG_INTERNAL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <sys/socket.h>
#include <sys/types.h>
#include "msg.h"
#define NEU_REQRESP_TYPE_MAP(XX) \
XX(NEU_RESP_ERROR, neu_resp_error_t) \
XX(NEU_REQ_READ_GROUP, neu_req_read_group_t) \
XX(NEU_RESP_READ_GROUP, neu_resp_read_group_t) \
XX(NEU_REQ_WRITE_TAG, neu_req_write_tag_t) \
XX(NEU_REQ_WRITE_TAGS, neu_req_write_tags_t) \
XX(NEU_REQ_WRITE_GTAGS, neu_req_write_gtags_t) \
XX(NEU_REQ_SUBSCRIBE_GROUP, neu_req_subscribe_t) \
XX(NEU_REQ_UNSUBSCRIBE_GROUP, neu_req_unsubscribe_t) \
XX(NEU_REQ_UPDATE_SUBSCRIBE_GROUP, neu_req_subscribe_t) \
XX(NEU_REQ_SUBSCRIBE_GROUPS, neu_req_subscribe_groups_t) \
XX(NEU_REQ_GET_SUBSCRIBE_GROUP, neu_req_get_subscribe_group_t) \
XX(NEU_RESP_GET_SUBSCRIBE_GROUP, neu_resp_get_subscribe_group_t) \
XX(NEU_REQ_GET_SUB_DRIVER_TAGS, neu_req_get_sub_driver_tags_t) \
XX(NEU_RESP_GET_SUB_DRIVER_TAGS, neu_resp_get_sub_driver_tags_t) \
XX(NEU_REQ_NODE_INIT, neu_req_node_init_t) \
XX(NEU_REQ_NODE_UNINIT, neu_req_node_uninit_t) \
XX(NEU_RESP_NODE_UNINIT, neu_resp_node_uninit_t) \
XX(NEU_REQ_ADD_NODE, neu_req_add_node_t) \
XX(NEU_REQ_UPDATE_NODE, neu_req_update_node_t) \
XX(NEU_REQ_DEL_NODE, neu_req_del_node_t) \
XX(NEU_REQ_GET_NODE, neu_req_get_node_t) \
XX(NEU_RESP_GET_NODE, neu_resp_get_node_t) \
XX(NEU_REQ_NODE_SETTING, neu_req_node_setting_t) \
XX(NEU_REQ_GET_NODE_SETTING, neu_req_get_node_setting_t) \
XX(NEU_RESP_GET_NODE_SETTING, neu_resp_get_node_setting_t) \
XX(NEU_REQ_GET_NODE_STATE, neu_req_get_node_state_t) \
XX(NEU_RESP_GET_NODE_STATE, neu_resp_get_node_state_t) \
XX(NEU_REQ_GET_NODES_STATE, neu_req_get_nodes_state_t) \
XX(NEU_RESP_GET_NODES_STATE, neu_resp_get_nodes_state_t) \
XX(NEU_REQ_NODE_CTL, neu_req_node_ctl_t) \
XX(NEU_REQ_NODE_RENAME, neu_req_node_rename_t) \
XX(NEU_RESP_NODE_RENAME, neu_resp_node_rename_t) \
XX(NEU_REQ_ADD_GROUP, neu_req_add_group_t) \
XX(NEU_REQ_DEL_GROUP, neu_req_del_group_t) \
XX(NEU_REQ_UPDATE_GROUP, neu_req_update_group_t) \
XX(NEU_REQ_UPDATE_DRIVER_GROUP, neu_req_update_group_t) \
XX(NEU_RESP_UPDATE_DRIVER_GROUP, neu_resp_update_group_t) \
XX(NEU_REQ_GET_GROUP, neu_req_get_group_t) \
XX(NEU_RESP_GET_GROUP, neu_resp_get_group_t) \
XX(NEU_REQ_GET_DRIVER_GROUP, neu_req_get_group_t) \
XX(NEU_RESP_GET_DRIVER_GROUP, neu_resp_get_driver_group_t) \
XX(NEU_REQ_ADD_TAG, neu_req_add_tag_t) \
XX(NEU_RESP_ADD_TAG, neu_resp_add_tag_t) \
XX(NEU_REQ_DEL_TAG, neu_req_del_tag_t) \
XX(NEU_REQ_UPDATE_TAG, neu_req_update_tag_t) \
XX(NEU_RESP_UPDATE_TAG, neu_resp_update_tag_t) \
XX(NEU_REQ_GET_TAG, neu_req_get_tag_t) \
XX(NEU_RESP_GET_TAG, neu_resp_get_tag_t) \
XX(NEU_REQ_ADD_PLUGIN, neu_req_add_plugin_t) \
XX(NEU_REQ_DEL_PLUGIN, neu_req_del_plugin_t) \
XX(NEU_REQ_GET_PLUGIN, neu_req_get_plugin_t) \
XX(NEU_RESP_GET_PLUGIN, neu_resp_get_plugin_t) \
XX(NEU_REQ_ADD_TEMPLATE, neu_req_add_template_t) \
XX(NEU_REQ_DEL_TEMPLATE, neu_req_del_template_t) \
XX(NEU_REQ_GET_TEMPLATE, neu_req_get_template_t) \
XX(NEU_RESP_GET_TEMPLATE, neu_resp_get_template_t) \
XX(NEU_REQ_GET_TEMPLATES, neu_req_get_templates_t) \
XX(NEU_RESP_GET_TEMPLATES, neu_resp_get_templates_t) \
XX(NEU_REQ_ADD_TEMPLATE_GROUP, neu_req_add_template_group_t) \
XX(NEU_REQ_DEL_TEMPLATE_GROUP, neu_req_del_template_group_t) \
XX(NEU_REQ_UPDATE_TEMPLATE_GROUP, neu_req_update_template_group_t) \
XX(NEU_REQ_GET_TEMPLATE_GROUP, neu_req_get_template_group_t) \
XX(NEU_REQ_ADD_TEMPLATE_TAG, neu_req_add_template_tag_t) \
XX(NEU_RESP_ADD_TEMPLATE_TAG, neu_resp_add_tag_t) \
XX(NEU_REQ_DEL_TEMPLATE_TAG, neu_req_del_template_tag_t) \
XX(NEU_REQ_UPDATE_TEMPLATE_TAG, neu_req_update_template_tag_t) \
XX(NEU_RESP_UPDATE_TEMPLATE_TAG, neu_resp_update_tag_t) \
XX(NEU_REQ_GET_TEMPLATE_TAG, neu_req_get_template_tag_t) \
XX(NEU_RESP_GET_TEMPLATE_TAG, neu_resp_get_tag_t) \
XX(NEU_REQ_INST_TEMPLATE, neu_req_inst_template_t) \
XX(NEU_REQ_INST_TEMPLATES, neu_req_inst_templates_t) \
XX(NEU_REQRESP_TRANS_DATA, neu_reqresp_trans_data_t) \
XX(NEU_REQRESP_NODES_STATE, neu_reqresp_nodes_state_t) \
XX(NEU_REQRESP_NODE_DELETED, neu_reqresp_node_deleted_t) \
XX(NEU_REQ_ADD_NDRIVER_MAP, neu_req_ndriver_map_t) \
XX(NEU_REQ_DEL_NDRIVER_MAP, neu_req_ndriver_map_t) \
XX(NEU_REQ_GET_NDRIVER_MAPS, neu_req_get_ndriver_maps_t) \
XX(NEU_RESP_GET_NDRIVER_MAPS, neu_resp_get_ndriver_maps_t) \
XX(NEU_REQ_UPDATE_NDRIVER_TAG_PARAM, neu_req_update_ndriver_tag_param_t) \
XX(NEU_REQ_UPDATE_NDRIVER_TAG_INFO, neu_req_update_ndriver_tag_info_t) \
XX(NEU_REQ_GET_NDRIVER_TAGS, neu_req_get_ndriver_tags_t) \
XX(NEU_RESP_GET_NDRIVER_TAGS, neu_resp_get_ndriver_tags_t) \
XX(NEU_REQ_UPDATE_LOG_LEVEL, neu_req_update_log_level_t) \
XX(NEU_REQ_ADD_NODE_EVENT, neu_req_add_node_t) \
XX(NEU_REQ_DEL_NODE_EVENT, neu_req_del_node_t) \
XX(NEU_REQ_NODE_CTL_EVENT, neu_req_node_ctl_t) \
XX(NEU_REQ_NODE_SETTING_EVENT, neu_req_node_setting_t) \
XX(NEU_REQ_ADD_GROUP_EVENT, neu_req_add_group_t) \
XX(NEU_REQ_DEL_GROUP_EVENT, neu_req_del_group_t) \
XX(NEU_REQ_UPDATE_GROUP_EVENT, neu_req_update_group_t) \
XX(NEU_REQ_ADD_TAG_EVENT, neu_req_add_tag_t) \
XX(NEU_REQ_DEL_TAG_EVENT, neu_req_del_tag_t) \
XX(NEU_REQ_UPDATE_TAG_EVENT, neu_req_update_tag_t)
static inline size_t neu_reqresp_size(neu_reqresp_type_e t)
{
switch (t) {
#define XX(type, structure) \
case type: \
return sizeof(structure);
NEU_REQRESP_TYPE_MAP(XX)
#undef XX
default:
assert(false);
}
return 0;
}
#define XX(type, structure) structure type##_data;
union neu_reqresp_u {
NEU_REQRESP_TYPE_MAP(XX)
};
#define NEU_REQRESP_MAX_SIZE sizeof(union neu_reqresp_u)
#undef XX
struct neu_msg_s {
neu_reqresp_head_t head;
// NOTE: we keep the data layout intact only to save refactor efforts.
// FIXME: potential alignment problem here.
neu_reqresp_head_t body[];
};
typedef struct neu_msg_s neu_msg_t;
static inline neu_msg_t *neu_msg_new(neu_reqresp_type_e t, void *ctx,
void *data)
{
size_t data_size = neu_reqresp_size(t);
// NOTE: ensure enough space to reuse message
size_t body_size = 0;
switch (t) {
case NEU_REQ_GET_PLUGIN:
body_size = neu_reqresp_size(NEU_RESP_GET_PLUGIN);
break;
case NEU_REQ_UPDATE_GROUP:
case NEU_REQ_UPDATE_DRIVER_GROUP:
body_size = neu_reqresp_size(NEU_RESP_UPDATE_DRIVER_GROUP);
break;
case NEU_REQ_UPDATE_NODE:
case NEU_REQ_NODE_RENAME:
body_size = neu_reqresp_size(NEU_RESP_NODE_RENAME);
break;
case NEU_REQ_DEL_NODE:
body_size = neu_reqresp_size(NEU_RESP_NODE_UNINIT);
break;
case NEU_REQ_GET_NODE_SETTING:
body_size = neu_reqresp_size(NEU_RESP_GET_NODE_SETTING);
break;
case NEU_REQ_GET_NODES_STATE:
body_size = neu_reqresp_size(NEU_RESP_GET_NODES_STATE);
break;
case NEU_REQ_GET_TEMPLATE:
body_size = neu_reqresp_size(NEU_RESP_GET_TEMPLATE);
break;
case NEU_REQ_GET_TEMPLATES:
body_size = neu_reqresp_size(NEU_RESP_GET_TEMPLATES);
break;
case NEU_REQ_READ_GROUP:
body_size = neu_reqresp_size(NEU_RESP_READ_GROUP);
break;
default:
body_size = data_size;
}
size_t total = sizeof(neu_msg_t) + body_size;
neu_msg_t *msg = calloc(1, total);
if (msg) {
msg->head.type = t;
msg->head.len = total;
msg->head.ctx = ctx;
if (data) {
memcpy(msg->body, data, data_size);
}
}
return msg;
}
static inline neu_msg_t *neu_msg_copy(const neu_msg_t *other)
{
neu_msg_t *msg = calloc(1, other->head.len);
if (msg) {
memcpy(msg, other, other->head.len);
}
return msg;
}
static inline void neu_msg_free(neu_msg_t *msg)
{
if (msg) {
free(msg);
}
}
static inline size_t neu_msg_size(neu_msg_t *msg)
{
return msg->head.len;
}
static inline size_t neu_msg_body_size(neu_msg_t *msg)
{
return msg->head.len - sizeof(msg->head);
}
static inline void *neu_msg_get_header(neu_msg_t *msg)
{
return &msg->head;
}
static inline void *neu_msg_get_body(neu_msg_t *msg)
{
return &msg->body;
}
inline static int neu_send_msg(int fd, neu_msg_t *msg)
{
int ret = send(fd, &msg, sizeof(neu_msg_t *), 0);
return sizeof(neu_msg_t *) == ret ? 0 : ret;
}
inline static int neu_recv_msg(int fd, neu_msg_t **msg_p)
{
neu_msg_t *msg = NULL;
int ret = recv(fd, &msg, sizeof(neu_msg_t *), 0);
if (sizeof(neu_msg_t *) != ret) {
// recv may return 0 bytes
return 0 == ret ? -1 : ret;
}
*msg_p = msg;
return 0;
}
inline static int neu_send_msg_to(int fd, struct sockaddr_in *addr,
neu_msg_t *msg)
{
int ret = sendto(fd, &msg, sizeof(neu_msg_t *), 0, (struct sockaddr *) addr,
sizeof(*addr));
return sizeof(neu_msg_t *) == ret ? 0 : ret;
}
inline static int neu_recv_msg_from(int fd, struct sockaddr_in *addr,
neu_msg_t **msg_p)
{
neu_msg_t *msg = NULL;
socklen_t addr_len = sizeof(struct sockaddr_in);
int ret = recvfrom(fd, &msg, sizeof(neu_msg_t *), 0,
(struct sockaddr *) addr, &addr_len);
if (sizeof(neu_msg_t *) != ret) {
// recvfrom may return 0 bytes
return 0 == ret ? -1 : ret;
}
*msg_p = msg;
return 0;
}
#ifdef __cplusplus
}
#endif
#endif
-1
View File
@@ -31,7 +31,6 @@ void neu_plugin_common_init(neu_plugin_common_t *common)
{
common->magic = NEU_PLUGIN_MAGIC_NUMBER;
common->link_state = NEU_NODE_LINK_STATE_DISCONNECTED;
strcpy(common->log_level, NEU_LOG_LEVEL_NOTICE);
}
bool neu_plugin_common_check(neu_plugin_t *plugin)
+27 -13
View File
@@ -242,21 +242,35 @@ int neu_datatag_parse_addr_option(const neu_datatag_t * datatag,
case NEU_TYPE_UINT64: {
char *op = find_last_character(datatag->address, '#');
option->value64.endian = NEU_DATATAG_ENDIAN_L64;
option->value64.endian = NEU_DATATAG_ENDIAN_L64;
option->value64.is_default = true;
if (op != NULL) {
char e = 0;
sscanf(op, "#%c", &e);
char e1 = 0;
char e2 = 0;
int n = sscanf(op, "#%c%c", &e1, &e2);
switch (e) {
case 'B':
option->value64.endian = NEU_DATATAG_ENDIAN_B64;
break;
case 'L':
option->value64.endian = NEU_DATATAG_ENDIAN_L64;
break;
default:
option->value64.endian = NEU_DATATAG_ENDIAN_L64;
break;
if (n == 2) {
if (e1 == 'B' && e2 == 'B') {
option->value64.endian = NEU_DATATAG_ENDIAN_BB64;
option->value64.is_default = false;
} else if (e1 == 'B' && e2 == 'L') {
option->value64.endian = NEU_DATATAG_ENDIAN_BL64;
option->value64.is_default = false;
} else if (e1 == 'L' && e2 == 'L') {
option->value64.endian = NEU_DATATAG_ENDIAN_LL64;
option->value64.is_default = false;
} else if (e1 == 'L' && e2 == 'B') {
option->value64.endian = NEU_DATATAG_ENDIAN_LB64;
option->value64.is_default = false;
}
} else if (n == 1) {
if (e1 == 'B') {
option->value64.endian = NEU_DATATAG_ENDIAN_B64;
option->value64.is_default = false;
} else if (e1 == 'L') {
option->value64.endian = NEU_DATATAG_ENDIAN_L64;
option->value64.is_default = false;
}
}
}
+27 -9
View File
@@ -347,8 +347,8 @@ ssize_t neu_conn_send(neu_conn_t *conn, uint8_t *buf, ssize_t len)
break;
}
} else {
if (rc == -1 && errno == EAGAIN) {
if (retry > 50) {
if (!conn->block && rc == -1 && errno == EAGAIN) {
if (retry > 10) {
zlog_error(conn->param.log,
"conn fd: %d, send buf len: %zd, ret: %zd, "
"errno: %s(%d)",
@@ -830,7 +830,14 @@ static void conn_connect(neu_conn_t *conn)
return;
}
if (ret != 0 && errno != EINPROGRESS) {
if ((conn->block && ret == 0) ||
(!conn->block && ret != 0 && errno == EINPROGRESS)) {
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;
} else {
close(fd);
zlog_error(conn->param.log, "connect %s:%d error: %s(%d)",
conn->param.params.tcp_client.ip,
@@ -838,13 +845,8 @@ static void conn_connect(neu_conn_t *conn)
errno);
conn->is_connected = false;
return;
} else {
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;
}
break;
}
case NEU_CONN_UDP: {
@@ -1282,10 +1284,18 @@ int neu_conn_stream_consume(neu_conn_t *conn, void *context,
neu_conn_disconnect(conn);
break;
} else {
pthread_mutex_lock(&conn->mtx);
if (conn->offset - used < 0) {
pthread_mutex_unlock(&conn->mtx);
zlog_warn(conn->param.log, "reset offset: %d, used: %d",
conn->offset, used);
return -1;
}
conn->offset -= used;
memmove(conn->buf, conn->buf + used, conn->offset);
neu_protocol_unpack_buf_init(&protocol_buf, conn->buf,
conn->offset);
pthread_mutex_unlock(&conn->mtx);
}
}
}
@@ -1311,10 +1321,18 @@ int neu_conn_stream_tcp_server_consume(neu_conn_t *conn, int fd, void *context,
neu_conn_tcp_server_close_client(conn, fd);
break;
} else {
pthread_mutex_lock(&conn->mtx);
if (conn->offset - used < 0) {
pthread_mutex_unlock(&conn->mtx);
zlog_warn(conn->param.log, "reset offset: %d, used: %d",
conn->offset, used);
return -1;
}
conn->offset -= used;
memmove(conn->buf, conn->buf + used, conn->offset);
neu_protocol_unpack_buf_init(&protocol_buf, conn->buf,
conn->offset);
pthread_mutex_unlock(&conn->mtx);
}
}
}
+7 -2
View File
@@ -433,8 +433,10 @@ static void connect_cb(nng_pipe p, nng_pipe_ev ev, void *arg)
neu_mqtt_client_t * client = arg;
neu_mqtt_client_connection_cb_t cb = NULL;
void * data = NULL;
int reason = 0;
log(notice, "mqtt client connected");
nng_pipe_get_int(p, NNG_OPT_MQTT_CONNECT_REASON, &reason);
log(notice, "mqtt client connected, reason: %d", reason);
nng_mtx_lock(client->mtx);
// start receiving
@@ -459,8 +461,11 @@ static void disconnect_cb(nng_pipe p, nng_pipe_ev ev, void *arg)
subscription_t * sub = NULL;
neu_mqtt_client_connection_cb_t cb = NULL;
void * data = NULL;
int reason = 0;
nng_pipe_get_int(p, NNG_OPT_MQTT_DISCONNECT_REASON, &reason);
log(notice, "mqtt client disconnected, reason: %d", reason);
log(notice, "mqtt client disconnected");
nng_mtx_lock(client->mtx);
client->connected = false;
cb = client->disconnect_cb;
+160 -132
View File
@@ -32,6 +32,7 @@
#include "adapter.h"
#include "adapter/adapter_internal.h"
#include "adapter/driver/driver_internal.h"
#include "base/msg_internal.h"
#include "errcodes.h"
#include "node_manager.h"
@@ -51,6 +52,9 @@ inline static void reply(neu_manager_t *manager, neu_reqresp_head_t *header,
void *data);
inline static void forward_msg(neu_manager_t * manager,
neu_reqresp_head_t *header, const char *node);
inline static void forward_msg_copy(neu_manager_t * manager,
neu_reqresp_head_t *header,
const char * node);
// inline static nng_msg *trans_data_dup(nng_msg *msg);
// inline static void trans_data_free(nng_msg *msg);
@@ -92,6 +96,7 @@ neu_manager_t *neu_manager_create()
manager->node_manager = neu_node_manager_create();
manager->subscribe_manager = neu_subscribe_manager_create();
manager->template_manager = neu_template_manager_create();
manager->log_level = ZLOG_LEVEL_NOTICE;
manager->server_fd =
socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP);
@@ -149,25 +154,21 @@ neu_manager_t *neu_manager_create()
void neu_manager_destroy(neu_manager_t *manager)
{
memset(manager->buf, 0, sizeof(manager->buf));
neu_reqresp_head_t *header = (neu_reqresp_head_t *) manager->buf;
neu_req_node_init_t uninit = { 0 };
UT_array *addrs = neu_node_manager_get_addrs_all(manager->node_manager);
neu_event_del_timer(manager->events, manager->timer_timestamp);
header->type = NEU_REQ_NODE_UNINIT;
strcpy(header->sender, "manager");
utarray_foreach(addrs, struct sockaddr_in *, addr)
{
neu_msg_gen(header, &uninit);
if (sendto(manager->server_fd, manager->buf, header->len, 0,
(struct sockaddr *) addr,
sizeof(struct sockaddr_in)) != (int) header->len) {
neu_msg_t *msg = neu_msg_new(NEU_REQ_NODE_UNINIT, NULL, &uninit);
neu_reqresp_head_t *header = neu_msg_get_header(msg);
strcpy(header->sender, "manager");
if (0 != neu_send_msg_to(manager->server_fd, addr, msg)) {
nlog_error("manager -> %s uninit msg send fail",
inet_ntoa((*addr).sin_addr));
neu_msg_free(msg);
}
}
utarray_free(addrs);
@@ -196,8 +197,8 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
{
int rv = 0;
neu_manager_t * manager = (neu_manager_t *) usr_data;
socklen_t addr_len = sizeof(struct sockaddr_in);
struct sockaddr_in src_addr = { 0 };
neu_msg_t * msg = NULL;
neu_reqresp_head_t *header = NULL;
if (type == NEU_EVENT_IO_CLOSED || type == NEU_EVENT_IO_HUP) {
@@ -205,16 +206,13 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
return 0;
}
memset(manager->recv_buf, 0, sizeof(manager->recv_buf));
rv = recvfrom(manager->server_fd, manager->recv_buf,
sizeof(manager->recv_buf), 0, (struct sockaddr *) &src_addr,
&addr_len);
rv = neu_recv_msg_from(manager->server_fd, &src_addr, &msg);
if (rv == -1) {
nlog_warn("manager recv msg error: %s(%d)", strerror(errno), errno);
return 0;
}
header = (neu_reqresp_head_t *) manager->recv_buf;
header = neu_msg_get_header(msg);
nlog_info("manager recv msg from: %s to %s, type: %s", header->sender,
header->receiver, neu_reqresp_type_string(header->type));
@@ -227,10 +225,12 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
src_addr)) {
nlog_warn("bind node %s to src addr(%d) fail", init->node,
ntohs(src_addr.sin_port));
neu_msg_free(msg);
break;
}
if (init->state == NEU_NODE_RUNNING_STATE_RUNNING ||
if (init->state == NEU_NODE_RUNNING_STATE_READY ||
init->state == NEU_NODE_RUNNING_STATE_RUNNING ||
init->state == NEU_NODE_RUNNING_STATE_STOPPED) {
neu_adapter_t *adapter =
neu_node_manager_find(manager->node_manager, init->node);
@@ -242,6 +242,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
nlog_notice("bind node %s to src addr(%d)", init->node,
ntohs(src_addr.sin_port));
neu_msg_free(msg);
break;
}
case NEU_REQ_ADD_PLUGIN: {
@@ -600,22 +601,42 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
manager_storage_del_node(manager, cmd->node);
if (neu_adapter_get_type(adapter) == NEU_NA_TYPE_APP) {
UT_array *subscriptions = neu_subscribe_manager_get(
manager->subscribe_manager, cmd->node);
neu_subscribe_manager_unsub_all(manager->subscribe_manager,
cmd->node);
utarray_foreach(subscriptions, neu_resp_subscribe_info_t *, sub)
{
// NOTE: neu_req_unsubscribe_t and neu_resp_subscribe_info_t
// have compatible memory layout
msg = neu_msg_new(NEU_REQ_UNSUBSCRIBE_GROUP, NULL, sub);
if (NULL == msg) {
break;
}
neu_reqresp_head_t *hd = neu_msg_get_header(msg);
strcpy(hd->receiver, sub->driver);
strcpy(hd->sender, "manager");
forward_msg(manager, hd, hd->receiver);
}
utarray_free(subscriptions);
}
notify_monitors(manager, NEU_REQ_DEL_NODE_EVENT, cmd);
neu_reqresp_node_deleted_t resp = { 0 };
strcpy(resp.node, header->receiver);
header->type = NEU_REQ_NODE_UNINIT;
forward_msg(manager, header, header->receiver);
notify_monitors(manager, NEU_REQ_DEL_NODE_EVENT, cmd);
if (neu_adapter_get_type(adapter) == NEU_NA_TYPE_DRIVER) {
UT_array *apps = neu_subscribe_manager_find_by_driver(
manager->subscribe_manager, cmd->node);
manager->subscribe_manager, resp.node);
utarray_foreach(apps, neu_app_subscribe_t *, app)
{
neu_reqresp_node_deleted_t resp = { 0 };
header->type = NEU_REQRESP_NODE_DELETED;
strcpy(resp.node, header->receiver);
msg = neu_msg_new(NEU_REQRESP_NODE_DELETED, NULL, &resp);
if (NULL == msg) {
break;
}
header = neu_msg_get_header(msg);
strcpy(header->receiver, app->app_name);
strcpy(header->sender, "manager");
reply(manager, header, &resp);
@@ -634,6 +655,8 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
neu_resp_error_t error = { 0 };
header->type = NEU_RESP_ERROR;
reply(manager, header, &error);
} else {
neu_msg_free(msg);
}
break;
}
@@ -658,8 +681,8 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
if (error.error == NEU_ERR_SUCCESS) {
cmd->port = app_port;
forward_msg(manager, header, cmd->app);
forward_msg(manager, header, cmd->driver);
forward_msg_copy(manager, header, cmd->app);
forward_msg_copy(manager, header, cmd->driver);
manager_storage_subscribe(manager, cmd->app, cmd->driver,
cmd->group, cmd->params);
} else {
@@ -711,7 +734,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
manager, cmd->app, cmd->driver, cmd->group, cmd->params);
if (error.error == NEU_ERR_SUCCESS) {
forward_msg(manager, header, cmd->app);
forward_msg_copy(manager, header, cmd->app);
manager_storage_update_subscribe(manager, cmd->app, cmd->driver,
cmd->group, cmd->params);
} else {
@@ -731,8 +754,8 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
neu_manager_unsubscribe(manager, cmd->app, cmd->driver, cmd->group);
if (error.error == NEU_ERR_SUCCESS) {
forward_msg(manager, header, cmd->app);
forward_msg(manager, header, cmd->driver);
forward_msg_copy(manager, header, cmd->app);
forward_msg_copy(manager, header, cmd->driver);
manager_storage_unsubscribe(manager, cmd->app, cmd->driver,
cmd->group);
}
@@ -787,11 +810,8 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
neu_resp_get_nodes_state_t resp = { 0 };
UT_array *states = neu_node_manager_get_state(manager->node_manager);
neu_adapter_t *adapter_core =
neu_node_manager_find(manager->node_manager, "default-dashboard");
strcpy(resp.core_level,
neu_plugin_to_plugin_common(adapter_core->plugin)->log_level);
resp.states = utarray_clone(states);
resp.core_level = manager->log_level;
resp.states = utarray_clone(states);
strcpy(header->receiver, header->sender);
strcpy(header->sender, "manager");
@@ -826,6 +846,15 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
case NEU_REQ_ADD_GROUP: {
if (neu_node_manager_find(manager->node_manager, header->receiver) ==
NULL) {
if (NEU_REQ_READ_GROUP == header->type) {
neu_req_read_group_fini((neu_req_read_group_t *) &header[1]);
} else if (NEU_REQ_WRITE_TAG == header->type) {
neu_req_write_tag_fini((neu_req_write_tag_t *) &header[1]);
} else if (NEU_REQ_WRITE_TAGS == header->type) {
neu_req_write_tags_fini((neu_req_write_tags_t *) &header[1]);
} else if (NEU_REQ_WRITE_GTAGS == header->type) {
neu_req_write_gtags_fini((neu_req_write_gtags_t *) &header[1]);
}
neu_resp_error_t e = { .error = NEU_ERR_NODE_NOT_EXIST };
header->type = NEU_RESP_ERROR;
neu_msg_exchange(header);
@@ -845,13 +874,6 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
neu_msg_exchange(header);
reply(manager, header, &e);
} else {
neu_resp_get_node_state_t *resp =
(neu_resp_get_node_state_t *) &header[1];
neu_adapter_t *adapter_core = neu_node_manager_find(
manager->node_manager, "default-dashboard");
strcpy(
resp->core_level,
neu_plugin_to_plugin_common(adapter_core->plugin)->log_level);
forward_msg(manager, header, header->receiver);
}
@@ -873,7 +895,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
utarray_foreach(apps, neu_app_subscribe_t *, app)
{
header->type = NEU_REQ_UPDATE_NODE;
forward_msg(manager, header, app->app_name);
forward_msg_copy(manager, header, app->app_name);
}
utarray_free(apps);
@@ -900,7 +922,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
utarray_foreach(apps, neu_app_subscribe_t *, app)
{
header->type = NEU_REQ_UPDATE_GROUP;
forward_msg(manager, header, app->app_name);
forward_msg_copy(manager, header, app->app_name);
}
utarray_free(apps);
@@ -924,6 +946,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
case NEU_REQ_DEL_TAG_EVENT:
case NEU_REQ_UPDATE_TAG_EVENT: {
notify_monitors(manager, header->type, &header[1]);
neu_msg_free(msg);
break;
}
@@ -960,9 +983,24 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
neu_msg_exchange(header);
reply(manager, header, &e);
} else {
UT_array *apps = neu_subscribe_manager_find(
manager->subscribe_manager, cmd->driver, cmd->group);
forward_msg(manager, header, header->receiver);
neu_subscribe_manager_remove(manager->subscribe_manager,
cmd->driver, cmd->group);
if (NULL == apps) {
break;
}
// notify app node about group deletion
utarray_foreach(apps, neu_app_subscribe_t *, app)
{
forward_msg_copy(manager, header, app->app_name);
}
utarray_free(apps);
}
break;
}
@@ -971,14 +1009,14 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
if (neu_node_manager_find(manager->node_manager, header->receiver) ==
NULL) {
neu_resp_error_t e = { .error = NEU_ERR_NODE_NOT_EXIST };
header->type = NEU_RESP_ERROR;
neu_msg_exchange(header);
reply(manager, header, &e);
for (int i = 0; i < cmd->n_tag; i++) {
free(cmd->tags[i]);
}
free(cmd->tags);
neu_resp_error_t e = { .error = NEU_ERR_NODE_NOT_EXIST };
header->type = NEU_RESP_ERROR;
neu_msg_exchange(header);
reply(manager, header, &e);
} else {
forward_msg(manager, header, header->receiver);
}
@@ -991,14 +1029,14 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
if (neu_node_manager_find(manager->node_manager, header->receiver) ==
NULL) {
neu_resp_error_t e = { .error = NEU_ERR_NODE_NOT_EXIST };
header->type = NEU_RESP_ERROR;
neu_msg_exchange(header);
reply(manager, header, &e);
for (int i = 0; i < cmd->n_tag; i++) {
neu_tag_fini(&cmd->tags[i]);
}
free(cmd->tags);
neu_resp_error_t e = { .error = NEU_ERR_NODE_NOT_EXIST };
header->type = NEU_RESP_ERROR;
neu_msg_exchange(header);
reply(manager, header, &e);
} else {
forward_msg(manager, header, header->receiver);
}
@@ -1010,11 +1048,11 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
if (neu_node_manager_find(manager->node_manager, header->receiver) ==
NULL) {
free(cmd->setting);
neu_resp_error_t e = { .error = NEU_ERR_NODE_NOT_EXIST };
header->type = NEU_RESP_ERROR;
neu_msg_exchange(header);
reply(manager, header, &e);
free(cmd->setting);
} else {
forward_msg(manager, header, header->receiver);
}
@@ -1030,12 +1068,19 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
case NEU_RESP_GET_NDRIVER_TAGS:
case NEU_RESP_GET_GROUP:
case NEU_RESP_GET_NODE_SETTING:
case NEU_RESP_GET_NODE_STATE:
case NEU_RESP_ERROR:
case NEU_RESP_READ_GROUP:
forward_msg(manager, header, header->receiver);
break;
case NEU_RESP_GET_NODE_STATE: {
neu_resp_get_node_state_t *resp =
(neu_resp_get_node_state_t *) &header[1];
resp->core_level = manager->log_level;
forward_msg(manager, header, header->receiver);
break;
}
case NEU_REQ_ADD_NDRIVER_MAP: {
neu_req_ndriver_map_t *cmd = (neu_req_ndriver_map_t *) &header[1];
neu_resp_error_t error = { 0 };
@@ -1043,7 +1088,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
error.error = neu_manager_add_ndriver_map(manager, cmd->ndriver,
cmd->driver, cmd->group);
if (error.error == NEU_ERR_SUCCESS) {
forward_msg(manager, header, cmd->ndriver);
forward_msg_copy(manager, header, cmd->ndriver);
manager_storage_add_ndriver_map(manager, cmd->ndriver, cmd->driver,
cmd->group);
}
@@ -1060,7 +1105,7 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
error.error = neu_manager_del_ndriver_map(manager, cmd->ndriver,
cmd->driver, cmd->group);
if (error.error == NEU_ERR_SUCCESS) {
forward_msg(manager, header, cmd->ndriver);
forward_msg_copy(manager, header, cmd->ndriver);
manager_storage_del_ndriver_map(manager, cmd->ndriver, cmd->driver,
cmd->group);
}
@@ -1117,59 +1162,25 @@ static int manager_loop(enum neu_event_io_type type, int fd, void *usr_data)
(neu_req_update_log_level_t *) &header[1];
if (cmd->core) {
if (strcmp(header->receiver, "") == 0) {
neu_adapter_t *adapter_core = neu_node_manager_find(
manager->node_manager, "default-dashboard");
strcpy(neu_plugin_to_plugin_common(adapter_core->plugin)
->log_level,
cmd->log_level);
neu_resp_error_t error = { 0 };
neu_msg_exchange(header);
header->type = NEU_RESP_ERROR;
reply(manager, header, &error);
} else {
if (neu_node_manager_find(manager->node_manager,
header->receiver) == NULL) {
neu_resp_error_t e = { .error = NEU_ERR_NODE_NOT_EXIST };
header->type = NEU_RESP_ERROR;
neu_msg_exchange(header);
reply(manager, header, &e);
} else {
neu_adapter_t *adapter_core = neu_node_manager_find(
manager->node_manager, "default-dashboard");
strcpy(neu_plugin_to_plugin_common(adapter_core->plugin)
->log_level,
cmd->log_level);
neu_adapter_t *adapter_log = neu_node_manager_find(
manager->node_manager, header->receiver);
strcpy(neu_plugin_to_plugin_common(adapter_log->plugin)
->log_level,
cmd->log_level);
forward_msg(manager, header, header->receiver);
}
}
} else {
if (strcmp(header->receiver, "") == 0) {
neu_resp_error_t e = { .error = NEU_ERR_PARAM_IS_WRONG };
manager->log_level = cmd->log_level;
nlog_level_change(manager->log_level);
}
if (strlen(cmd->node) > 0) {
if (neu_node_manager_find(manager->node_manager,
header->receiver) == NULL) {
neu_resp_error_t e = { .error = NEU_ERR_NODE_NOT_EXIST };
header->type = NEU_RESP_ERROR;
neu_msg_exchange(header);
reply(manager, header, &e);
} else {
if (neu_node_manager_find(manager->node_manager,
header->receiver) == NULL) {
neu_resp_error_t e = { .error = NEU_ERR_NODE_NOT_EXIST };
header->type = NEU_RESP_ERROR;
neu_msg_exchange(header);
reply(manager, header, &e);
} else {
neu_adapter_t *adapter_log = neu_node_manager_find(
manager->node_manager, header->receiver);
strcpy(neu_plugin_to_plugin_common(adapter_log->plugin)
->log_level,
cmd->log_level);
forward_msg(manager, header, header->receiver);
}
forward_msg(manager, header, header->receiver);
}
} else {
neu_resp_error_t e = { .error = NEU_ERR_SUCCESS };
header->type = NEU_RESP_ERROR;
neu_msg_exchange(header);
reply(manager, header, &e);
}
break;
@@ -1188,18 +1199,29 @@ inline static void forward_msg(neu_manager_t * manager,
struct sockaddr_in addr =
neu_node_manager_get_addr(manager->node_manager, node);
int ret = sendto(manager->server_fd, header, header->len, 0,
(struct sockaddr *) &addr, sizeof(addr));
if (ret != (int) header->len) {
nlog_warn("forward msg %s to node (%s)%d fail",
neu_reqresp_type_string(header->type), node,
ntohs(addr.sin_port));
neu_reqresp_type_e t = header->type;
char receiver[NEU_NODE_NAME_LEN] = { 0 };
strncpy(receiver, header->receiver, sizeof(receiver));
neu_msg_t *msg = (neu_msg_t *) header;
int ret = neu_send_msg_to(manager->server_fd, &addr, msg);
if (0 == ret) {
nlog_info("forward msg %s to %s", neu_reqresp_type_string(t), receiver);
} else {
nlog_info("forward msg %s to %s", neu_reqresp_type_string(header->type),
node);
nlog_warn("forward msg %s to node (%s)%d fail",
neu_reqresp_type_string(t), receiver, ntohs(addr.sin_port));
neu_msg_free(msg);
}
}
inline static void forward_msg_copy(neu_manager_t * manager,
neu_reqresp_head_t *header,
const char * node)
{
neu_msg_t *msg = neu_msg_copy((neu_msg_t *) header);
forward_msg(manager, neu_msg_get_header(msg), node);
}
struct notify_monitor_ctx {
neu_manager_t * manager;
neu_reqresp_type_e event;
@@ -1219,10 +1241,21 @@ static int notify_monitor(const char *name, struct sockaddr_in addr, void *arg)
return 0;
}
// message header
neu_msg_t *msg = neu_msg_new(ctx->event, NULL, data);
if (NULL == msg) {
return -1;
}
neu_reqresp_head_t *header = neu_msg_get_header(msg);
strcpy(header->sender, "manager");
strcpy(header->receiver, name);
// copy message data
switch (ctx->event) {
case NEU_REQ_NODE_SETTING_EVENT: {
if (0 != neu_req_node_setting_copy(&setting, ctx->data)) {
neu_msg_free(msg);
return -1;
}
data = &setting;
@@ -1231,6 +1264,7 @@ static int notify_monitor(const char *name, struct sockaddr_in addr, void *arg)
case NEU_REQ_ADD_TAG_EVENT:
case NEU_REQ_UPDATE_TAG_EVENT: {
if (0 != neu_req_add_tag_copy(&mod_tag, ctx->data)) {
neu_msg_free(msg);
return -1;
}
data = &mod_tag;
@@ -1238,6 +1272,7 @@ static int notify_monitor(const char *name, struct sockaddr_in addr, void *arg)
}
case NEU_REQ_DEL_TAG_EVENT: {
if (0 != neu_req_del_tag_copy(&del_tag, ctx->data)) {
neu_msg_free(msg);
return -1;
}
data = &del_tag;
@@ -1247,23 +1282,12 @@ static int notify_monitor(const char *name, struct sockaddr_in addr, void *arg)
data = ctx->data;
}
// message header
memset(ctx->manager->buf, 0, sizeof(ctx->manager->buf));
neu_reqresp_head_t *header = (neu_reqresp_head_t *) ctx->manager->buf;
strcpy(header->sender, "manager");
strcpy(header->receiver, name);
header->type = ctx->event;
// send message
neu_msg_gen(header, data);
int ret = sendto(ctx->manager->server_fd, header, header->len, 0,
(struct sockaddr *) &addr, sizeof(addr));
if (ret <= 0) {
int ret = neu_send_msg_to(ctx->manager->server_fd, &addr, msg);
if (0 != ret) {
nlog_warn("notify %s of %s, error: %s(%d)", header->receiver,
neu_reqresp_type_string(header->type), strerror(errno),
errno);
neu_msg_free(msg);
}
return 0;
@@ -1344,16 +1368,20 @@ inline static void reply(neu_manager_t *manager, neu_reqresp_head_t *header,
struct sockaddr_in addr =
neu_node_manager_get_addr(manager->node_manager, header->receiver);
int ret = sendto(manager->server_fd, header, header->len, 0,
(struct sockaddr *) &addr, sizeof(addr));
neu_reqresp_type_e t = header->type;
void * ctx = header->ctx;
char receiver[NEU_NODE_NAME_LEN] = { 0 };
strncpy(receiver, header->receiver, sizeof(receiver));
if (ret != (int) header->len) {
nlog_warn("reply %s to %s, error: %d",
neu_reqresp_type_string(header->type), header->receiver, ret);
neu_msg_t *msg = (neu_msg_t *) header;
int ret = neu_send_msg_to(manager->server_fd, &addr, msg);
if (0 == ret) {
nlog_notice("reply %s to %s(%d) %p", neu_reqresp_type_string(t),
receiver, ntohs(addr.sin_port), ctx);
} else {
nlog_notice("reply %s to %s(%d) %p",
neu_reqresp_type_string(header->type), header->receiver,
ntohs(addr.sin_port), header->ctx);
nlog_warn("reply %s to %s, error: %d", neu_reqresp_type_string(t),
receiver, ret);
neu_msg_free(msg);
}
}
@@ -1362,4 +1390,4 @@ static int update_timestamp(void *usr_data)
(void) usr_data;
global_timestamp = neu_time_ms();
return 0;
}
}
+33 -25
View File
@@ -26,6 +26,7 @@
#include "adapter/adapter_internal.h"
#include "adapter/driver/driver_internal.h"
#include "base/msg_internal.h"
#include "manager_internal.h"
#include "template_manager.h"
@@ -701,10 +702,11 @@ int neu_manager_subscribe(neu_manager_t *manager, const char *app,
// guard against empty mqtt topic parameter
// this is not an elegant solution due to the current architecture
if (params && 0 == strcmp(adapter->module->module_name, "MQTT")) {
neu_json_elem_t elem = { .name = "topic", .t = NEU_JSON_STR };
neu_json_decode((char *) params, 1, &elem);
neu_parse_param(params, NULL, 1, &elem);
if (elem.v.val_str && 0 == strlen(elem.v.val_str)) {
neu_json_elem_t elem = { .name = "topic",
.t = NEU_JSON_STR,
.v.val_str = NULL };
int ret = neu_parse_param(params, NULL, 1, &elem);
if (ret != 0 || (elem.v.val_str && 0 == strlen(elem.v.val_str))) {
free(elem.v.val_str);
return NEU_ERR_MQTT_SUBSCRIBE_FAILURE;
}
@@ -730,12 +732,6 @@ int neu_manager_send_subscribe(neu_manager_t *manager, const char *app,
const char *driver, const char *group,
uint16_t app_port, const char *params)
{
memset(manager->buf, 0, sizeof(manager->buf));
neu_reqresp_head_t *header = (neu_reqresp_head_t *) manager->buf;
header->type = NEU_REQ_SUBSCRIBE_GROUP;
strcpy(header->sender, "manager");
strcpy(header->receiver, app);
neu_req_subscribe_t cmd = { 0 };
strcpy(cmd.app, app);
strcpy(cmd.driver, driver);
@@ -746,35 +742,47 @@ int neu_manager_send_subscribe(neu_manager_t *manager, const char *app,
return NEU_ERR_EINTERNAL;
}
neu_msg_t *msg = neu_msg_new(NEU_REQ_SUBSCRIBE_GROUP, NULL, &cmd);
if (NULL == msg) {
free(cmd.params);
return NEU_ERR_EINTERNAL;
}
neu_reqresp_head_t *header = neu_msg_get_header(msg);
strcpy(header->sender, "manager");
strcpy(header->receiver, app);
struct sockaddr_in addr =
neu_node_manager_get_addr(manager->node_manager, app);
neu_msg_gen(header, &cmd);
int ret = sendto(manager->server_fd, header, header->len, 0,
(struct sockaddr *) &addr, sizeof(addr));
if (ret != (int) header->len) {
int ret = neu_send_msg_to(manager->server_fd, &addr, msg);
if (0 != ret) {
nlog_warn("send %s to %s app failed",
neu_reqresp_type_string(header->type), app);
neu_reqresp_type_string(NEU_REQ_SUBSCRIBE_GROUP), app);
free(cmd.params);
neu_msg_free(msg);
} else {
nlog_notice("send %s to %s app", neu_reqresp_type_string(header->type),
app);
nlog_notice("send %s to %s app",
neu_reqresp_type_string(NEU_REQ_SUBSCRIBE_GROUP), app);
}
cmd.params = NULL;
msg = neu_msg_new(NEU_REQ_SUBSCRIBE_GROUP, NULL, &cmd);
if (NULL == msg) {
return NEU_ERR_EINTERNAL;
}
header = neu_msg_get_header(msg);
strcpy(header->sender, "manager");
strcpy(header->receiver, driver);
addr = neu_node_manager_get_addr(manager->node_manager, driver);
neu_msg_gen(header, &cmd);
ret = sendto(manager->server_fd, header, header->len, 0,
(struct sockaddr *) &addr, sizeof(addr));
if (ret != (int) header->len) {
ret = neu_send_msg_to(manager->server_fd, &addr, msg);
if (0 != ret) {
nlog_warn("send %s to %s driver failed",
neu_reqresp_type_string(header->type), app);
neu_reqresp_type_string(NEU_REQ_SUBSCRIBE_GROUP), driver);
neu_msg_free(msg);
} else {
nlog_notice("send %s to %s driver",
neu_reqresp_type_string(header->type), app);
neu_reqresp_type_string(NEU_REQ_SUBSCRIBE_GROUP), driver);
}
return 0;
+4 -3
View File
@@ -29,9 +29,8 @@
#include "template_manager.h"
typedef struct neu_manager {
int server_fd;
uint8_t buf[NEU_MSG_MAX_SIZE];
uint8_t recv_buf[NEU_MSG_MAX_SIZE];
int server_fd;
neu_events_t * events;
neu_event_io_t *loop;
@@ -43,6 +42,8 @@ typedef struct neu_manager {
neu_event_timer_t *timer_timestamp;
int64_t timestamp_lev_manager;
int log_level;
} neu_manager_t;
int neu_manager_add_plugin(neu_manager_t *manager, const char *library);
+1 -2
View File
@@ -414,8 +414,7 @@ UT_array *neu_node_manager_get_state(neu_node_manager_t *mgr)
state.state.running = el->adapter->state;
state.state.link =
neu_plugin_to_plugin_common(el->adapter->plugin)->link_state;
strcpy(state.state.log_level,
neu_plugin_to_plugin_common(el->adapter->plugin)->log_level);
state.state.log_level = el->adapter->log_level;
neu_metric_entry_t *e = NULL;
if (NULL != el->adapter->metrics) {
HASH_FIND_STR(el->adapter->metrics->entries,
+8 -3
View File
@@ -149,9 +149,14 @@ int neuron_already_running()
fd = open(NEURON_DAEMON_LOCK_FNAME, O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (fd < 0) {
nlog_error("cannot open %s reason: %s\n", NEURON_DAEMON_LOCK_FNAME,
strerror(errno));
exit(1);
// work around fs.protected_regular
fd = open(NEURON_DAEMON_LOCK_FNAME, O_RDWR,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
if (fd < 0) {
nlog_error("cannot open %s reason: %s\n", NEURON_DAEMON_LOCK_FNAME,
strerror(errno));
exit(1);
}
}
// try to lock file
+28 -13
View File
@@ -66,6 +66,8 @@ struct event_data {
bool use;
};
#define EVENT_SIZE 1400
struct neu_events {
int epoll_fd;
pthread_t thread;
@@ -73,14 +75,14 @@ struct neu_events {
pthread_mutex_t mtx;
int n_event;
struct event_data event_datas[512];
struct event_data event_datas[EVENT_SIZE];
};
static int get_free_event(neu_events_t *events)
{
int ret = -1;
pthread_mutex_lock(&events->mtx);
for (int i = 0; i < 512; i++) {
for (int i = 0; i < EVENT_SIZE; i++) {
if (events->event_datas[i].use == false) {
events->event_datas[i].use = true;
events->event_datas[i].index = i;
@@ -180,8 +182,12 @@ neu_events_t *neu_event_new(void)
neu_events_t *events = calloc(1, sizeof(struct neu_events));
events->epoll_fd = epoll_create(1);
events->stop = false;
events->n_event = 0;
nlog_notice("create epoll: %d(%d)", events->epoll_fd, errno);
assert(events->epoll_fd > 0);
events->stop = false;
events->n_event = 0;
pthread_mutex_init(&events->mtx, NULL);
pthread_create(&events->thread, NULL, event_loop, events);
@@ -233,6 +239,7 @@ neu_event_timer_t *neu_event_add_timer(neu_events_t * events,
timer_ctx->event_data->usr_data = timer.usr_data;
timer_ctx->event_data->callback.timer = timer.cb;
timer_ctx->event_data->ctx.timer = events->event_datas[index].ctx.timer;
timer_ctx->event_data->index = index;
timer_ctx->value = value;
timer_ctx->fd = timer_fd;
@@ -245,17 +252,17 @@ neu_event_timer_t *neu_event_add_timer(neu_events_t * events,
zlog_notice(neuron,
"add timer, second: %" PRId64 ", millisecond: %" PRId64
", timer: %d in epoll %d, "
"ret: %d",
"ret: %d, index: %d",
timer.second, timer.millisecond, timer_fd, events->epoll_fd,
ret);
ret, index);
return timer_ctx;
}
int neu_event_del_timer(neu_events_t *events, neu_event_timer_t *timer)
{
zlog_notice(neuron, "del timer: %d from epoll: %d", timer->fd,
events->epoll_fd);
zlog_notice(neuron, "del timer: %d from epoll: %d, index: %d", timer->fd,
events->epoll_fd, timer->event_data->index);
timer->stop = true;
epoll_ctl(events->epoll_fd, EPOLL_CTL_DEL, timer->fd, NULL);
@@ -271,8 +278,13 @@ int neu_event_del_timer(neu_events_t *events, neu_event_timer_t *timer)
neu_event_io_t *neu_event_add_io(neu_events_t *events, neu_event_io_param_t io)
{
int ret = 0;
int index = get_free_event(events);
int ret = 0;
int index = get_free_event(events);
nlog_notice("add io, fd: %d, epoll: %d, index: %d", io.fd, events->epoll_fd,
index);
assert(index >= 0);
neu_event_io_t *io_ctx = &events->event_datas[index].ctx.io;
io_ctx->event_data = &events->event_datas[index];
struct epoll_event event = {
@@ -285,13 +297,15 @@ neu_event_io_t *neu_event_add_io(neu_events_t *events, neu_event_io_param_t io)
io_ctx->event_data->usr_data = io.usr_data;
io_ctx->event_data->callback.io = io.cb;
io_ctx->event_data->ctx.io = events->event_datas[index].ctx.io;
io_ctx->event_data->index = index;
io_ctx->fd = io.fd;
ret = epoll_ctl(events->epoll_fd, EPOLL_CTL_ADD, io.fd, &event);
nlog_notice("add io, fd: %d, epoll: %d, ret: %d", io.fd, events->epoll_fd,
ret);
nlog_notice("add io, fd: %d, epoll: %d, ret: %d(%d), index: %d", io.fd,
events->epoll_fd, ret, errno, index);
assert(ret == 0);
return io_ctx;
}
@@ -302,7 +316,8 @@ int neu_event_del_io(neu_events_t *events, neu_event_io_t *io)
return 0;
}
zlog_notice(neuron, "del io: %d from epoll: %d", io->fd, events->epoll_fd);
zlog_notice(neuron, "del io: %d from epoll: %d, index: %d", io->fd,
events->epoll_fd, io->event_data->index);
epoll_ctl(events->epoll_fd, EPOLL_CTL_DEL, io->fd, NULL);
free_event(events, io->event_data->index);
+25 -1
View File
@@ -62,8 +62,31 @@ static void sig_handler(int sig)
exit(-1);
}
static inline char syslog_priority(const char *level)
{
switch (level[0]) {
case 'D': // DEBUG
return '7';
case 'I': // INFO
return '6';
case 'N': // NOTICE
return '5';
case 'W': // WARN
return '4';
case 'E': // ERROR
return '3';
case 'F': // FATAL
return '2';
default: // UNKNOWN
return '1';
}
}
static int remote_syslog(zlog_msg_t *msg)
{
// fix priority
msg->buf[1] = syslog_priority(msg->path);
sendto(g_remote_syslog_ctx.fd, msg->buf, msg->len, 0,
(const struct sockaddr *) &g_remote_syslog_ctx.addr,
sizeof(g_remote_syslog_ctx.addr));
@@ -102,9 +125,10 @@ static int neuron_run(const neu_cli_args_t *args)
int rv = 0;
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
signal(SIGABRT, sig_handler);
signal(SIGSEGV, sig_handler);
signal(SIGTERM, sig_handler);
signal(SIGKILL, sig_handler);
// try to enable core dump
rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
-81
View File
@@ -1,81 +0,0 @@
/**
* NEURON IIoT System for Industry 4.0
* Copyright (C) 2020-2022 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.
**/
/*
* DO NOT EDIT THIS FILE MANUALLY!
* It was automatically generated by `json-autotype`.
*/
#include <stdlib.h>
#include <string.h>
#include "json/json.h"
#include "neu_json_file.h"
int neu_json_encode_get_file_list_resp(void *json_object, void *param)
{
int ret = 0;
neu_json_get_file_list_resp_t *resp =
(neu_json_get_file_list_resp_t *) param;
void * file_list_array = neu_json_array();
neu_json_get_file_resp_t *p_file = resp->file;
for (int i = 0; i < resp->n_file; i++) {
neu_json_elem_t file_elems[] = {
{
.name = "name",
.t = NEU_JSON_STR,
.v.val_str = p_file->name,
},
{
.name = "size",
.t = NEU_JSON_INT,
.v.val_int = p_file->size,
},
{
.name = "ctime",
.t = NEU_JSON_STR,
.v.val_str = p_file->ctime,
},
{
.name = "mtime",
.t = NEU_JSON_STR,
.v.val_str = p_file->mtime,
},
};
file_list_array = neu_json_encode_array(file_list_array, file_elems,
NEU_JSON_ELEM_SIZE(file_elems));
p_file++;
}
neu_json_elem_t resp_elems[] = { {
.name = "files",
.t = NEU_JSON_OBJECT,
.v.val_object = file_list_array,
} };
ret = neu_json_encode_field(json_object, resp_elems,
NEU_JSON_ELEM_SIZE(resp_elems));
return ret;
}
-52
View File
@@ -1,52 +0,0 @@
/**
* NEURON IIoT System for Industry 4.0
* Copyright (C) 2020-2022 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.
**/
/*
* DO NOT EDIT THIS FILE MANUALLY!
* It was automatically generated by `json-autotype`.
*/
#ifndef _NEU_JOSN_API_NEU_JSON_FILE_H_
#define _NEU_JSON_API_NEU_JSON_FILE_H_
#include "json/json.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
char *name;
int size;
char *ctime;
char *mtime;
} neu_json_get_file_resp_t;
typedef struct {
int n_file;
neu_json_get_file_resp_t *file;
} neu_json_get_file_list_resp_t;
int neu_json_encode_get_file_list_resp(void *json_object, void *param);
#ifdef __cplusplus
}
#endif
#endif
+2 -2
View File
@@ -54,7 +54,7 @@ typedef struct {
int64_t link;
int64_t rtt;
char * log_level;
char core_level[NEU_LOG_LEVEL_LEN];
char * core_level;
} neu_json_get_node_state_resp_t;
int neu_json_encode_get_node_state_resp(void *json_object, void *param);
@@ -70,7 +70,7 @@ typedef struct {
typedef struct {
uint16_t n_node;
neu_json_get_nodes_state_t *nodes;
char core_level[NEU_LOG_LEVEL_LEN];
char * core_level;
} neu_json_get_nodes_state_resp_t;
int neu_json_encode_get_nodes_state_resp(void *json_object, void *param);
+4 -1
View File
@@ -306,14 +306,17 @@ static int decode_write_tags_req_json(void * json_obj,
req->tags[i].value = v_elems[1].v;
if (ret != 0) {
while (i-- >= 0) {
for (; i >= 0; --i) {
free(req->tags[i].tag);
if (NEU_JSON_STR == req->tags[i].t) {
free(req->tags[i].value.val_str);
}
}
free(req->node);
free(req->group);
free(req->tags);
req->tags = NULL;
return ret;
}
}
+1 -2
View File
@@ -317,8 +317,6 @@ int neu_http_response(nng_aio *aio, neu_err_code_e code, char *content)
case NEU_ERR_NEED_TOKEN:
case NEU_ERR_DECODE_TOKEN:
case NEU_ERR_INVALID_USER_OR_PASSWORD:
case NEU_ERR_INVALID_USER:
case NEU_ERR_INVALID_PASSWORD:
status = NNG_HTTP_STATUS_UNAUTHORIZED;
break;
case NEU_ERR_BODY_IS_WRONG:
@@ -352,6 +350,7 @@ int neu_http_response(nng_aio *aio, neu_err_code_e code, char *content)
case NEU_ERR_NODE_NOT_EXIST:
case NEU_ERR_TAG_NOT_EXIST:
case NEU_ERR_LICENSE_NOT_FOUND:
case NEU_ERR_LICENSE_TOKEN_NOT_FOUND:
case NEU_ERR_GROUP_NOT_EXIST:
case NEU_ERR_GROUP_NOT_SUBSCRIBE:
case NEU_ERR_COMMAND_EXECUTION_FAILED:
+8 -2
View File
@@ -140,9 +140,15 @@ static int decode_object(json_t *root, neu_json_elem_t *ele)
case NEU_JSON_INT:
ele->v.val_int = json_integer_value(ob);
break;
case NEU_JSON_STR:
ele->v.val_str = strdup(json_string_value(ob));
case NEU_JSON_STR: {
const char *str = json_string_value(ob);
if (str != NULL) {
ele->v.val_str = strdup(str);
} else {
return -1;
}
break;
}
case NEU_JSON_FLOAT:
if (json_is_integer(ob)) {
ele->v.val_float = (float) json_integer_value(ob);
+9 -1
View File
@@ -49,10 +49,18 @@ target_include_directories(modbus_test PRIVATE
${CMAKE_SOURCE_DIR}/plugins/modbus)
target_link_libraries(modbus_test neuron-base gtest_main gtest pthread zlog)
add_executable(rolling_counter_test rolling_counter_test.cc)
target_include_directories(rolling_counter_test PRIVATE
${CMAKE_SOURCE_DIR}/src
${CMAKE_SOURCE_DIR}/include
)
target_link_libraries(rolling_counter_test neuron-base gtest_main gtest)
include(GoogleTest)
gtest_discover_tests(json_test)
gtest_discover_tests(http_test)
gtest_discover_tests(jwt_test)
gtest_discover_tests(base64_test)
gtest_discover_tests(tag_sort_test)
gtest_discover_tests(modbus_test)
gtest_discover_tests(modbus_test)
gtest_discover_tests(rolling_counter_test)
+45
View File
@@ -0,0 +1,45 @@
#include <gtest/gtest.h>
#include "utils/log.h"
#include "utils/rolling_counter.h"
zlog_category_t *neuron = NULL;
TEST(RollingCounterTest, neu_rolling_counter_inc)
{
uint64_t ts = 0;
neu_rolling_counter_t *counter = neu_rolling_counter_new(4000);
EXPECT_NE(nullptr, counter);
for (int i = 1; i <= 4; ++i) {
ts += 1000;
EXPECT_EQ(i, neu_rolling_counter_inc(counter, ts, 1));
}
// wrap around
for (int i = 1; i <= 4; ++i) {
ts += 1000;
EXPECT_EQ(4, neu_rolling_counter_inc(counter, ts, 1));
}
// increment without time stamp update
EXPECT_EQ(4, neu_rolling_counter_value(counter));
for (int i = 1; i <= 10; ++i) {
EXPECT_EQ(4 + i, neu_rolling_counter_inc(counter, ts, 1));
}
EXPECT_EQ(4 + 10, neu_rolling_counter_value(counter));
// stale value will be clean
ts += 4000;
EXPECT_EQ(0, neu_rolling_counter_inc(counter, ts, 0));
neu_rolling_counter_free(counter);
}
int main(int argc, char **argv)
{
zlog_init("./config/dev.conf");
neuron = zlog_get_category("neuron");
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
+1 -1
View File
@@ -1 +1 @@
2.6.2
2.6.9
+3 -3
View File
@@ -5,9 +5,9 @@ file perms = 666
[formats]
simple = "%d:%ms [%V] %f:%L %m%n"
syslog = "%d:%ms %H neuron[%p]: [%V] [%c] %f:%L %m%n"
syslog = "<P>%d:%ms %H neuron[%p]: [%V] [%c] %f:%L %m%n"
[rules]
*.* "./logs/%c.log", 50MB * 1 ~ "./logs/%c.#2s.log"; simple
*.* $remote_syslog; syslog
*.* "./logs/%c.log", 25MB * 1 ~ "./logs/%c.#2r.log"; simple
*.* $remote_syslog,"%V"; syslog