mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2025-11-02 11:47:47 +00:00
Compare commits
999 Commits
feature/wi
...
v2.6.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a45d351081 | ||
|
|
7f291914bd | ||
|
|
3edbb02187 | ||
|
|
27beb0bd5d | ||
|
|
24ec3259c6 | ||
|
|
b09cec0bc2 | ||
|
|
d14ca95010 | ||
|
|
2df1100795 | ||
|
|
2f961f992a | ||
|
|
ecdc5b3531 | ||
|
|
5f08a581f2 | ||
|
|
87b4a5d626 | ||
|
|
6aa2ef2878 | ||
|
|
9267a36529 | ||
|
|
72db313d8d | ||
|
|
93f0b2500e | ||
|
|
76b7aba5bd | ||
|
|
0585884033 | ||
|
|
c31fa08579 | ||
|
|
d9c3fea93d | ||
|
|
6325476325 | ||
|
|
054e172b64 | ||
|
|
7ae51f0fec | ||
|
|
531c0e24ba | ||
|
|
d97a31e002 | ||
|
|
70e5b1d0db | ||
|
|
63516e85db | ||
|
|
35b1dbdc2e | ||
|
|
c9abe16cfe | ||
|
|
aee7530b2b | ||
|
|
ceda99fa84 | ||
|
|
ce78b144e6 | ||
|
|
3fd3717978 | ||
|
|
9be3f1dfa9 | ||
|
|
2249367696 | ||
|
|
b68af82771 | ||
|
|
884d2e323b | ||
|
|
5a21b6f197 | ||
|
|
62c0178aa9 | ||
|
|
041452cf93 | ||
|
|
89ebaf78bc | ||
|
|
295a6496ef | ||
|
|
48fb10bcec | ||
|
|
525e464592 | ||
|
|
5f20866a31 | ||
|
|
05f60cd08b | ||
|
|
bd7b56757d | ||
|
|
bc3c85fe2d | ||
|
|
22c87decdc | ||
|
|
d13216e0e2 | ||
|
|
992d977312 | ||
|
|
9cb789d0b0 | ||
|
|
b4e9747bfa | ||
|
|
351633f215 | ||
|
|
5ec9d6a2c8 | ||
|
|
3abb24919f | ||
|
|
089446c3b4 | ||
|
|
345195dd1e | ||
|
|
21db12bcc6 | ||
|
|
be01cfb142 | ||
|
|
55645c5da4 | ||
|
|
aa0316462f | ||
|
|
ebb3c8fed0 | ||
|
|
4fb788def4 | ||
|
|
5b1e048be3 | ||
|
|
03ebc88672 | ||
|
|
80bb7ffa07 | ||
|
|
1776a70a0e | ||
|
|
3a0de1fee9 | ||
|
|
8414ed719b | ||
|
|
eebb18fccf | ||
|
|
1e59b8e160 | ||
|
|
6da673e754 | ||
|
|
ee4cb53517 | ||
|
|
61da6aa317 | ||
|
|
bbbadd3a23 | ||
|
|
855eb0dc13 | ||
|
|
0601aaf340 | ||
|
|
100d0302be | ||
|
|
1fe4dbf49f | ||
|
|
720222137c | ||
|
|
d464b8a6f4 | ||
|
|
019a995bdd | ||
|
|
f70a8f1732 | ||
|
|
0c79d2a632 | ||
|
|
1d16bd352a | ||
|
|
88564f2a77 | ||
|
|
1907ab9623 | ||
|
|
60e50b2af4 | ||
|
|
cd24a45c87 | ||
|
|
cab25f6fd7 | ||
|
|
23c5879a4b | ||
|
|
4e90422e7c | ||
|
|
e75983019a | ||
|
|
a6afef5f8e | ||
|
|
15e45f32a1 | ||
|
|
4c7e1807a2 | ||
|
|
301b24415c | ||
|
|
da0698ab9b | ||
|
|
f8454e6b83 | ||
|
|
cfaab404e9 | ||
|
|
e5f98cda04 | ||
|
|
bd8fece423 | ||
|
|
68a707fe57 | ||
|
|
e02a5595a1 | ||
|
|
744c1143fb | ||
|
|
41423a6d5f | ||
|
|
060c8673e7 | ||
|
|
1210ae821b | ||
|
|
1a2e4cc184 | ||
|
|
e32ace120b | ||
|
|
3f2c046a96 | ||
|
|
9459bb022c | ||
|
|
9526a2639a | ||
|
|
2051467c0b | ||
|
|
bacaa9959c | ||
|
|
875ee6bfd1 | ||
|
|
8f966fa80c | ||
|
|
d9ac843134 | ||
|
|
4abedcddf0 | ||
|
|
c14abf8aa0 | ||
|
|
d779fca535 | ||
|
|
7e1d545f26 | ||
|
|
9c2d60ed3a | ||
|
|
b8516cad84 | ||
|
|
eba979d9da | ||
|
|
d163f7522d | ||
|
|
132fdafd32 | ||
|
|
3d6527f30b | ||
|
|
dc114de8fa | ||
|
|
0592537b71 | ||
|
|
eddaaa0cd6 | ||
|
|
46e72369ae | ||
|
|
3fc3af68ee | ||
|
|
58648d7dc5 | ||
|
|
b2bd6aab9e | ||
|
|
3781f5283f | ||
|
|
7b990a7d2f | ||
|
|
eca43e1d57 | ||
|
|
c1347fc3b8 | ||
|
|
888fcbbcd3 | ||
|
|
4e4156c420 | ||
|
|
ee98a7b8a5 | ||
|
|
0b5518d265 | ||
|
|
7bc0656f25 | ||
|
|
177a8b40ee | ||
|
|
85ee78f35e | ||
|
|
9043b3a558 | ||
|
|
4d2d488812 | ||
|
|
adf226f2e8 | ||
|
|
749d425d80 | ||
|
|
a6f9deb315 | ||
|
|
f4236408fc | ||
|
|
377c7bfc0b | ||
|
|
2e3efd97e4 | ||
|
|
58abf04e42 | ||
|
|
5e002899b5 | ||
|
|
d43c8f63ab | ||
|
|
07a64877bb | ||
|
|
a00ba50920 | ||
|
|
c2fa87d6bd | ||
|
|
ab0b36a96f | ||
|
|
89f8047e2f | ||
|
|
1515c9bb6a | ||
|
|
b53e6f44fa | ||
|
|
769c9c90f6 | ||
|
|
dc0eb35376 | ||
|
|
e6b497f0b4 | ||
|
|
bab9d869b1 | ||
|
|
a9127d4fcf | ||
|
|
fea78abe9b | ||
|
|
bd72993fa5 | ||
|
|
7d74694bf9 | ||
|
|
8e84a0f1f3 | ||
|
|
98c8f29555 | ||
|
|
42a4ee0864 | ||
|
|
fcce86acf4 | ||
|
|
31aad8b41b | ||
|
|
a828039445 | ||
|
|
6905aeaeec | ||
|
|
3293b7b71d | ||
|
|
2d6df5ea29 | ||
|
|
e466f76b75 | ||
|
|
170b97514b | ||
|
|
a463bb60dd | ||
|
|
9bbb12b674 | ||
|
|
46cc41e065 | ||
|
|
1776643579 | ||
|
|
c0d9aca88a | ||
|
|
88018335da | ||
|
|
7ce7927c95 | ||
|
|
5b797cf937 | ||
|
|
cd615e8f2b | ||
|
|
cf3f0fe67f | ||
|
|
b80e92f3dc | ||
|
|
11034bd4fd | ||
|
|
01980892b1 | ||
|
|
f4d4405663 | ||
|
|
a8370dc8dd | ||
|
|
861c4d0dee | ||
|
|
8c70e833ea | ||
|
|
f8928bbec2 | ||
|
|
0b7e474e01 | ||
|
|
14f0bb75d1 | ||
|
|
32d37a3b9c | ||
|
|
24391c5ac4 | ||
|
|
7ac47dfaa0 | ||
|
|
fd77d6ef37 | ||
|
|
04c9deffd3 | ||
|
|
f8bc00cb55 | ||
|
|
f2ae0b6bd4 | ||
|
|
1904b34c84 | ||
|
|
23ea21d2b4 | ||
|
|
276572a8a5 | ||
|
|
b9bd5ca6a5 | ||
|
|
201a4dd6e7 | ||
|
|
769eb83744 | ||
|
|
66a30c4f37 | ||
|
|
2a744e2fde | ||
|
|
f212aa2e8c | ||
|
|
fc478bd304 | ||
|
|
6e8a2478c4 | ||
|
|
eceb5a9034 | ||
|
|
782acea8c7 | ||
|
|
524d392e83 | ||
|
|
885f1affeb | ||
|
|
50abf75a0a | ||
|
|
4af6427814 | ||
|
|
2a6ec50ce1 | ||
|
|
4497dc655b | ||
|
|
1e2d04ad07 | ||
|
|
5874d3f1fd | ||
|
|
a4abbe6ef3 | ||
|
|
41e3cbb2b2 | ||
|
|
1f77083973 | ||
|
|
b08f993a20 | ||
|
|
113baa625e | ||
|
|
3765d22815 | ||
|
|
24d492903b | ||
|
|
3b4fd70522 | ||
|
|
19cf9101fe | ||
|
|
004319e7ad | ||
|
|
94893d1185 | ||
|
|
13dce2f3e8 | ||
|
|
ea7bc3c52f | ||
|
|
0235a13841 | ||
|
|
be33c88337 | ||
|
|
0456f638c9 | ||
|
|
83ada79ca3 | ||
|
|
913d1e571d | ||
|
|
8f98e510db | ||
|
|
fb0da90b63 | ||
|
|
1e1dec51ab | ||
|
|
c35602e30e | ||
|
|
4c90a777e0 | ||
|
|
9abfa4bad5 | ||
|
|
7ecd0c9891 | ||
|
|
6e25ccdd87 | ||
|
|
a8f970eaf2 | ||
|
|
9f4d362a6d | ||
|
|
5f3f9e93d2 | ||
|
|
c84f05cd22 | ||
|
|
a532520044 | ||
|
|
6d82ee355e | ||
|
|
02c3b2fe2e | ||
|
|
cce4a7ec93 | ||
|
|
9aef183dc2 | ||
|
|
60a3365a9e | ||
|
|
6c052d7afe | ||
|
|
88eae31b7f | ||
|
|
d59f6e3dfc | ||
|
|
c97566f625 | ||
|
|
1fb41a9460 | ||
|
|
cfec8a1cbc | ||
|
|
7a84640c71 | ||
|
|
0d2276ff5a | ||
|
|
d227f83384 | ||
|
|
acb4d91a3d | ||
|
|
72b2913cc5 | ||
|
|
746ef603e2 | ||
|
|
ab792f7239 | ||
|
|
c4bb577763 | ||
|
|
3caf67102e | ||
|
|
8a3ade14ae | ||
|
|
4199b859ad | ||
|
|
be1b571f7f | ||
|
|
3002e17fd2 | ||
|
|
0d1a794e10 | ||
|
|
2aa7d97c80 | ||
|
|
0d3a0cbf03 | ||
|
|
1d8cb5447b | ||
|
|
3526a7abd9 | ||
|
|
d7ec9a3552 | ||
|
|
9f567e0e69 | ||
|
|
b16a410f1d | ||
|
|
0955f23dfc | ||
|
|
bd10ebc19c | ||
|
|
f74c5b496f | ||
|
|
6e961be74e | ||
|
|
c92d22f3cb | ||
|
|
e1770dc6a2 | ||
|
|
eace417fd3 | ||
|
|
ec3b5ededc | ||
|
|
4c6a0ab9e2 | ||
|
|
78a6b011f8 | ||
|
|
a5450418b3 | ||
|
|
c74aa0d89f | ||
|
|
5f5e887f91 | ||
|
|
54a9290589 | ||
|
|
24be35c974 | ||
|
|
937d2818c0 | ||
|
|
f014960b3a | ||
|
|
cc5b319141 | ||
|
|
d5e7a6661f | ||
|
|
3368782471 | ||
|
|
2f013557a9 | ||
|
|
09595abc8c | ||
|
|
5104ab1dc3 | ||
|
|
8f3b2f795f | ||
|
|
9779ee669b | ||
|
|
f7187749a1 | ||
|
|
ddec407856 | ||
|
|
4650ac592a | ||
|
|
bc5c9e30cf | ||
|
|
1b53398e1e | ||
|
|
7b59a981dd | ||
|
|
ec3cb6586f | ||
|
|
c40be95aa8 | ||
|
|
ba8edb7f74 | ||
|
|
ea14936a1d | ||
|
|
676f131ca9 | ||
|
|
2e1fc663c8 | ||
|
|
cd9ef2ed2a | ||
|
|
4a1a903656 | ||
|
|
f6409fc063 | ||
|
|
6af855f6ca | ||
|
|
bec81bc380 | ||
|
|
0e4e4156a1 | ||
|
|
2aa60a5676 | ||
|
|
8b396e51ff | ||
|
|
01f53d7b78 | ||
|
|
b3c188701f | ||
|
|
7eb4c9e38b | ||
|
|
c93c34c042 | ||
|
|
418f8d31ae | ||
|
|
77c0c191f7 | ||
|
|
f0f4cf54bb | ||
|
|
917abf1d7f | ||
|
|
b4e7e4e26b | ||
|
|
9d0a146859 | ||
|
|
2efed5e626 | ||
|
|
7420b72b23 | ||
|
|
5fc675484c | ||
|
|
38ad11542b | ||
|
|
63f2a4085a | ||
|
|
fea70efb2d | ||
|
|
da42c9845f | ||
|
|
ed46778bd4 | ||
|
|
1f7c0b7fdf | ||
|
|
15ec31fc89 | ||
|
|
d2a0d6da8a | ||
|
|
77cae31031 | ||
|
|
6cab1caf6c | ||
|
|
faf7881c87 | ||
|
|
eea8203869 | ||
|
|
040397aa8e | ||
|
|
bba92aa9b8 | ||
|
|
c332a3946d | ||
|
|
02e677f849 | ||
|
|
a26f7c03c1 | ||
|
|
9181ae01cc | ||
|
|
7825b00d2e | ||
|
|
8b895c2088 | ||
|
|
49d39d37a1 | ||
|
|
406d59d5d7 | ||
|
|
186d12c78a | ||
|
|
421c24c961 | ||
|
|
e00c835680 | ||
|
|
3f972ebb4a | ||
|
|
cf8d29e66f | ||
|
|
d5e11d246a | ||
|
|
6ac29199e0 | ||
|
|
2f9452d6ef | ||
|
|
caed454e1a | ||
|
|
30916cbed1 | ||
|
|
81899788a9 | ||
|
|
e1590cbe90 | ||
|
|
bcbc212436 | ||
|
|
520671684b | ||
|
|
eacf9c0450 | ||
|
|
bef4c3ed5c | ||
|
|
4fe6254bf2 | ||
|
|
63ba3d633d | ||
|
|
1255cf0a56 | ||
|
|
7a6f2a517c | ||
|
|
6c15908ed6 | ||
|
|
d0a7670fff | ||
|
|
17d6253cfe | ||
|
|
ab592305ce | ||
|
|
0da527e1d7 | ||
|
|
d3848a6f8b | ||
|
|
c522c22d31 | ||
|
|
783886662f | ||
|
|
56ab9b1409 | ||
|
|
67e86a0edf | ||
|
|
70c12a5b77 | ||
|
|
03f2e2d457 | ||
|
|
ed12331d20 | ||
|
|
ec0c295c7c | ||
|
|
2438bd7ca7 | ||
|
|
18d18f68c5 | ||
|
|
120f94a95a | ||
|
|
7b9cda8c3d | ||
|
|
0d116119ed | ||
|
|
b9a7f53a92 | ||
|
|
ee3aa66b11 | ||
|
|
459029d5d7 | ||
|
|
bfe0ff4481 | ||
|
|
b70a95d12b | ||
|
|
8280ff46db | ||
|
|
59da808bcd | ||
|
|
dbc785aca6 | ||
|
|
5207579645 | ||
|
|
840c22e0d1 | ||
|
|
996e410fde | ||
|
|
521dcc2eed | ||
|
|
4d73467b8a | ||
|
|
515444d223 | ||
|
|
dccda306d4 | ||
|
|
3fd5c59994 | ||
|
|
87fee4ecd2 | ||
|
|
b37e7d4c5d | ||
|
|
f8c21f0c68 | ||
|
|
f74c098b99 | ||
|
|
1619cec197 | ||
|
|
62211b6e8b | ||
|
|
1bebe0729a | ||
|
|
6a8a6aa851 | ||
|
|
4b6880a306 | ||
|
|
3d252116dd | ||
|
|
2fc5e69145 | ||
|
|
8d2e85d0ee | ||
|
|
d1efdc93a4 | ||
|
|
c27627302f | ||
|
|
ae18fead11 | ||
|
|
75a6300ffb | ||
|
|
f84a4c83d0 | ||
|
|
b882f07eef | ||
|
|
d5c8cb5837 | ||
|
|
a09f2ec7bd | ||
|
|
7af9be5845 | ||
|
|
bc6e7d538b | ||
|
|
59ed9df3c9 | ||
|
|
0f46a6ded0 | ||
|
|
ef09214187 | ||
|
|
aa4631b55d | ||
|
|
08b59e04ee | ||
|
|
3455297cd6 | ||
|
|
8f4e585c88 | ||
|
|
350ccd5371 | ||
|
|
b89c0773c5 | ||
|
|
d03cd6a6df | ||
|
|
142a04ffc3 | ||
|
|
bb519eb84b | ||
|
|
2b8e496bbc | ||
|
|
776a781a87 | ||
|
|
f5d66365b8 | ||
|
|
fd8b021225 | ||
|
|
1d2b54b6cf | ||
|
|
07ed169c08 | ||
|
|
f33b6c94be | ||
|
|
b073246293 | ||
|
|
8205cb7336 | ||
|
|
9339ae893a | ||
|
|
ce483ba51c | ||
|
|
85a7de67fb | ||
|
|
abdabe7da3 | ||
|
|
669af7640c | ||
|
|
83c46c44aa | ||
|
|
7b2ba4fed4 | ||
|
|
ef5aa26991 | ||
|
|
92b25846d2 | ||
|
|
77663f9184 | ||
|
|
61c7ab3267 | ||
|
|
8ae0006343 | ||
|
|
64a1fa1c85 | ||
|
|
2b9c90d5e6 | ||
|
|
565cee2373 | ||
|
|
36c5c9c5b6 | ||
|
|
837c3d5570 | ||
|
|
2a71721548 | ||
|
|
055bdcf937 | ||
|
|
221ee05298 | ||
|
|
afb8252dc2 | ||
|
|
77f86d139f | ||
|
|
b2353b6a0e | ||
|
|
bf4b9b0d63 | ||
|
|
e51236f0ca | ||
|
|
5be8ad75ed | ||
|
|
054e3e1591 | ||
|
|
06366f875c | ||
|
|
64d3f8c3ee | ||
|
|
8878445e03 | ||
|
|
ea30684f0c | ||
|
|
ebf08a63f1 | ||
|
|
e9e7db9ac0 | ||
|
|
7f9d03ed34 | ||
|
|
084483b028 | ||
|
|
285dbacd12 | ||
|
|
8f79d70753 | ||
|
|
6d20481d64 | ||
|
|
7da4bbba61 | ||
|
|
ff955d8b2f | ||
|
|
29d615393f | ||
|
|
2a716e6c66 | ||
|
|
b662dcf88c | ||
|
|
253ffbf111 | ||
|
|
dfd689512b | ||
|
|
cee2705bf8 | ||
|
|
af1e293bde | ||
|
|
58266eb239 | ||
|
|
87dc357c9f | ||
|
|
02798de88a | ||
|
|
d7bd812f97 | ||
|
|
b692a7868e | ||
|
|
f57dfc62c0 | ||
|
|
21794d669e | ||
|
|
2139093a73 | ||
|
|
bc1f0670fb | ||
|
|
a0b0a169fa | ||
|
|
7feb9f3655 | ||
|
|
3878d8abe6 | ||
|
|
770b5969f8 | ||
|
|
00bca216fc | ||
|
|
64eb7748d1 | ||
|
|
8ed351ad17 | ||
|
|
4a71be0558 | ||
|
|
d6434666b4 | ||
|
|
747c84de4a | ||
|
|
538bdb25b1 | ||
|
|
07229e7e1f | ||
|
|
a63a1785e2 | ||
|
|
14820bd9c8 | ||
|
|
aeeb333c62 | ||
|
|
caa8f8c5a5 | ||
|
|
02aada469b | ||
|
|
020f9aea16 | ||
|
|
a8d5717fd5 | ||
|
|
51dd030419 | ||
|
|
6a83895efc | ||
|
|
c5e2574ab1 | ||
|
|
5a1828eaea | ||
|
|
c62f5a16f5 | ||
|
|
b6e778ada3 | ||
|
|
1b34ec8a78 | ||
|
|
57eb7312c8 | ||
|
|
368cdb72d4 | ||
|
|
712d326560 | ||
|
|
11df029ec0 | ||
|
|
020542b751 | ||
|
|
4b19163091 | ||
|
|
852ae3fde7 | ||
|
|
1ab9729ec1 | ||
|
|
9b1711fff6 | ||
|
|
929bc79136 | ||
|
|
e8fec5075f | ||
|
|
0bae840106 | ||
|
|
bf519637aa | ||
|
|
b15dc2b517 | ||
|
|
44f2843a7f | ||
|
|
e2eda25764 | ||
|
|
b2411d97d6 | ||
|
|
4a61f57912 | ||
|
|
1cafe0b6fc | ||
|
|
20763dedf6 | ||
|
|
80c0a3c07e | ||
|
|
0138cfdede | ||
|
|
066bad7953 | ||
|
|
2ca1508be1 | ||
|
|
737e49a376 | ||
|
|
251a4c2310 | ||
|
|
4e4ad418b6 | ||
|
|
b07c381bf7 | ||
|
|
e3375a4510 | ||
|
|
6134c37d2b | ||
|
|
5e42202264 | ||
|
|
2f389599f8 | ||
|
|
36b633fcb7 | ||
|
|
5a1d56399c | ||
|
|
8ebb92b95a | ||
|
|
69716f50c0 | ||
|
|
580e4ce052 | ||
|
|
ab663be084 | ||
|
|
d5350b4283 | ||
|
|
873d77adf0 | ||
|
|
530555ff26 | ||
|
|
3db8892e58 | ||
|
|
c1ba58be6e | ||
|
|
0750be2d81 | ||
|
|
adec21906f | ||
|
|
80b5c6f3b5 | ||
|
|
e29a7589f2 | ||
|
|
8255ff3218 | ||
|
|
5b70cdfe53 | ||
|
|
2e94733c8d | ||
|
|
3d62625cf6 | ||
|
|
eb0eae90b6 | ||
|
|
d7dc43f0de | ||
|
|
3c6ec00695 | ||
|
|
eb705dfeb1 | ||
|
|
46bd78ba15 | ||
|
|
e730c60ebc | ||
|
|
3329781bc2 | ||
|
|
dfcc59a7b8 | ||
|
|
b72fb379cd | ||
|
|
74db8cd36d | ||
|
|
1219a70da2 | ||
|
|
dc95a8632a | ||
|
|
8b0ecb464b | ||
|
|
9f863c1cc2 | ||
|
|
fda6f8b2d9 | ||
|
|
9703ed035a | ||
|
|
4117ed927a | ||
|
|
8980eaa5ba | ||
|
|
d3d1ccee81 | ||
|
|
4a0aaa8f6b | ||
|
|
85e84e0672 | ||
|
|
7d63852d94 | ||
|
|
698a2b2fcb | ||
|
|
62e1c6eb0f | ||
|
|
1a8fa724d6 | ||
|
|
b4088519cf | ||
|
|
58ce304e53 | ||
|
|
9fbc77a85a | ||
|
|
623c4c43d4 | ||
|
|
63ea97b435 | ||
|
|
d9f3d92736 | ||
|
|
7fc2239e59 | ||
|
|
badfe61d6a | ||
|
|
ab57221040 | ||
|
|
5ae62b8892 | ||
|
|
c5425fc9cf | ||
|
|
dbdc14891c | ||
|
|
f4b4627c78 | ||
|
|
35dbe47571 | ||
|
|
a97337234e | ||
|
|
a87b8de6e3 | ||
|
|
949d7a54ad | ||
|
|
5a3c97a529 | ||
|
|
0772898160 | ||
|
|
638ed3f5c8 | ||
|
|
d996e9e05e | ||
|
|
58fd622980 | ||
|
|
29113ac39c | ||
|
|
f947f472b9 | ||
|
|
393763fb9e | ||
|
|
eced94910d | ||
|
|
df000f35ee | ||
|
|
24d2de568f | ||
|
|
8508396ae6 | ||
|
|
9f6d38e6b7 | ||
|
|
b8f3b9b37a | ||
|
|
71cdcb5909 | ||
|
|
e92e852dcb | ||
|
|
0ac5b3a39d | ||
|
|
3fbf460f81 | ||
|
|
9b7db5c095 | ||
|
|
eb9e88b54a | ||
|
|
952b1c4562 | ||
|
|
cec50beecf | ||
|
|
2048107866 | ||
|
|
2d72a15ec0 | ||
|
|
d5c36aa2e9 | ||
|
|
41079d9f0b | ||
|
|
a47977b029 | ||
|
|
e20b71181f | ||
|
|
4f29e5a650 | ||
|
|
e168c7b2c7 | ||
|
|
1f6de95f16 | ||
|
|
96995730c6 | ||
|
|
9d000ca84d | ||
|
|
9af6deaec3 | ||
|
|
aaa13e1e2f | ||
|
|
bd0419fb0c | ||
|
|
656efd0d57 | ||
|
|
863ff017b0 | ||
|
|
8c26cc37d7 | ||
|
|
4e9c26cd04 | ||
|
|
d098bca86f | ||
|
|
9980c2b175 | ||
|
|
a52daae4a5 | ||
|
|
1d8af05302 | ||
|
|
2efccedfba | ||
|
|
243b615814 | ||
|
|
dc37bcb5ff | ||
|
|
edac1d6ceb | ||
|
|
64848d8fdd | ||
|
|
c874b7633d | ||
|
|
2ca85970e4 | ||
|
|
0184aa8879 | ||
|
|
ac05fe833e | ||
|
|
998a686179 | ||
|
|
288b5e207f | ||
|
|
2ec0c923c3 | ||
|
|
4c9dd0cef7 | ||
|
|
8f16abd4ff | ||
|
|
c706ea4118 | ||
|
|
9c2fef1ee4 | ||
|
|
1648acca32 | ||
|
|
c11c0281ce | ||
|
|
58ee7344bf | ||
|
|
6c9dac79d5 | ||
|
|
7aa284e92c | ||
|
|
933b41e7c1 | ||
|
|
a39e586bc1 | ||
|
|
4e81683bcd | ||
|
|
6a74297cb3 | ||
|
|
67764ec5c1 | ||
|
|
ebbcd99453 | ||
|
|
3719df39fe | ||
|
|
70670117a7 | ||
|
|
31f77b84d6 | ||
|
|
924e2f0775 | ||
|
|
cb61ce3f9e | ||
|
|
d97033d6cf | ||
|
|
c2f547da0c | ||
|
|
7cc60e6063 | ||
|
|
4f117199f0 | ||
|
|
0d444c4bc9 | ||
|
|
87646944dd | ||
|
|
13c9633964 | ||
|
|
ab77f1371d | ||
|
|
4ac71c4af2 | ||
|
|
1ca1fffa26 | ||
|
|
4e623ab182 | ||
|
|
fb27ea8528 | ||
|
|
bc20d66694 | ||
|
|
beadcd50e7 | ||
|
|
5d1c9b10da | ||
|
|
7e877b74a7 | ||
|
|
47b569aa59 | ||
|
|
2afa4b64e8 | ||
|
|
315bad5451 | ||
|
|
c8fa1d5405 | ||
|
|
40a28015bd | ||
|
|
4a25b0ba99 | ||
|
|
9ea7ab14df | ||
|
|
aa692d9f30 | ||
|
|
044d978c46 | ||
|
|
b767dd3aa4 | ||
|
|
9acbd6cef6 | ||
|
|
a20ec0587e | ||
|
|
28b72a6303 | ||
|
|
9540fc9a5f | ||
|
|
18eac29b1a | ||
|
|
76b2255716 | ||
|
|
17377aa8bc | ||
|
|
d1a50fcf22 | ||
|
|
cccd8f8fbd | ||
|
|
9c37d0760d | ||
|
|
90d56197e6 | ||
|
|
6b91065468 | ||
|
|
f851957523 | ||
|
|
ec0574bfdf | ||
|
|
6bc279ac32 | ||
|
|
1cdb5ef2e3 | ||
|
|
d85854a1f2 | ||
|
|
e0d6fb0bcc | ||
|
|
6e864c14a1 | ||
|
|
8e49ffa904 | ||
|
|
4db50c0ed2 | ||
|
|
191611bc24 | ||
|
|
d10541afb7 | ||
|
|
1887878088 | ||
|
|
de3985191a | ||
|
|
629a615f7c | ||
|
|
ec947df8a0 | ||
|
|
203095a6f7 | ||
|
|
f71ce62c5b | ||
|
|
89680d6be7 | ||
|
|
e411f4f6ac | ||
|
|
bbcb23b821 | ||
|
|
75dfd49067 | ||
|
|
39d4423a5e | ||
|
|
6238fee522 | ||
|
|
e301ea7cee | ||
|
|
42aff04610 | ||
|
|
345053bdba | ||
|
|
285fd26f99 | ||
|
|
49c393a02f | ||
|
|
7242b7b34f | ||
|
|
a2aad9d1fa | ||
|
|
8a27698d2b | ||
|
|
5fecaaf891 | ||
|
|
8a651613c6 | ||
|
|
23f6eb7417 | ||
|
|
6d0e58cb0f | ||
|
|
317bbcbcd8 | ||
|
|
5f3f1cada2 | ||
|
|
5b83e39c46 | ||
|
|
9342b1ece2 | ||
|
|
ba1ef56b1f | ||
|
|
6bf1b1b9e1 | ||
|
|
fc5e5804ff | ||
|
|
5188615006 | ||
|
|
89d62109f9 | ||
|
|
a539fecfb4 | ||
|
|
19b213bb08 | ||
|
|
391d2df605 | ||
|
|
d7859ef6f2 | ||
|
|
386c9ac217 | ||
|
|
567bb7140a | ||
|
|
787a80eec3 | ||
|
|
87a6b2ae3f | ||
|
|
bc1969e5f6 | ||
|
|
aa654510e9 | ||
|
|
2591ce2752 | ||
|
|
118f79864f | ||
|
|
fb074e16c1 | ||
|
|
a687ea64bd | ||
|
|
f07c87d198 | ||
|
|
f2ec7b08a7 | ||
|
|
9f2e6c77a5 | ||
|
|
544272c6f8 | ||
|
|
db033d1045 | ||
|
|
073909f735 | ||
|
|
c6516e3ac7 | ||
|
|
d695b6994e | ||
|
|
0fe158fc3e | ||
|
|
a66d8e8845 | ||
|
|
fef479e241 | ||
|
|
ef84384324 | ||
|
|
cee1894716 | ||
|
|
6e9cb56ce8 | ||
|
|
7c2fc66f93 | ||
|
|
794040f3c7 | ||
|
|
9c0c5f1772 | ||
|
|
d289c4b242 | ||
|
|
49aeea00ff | ||
|
|
072191fbc4 | ||
|
|
0a4249e615 | ||
|
|
ebaa0ea59e | ||
|
|
f12597d72f | ||
|
|
87bf2fb413 | ||
|
|
ce848f6057 | ||
|
|
031a635c2d | ||
|
|
52d5d147fa | ||
|
|
ff1c85cbd6 | ||
|
|
a7d661de27 | ||
|
|
a8db90b554 | ||
|
|
b01f9eab33 | ||
|
|
cb29abf914 | ||
|
|
48f2b62cf0 | ||
|
|
90074096fc | ||
|
|
ecf28c596b | ||
|
|
caf53ef6ba | ||
|
|
318d65ea1f | ||
|
|
e9b39b57ff | ||
|
|
c4a7c8dab2 | ||
|
|
6a2a8d3b8c | ||
|
|
74eb9450f0 | ||
|
|
8183ae6314 | ||
|
|
7f80252bf9 | ||
|
|
430275cbf0 | ||
|
|
617f8a8307 | ||
|
|
49435f1cb8 | ||
|
|
45f19e57f3 | ||
|
|
02fb282698 | ||
|
|
e4becc70ca | ||
|
|
946ccdb9dc | ||
|
|
be6eb734fe | ||
|
|
4c9df3e574 | ||
|
|
6745aa425d | ||
|
|
659f45d4ef | ||
|
|
2939efb7b0 | ||
|
|
909efce91a | ||
|
|
4e81e54fe3 | ||
|
|
af355bd5a1 | ||
|
|
52bb4acb2e | ||
|
|
19f1238b1c | ||
|
|
1e397077aa | ||
|
|
dd78d52798 | ||
|
|
56a20e475b | ||
|
|
313e21a461 | ||
|
|
ff37328806 | ||
|
|
19dfe74ada | ||
|
|
3a8254dfda | ||
|
|
796db4db9a | ||
|
|
a9fa9abad3 | ||
|
|
4e5d9020ea | ||
|
|
86d8cdda75 | ||
|
|
77f91d041f | ||
|
|
446fabb372 | ||
|
|
d7bac5d731 | ||
|
|
98e705bba4 | ||
|
|
fcaa9efe81 | ||
|
|
05b9c1d85f | ||
|
|
b7775206db | ||
|
|
79b7104319 | ||
|
|
71ca079c83 | ||
|
|
d132251e36 | ||
|
|
9d0ed5e363 | ||
|
|
b9d8e8ef67 | ||
|
|
347eb883ea | ||
|
|
5dd259901c | ||
|
|
0797c719e4 | ||
|
|
59b183f2d2 | ||
|
|
c3c80d07a5 | ||
|
|
8f68d44388 | ||
|
|
68446b7807 | ||
|
|
36bd0a9eb0 | ||
|
|
0ad1ccfdf1 | ||
|
|
851dc1372c | ||
|
|
5093a80a88 | ||
|
|
cac3e5f6ff | ||
|
|
0d63037a6e | ||
|
|
5ab641aeb7 | ||
|
|
c87074cfb5 | ||
|
|
1bc537dade | ||
|
|
93b24fc292 | ||
|
|
c1f6f1d50c | ||
|
|
067a481e4a | ||
|
|
3086675af5 | ||
|
|
3c22fe8af2 | ||
|
|
9a4e834c94 | ||
|
|
53a8f4db1f | ||
|
|
36c381ccbf | ||
|
|
c74807993f | ||
|
|
a9e7e1e514 | ||
|
|
15286d07f0 | ||
|
|
3baeea6833 | ||
|
|
ef8db87ee7 | ||
|
|
4372c66e32 | ||
|
|
bd38bb71d3 | ||
|
|
0d0c310280 | ||
|
|
2ca0f6ddcd | ||
|
|
a2ad4f58ad | ||
|
|
02d0daff14 | ||
|
|
3c37b60f74 | ||
|
|
6626567a5f | ||
|
|
adc1b4c61f | ||
|
|
2764821f21 | ||
|
|
abd4219304 | ||
|
|
fc8bcdecdb | ||
|
|
82e4cd157a | ||
|
|
29ad904c53 | ||
|
|
05a069efda | ||
|
|
6f6f85f40b | ||
|
|
5f709ac70f | ||
|
|
977fca2887 | ||
|
|
0bbfda3de5 | ||
|
|
784795b21a | ||
|
|
00a1309040 | ||
|
|
db95129339 | ||
|
|
0c41105c94 | ||
|
|
ccead902ec | ||
|
|
cf582f8899 | ||
|
|
3a5c1c1218 | ||
|
|
7e5e998265 | ||
|
|
306dc49bc1 | ||
|
|
297510c2e2 | ||
|
|
0ec0cea131 | ||
|
|
0cd78ad1d8 | ||
|
|
46c7361f55 | ||
|
|
9b55ce0f45 | ||
|
|
77c7420700 | ||
|
|
b7e7541d7d | ||
|
|
dac7b7ca93 | ||
|
|
7160dbdaa7 | ||
|
|
164d8e12a3 | ||
|
|
90625f5e3a | ||
|
|
4ec83bdc59 | ||
|
|
3a1dcdb026 | ||
|
|
ed5a18805c | ||
|
|
ba9075d46e | ||
|
|
391ebebc70 | ||
|
|
0ce355004b | ||
|
|
187a2c7168 | ||
|
|
b8a646a011 | ||
|
|
9cb99ef9cd | ||
|
|
53761649f8 | ||
|
|
13bbb011a9 | ||
|
|
bc14a41152 | ||
|
|
adacc8b3fe | ||
|
|
47323d2eee | ||
|
|
283f9f7bf6 | ||
|
|
5895613ada | ||
|
|
8b99e863eb | ||
|
|
dfb6395b30 | ||
|
|
64e2cba3ae | ||
|
|
6337f6e61a | ||
|
|
5c286f4efe | ||
|
|
55d320b4d0 | ||
|
|
2377497497 | ||
|
|
ee9963ad8a | ||
|
|
43d631ba3e | ||
|
|
5ae2e0b945 | ||
|
|
6f1dec06d5 | ||
|
|
9fae68766c |
35
.github/workflows/ci.yml
vendored
35
.github/workflows/ci.yml
vendored
@@ -13,6 +13,7 @@ on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- 'release/*'
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@@ -39,6 +40,16 @@ jobs:
|
||||
registry_user: ucentral
|
||||
registry_password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
|
||||
|
||||
- name: Notify on failure via Slack
|
||||
if: failure() && github.ref == 'refs/heads/master'
|
||||
uses: rtCamp/action-slack-notify@v2
|
||||
env:
|
||||
SLACK_USERNAME: GitHub Actions failure notifier
|
||||
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
||||
SLACK_COLOR: "${{ job.status }}"
|
||||
SLACK_ICON: https://raw.githubusercontent.com/quintessence/slack-icons/master/images/github-logo-slack-icon.png
|
||||
SLACK_TITLE: Docker build failed for OWGW service
|
||||
|
||||
trigger-testing:
|
||||
if: startsWith(github.ref, 'refs/pull/')
|
||||
runs-on: ubuntu-latest
|
||||
@@ -65,4 +76,26 @@ jobs:
|
||||
workflow: ow_docker-compose.yml
|
||||
token: ${{ secrets.WLAN_TESTING_PAT }}
|
||||
ref: master
|
||||
inputs: '{"microservice": "owgw", "owgw_version": "${{ github.sha }}", "owgwui_version": "${{ env.BASE_BRANCH }}", "owsec_version": "${{ env.BASE_BRANCH }}", "owfms_version": "${{ env.BASE_BRANCH }}", "owprov_version": "${{ env.BASE_BRANCH }}", "owprovui_version": "${{ env.BASE_BRANCH }}"}'
|
||||
inputs: '{"deployment_version": "${{ env.BASE_BRANCH }}", "owgw_version": "${{ github.sha }}", "owsec_version": "${{ env.BASE_BRANCH }}", "owfms_version": "${{ env.BASE_BRANCH }}", "owprov_version": "${{ env.BASE_BRANCH }}", "owanalytics_version": "${{ env.BASE_BRANCH }}", "owsub_version": "${{ env.BASE_BRANCH }}", "microservice": "owgw"}'
|
||||
|
||||
trigger-deploy-to-dev:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/master'
|
||||
needs:
|
||||
- docker
|
||||
steps:
|
||||
- name: Checkout actions repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
repository: Telecominfraproject/.github
|
||||
path: github
|
||||
|
||||
- name: Trigger deployment of the latest version to dev instance and wait for result
|
||||
uses: ./github/composite-actions/trigger-workflow-and-wait
|
||||
with:
|
||||
owner: Telecominfraproject
|
||||
repo: wlan-testing
|
||||
workflow: ucentralgw-dev-deployment.yaml
|
||||
token: ${{ secrets.WLAN_TESTING_PAT }}
|
||||
ref: master
|
||||
inputs: '{"force_latest": "true"}'
|
||||
|
||||
8
.github/workflows/cleanup.yml
vendored
8
.github/workflows/cleanup.yml
vendored
@@ -17,4 +17,10 @@ jobs:
|
||||
- name: Cleanup Docker image with PR branch tag
|
||||
run: |
|
||||
export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
|
||||
curl -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owgw/$PR_BRANCH_TAG"
|
||||
|
||||
if [[ ! $PR_BRANCH_TAG =~ (main|master|release-*) ]]; then
|
||||
echo "PR branch is $PR_BRANCH_TAG, deleting Docker image"
|
||||
curl -s -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owgw/$PR_BRANCH_TAG"
|
||||
else
|
||||
echo "PR branch is $PR_BRANCH_TAG, not deleting Docker image"
|
||||
fi
|
||||
|
||||
46
.github/workflows/release.yml
vendored
Normal file
46
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
name: Release chart package
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
helm-package:
|
||||
runs-on: ubuntu-20.04
|
||||
env:
|
||||
HELM_REPO_URL: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||
HELM_REPO_USERNAME: ucentral
|
||||
steps:
|
||||
- name: Checkout uCentral assembly chart repo
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
path: wlan-cloud-ucentralgw
|
||||
|
||||
- name: Build package
|
||||
working-directory: wlan-cloud-ucentralgw/helm
|
||||
run: |
|
||||
helm plugin install https://github.com/aslafy-z/helm-git --version 0.10.0
|
||||
helm repo add bitnami https://charts.bitnami.com/bitnami
|
||||
helm repo update
|
||||
helm dependency update
|
||||
mkdir dist
|
||||
helm package . -d dist
|
||||
|
||||
- name: Generate GitHub release body
|
||||
working-directory: wlan-cloud-ucentralgw/helm
|
||||
run: |
|
||||
pip3 install yq -q
|
||||
echo "Docker image - tip-tip-wlan-cloud-ucentral.jfrog.io/owgw:$GITHUB_REF_NAME" > release.txt
|
||||
echo "Helm charted may be attached to this release" >> release.txt
|
||||
echo "Deployment artifacts may be found in https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/$GITHUB_REF_NAME" >> release.txt
|
||||
|
||||
- name: Create GitHub release
|
||||
uses: softprops/action-gh-release@v1
|
||||
with:
|
||||
body_path: wlan-cloud-ucentralgw/helm/release.txt
|
||||
files: wlan-cloud-ucentralgw/helm/dist/*
|
||||
@@ -44,12 +44,9 @@ endif()
|
||||
|
||||
add_definitions(-DTIP_GATEWAY_SERVICE="1")
|
||||
|
||||
set(Boost_USE_STATIC_LIBS OFF)
|
||||
set(Boost_USE_MULTITHREADED ON)
|
||||
set(Boost_USE_STATIC_RUNTIME OFF)
|
||||
find_package(Boost REQUIRED system)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(fmt REQUIRED)
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
find_package(nlohmann_json_schema_validator REQUIRED)
|
||||
|
||||
@@ -66,6 +63,14 @@ include_directories(/usr/local/include /usr/local/opt/openssl/include src inclu
|
||||
|
||||
configure_file(src/ow_version.h.in ${PROJECT_SOURCE_DIR}/src/ow_version.h @ONLY)
|
||||
|
||||
add_compile_options(-Wall -Wextra)
|
||||
if(ASAN)
|
||||
add_compile_options(-fsanitize=address)
|
||||
add_link_options(-fsanitize=address)
|
||||
add_compile_options(-fsanitize=undefined)
|
||||
add_link_options(-fsanitize=undefined)
|
||||
endif()
|
||||
|
||||
add_executable( owgw
|
||||
build
|
||||
src/ow_version.h.in
|
||||
@@ -94,7 +99,6 @@ add_executable( owgw
|
||||
src/RESTAPI/RESTAPI_RPC.cpp src/RESTAPI/RESTAPI_RPC.h
|
||||
src/RESTAPI/RESTAPI_deviceDashboardHandler.cpp src/RESTAPI/RESTAPI_deviceDashboardHandler.h
|
||||
src/RESTAPI/RESTAPI_telemetryWebSocket.cpp src/RESTAPI/RESTAPI_telemetryWebSocket.h
|
||||
src/RESTAPI/RESTAPI_webSocketServer.cpp src/RESTAPI/RESTAPI_webSocketServer.h
|
||||
src/storage/storage_blacklist.cpp src/storage/storage_tables.cpp src/storage/storage_logs.cpp
|
||||
src/storage/storage_command.cpp src/storage/storage_healthcheck.cpp src/storage/storage_statistics.cpp
|
||||
src/storage/storage_device.cpp src/storage/storage_capabilities.cpp src/storage/storage_defconfig.cpp
|
||||
@@ -114,7 +118,7 @@ add_executable( owgw
|
||||
src/TelemetryStream.cpp src/TelemetryStream.h
|
||||
src/framework/ConfigurationValidator.cpp src/framework/ConfigurationValidator.h
|
||||
src/ConfigurationCache.h
|
||||
src/CapabilitiesCache.h src/FindCountry.h src/rttys/RTTYS_server.cpp src/rttys/RTTYS_server.h src/rttys/RTTYS_device.cpp src/rttys/RTTYS_device.h src/rttys/RTTYS_ClientConnection.cpp src/rttys/RTTYS_ClientConnection.h src/rttys/RTTYS_WebServer.cpp src/rttys/RTTYS_WebServer.h src/RESTAPI/RESTAPI_device_helper.h src/SDKcalls.cpp src/SDKcalls.h src/StateUtils.cpp src/StateUtils.h src/WS_ReactorPool.h src/WS_Connection.h src/WS_Connection.cpp src/TelemetryClient.h src/TelemetryClient.cpp src/RESTAPI/RESTAPI_iptocountry_handler.cpp src/RESTAPI/RESTAPI_iptocountry_handler.h src/framework/ow_constants.h)
|
||||
src/CapabilitiesCache.h src/FindCountry.h src/rttys/RTTYS_server.cpp src/rttys/RTTYS_server.h src/rttys/RTTYS_device.cpp src/rttys/RTTYS_device.h src/rttys/RTTYS_ClientConnection.cpp src/rttys/RTTYS_ClientConnection.h src/rttys/RTTYS_WebServer.cpp src/rttys/RTTYS_WebServer.h src/RESTAPI/RESTAPI_device_helper.h src/SDKcalls.cpp src/SDKcalls.h src/StateUtils.cpp src/StateUtils.h src/WS_ReactorPool.h src/WS_Connection.h src/WS_Connection.cpp src/TelemetryClient.h src/TelemetryClient.cpp src/RESTAPI/RESTAPI_iptocountry_handler.cpp src/RESTAPI/RESTAPI_iptocountry_handler.h src/framework/ow_constants.h src/GwWebSocketClient.cpp src/GwWebSocketClient.h src/framework/WebSocketClientNotifications.h src/RADIUS_proxy_server.cpp src/RADIUS_proxy_server.h src/RESTAPI/RESTAPI_radiusProxyConfig_handler.cpp src/RESTAPI/RESTAPI_radiusProxyConfig_handler.h src/ParseWifiScan.h src/RADIUS_helpers.h src/VenueBroadcaster.h src/sdks/sdk_prov.h)
|
||||
|
||||
if(NOT SMALL_BUILD)
|
||||
|
||||
@@ -125,12 +129,15 @@ INSTALL(TARGETS owgw
|
||||
)
|
||||
|
||||
target_link_libraries(owgw PUBLIC
|
||||
${Poco_LIBRARIES} ${Boost_LIBRARIES} ${ZLIB_LIBRARIES})
|
||||
${Poco_LIBRARIES}
|
||||
${ZLIB_LIBRARIES})
|
||||
|
||||
if(NOT SMALL_BUILD)
|
||||
target_link_libraries(owgw PUBLIC
|
||||
${MySQL_LIBRARIES} ${ZLIB_LIBRARIES}
|
||||
CppKafka::cppkafka
|
||||
nlohmann_json_schema_validator
|
||||
fmt::fmt
|
||||
)
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(owgw PUBLIC PocoJSON)
|
||||
|
||||
15
Dockerfile
15
Dockerfile
@@ -18,6 +18,18 @@ RUN cmake ..
|
||||
RUN cmake --build . --config Release -j8
|
||||
RUN cmake --build . --target install
|
||||
|
||||
FROM build-base AS fmtlib-build
|
||||
|
||||
ADD https://api.github.com/repos/fmtlib/fmt/git/refs/heads/master version.json
|
||||
RUN git clone https://github.com/fmtlib/fmt /fmtlib
|
||||
|
||||
WORKDIR /fmtlib
|
||||
RUN mkdir cmake-build
|
||||
WORKDIR cmake-build
|
||||
RUN cmake ..
|
||||
RUN make
|
||||
RUN make install
|
||||
|
||||
FROM build-base AS cppkafka-build
|
||||
|
||||
ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json
|
||||
@@ -55,6 +67,8 @@ COPY --from=cppkafka-build /usr/local/include /usr/local/include
|
||||
COPY --from=cppkafka-build /usr/local/lib /usr/local/lib
|
||||
COPY --from=json-schema-validator-build /usr/local/include /usr/local/include
|
||||
COPY --from=json-schema-validator-build /usr/local/lib /usr/local/lib
|
||||
COPY --from=fmtlib-build /usr/local/include /usr/local/include
|
||||
COPY --from=fmtlib-build /usr/local/lib /usr/local/lib
|
||||
|
||||
WORKDIR /owgw
|
||||
RUN mkdir cmake-build
|
||||
@@ -84,6 +98,7 @@ COPY test_scripts/curl/cli /cli
|
||||
COPY owgw.properties.tmpl /
|
||||
COPY docker-entrypoint.sh /
|
||||
COPY wait-for-postgres.sh /
|
||||
COPY rtty_ui /dist/rtty_ui
|
||||
RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \
|
||||
-O /usr/local/share/ca-certificates/restapi-ca-selfsigned.pem
|
||||
|
||||
|
||||
182
MICRO_SERVICE_PROTOCOL.md
Normal file
182
MICRO_SERVICE_PROTOCOL.md
Normal file
@@ -0,0 +1,182 @@
|
||||
# Micro-service backbone responsibilities
|
||||
|
||||
## Bus management
|
||||
Each microservice must get onto kafka and consume/produce messages on the kafka bus. The topic to subscribe to is `service_events`.
|
||||
|
||||
## System messages
|
||||
System messages are what maintains the collection of micro-services working on the system. Each message has the format
|
||||
|
||||
```json
|
||||
{
|
||||
"event": <event-type>,
|
||||
"id": 1234567890,
|
||||
"type": "owrrm",
|
||||
"publicEndPoint": "https://myhostname.com:16020",
|
||||
"privateEndPoint": "https://localhost:17020",
|
||||
"key" : "289479847948794870749",
|
||||
"version" : "1.0"
|
||||
}
|
||||
```
|
||||
|
||||
### `event-type`
|
||||
When a service joins the bus, it should generate an event-type of `join`. When a service shutdown, it should generate a `leave` event-type. Every 30 seconds, a service
|
||||
should generate a `keep-alive` message.
|
||||
|
||||
### `id`
|
||||
You should generate a random number from some unique factor for the system. This ID is used to identify different services. You should reuse that ID
|
||||
when you restart.
|
||||
|
||||
## Micro-service maintaining bus state
|
||||
A micro-service should maintain its own lists of available micro-services by looking at the messages it receives and keep a list.
|
||||
|
||||
## The `type`
|
||||
The `type` in the system message is oen of the following:
|
||||
```c++
|
||||
static const std::string uSERVICE_SECURITY{"owsec"};
|
||||
static const std::string uSERVICE_GATEWAY{"owgw"};
|
||||
static const std::string uSERVICE_FIRMWARE{ "owfms"};
|
||||
static const std::string uSERVICE_TOPOLOGY{ "owtopo"};
|
||||
static const std::string uSERVICE_PROVISIONING{ "owprov"};
|
||||
static const std::string uSERVICE_OWLS{ "owls"};
|
||||
static const std::string uSERVICE_SUBCRIBER{ "owsub"};
|
||||
static const std::string uSERVICE_INSTALLER{ "owinst"};
|
||||
static const std::string uSERVICE_ANALYTICS{ "owanalytics"};
|
||||
static const std::string uSERVICE_OWRRM{ "owrrm"};
|
||||
```
|
||||
|
||||
The `type` is what you should use to find the `privateEndPoint` you are looking to communicate with.
|
||||
|
||||
### Example
|
||||
Assume you want to communicate with the gateway t pconfigure a device.
|
||||
|
||||
```text
|
||||
1. Look into my list of current Micro-services for the type=owgw.
|
||||
2. Use the priovateEndPoint associated with that entry
|
||||
```
|
||||
|
||||
## REST API calls on the private interface
|
||||
For inter-service REST calls, you should never use the `Authorization: Bearer token` method. Instead, the following headers should be included in all API calls
|
||||
```json
|
||||
{
|
||||
"X-API-KEY" : "289479847948794870749",
|
||||
"X-INTERNAL-NAME" : "https://myhostname.com:16020"
|
||||
}
|
||||
```
|
||||
|
||||
### `X-API-KEY`
|
||||
This is the `key` you included in your `system-messages`.
|
||||
|
||||
### `X-INTERNAL-NAME`
|
||||
This is the `publicEndPoint` you included in your `system-messages`.
|
||||
|
||||
This method can _only_ be used to any another `privateEndPoint` in the system. You can use the exact same EndPoints provided in the OpenAPI files for any of the services.
|
||||
|
||||
## OpenAPI Integration
|
||||
To appear in the UI consoles, a micro-service should ne able to handle a get to the `/api/v1/system` endpoint on its `publicEndPoint` interface.
|
||||
|
||||
Here is a brief description of what the micro-service should answer:
|
||||
```yaml
|
||||
/system:
|
||||
get:
|
||||
tags:
|
||||
- System Commands
|
||||
summary: Retrieve different values from the running service.
|
||||
operationId: getSystemCommand
|
||||
parameters:
|
||||
- in: query
|
||||
description: Get a value
|
||||
name: command
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- info
|
||||
required: true
|
||||
|
||||
responses:
|
||||
200:
|
||||
description: Successful command execution
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/SystemInfoResults'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
```
|
||||
The relevant data structures are:
|
||||
```yaml
|
||||
SystemInfoResults:
|
||||
type: object
|
||||
properties:
|
||||
version:
|
||||
type: string
|
||||
uptime:
|
||||
type: integer
|
||||
format: integer64
|
||||
start:
|
||||
type: integer
|
||||
format: integer64
|
||||
os:
|
||||
type: string
|
||||
processors:
|
||||
type: integer
|
||||
hostname:
|
||||
type: string
|
||||
certificates:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
filename:
|
||||
type: string
|
||||
expires:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
```
|
||||
and
|
||||
```yaml
|
||||
responses:
|
||||
NotFound:
|
||||
description: The specified resource was not found.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
ErrorCode:
|
||||
type: integer
|
||||
ErrorDetails:
|
||||
type: string
|
||||
ErrorDescription:
|
||||
type: string
|
||||
|
||||
Unauthorized:
|
||||
description: The requested does not have sufficient rights to perform the operation.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
ErrorCode:
|
||||
type: integer
|
||||
enum:
|
||||
- 0 # Success
|
||||
- 1 # PASSWORD_CHANGE_REQUIRED,
|
||||
- 2 # INVALID_CREDENTIALS,
|
||||
- 3 # PASSWORD_ALREADY_USED,
|
||||
- 4 # USERNAME_PENDING_VERIFICATION,
|
||||
- 5 # PASSWORD_INVALID,
|
||||
- 6 # INTERNAL_ERROR,
|
||||
- 7 # ACCESS_DENIED,
|
||||
- 8 # INVALID_TOKEN
|
||||
- 9 # EXPIRED_TOKEN
|
||||
- 10 # RATE_LIMIT_EXCEEDED
|
||||
- 11 # BAD_MFA_TRANSACTION
|
||||
- 12 # MFA_FAILURE
|
||||
- 13 # SECURITY_SERVICE_UNREACHABLE
|
||||
ErrorDetails:
|
||||
type: string
|
||||
ErrorDescription:
|
||||
type: string
|
||||
```
|
||||
207
PROTOCOL.md
207
PROTOCOL.md
@@ -30,7 +30,7 @@ In this RPC, here are some common interpretations:
|
||||
#### Connection event
|
||||
Device Sends connection notification to the controller after establishing a connection. The controller
|
||||
my decide to send the AP a newer configuration. The controller will record the device capabilities provided.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "connect" ,
|
||||
"params" : {
|
||||
@@ -47,7 +47,7 @@ my decide to send the AP a newer configuration. The controller will record the d
|
||||
#### State event
|
||||
The device sends device state information periodically. If the controller detects that it has a newer configuration, it
|
||||
may decide to send this new configuration to the AP.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "state" ,
|
||||
"params" : {
|
||||
@@ -62,7 +62,7 @@ may decide to send this new configuration to the AP.
|
||||
#### Healthcheck event
|
||||
Device sends a `healthcheck` periodically. This message contains information about how vital subsystems are operating and
|
||||
if they need attention.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "healthcheck" ,
|
||||
"params" : {
|
||||
@@ -77,7 +77,7 @@ if they need attention.
|
||||
|
||||
#### Log event
|
||||
Device sends a log message whenever necessary. The controller will log this message to the log system for the device.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "log" ,
|
||||
"params" : {
|
||||
@@ -102,7 +102,7 @@ The `severity` matches the `syslog` levels. Here are the details:
|
||||
|
||||
#### Crash Log event
|
||||
Device may send a crash log event after rebooting after a crash. The event cannot be sent until a connection event has been sent.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "crashlog" ,
|
||||
"params" : {
|
||||
@@ -117,7 +117,7 @@ Device may send a crash log event after rebooting after a crash. The event canno
|
||||
Device sends this message to tell the controller that the device
|
||||
has received a configuration but is still running an older configuration. The controller will not
|
||||
reply to this message.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "cfgpending" ,
|
||||
"params" : {
|
||||
@@ -131,7 +131,7 @@ reply to this message.
|
||||
#### DeviceUpdate event
|
||||
Device sends this message to tell the controller it is changing something is its configuration because
|
||||
of some requirement or some changes.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "deviceupdate" ,
|
||||
"params" : {
|
||||
@@ -145,7 +145,7 @@ of some requirement or some changes.
|
||||
#### Send a keepalive to the controller event
|
||||
Device sends a keepalive whenever necessary. The device will send this message to tell the controller
|
||||
which version it is running. The Controller may decide to send the device a newer configuration.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "ping" ,
|
||||
"params" : {
|
||||
@@ -157,7 +157,7 @@ which version it is running. The Controller may decide to send the device a newe
|
||||
|
||||
#### Recovery Event
|
||||
Device may decide it has to do into recovery mode. This event should be used.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "recovery" ,
|
||||
"params" : {
|
||||
@@ -170,6 +170,34 @@ Device may decide it has to do into recovery mode. This event should be used.
|
||||
}
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
"status" : {
|
||||
"error" : 0 or an error number,
|
||||
"text" : <description of the error or success>
|
||||
}
|
||||
},
|
||||
"id" : <same number>
|
||||
}
|
||||
```
|
||||
|
||||
#### Device requests a venue broadcast message
|
||||
Device send this message when it wants to reach out to all other APs in the same venue. The GW will find the
|
||||
venue where this device belongs and resend the same message to all other devices in the venue.
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "venue_broadcast" ,
|
||||
"params" : {
|
||||
"serial" : <serial number> ,
|
||||
"timestamp" : <the UTC timestamp when the message was sent>,
|
||||
"data" : <an opaque string from the AP. This could be Zipped and so on and most likely base64 encoded>
|
||||
}
|
||||
}
|
||||
```
|
||||
Upon receiving a `venue_broadcast` message, the GW will simply resent the message to all the APs in the venue.
|
||||
|
||||
### Controller commands
|
||||
Most controller commands include a `when` member. This is a UTC clock time asking the AP
|
||||
@@ -180,7 +208,7 @@ always a numeric parameter.
|
||||
#### Controller wants the device to apply a given configuration
|
||||
Controller sends this command when it believes the device should load a new configuration. The device
|
||||
should send message with `pending change` events until this version has been applied and running.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "configure" ,
|
||||
"params" : {
|
||||
@@ -194,7 +222,7 @@ should send message with `pending change` events until this version has been app
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
@@ -233,7 +261,7 @@ The rejected section is an array containing the following:
|
||||
|
||||
#### Controller wants the device to reboot
|
||||
Controller sends this command when it believes the device should reboot.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "reboot" ,
|
||||
"params" : {
|
||||
@@ -245,7 +273,7 @@ Controller sends this command when it believes the device should reboot.
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
@@ -264,7 +292,7 @@ The device should answer:
|
||||
|
||||
#### Controller wants the device to upgrade its firmware
|
||||
Controller sends this command when it believes the device should upgrade its firmware.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "upgrade" ,
|
||||
"params" : {
|
||||
@@ -277,7 +305,7 @@ Controller sends this command when it believes the device should upgrade its fir
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
@@ -293,7 +321,7 @@ The device should answer:
|
||||
|
||||
#### Controller wants the device to perform a factory reset
|
||||
Controller sends this command when it believes the device should upgrade its firmware.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "factory" ,
|
||||
"params" : {
|
||||
@@ -306,7 +334,7 @@ Controller sends this command when it believes the device should upgrade its fir
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
@@ -320,9 +348,50 @@ The device should answer:
|
||||
}
|
||||
```
|
||||
|
||||
#### Controller issuing RRM commands to the AP
|
||||
Controller sends this command to perform several RRM commands.
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "rrm" ,
|
||||
"params" : {
|
||||
"serial" : <serial number> ,
|
||||
"actions": [
|
||||
{
|
||||
"type": "roam",
|
||||
"bss": [ "00:11:22:33:44:55", ... ],
|
||||
"params" : { action specific data }
|
||||
}, {
|
||||
"type": "tx-power",
|
||||
"bss": [ "00:11:22:33:44:55", ... ],
|
||||
“params”: { action specific data }
|
||||
}, {
|
||||
"type": "beacon-request",
|
||||
"bss": [ "00:11:22:33:44:55", ... ],
|
||||
"params": { action specific data }
|
||||
}
|
||||
]
|
||||
},
|
||||
"id" : <some number>
|
||||
}
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
"status" : {
|
||||
"error" : 0 or an error number,
|
||||
"text" : <description of the error or success>,
|
||||
}
|
||||
},
|
||||
"id" : <same number>
|
||||
}
|
||||
```
|
||||
|
||||
#### Controller wants the device to flash its LEDs
|
||||
Controller sends this command when it wants the device to flash its LEDs.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "leds" ,
|
||||
"params" : {
|
||||
@@ -336,14 +405,13 @@ Controller sends this command when it wants the device to flash its LEDs.
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
"status" : {
|
||||
"error" : 0 or an error number,
|
||||
"text" : <description of the error or success>,
|
||||
"when" : <time when this will be performed as UTC seconds>,
|
||||
}
|
||||
},
|
||||
"id" : <same number>
|
||||
@@ -358,7 +426,7 @@ The device should answer:
|
||||
#### Controller sends a device specific command
|
||||
Controller sends this command specific to this device. The command is proprietary and must be agreed upon by the device
|
||||
and the controller.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "perform" ,
|
||||
"params" : {
|
||||
@@ -372,7 +440,7 @@ and the controller.
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
@@ -395,7 +463,7 @@ The device should answer with teh above message. The `error` value should be int
|
||||
|
||||
#### Controller wants the device to perform a trace
|
||||
Controller sends this command when it needs the device to perform a trace (i.e. tcpdump).
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "trace" ,
|
||||
"params" : {
|
||||
@@ -412,7 +480,7 @@ Controller sends this command when it needs the device to perform a trace (i.e.
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
@@ -438,7 +506,7 @@ uploaded or the timeout occurs, the upload will be rejected.
|
||||
|
||||
#### Controller wants the device to perform a WiFi Scan
|
||||
Controller sends this command when it needs the device to perform a WiFi Scan.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "wifiscan" ,
|
||||
"params" : {
|
||||
@@ -446,15 +514,16 @@ Controller sends this command when it needs the device to perform a WiFi Scan.
|
||||
"bands" : [ "2","5","5l","5u",6" ], <optional this is a list of bands to scan: on or more bands >
|
||||
"channels" : [ 1,2,3...] , <optional list of discreet channels to scan >
|
||||
"verbose" : <optional boolean: true or false> (by default false),
|
||||
"bandwidth" : <optional int: 20,40,80 in MHz>
|
||||
"active" : 0 or 1 (to select passive or active scan)
|
||||
"bandwidth" : <optional int: 20,40,80 in MHz>,
|
||||
"active" : 0 or 1 (to select passive or active scan),
|
||||
"ies": <optional: array of unsigned int 8 bits: i.e. [1,4,34,58,91]>
|
||||
},
|
||||
"id" : <some number>
|
||||
}
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
@@ -477,7 +546,7 @@ Controller sends this command when it needs the device to provide a message back
|
||||
supported messages are "state" and "healthcheck". More messages maybe added later. The messages will
|
||||
be returned the usual way. The RPC response to this message just says that the request has been accepted and the
|
||||
message will be returned "soon".
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "request" ,
|
||||
"params" : {
|
||||
@@ -491,7 +560,7 @@ message will be returned "soon".
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
@@ -507,7 +576,7 @@ The device should answer:
|
||||
|
||||
#### Controller requesting eventqueue buffers
|
||||
Controller sends this command when it needs the device to provide the content of ist ring buffers.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "event" ,
|
||||
"params" : {
|
||||
@@ -521,7 +590,7 @@ Controller sends this command when it needs the device to provide the content of
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
@@ -537,7 +606,7 @@ The device should answer:
|
||||
|
||||
#### Controller requesting telemetry stream information
|
||||
Controller sends this command when it needs the device to telemetry streaming.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "telemetry" ,
|
||||
"params" : {
|
||||
@@ -550,7 +619,7 @@ Controller sends this command when it needs the device to telemetry streaming.
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
@@ -564,7 +633,7 @@ The device should answer:
|
||||
```
|
||||
|
||||
When the interval is greater than 0, the gateway will start to receive messages
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "telemetry" ,
|
||||
"params" : {
|
||||
@@ -579,7 +648,7 @@ The device will stop sending data after 30 minutes or if it receives a `telemetr
|
||||
|
||||
#### Controller requesting an `rtty` session
|
||||
Controller sends this command an administrator requests to start an `rtty` session with the AP.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "remote_access" ,
|
||||
"params" : {
|
||||
@@ -597,7 +666,7 @@ Controller sends this command an administrator requests to start an `rtty` sessi
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
@@ -613,7 +682,7 @@ The device should answer:
|
||||
|
||||
#### Controller wants to ping the device
|
||||
Controller sends this command when it tries to establish latency to the device.
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "ping" ,
|
||||
"params" : {
|
||||
@@ -624,7 +693,7 @@ Controller sends this command when it tries to establish latency to the device.
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
@@ -635,8 +704,41 @@ The device should answer:
|
||||
}
|
||||
```
|
||||
|
||||
#### Controller wants the device to perform a script
|
||||
Controller sends this command to run a predefined script. Extreme care must be taken.
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "script" ,
|
||||
"params" : {
|
||||
"serial" : <serial number>,
|
||||
"type" : <one of "shell", "ucode">,
|
||||
"script" : <text blob containing the script>,
|
||||
"timeout" : <max timeout in seconds, default is 30>,
|
||||
"when" : <time when this will be performed as UTC seconds>
|
||||
},
|
||||
"id" : <some number>
|
||||
}
|
||||
```
|
||||
|
||||
#### `rtty server`
|
||||
The device should answer:
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
"status" : {
|
||||
"error" : <0 or the value of $? from the shell running the command, 255 signifies a timeout>,
|
||||
one of either
|
||||
"result_64" : <gzipped base64 result of running the command>,
|
||||
"result_sz" : <size of unzipped content>
|
||||
or
|
||||
"result" : <a single text blob of the result>
|
||||
}
|
||||
},
|
||||
"id" : <same number>
|
||||
}
|
||||
```
|
||||
|
||||
### `rtty server`
|
||||
More information about the [rtty server](https://github.com/zhaojh329/rtty) can be found here.
|
||||
|
||||
### Message compression
|
||||
@@ -653,7 +755,7 @@ params will be dropped. Additional compression schemes may be developed later.
|
||||
The original `params` element should be run through `zlib:compress` and then encoded using base64, and passed as a string. Here is an example
|
||||
of the completed message. The following should how the `state` event could be compressed:
|
||||
|
||||
```
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "state" ,
|
||||
"params" : {
|
||||
@@ -662,6 +764,29 @@ of the completed message. The following should how the `state` event could be co
|
||||
}
|
||||
```
|
||||
|
||||
### 'Radius Proxying'
|
||||
The gateway can receive RADIUS messages from the device and forward them. It can also receive messages
|
||||
on its behalf and send them to the device.
|
||||
|
||||
```json
|
||||
{
|
||||
"radius" : <type, can be auth, acct, coa> ,
|
||||
"data" : <base 64 encoded raw RADIUS payload>
|
||||
}
|
||||
```
|
||||
|
||||
The GW will include a TLV to mark the sender MAC. The RADIUS server must use the same TLV to
|
||||
identify the destination for its messages.
|
||||
|
||||
#### Incoming RADIUS messages configuration
|
||||
The GW must be configured with the following:
|
||||
|
||||
```asm
|
||||
radius.proxy.enable = true
|
||||
radius.proxy.accounting.port = 1813
|
||||
radius.proxy.authentication.port = 1812
|
||||
radius.proxy.coa.port = 3799
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@ sudo cmake --build . --target install
|
||||
cd ~
|
||||
git clone https://github.com/nlohmann/json.git
|
||||
cd json
|
||||
git checkout tags/v3.10.2
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
cmake ..
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,637 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<CodeBlocks_project_file>
|
||||
<FileVersion major="1" minor="6"/>
|
||||
<Project>
|
||||
<Option title="ucentralgw"/>
|
||||
<Option makefile_is_custom="1"/>
|
||||
<Option compiler="gcc"/>
|
||||
<Option virtualFolders="CMake Files\;CMake Files\..\;CMake Files\..\..\;CMake Files\..\..\..\;CMake Files\..\..\..\..\;CMake Files\..\..\..\..\..\;CMake Files\..\..\..\..\..\..\;CMake Files\..\..\..\..\..\..\usr\;CMake Files\..\..\..\..\..\..\usr\local\;CMake Files\..\..\..\..\..\..\usr\local\lib\;CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\;CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Boost-1.75.0\;CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\boost_headers-1.75.0\;CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\boost_system-1.75.0\;CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\CppKafka\;CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\;CMake Files\cmake\;CMake Files\cmake-build-debug\;"/>
|
||||
<Build>
|
||||
<Target title="all">
|
||||
<Option working_dir="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug"/>
|
||||
<Option type="4"/>
|
||||
<MakeCommands>
|
||||
<Build command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 all"/>
|
||||
<CompileFile command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 "$file""/>
|
||||
<Clean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
<DistClean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
</MakeCommands>
|
||||
</Target>
|
||||
<Target title="install/local">
|
||||
<Option working_dir="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug"/>
|
||||
<Option type="4"/>
|
||||
<MakeCommands>
|
||||
<Build command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 install/local"/>
|
||||
<CompileFile command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 "$file""/>
|
||||
<Clean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
<DistClean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
</MakeCommands>
|
||||
</Target>
|
||||
<Target title="rebuild_cache">
|
||||
<Option working_dir="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug"/>
|
||||
<Option type="4"/>
|
||||
<MakeCommands>
|
||||
<Build command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 rebuild_cache"/>
|
||||
<CompileFile command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 "$file""/>
|
||||
<Clean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
<DistClean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
</MakeCommands>
|
||||
</Target>
|
||||
<Target title="edit_cache">
|
||||
<Option working_dir="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug"/>
|
||||
<Option type="4"/>
|
||||
<MakeCommands>
|
||||
<Build command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 edit_cache"/>
|
||||
<CompileFile command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 "$file""/>
|
||||
<Clean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
<DistClean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
</MakeCommands>
|
||||
</Target>
|
||||
<Target title="install/strip">
|
||||
<Option working_dir="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug"/>
|
||||
<Option type="4"/>
|
||||
<MakeCommands>
|
||||
<Build command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 install/strip"/>
|
||||
<CompileFile command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 "$file""/>
|
||||
<Clean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
<DistClean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
</MakeCommands>
|
||||
</Target>
|
||||
<Target title="install">
|
||||
<Option working_dir="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug"/>
|
||||
<Option type="4"/>
|
||||
<MakeCommands>
|
||||
<Build command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 install"/>
|
||||
<CompileFile command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 "$file""/>
|
||||
<Clean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
<DistClean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
</MakeCommands>
|
||||
</Target>
|
||||
<Target title="list_install_components">
|
||||
<Option working_dir="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug"/>
|
||||
<Option type="4"/>
|
||||
<MakeCommands>
|
||||
<Build command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 list_install_components"/>
|
||||
<CompileFile command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 "$file""/>
|
||||
<Clean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
<DistClean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
</MakeCommands>
|
||||
</Target>
|
||||
<Target title="ucentralgw">
|
||||
<Option output="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/ucentralgw" prefix_auto="0" extension_auto="0"/>
|
||||
<Option working_dir="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug"/>
|
||||
<Option object_output="./"/>
|
||||
<Option type="1"/>
|
||||
<Option compiler="gcc"/>
|
||||
<Compiler>
|
||||
<Add option="-DAPP_VERSION="0.7.0""/>
|
||||
<Add option="-DBUILD_NUMBER="120""/>
|
||||
<Add option="-DTIP_GATEWAY_SERVICE="1""/>
|
||||
<Add option="-D_DEBUG"/>
|
||||
<Add option="-DPOCO_ENABLE_CPP14"/>
|
||||
<Add option="-DPOCO_ENABLE_CPP11"/>
|
||||
<Add option="-DPOCO_OS_FAMILY_UNIX"/>
|
||||
<Add option="-DPOCO_HAVE_IPv6"/>
|
||||
<Add option="-DPOCO_NO_STAT64"/>
|
||||
<Add option="-DXML_DTD"/>
|
||||
<Add option="-DTHREADSAFE"/>
|
||||
<Add option="-DNO_TCL"/>
|
||||
<Add option="-DBOOST_ALL_NO_LIB"/>
|
||||
<Add directory="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src"/>
|
||||
<Add directory="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/include/kafka"/>
|
||||
<Add directory="/usr/local/opt/mysql-client/include"/>
|
||||
<Add directory="/usr/local/include"/>
|
||||
<Add directory="/usr/local/opt/openssl/include"/>
|
||||
<Add directory="/usr/local/opt/mysql-client/include/mysql"/>
|
||||
<Add directory="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1"/>
|
||||
<Add directory="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.5/include"/>
|
||||
<Add directory="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include"/>
|
||||
<Add directory="/System/Library/Frameworks"/>
|
||||
<Add directory="/Library/Frameworks"/>
|
||||
</Compiler>
|
||||
<MakeCommands>
|
||||
<Build command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 ucentralgw"/>
|
||||
<CompileFile command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 "$file""/>
|
||||
<Clean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
<DistClean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
</MakeCommands>
|
||||
</Target>
|
||||
<Target title="ucentralgw/fast">
|
||||
<Option output="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/ucentralgw" prefix_auto="0" extension_auto="0"/>
|
||||
<Option working_dir="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug"/>
|
||||
<Option object_output="./"/>
|
||||
<Option type="1"/>
|
||||
<Option compiler="gcc"/>
|
||||
<Compiler>
|
||||
<Add option="-DAPP_VERSION="0.7.0""/>
|
||||
<Add option="-DBUILD_NUMBER="120""/>
|
||||
<Add option="-DTIP_GATEWAY_SERVICE="1""/>
|
||||
<Add option="-D_DEBUG"/>
|
||||
<Add option="-DPOCO_ENABLE_CPP14"/>
|
||||
<Add option="-DPOCO_ENABLE_CPP11"/>
|
||||
<Add option="-DPOCO_OS_FAMILY_UNIX"/>
|
||||
<Add option="-DPOCO_HAVE_IPv6"/>
|
||||
<Add option="-DPOCO_NO_STAT64"/>
|
||||
<Add option="-DXML_DTD"/>
|
||||
<Add option="-DTHREADSAFE"/>
|
||||
<Add option="-DNO_TCL"/>
|
||||
<Add option="-DBOOST_ALL_NO_LIB"/>
|
||||
<Add directory="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src"/>
|
||||
<Add directory="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/include/kafka"/>
|
||||
<Add directory="/usr/local/opt/mysql-client/include"/>
|
||||
<Add directory="/usr/local/include"/>
|
||||
<Add directory="/usr/local/opt/openssl/include"/>
|
||||
<Add directory="/usr/local/opt/mysql-client/include/mysql"/>
|
||||
<Add directory="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1"/>
|
||||
<Add directory="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.5/include"/>
|
||||
<Add directory="/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include"/>
|
||||
<Add directory="/System/Library/Frameworks"/>
|
||||
<Add directory="/Library/Frameworks"/>
|
||||
</Compiler>
|
||||
<MakeCommands>
|
||||
<Build command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 ucentralgw/fast"/>
|
||||
<CompileFile command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 "$file""/>
|
||||
<Clean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
<DistClean command="/usr/local/bin/gmake -j16 -f "/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/Makefile" VERBOSE=1 clean"/>
|
||||
</MakeCommands>
|
||||
</Target>
|
||||
</Build>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/build">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/ALBHealthCheckServer.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/AuthClient.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/AuthClient.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/CentralConfig.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/CentralConfig.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/CommandChannel.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/CommandChannel.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/CommandManager.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/CommandManager.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/Daemon.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/Daemon.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/DeviceRegistry.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/DeviceRegistry.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/FileUploader.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/FileUploader.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/KafkaManager.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/KafkaManager.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/Kafka_topics.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/MicroService.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/MicroService.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/OUIServer.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/OUIServer.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/OpenAPIRequest.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/OpenAPIRequest.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_BlackList.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_BlackList.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_GWobjects.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_GWobjects.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_InternalServer.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_InternalServer.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_RPC.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_RPC.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_SecurityObjects.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_SecurityObjects.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_command.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_command.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_commands.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_commands.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_default_configuration.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_default_configuration.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_default_configurations.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_default_configurations.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_device_commandHandler.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_device_commandHandler.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_device_handler.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_device_handler.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_devices_handler.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_devices_handler.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_file.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_file.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_handler.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_handler.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_ouis.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_ouis.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_protocol.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_server.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_server.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_system_command.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_system_command.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_utils.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_utils.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/StateProcessor.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/StateProcessor.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/StorageArchiver.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/StorageArchiver.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/StorageService.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/StorageService.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/SubSystemServer.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/SubSystemServer.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/Utils.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/Utils.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/WebSocketServer.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/WebSocketServer.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_blacklist.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_capabilities.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_command.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_defconfig.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_device.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_healthcheck.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_lifetime_stats.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_logs.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_mysql.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_pgql.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_sqlite.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_statistics.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_tables.cpp">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCentralProtocol.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCentralTypes.h">
|
||||
<Option target="ucentralgw"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/CMakeLists.txt">
|
||||
<Option virtualFolder="CMake Files\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/BoostDetectToolset-1.75.0.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Boost-1.75.0/BoostConfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Boost-1.75.0\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Boost-1.75.0/BoostConfigVersion.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Boost-1.75.0\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/boost_headers-1.75.0/boost_headers-config-version.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\boost_headers-1.75.0\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/boost_headers-1.75.0/boost_headers-config.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\boost_headers-1.75.0\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/boost_system-1.75.0/boost_system-config-version.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\boost_system-1.75.0\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/boost_system-1.75.0/boost_system-config.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\boost_system-1.75.0\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/boost_system-1.75.0/libboost_system-variant-mt-shared.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\boost_system-1.75.0\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/boost_system-1.75.0/libboost_system-variant-mt-static.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\boost_system-1.75.0\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/boost_system-1.75.0/libboost_system-variant-shared.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\boost_system-1.75.0\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/boost_system-1.75.0/libboost_system-variant-static.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\boost_system-1.75.0\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/CppKafka/CppKafkaConfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\CppKafka\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/CppKafka/CppKafkaConfigVersion.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\CppKafka\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/CppKafka/CppKafkaTargets-noconfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\CppKafka\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/CppKafka/CppKafkaTargets.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\CppKafka\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoConfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoConfigVersion.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoCryptoConfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoCryptoConfigVersion.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoCryptoTargets-relwithdebinfo.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoCryptoTargets.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataConfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataConfigVersion.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataMySQLConfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataMySQLConfigVersion.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataMySQLTargets-relwithdebinfo.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataMySQLTargets.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataPostgreSQLConfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataPostgreSQLConfigVersion.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataPostgreSQLTargets-relwithdebinfo.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataPostgreSQLTargets.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataSQLiteConfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataSQLiteConfigVersion.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataSQLiteTargets-relwithdebinfo.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataSQLiteTargets.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataTargets-relwithdebinfo.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataTargets.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoFoundationConfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoFoundationConfigVersion.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoFoundationTargets-relwithdebinfo.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoFoundationTargets.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJSONConfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJSONConfigVersion.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJSONTargets-relwithdebinfo.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJSONTargets.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJWTConfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJWTConfigVersion.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJWTTargets-relwithdebinfo.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJWTTargets.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetConfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetConfigVersion.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetSSLConfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetSSLConfigVersion.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetSSLTargets-relwithdebinfo.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetSSLTargets.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetTargets-relwithdebinfo.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetTargets.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoUtilConfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoUtilConfigVersion.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoUtilTargets-relwithdebinfo.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoUtilTargets.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoXMLConfig.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoXMLConfigVersion.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoXMLTargets-relwithdebinfo.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoXMLTargets.cmake">
|
||||
<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake/FindMySQL.cmake">
|
||||
<Option virtualFolder="CMake Files\cmake\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake/FindPostgreSQL.cmake">
|
||||
<Option virtualFolder="CMake Files\cmake\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake/FindRdKafka.cmake">
|
||||
<Option virtualFolder="CMake Files\cmake\"/>
|
||||
</Unit>
|
||||
<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/cmake-build-debug/rdkafka_version_test.cpp">
|
||||
<Option virtualFolder="CMake Files\cmake-build-debug\"/>
|
||||
</Unit>
|
||||
</Project>
|
||||
</CodeBlocks_project_file>
|
||||
@@ -5,69 +5,90 @@ if [ "$SELFSIGNED_CERTS" = 'true' ]; then
|
||||
update-ca-certificates
|
||||
fi
|
||||
|
||||
if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWGW_CONFIG"/owgw.properties ]]; then
|
||||
WEBSOCKET_HOST_ROOTCA=${WEBSOCKET_HOST_ROOTCA:-"\$OWGW_ROOT/certs/root.pem"} \
|
||||
WEBSOCKET_HOST_ISSUER=${WEBSOCKET_HOST_ISSUER:-"\$OWGW_ROOT/certs/issuer.pem"} \
|
||||
WEBSOCKET_HOST_CERT=${WEBSOCKET_HOST_CERT:-"\$OWGW_ROOT/certs/websocket-cert.pem"} \
|
||||
WEBSOCKET_HOST_KEY=${WEBSOCKET_HOST_KEY:-"\$OWGW_ROOT/certs/websocket-key.pem"} \
|
||||
WEBSOCKET_HOST_CLIENTCAS=${WEBSOCKET_HOST_CLIENTCAS:-"\$OWGW_ROOT/certs/clientcas.pem"} \
|
||||
WEBSOCKET_HOST_CAS=${WEBSOCKET_HOST_CAS:-"\$OWGW_ROOT/certs/cas"} \
|
||||
WEBSOCKET_HOST_PORT=${WEBSOCKET_HOST_PORT:-"15002"} \
|
||||
WEBSOCKET_HOST_KEY_PASSWORD=${WEBSOCKET_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWGW_ROOT/certs/restapi-ca.pem"} \
|
||||
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16002"} \
|
||||
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWGW_ROOT/certs/restapi-cert.pem"} \
|
||||
RESTAPI_HOST_KEY=${RESTAPI_HOST_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||
RESTAPI_HOST_KEY_PASSWORD=${RESTAPI_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
INTERNAL_RESTAPI_HOST_ROOTCA=${INTERNAL_RESTAPI_HOST_ROOTCA:-"\$OWGW_ROOT/certs/restapi-ca.pem"} \
|
||||
INTERNAL_RESTAPI_HOST_PORT=${INTERNAL_RESTAPI_HOST_PORT:-"17002"} \
|
||||
INTERNAL_RESTAPI_HOST_CERT=${INTERNAL_RESTAPI_HOST_CERT:-"\$OWGW_ROOT/certs/restapi-cert.pem"} \
|
||||
INTERNAL_RESTAPI_HOST_KEY=${INTERNAL_RESTAPI_HOST_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||
INTERNAL_RESTAPI_HOST_KEY_PASSWORD=${INTERNAL_RESTAPI_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
FILEUPLOADER_HOST_ROOTCA=${FILEUPLOADER_HOST_ROOTCA:-"\$OWGW_ROOT/certs/restapi-ca.pem"} \
|
||||
FILEUPLOADER_HOST_NAME=${FILEUPLOADER_HOST_NAME:-"localhost"} \
|
||||
FILEUPLOADER_HOST_PORT=${FILEUPLOADER_HOST_PORT:-"16003"} \
|
||||
FILEUPLOADER_HOST_CERT=${FILEUPLOADER_HOST_CERT:-"\$OWGW_ROOT/certs/restapi-cert.pem"} \
|
||||
FILEUPLOADER_HOST_KEY=${FILEUPLOADER_HOST_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||
FILEUPLOADER_HOST_KEY_PASSWORD=${FILEUPLOADER_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
FILEUPLOADER_PATH=${FILEUPLOADER_PATH:-"\$OWGW_ROOT/uploads"} \
|
||||
FILEUPLOADER_URI=${FILEUPLOADER_URI:-"https://localhost:16003"} \
|
||||
SERVICE_KEY=${SERVICE_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||
SERVICE_KEY_PASSWORD=${SERVICE_KEY_PASSWORD:-"mypassword"} \
|
||||
SYSTEM_DATA=${SYSTEM_DATA:-"\$OWGW_ROOT/data"} \
|
||||
SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17002"} \
|
||||
SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16002"} \
|
||||
SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
|
||||
SIMULATORID=${SIMULATORID:-""} \
|
||||
RTTY_ENABLED=${RTTY_ENABLED:-"false"} \
|
||||
RTTY_SERVER=${RTTY_SERVER:-"localhost"} \
|
||||
RTTY_PORT=${RTTY_PORT:-"5912"} \
|
||||
RTTY_TOKEN=${RTTY_TOKEN:-"96181c567b4d0d98c50f127230068fa8"} \
|
||||
RTTY_TIMEOUT=${RTTY_TIMEOUT:-"60"} \
|
||||
RTTY_VIEWPORT=${RTTY_VIEWPORT:-"5913"} \
|
||||
KAFKA_ENABLE=${KAFKA_ENABLE:-"true"} \
|
||||
KAFKA_BROKERLIST=${KAFKA_BROKERLIST:-"localhost:9092"} \
|
||||
KAFKA_SSL_CA_LOCATION=${KAFKA_SSL_CA_LOCATION:-""} \
|
||||
KAFKA_SSL_CERTIFICATE_LOCATION=${KAFKA_SSL_CERTIFICATE_LOCATION:-""} \
|
||||
KAFKA_SSL_KEY_LOCATION=${KAFKA_SSL_KEY_LOCATION:-""} \
|
||||
KAFKA_SSL_KEY_PASSWORD=${KAFKA_SSL_KEY_PASSWORD:-""} \
|
||||
STORAGE_TYPE=${STORAGE_TYPE:-"sqlite"} \
|
||||
STORAGE_TYPE_POSTGRESQL_HOST=${STORAGE_TYPE_POSTGRESQL_HOST:-"localhost"} \
|
||||
STORAGE_TYPE_POSTGRESQL_USERNAME=${STORAGE_TYPE_POSTGRESQL_USERNAME:-"owgw"} \
|
||||
STORAGE_TYPE_POSTGRESQL_PASSWORD=${STORAGE_TYPE_POSTGRESQL_PASSWORD:-"owgw"} \
|
||||
STORAGE_TYPE_POSTGRESQL_DATABASE=${STORAGE_TYPE_POSTGRESQL_DATABASE:-"owgw"} \
|
||||
STORAGE_TYPE_POSTGRESQL_PORT=${STORAGE_TYPE_POSTGRESQL_PORT:-"5432"} \
|
||||
STORAGE_TYPE_MYSQL_HOST=${STORAGE_TYPE_MYSQL_HOST:-"localhost"} \
|
||||
STORAGE_TYPE_MYSQL_USERNAME=${STORAGE_TYPE_MYSQL_USERNAME:-"owgw"} \
|
||||
STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"owgw"} \
|
||||
STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"owgw"} \
|
||||
STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \
|
||||
envsubst < /owgw.properties.tmpl > $OWGW_CONFIG/owgw.properties
|
||||
if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
||||
WEBSOCKET_HOST_ROOTCA=${WEBSOCKET_HOST_ROOTCA:-"\$OWGW_ROOT/certs/root.pem"} \
|
||||
WEBSOCKET_HOST_ISSUER=${WEBSOCKET_HOST_ISSUER:-"\$OWGW_ROOT/certs/issuer.pem"} \
|
||||
WEBSOCKET_HOST_CERT=${WEBSOCKET_HOST_CERT:-"\$OWGW_ROOT/certs/websocket-cert.pem"} \
|
||||
WEBSOCKET_HOST_KEY=${WEBSOCKET_HOST_KEY:-"\$OWGW_ROOT/certs/websocket-key.pem"} \
|
||||
WEBSOCKET_HOST_CLIENTCAS=${WEBSOCKET_HOST_CLIENTCAS:-"\$OWGW_ROOT/certs/clientcas.pem"} \
|
||||
WEBSOCKET_HOST_CAS=${WEBSOCKET_HOST_CAS:-"\$OWGW_ROOT/certs/cas"} \
|
||||
WEBSOCKET_HOST_PORT=${WEBSOCKET_HOST_PORT:-"15002"} \
|
||||
WEBSOCKET_HOST_KEY_PASSWORD=${WEBSOCKET_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWGW_ROOT/certs/restapi-ca.pem"} \
|
||||
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16002"} \
|
||||
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWGW_ROOT/certs/restapi-cert.pem"} \
|
||||
RESTAPI_HOST_KEY=${RESTAPI_HOST_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||
RESTAPI_HOST_KEY_PASSWORD=${RESTAPI_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
INTERNAL_RESTAPI_HOST_ROOTCA=${INTERNAL_RESTAPI_HOST_ROOTCA:-"\$OWGW_ROOT/certs/restapi-ca.pem"} \
|
||||
INTERNAL_RESTAPI_HOST_PORT=${INTERNAL_RESTAPI_HOST_PORT:-"17002"} \
|
||||
INTERNAL_RESTAPI_HOST_CERT=${INTERNAL_RESTAPI_HOST_CERT:-"\$OWGW_ROOT/certs/restapi-cert.pem"} \
|
||||
INTERNAL_RESTAPI_HOST_KEY=${INTERNAL_RESTAPI_HOST_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||
INTERNAL_RESTAPI_HOST_KEY_PASSWORD=${INTERNAL_RESTAPI_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
FILEUPLOADER_HOST_ROOTCA=${FILEUPLOADER_HOST_ROOTCA:-"\$OWGW_ROOT/certs/restapi-ca.pem"} \
|
||||
FILEUPLOADER_HOST_NAME=${FILEUPLOADER_HOST_NAME:-"localhost"} \
|
||||
FILEUPLOADER_HOST_PORT=${FILEUPLOADER_HOST_PORT:-"16003"} \
|
||||
FILEUPLOADER_HOST_CERT=${FILEUPLOADER_HOST_CERT:-"\$OWGW_ROOT/certs/restapi-cert.pem"} \
|
||||
FILEUPLOADER_HOST_KEY=${FILEUPLOADER_HOST_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||
FILEUPLOADER_HOST_KEY_PASSWORD=${FILEUPLOADER_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
FILEUPLOADER_PATH=${FILEUPLOADER_PATH:-"\$OWGW_ROOT/uploads"} \
|
||||
FILEUPLOADER_URI=${FILEUPLOADER_URI:-"https://localhost:16003"} \
|
||||
SERVICE_KEY=${SERVICE_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||
SERVICE_KEY_PASSWORD=${SERVICE_KEY_PASSWORD:-"mypassword"} \
|
||||
SYSTEM_DATA=${SYSTEM_DATA:-"\$OWGW_ROOT/data"} \
|
||||
SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17002"} \
|
||||
SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16002"} \
|
||||
SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
|
||||
SIMULATORID=${SIMULATORID:-""} \
|
||||
IPTOCOUNTRY_PROVIDER=${IPTOCOUNTRY_PROVIDER:-"ipinfo"} \
|
||||
IPTOCOUNTRY_IPINFO_TOKEN=${IPTOCOUNTRY_IPINFO_TOKEN:-""} \
|
||||
IPTOCOUNTRY_IPDATA_APIKEY=${IPTOCOUNTRY_IPDATA_APIKEY:-""} \
|
||||
AUTOPROVISIONING_PROCESS=${AUTOPROVISIONING_PROCESS:-"prov,default"} \
|
||||
RTTY_INTERNAL=${RTTY_INTERNAL:-"true"} \
|
||||
RTTY_ENABLED=${RTTY_ENABLED:-"true"} \
|
||||
RTTY_SERVER=${RTTY_SERVER:-"localhost"} \
|
||||
RTTY_PORT=${RTTY_PORT:-"5912"} \
|
||||
RTTY_TOKEN=${RTTY_TOKEN:-""} \
|
||||
RTTY_TIMEOUT=${RTTY_TIMEOUT:-"60"} \
|
||||
RTTY_VIEWPORT=${RTTY_VIEWPORT:-"5913"} \
|
||||
RTTY_ASSETS=${RTTY_ASSETS:-"\$OWGW_ROOT/rtty_ui"} \
|
||||
KAFKA_ENABLE=${KAFKA_ENABLE:-"true"} \
|
||||
KAFKA_BROKERLIST=${KAFKA_BROKERLIST:-"localhost:9092"} \
|
||||
KAFKA_SSL_CA_LOCATION=${KAFKA_SSL_CA_LOCATION:-""} \
|
||||
KAFKA_SSL_CERTIFICATE_LOCATION=${KAFKA_SSL_CERTIFICATE_LOCATION:-""} \
|
||||
KAFKA_SSL_KEY_LOCATION=${KAFKA_SSL_KEY_LOCATION:-""} \
|
||||
KAFKA_SSL_KEY_PASSWORD=${KAFKA_SSL_KEY_PASSWORD:-""} \
|
||||
STORAGE_TYPE=${STORAGE_TYPE:-"sqlite"} \
|
||||
STORAGE_TYPE_POSTGRESQL_HOST=${STORAGE_TYPE_POSTGRESQL_HOST:-"localhost"} \
|
||||
STORAGE_TYPE_POSTGRESQL_USERNAME=${STORAGE_TYPE_POSTGRESQL_USERNAME:-"owgw"} \
|
||||
STORAGE_TYPE_POSTGRESQL_PASSWORD=${STORAGE_TYPE_POSTGRESQL_PASSWORD:-"owgw"} \
|
||||
STORAGE_TYPE_POSTGRESQL_DATABASE=${STORAGE_TYPE_POSTGRESQL_DATABASE:-"owgw"} \
|
||||
STORAGE_TYPE_POSTGRESQL_PORT=${STORAGE_TYPE_POSTGRESQL_PORT:-"5432"} \
|
||||
STORAGE_TYPE_MYSQL_HOST=${STORAGE_TYPE_MYSQL_HOST:-"localhost"} \
|
||||
STORAGE_TYPE_MYSQL_USERNAME=${STORAGE_TYPE_MYSQL_USERNAME:-"owgw"} \
|
||||
STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"owgw"} \
|
||||
STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"owgw"} \
|
||||
STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \
|
||||
envsubst < /owgw.properties.tmpl > $OWGW_CONFIG/owgw.properties
|
||||
fi
|
||||
|
||||
# Check if rtty_ui directory exists
|
||||
export RTTY_ASSETS=$(grep 'rtty.assets' $OWGW_CONFIG/owgw.properties | awk -F '=' '{print $2}' | xargs | envsubst)
|
||||
|
||||
if [ -z "$RTTY_ASSETS" ]; then
|
||||
export RTTY_ASSETS="$OWGW_ROOT/rtty_ui"
|
||||
fi
|
||||
|
||||
if [[ ! -d "$(dirname $RTTY_ASSETS)" ]]; then
|
||||
mkdir -p $(dirname $RTTY_ASSETS)
|
||||
fi
|
||||
|
||||
if [[ ! -d "$RTTY_ASSETS" ]]; then
|
||||
cp -r /dist/rtty_ui $RTTY_ASSETS
|
||||
fi
|
||||
|
||||
if [ "$1" = '/openwifi/owgw' -a "$(id -u)" = '0' ]; then
|
||||
if [ "$RUN_CHOWN" = 'true' ]; then
|
||||
chown -R "$OWGW_USER": "$OWGW_ROOT" "$OWGW_CONFIG"
|
||||
chown -R "$OWGW_USER": "$OWGW_ROOT" "$OWGW_CONFIG"
|
||||
fi
|
||||
exec su-exec "$OWGW_USER" "$@"
|
||||
fi
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||
version: 10.9.2
|
||||
- name: mysql
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||
version: 8.8.3
|
||||
- name: mariadb
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||
version: 9.4.2
|
||||
digest: sha256:1fdae7cbea906e41dccd8618ff9e2c68d0c684724ae27c79a12bb6089968df5c
|
||||
generated: "2021-08-17T12:18:40.341427893+03:00"
|
||||
digest: sha256:e9df5a5d8a0a193bfda33ea06060203aace01f0f7df9eda662a84185322c7ab5
|
||||
generated: "2022-06-03T15:38:31.063022252+03:00"
|
||||
|
||||
@@ -5,14 +5,14 @@ name: owgw
|
||||
version: 0.1.0
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||
version: 10.9.2
|
||||
condition: postgresql.enabled
|
||||
- name: mysql
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||
version: 8.8.3
|
||||
condition: mysql.enabled
|
||||
- name: mariadb
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||
version: 9.4.2
|
||||
condition: mariadb.enabled
|
||||
|
||||
@@ -9,7 +9,7 @@ fullnameOverride: ""
|
||||
images:
|
||||
owgw:
|
||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owgw
|
||||
tag: master
|
||||
tag: v2.6.2
|
||||
pullPolicy: Always
|
||||
# regcred:
|
||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||
@@ -40,6 +40,12 @@ services:
|
||||
servicePort: 16003
|
||||
targetPort: 16003
|
||||
protocol: TCP
|
||||
rttys:
|
||||
servicePort: 5912
|
||||
targetPort: 5912
|
||||
rttys-view:
|
||||
servicePort: 5913
|
||||
targetPort: 5913
|
||||
|
||||
checks:
|
||||
owgw:
|
||||
@@ -209,19 +215,22 @@ configProperties:
|
||||
openwifi.devicetypes.0: AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
|
||||
openwifi.devicetypes.1: SWITCH:edgecore_ecs4100-12ph
|
||||
openwifi.devicetypes.2: IOT:esp32
|
||||
oui.download.uri: https://linuxnet.ca/ieee/oui.txt
|
||||
oui.download.uri: https://standards-oui.ieee.org/oui/oui.txt
|
||||
firmware.autoupdate.policy.default: auto
|
||||
iptocountry.provider: ipinfo
|
||||
# Callback
|
||||
openwifi.callback.enable: "false"
|
||||
openwifi.callback.0.local: localhost:16001
|
||||
openwifi.callback.0.remote: localhost:15055
|
||||
openwifi.callback.0.topics: owfws
|
||||
# rtty
|
||||
rtty.internal: "true"
|
||||
rtty.enabled: "true"
|
||||
rtty.server: localhost
|
||||
rtty.port: 5912
|
||||
rtty.timeout: 60
|
||||
rtty.viewport: 5913
|
||||
rtty.assets: $OWGW_ROOT/rtty_ui
|
||||
# ALB
|
||||
alb.enable: "true"
|
||||
alb.port: 16102
|
||||
|
||||
@@ -31,58 +31,13 @@ components:
|
||||
|
||||
responses:
|
||||
NotFound:
|
||||
description: The specified resource was not found.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
ErrorCode:
|
||||
type: integer
|
||||
ErrorDetails:
|
||||
type: string
|
||||
ErrorDescription:
|
||||
type: string
|
||||
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound'
|
||||
Unauthorized:
|
||||
description: The requested does not have sufficient rights to perform the operation.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
ErrorCode:
|
||||
type: integer
|
||||
enum:
|
||||
- 0 # Success
|
||||
- 1 # PASSWORD_CHANGE_REQUIRED,
|
||||
- 2 # INVALID_CREDENTIALS,
|
||||
- 3 # PASSWORD_ALREADY_USED,
|
||||
- 4 # USERNAME_PENDING_VERIFICATION,
|
||||
- 5 # PASSWORD_INVALID,
|
||||
- 6 # INTERNAL_ERROR,
|
||||
- 7 # ACCESS_DENIED,
|
||||
- 8 # INVALID_TOKEN
|
||||
- 9 # EXPIRED_TOKEN
|
||||
- 10 # RATE_LIMIT_EXCEEDED
|
||||
- 11 # BAD_MFA_TRANSACTION
|
||||
- 12 # MFA_FAILURE
|
||||
- 13 # SECURITY_SERVICE_UNREACHABLE
|
||||
ErrorDetails:
|
||||
type: string
|
||||
ErrorDescription:
|
||||
type: string
|
||||
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized'
|
||||
Success:
|
||||
description: The requested operation was performed.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
Operation:
|
||||
type: string
|
||||
Details:
|
||||
type: string
|
||||
Code:
|
||||
type: integer
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success'
|
||||
BadRequest:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest'
|
||||
|
||||
schemas:
|
||||
DeviceType:
|
||||
@@ -510,6 +465,31 @@ components:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
ScriptRequest:
|
||||
type: object
|
||||
properties:
|
||||
serialNumber:
|
||||
type: string
|
||||
timeout:
|
||||
type: integer
|
||||
format: int64
|
||||
default: 30
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- uci
|
||||
- ucode
|
||||
- shell
|
||||
script:
|
||||
type: string
|
||||
scriptId:
|
||||
type: string
|
||||
format: uuid
|
||||
when:
|
||||
type: integer
|
||||
format: int64
|
||||
default: 0
|
||||
|
||||
FactoryRequest:
|
||||
type: object
|
||||
properties:
|
||||
@@ -976,6 +956,12 @@ components:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/WifiBands'
|
||||
- $ref: '#/components/schemas/WifiChannels'
|
||||
ies:
|
||||
type: array
|
||||
items:
|
||||
type: integer
|
||||
minimum: 0
|
||||
maximum: 255
|
||||
required:
|
||||
- serialNumber
|
||||
|
||||
@@ -1047,6 +1033,72 @@ components:
|
||||
items:
|
||||
$ref: '#/components/schemas/CapabilitiesModel'
|
||||
|
||||
RadiusProxyServerEntry:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
ip:
|
||||
type: string
|
||||
format: ip-addr
|
||||
port:
|
||||
type: integer
|
||||
weight:
|
||||
type: integer
|
||||
secret:
|
||||
type: string
|
||||
certificate:
|
||||
type: string
|
||||
|
||||
RadiusProxyServerConfig:
|
||||
type: object
|
||||
properties:
|
||||
strategy:
|
||||
type: string
|
||||
enum:
|
||||
- random
|
||||
- round_robin
|
||||
- weighted
|
||||
monitor:
|
||||
type: boolean
|
||||
default: false
|
||||
monitorMethod:
|
||||
type: string
|
||||
enum:
|
||||
- none
|
||||
- https
|
||||
- radius
|
||||
methodParameters:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
servers:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/RadiusProxyServerEntry'
|
||||
|
||||
RadiusProxyPool:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
authConfig:
|
||||
$ref: '#/components/schemas/RadiusProxyServerConfig'
|
||||
acctConfig:
|
||||
$ref: '#/components/schemas/RadiusProxyServerConfig'
|
||||
coaConfig:
|
||||
$ref: '#/components/schemas/RadiusProxyServerConfig'
|
||||
|
||||
RadiusProxyPoolList:
|
||||
type: object
|
||||
properties:
|
||||
pools:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/RadiusProxyPool'
|
||||
|
||||
paths:
|
||||
/devices:
|
||||
get:
|
||||
@@ -1096,6 +1148,20 @@ paths:
|
||||
name: deviceWithStatus
|
||||
schema:
|
||||
type: boolean
|
||||
- in: query
|
||||
description: return extended information
|
||||
name: orderBy
|
||||
schema:
|
||||
type: string
|
||||
example: serialNumber:a,created:d
|
||||
required: false
|
||||
- in: query
|
||||
description: return extended information
|
||||
name: orderSpec
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
responses:
|
||||
200:
|
||||
description: List devices
|
||||
@@ -1992,6 +2058,32 @@ paths:
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/device/{serialNumber}/script:
|
||||
post:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Debug a device.
|
||||
operationId: debugDevice
|
||||
parameters:
|
||||
- in: path
|
||||
name: serialNumber
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
requestBody:
|
||||
description: Command details
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ScriptRequest'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/CommandInfo'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/device/{serialNumber}/factory:
|
||||
post:
|
||||
tags:
|
||||
@@ -2433,6 +2525,45 @@ paths:
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/radiusProxyConfig:
|
||||
get:
|
||||
tags:
|
||||
- RADIUSProxy
|
||||
summary: Retrieve RADIUS Proxy configuration.
|
||||
operationId: getRadiusProxyConfig
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/RadiusProxyPoolList'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
put:
|
||||
tags:
|
||||
- RADIUSProxy
|
||||
summary: Modify RADIUS Proxy configuration.
|
||||
operationId: modifyRadiusProxyConfig
|
||||
requestBody:
|
||||
description: Change RADIUS configuration pool config
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RadiusProxyPoolList'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/RadiusProxyPoolList'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- RADIUSProxy
|
||||
summary: Delete RADIUS Proxy configuration.
|
||||
operationId: deleteRadiusProxyConfig
|
||||
responses:
|
||||
204:
|
||||
$ref: '#/components/responses/Success'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
/deviceDashboard:
|
||||
get:
|
||||
tags:
|
||||
|
||||
@@ -74,7 +74,7 @@ openwifi.autoprovisioning = true
|
||||
openwifi.devicetypes.0 = AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
|
||||
openwifi.devicetypes.1 = SWITCH:edgecore_ecs4100-12ph
|
||||
openwifi.devicetypes.2 = IOT:esp32
|
||||
oui.download.uri = https://linuxnet.ca/ieee/oui.txt
|
||||
oui.download.uri = https://standards-oui.ieee.org/oui/oui.txt
|
||||
|
||||
iptocountry.default = US
|
||||
iptocountry.provider = ipinfo
|
||||
@@ -96,6 +96,12 @@ rtty.timeout = 60
|
||||
rtty.viewport = 5913
|
||||
rtty.assets = $OWGW_ROOT/rtty_ui
|
||||
|
||||
### RADIUS proxy config
|
||||
radius.proxy.enable = false
|
||||
radius.proxy.accounting.port = 1813
|
||||
radius.proxy.authentication.port = 1812
|
||||
radius.proxy.coa.port = 3799
|
||||
|
||||
#############################
|
||||
# Generic information for all micro services
|
||||
#############################
|
||||
|
||||
@@ -52,8 +52,8 @@ openwifi.fileuploader.host.0.cert = ${FILEUPLOADER_HOST_CERT}
|
||||
openwifi.fileuploader.host.0.key = ${FILEUPLOADER_HOST_KEY}
|
||||
openwifi.fileuploader.host.0.key.password = ${FILEUPLOADER_HOST_KEY_PASSWORD}
|
||||
openwifi.fileuploader.path = ${FILEUPLOADER_PATH}
|
||||
openwifi.fileuploader.uri = ${FILEUPLOADER_URI}
|
||||
openwifi.fileuploader.maxsize = 10000
|
||||
openwifi.fileuploader.uri = ${FILEUPLOADER_URI}
|
||||
|
||||
#
|
||||
# Generic section that all microservices must have
|
||||
@@ -74,19 +74,26 @@ openwifi.autoprovisioning = true
|
||||
openwifi.devicetypes.0 = AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
|
||||
openwifi.devicetypes.1 = SWITCH:edgecore_ecs4100-12ph
|
||||
openwifi.devicetypes.2 = IOT:esp32
|
||||
oui.download.uri = https://linuxnet.ca/ieee/oui.txt
|
||||
firmware.autoupdate.policy.default = auto
|
||||
oui.download.uri = https://standards-oui.ieee.org/oui/oui.txt
|
||||
simulatorid = ${SIMULATORID}
|
||||
iptocountry.default = US
|
||||
iptocountry.provider = ${IPTOCOUNTRY_PROVIDER}
|
||||
iptocountry.ipinfo.token = ${IPTOCOUNTRY_IPINFO_TOKEN}
|
||||
iptocountry.ipdata.apikey = ${IPTOCOUNTRY_IPDATA_APIKEY}
|
||||
|
||||
autoprovisioning.process = ${AUTOPROVISIONING_PROCESS}
|
||||
|
||||
#
|
||||
# rtty
|
||||
#
|
||||
rtty.internal = ${RTTY_INTERNAL}
|
||||
rtty.enabled = ${RTTY_ENABLED}
|
||||
rtty.server = ${RTTY_SERVER}
|
||||
rtty.port = ${RTTY_PORT}
|
||||
rtty.token = ${RTTY_TOKEN}
|
||||
rtty.timeout = ${RTTY_TIMEOUT}
|
||||
rtty.viewport = ${RTTY_VIEWPORT}
|
||||
rtty.assets = ${RTTY_ASSETS}
|
||||
|
||||
#############################
|
||||
# Generic information for all micro services
|
||||
@@ -106,6 +113,7 @@ openwifi.kafka.enable = ${KAFKA_ENABLE}
|
||||
openwifi.kafka.brokerlist = ${KAFKA_BROKERLIST}
|
||||
openwifi.kafka.auto.commit = false
|
||||
openwifi.kafka.queue.buffering.max.ms = 50
|
||||
|
||||
openwifi.kafka.ssl.ca.location = ${KAFKA_SSL_CA_LOCATION}
|
||||
openwifi.kafka.ssl.certificate.location = ${KAFKA_SSL_CERTIFICATE_LOCATION}
|
||||
openwifi.kafka.ssl.key.location = ${KAFKA_SSL_KEY_LOCATION}
|
||||
|
||||
41
pcap/radius
Normal file
41
pcap/radius
Normal file
@@ -0,0 +1,41 @@
|
||||
/* Frame (255 bytes) */
|
||||
static const unsigned char pkt41[255] = {
|
||||
0x14, 0x98, 0x77, 0x71, 0xc6, 0xe7, 0x34, 0xef, /* ..wq..4. */
|
||||
0xb6, 0xaf, 0x4a, 0x5c, 0x08, 0x00, 0x45, 0x00, /* ..J\..E. */
|
||||
0x00, 0xf1, 0x87, 0x50, 0x00, 0x00, 0x40, 0x11, /* ...P..@. */
|
||||
0x0c, 0xdf, 0xc0, 0xa8, 0xb2, 0x1b, 0xc0, 0xa8, /* ........ */
|
||||
0xb2, 0x60, 0xc3, 0xfe, 0x07, 0x14, 0x00, 0xdd, /* .`...... */
|
||||
0x26, 0x63, 0x01, 0x04, 0x00, 0xd5, 0xcc, 0x29, /* &c.....) */
|
||||
0x82, 0x36, 0xd6, 0x57, 0x3d, 0xa7, 0xd5, 0x62, /* .6.W=..b */
|
||||
0x70, 0x12, 0x00, 0xc0, 0xf2, 0x19, 0x01, 0x03, /* p....... */
|
||||
0x61, 0x1e, 0x1c, 0x33, 0x34, 0x2d, 0x45, 0x46, /* a..34-EF */
|
||||
0x2d, 0x42, 0x36, 0x2d, 0x41, 0x46, 0x2d, 0x34, /* -B6-AF-4 */
|
||||
0x41, 0x2d, 0x36, 0x30, 0x3a, 0x4f, 0x70, 0x65, /* A-60:Ope */
|
||||
0x6e, 0x57, 0x69, 0x66, 0x69, 0x3d, 0x06, 0x00, /* nWifi=.. */
|
||||
0x00, 0x00, 0x13, 0x06, 0x06, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x02, 0x05, 0x06, 0x00, 0x00, 0x00, 0x01, 0x1f, /* ........ */
|
||||
0x13, 0x42, 0x36, 0x2d, 0x43, 0x34, 0x2d, 0x30, /* .B6-C4-0 */
|
||||
0x36, 0x2d, 0x30, 0x39, 0x2d, 0x31, 0x35, 0x2d, /* 6-09-15- */
|
||||
0x42, 0x37, 0x4d, 0x18, 0x43, 0x4f, 0x4e, 0x4e, /* B7M.CONN */
|
||||
0x45, 0x43, 0x54, 0x20, 0x35, 0x34, 0x4d, 0x62, /* ECT 54Mb */
|
||||
0x70, 0x73, 0x20, 0x38, 0x30, 0x32, 0x2e, 0x31, /* ps 802.1 */
|
||||
0x31, 0x61, 0x2c, 0x12, 0x33, 0x42, 0x45, 0x44, /* 1a,.3BED */
|
||||
0x37, 0x32, 0x39, 0x30, 0x44, 0x30, 0x43, 0x38, /* 7290D0C8 */
|
||||
0x35, 0x36, 0x44, 0x33, 0xba, 0x06, 0x00, 0x0f, /* 56D3.... */
|
||||
0xac, 0x04, 0xbb, 0x06, 0x00, 0x0f, 0xac, 0x04, /* ........ */
|
||||
0xbc, 0x06, 0x00, 0x0f, 0xac, 0x05, 0xbd, 0x06, /* ........ */
|
||||
0x00, 0x0f, 0xac, 0x06, 0x1a, 0x1b, 0x00, 0x00, /* ........ */
|
||||
0xe6, 0x08, 0x47, 0x15, 0x01, 0x13, 0x33, 0x34, /* ..G...34 */
|
||||
0x2d, 0x65, 0x66, 0x2d, 0x62, 0x36, 0x2d, 0x61, /* -ef-b6-a */
|
||||
0x66, 0x2d, 0x34, 0x61, 0x2d, 0x35, 0x63, 0x0c, /* f-4a-5c. */
|
||||
0x06, 0x00, 0x00, 0x05, 0x78, 0x4f, 0x08, 0x02, /* ....xO.. */
|
||||
0x01, 0x00, 0x06, 0x01, 0x61, 0x50, 0x12, 0x20, /* ....aP. */
|
||||
0x9c, 0xae, 0xe5, 0xe3, 0x77, 0xaf, 0x0b, 0x1b, /* ....w... */
|
||||
0xaf, 0x0e, 0xb5, 0x08, 0x82, 0x9e, 0xeb /* ....... */
|
||||
};
|
||||
|
||||
/* Reassembled EAP (6 bytes) */
|
||||
static const unsigned char pkt41_1[6] = {
|
||||
0x02, 0x01, 0x00, 0x06, 0x01, 0x61 /* .....a */
|
||||
};
|
||||
|
||||
1
pcap/radius.blob.bin
Normal file
1
pcap/radius.blob.bin
Normal file
@@ -0,0 +1 @@
|
||||
192.168.178.1
|
||||
BIN
pcap/radius.pcapng
Normal file
BIN
pcap/radius.pcapng
Normal file
Binary file not shown.
72
radius_config_sample.json
Normal file
72
radius_config_sample.json
Normal file
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"pools" : [
|
||||
{
|
||||
"name" : "master" ,
|
||||
"description" : "master pool",
|
||||
"useByDefault" : true,
|
||||
"authConfig" : {
|
||||
"strategy" : "weighted",
|
||||
"monitor" : false,
|
||||
"monitorMethod" : "none",
|
||||
"methodParameters" : [],
|
||||
"servers" : [ {
|
||||
"name" : "svr1",
|
||||
"ip" : "10.100.0.1",
|
||||
"port" : 1812,
|
||||
"weight" : 10,
|
||||
"secret" : "my_secret!"
|
||||
},
|
||||
{
|
||||
"name" : "svr2",
|
||||
"ip" : "10.100.10.1",
|
||||
"port" : 1812,
|
||||
"weight" : 20,
|
||||
"secret" : "my_secret!"
|
||||
}
|
||||
]
|
||||
},
|
||||
"acctConfig" : {
|
||||
"strategy" : "random",
|
||||
"monitor" : false,
|
||||
"monitorMethod" : "none",
|
||||
"methodParameters" : [],
|
||||
"servers" : [ {
|
||||
"name" : "svr1",
|
||||
"ip" : "10.100.0.1",
|
||||
"port" : 1813,
|
||||
"weight" : 10,
|
||||
"secret" : "my_secret!"
|
||||
},
|
||||
{
|
||||
"name" : "svr2",
|
||||
"ip" : "10.100.10.1",
|
||||
"port" : 1813,
|
||||
"weight" : 20,
|
||||
"secret" : "my_secret!"
|
||||
}
|
||||
]
|
||||
},
|
||||
"coaConfig" : {
|
||||
"strategy" : "round_robin",
|
||||
"monitor" : false,
|
||||
"monitorMethod" : "none",
|
||||
"methodParameters" : [],
|
||||
"servers" : [ {
|
||||
"name" : "svr1",
|
||||
"ip" : "10.100.0.1",
|
||||
"port" : 3799,
|
||||
"weight" : 10,
|
||||
"secret" : "my_secret!"
|
||||
},
|
||||
{
|
||||
"name" : "svr2",
|
||||
"ip" : "10.100.10.1",
|
||||
"port" : 3799,
|
||||
"weight" : 20,
|
||||
"secret" : "my_secret!"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +1,26 @@
|
||||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="/favicon.ico"><title>Rttys</title><link href="/css/app.0e046291.css" rel="preload" as="style"><link href="/css/chunk-vendors.b221ddbd.css" rel="preload" as="style"><link href="/js/app.79bf330a.js" rel="preload" as="script"><link href="/js/chunk-vendors.7fd2577a.js" rel="preload" as="script"><link href="/css/chunk-vendors.b221ddbd.css" rel="stylesheet"><link href="/css/app.0e046291.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but Rttys doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/js/chunk-vendors.7fd2577a.js"></script><script src="/js/app.79bf330a.js"></script></body></html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||
<link rel="icon" href="/favicon.ico">
|
||||
<title>RTTYs</title>
|
||||
<link href="/css/app.0e046291.css" rel="preload" as="style">
|
||||
<link href="/css/chunk-vendors.b221ddbd.css" rel="preload" as="style">
|
||||
<link href="/css/chunk-vendors.b221ddbd.css" rel="stylesheet">
|
||||
<link href="/css/app.0e046291.css" rel="stylesheet">
|
||||
<link href="/js/app.79bf330a.js" rel="preload" as="script">
|
||||
<link href="/js/chunk-vendors.7fd2577a.js" rel="preload" as="script">
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but Rttys doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<script src="/js/chunk-vendors.7fd2577a.js">
|
||||
</script><script src="/js/app.79bf330a.js">
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
#include "CommandManager.h"
|
||||
#include "DeviceRegistry.h"
|
||||
#include "RESTObjects//RESTAPI_GWobjects.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/ow_constants.h"
|
||||
@@ -20,64 +19,75 @@
|
||||
namespace OpenWifi {
|
||||
|
||||
void CommandManager::run() {
|
||||
Utils::SetThreadName("cmd-mgr");
|
||||
Running_ = true;
|
||||
while(Running_)
|
||||
{
|
||||
Poco::Thread::trySleep(30000);
|
||||
if(!Running_)
|
||||
break;
|
||||
Poco::AutoPtr<Poco::Notification> NextMsg(ResponseQueue_.waitDequeueNotification());
|
||||
while(NextMsg && Running_) {
|
||||
auto Resp = dynamic_cast<RPCResponseNotification*>(NextMsg.get());
|
||||
|
||||
std::vector<GWObjects::CommandDetails> Commands;
|
||||
if(StorageService()->GetReadyToExecuteCommands(0,200,Commands))
|
||||
{
|
||||
for(auto & Cmd: Commands)
|
||||
{
|
||||
if(!Running_)
|
||||
break;
|
||||
try {
|
||||
Poco::JSON::Parser P;
|
||||
bool Sent;
|
||||
Logger().information(Poco::format("Parsing: %s", Cmd.UUID));
|
||||
auto Params = P.parse(Cmd.Details).extract<Poco::JSON::Object::Ptr>();
|
||||
Logger().information(Poco::format("Parsed: %s", Cmd.UUID));
|
||||
auto Result = PostCommandDisk( Cmd.SerialNumber,
|
||||
Cmd.Command,
|
||||
*Params,
|
||||
Cmd.UUID,
|
||||
Sent);
|
||||
if(Sent) {
|
||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||
Logger().information(Poco::format("%s: Sent command '%s-%s'", Cmd.SerialNumber, Cmd.Command, Cmd.UUID));
|
||||
if(Resp!= nullptr) {
|
||||
const Poco::JSON::Object & Payload = Resp->Payload_;
|
||||
const std::string & SerialNumber = Resp->SerialNumber_;
|
||||
|
||||
std::ostringstream SS;
|
||||
Payload.stringify(SS);
|
||||
|
||||
Logger().debug(fmt::format("({}): RPC Response received.", SerialNumber));
|
||||
if(!Payload.has(uCentralProtocol::ID)){
|
||||
Logger().error(fmt::format("({}): Invalid RPC response.", SerialNumber));
|
||||
} else {
|
||||
uint64_t ID = Payload.get(uCentralProtocol::ID);
|
||||
if (ID < 2) {
|
||||
Logger().debug(fmt::format("({}): Ignoring RPC response.", SerialNumber));
|
||||
} else {
|
||||
auto Idx = CommandTagIndex{.Id = ID, .SerialNumber = SerialNumber};
|
||||
std::lock_guard G(Mutex_);
|
||||
auto RPC = OutStandingRequests_.find(Idx);
|
||||
if (RPC == OutStandingRequests_.end()) {
|
||||
Logger().warning(
|
||||
fmt::format("({}): Outdated RPC {}", SerialNumber, ID));
|
||||
} else {
|
||||
Logger().information(Poco::format("%s: Could not send command '%s-%s'", Cmd.SerialNumber, Cmd.Command, Cmd.UUID));
|
||||
std::chrono::duration<double, std::milli> rpc_execution_time =
|
||||
std::chrono::high_resolution_clock::now() - RPC->second->submitted;
|
||||
StorageService()->CommandCompleted(RPC->second->uuid, Payload,
|
||||
rpc_execution_time, true);
|
||||
if (RPC->second->rpc_entry) {
|
||||
RPC->second->rpc_entry->set_value(Payload);
|
||||
}
|
||||
OutstandingUUIDs_.erase(RPC->second->uuid);
|
||||
OutStandingRequests_.erase(Idx);
|
||||
Logger().information(
|
||||
fmt::format("({}): Received RPC answer {}", SerialNumber, ID));
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().information(Poco::format("%s: Failed command '%s-%s'", Cmd.SerialNumber, Cmd.Command, Cmd.UUID));
|
||||
Logger().log(E);
|
||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||
} catch (...) {
|
||||
Logger().information(Poco::format("%s: Exception - hard fail - Failed command '%s-%s'", Cmd.SerialNumber, Cmd.Command, Cmd.UUID));
|
||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NextMsg = ResponseQueue_.waitDequeueNotification();
|
||||
}
|
||||
}
|
||||
|
||||
int CommandManager::Start() {
|
||||
Logger().notice("Starting...");
|
||||
ManagerThread.start(*this);
|
||||
JanitorCallback_ = std::make_unique<Poco::TimerCallback<CommandManager>>(*this,&CommandManager::onTimer);
|
||||
Timer_.setStartInterval( 10000 );
|
||||
Timer_.setPeriodicInterval(5 * 60 * 1000); // 1 hours
|
||||
Timer_.start(*JanitorCallback_);
|
||||
JanitorCallback_ = std::make_unique<Poco::TimerCallback<CommandManager>>(*this,&CommandManager::onJanitorTimer);
|
||||
JanitorTimer_.setStartInterval( 10000 );
|
||||
JanitorTimer_.setPeriodicInterval(10 * 60 * 1000); // 1 hours
|
||||
JanitorTimer_.start(*JanitorCallback_);
|
||||
|
||||
CommandRunnerCallback_ = std::make_unique<Poco::TimerCallback<CommandManager>>(*this,&CommandManager::onCommandRunnerTimer);
|
||||
CommandRunnerTimer_.setStartInterval( 10000 );
|
||||
CommandRunnerTimer_.setPeriodicInterval(30 * 1000); // 1 hours
|
||||
CommandRunnerTimer_.start(*CommandRunnerCallback_);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CommandManager::Stop() {
|
||||
Logger().notice("Stopping...");
|
||||
Running_ = false;
|
||||
Timer_.stop();
|
||||
JanitorTimer_.stop();
|
||||
CommandRunnerTimer_.stop();
|
||||
ResponseQueue_.wakeUpAll();
|
||||
ManagerThread.wakeUp();
|
||||
ManagerThread.join();
|
||||
}
|
||||
@@ -87,22 +97,75 @@ namespace OpenWifi {
|
||||
ManagerThread.wakeUp();
|
||||
}
|
||||
|
||||
void CommandManager::onTimer(Poco::Timer & timer) {
|
||||
void CommandManager::onJanitorTimer([[maybe_unused]] Poco::Timer & timer) {
|
||||
std::lock_guard G(Mutex_);
|
||||
Logger().information("Removing expired commands: start");
|
||||
auto Now = std::chrono::high_resolution_clock::now();
|
||||
Utils::SetThreadName("cmd-janitor");
|
||||
Poco::Logger & MyLogger = Poco::Logger::get("CMD-MGR-JANITOR");
|
||||
MyLogger.information(
|
||||
fmt::format("Removing expired commands: start. {} outstanding-requests {} outstanding-uuids commands.",
|
||||
OutStandingRequests_.size(), OutstandingUUIDs_.size() ));
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
for(auto i=OutStandingRequests_.begin();i!=OutStandingRequests_.end();) {
|
||||
std::chrono::duration<double, std::milli> delta = Now - i->second->submitted;
|
||||
if(delta > 120000ms) {
|
||||
std::chrono::duration<double, std::milli> delta = now - i->second->submitted;
|
||||
if(delta > 6000000ms) {
|
||||
MyLogger.debug(fmt::format("{}: Timed out.", i->second->uuid));
|
||||
OutstandingUUIDs_.erase(i->second->uuid);
|
||||
i = OutStandingRequests_.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
Logger().information("Removing expired commands: done");
|
||||
MyLogger.information("Removing expired commands: done.");
|
||||
}
|
||||
|
||||
std::shared_ptr<CommandManager::promise_type_t> CommandManager::PostCommand( const std::string &SerialNumber,
|
||||
void CommandManager::onCommandRunnerTimer([[maybe_unused]] Poco::Timer &timer) {
|
||||
Utils::SetThreadName("cmd-schdlr");
|
||||
Poco::Logger & MyLogger = Poco::Logger::get("CMD-MGR-SCHEDULER");
|
||||
|
||||
std::vector<GWObjects::CommandDetails> Commands;
|
||||
if(StorageService()->GetReadyToExecuteCommands(0,200,Commands))
|
||||
{
|
||||
for(auto & Cmd: Commands)
|
||||
{
|
||||
if(!Running_)
|
||||
break;
|
||||
try {
|
||||
{
|
||||
std::lock_guard M(Mutex_);
|
||||
if(OutstandingUUIDs_.find(Cmd.UUID)!=OutstandingUUIDs_.end())
|
||||
continue;
|
||||
}
|
||||
|
||||
Poco::JSON::Parser P;
|
||||
bool Sent;
|
||||
MyLogger.information(fmt::format("{}: Preparing execution of {} for {}.", Cmd.UUID, Cmd.Command, Cmd.SerialNumber));
|
||||
auto Params = P.parse(Cmd.Details).extract<Poco::JSON::Object::Ptr>();
|
||||
auto Result = PostCommandDisk( Cmd.SerialNumber,
|
||||
Cmd.Command,
|
||||
*Params,
|
||||
Cmd.UUID,
|
||||
Sent);
|
||||
if(Sent) {
|
||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||
std::lock_guard M(Mutex_);
|
||||
OutstandingUUIDs_.insert(Cmd.UUID);
|
||||
MyLogger.information(fmt::format("{}: Queued command.", Cmd.UUID));
|
||||
} else {
|
||||
MyLogger.information(fmt::format("{}: Could queue command.", Cmd.UUID));
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
MyLogger.information(fmt::format("{}: Failed. Command marked as completed.", Cmd.UUID));
|
||||
MyLogger.log(E);
|
||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||
} catch (...) {
|
||||
MyLogger.information(fmt::format("{}: Hard failure.", Cmd.UUID));
|
||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<CommandManager::promise_type_t> CommandManager::PostCommand(const std::string &SerialNumber,
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
@@ -133,9 +196,6 @@ namespace OpenWifi {
|
||||
CompleteRPC.set(uCentralProtocol::METHOD, Method);
|
||||
CompleteRPC.set(uCentralProtocol::PARAMS, Params);
|
||||
Poco::JSON::Stringifier::stringify(CompleteRPC, ToSend);
|
||||
Logger().information(
|
||||
Poco::format("(%s): Sending command '%s', ID: %lu", SerialNumber, Method, Idx.Id));
|
||||
|
||||
Object->submitted = std::chrono::high_resolution_clock::now();
|
||||
Object->uuid = UUID;
|
||||
if(disk_only) {
|
||||
@@ -143,41 +203,19 @@ namespace OpenWifi {
|
||||
} else {
|
||||
Object->rpc_entry = std::make_shared<CommandManager::promise_type_t>();
|
||||
}
|
||||
OutStandingRequests_[Idx] = Object;
|
||||
if(!oneway_rpc) {
|
||||
OutStandingRequests_[Idx] = Object;
|
||||
OutstandingUUIDs_.insert(UUID);
|
||||
}
|
||||
}
|
||||
|
||||
Logger().information(fmt::format("{}: Sending command. ID: {}", UUID, Idx.Id));
|
||||
if(DeviceRegistry()->SendFrame(SerialNumber, ToSend.str())) {
|
||||
Logger().information(fmt::format("{}: Sent command. ID: {}", UUID, Idx.Id));
|
||||
Sent=true;
|
||||
return Object->rpc_entry;
|
||||
}
|
||||
Logger().information(fmt::format("{}: Failed to send command. ID: {}", UUID, Idx.Id));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CommandManager::PostCommandResult(const std::string &SerialNumber, Poco::JSON::Object::Ptr Obj) {
|
||||
|
||||
if(!Obj->has(uCentralProtocol::ID)){
|
||||
Logger().error(Poco::format("(%s): Invalid RPC response.",SerialNumber));
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t ID = Obj->get(uCentralProtocol::ID);
|
||||
if(ID<2) {
|
||||
Logger().error(Poco::format("(%s): Ignoring RPC response.",SerialNumber));
|
||||
return;
|
||||
}
|
||||
std::lock_guard G(Mutex_);
|
||||
auto Idx = CommandTagIndex{.Id = ID, .SerialNumber = SerialNumber};
|
||||
auto RPC = OutStandingRequests_.find(Idx);
|
||||
if (RPC == OutStandingRequests_.end()) {
|
||||
Logger().warning(Poco::format("(%s): Outdated RPC %lu", SerialNumber, ID));
|
||||
return;
|
||||
}
|
||||
std::chrono::duration<double, std::milli> rpc_execution_time = std::chrono::high_resolution_clock::now() - RPC->second->submitted;
|
||||
StorageService()->CommandCompleted(RPC->second->uuid, Obj, rpc_execution_time, true);
|
||||
if(RPC->second->rpc_entry) {
|
||||
RPC->second->rpc_entry->set_value(Obj);
|
||||
}
|
||||
Logger().information(Poco::format("(%s): Received RPC answer %lu", SerialNumber, ID));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -43,9 +43,23 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
class CommandManager : public SubSystemServer, Poco::Runnable {
|
||||
class RPCResponseNotification: public Poco::Notification {
|
||||
public:
|
||||
RPCResponseNotification(const std::string &ser,
|
||||
const Poco::JSON::Object &pl) :
|
||||
SerialNumber_(ser),
|
||||
Payload_(pl)
|
||||
{
|
||||
|
||||
}
|
||||
std::string SerialNumber_;
|
||||
Poco::JSON::Object Payload_;
|
||||
};
|
||||
|
||||
|
||||
class CommandManager : public SubSystemServer, Poco::Runnable {
|
||||
public:
|
||||
typedef Poco::JSON::Object::Ptr objtype_t;
|
||||
typedef Poco::JSON::Object objtype_t;
|
||||
typedef std::promise<objtype_t> promise_type_t;
|
||||
struct RpcObject {
|
||||
std::string uuid;
|
||||
@@ -53,10 +67,25 @@ namespace OpenWifi {
|
||||
std::shared_ptr<promise_type_t> rpc_entry;
|
||||
};
|
||||
|
||||
struct RPCResponse {
|
||||
std::string serialNumber;
|
||||
Poco::JSON::Object payload;
|
||||
|
||||
explicit RPCResponse(const std::string &ser, const Poco::JSON::Object &pl)
|
||||
:
|
||||
serialNumber(ser),
|
||||
payload(pl) {
|
||||
}
|
||||
};
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void WakeUp();
|
||||
void PostCommandResult(const std::string &SerialNumber, Poco::JSON::Object::Ptr Obj);
|
||||
inline void PostCommandResult(const std::string &SerialNumber, const Poco::JSON::Object &Obj) {
|
||||
std::lock_guard G(Mutex_);
|
||||
// RPCResponseQueue_->Write(RPCResponse{.serialNumber=SerialNumber, .payload = Obj});
|
||||
ResponseQueue_.enqueueNotification(new RPCResponseNotification(SerialNumber,Obj));
|
||||
}
|
||||
|
||||
std::shared_ptr<promise_type_t> PostCommandOneWayDisk(
|
||||
const std::string &SerialNumber,
|
||||
@@ -120,15 +149,21 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
inline bool Running() const { return Running_; }
|
||||
void onTimer(Poco::Timer & timer);
|
||||
void onJanitorTimer(Poco::Timer & timer);
|
||||
void onCommandRunnerTimer(Poco::Timer & timer);
|
||||
void onRPCAnswer(bool& b);
|
||||
|
||||
private:
|
||||
std::atomic_bool Running_ = false;
|
||||
volatile bool Running_ = false;
|
||||
Poco::Thread ManagerThread;
|
||||
uint64_t Id_=3; // do not start @1. We ignore ID=1 & 0 is illegal..
|
||||
volatile uint64_t Id_=3; // do not start @1. We ignore ID=1 & 0 is illegal..
|
||||
std::map<CommandTagIndex,std::shared_ptr<RpcObject>> OutStandingRequests_;
|
||||
Poco::Timer Timer_;
|
||||
std::set<std::string> OutstandingUUIDs_;
|
||||
Poco::Timer JanitorTimer_;
|
||||
std::unique_ptr<Poco::TimerCallback<CommandManager>> JanitorCallback_;
|
||||
Poco::Timer CommandRunnerTimer_;
|
||||
std::unique_ptr<Poco::TimerCallback<CommandManager>> CommandRunnerCallback_;
|
||||
Poco::NotificationQueue ResponseQueue_;
|
||||
|
||||
std::shared_ptr<promise_type_t> PostCommand(
|
||||
const std::string &SerialNumber,
|
||||
|
||||
@@ -6,12 +6,10 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/Option.h"
|
||||
#include "Poco/Environment.h"
|
||||
|
||||
#include "CentralConfig.h"
|
||||
#include "CommandManager.h"
|
||||
#include "Daemon.h"
|
||||
#include "DeviceRegistry.h"
|
||||
@@ -26,6 +24,8 @@
|
||||
#include "framework/MicroService.h"
|
||||
#include "FindCountry.h"
|
||||
#include "rttys/RTTYS_server.h"
|
||||
#include "RADIUS_proxy_server.h"
|
||||
#include "VenueBroadcaster.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class Daemon *Daemon::instance() {
|
||||
@@ -38,6 +38,7 @@ namespace OpenWifi {
|
||||
StorageService(),
|
||||
SerialNumberCache(),
|
||||
ConfigurationValidator(),
|
||||
WebSocketClientServer(),
|
||||
OUIServer(),
|
||||
FindCountryFromIP(),
|
||||
DeviceRegistry(),
|
||||
@@ -46,7 +47,9 @@ namespace OpenWifi {
|
||||
StorageArchiver(),
|
||||
TelemetryStream(),
|
||||
RTTYS_server(),
|
||||
WebSocketServer()
|
||||
WebSocketServer(),
|
||||
RADIUS_proxy_server(),
|
||||
VenueBroadcaster()
|
||||
});
|
||||
return &instance;
|
||||
}
|
||||
@@ -84,14 +87,12 @@ namespace OpenWifi {
|
||||
{"wallys_dr40x9","AP"}
|
||||
};
|
||||
|
||||
void Daemon::initialize() {
|
||||
void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) {
|
||||
AutoProvisioning_ = config().getBool("openwifi.autoprovisioning",false);
|
||||
DeviceTypes_ = DefaultDeviceTypes;
|
||||
}
|
||||
|
||||
void MicroServicePostInitialization() {
|
||||
Daemon()->initialize();
|
||||
}
|
||||
WebSocketProcessor_ = std::make_unique<GwWebSocketClient>(logger());
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string Daemon::IdentifyDevice(const std::string & Id ) const {
|
||||
for(const auto &[DeviceType,Type]:DeviceTypes_)
|
||||
|
||||
18
src/Daemon.h
18
src/Daemon.h
@@ -27,14 +27,15 @@
|
||||
#include "Dashboard.h"
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
#include "GwWebSocketClient.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
static const char * vDAEMON_PROPERTIES_FILENAME = "owgw.properties";
|
||||
static const char * vDAEMON_ROOT_ENV_VAR = "OWGW_ROOT";
|
||||
static const char * vDAEMON_CONFIG_ENV_VAR = "OWGW_CONFIG";
|
||||
static const char * vDAEMON_APP_NAME = uSERVICE_GATEWAY.c_str();
|
||||
static const uint64_t vDAEMON_BUS_TIMER = 10000;
|
||||
[[maybe_unused]] static const char * vDAEMON_PROPERTIES_FILENAME = "owgw.properties";
|
||||
[[maybe_unused]] static const char * vDAEMON_ROOT_ENV_VAR = "OWGW_ROOT";
|
||||
[[maybe_unused]] static const char * vDAEMON_CONFIG_ENV_VAR = "OWGW_CONFIG";
|
||||
[[maybe_unused]] static const char * vDAEMON_APP_NAME = uSERVICE_GATEWAY.c_str();
|
||||
[[maybe_unused]] static const uint64_t vDAEMON_BUS_TIMER = 10000;
|
||||
|
||||
class Daemon : public MicroService {
|
||||
public:
|
||||
@@ -48,17 +49,20 @@ namespace OpenWifi {
|
||||
|
||||
bool AutoProvisioning() const { return AutoProvisioning_ ; }
|
||||
[[nodiscard]] std::string IdentifyDevice(const std::string & Compatible) const;
|
||||
void initialize();
|
||||
static Daemon *instance();
|
||||
inline DeviceDashboard & GetDashboard() { return DB_; }
|
||||
Poco::Logger & Log() { return Poco::Logger::get(AppName()); }
|
||||
void PostInitialization(Poco::Util::Application &self);
|
||||
private:
|
||||
bool AutoProvisioning_ = false;
|
||||
std::vector<std::pair<std::string,std::string>> DeviceTypes_;
|
||||
DeviceDashboard DB_;
|
||||
|
||||
std::unique_ptr<GwWebSocketClient> WebSocketProcessor_;
|
||||
};
|
||||
|
||||
inline Daemon * Daemon() { return Daemon::instance(); }
|
||||
inline void DaemonPostInitialization(Poco::Util::Application &self) {
|
||||
Daemon()->PostInitialization(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
void DeviceDashboard::Create() {
|
||||
uint64_t Now = std::time(nullptr);
|
||||
uint64_t Now = OpenWifi::Now();
|
||||
|
||||
if(LastRun_==0 || (Now-LastRun_)>120) {
|
||||
DB_.reset();
|
||||
|
||||
@@ -93,7 +93,7 @@ namespace OpenWifi {
|
||||
|
||||
const auto & E = Devices_[SerialNumber] = std::make_shared<ConnectionEntry>();
|
||||
E->WSConn_ = Ptr;
|
||||
E->Conn_.LastContact = std::time(nullptr);
|
||||
E->Conn_.LastContact = OpenWifi::Now();
|
||||
E->Conn_.Connected = true ;
|
||||
E->Conn_.UUID = 0 ;
|
||||
E->Conn_.MessageCount = 0 ;
|
||||
@@ -129,7 +129,58 @@ namespace OpenWifi {
|
||||
try {
|
||||
return Device->second->WSConn_->Send(Payload);
|
||||
} catch (...) {
|
||||
Logger().debug(Poco::format("Could not send data to device '%s'", SerialNumber));
|
||||
Logger().debug(fmt::format("Could not send data to device '{}'", SerialNumber));
|
||||
Device->second->Conn_.Address = "";
|
||||
Device->second->WSConn_ = nullptr;
|
||||
Device->second->Conn_.Connected = false;
|
||||
Device->second->Conn_.VerifiedCertificate = GWObjects::NO_CERTIFICATE;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceRegistry::SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
auto Device = Devices_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||
if(Device!=Devices_.end() && Device->second->WSConn_!= nullptr) {
|
||||
try {
|
||||
return Device->second->WSConn_->SendRadiusAccountingData(buffer,size);
|
||||
} catch (...) {
|
||||
Logger().debug(fmt::format("Could not send data to device '{}'", SerialNumber));
|
||||
Device->second->Conn_.Address = "";
|
||||
Device->second->WSConn_ = nullptr;
|
||||
Device->second->Conn_.Connected = false;
|
||||
Device->second->Conn_.VerifiedCertificate = GWObjects::NO_CERTIFICATE;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceRegistry::SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
auto Device = Devices_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||
if(Device!=Devices_.end() && Device->second->WSConn_!= nullptr) {
|
||||
try {
|
||||
return Device->second->WSConn_->SendRadiusAuthenticationData(buffer,size);
|
||||
} catch (...) {
|
||||
Logger().debug(fmt::format("Could not send data to device '{}'", SerialNumber));
|
||||
Device->second->Conn_.Address = "";
|
||||
Device->second->WSConn_ = nullptr;
|
||||
Device->second->Conn_.Connected = false;
|
||||
Device->second->Conn_.VerifiedCertificate = GWObjects::NO_CERTIFICATE;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceRegistry::SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
auto Device = Devices_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||
if(Device!=Devices_.end() && Device->second->WSConn_!= nullptr) {
|
||||
try {
|
||||
return Device->second->WSConn_->SendRadiusCoAData(buffer,size);
|
||||
} catch (...) {
|
||||
Logger().debug(fmt::format("Could not send data to device '{}'", SerialNumber));
|
||||
Device->second->Conn_.Address = "";
|
||||
Device->second->WSConn_ = nullptr;
|
||||
Device->second->Conn_.Connected = false;
|
||||
|
||||
@@ -103,6 +103,10 @@ namespace OpenWifi {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
|
||||
private:
|
||||
inline static std::atomic_uint64_t Id_=1;
|
||||
std::map<uint64_t ,std::shared_ptr<ConnectionEntry>> Devices_;
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
#include "Poco/Net/HTTPServerParams.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "Poco/DynamicAny.h"
|
||||
#include "Poco/Net/HTMLForm.h"
|
||||
#include "Poco/Net/PartHandler.h"
|
||||
#include "Poco/Net/MessageHeader.h"
|
||||
#include "Poco/Net/MultipartReader.h"
|
||||
#include "Poco/CountingStream.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/Exception.h"
|
||||
@@ -41,37 +41,65 @@ namespace OpenWifi {
|
||||
Path_ = "/tmp";
|
||||
}
|
||||
}
|
||||
|
||||
for(const auto & Svr: ConfigServersList_) {
|
||||
std::string l{"Starting: " +
|
||||
Svr.Address() + ":" + std::to_string(Svr.Port()) +
|
||||
" key:" + Svr.KeyFile() +
|
||||
" cert:" + Svr.CertFile()};
|
||||
Logger().information(l);
|
||||
if(MicroService::instance().NoAPISecurity()) {
|
||||
Logger().information(fmt::format("Starting: {}:{}",Svr.Address(),Svr.Port()));
|
||||
|
||||
auto Sock{Svr.CreateSecureSocket(Logger())};
|
||||
auto Sock{Svr.CreateSocket(Logger())};
|
||||
|
||||
Svr.LogCert(Logger());
|
||||
if(!Svr.RootCA().empty())
|
||||
Svr.LogCas(Logger());
|
||||
auto Params = new Poco::Net::HTTPServerParams;
|
||||
Params->setMaxThreads(16);
|
||||
Params->setMaxQueued(100);
|
||||
|
||||
auto Params = new Poco::Net::HTTPServerParams;
|
||||
Params->setMaxThreads(16);
|
||||
Params->setMaxQueued(100);
|
||||
if (FullName_.empty()) {
|
||||
std::string TmpName =
|
||||
MicroService::instance().ConfigGetString("openwifi.fileuploader.uri", "");
|
||||
if (TmpName.empty()) {
|
||||
FullName_ =
|
||||
"https://" + Svr.Name() + ":" + std::to_string(Svr.Port()) + URI_BASE;
|
||||
} else {
|
||||
FullName_ = TmpName + URI_BASE;
|
||||
}
|
||||
Logger().information(fmt::format("Uploader URI base is '{}'", FullName_));
|
||||
}
|
||||
|
||||
if(FullName_.empty()) {
|
||||
std::string TmpName = MicroService::instance().ConfigGetString("openwifi.fileuploader.uri","");
|
||||
if(TmpName.empty()) {
|
||||
FullName_ =
|
||||
"https://" + Svr.Name() + ":" + std::to_string(Svr.Port()) + URI_BASE;
|
||||
} else {
|
||||
FullName_ = TmpName + URI_BASE ;
|
||||
}
|
||||
Logger().information(Poco::format("Uploader URI base is '%s'", FullName_));
|
||||
}
|
||||
auto NewServer = std::make_unique<Poco::Net::HTTPServer>(
|
||||
new FileUpLoaderRequestHandlerFactory(Logger()), Sock, Params);
|
||||
NewServer->start();
|
||||
Servers_.push_back(std::move(NewServer));
|
||||
} else {
|
||||
std::string l{"Starting: " + Svr.Address() + ":" + std::to_string(Svr.Port()) +
|
||||
" key:" + Svr.KeyFile() + " cert:" + Svr.CertFile()};
|
||||
Logger().information(l);
|
||||
|
||||
auto NewServer = std::make_unique<Poco::Net::HTTPServer>(new FileUpLoaderRequestHandlerFactory(Logger()), Pool_, Sock, Params);
|
||||
NewServer->start();
|
||||
Servers_.push_back(std::move(NewServer));
|
||||
auto Sock{Svr.CreateSecureSocket(Logger())};
|
||||
|
||||
Svr.LogCert(Logger());
|
||||
if (!Svr.RootCA().empty())
|
||||
Svr.LogCas(Logger());
|
||||
|
||||
auto Params = new Poco::Net::HTTPServerParams;
|
||||
Params->setMaxThreads(16);
|
||||
Params->setMaxQueued(100);
|
||||
|
||||
if (FullName_.empty()) {
|
||||
std::string TmpName =
|
||||
MicroService::instance().ConfigGetString("openwifi.fileuploader.uri", "");
|
||||
if (TmpName.empty()) {
|
||||
FullName_ =
|
||||
"https://" + Svr.Name() + ":" + std::to_string(Svr.Port()) + URI_BASE;
|
||||
} else {
|
||||
FullName_ = TmpName + URI_BASE;
|
||||
}
|
||||
Logger().information(fmt::format("Uploader URI base is '{}'", FullName_));
|
||||
}
|
||||
|
||||
auto NewServer = std::make_unique<Poco::Net::HTTPServer>(
|
||||
new FileUpLoaderRequestHandlerFactory(Logger()), Sock, Params);
|
||||
NewServer->start();
|
||||
Servers_.push_back(std::move(NewServer));
|
||||
}
|
||||
}
|
||||
|
||||
MaxSize_ = 1000 * MicroService::instance().ConfigGetInt("openwifi.fileuploader.maxsize", 10000);
|
||||
@@ -79,7 +107,7 @@ namespace OpenWifi {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FileUploader::reinitialize(Poco::Util::Application &self) {
|
||||
void FileUploader::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
||||
MicroService::instance().LoadConfigurationFile();
|
||||
Logger().information("Reinitializing.");
|
||||
Stop();
|
||||
@@ -94,18 +122,18 @@ namespace OpenWifi {
|
||||
bool FileUploader::AddUUID( const std::string & UUID) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
uint64_t Now = time(nullptr) ;
|
||||
uint64_t now = OpenWifi::Now();
|
||||
|
||||
// remove old stuff...
|
||||
for(auto i=OutStandingUploads_.cbegin();i!=OutStandingUploads_.end();) {
|
||||
if ((Now-i->second) > (60 * 30))
|
||||
OutStandingUploads_.erase(i++);
|
||||
for(auto i=OutStandingUploads_.begin();i!=OutStandingUploads_.end();) {
|
||||
if ((now-i->second) > (60 * 30))
|
||||
i = OutStandingUploads_.erase(i);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
|
||||
if(!UUID.empty())
|
||||
OutStandingUploads_[UUID] = Now;
|
||||
OutStandingUploads_[UUID] = now;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -121,64 +149,39 @@ namespace OpenWifi {
|
||||
OutStandingUploads_.erase(UUID);
|
||||
}
|
||||
|
||||
class FileUploaderPartHandler: public Poco::Net::PartHandler
|
||||
{
|
||||
public:
|
||||
FileUploaderPartHandler(std::string UUID, Poco::Logger & Logger):
|
||||
UUID_(std::move(UUID)),
|
||||
Logger_(Logger)
|
||||
{
|
||||
}
|
||||
|
||||
void handlePart(const Poco::Net::MessageHeader& Header, std::istream& Stream) override
|
||||
{
|
||||
try {
|
||||
Name_ = "(unnamed)";
|
||||
if (Header.has("Content-Disposition")) {
|
||||
std::string Disposition;
|
||||
Poco::Net::NameValueCollection Parameters;
|
||||
Poco::Net::MessageHeader::splitParameters(Header["Content-Disposition"],
|
||||
Disposition, Parameters);
|
||||
Name_ = Parameters.get("filename", "(unnamed)");
|
||||
}
|
||||
|
||||
std::string FinalFileName = FileUploader()->Path() + "/" + UUID_;
|
||||
|
||||
Logger().information(Poco::format("FILE-UPLOADER: uploading trace for %s", FinalFileName));
|
||||
Poco::CountingInputStream InputStream(Stream);
|
||||
std::ofstream OutputStream(FinalFileName, std::ofstream::out);
|
||||
Poco::StreamCopier::copyStream(InputStream, OutputStream);
|
||||
|
||||
Poco::File TmpFile(FinalFileName);
|
||||
Length_ = TmpFile.getSize();
|
||||
if (Length_ < FileUploader()->MaxSize()) {
|
||||
Good_=true;
|
||||
} else {
|
||||
TmpFile.remove();
|
||||
Error_ = "File is too large.";
|
||||
}
|
||||
return;
|
||||
} catch (const Poco::Exception &E ) {
|
||||
Logger().log(E);
|
||||
Error_ = std::string("Upload caused an internal error: ") + E.what() ;
|
||||
}
|
||||
class FileUploaderPartHandler2 : public Poco::Net::PartHandler {
|
||||
public:
|
||||
FileUploaderPartHandler2(std::string Id, Poco::Logger &Logger, std::stringstream & ofs) :
|
||||
Id_(std::move(Id)),
|
||||
Logger_(Logger),
|
||||
OutputStream_(ofs){
|
||||
}
|
||||
void handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream) {
|
||||
FileType_ = Header.get(RESTAPI::Protocol::CONTENTTYPE, RESTAPI::Protocol::UNSPECIFIED);
|
||||
if (Header.has(RESTAPI::Protocol::CONTENTDISPOSITION)) {
|
||||
std::string Disposition;
|
||||
Poco::Net::NameValueCollection Parameters;
|
||||
Poco::Net::MessageHeader::splitParameters(Header[RESTAPI::Protocol::CONTENTDISPOSITION], Disposition, Parameters);
|
||||
Name_ = Parameters.get(RESTAPI::Protocol::NAME, RESTAPI::Protocol::UNNAMED);
|
||||
}
|
||||
Poco::CountingInputStream InputStream(Stream);
|
||||
Poco::StreamCopier::copyStream(InputStream, OutputStream_);
|
||||
Length_ = OutputStream_.str().size();
|
||||
}
|
||||
[[nodiscard]] uint64_t Length() const { return Length_; }
|
||||
[[nodiscard]] std::string &Name() { return Name_; }
|
||||
[[nodiscard]] std::string &ContentType() { return FileType_; }
|
||||
|
||||
[[nodiscard]] uint64_t Length() const { return Length_; }
|
||||
[[nodiscard]] const std::string& Name() const { return Name_; }
|
||||
[[nodiscard]] bool Good() const { return Good_; }
|
||||
std::string & Error() { return Error_; }
|
||||
inline Poco::Logger & Logger() { return Logger_; }
|
||||
|
||||
private:
|
||||
uint64_t Length_=0;
|
||||
bool Good_=false;
|
||||
std::string Name_;
|
||||
std::string UUID_;
|
||||
std::string Error_;
|
||||
Poco::Logger & Logger_;
|
||||
};
|
||||
private:
|
||||
uint64_t Length_ = 0;
|
||||
std::string FileType_;
|
||||
std::string Name_;
|
||||
std::string Id_;
|
||||
Poco::Logger &Logger_;
|
||||
std::stringstream &OutputStream_;
|
||||
|
||||
inline Poco::Logger & Logger() { return Logger_; };
|
||||
};
|
||||
|
||||
class FormRequestHandler: public Poco::Net::HTTPRequestHandler
|
||||
{
|
||||
@@ -189,40 +192,71 @@ namespace OpenWifi {
|
||||
{
|
||||
}
|
||||
|
||||
void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override
|
||||
{
|
||||
try {
|
||||
FileUploaderPartHandler partHandler(UUID_,Logger());
|
||||
void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) final {
|
||||
|
||||
Poco::Net::HTMLForm form(Request, Request.stream(), partHandler);
|
||||
Utils::SetThreadName("FileUploader");
|
||||
const auto ContentType = Request.getContentType();
|
||||
const auto Tokens = Poco::StringTokenizer(ContentType,";",Poco::StringTokenizer::TOK_TRIM);
|
||||
|
||||
Response.setChunkedTransferEncoding(true);
|
||||
Response.setContentType("application/json");
|
||||
Logger().debug(fmt::format("{}: Preparing to upload trace file.",UUID_));
|
||||
Poco::JSON::Object Answer;
|
||||
|
||||
Poco::JSON::Object Answer;
|
||||
if (partHandler.Good()) {
|
||||
Answer.set("filename", UUID_);
|
||||
Answer.set("error", 0);
|
||||
StorageService()->AttachFileToCommand(UUID_);
|
||||
} else {
|
||||
Answer.set("filename", UUID_);
|
||||
Answer.set("error", 13);
|
||||
Answer.set("errorText", partHandler.Error() );
|
||||
StorageService()->CancelWaitFile(UUID_, partHandler.Error() );
|
||||
try {
|
||||
if (Poco::icompare(Tokens[0], "multipart/form-data") == 0 ||
|
||||
Poco::icompare(Tokens[0], "multipart/mixed") == 0) {
|
||||
|
||||
const auto &BoundaryTokens =
|
||||
Poco::StringTokenizer(Tokens[1], "=", Poco::StringTokenizer::TOK_TRIM);
|
||||
|
||||
if (BoundaryTokens[0] == "boundary") {
|
||||
const std::string &Boundary = BoundaryTokens[1];
|
||||
Poco::Net::MultipartReader Reader(Request.stream(), Boundary);
|
||||
bool Done = false;
|
||||
|
||||
while (!Done) {
|
||||
Poco::Net::MessageHeader Hdr;
|
||||
Reader.nextPart(Hdr);
|
||||
|
||||
const auto PartContentType = Hdr.get("Content-Type", "");
|
||||
if (PartContentType == "application/octet-stream") {
|
||||
std::stringstream FileContent;
|
||||
Poco::StreamCopier::copyStream(Reader.stream(), FileContent);
|
||||
Answer.set("filename", UUID_);
|
||||
Answer.set("error", 0);
|
||||
Logger().debug(fmt::format("{}: Trace file uploaded.", UUID_));
|
||||
StorageService()->AttachFileDataToCommand(UUID_, FileContent);
|
||||
std::ostream &ResponseStream = Response.send();
|
||||
Poco::JSON::Stringifier::stringify(Answer, ResponseStream);
|
||||
return;
|
||||
} else {
|
||||
std::stringstream OO;
|
||||
Poco::StreamCopier::copyStream(Reader.stream(), OO);
|
||||
}
|
||||
|
||||
if (!Reader.hasNextPart())
|
||||
Done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::ostream &ResponseStream = Response.send();
|
||||
Poco::JSON::Stringifier::stringify(Answer, ResponseStream);
|
||||
return;
|
||||
}
|
||||
catch( const Poco::Exception & E )
|
||||
{
|
||||
Logger().warning(Poco::format("Error occurred while performing upload. Error='%s'",E.displayText()));
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
}
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
} catch (...) {
|
||||
Logger().debug("Exception while receiving trace file.");
|
||||
}
|
||||
|
||||
Logger().debug(fmt::format("{}: Failed to upload trace file.",UUID_));
|
||||
std::string Error{"Trace file rejected"};
|
||||
StorageService()->CancelWaitFile(UUID_, Error);
|
||||
Answer.set("filename", UUID_);
|
||||
Answer.set("error", 13);
|
||||
Answer.set("errorText", "Attached file is too large");
|
||||
StorageService()->CancelWaitFile(UUID_, Error);
|
||||
std::ostream &ResponseStream = Response.send();
|
||||
Poco::JSON::Stringifier::stringify(Answer, ResponseStream);
|
||||
}
|
||||
|
||||
inline Poco::Logger & Logger() { return Logger_; }
|
||||
|
||||
private:
|
||||
std::string UUID_;
|
||||
Poco::Logger & Logger_;
|
||||
@@ -230,7 +264,7 @@ namespace OpenWifi {
|
||||
|
||||
Poco::Net::HTTPRequestHandler *FileUpLoaderRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest & Request) {
|
||||
|
||||
Logger().debug(Poco::format("REQUEST(%s): %s %s", Utils::FormatIPv6(Request.clientAddress().toString()), Request.getMethod(), Request.getURI()));
|
||||
Logger().debug(fmt::format("REQUEST({}): {} {}", Utils::FormatIPv6(Request.clientAddress().toString()), Request.getMethod(), Request.getURI()));
|
||||
|
||||
// The UUID should be after the /v1/upload/ part...
|
||||
auto UUIDLocation = Request.getURI().find_first_of(URI_BASE);
|
||||
@@ -246,7 +280,7 @@ namespace OpenWifi {
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger().warning(Poco::format("Unknown UUID=%s",UUID));
|
||||
Logger().warning(fmt::format("Unknown UUID={}",UUID));
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
|
||||
@@ -37,15 +37,13 @@ namespace OpenWifi {
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> Servers_;
|
||||
Poco::ThreadPool Pool_;
|
||||
std::string FullName_;
|
||||
std::map<std::string,uint64_t> OutStandingUploads_;
|
||||
std::string Path_;
|
||||
uint64_t MaxSize_=10000000;
|
||||
|
||||
explicit FileUploader() noexcept:
|
||||
SubSystemServer("FileUploader", "FILE-UPLOAD", "openwifi.fileuploader"),
|
||||
Pool_("FileUpLoaderPool")
|
||||
SubSystemServer("FileUploader", "FILE-UPLOAD", "openwifi.fileuploader")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
67
src/GwWebSocketClient.cpp
Normal file
67
src/GwWebSocketClient.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
//
|
||||
// Created by stephane bourque on 2022-04-28.
|
||||
//
|
||||
|
||||
#include "GwWebSocketClient.h"
|
||||
#include "SerialNumberCache.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
GwWebSocketClient::GwWebSocketClient(Poco::Logger &Logger):
|
||||
Logger_(Logger){
|
||||
WebSocketClientServer()->SetProcessor(this);
|
||||
}
|
||||
|
||||
GwWebSocketClient::~GwWebSocketClient() {
|
||||
WebSocketClientServer()->SetProcessor(nullptr);
|
||||
}
|
||||
|
||||
void GwWebSocketClient::Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done ) {
|
||||
try {
|
||||
if (O->has("command")) {
|
||||
auto Command = O->get("command").toString();
|
||||
if (Command == "serial_number_search" && O->has("serial_prefix")) {
|
||||
ws_command_serial_number_search(O,Done,Answer);
|
||||
} else if (Command=="exit") {
|
||||
ws_command_exit(O,Done,Answer);
|
||||
} else {
|
||||
ws_command_invalid(O, Done, Answer);
|
||||
}
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
|
||||
void GwWebSocketClient::ws_command_serial_number_search(const Poco::JSON::Object::Ptr &O,
|
||||
bool &Done, std::string &Answer) {
|
||||
Done = false;
|
||||
auto Prefix = O->get("serial_prefix").toString();
|
||||
Logger().information(Poco::format("serial_number_search: %s", Prefix));
|
||||
if (!Prefix.empty() && Prefix.length() < 13) {
|
||||
std::vector<uint64_t> Numbers;
|
||||
SerialNumberCache()->FindNumbers(Prefix, 50, Numbers);
|
||||
Poco::JSON::Array Arr;
|
||||
for (const auto &i : Numbers)
|
||||
Arr.add(Utils::int_to_hex(i));
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set("serialNumbers", Arr);
|
||||
std::ostringstream SS;
|
||||
Poco::JSON::Stringifier::stringify(RetObj, SS);
|
||||
Answer = SS.str();
|
||||
}
|
||||
}
|
||||
|
||||
void GwWebSocketClient::ws_command_exit([[maybe_unused]] const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) {
|
||||
Done = true;
|
||||
Answer = R"lit({ "closing" : "Goodbye! Aurevoir! Hasta la vista!" })lit";
|
||||
}
|
||||
|
||||
void GwWebSocketClient::ws_command_invalid([[maybe_unused]] const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) {
|
||||
Done = false;
|
||||
Answer = std::string{R"lit({ "error" : "invalid command" })lit"};
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
23
src/GwWebSocketClient.h
Normal file
23
src/GwWebSocketClient.h
Normal file
@@ -0,0 +1,23 @@
|
||||
//
|
||||
// Created by stephane bourque on 2022-04-28.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class GwWebSocketClient : public WebSocketClientProcessor {
|
||||
public:
|
||||
explicit GwWebSocketClient(Poco::Logger &Logger);
|
||||
virtual ~GwWebSocketClient();
|
||||
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done );
|
||||
void ws_command_serial_number_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
void ws_command_exit( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
void ws_command_invalid( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
|
||||
private:
|
||||
Poco::Logger & Logger_;
|
||||
inline Poco::Logger & Logger() { return Logger_; }
|
||||
};
|
||||
}
|
||||
@@ -21,6 +21,9 @@ namespace OpenWifi {
|
||||
|
||||
int OUIServer::Start() {
|
||||
Running_ = true;
|
||||
LatestOUIFileName_ = MicroService::instance().DataDir() + "/newOUIFile.txt";
|
||||
CurrentOUIFileName_ = MicroService::instance().DataDir() + "/current_oui.txt";
|
||||
|
||||
UpdaterCallBack_ = std::make_unique<Poco::TimerCallback<OUIServer>>(*this, &OUIServer::onTimer);
|
||||
Timer_.setStartInterval(30 * 1000); // first run in 5 minutes
|
||||
Timer_.setPeriodicInterval(7 * 24 * 60 * 60 * 1000);
|
||||
@@ -33,7 +36,7 @@ namespace OpenWifi {
|
||||
Timer_.stop();
|
||||
}
|
||||
|
||||
void OUIServer::reinitialize(Poco::Util::Application &self) {
|
||||
void OUIServer::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
||||
MicroService::instance().LoadConfigurationFile();
|
||||
Logger().information("Reinitializing.");
|
||||
Stop();
|
||||
@@ -42,17 +45,15 @@ namespace OpenWifi {
|
||||
|
||||
bool OUIServer::GetFile(const std::string &FileName) {
|
||||
try {
|
||||
Logger().information(Poco::format("Start: Retrieving OUI file: %s",MicroService::instance().ConfigGetString("oui.download.uri")));
|
||||
LastUpdate_ = OpenWifi::Now();
|
||||
Logger().information(fmt::format("Start: Retrieving OUI file: {}",MicroService::instance().ConfigGetString("oui.download.uri")));
|
||||
std::unique_ptr<std::istream> pStr(
|
||||
Poco::URIStreamOpener::defaultOpener().open(MicroService::instance().ConfigGetString("oui.download.uri")));
|
||||
std::ofstream OS;
|
||||
Poco::File F(FileName);
|
||||
if(F.exists())
|
||||
F.remove();
|
||||
OS.open(FileName);
|
||||
Poco::StreamCopier::copyStream(*pStr, OS);
|
||||
OS.close();
|
||||
Logger().information(Poco::format("Done: Retrieving OUI file: %s",MicroService::instance().ConfigGetString("oui.download.uri")));
|
||||
Logger().information(fmt::format("Done: Retrieving OUI file: {}",MicroService::instance().ConfigGetString("oui.download.uri")));
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
@@ -80,7 +81,7 @@ namespace OpenWifi {
|
||||
auto MAC = Utils::SerialNumberToOUI(Tokens[0]);
|
||||
if (MAC > 0) {
|
||||
std::string Manufacturer;
|
||||
for (auto i = 2; i < Tokens.count(); i++)
|
||||
for (size_t i = 2; i < Tokens.count(); i++)
|
||||
Manufacturer += Tokens[i] + " ";
|
||||
auto M = Poco::trim(Manufacturer);
|
||||
if (!M.empty())
|
||||
@@ -96,33 +97,49 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
void OUIServer::onTimer(Poco::Timer & timer) {
|
||||
void OUIServer::onTimer([[maybe_unused]] Poco::Timer & timer) {
|
||||
Utils::SetThreadName("ouisvr-timer");
|
||||
if(Updating_)
|
||||
return;
|
||||
Updating_ = true;
|
||||
|
||||
// fetch data from server, if not available, just use the file we already have.
|
||||
std::string LatestOUIFileName{ MicroService::instance().DataDir() + "/newOUIFile.txt"};
|
||||
std::string CurrentOUIFileName{ MicroService::instance().DataDir() + "/current_oui.txt"};
|
||||
Poco::File Current(CurrentOUIFileName_);
|
||||
if(Current.exists()) {
|
||||
if((OpenWifi::Now()-Current.getLastModified().epochTime()) < (7*24*60*60)) {
|
||||
if(!Initialized_) {
|
||||
if(ProcessFile(CurrentOUIFileName_, OUIs_)) {
|
||||
Initialized_ = true;
|
||||
Updating_=false;
|
||||
Logger().information("Using cached file.");
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Updating_=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OUIMap TmpOUIs;
|
||||
if(GetFile(LatestOUIFileName) && ProcessFile(LatestOUIFileName, TmpOUIs)) {
|
||||
if(GetFile(LatestOUIFileName_) && ProcessFile(LatestOUIFileName_, TmpOUIs)) {
|
||||
std::lock_guard G(Mutex_);
|
||||
OUIs_ = std::move(TmpOUIs);
|
||||
LastUpdate_ = std::time(nullptr);
|
||||
Poco::File F1(CurrentOUIFileName);
|
||||
LastUpdate_ = OpenWifi::Now();
|
||||
Poco::File F1(CurrentOUIFileName_);
|
||||
if(F1.exists())
|
||||
F1.remove();
|
||||
Poco::File F2(LatestOUIFileName);
|
||||
F2.renameTo(CurrentOUIFileName);
|
||||
Logger().information(Poco::format("New OUI file %s downloaded.",LatestOUIFileName));
|
||||
Poco::File F2(LatestOUIFileName_);
|
||||
F2.renameTo(CurrentOUIFileName_);
|
||||
Logger().information(fmt::format("New OUI file {} downloaded.",LatestOUIFileName_));
|
||||
} else if(OUIs_.empty()) {
|
||||
if(ProcessFile(CurrentOUIFileName, TmpOUIs)) {
|
||||
LastUpdate_ = std::time(nullptr);
|
||||
if(ProcessFile(CurrentOUIFileName_, TmpOUIs)) {
|
||||
LastUpdate_ = OpenWifi::Now();
|
||||
std::lock_guard G(Mutex_);
|
||||
OUIs_ = std::move(TmpOUIs);
|
||||
}
|
||||
}
|
||||
Initialized_=true;
|
||||
Updating_ = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -31,12 +31,13 @@ namespace OpenWifi {
|
||||
|
||||
private:
|
||||
uint64_t LastUpdate_ = 0 ;
|
||||
bool ValidFile_=false;
|
||||
bool Initialized_ = false;
|
||||
OUIMap OUIs_;
|
||||
std::atomic_bool Updating_=false;
|
||||
std::atomic_bool Running_=false;
|
||||
volatile std::atomic_bool Updating_=false;
|
||||
volatile std::atomic_bool Running_=false;
|
||||
Poco::Timer Timer_;
|
||||
std::unique_ptr<Poco::TimerCallback<OUIServer>> UpdaterCallBack_;
|
||||
std::string LatestOUIFileName_,CurrentOUIFileName_;
|
||||
|
||||
OUIServer() noexcept:
|
||||
SubSystemServer("OUIServer", "OUI-SVR", "ouiserver")
|
||||
|
||||
1829
src/ParseWifiScan.h
Normal file
1829
src/ParseWifiScan.h
Normal file
File diff suppressed because it is too large
Load Diff
211
src/RADIUS_helpers.h
Normal file
211
src/RADIUS_helpers.h
Normal file
@@ -0,0 +1,211 @@
|
||||
//
|
||||
// Created by stephane bourque on 2022-06-20.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace OpenWifi::RADIUS {
|
||||
|
||||
#pragma pack(push,1)
|
||||
struct RadiusAttribute {
|
||||
unsigned char type{0};
|
||||
uint16_t pos{0};
|
||||
unsigned len{0};
|
||||
};
|
||||
struct RawRadiusPacket {
|
||||
unsigned char code{1};
|
||||
unsigned char identifier{0};
|
||||
uint16_t len{0};
|
||||
unsigned char authenticator[16]{0};
|
||||
unsigned char attributes[4096]{0};
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
//
|
||||
// From: https://github.com/Telecominfraproject/wlan-dictionary/blob/main/dictionary.tip
|
||||
//
|
||||
static const uint32_t TIP_vendor_id = 58888;
|
||||
static const unsigned char TIP_serial = 1;
|
||||
static const unsigned char TIP_AAAipaddr = 2;
|
||||
static const unsigned char TIP_AAAipv6addr = 3;
|
||||
|
||||
|
||||
using AttributeList = std::list<RadiusAttribute>;
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, AttributeList const &P) {
|
||||
for(const auto &attr:P) {
|
||||
os << "\tAttr: " << (uint16_t) attr.type << " Size: " << (uint16_t) attr.len << std::endl;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
bool ParseRadius(uint32_t offset, const unsigned char *Buffer, uint16_t Size, AttributeList &Attrs) {
|
||||
Attrs.clear();
|
||||
uint16_t pos=0;
|
||||
auto x=25;
|
||||
while(pos<Size && x) {
|
||||
RadiusAttribute Attr{ .type=Buffer[pos], .pos=(uint16_t )(pos+2+offset), .len=Buffer[pos+1]};
|
||||
// std::cout << "POS: " << pos << " P:" << (uint32_t) Attr.pos << " T:" << (uint32_t) Attr.type << " L:" << (uint32_t) Attr.len << " S:" << (uint32_t) Size << std::endl;
|
||||
if(pos+Attr.len<=Size) {
|
||||
Attrs.emplace_back(Attr);
|
||||
} else {
|
||||
std::cout << "Bad parse1: " << (uint32_t) (pos+Attr.len) << " S:" << Size << std::endl;
|
||||
return false;
|
||||
}
|
||||
if(Buffer[pos+1]==0) {
|
||||
std::cout << "Bad parse2: " << (uint32_t) (pos+Attr.len) << " S:" << Size << std::endl;
|
||||
return false;
|
||||
}
|
||||
pos+=Buffer[pos+1];
|
||||
x--;
|
||||
}
|
||||
// std::cout << "Good parse" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
class RadiusPacket {
|
||||
public:
|
||||
explicit RadiusPacket(const unsigned char *buffer, uint16_t size) {
|
||||
memcpy((void *)&P_,buffer, size);
|
||||
Size_=size;
|
||||
Valid_ = ParseRadius(0,(unsigned char *)&P_.attributes[0],Size_-20,Attrs_);
|
||||
}
|
||||
|
||||
explicit RadiusPacket(const std::string &p) {
|
||||
memcpy((void *)&P_,(const unsigned char*) p.c_str(), p.size());
|
||||
Size_=p.size();
|
||||
Valid_ = ParseRadius(0,(unsigned char *)&P_.attributes[0],Size_-20,Attrs_);
|
||||
}
|
||||
|
||||
RadiusPacket() = default;
|
||||
|
||||
unsigned char * Buffer() { return (unsigned char *)&P_; }
|
||||
[[nodiscard]] uint16_t BufferLen() const { return sizeof(P_);}
|
||||
|
||||
void Evaluate(uint16_t size) {
|
||||
Size_ = size;
|
||||
Valid_ = ParseRadius(0,(unsigned char *)&P_.attributes[0],Size_-20,Attrs_);
|
||||
}
|
||||
|
||||
[[nodiscard]] uint16_t Len() const { return htons(P_.len); }
|
||||
[[nodiscard]] uint16_t Size() const { return Size_; }
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &os, RadiusPacket const &P);
|
||||
|
||||
void Log(std::ostream &os) {
|
||||
uint16_t p = 0;
|
||||
|
||||
while(p<Size_) {
|
||||
os << std::setfill('0') << std::setw(4) << p << ": ";
|
||||
uint16_t v=0;
|
||||
while(v<16 && p+v<Size_) {
|
||||
os << std::setfill('0') << std::setw(2) << std::right << std::hex << (uint16_t )((const unsigned char *)&P_)[p+v] << " ";
|
||||
v++;
|
||||
}
|
||||
os << std::endl;
|
||||
p+=16;
|
||||
}
|
||||
os << std::dec << std::endl;
|
||||
}
|
||||
|
||||
std::string ExtractSerialNumberTIP() {
|
||||
std::string R;
|
||||
|
||||
for(const auto &attribute:Attrs_) {
|
||||
if(attribute.type==26) {
|
||||
AttributeList VendorAttributes;
|
||||
uint32_t VendorId = htonl( *(const uint32_t *)&(P_.attributes[attribute.pos]));
|
||||
// std::cout << VendorId << std::endl;
|
||||
if(VendorId==TIP_vendor_id) {
|
||||
if (ParseRadius(attribute.pos + 4, &P_.attributes[attribute.pos + 4], attribute.len - 4 - 2,
|
||||
VendorAttributes)) {
|
||||
// std::cout << VendorAttributes << std::endl;
|
||||
for (const auto &vendorAttr: VendorAttributes) {
|
||||
if (vendorAttr.type == TIP_serial) {
|
||||
for (uint16_t i = 0; i < vendorAttr.len; i++) {
|
||||
if (P_.attributes[vendorAttr.pos + i] == '-')
|
||||
continue;
|
||||
R += (char) P_.attributes[vendorAttr.pos + i];
|
||||
}
|
||||
return R;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return R;
|
||||
}
|
||||
|
||||
std::string ExtractSerialNumberFromProxyState() {
|
||||
std::string Result;
|
||||
for(const auto &attribute:Attrs_) {
|
||||
if(attribute.type==33) {
|
||||
const char * SN = (const char *)&P_.attributes[attribute.pos];
|
||||
auto i=0;
|
||||
while(*SN!=':' && i<12) {
|
||||
Result+=*SN++;
|
||||
i++;
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::string ExtractProxyStateDestination() {
|
||||
std::string Result;
|
||||
for(const auto &attribute:Attrs_) {
|
||||
if(attribute.type==33 && attribute.len>2) {
|
||||
std::string Attr33;
|
||||
// format is serial:IP:port:interface
|
||||
Attr33.assign((const char *)(const char *)&P_.attributes[attribute.pos],attribute.len-2);
|
||||
auto Parts = Poco::StringTokenizer(Attr33,":");
|
||||
if(Parts.count()==4)
|
||||
return Parts[1]+":"+Parts[2];
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::string ExtractCallingStationID() {
|
||||
std::string Result;
|
||||
for(const auto &attribute:Attrs_) {
|
||||
if(attribute.type==31 && attribute.len>2) {
|
||||
Result.assign((const char *)(const char *)&P_.attributes[attribute.pos],attribute.len-2);
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
std::string ExtractCalledStationID() {
|
||||
std::string Result;
|
||||
for(const auto &attribute:Attrs_) {
|
||||
if(attribute.type==30 && attribute.len>2) {
|
||||
Result.assign((const char *)(const char *)&P_.attributes[attribute.pos],attribute.len-2);
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
private:
|
||||
RawRadiusPacket P_;
|
||||
uint16_t Size_{0};
|
||||
AttributeList Attrs_;
|
||||
bool Valid_=false;
|
||||
};
|
||||
|
||||
std::ostream &operator<<(std::ostream &os, RadiusPacket const &P) {
|
||||
os << P.Attrs_ ;
|
||||
return os;
|
||||
}
|
||||
}
|
||||
489
src/RADIUS_proxy_server.cpp
Normal file
489
src/RADIUS_proxy_server.cpp
Normal file
@@ -0,0 +1,489 @@
|
||||
//
|
||||
// Created by stephane bourque on 2022-05-18.
|
||||
//
|
||||
|
||||
#include "RADIUS_proxy_server.h"
|
||||
#include "DeviceRegistry.h"
|
||||
#include "RADIUS_helpers.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
const int SMALLEST_RADIUS_PACKET = 20+19+4;
|
||||
const int DEFAULT_RADIUS_AUTHENTICATION_PORT = 1812;
|
||||
const int DEFAULT_RADIUS_ACCOUNTING_PORT = 1813;
|
||||
const int DEFAULT_RADIUS_CoA_PORT = 3799;
|
||||
|
||||
int RADIUS_proxy_server::Start() {
|
||||
|
||||
enabled_ = MicroService::instance().ConfigGetBool("radius.proxy.enable",false);
|
||||
if(!enabled_)
|
||||
return 0;
|
||||
|
||||
ConfigFilename_ = MicroService::instance().DataDir()+"/radius_pool_config.json";
|
||||
|
||||
|
||||
|
||||
Poco::Net::SocketAddress AuthSockAddrV4(Poco::Net::AddressFamily::IPv4,
|
||||
MicroService::instance().ConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
|
||||
AuthenticationSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV4,true);
|
||||
Poco::Net::SocketAddress AuthSockAddrV6(Poco::Net::AddressFamily::IPv6,
|
||||
MicroService::instance().ConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
|
||||
AuthenticationSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV6,true);
|
||||
|
||||
Poco::Net::SocketAddress AcctSockAddrV4(Poco::Net::AddressFamily::IPv4,
|
||||
MicroService::instance().ConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
|
||||
AccountingSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV4,true);
|
||||
Poco::Net::SocketAddress AcctSockAddrV6(Poco::Net::AddressFamily::IPv6,
|
||||
MicroService::instance().ConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
|
||||
AccountingSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV6,true);
|
||||
|
||||
Poco::Net::SocketAddress CoASockAddrV4(Poco::Net::AddressFamily::IPv4,
|
||||
MicroService::instance().ConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
|
||||
CoASocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV4,true);
|
||||
Poco::Net::SocketAddress CoASockAddrV6(Poco::Net::AddressFamily::IPv6,
|
||||
MicroService::instance().ConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
|
||||
CoASocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV6,true);
|
||||
|
||||
AuthenticationReactor_.addEventHandler(*AuthenticationSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
AuthenticationReactor_.addEventHandler(*AuthenticationSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
|
||||
AccountingReactor_.addEventHandler(*AccountingSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
AccountingReactor_.addEventHandler(*AccountingSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
|
||||
|
||||
CoAReactor_.addEventHandler(*CoASocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnCoASocketReadable));
|
||||
CoAReactor_.addEventHandler(*CoASocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnCoASocketReadable));
|
||||
|
||||
ParseConfig();
|
||||
|
||||
AuthenticationReactorThread_.start(AuthenticationReactor_);
|
||||
AccountingReactorThread_.start(AccountingReactor_);
|
||||
CoAReactorThread_.start(CoAReactor_);
|
||||
|
||||
Utils::SetThreadName(AuthenticationReactorThread_,"radproxy-auth");
|
||||
Utils::SetThreadName(AccountingReactorThread_,"radproxy-acct");
|
||||
Utils::SetThreadName(CoAReactorThread_,"radproxy-coa");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::Stop() {
|
||||
if(enabled_) {
|
||||
AuthenticationReactor_.removeEventHandler(
|
||||
*AuthenticationSocketV4_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
AuthenticationReactor_.removeEventHandler(
|
||||
*AuthenticationSocketV6_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
|
||||
AccountingReactor_.removeEventHandler(
|
||||
*AccountingSocketV4_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
AccountingReactor_.removeEventHandler(
|
||||
*AccountingSocketV6_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
|
||||
CoAReactor_.removeEventHandler(
|
||||
*CoASocketV4_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
CoAReactor_.removeEventHandler(
|
||||
*CoASocketV6_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
|
||||
AuthenticationReactor_.stop();
|
||||
AuthenticationReactorThread_.join();
|
||||
|
||||
AccountingReactor_.stop();
|
||||
AccountingReactorThread_.join();
|
||||
|
||||
CoAReactor_.stop();
|
||||
CoAReactorThread_.join();
|
||||
enabled_=false;
|
||||
}
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::OnAccountingSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
Poco::Net::SocketAddress Sender;
|
||||
RADIUS::RadiusPacket P;
|
||||
|
||||
auto ReceiveSize = pNf->socket().impl()->receiveBytes(P.Buffer(),P.BufferLen());
|
||||
if(ReceiveSize<SMALLEST_RADIUS_PACKET) {
|
||||
Logger().warning("Accounting: bad packet received.");
|
||||
return;
|
||||
}
|
||||
P.Evaluate(ReceiveSize);
|
||||
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
||||
if(SerialNumber.empty()) {
|
||||
Logger().warning("Accounting: missing serial number.");
|
||||
return;
|
||||
}
|
||||
auto CallingStationID = P.ExtractCallingStationID();
|
||||
auto CalledStationID = P.ExtractCalledStationID();
|
||||
|
||||
Logger().information(fmt::format("Accounting Packet received for {}, CalledStationID: {}, CallingStationID:{}",SerialNumber, CalledStationID, CallingStationID));
|
||||
DeviceRegistry()->SendRadiusAccountingData(SerialNumber,P.Buffer(),P.Size());
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::OnAuthenticationSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
Poco::Net::SocketAddress Sender;
|
||||
RADIUS::RadiusPacket P;
|
||||
|
||||
auto ReceiveSize = pNf->socket().impl()->receiveBytes(P.Buffer(),P.BufferLen());
|
||||
if(ReceiveSize<SMALLEST_RADIUS_PACKET) {
|
||||
Logger().warning("Authentication: bad packet received.");
|
||||
return;
|
||||
}
|
||||
P.Evaluate(ReceiveSize);
|
||||
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
||||
if(SerialNumber.empty()) {
|
||||
Logger().warning("Authentication: missing serial number.");
|
||||
return;
|
||||
}
|
||||
auto CallingStationID = P.ExtractCallingStationID();
|
||||
auto CalledStationID = P.ExtractCalledStationID();
|
||||
|
||||
Logger().information(fmt::format("Authentication Packet received for {}, CalledStationID: {}, CallingStationID:{}",SerialNumber, CalledStationID, CallingStationID));
|
||||
DeviceRegistry()->SendRadiusAuthenticationData(SerialNumber,P.Buffer(),P.Size());
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::OnCoASocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
Poco::Net::SocketAddress Sender;
|
||||
RADIUS::RadiusPacket P;
|
||||
|
||||
auto ReceiveSize = pNf.get()->socket().impl()->receiveBytes(P.Buffer(),P.BufferLen());
|
||||
if(ReceiveSize<SMALLEST_RADIUS_PACKET) {
|
||||
Logger().warning("CoA/DM: bad packet received.");
|
||||
return;
|
||||
}
|
||||
P.Evaluate(ReceiveSize);
|
||||
auto SerialNumber = P.ExtractSerialNumberTIP();
|
||||
if(SerialNumber.empty()) {
|
||||
Logger().warning("CoA/DM: missing serial number.");
|
||||
return;
|
||||
}
|
||||
auto CallingStationID = P.ExtractCallingStationID();
|
||||
auto CalledStationID = P.ExtractCalledStationID();
|
||||
|
||||
Logger().information(fmt::format("CoA Packet received for {}, CalledStationID: {}, CallingStationID:{}",SerialNumber, CalledStationID, CallingStationID));
|
||||
DeviceRegistry()->SendRadiusCoAData(SerialNumber,P.Buffer(),P.Size());
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::SendAccountingData(const std::string &serialNumber, const char *buffer, std::size_t size) {
|
||||
RADIUS::RadiusPacket P((unsigned char *)buffer,size);
|
||||
auto Destination = P.ExtractProxyStateDestination();
|
||||
auto CallingStationID = P.ExtractCallingStationID();
|
||||
auto CalledStationID = P.ExtractCalledStationID();
|
||||
Poco::Net::SocketAddress Dst(Destination);
|
||||
|
||||
std::lock_guard G(Mutex_);
|
||||
auto FinalDestination = Route(radius_type::auth, Dst);
|
||||
auto AllSent = SendData(Dst.family()==Poco::Net::SocketAddress::IPv4 ? *AccountingSocketV4_ : *AccountingSocketV6_, (const unsigned char *)buffer, size, FinalDestination);
|
||||
if(!AllSent)
|
||||
Logger().error(fmt::format("{}: Could not send Accounting packet packet to {}.", serialNumber, Destination));
|
||||
else
|
||||
Logger().information(fmt::format("{}: Sending Accounting Packet to {}, CalledStationID: {}, CallingStationID:{}", serialNumber, FinalDestination.toString(), CalledStationID, CallingStationID));
|
||||
}
|
||||
|
||||
bool RADIUS_proxy_server::SendData( Poco::Net::DatagramSocket & Sock, const unsigned char *buf , std::size_t size, const Poco::Net::SocketAddress &S) {
|
||||
return Sock.sendTo(buf, size, S)==(int)size;
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::SendAuthenticationData(const std::string &serialNumber, const char *buffer, std::size_t size) {
|
||||
RADIUS::RadiusPacket P((unsigned char *)buffer,size);
|
||||
auto Destination = P.ExtractProxyStateDestination();
|
||||
auto CallingStationID = P.ExtractCallingStationID();
|
||||
auto CalledStationID = P.ExtractCalledStationID();
|
||||
Poco::Net::SocketAddress Dst(Destination);
|
||||
|
||||
std::lock_guard G(Mutex_);
|
||||
auto FinalDestination = Route(radius_type::auth, Dst);
|
||||
auto AllSent = SendData(Dst.family()==Poco::Net::SocketAddress::IPv4 ? *AuthenticationSocketV4_ : *AuthenticationSocketV6_, (const unsigned char *)buffer, size, FinalDestination);
|
||||
if(!AllSent)
|
||||
Logger().error(fmt::format("{}: Could not send Authentication packet packet to {}.", serialNumber, Destination));
|
||||
else
|
||||
Logger().information(fmt::format("{}: Sending Authentication Packet to {}, CalledStationID: {}, CallingStationID:{}", serialNumber, FinalDestination.toString(), CalledStationID, CallingStationID));
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::SendCoAData(const std::string &serialNumber, const char *buffer, std::size_t size) {
|
||||
RADIUS::RadiusPacket P((unsigned char *)buffer,size);
|
||||
auto Destination = P.ExtractProxyStateDestination();
|
||||
// auto CallingStationID = P.ExtractCallingStationID();
|
||||
// auto CalledStationID = P.ExtractCalledStationID();
|
||||
|
||||
if(Destination.empty()) {
|
||||
Destination = "0.0.0.0:0";
|
||||
}
|
||||
|
||||
Poco::Net::SocketAddress Dst(Destination);
|
||||
std::lock_guard G(Mutex_);
|
||||
auto FinalDestination = Route(radius_type::auth, Dst);
|
||||
auto AllSent = SendData(Dst.family()==Poco::Net::SocketAddress::IPv4 ? *CoASocketV4_ : *CoASocketV6_, (const unsigned char *)buffer, size, FinalDestination);
|
||||
if(!AllSent)
|
||||
Logger().error(fmt::format("{}: Could not send CoA packet packet to {}.", serialNumber, Destination));
|
||||
else
|
||||
Logger().information(fmt::format("{}: Sending CoA Packet to {}", serialNumber, FinalDestination.toString()));
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::ParseServerList(const GWObjects::RadiusProxyServerConfig & Config, std::vector<Destination> &V4, std::vector<Destination> &V6, bool setAsDefault) {
|
||||
uint64_t TotalV4=0, TotalV6=0;
|
||||
|
||||
for(const auto &server:Config.servers) {
|
||||
Poco::Net::IPAddress a;
|
||||
if(!Poco::Net::IPAddress::tryParse(server.ip,a)) {
|
||||
Logger().error(fmt::format("RADIUS-PARSE Config: server address {} is nto a valid address in v4 or v6. Entry skipped.",server.ip));
|
||||
continue;
|
||||
}
|
||||
auto S = Poco::Net::SocketAddress(fmt::format("{}:{}",server.ip,server.port));
|
||||
Destination D{
|
||||
.Addr = S,
|
||||
.state = 0,
|
||||
.step = 0,
|
||||
.weight = server.weight,
|
||||
.available = true,
|
||||
.strategy = Config.strategy,
|
||||
.monitor = Config. monitor,
|
||||
.monitorMethod = Config.monitorMethod,
|
||||
.methodParameters = Config.methodParameters,
|
||||
.useAsDefault = setAsDefault
|
||||
};
|
||||
|
||||
if(S.family()==Poco::Net::IPAddress::IPv4) {
|
||||
TotalV4 += server.weight;
|
||||
V4.push_back(D);
|
||||
} else {
|
||||
TotalV6 += server.weight;
|
||||
V6.push_back(D);
|
||||
}
|
||||
}
|
||||
|
||||
for(auto &i:V4) {
|
||||
if(TotalV4==0) {
|
||||
i.step = 1000;
|
||||
} else {
|
||||
i.step = 1000 - ((1000 * i.weight) / TotalV4);
|
||||
}
|
||||
}
|
||||
|
||||
for(auto &i:V6) {
|
||||
if(TotalV6==0) {
|
||||
i.step = 1000;
|
||||
} else {
|
||||
i.step = 1000 - ((1000 * i.weight) / TotalV6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::ParseConfig() {
|
||||
|
||||
try {
|
||||
Poco::File F(ConfigFilename_);
|
||||
|
||||
std::lock_guard G(Mutex_);
|
||||
|
||||
if(F.exists()) {
|
||||
std::ifstream ifs(ConfigFilename_,std::ios_base::binary);
|
||||
Poco::JSON::Parser P;
|
||||
auto RawConfig = P.parse(ifs).extract<Poco::JSON::Object::Ptr>();
|
||||
GWObjects::RadiusProxyPoolList RPC;
|
||||
if(RPC.from_json(RawConfig)) {
|
||||
ResetConfig();
|
||||
PoolList_ = RPC;
|
||||
for(const auto &pool:RPC.pools) {
|
||||
RadiusPool NewPool;
|
||||
ParseServerList(pool.authConfig, NewPool.AuthV4, NewPool.AuthV6, pool.useByDefault);
|
||||
ParseServerList(pool.acctConfig, NewPool.AcctV4, NewPool.AcctV6, pool.useByDefault);
|
||||
ParseServerList(pool.coaConfig, NewPool.CoaV4, NewPool.CoaV6, pool.useByDefault);
|
||||
Pools_.push_back(NewPool);
|
||||
}
|
||||
} else {
|
||||
Logger().warning(fmt::format("Configuration file '{}' is bad.",ConfigFilename_));
|
||||
}
|
||||
} else {
|
||||
Logger().warning(fmt::format("No configuration file '{}' exists.",ConfigFilename_));
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
} catch (...) {
|
||||
Logger().error(fmt::format("Error while parsing configuration file '{}'",ConfigFilename_));
|
||||
}
|
||||
}
|
||||
|
||||
Poco::Net::SocketAddress RADIUS_proxy_server::DefaultRoute([[maybe_unused]] radius_type rtype, const Poco::Net::SocketAddress &RequestedAddress) {
|
||||
bool IsV4 = RequestedAddress.family()==Poco::Net::SocketAddress::IPv4;
|
||||
switch(rtype) {
|
||||
case radius_type::coa: {
|
||||
return ChooseAddress(IsV4 ? Pools_[defaultPoolIndex_].CoaV4
|
||||
: Pools_[defaultPoolIndex_].CoaV6,
|
||||
RequestedAddress);
|
||||
}
|
||||
case radius_type::auth: {
|
||||
return ChooseAddress(IsV4 ? Pools_[defaultPoolIndex_].AuthV4
|
||||
: Pools_[defaultPoolIndex_].AuthV6,
|
||||
RequestedAddress);
|
||||
}
|
||||
case radius_type::acct:
|
||||
default: {
|
||||
return ChooseAddress(IsV4 ? Pools_[defaultPoolIndex_].AcctV4
|
||||
: Pools_[defaultPoolIndex_].AcctV6,
|
||||
RequestedAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Poco::Net::SocketAddress RADIUS_proxy_server::Route([[maybe_unused]] radius_type rtype, const Poco::Net::SocketAddress &RequestedAddress) {
|
||||
std::lock_guard G(Mutex_);
|
||||
|
||||
if(Pools_.empty()) {
|
||||
return RequestedAddress;
|
||||
}
|
||||
|
||||
bool IsV4 = RequestedAddress.family()==Poco::Net::SocketAddress::IPv4;
|
||||
bool useDefault = false;
|
||||
useDefault = IsV4 ? RequestedAddress.host() == Poco::Net::IPAddress::wildcard(Poco::Net::IPAddress::IPv4) : RequestedAddress.host() == Poco::Net::IPAddress::wildcard(Poco::Net::IPAddress::IPv6) ;
|
||||
|
||||
if(useDefault) {
|
||||
return DefaultRoute(rtype, RequestedAddress);
|
||||
}
|
||||
|
||||
auto isAddressInPool = [&](const std::vector<Destination> & D) -> bool {
|
||||
for(const auto &entry:D)
|
||||
if(entry.Addr.host()==RequestedAddress.host())
|
||||
return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
for(auto &i:Pools_) {
|
||||
switch(rtype) {
|
||||
case radius_type::coa: {
|
||||
if (isAddressInPool((IsV4 ? i.CoaV4 : i.CoaV6))) {
|
||||
return ChooseAddress(IsV4 ? i.CoaV4 : i.CoaV6, RequestedAddress);
|
||||
}
|
||||
} break;
|
||||
case radius_type::auth: {
|
||||
if (isAddressInPool((IsV4 ? i.AuthV4 : i.AuthV6))) {
|
||||
return ChooseAddress(IsV4 ? i.AuthV4 : i.AuthV6, RequestedAddress);
|
||||
}
|
||||
} break;
|
||||
case radius_type::acct: {
|
||||
if (isAddressInPool((IsV4 ? i.AcctV4 : i.AcctV6))) {
|
||||
return ChooseAddress(IsV4 ? i.AcctV4 : i.AcctV6, RequestedAddress);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
return DefaultRoute(rtype, RequestedAddress);
|
||||
}
|
||||
|
||||
Poco::Net::SocketAddress RADIUS_proxy_server::ChooseAddress(std::vector<Destination> &Pool, const Poco::Net::SocketAddress & OriginalAddress) {
|
||||
|
||||
if(Pool.size()==1) {
|
||||
return Pool[0].Addr;
|
||||
}
|
||||
|
||||
if (Pool[0].strategy == "weighted") {
|
||||
bool found = false;
|
||||
uint64_t cur_state = std::numeric_limits<uint64_t>::max();
|
||||
std::size_t pos = 0, index = 0;
|
||||
for (auto &i : Pool) {
|
||||
if (!i.available) {
|
||||
i.state += i.step;
|
||||
continue;
|
||||
}
|
||||
if (i.state < cur_state) {
|
||||
index = pos;
|
||||
cur_state = i.state;
|
||||
found = true;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
return OriginalAddress;
|
||||
}
|
||||
|
||||
Pool[index].state += Pool[index].step;
|
||||
return Pool[index].Addr;
|
||||
} else if (Pool[0].strategy == "round_robin") {
|
||||
bool found = false;
|
||||
uint64_t cur_state = std::numeric_limits<uint64_t>::max();
|
||||
std::size_t pos = 0, index = 0;
|
||||
for (auto &i : Pool) {
|
||||
if (!i.available) {
|
||||
i.state += 1;
|
||||
continue;
|
||||
}
|
||||
if (i.state < cur_state) {
|
||||
index = pos;
|
||||
cur_state = i.state;
|
||||
found = true;
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
return OriginalAddress;
|
||||
}
|
||||
|
||||
Pool[index].state += 1;
|
||||
return Pool[index].Addr;
|
||||
} else if (Pool[0].strategy == "random") {
|
||||
if (Pool.size() > 1) {
|
||||
return Pool[std::rand() % Pool.size()].Addr;
|
||||
} else {
|
||||
return OriginalAddress;
|
||||
}
|
||||
}
|
||||
return OriginalAddress;
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::SetConfig(const GWObjects::RadiusProxyPoolList &C) {
|
||||
std::lock_guard G(Mutex_);
|
||||
PoolList_ = C;
|
||||
|
||||
Poco::JSON::Object Disk;
|
||||
C.to_json(Disk);
|
||||
|
||||
std::ofstream ofs(ConfigFilename_, std::ios_base::trunc | std::ios_base::binary );
|
||||
Disk.stringify(ofs);
|
||||
ofs.close();
|
||||
|
||||
ParseConfig();
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::ResetConfig() {
|
||||
PoolList_.pools.clear();
|
||||
Pools_.clear();
|
||||
defaultPoolIndex_=0;
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::DeleteConfig() {
|
||||
std::lock_guard G(Mutex_);
|
||||
|
||||
try {
|
||||
Poco::File F(ConfigFilename_);
|
||||
if (F.exists())
|
||||
F.remove();
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
ResetConfig();
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::GetConfig(GWObjects::RadiusProxyPoolList &C) {
|
||||
std::lock_guard G(Mutex_);
|
||||
C = PoolList_;
|
||||
}
|
||||
|
||||
}
|
||||
102
src/RADIUS_proxy_server.h
Normal file
102
src/RADIUS_proxy_server.h
Normal file
@@ -0,0 +1,102 @@
|
||||
//
|
||||
// Created by stephane bourque on 2022-05-18.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "Poco/Net/DatagramSocket.h"
|
||||
#include "Poco/Net/SocketReactor.h"
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
enum class radius_type {
|
||||
auth, acct, coa
|
||||
};
|
||||
|
||||
class RADIUS_proxy_server : public SubSystemServer {
|
||||
public:
|
||||
inline static auto instance() {
|
||||
static auto instance_= new RADIUS_proxy_server;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
int Start() final;
|
||||
void Stop() final;
|
||||
inline bool Enabled() const { return enabled_; }
|
||||
|
||||
void OnAccountingSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
||||
void OnAuthenticationSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
||||
void OnCoASocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
||||
|
||||
void SendAccountingData(const std::string &serialNumber, const char *buffer, std::size_t size);
|
||||
void SendAuthenticationData(const std::string &serialNumber, const char *buffer, std::size_t size);
|
||||
void SendCoAData(const std::string &serialNumber, const char *buffer, std::size_t size);
|
||||
|
||||
void SetConfig(const GWObjects::RadiusProxyPoolList &C);
|
||||
void DeleteConfig();
|
||||
void GetConfig(GWObjects::RadiusProxyPoolList &C);
|
||||
|
||||
struct Destination {
|
||||
Poco::Net::SocketAddress Addr;
|
||||
uint64_t state = 0;
|
||||
uint64_t step = 0;
|
||||
uint64_t weight=0;
|
||||
bool available = true;
|
||||
std::string strategy;
|
||||
bool monitor=false;
|
||||
std::string monitorMethod;
|
||||
std::vector<std::string> methodParameters;
|
||||
bool useAsDefault=false;
|
||||
};
|
||||
|
||||
private:
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV4_;
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV6_;
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> AuthenticationSocketV4_;
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> AuthenticationSocketV6_;
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> CoASocketV4_;
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> CoASocketV6_;
|
||||
Poco::Net::SocketReactor AccountingReactor_;
|
||||
Poco::Net::SocketReactor AuthenticationReactor_;
|
||||
Poco::Net::SocketReactor CoAReactor_;
|
||||
Poco::Thread AuthenticationReactorThread_;
|
||||
Poco::Thread AccountingReactorThread_;
|
||||
Poco::Thread CoAReactorThread_;
|
||||
|
||||
GWObjects::RadiusProxyPoolList PoolList_;
|
||||
std::string ConfigFilename_;
|
||||
|
||||
struct RadiusPool {
|
||||
std::vector<Destination> AuthV4;
|
||||
std::vector<Destination> AuthV6;
|
||||
std::vector<Destination> AcctV4;
|
||||
std::vector<Destination> AcctV6;
|
||||
std::vector<Destination> CoaV4;
|
||||
std::vector<Destination> CoaV6;
|
||||
};
|
||||
|
||||
std::vector<RadiusPool> Pools_;
|
||||
uint defaultPoolIndex_=0;
|
||||
bool enabled_=false;
|
||||
|
||||
RADIUS_proxy_server() noexcept:
|
||||
SubSystemServer("RADIUS-PROXY", "RADIUS-PROXY", "radius.proxy")
|
||||
{
|
||||
}
|
||||
|
||||
static bool SendData( Poco::Net::DatagramSocket & Sock, const unsigned char *buf , std::size_t size, const Poco::Net::SocketAddress &S);
|
||||
|
||||
void ParseConfig();
|
||||
void ResetConfig();
|
||||
Poco::Net::SocketAddress Route(radius_type rtype, const Poco::Net::SocketAddress &A);
|
||||
void ParseServerList(const GWObjects::RadiusProxyServerConfig & Config, std::vector<Destination> &V4, std::vector<Destination> &V6, bool setAsDefault);
|
||||
static Poco::Net::SocketAddress ChooseAddress(std::vector<Destination> &Pool, const Poco::Net::SocketAddress & OriginalAddress);
|
||||
Poco::Net::SocketAddress DefaultRoute([[maybe_unused]] radius_type rtype, const Poco::Net::SocketAddress &RequestedAddress);
|
||||
};
|
||||
|
||||
inline auto RADIUS_proxy_server() { return RADIUS_proxy_server::instance(); }
|
||||
|
||||
}
|
||||
|
||||
@@ -11,20 +11,24 @@
|
||||
#include "DeviceRegistry.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/ow_constants.h"
|
||||
#include "ParseWifiScan.h"
|
||||
|
||||
namespace OpenWifi::RESTAPI_RPC {
|
||||
void SetCommandStatus(GWObjects::CommandDetails &Cmd,
|
||||
Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response,
|
||||
RESTAPIHandler *Handler,
|
||||
OpenWifi::Storage::CommandExecutionType Status,
|
||||
Poco::Logger &Logger) {
|
||||
[[maybe_unused]] Poco::Net::HTTPServerRequest &Request,
|
||||
[[maybe_unused]] Poco::Net::HTTPServerResponse &Response,
|
||||
RESTAPIHandler *Handler,
|
||||
OpenWifi::Storage::CommandExecutionType Status,
|
||||
[[maybe_unused]] Poco::Logger &Logger) {
|
||||
if (StorageService()->AddCommand(Cmd.SerialNumber, Cmd, Status)) {
|
||||
Poco::JSON::Object RetObj;
|
||||
Cmd.to_json(RetObj);
|
||||
return Handler->ReturnObject(RetObj);
|
||||
if(Handler!= nullptr)
|
||||
return Handler->ReturnObject(RetObj);
|
||||
return;
|
||||
}
|
||||
return Handler->ReturnStatus(Poco::Net::HTTPResponse::HTTP_INTERNAL_SERVER_ERROR);
|
||||
if(Handler!= nullptr)
|
||||
return Handler->ReturnStatus(Poco::Net::HTTPResponse::HTTP_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
void WaitForCommand(GWObjects::CommandDetails &Cmd,
|
||||
@@ -36,102 +40,106 @@ namespace OpenWifi::RESTAPI_RPC {
|
||||
RESTAPIHandler * Handler,
|
||||
Poco::Logger &Logger) {
|
||||
|
||||
Logger.information(fmt::format("{}: New {} command. User={} Serial={}. ", Cmd.UUID, Cmd.Command, Cmd.SubmittedBy, Cmd.SerialNumber));
|
||||
|
||||
// if the command should be executed in the future, or if the device is not connected,
|
||||
// then we should just add the command to
|
||||
// the DB and let it figure out when to deliver the command.
|
||||
if (Cmd.RunAt || !DeviceRegistry()->Connected(Cmd.SerialNumber)) {
|
||||
Logger.information(fmt::format("{}: Command will be run in the future or when device is connected again.", Cmd.UUID));
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_PENDING, Logger);
|
||||
return;
|
||||
}
|
||||
|
||||
Cmd.Executed = std::time(nullptr);
|
||||
Cmd.Executed = OpenWifi::Now();
|
||||
|
||||
bool Sent;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> rpc_submitted = std::chrono::high_resolution_clock::now();
|
||||
std::shared_ptr<CommandManager::promise_type_t> rpc_endpoint =
|
||||
CommandManager()->PostCommand(Cmd.SerialNumber, Cmd.Command, Params, Cmd.UUID, Sent);
|
||||
|
||||
if (Sent && rpc_endpoint!= nullptr) {
|
||||
std::future<CommandManager::objtype_t> rpc_future(rpc_endpoint->get_future());
|
||||
auto rpc_result = rpc_future.wait_for(WaitTimeInMs);
|
||||
if (rpc_result == std::future_status::ready && rpc_future.valid()) {
|
||||
std::chrono::duration<double, std::milli> rpc_execution_time = std::chrono::high_resolution_clock::now() - rpc_submitted;
|
||||
auto rpc_answer = rpc_future.get();
|
||||
if (rpc_answer) {
|
||||
if (rpc_answer->has(uCentralProtocol::RESULT) && rpc_answer->isObject(uCentralProtocol::RESULT)) {
|
||||
auto ResultFields =
|
||||
rpc_answer->get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
|
||||
if (ResultFields->has(uCentralProtocol::STATUS) && ResultFields->isObject(uCentralProtocol::STATUS)) {
|
||||
auto StatusInnerObj =
|
||||
ResultFields->get(uCentralProtocol::STATUS).extract<Poco::JSON::Object::Ptr>();
|
||||
if (StatusInnerObj->has(uCentralProtocol::ERROR))
|
||||
Cmd.ErrorCode = StatusInnerObj->get(uCentralProtocol::ERROR);
|
||||
if (StatusInnerObj->has(uCentralProtocol::TEXT))
|
||||
Cmd.ErrorText = StatusInnerObj->get(uCentralProtocol::TEXT).toString();
|
||||
std::stringstream ResultText;
|
||||
Poco::JSON::Stringifier::stringify(rpc_answer->get(uCentralProtocol::RESULT),
|
||||
ResultText);
|
||||
Cmd.Results = ResultText.str();
|
||||
Cmd.Status = "completed";
|
||||
Cmd.Completed = std::time(nullptr);
|
||||
Cmd.executionTime = rpc_execution_time.count();
|
||||
if(!Sent || rpc_endpoint== nullptr) {
|
||||
Logger.information(fmt::format("{}: Pending completion. Device is not connected.", Cmd.UUID));
|
||||
return SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_PENDING, Logger);
|
||||
}
|
||||
|
||||
if (Cmd.ErrorCode && Cmd.Command == uCentralProtocol::TRACE) {
|
||||
Cmd.WaitingForFile = 0;
|
||||
Cmd.AttachDate = Cmd.AttachSize = 0;
|
||||
Cmd.AttachType = "";
|
||||
}
|
||||
Logger.information(fmt::format("{}: Command sent.", Cmd.UUID));
|
||||
|
||||
// Add the completed command to the database...
|
||||
StorageService()->AddCommand(Cmd.SerialNumber, Cmd, Storage::COMMAND_COMPLETED);
|
||||
Poco::JSON::Object L;
|
||||
|
||||
if (ObjectToReturn) {
|
||||
Handler->ReturnObject(*ObjectToReturn);
|
||||
} else {
|
||||
Poco::JSON::Object O;
|
||||
Cmd.to_json(O);
|
||||
Handler->ReturnObject(O);
|
||||
}
|
||||
Logger.information(Poco::format("Command(%s): completed in %8.3fms.", Cmd.UUID, Cmd.executionTime));
|
||||
return;
|
||||
} else {
|
||||
SetCommandStatus(Cmd, Request, Response, Handler,
|
||||
Storage::COMMAND_FAILED, Logger);
|
||||
Logger.information(Poco::format(
|
||||
"Invalid response for command '%s'. Missing status.", Cmd.UUID));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_FAILED,
|
||||
Logger);
|
||||
Logger.information(Poco::format(
|
||||
"Invalid response for command '%s'. Missing status.", Cmd.UUID));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Logger.information(Poco::format(
|
||||
"Timeout1 for command '%s'.", Cmd.UUID));
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_TIMEDOUT,
|
||||
Logger);
|
||||
return;
|
||||
}
|
||||
} else if (rpc_result == std::future_status::timeout) {
|
||||
Logger.information(Poco::format(
|
||||
"Timeout2 for command '%s'.", Cmd.UUID));
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_TIMEDOUT,
|
||||
Logger);
|
||||
return;
|
||||
} else {
|
||||
Logger.information(Poco::format(
|
||||
"Pending completion for command '%s'.", Cmd.UUID));
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_PENDING, Logger);
|
||||
std::future<CommandManager::objtype_t> rpc_future(rpc_endpoint->get_future());
|
||||
auto rpc_result = rpc_future.wait_for(WaitTimeInMs);
|
||||
if (rpc_result == std::future_status::ready) {
|
||||
std::chrono::duration<double, std::milli> rpc_execution_time = std::chrono::high_resolution_clock::now() - rpc_submitted;
|
||||
auto rpc_answer = rpc_future.get();
|
||||
if (!rpc_answer.has(uCentralProtocol::RESULT) || !rpc_answer.isObject(uCentralProtocol::RESULT)) {
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_FAILED, Logger);
|
||||
Logger.information(fmt::format("{}: Invalid response. Missing result.", Cmd.UUID));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Logger.information(Poco::format(
|
||||
"Pending completion for command '%s'.", Cmd.UUID));
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_PENDING, Logger);
|
||||
|
||||
auto ResultFields = rpc_answer.get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
|
||||
if (!ResultFields->has(uCentralProtocol::STATUS) || !ResultFields->isObject(uCentralProtocol::STATUS)) {
|
||||
Cmd.executionTime = rpc_execution_time.count();
|
||||
if(Cmd.Command=="ping") {
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_COMPLETED, Logger);
|
||||
Logger.information(fmt::format("{}: Invalid response from device (ping: fix override). Missing status.", Cmd.UUID));
|
||||
} else {
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_FAILED, Logger);
|
||||
Logger.information(fmt::format("{}: Invalid response from device. Missing status.", Cmd.UUID));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
auto StatusInnerObj = ResultFields->get(uCentralProtocol::STATUS).extract<Poco::JSON::Object::Ptr>();
|
||||
if (StatusInnerObj->has(uCentralProtocol::ERROR))
|
||||
Cmd.ErrorCode = StatusInnerObj->get(uCentralProtocol::ERROR);
|
||||
if (StatusInnerObj->has(uCentralProtocol::TEXT))
|
||||
Cmd.ErrorText = StatusInnerObj->get(uCentralProtocol::TEXT).toString();
|
||||
std::stringstream ResultText;
|
||||
if(rpc_answer.has(uCentralProtocol::RESULT)) {
|
||||
if(Cmd.Command==uCentralProtocol::WIFISCAN) {
|
||||
auto ScanObj = rpc_answer.get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
|
||||
ParseWifiScan(ScanObj, ResultText, Logger);
|
||||
} else {
|
||||
Poco::JSON::Stringifier::stringify(
|
||||
rpc_answer.get(uCentralProtocol::RESULT), ResultText);
|
||||
}
|
||||
} if (rpc_answer.has(uCentralProtocol::RESULT_64)) {
|
||||
uint64_t sz=0;
|
||||
if(rpc_answer.has(uCentralProtocol::RESULT_SZ))
|
||||
sz=rpc_answer.get(uCentralProtocol::RESULT_SZ);
|
||||
std::string UnCompressedData;
|
||||
Utils::ExtractBase64CompressedData(rpc_answer.get(uCentralProtocol::RESULT_64).toString(),
|
||||
UnCompressedData,sz);
|
||||
Poco::JSON::Stringifier::stringify(UnCompressedData, ResultText);
|
||||
}
|
||||
Cmd.Results = ResultText.str();
|
||||
Cmd.Status = "completed";
|
||||
Cmd.Completed = OpenWifi::Now();
|
||||
Cmd.executionTime = rpc_execution_time.count();
|
||||
|
||||
if (Cmd.ErrorCode && Cmd.Command == uCentralProtocol::TRACE) {
|
||||
Cmd.WaitingForFile = 0;
|
||||
Cmd.AttachDate = Cmd.AttachSize = 0;
|
||||
Cmd.AttachType = "";
|
||||
}
|
||||
|
||||
// Add the completed command to the database...
|
||||
StorageService()->AddCommand(Cmd.SerialNumber, Cmd, Storage::COMMAND_COMPLETED);
|
||||
|
||||
if (ObjectToReturn && Handler) {
|
||||
Handler->ReturnObject(*ObjectToReturn);
|
||||
} else {
|
||||
Poco::JSON::Object O;
|
||||
Cmd.to_json(O);
|
||||
if(Handler)
|
||||
Handler->ReturnObject(O);
|
||||
}
|
||||
Logger.information( fmt::format("{}: Completed in {:.3f}ms.", Cmd.UUID, Cmd.executionTime));
|
||||
return;
|
||||
}
|
||||
Logger.information(fmt::format( "{}: Pending completion.", Cmd.UUID));
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_PENDING, Logger);
|
||||
}
|
||||
}
|
||||
@@ -51,8 +51,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void RESTAPI_blacklist::DoPost() {
|
||||
auto Obj = ParseStream();
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
GWObjects::BlackListedDevice D;
|
||||
if(!D.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
@@ -68,7 +67,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
D.author = UserInfo_.userinfo.email;
|
||||
D.created = std::time(nullptr);
|
||||
D.created = OpenWifi::Now();
|
||||
|
||||
if(StorageService()->AddBlackListDevice(D)) {
|
||||
GWObjects::BlackListedDevice CreatedDevice;
|
||||
@@ -88,8 +87,7 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
auto Obj = ParseStream();
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
GWObjects::BlackListedDevice Existing;
|
||||
if(!StorageService()->GetBlackListDevice(SerialNumber, Existing)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace OpenWifi {
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/blacklist/{serialNumber}"};}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/blacklist/{serialNumber}"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final;
|
||||
void DoPost() final;
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace OpenWifi {
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/blacklist"};}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/blacklist"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace OpenWifi {
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/capabilities"};}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/capabilities"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_command::DoGet() {
|
||||
auto CommandUUID = GetBinding(RESTAPI::Protocol::COMMANDUUID, "");
|
||||
if(!Utils::ValidUUID(CommandUUID)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
GWObjects::CommandDetails Command;
|
||||
if (StorageService()->GetCommand(CommandUUID, Command)) {
|
||||
Poco::JSON::Object RetObj;
|
||||
@@ -24,20 +28,23 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void RESTAPI_command::DoDelete() {
|
||||
auto UUID = GetBinding(RESTAPI::Protocol::COMMANDUUID, "");
|
||||
|
||||
if(UUID.empty()) {
|
||||
auto CommandUUID = GetBinding(RESTAPI::Protocol::COMMANDUUID, "");
|
||||
if(CommandUUID.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
|
||||
GWObjects::CommandDetails C;
|
||||
if(!StorageService()->GetCommand(UUID, C)) {
|
||||
if(!Utils::ValidUUID(CommandUUID)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (StorageService()->DeleteCommand(UUID)) {
|
||||
GWObjects::CommandDetails C;
|
||||
if(!StorageService()->GetCommand(CommandUUID, C)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if (StorageService()->DeleteCommand(CommandUUID)) {
|
||||
return OK();
|
||||
}
|
||||
return InternalError();
|
||||
return InternalError(RESTAPI::Errors::NoRecordsDeleted);
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ class RESTAPI_command : public RESTAPIHandler {
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/command/{commandUUID}"};}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/command/{commandUUID}"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final;
|
||||
void DoPost() final {};
|
||||
|
||||
@@ -40,6 +40,6 @@ namespace OpenWifi {
|
||||
if (StorageService()->DeleteCommands(SerialNumber, QB_.StartDate, QB_.EndDate)) {
|
||||
return OK();
|
||||
}
|
||||
InternalError();
|
||||
InternalError(RESTAPI::Errors::NoRecordsDeleted);
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ namespace OpenWifi {
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/commands"};}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/commands"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final;
|
||||
void DoPost() final {};
|
||||
|
||||
@@ -47,17 +47,17 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
if(StorageService()->DefaultConfigurationAlreadyExists(Name)) {
|
||||
return BadRequest("Configuration name already exists.");
|
||||
return BadRequest(RESTAPI::Errors::DefConfigNameExists);
|
||||
}
|
||||
|
||||
auto Obj = ParseStream();
|
||||
const auto &Obj = ParsedBody_;
|
||||
GWObjects::DefaultConfiguration DefConfig;
|
||||
if (!DefConfig.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if(DefConfig.Models.empty()) {
|
||||
return BadRequest("modelIds cannot be empty");
|
||||
return BadRequest(RESTAPI::Errors::ModelIDListCannotBeEmpty);
|
||||
}
|
||||
|
||||
std::string Error;
|
||||
@@ -65,7 +65,7 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||
}
|
||||
|
||||
DefConfig.Created = DefConfig.LastModified = std::time(nullptr);
|
||||
DefConfig.Created = DefConfig.LastModified = OpenWifi::Now();
|
||||
if (StorageService()->CreateDefaultConfiguration(Name, DefConfig)) {
|
||||
return OK();
|
||||
}
|
||||
@@ -76,7 +76,7 @@ namespace OpenWifi {
|
||||
void RESTAPI_default_configuration::DoPut() {
|
||||
std::string Name = GetBinding(RESTAPI::Protocol::NAME, "");
|
||||
|
||||
auto Obj = ParseStream();
|
||||
const auto &Obj = ParsedBody_;
|
||||
GWObjects::DefaultConfiguration NewConfig;
|
||||
if (!NewConfig.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
@@ -95,7 +95,7 @@ namespace OpenWifi {
|
||||
Existing.Configuration = NewConfig.Configuration;
|
||||
}
|
||||
|
||||
Existing.LastModified = std::time(nullptr);
|
||||
Existing.LastModified = OpenWifi::Now();
|
||||
AssignIfPresent(Obj,"description",Existing.Description);
|
||||
if(Obj->has("modelIds"))
|
||||
Existing.Models = NewConfig.Models;
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace OpenWifi {
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/default_configuration/{name}"};}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/default_configuration/{name}"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final;
|
||||
void DoPost() final;
|
||||
|
||||
@@ -20,7 +20,7 @@ class RESTAPI_default_configurations : public RESTAPIHandler {
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){};
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/default_configurations"};}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/default_configurations"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace OpenWifi {
|
||||
std::vector<std::string>{
|
||||
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS}, Server, TransactionId,Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/deviceDashboard"};}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/deviceDashboard"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -45,8 +45,9 @@ namespace OpenWifi {
|
||||
void Rtty();
|
||||
void Telemetry();
|
||||
void Ping();
|
||||
void Script();
|
||||
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/device/{serialNumber}/{command}"}; };
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/device/{serialNumber}/{command}"}; };
|
||||
void DoGet() final;
|
||||
void DoDelete() final;
|
||||
void DoPost() final;
|
||||
|
||||
@@ -90,13 +90,13 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
std::string Arg;
|
||||
if(HasParameter("validateOnly",Arg) && Arg=="true") {
|
||||
auto Body = ParseStream();
|
||||
if(!Body->has("configuration")) {
|
||||
return BadRequest("Must have 'configuration' element.");
|
||||
if(!Obj->has("configuration")) {
|
||||
return BadRequest(RESTAPI::Errors::MustHaveConfigElement);
|
||||
}
|
||||
auto Config=Body->get("configuration").toString();
|
||||
auto Config=Obj->get("configuration").toString();
|
||||
Poco::JSON::Object Answer;
|
||||
std::string Error;
|
||||
auto Res = ValidateUCentralConfiguration(Config, Error);
|
||||
@@ -107,11 +107,10 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
if (!Utils::ValidSerialNumber(SerialNumber)) {
|
||||
Logger_.warning(Poco::format("CREATE-DEVICE(%s): Illegal serial number.", SerialNumber));
|
||||
Logger_.warning(fmt::format("CREATE-DEVICE({}): Illegal serial number.", SerialNumber));
|
||||
return BadRequest( RESTAPI::Errors::InvalidSerialNumber);
|
||||
}
|
||||
|
||||
auto Obj = ParseStream();
|
||||
GWObjects::Device Device;
|
||||
if (!Device.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
@@ -126,11 +125,13 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||
}
|
||||
|
||||
for(auto &i:Device.Notes)
|
||||
for(auto &i:Device.Notes) {
|
||||
i.createdBy = UserInfo_.userinfo.email;
|
||||
i.created = OpenWifi::Now();
|
||||
}
|
||||
|
||||
Config::Config NewConfig(Device.Configuration);
|
||||
Device.UUID = std::time(nullptr);
|
||||
Device.UUID = OpenWifi::Now();
|
||||
NewConfig.SetUUID(Device.UUID);
|
||||
Device.Configuration = NewConfig.get();
|
||||
|
||||
@@ -152,7 +153,7 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
auto Obj = ParseStream();
|
||||
const auto &Obj = ParsedBody_;
|
||||
GWObjects::Device NewDevice;
|
||||
if (!NewDevice.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
@@ -169,7 +170,7 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||
}
|
||||
Config::Config NewConfig(NewDevice.Configuration);
|
||||
uint64_t NewConfigUUID = std::time(nullptr);
|
||||
uint64_t NewConfigUUID = OpenWifi::Now();
|
||||
NewConfig.SetUUID(NewConfigUUID);
|
||||
Existing.Configuration = NewConfig.get();
|
||||
Existing.UUID = NewConfigUUID;
|
||||
@@ -183,10 +184,11 @@ namespace OpenWifi {
|
||||
|
||||
for(auto &i:NewDevice.Notes) {
|
||||
i.createdBy = UserInfo_.userinfo.email;
|
||||
i.created = OpenWifi::Now();
|
||||
Existing.Notes.push_back(i);
|
||||
}
|
||||
|
||||
Existing.LastConfigurationChange = std::time(nullptr);
|
||||
Existing.LastConfigurationChange = OpenWifi::Now();
|
||||
if (StorageService()->UpdateDevice(Existing)) {
|
||||
SetCurrentConfigurationID(SerialNumber, Existing.UUID);
|
||||
Poco::JSON::Object DevObj;
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace OpenWifi {
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/device/{serialNumber}"}; };
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/device/{serialNumber}"}; };
|
||||
void DoGet() final;
|
||||
void DoDelete() final;
|
||||
void DoPost() final;
|
||||
|
||||
@@ -17,8 +17,60 @@
|
||||
#include "Poco/StringTokenizer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
|
||||
bool PrepareOrderBy(const std::string &OrderByList, std::string &OrderByString) {
|
||||
auto items = Poco::StringTokenizer(OrderByList,",");
|
||||
std::string ItemList;
|
||||
|
||||
Types::StringVec Fields;
|
||||
StorageService()->GetDeviceDbFieldList(Fields);
|
||||
|
||||
std::set<std::string> FieldNames;
|
||||
for(const auto &field:Fields)
|
||||
FieldNames.insert(Poco::toLower(field));
|
||||
|
||||
for(const auto &i:items) {
|
||||
auto T = Poco::StringTokenizer(i,":");
|
||||
if(T.count()!=2) {
|
||||
return false;
|
||||
}
|
||||
if(T[1]!="a" && T[1]!="d") {
|
||||
return false;
|
||||
}
|
||||
if(!ItemList.empty())
|
||||
ItemList += " , ";
|
||||
auto hint = FieldNames.find(Poco::toLower(T[0]));
|
||||
if(hint==FieldNames.end()) {
|
||||
return false;
|
||||
}
|
||||
ItemList += T[0] + (T[1]=="a" ? " ASC" : " DESC");
|
||||
}
|
||||
|
||||
if(!ItemList.empty()) {
|
||||
OrderByString = " ORDER BY " + ItemList;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RESTAPI_devices_handler::DoGet() {
|
||||
|
||||
if(GetBoolParameter("orderSpec")) {
|
||||
Types::StringVec Fields;
|
||||
StorageService()->GetDeviceDbFieldList(Fields);
|
||||
std::sort(Fields.begin(),Fields.end());
|
||||
Poco::JSON::Object Answer;
|
||||
RESTAPI_utils::field_to_json(Answer,"list",Fields);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
|
||||
std::string OrderBy{" ORDER BY serialNumber ASC "}, Arg;
|
||||
if(HasParameter("orderBy",Arg)) {
|
||||
if(!PrepareOrderBy(Arg,OrderBy)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidLOrderBy);
|
||||
}
|
||||
}
|
||||
|
||||
auto serialOnly = GetBoolParameter(RESTAPI::Protocol::SERIALONLY, false);
|
||||
auto deviceWithStatus = GetBoolParameter(RESTAPI::Protocol::DEVICEWITHSTATUS, false);
|
||||
auto completeInfo = GetBoolParameter("completeInfo",false);
|
||||
@@ -44,7 +96,7 @@ namespace OpenWifi {
|
||||
}
|
||||
} else {
|
||||
Logger_.error(
|
||||
Poco::format("DEVICE(%s): device in select cannot be found.", i));
|
||||
fmt::format("DEVICE({}): device in select cannot be found.", i));
|
||||
}
|
||||
}
|
||||
if (deviceWithStatus)
|
||||
@@ -59,7 +111,7 @@ namespace OpenWifi {
|
||||
}
|
||||
} else if (serialOnly) {
|
||||
std::vector<std::string> SerialNumbers;
|
||||
StorageService()->GetDeviceSerialNumbers(QB_.Offset, QB_.Limit, SerialNumbers);
|
||||
StorageService()->GetDeviceSerialNumbers(QB_.Offset, QB_.Limit, SerialNumbers, OrderBy);
|
||||
Poco::JSON::Array Objects;
|
||||
for (const auto &i : SerialNumbers) {
|
||||
Objects.add(i);
|
||||
@@ -67,7 +119,7 @@ namespace OpenWifi {
|
||||
RetObj.set(RESTAPI::Protocol::SERIALNUMBERS, Objects);
|
||||
} else {
|
||||
std::vector<GWObjects::Device> Devices;
|
||||
StorageService()->GetDevices(QB_.Offset, QB_.Limit, Devices);
|
||||
StorageService()->GetDevices(QB_.Offset, QB_.Limit, Devices, OrderBy);
|
||||
Poco::JSON::Array Objects;
|
||||
for (const auto &i : Devices) {
|
||||
Poco::JSON::Object Obj;
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenWifi {
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){};
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/devices"}; };
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/devices"}; };
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
|
||||
@@ -20,15 +20,12 @@ namespace OpenWifi {
|
||||
auto UUID = GetBinding(RESTAPI::Protocol::FILEUUID, "");
|
||||
auto SerialNumber = GetParameter(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
// does the file exist
|
||||
Poco::File DownloadFile(FileUploader()->Path() + "/" + UUID);
|
||||
|
||||
std::string FileType;
|
||||
if (!StorageService()->GetAttachedFile(UUID, SerialNumber, DownloadFile.path(), FileType)) {
|
||||
std::string FileContent;
|
||||
if (!StorageService()->GetAttachedFileContent(UUID, SerialNumber, FileContent, FileType)) {
|
||||
return NotFound();
|
||||
}
|
||||
SendFile(DownloadFile, UUID);
|
||||
DownloadFile.remove();
|
||||
SendFileContent(FileContent,"pcap",UUID+".pcap");
|
||||
}
|
||||
|
||||
void RESTAPI_file::DoDelete() {
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace OpenWifi {
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/file/{uuid}"};}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/file/{uuid}"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final;
|
||||
void DoPost() final {};
|
||||
|
||||
@@ -16,7 +16,7 @@ class RESTAPI_iptocountry_handler : public RESTAPIHandler {
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){};
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/iptocountry"}; };
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/iptocountry"}; };
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace OpenWifi {
|
||||
std::vector<std::string>{
|
||||
Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS}, Server, TransactionId,Internal) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/ouis"};}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/ouis"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
|
||||
70
src/RESTAPI/RESTAPI_radiusProxyConfig_handler.cpp
Normal file
70
src/RESTAPI/RESTAPI_radiusProxyConfig_handler.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// Created by stephane bourque on 2022-05-20.
|
||||
//
|
||||
|
||||
#include "RESTAPI_radiusProxyConfig_handler.h"
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
#include "RADIUS_proxy_server.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_radiusProxyConfig_handler::DoGet() {
|
||||
GWObjects::RadiusProxyPoolList C;
|
||||
RADIUS_proxy_server()->GetConfig(C);
|
||||
Poco::JSON::Object Answer;
|
||||
C.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
|
||||
void RESTAPI_radiusProxyConfig_handler::DoDelete() {
|
||||
if(!Internal_ && (UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN)) {
|
||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||
}
|
||||
RADIUS_proxy_server()->DeleteConfig();
|
||||
return OK();
|
||||
}
|
||||
|
||||
void RESTAPI_radiusProxyConfig_handler::DoPut() {
|
||||
|
||||
if(!Internal_ && (UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN)) {
|
||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
GWObjects::RadiusProxyPoolList C;
|
||||
if(!C.from_json(ParsedBody_)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
// Logically validate the config.
|
||||
for(const auto &pool:C.pools) {
|
||||
if(pool.name.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::PoolNameInvalid);
|
||||
}
|
||||
for(const auto &config:{pool.acctConfig,pool.authConfig,pool.coaConfig}) {
|
||||
if(config.strategy!="random" && config.strategy!="round_robin" && config.strategy!="weighted") {
|
||||
return BadRequest(RESTAPI::Errors::InvalidRadiusProxyStrategy);
|
||||
}
|
||||
if(config.monitorMethod!="none" && config.monitorMethod!="https" && config.monitorMethod!="radius") {
|
||||
return BadRequest(RESTAPI::Errors::InvalidRadiusProxyMonitorMethod);
|
||||
}
|
||||
if(config.servers.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MustHaveAtLeastOneRadiusServer);
|
||||
}
|
||||
|
||||
for(auto &server:config.servers) {
|
||||
Poco::Net::IPAddress Addr;
|
||||
if(!Poco::Net::IPAddress::tryParse(server.ip,Addr) || server.port==0) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidRadiusServerEntry);
|
||||
}
|
||||
if(config.strategy=="weighted" && server.weight==0) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidRadiusServerWeigth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RADIUS_proxy_server()->SetConfig(C);
|
||||
return ReturnObject(*ParsedBody_);
|
||||
}
|
||||
|
||||
}
|
||||
27
src/RESTAPI/RESTAPI_radiusProxyConfig_handler.h
Normal file
27
src/RESTAPI/RESTAPI_radiusProxyConfig_handler.h
Normal file
@@ -0,0 +1,27 @@
|
||||
//
|
||||
// Created by stephane bourque on 2022-05-20.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_radiusProxyConfig_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_radiusProxyConfig_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
|
||||
RESTAPI_GenericServer &Server, uint64_t TransactionId,
|
||||
bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal) {}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/radiusProxyConfig"}; }
|
||||
void DoGet() final;
|
||||
void DoDelete() final;
|
||||
void DoPost() final{};
|
||||
void DoPut() final;
|
||||
};
|
||||
}
|
||||
@@ -16,15 +16,14 @@
|
||||
#include "RESTAPI/RESTAPI_devices_handler.h"
|
||||
#include "RESTAPI/RESTAPI_file.h"
|
||||
#include "RESTAPI/RESTAPI_ouis.h"
|
||||
|
||||
#include "RESTAPI/RESTAPI_capabilities_handler.h"
|
||||
#include "RESTAPI/RESTAPI_telemetryWebSocket.h"
|
||||
#include "RESTAPI/RESTAPI_webSocketServer.h"
|
||||
#include "RESTAPI/RESTAPI_iptocountry_handler.h"
|
||||
#include "RESTAPI/RESTAPI_radiusProxyConfig_handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
|
||||
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
|
||||
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
|
||||
|
||||
Poco::Thread::current()->setName("ExtWebServerThread_" + std::to_string(TransactionId));
|
||||
@@ -44,10 +43,11 @@ namespace OpenWifi {
|
||||
RESTAPI_blacklist,
|
||||
RESTAPI_blacklist_list,
|
||||
RESTAPI_iptocountry_handler,
|
||||
RESTAPI_radiusProxyConfig_handler,
|
||||
RESTAPI_capabilities_handler, RESTAPI_telemetryWebSocket>(Path,Bindings,L, S, TransactionId);
|
||||
}
|
||||
|
||||
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
|
||||
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
|
||||
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
|
||||
|
||||
Poco::Thread::current()->setName("IntWebServerThread_" + std::to_string(TransactionId));
|
||||
@@ -63,6 +63,7 @@ namespace OpenWifi {
|
||||
RESTAPI_file,
|
||||
RESTAPI_blacklist,
|
||||
RESTAPI_iptocountry_handler,
|
||||
RESTAPI_radiusProxyConfig_handler,
|
||||
RESTAPI_blacklist_list>(Path,Bindings,L, S, TransactionId);
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ namespace OpenWifi {
|
||||
|
||||
void RESTAPI_telemetryWebSocket::DoGet() {
|
||||
// try and upgrade this session to websocket...
|
||||
Poco::Thread::current()->setName(fmt::format("TELEMETRY-WS({})",UserInfo_.userinfo.email));
|
||||
if (Request->find("Upgrade") != Request->end() &&
|
||||
Poco::icompare((*Request)["Upgrade"], "websocket") == 0) {
|
||||
try {
|
||||
@@ -28,11 +29,16 @@ void RESTAPI_telemetryWebSocket::DoGet() {
|
||||
auto SerialNumber = Utils::SerialNumberToInt(SNum);
|
||||
|
||||
if(!TelemetryStream()->IsValidEndPoint(SerialNumber,UUID)) {
|
||||
Logger_.warning(Poco::format("Illegal telemetry request for S: %s, UUID: %s", SerialNumber, UUID));
|
||||
Logger_.warning(fmt::format("Illegal telemetry request for S: {}, UUID: {}", SerialNumber, UUID));
|
||||
Response->setStatusAndReason(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
|
||||
Response->setContentLength(0);
|
||||
Response->send();
|
||||
return;
|
||||
}
|
||||
auto WS = Poco::SharedPtr<Poco::Net::WebSocket>( new Poco::Net::WebSocket(*Request, *Response));
|
||||
new TelemetryClient(UUID, SerialNumber, WS, TelemetryStream()->NextReactor(), Logger_);
|
||||
|
||||
auto WS = std::make_unique<Poco::Net::WebSocket>(*Request, *Response);
|
||||
new TelemetryClient(UUID, SerialNumber, std::move(WS), TelemetryStream()->NextReactor(), Logger_);
|
||||
|
||||
} catch (const Poco::Net::WebSocketException &E) {
|
||||
Logger_.log(E);
|
||||
switch (E.code()) {
|
||||
@@ -49,7 +55,21 @@ void RESTAPI_telemetryWebSocket::DoGet() {
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
Response->setStatusAndReason(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
|
||||
Response->setContentLength(0);
|
||||
Response->send();
|
||||
return;
|
||||
} catch (...) {
|
||||
Response->setStatusAndReason(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
|
||||
Response->setContentLength(0);
|
||||
Response->send();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
SetCommonHeaders(true);
|
||||
Response->setStatus(Poco::Net::HTTPResponse::HTTP_METHOD_NOT_ALLOWED);
|
||||
Response->send();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ namespace OpenWifi {
|
||||
std::vector<std::string>{ Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal, false) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/ws_telemetry"};}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/ws_telemetry"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-08-12.
|
||||
//
|
||||
|
||||
#include "Poco/Net/WebSocket.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/Net/HTTPResponse.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
#include "RESTAPI_webSocketServer.h"
|
||||
#include "SerialNumberCache.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_webSocketServer::DoGet() {
|
||||
|
||||
// try and upgrade this session to websocket...
|
||||
if(Request->find("Upgrade") != Request->end() && Poco::icompare((*Request)["Upgrade"], "websocket") == 0) {
|
||||
try
|
||||
{
|
||||
Poco::Net::WebSocket WS(*Request, *Response);
|
||||
int flags;
|
||||
int n;
|
||||
bool Authenticated=false;
|
||||
bool Done=false;
|
||||
do
|
||||
{
|
||||
Poco::Buffer<char> IncomingFrame(0);
|
||||
n = WS.receiveFrame(IncomingFrame, flags);
|
||||
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
||||
switch(Op) {
|
||||
case Poco::Net::WebSocket::FRAME_OP_PING: {
|
||||
WS.sendFrame("", 0,
|
||||
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
|
||||
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
||||
}
|
||||
break;
|
||||
case Poco::Net::WebSocket::FRAME_OP_PONG: {
|
||||
}
|
||||
break;
|
||||
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
|
||||
IncomingFrame.append(0);
|
||||
if(!Authenticated) {
|
||||
std::string Frame{IncomingFrame.begin()};
|
||||
auto Tokens = Utils::Split(Frame,':');
|
||||
bool Expired=false, Contacted = false;
|
||||
if(Tokens.size()==2 && AuthClient()->IsAuthorized(Tokens[1], UserInfo_, Expired, Contacted)) {
|
||||
Authenticated=true;
|
||||
std::string S{"Welcome! Bienvenue! Bienvenidos!"};
|
||||
WS.sendFrame(S.c_str(),S.size());
|
||||
} else {
|
||||
std::string S{"Invalid token. Closing connection."};
|
||||
WS.sendFrame(S.c_str(),S.size());
|
||||
Done=true;
|
||||
}
|
||||
|
||||
} else {
|
||||
try {
|
||||
Poco::JSON::Parser P;
|
||||
auto Obj = P.parse(IncomingFrame.begin())
|
||||
.extract<Poco::JSON::Object::Ptr>();
|
||||
std::string Answer;
|
||||
if(Process(Obj, Answer)) {
|
||||
if (!Answer.empty())
|
||||
WS.sendFrame(Answer.c_str(), Answer.size());
|
||||
else {
|
||||
WS.sendFrame("{}", 2);
|
||||
}
|
||||
} else {
|
||||
Done=true;
|
||||
}
|
||||
} catch (const Poco::JSON::JSONException & E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
|
||||
Done=true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!Done && (n > 0 && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE));
|
||||
}
|
||||
catch (const Poco::Net::WebSocketException & E)
|
||||
{
|
||||
Logger_.log(E);
|
||||
switch (E.code())
|
||||
{
|
||||
case Poco::Net::WebSocket::WS_ERR_HANDSHAKE_UNSUPPORTED_VERSION:
|
||||
Response->set("Sec-WebSocket-Version", Poco::Net::WebSocket::WEBSOCKET_VERSION);
|
||||
// fallthrough
|
||||
case Poco::Net::WebSocket::WS_ERR_NO_HANDSHAKE:
|
||||
case Poco::Net::WebSocket::WS_ERR_HANDSHAKE_NO_VERSION:
|
||||
case Poco::Net::WebSocket::WS_ERR_HANDSHAKE_NO_KEY:
|
||||
Response->setStatusAndReason(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
|
||||
Response->setContentLength(0);
|
||||
Response->send();
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
catch (...) {
|
||||
|
||||
}
|
||||
} else {
|
||||
return BadRequest("Client does not support a websocket connection.");
|
||||
}
|
||||
}
|
||||
|
||||
bool RESTAPI_webSocketServer::Process(const Poco::JSON::Object::Ptr &O, std::string &Answer ) {
|
||||
try {
|
||||
if (O->has("command")) {
|
||||
auto Command = O->get("command").toString();
|
||||
if (Command == "serial_number_search" && O->has("serial_prefix")) {
|
||||
auto Prefix = O->get("serial_prefix").toString();
|
||||
uint64_t HowMany = 50;
|
||||
if (O->has("howMany"))
|
||||
HowMany = O->get("howMany");
|
||||
Logger_.information(Poco::format("serial_number_search: %s", Prefix));
|
||||
if (!Prefix.empty() && Prefix.length() < 13) {
|
||||
std::vector<uint64_t> Numbers;
|
||||
SerialNumberCache()->FindNumbers(Prefix, HowMany, Numbers);
|
||||
Poco::JSON::Array A;
|
||||
for (const auto &i : Numbers)
|
||||
A.add(Utils::IntToSerialNumber(i));
|
||||
Poco::JSON::Object AO;
|
||||
AO.set("serialNumbers", A);
|
||||
AO.set("command","serial_number_search");
|
||||
std::ostringstream SS;
|
||||
Poco::JSON::Stringifier::stringify(AO, SS);
|
||||
Answer = SS.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-08-12.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_webSocketServer : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{ Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal,false) {}
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/ws"};}
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
private:
|
||||
bool Process(const Poco::JSON::Object::Ptr &O, std::string &Answer);
|
||||
};
|
||||
}
|
||||
624
src/RESTObjects/RESTAPI_AnalyticsObjects.cpp
Normal file
624
src/RESTObjects/RESTAPI_AnalyticsObjects.cpp
Normal file
@@ -0,0 +1,624 @@
|
||||
//
|
||||
// Created by stephane bourque on 2022-01-10.
|
||||
//
|
||||
|
||||
#include "RESTAPI_AnalyticsObjects.h"
|
||||
#include "RESTAPI_ProvObjects.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
using OpenWifi::RESTAPI_utils::field_to_json;
|
||||
using OpenWifi::RESTAPI_utils::field_from_json;
|
||||
|
||||
namespace OpenWifi::AnalyticsObjects {
|
||||
|
||||
void Report::reset() {
|
||||
}
|
||||
|
||||
void Report::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const {
|
||||
}
|
||||
|
||||
void VenueInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"id",id);
|
||||
field_to_json(Obj,"name",name);
|
||||
field_to_json(Obj,"description",description);
|
||||
field_to_json(Obj,"retention",retention);
|
||||
field_to_json(Obj,"interval",interval);
|
||||
field_to_json(Obj,"monitorSubVenues",monitorSubVenues);
|
||||
}
|
||||
|
||||
bool VenueInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"id",id);
|
||||
field_from_json(Obj,"name",name);
|
||||
field_from_json(Obj,"description",description);
|
||||
field_from_json(Obj,"retention",retention);
|
||||
field_from_json(Obj,"interval",interval);
|
||||
field_from_json(Obj,"monitorSubVenues",monitorSubVenues);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BoardInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||
info.to_json(Obj);
|
||||
field_to_json(Obj,"venueList",venueList);
|
||||
}
|
||||
|
||||
bool BoardInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
info.from_json(Obj);
|
||||
field_from_json(Obj,"venueList",venueList);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeviceInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"boardId",boardId);
|
||||
field_to_json(Obj,"type",type);
|
||||
field_to_json(Obj,"serialNumber",serialNumber);
|
||||
field_to_json(Obj,"deviceType",deviceType);
|
||||
field_to_json(Obj,"lastContact",lastContact);
|
||||
field_to_json(Obj,"lastPing",lastPing);
|
||||
field_to_json(Obj,"lastState",lastState);
|
||||
field_to_json(Obj,"lastFirmware",lastFirmware);
|
||||
field_to_json(Obj,"lastFirmwareUpdate",lastFirmwareUpdate);
|
||||
field_to_json(Obj,"lastConnection",lastConnection);
|
||||
field_to_json(Obj,"lastDisconnection",lastDisconnection);
|
||||
field_to_json(Obj,"pings",pings);
|
||||
field_to_json(Obj,"states",states);
|
||||
field_to_json(Obj,"connected",connected);
|
||||
field_to_json(Obj,"connectionIp",connectionIp);
|
||||
field_to_json(Obj,"associations_2g",associations_2g);
|
||||
field_to_json(Obj,"associations_5g",associations_5g);
|
||||
field_to_json(Obj,"associations_6g",associations_6g);
|
||||
field_to_json(Obj,"health",health);
|
||||
field_to_json(Obj,"lastHealth",lastHealth);
|
||||
field_to_json(Obj,"locale",locale);
|
||||
field_to_json(Obj,"uptime",uptime);
|
||||
field_to_json(Obj,"memory",memory);
|
||||
}
|
||||
|
||||
bool DeviceInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"boardId",boardId);
|
||||
field_from_json(Obj,"type",type);
|
||||
field_from_json(Obj,"serialNumber",serialNumber);
|
||||
field_from_json(Obj,"deviceType",deviceType);
|
||||
field_from_json(Obj,"lastContact",lastContact);
|
||||
field_from_json(Obj,"lastPing",lastPing);
|
||||
field_from_json(Obj,"lastState",lastState);
|
||||
field_from_json(Obj,"lastFirmware",lastFirmware);
|
||||
field_from_json(Obj,"lastFirmwareUpdate",lastFirmwareUpdate);
|
||||
field_from_json(Obj,"lastConnection",lastConnection);
|
||||
field_from_json(Obj,"lastDisconnection",lastDisconnection);
|
||||
field_from_json(Obj,"pings",pings);
|
||||
field_from_json(Obj,"states",states);
|
||||
field_from_json(Obj,"connected",connected);
|
||||
field_from_json(Obj,"connectionIp",connectionIp);
|
||||
field_from_json(Obj,"associations_2g",associations_2g);
|
||||
field_from_json(Obj,"associations_5g",associations_5g);
|
||||
field_from_json(Obj,"associations_6g",associations_6g);
|
||||
field_from_json(Obj,"health",health);
|
||||
field_from_json(Obj,"lastHealth",lastHealth);
|
||||
field_from_json(Obj,"locale",locale);
|
||||
field_from_json(Obj,"uptime",uptime);
|
||||
field_from_json(Obj,"memory",memory);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeviceInfoList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"devices",devices);
|
||||
}
|
||||
|
||||
bool DeviceInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"devices",devices);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void UE_rate::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"bitrate",bitrate);
|
||||
field_to_json(Obj,"mcs",mcs);
|
||||
field_to_json(Obj,"nss",nss);
|
||||
field_to_json(Obj,"ht",ht);
|
||||
field_to_json(Obj,"sgi",sgi);
|
||||
field_to_json(Obj,"chwidth",chwidth);
|
||||
}
|
||||
|
||||
bool UE_rate::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"bitrate",bitrate);
|
||||
field_from_json(Obj,"mcs",mcs);
|
||||
field_from_json(Obj,"nss",nss);
|
||||
field_from_json(Obj,"ht",ht);
|
||||
field_from_json(Obj,"sgi",sgi);
|
||||
field_from_json(Obj,"chwidth",chwidth);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void UETimePoint::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"station",station);
|
||||
field_to_json(Obj,"rssi",rssi);
|
||||
field_to_json(Obj,"tx_bytes",tx_bytes);
|
||||
field_to_json(Obj,"rx_bytes",rx_bytes);
|
||||
field_to_json(Obj,"tx_duration",tx_duration);
|
||||
field_to_json(Obj,"rx_packets",rx_packets);
|
||||
field_to_json(Obj,"tx_packets",tx_packets);
|
||||
field_to_json(Obj,"tx_retries",tx_retries);
|
||||
field_to_json(Obj,"tx_failed",tx_failed);
|
||||
field_to_json(Obj,"connected",connected);
|
||||
field_to_json(Obj,"inactive",inactive);
|
||||
field_to_json(Obj,"tx_rate",tx_rate);
|
||||
field_to_json(Obj,"rx_rate",rx_rate);
|
||||
// field_to_json(Obj, "tidstats", tidstats);
|
||||
|
||||
field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||
field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||
field_to_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||
field_to_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||
field_to_json(Obj,"tx_failed_pct",tx_failed_pct);
|
||||
field_to_json(Obj,"tx_retries_pct",tx_retries_pct);
|
||||
field_to_json(Obj,"tx_duration_pct",tx_duration_pct);
|
||||
|
||||
field_to_json(Obj,"tx_bytes_delta",tx_bytes_delta);
|
||||
field_to_json(Obj,"rx_bytes_delta",rx_bytes_delta);
|
||||
field_to_json(Obj,"tx_packets_delta",tx_packets_delta);
|
||||
field_to_json(Obj,"rx_packets_delta",rx_packets_delta);
|
||||
field_to_json(Obj,"tx_failed_delta",tx_failed_delta);
|
||||
field_to_json(Obj,"tx_retries_delta",tx_retries_delta);
|
||||
field_to_json(Obj,"tx_duration_delta",tx_duration_delta);
|
||||
}
|
||||
|
||||
bool UETimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"station",station);
|
||||
field_from_json(Obj,"rssi",rssi);
|
||||
field_from_json(Obj,"tx_bytes",tx_bytes);
|
||||
field_from_json(Obj,"rx_bytes",rx_bytes);
|
||||
field_from_json(Obj,"tx_duration",tx_duration);
|
||||
field_from_json(Obj,"rx_packets",rx_packets);
|
||||
field_from_json(Obj,"tx_packets",tx_packets);
|
||||
field_from_json(Obj,"tx_retries",tx_retries);
|
||||
field_from_json(Obj,"tx_failed",tx_failed);
|
||||
field_from_json(Obj,"connected",connected);
|
||||
field_from_json(Obj,"inactive",inactive);
|
||||
field_from_json(Obj,"tx_rate",tx_rate);
|
||||
field_from_json(Obj,"rx_rate",rx_rate);
|
||||
// field_from_json(Obj,"tidstats",tidstats);
|
||||
field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||
field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||
field_from_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||
field_from_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||
field_from_json(Obj,"tx_failed_pct",tx_failed_pct);
|
||||
field_from_json(Obj,"tx_retries_pct",tx_retries_pct);
|
||||
field_from_json(Obj,"tx_duration_pct",tx_duration_pct);
|
||||
field_from_json(Obj,"tx_bytes_delta",tx_bytes_delta);
|
||||
field_from_json(Obj,"rx_bytes_delta",rx_bytes_delta);
|
||||
field_from_json(Obj,"tx_packets_delta",tx_packets_delta);
|
||||
field_from_json(Obj,"rx_packets_delta",rx_packets_delta);
|
||||
field_from_json(Obj,"tx_failed_delta",tx_failed_delta);
|
||||
field_from_json(Obj,"tx_retries_delta",tx_retries_delta);
|
||||
field_from_json(Obj,"tx_duration_delta",tx_duration_delta);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void APTimePoint::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"collisions",collisions);
|
||||
field_to_json(Obj,"multicast",multicast);
|
||||
field_to_json(Obj,"rx_bytes",rx_bytes);
|
||||
field_to_json(Obj,"rx_dropped",rx_dropped);
|
||||
field_to_json(Obj,"rx_errors",rx_errors);
|
||||
field_to_json(Obj,"rx_packets",rx_packets);
|
||||
field_to_json(Obj,"tx_bytes",tx_bytes);
|
||||
field_to_json(Obj,"tx_packets",tx_packets);
|
||||
field_to_json(Obj,"tx_dropped",tx_dropped);
|
||||
field_to_json(Obj,"tx_errors",tx_errors);
|
||||
field_to_json(Obj,"tx_packets",tx_packets);
|
||||
|
||||
field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||
field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||
field_to_json(Obj,"rx_dropped_pct",rx_dropped_pct);
|
||||
field_to_json(Obj,"tx_dropped_pct",tx_dropped_pct);
|
||||
field_to_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||
field_to_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||
field_to_json(Obj,"rx_errors_pct",rx_errors_pct);
|
||||
field_to_json(Obj,"tx_errors_pct",tx_errors_pct);
|
||||
|
||||
field_to_json(Obj,"tx_bytes_delta",tx_bytes_delta);
|
||||
field_to_json(Obj,"rx_bytes_delta",rx_bytes_delta);
|
||||
field_to_json(Obj,"rx_dropped_delta",rx_dropped_delta);
|
||||
field_to_json(Obj,"tx_dropped_delta",tx_dropped_delta);
|
||||
field_to_json(Obj,"rx_packets_delta",rx_packets_delta);
|
||||
field_to_json(Obj,"tx_packets_delta",tx_packets_delta);
|
||||
field_to_json(Obj,"rx_errors_delta",rx_errors_delta);
|
||||
field_to_json(Obj,"tx_errors_delta",tx_errors_delta);
|
||||
}
|
||||
|
||||
bool APTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"collisions",collisions);
|
||||
field_from_json(Obj,"multicast",multicast);
|
||||
field_from_json(Obj,"rx_bytes",rx_bytes);
|
||||
field_from_json(Obj,"rx_dropped",rx_dropped);
|
||||
field_from_json(Obj,"rx_errors",rx_errors);
|
||||
field_from_json(Obj,"rx_packets",rx_packets);
|
||||
field_from_json(Obj,"tx_bytes",tx_bytes);
|
||||
field_from_json(Obj,"tx_packets",tx_packets);
|
||||
field_from_json(Obj,"tx_dropped",tx_dropped);
|
||||
field_from_json(Obj,"tx_errors",tx_errors);
|
||||
field_from_json(Obj,"tx_packets",tx_packets);
|
||||
|
||||
field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||
field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||
field_from_json(Obj,"rx_dropped_pct",rx_dropped_pct);
|
||||
field_from_json(Obj,"tx_dropped_pct",tx_dropped_pct);
|
||||
field_from_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||
field_from_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||
field_from_json(Obj,"rx_errors_pct",rx_errors_pct);
|
||||
field_from_json(Obj,"tx_errors_pct",tx_errors_pct);
|
||||
|
||||
field_from_json(Obj,"tx_bytes_delta",tx_bytes_delta);
|
||||
field_from_json(Obj,"rx_bytes_delta",rx_bytes_delta);
|
||||
field_from_json(Obj,"rx_dropped_delta",rx_dropped_delta);
|
||||
field_from_json(Obj,"tx_dropped_delta",tx_dropped_delta);
|
||||
field_from_json(Obj,"rx_packets_delta",rx_packets_delta);
|
||||
field_from_json(Obj,"tx_packets_delta",tx_packets_delta);
|
||||
field_from_json(Obj,"rx_errors_delta",rx_errors_delta);
|
||||
field_from_json(Obj,"tx_errors_delta",tx_errors_delta);
|
||||
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TIDstat_entry::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"rx_msdu",rx_msdu);
|
||||
field_to_json(Obj,"tx_msdu",tx_msdu);
|
||||
field_to_json(Obj,"tx_msdu_failed",tx_msdu_failed);
|
||||
field_to_json(Obj,"tx_msdu_retries",tx_msdu_retries);
|
||||
}
|
||||
|
||||
bool TIDstat_entry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"rx_msdu",rx_msdu);
|
||||
field_from_json(Obj,"tx_msdu",tx_msdu);
|
||||
field_from_json(Obj,"tx_msdu_failed",tx_msdu_failed);
|
||||
field_from_json(Obj,"tx_msdu_retries",tx_msdu_retries);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RadioTimePoint::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"band",band);
|
||||
field_to_json(Obj,"channel_width",channel_width);
|
||||
field_to_json(Obj,"active_ms",active_ms);
|
||||
field_to_json(Obj,"busy_ms",busy_ms);
|
||||
field_to_json(Obj,"receive_ms",receive_ms);
|
||||
field_to_json(Obj,"transmit_ms",transmit_ms);
|
||||
field_to_json(Obj,"tx_power",tx_power);
|
||||
field_to_json(Obj,"channel",channel);
|
||||
field_to_json(Obj,"temperature",temperature);
|
||||
field_to_json(Obj,"noise",noise);
|
||||
field_to_json(Obj,"active_pct",active_pct);
|
||||
field_to_json(Obj,"busy_pct",busy_pct);
|
||||
field_to_json(Obj,"receive_pct",receive_pct);
|
||||
field_to_json(Obj,"transmit_pct",transmit_pct);
|
||||
}
|
||||
|
||||
bool RadioTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"band",band);
|
||||
field_from_json(Obj,"channel_width",channel_width);
|
||||
field_from_json(Obj,"active_ms",active_ms);
|
||||
field_from_json(Obj,"busy_ms",busy_ms);
|
||||
field_from_json(Obj,"receive_ms",receive_ms);
|
||||
field_from_json(Obj,"transmit_ms",transmit_ms);
|
||||
field_from_json(Obj,"tx_power",tx_power);
|
||||
field_from_json(Obj,"channel",channel);
|
||||
field_from_json(Obj,"temperature",temperature);
|
||||
field_from_json(Obj,"noise",noise);
|
||||
field_from_json(Obj,"active_pct",active_pct);
|
||||
field_from_json(Obj,"busy_pct",busy_pct);
|
||||
field_from_json(Obj,"receive_pct",receive_pct);
|
||||
field_from_json(Obj,"transmit_pct",transmit_pct);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AveragePoint::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"min",min);
|
||||
field_to_json(Obj,"max",max);
|
||||
field_to_json(Obj,"avg",avg);
|
||||
}
|
||||
|
||||
bool AveragePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"min",min);
|
||||
field_from_json(Obj,"max",max);
|
||||
field_from_json(Obj,"avg",avg);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SSIDTimePoint::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"bssid",bssid);
|
||||
field_to_json(Obj,"mode",mode);
|
||||
field_to_json(Obj,"ssid",ssid);
|
||||
field_to_json(Obj,"band",band);
|
||||
field_to_json(Obj,"channel",channel);
|
||||
field_to_json(Obj,"associations",associations);
|
||||
field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||
field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||
field_to_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||
field_to_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||
field_to_json(Obj,"tx_failed_pct",tx_failed_pct);
|
||||
field_to_json(Obj,"tx_retries_pct",tx_retries_pct);
|
||||
field_to_json(Obj,"tx_duration_pct",tx_duration_pct);
|
||||
}
|
||||
|
||||
bool SSIDTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"bssid",bssid);
|
||||
field_from_json(Obj,"mode",mode);
|
||||
field_from_json(Obj,"ssid",ssid);
|
||||
field_from_json(Obj,"band",band);
|
||||
field_from_json(Obj,"channel",channel);
|
||||
field_from_json(Obj,"associations",associations);
|
||||
field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||
field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||
field_from_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||
field_from_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||
field_from_json(Obj,"tx_failed_pct",tx_failed_pct);
|
||||
field_from_json(Obj,"tx_retries_pct",tx_retries_pct);
|
||||
field_from_json(Obj,"tx_duration_pct",tx_duration_pct);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeviceTimePoint::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"id",id);
|
||||
field_to_json(Obj,"boardId",boardId);
|
||||
field_to_json(Obj,"timestamp",timestamp);
|
||||
field_to_json(Obj,"ap_data",ap_data);
|
||||
field_to_json(Obj,"ssid_data",ssid_data);
|
||||
field_to_json(Obj,"radio_data",radio_data);
|
||||
field_to_json(Obj,"device_info",device_info);
|
||||
field_to_json(Obj,"serialNumber",serialNumber);
|
||||
}
|
||||
|
||||
bool DeviceTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"id",id);
|
||||
field_from_json(Obj,"boardId",boardId);
|
||||
field_from_json(Obj,"timestamp",timestamp);
|
||||
field_from_json(Obj,"ap_data",ap_data);
|
||||
field_from_json(Obj,"ssid_data",ssid_data);
|
||||
field_from_json(Obj,"radio_data",radio_data);
|
||||
field_from_json(Obj,"device_info",device_info);
|
||||
field_from_json(Obj,"serialNumber",serialNumber);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeviceTimePointAnalysis::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"noise",noise);
|
||||
field_to_json(Obj,"temperature",temperature);
|
||||
field_to_json(Obj,"active_pct",active_pct);
|
||||
field_to_json(Obj,"busy_pct",busy_pct);
|
||||
field_to_json(Obj,"receive_pct",receive_pct);
|
||||
field_to_json(Obj,"transmit_pct",transmit_pct);
|
||||
field_to_json(Obj,"tx_power",tx_power);
|
||||
field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||
field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||
field_to_json(Obj,"rx_dropped_pct",rx_dropped_pct);
|
||||
field_to_json(Obj,"tx_dropped_pct",tx_dropped_pct);
|
||||
field_to_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||
field_to_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||
field_to_json(Obj,"rx_errors_pct",rx_errors_pct);
|
||||
field_to_json(Obj,"tx_errors_pct",tx_errors_pct);
|
||||
}
|
||||
|
||||
bool DeviceTimePointAnalysis::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"noise",noise);
|
||||
field_from_json(Obj,"temperature",temperature);
|
||||
field_from_json(Obj,"active_pct",active_pct);
|
||||
field_from_json(Obj,"busy_pct",busy_pct);
|
||||
field_from_json(Obj,"receive_pct",receive_pct);
|
||||
field_from_json(Obj,"transmit_pct",transmit_pct);
|
||||
field_from_json(Obj,"tx_power",tx_power);
|
||||
field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||
field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||
field_from_json(Obj,"rx_dropped_pct",rx_dropped_pct);
|
||||
field_from_json(Obj,"tx_dropped_pct",tx_dropped_pct);
|
||||
field_from_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||
field_from_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||
field_from_json(Obj,"rx_errors_pct",rx_errors_pct);
|
||||
field_from_json(Obj,"tx_errors_pct",tx_errors_pct);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeviceTimePointList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"points",points);
|
||||
field_to_json(Obj,"stats",stats);
|
||||
}
|
||||
|
||||
bool DeviceTimePointList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"points",points);
|
||||
field_from_json(Obj,"stats",stats);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeviceTimePointStats::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"firstPoint",firstPoint);
|
||||
field_to_json(Obj,"lastPoint",lastPoint);
|
||||
field_to_json(Obj,"count",count);
|
||||
}
|
||||
|
||||
bool DeviceTimePointStats::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"firstPoint",firstPoint);
|
||||
field_from_json(Obj,"lastPoint",lastPoint);
|
||||
field_from_json(Obj,"count",count);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void WifiClientRate::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"bitrate",bitrate);
|
||||
field_to_json(Obj,"chwidth",chwidth);
|
||||
field_to_json(Obj,"mcs",mcs);
|
||||
field_to_json(Obj,"nss",nss);
|
||||
field_to_json(Obj,"vht",vht);
|
||||
}
|
||||
|
||||
bool WifiClientRate::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"bitrate",bitrate);
|
||||
field_from_json(Obj,"chwidth",chwidth);
|
||||
field_from_json(Obj,"mcs",mcs);
|
||||
field_from_json(Obj,"nss",nss);
|
||||
field_from_json(Obj,"vht",vht);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void WifiClientHistory::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"timestamp",timestamp);
|
||||
field_to_json(Obj,"station_id",station_id);
|
||||
field_to_json(Obj,"bssid",bssid);
|
||||
field_to_json(Obj,"ssid",ssid);
|
||||
field_to_json(Obj,"rssi",rssi);
|
||||
field_to_json(Obj,"rx_bitrate",rx_bitrate);
|
||||
field_to_json(Obj,"rx_chwidth",rx_chwidth);
|
||||
field_to_json(Obj,"rx_mcs",rx_mcs);
|
||||
field_to_json(Obj,"rx_nss",rx_nss);
|
||||
field_to_json(Obj,"rx_vht",rx_vht);
|
||||
field_to_json(Obj,"tx_bitrate",tx_bitrate);
|
||||
field_to_json(Obj,"tx_chwidth",tx_chwidth);
|
||||
field_to_json(Obj,"tx_mcs",tx_mcs);
|
||||
field_to_json(Obj,"tx_nss",tx_nss);
|
||||
field_to_json(Obj,"tx_vht",tx_vht);
|
||||
field_to_json(Obj,"rx_bytes",rx_bytes);
|
||||
field_to_json(Obj,"tx_bytes",tx_bytes);
|
||||
field_to_json(Obj,"rx_duration",rx_duration);
|
||||
field_to_json(Obj,"tx_duration",tx_duration);
|
||||
field_to_json(Obj,"rx_packets",rx_packets);
|
||||
field_to_json(Obj,"tx_packets",tx_packets);
|
||||
field_to_json(Obj,"ipv4",ipv4);
|
||||
field_to_json(Obj,"ipv6",ipv6);
|
||||
field_to_json(Obj,"channel_width",channel_width);
|
||||
field_to_json(Obj,"noise",noise);
|
||||
field_to_json(Obj,"tx_power",tx_power);
|
||||
field_to_json(Obj,"channel",channel);
|
||||
field_to_json(Obj,"active_ms",active_ms);
|
||||
field_to_json(Obj,"busy_ms",busy_ms);
|
||||
field_to_json(Obj,"receive_ms",receive_ms);
|
||||
field_to_json(Obj,"mode",mode);
|
||||
field_to_json(Obj,"ack_signal",ack_signal);
|
||||
field_to_json(Obj,"ack_signal_avg",ack_signal_avg);
|
||||
field_to_json(Obj,"connected",connected);
|
||||
field_to_json(Obj,"inactive",inactive);
|
||||
field_to_json(Obj,"tx_retries",tx_retries);
|
||||
field_to_json(Obj,"venue_id",venue_id);
|
||||
}
|
||||
|
||||
bool WifiClientHistory::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"timestamp",timestamp);
|
||||
field_from_json(Obj,"station_id",station_id);
|
||||
field_from_json(Obj,"bssid",bssid);
|
||||
field_from_json(Obj,"ssid",ssid);
|
||||
field_from_json(Obj,"rssi",rssi);
|
||||
field_from_json(Obj,"rx_bitrate",rx_bitrate);
|
||||
field_from_json(Obj,"rx_chwidth",rx_chwidth);
|
||||
field_from_json(Obj,"rx_mcs",rx_mcs);
|
||||
field_from_json(Obj,"rx_nss",rx_nss);
|
||||
field_from_json(Obj,"rx_vht",rx_vht);
|
||||
field_from_json(Obj,"tx_bitrate",tx_bitrate);
|
||||
field_from_json(Obj,"tx_chwidth",tx_chwidth);
|
||||
field_from_json(Obj,"tx_mcs",tx_mcs);
|
||||
field_from_json(Obj,"tx_nss",tx_nss);
|
||||
field_from_json(Obj,"tx_vht",tx_vht);
|
||||
field_from_json(Obj,"rx_bytes",rx_bytes);
|
||||
field_from_json(Obj,"tx_bytes",tx_bytes);
|
||||
field_from_json(Obj,"rx_duration",rx_duration);
|
||||
field_from_json(Obj,"tx_duration",tx_duration);
|
||||
field_from_json(Obj,"rx_packets",rx_packets);
|
||||
field_from_json(Obj,"tx_packets",tx_packets);
|
||||
field_from_json(Obj,"ipv4",ipv4);
|
||||
field_from_json(Obj,"ipv6",ipv6);
|
||||
field_from_json(Obj,"channel_width",channel_width);
|
||||
field_from_json(Obj,"noise",noise);
|
||||
field_from_json(Obj,"tx_power",tx_power);
|
||||
field_from_json(Obj,"channel",channel);
|
||||
field_from_json(Obj,"active_ms",active_ms);
|
||||
field_from_json(Obj,"busy_ms",busy_ms);
|
||||
field_from_json(Obj,"receive_ms",receive_ms);
|
||||
field_from_json(Obj,"mode",mode);
|
||||
field_from_json(Obj,"ack_signal",ack_signal);
|
||||
field_from_json(Obj,"ack_signal_avg",ack_signal_avg);
|
||||
field_from_json(Obj,"connected",connected);
|
||||
field_from_json(Obj,"inactive",inactive);
|
||||
field_from_json(Obj,"tx_retries",tx_retries);
|
||||
field_from_json(Obj,"venue_id",venue_id);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
422
src/RESTObjects/RESTAPI_AnalyticsObjects.h
Normal file
422
src/RESTObjects/RESTAPI_AnalyticsObjects.h
Normal file
@@ -0,0 +1,422 @@
|
||||
//
|
||||
// Created by stephane bourque on 2022-01-10.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RESTAPI_ProvObjects.h"
|
||||
#include <vector>
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
namespace AnalyticsObjects {
|
||||
|
||||
struct Report {
|
||||
uint64_t snapShot = 0;
|
||||
|
||||
void reset();
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
|
||||
struct VenueInfo {
|
||||
OpenWifi::Types::UUID_t id;
|
||||
std::string name;
|
||||
std::string description;
|
||||
uint64_t retention = 0;
|
||||
uint64_t interval = 0;
|
||||
bool monitorSubVenues = false;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct BoardInfo {
|
||||
ProvObjects::ObjectInfo info;
|
||||
std::vector<VenueInfo> venueList;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
|
||||
inline bool operator<(const BoardInfo &bb) const {
|
||||
return info.id < bb.info.id;
|
||||
}
|
||||
|
||||
inline bool operator==(const BoardInfo &bb) const {
|
||||
return info.id == bb.info.id;
|
||||
}
|
||||
};
|
||||
|
||||
struct DeviceInfo {
|
||||
std::string boardId;
|
||||
std::string type;
|
||||
std::string serialNumber;
|
||||
std::string deviceType;
|
||||
uint64_t lastContact = 0 ;
|
||||
uint64_t lastPing = 0;
|
||||
uint64_t lastState = 0;
|
||||
std::string lastFirmware;
|
||||
uint64_t lastFirmwareUpdate = 0;
|
||||
uint64_t lastConnection = 0;
|
||||
uint64_t lastDisconnection = 0;
|
||||
uint64_t pings = 0;
|
||||
uint64_t states = 0;
|
||||
bool connected = false;
|
||||
std::string connectionIp;
|
||||
uint64_t associations_2g = 0;
|
||||
uint64_t associations_5g = 0;
|
||||
uint64_t associations_6g = 0;
|
||||
uint64_t health = 0;
|
||||
uint64_t lastHealth = 0;
|
||||
std::string locale;
|
||||
uint64_t uptime = 0;
|
||||
double memory = 0.0;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct DeviceInfoList {
|
||||
std::vector<DeviceInfo> devices;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
enum wifi_band {
|
||||
band_2g = 0, band_5g = 1, band_6g = 2
|
||||
};
|
||||
|
||||
struct TIDstat_entry {
|
||||
uint64_t rx_msdu = 0,
|
||||
tx_msdu = 0,
|
||||
tx_msdu_failed = 0,
|
||||
tx_msdu_retries = 0;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct UE_rate {
|
||||
uint64_t bitrate=0;
|
||||
uint64_t mcs=0;
|
||||
uint64_t nss=0;
|
||||
bool ht=false;
|
||||
bool sgi=false;
|
||||
uint64_t chwidth=0;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct AveragePoint {
|
||||
double min = 0.0,
|
||||
max = 0.0,
|
||||
avg = 0.0;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct UETimePoint {
|
||||
std::string station;
|
||||
int64_t rssi = 0;
|
||||
uint64_t tx_bytes = 0,
|
||||
rx_bytes = 0,
|
||||
tx_duration = 0,
|
||||
rx_packets = 0,
|
||||
tx_packets = 0,
|
||||
tx_retries = 0,
|
||||
tx_failed = 0,
|
||||
connected = 0,
|
||||
inactive = 0;
|
||||
|
||||
double tx_bytes_bw = 0.0 ,
|
||||
rx_bytes_bw = 0.0 ,
|
||||
tx_packets_bw = 0.0 ,
|
||||
rx_packets_bw = 0.0 ,
|
||||
tx_failed_pct = 0.0 ,
|
||||
tx_retries_pct = 0.0 ,
|
||||
tx_duration_pct = 0.0;
|
||||
|
||||
uint64_t tx_bytes_delta = 0,
|
||||
rx_bytes_delta = 0,
|
||||
tx_duration_delta = 0,
|
||||
rx_packets_delta = 0,
|
||||
tx_packets_delta = 0,
|
||||
tx_retries_delta = 0,
|
||||
tx_failed_delta = 0;
|
||||
|
||||
UE_rate tx_rate,
|
||||
rx_rate;
|
||||
std::vector<TIDstat_entry> tidstats;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
enum SSID_MODES {
|
||||
unknown = 0,
|
||||
ap,
|
||||
mesh,
|
||||
sta,
|
||||
wds_ap,
|
||||
wds_sta,
|
||||
wds_repeater
|
||||
};
|
||||
|
||||
inline SSID_MODES SSID_Mode(const std::string &m) {
|
||||
if (m == "ap")
|
||||
return ap;
|
||||
if (m == "sta")
|
||||
return sta;
|
||||
if (m == "mesh")
|
||||
return mesh;
|
||||
if (m == "wds-ap")
|
||||
return wds_ap;
|
||||
if (m == "wds-sta")
|
||||
return wds_sta;
|
||||
if (m == "wds-repeater")
|
||||
return wds_repeater;
|
||||
return unknown;
|
||||
}
|
||||
|
||||
struct SSIDTimePoint {
|
||||
std::string bssid,
|
||||
mode,
|
||||
ssid;
|
||||
uint64_t band=0,
|
||||
channel=0;
|
||||
std::vector<UETimePoint> associations;
|
||||
|
||||
AveragePoint tx_bytes_bw,
|
||||
rx_bytes_bw,
|
||||
tx_packets_bw,
|
||||
rx_packets_bw,
|
||||
tx_failed_pct,
|
||||
tx_retries_pct,
|
||||
tx_duration_pct;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
|
||||
struct APTimePoint {
|
||||
uint64_t collisions = 0,
|
||||
multicast = 0,
|
||||
rx_bytes = 0,
|
||||
rx_dropped = 0,
|
||||
rx_errors = 0,
|
||||
rx_packets = 0,
|
||||
tx_bytes = 0,
|
||||
tx_dropped = 0,
|
||||
tx_errors = 0,
|
||||
tx_packets = 0;
|
||||
|
||||
double tx_bytes_bw = 0.0 ,
|
||||
rx_bytes_bw = 0.0 ,
|
||||
rx_dropped_pct = 0.0,
|
||||
tx_dropped_pct = 0.0,
|
||||
rx_packets_bw = 0.0,
|
||||
tx_packets_bw = 0.0,
|
||||
rx_errors_pct = 0.0 ,
|
||||
tx_errors_pct = 0.0;
|
||||
|
||||
uint64_t tx_bytes_delta = 0,
|
||||
rx_bytes_delta = 0 ,
|
||||
rx_dropped_delta = 0,
|
||||
tx_dropped_delta = 0,
|
||||
rx_packets_delta = 0,
|
||||
tx_packets_delta = 0,
|
||||
rx_errors_delta = 0,
|
||||
tx_errors_delta = 0;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct RadioTimePoint {
|
||||
uint64_t band = 0,
|
||||
channel_width = 0;
|
||||
uint64_t active_ms = 0,
|
||||
busy_ms = 0,
|
||||
receive_ms = 0,
|
||||
transmit_ms = 0,
|
||||
tx_power = 0,
|
||||
channel = 0;
|
||||
int64_t temperature = 0,
|
||||
noise = 0;
|
||||
|
||||
double active_pct = 0.0 ,
|
||||
busy_pct = 0.0,
|
||||
receive_pct = 0.0,
|
||||
transmit_pct = 0.0;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
|
||||
struct DeviceTimePoint {
|
||||
std::string id;
|
||||
std::string boardId;
|
||||
uint64_t timestamp = 0;
|
||||
APTimePoint ap_data;
|
||||
std::vector<SSIDTimePoint> ssid_data;
|
||||
std::vector<RadioTimePoint> radio_data;
|
||||
AnalyticsObjects::DeviceInfo device_info;
|
||||
std::string serialNumber;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
|
||||
inline bool operator<(const DeviceTimePoint &rhs) const {
|
||||
if(timestamp < rhs.timestamp)
|
||||
return true;
|
||||
if(timestamp > rhs.timestamp)
|
||||
return false;
|
||||
if(device_info.serialNumber < rhs.device_info.serialNumber)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool operator==(const DeviceTimePoint &rhs) const {
|
||||
return timestamp==rhs.timestamp && device_info.serialNumber==rhs.device_info.serialNumber;
|
||||
}
|
||||
|
||||
inline bool operator>(const DeviceTimePoint &rhs) const {
|
||||
if(timestamp > rhs.timestamp)
|
||||
return true;
|
||||
if(timestamp < rhs.timestamp)
|
||||
return false;
|
||||
if(device_info.serialNumber > rhs.device_info.serialNumber)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct DeviceTimePointAnalysis {
|
||||
uint64_t timestamp;
|
||||
|
||||
AveragePoint noise;
|
||||
AveragePoint temperature;
|
||||
AveragePoint active_pct;
|
||||
AveragePoint busy_pct;
|
||||
AveragePoint receive_pct;
|
||||
AveragePoint transmit_pct;
|
||||
AveragePoint tx_power;
|
||||
|
||||
AveragePoint tx_bytes_bw;
|
||||
AveragePoint rx_bytes_bw;
|
||||
AveragePoint rx_dropped_pct;
|
||||
AveragePoint tx_dropped_pct;
|
||||
AveragePoint rx_packets_bw;
|
||||
AveragePoint tx_packets_bw;
|
||||
AveragePoint rx_errors_pct;
|
||||
AveragePoint tx_errors_pct;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
|
||||
};
|
||||
|
||||
struct DeviceTimePointList {
|
||||
std::vector<DeviceTimePoint> points;
|
||||
std::vector<DeviceTimePointAnalysis> stats;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct BandwidthAnalysisEntry {
|
||||
uint64_t timestamp = 0;
|
||||
|
||||
};
|
||||
|
||||
struct BandwidthAnalysis {
|
||||
|
||||
};
|
||||
|
||||
struct AverageValueSigned {
|
||||
int64_t peak=0, avg=0, low=0;
|
||||
};
|
||||
|
||||
struct AverageValueUnsigned {
|
||||
uint64_t peak=0, avg=0, low=0;
|
||||
};
|
||||
|
||||
struct RadioAnalysis {
|
||||
uint64_t timestamp=0;
|
||||
AverageValueSigned noise, temperature;
|
||||
AverageValueUnsigned active_ms,
|
||||
busy_ms,
|
||||
transmit_ms,
|
||||
receive_ms;
|
||||
};
|
||||
|
||||
struct DeviceTimePointStats {
|
||||
uint64_t firstPoint=0;
|
||||
uint64_t lastPoint=0;
|
||||
uint64_t count=0;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct WifiClientRate {
|
||||
uint32_t bitrate=0;
|
||||
uint32_t chwidth=0;
|
||||
uint16_t mcs=0;
|
||||
uint16_t nss=0;
|
||||
bool vht=false;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct WifiClientHistory {
|
||||
uint64_t timestamp=OpenWifi::Now();
|
||||
std::string station_id;
|
||||
std::string bssid;
|
||||
std::string ssid;
|
||||
int64_t rssi=0;
|
||||
uint32_t rx_bitrate=0;
|
||||
uint32_t rx_chwidth=0;
|
||||
uint16_t rx_mcs=0;
|
||||
uint16_t rx_nss=0;
|
||||
bool rx_vht=false;
|
||||
uint32_t tx_bitrate=0;
|
||||
uint32_t tx_chwidth=0;
|
||||
uint16_t tx_mcs=0;
|
||||
uint16_t tx_nss=0;
|
||||
bool tx_vht=false;
|
||||
uint64_t rx_bytes=0;
|
||||
uint64_t tx_bytes=0;
|
||||
uint64_t rx_duration=0;
|
||||
uint64_t tx_duration=0;
|
||||
uint64_t rx_packets=0;
|
||||
uint64_t tx_packets=0;
|
||||
std::string ipv4;
|
||||
std::string ipv6;
|
||||
uint64_t channel_width=0;
|
||||
int64_t noise=0;
|
||||
uint64_t tx_power=0;
|
||||
uint64_t channel=0;
|
||||
uint64_t active_ms=0;
|
||||
uint64_t busy_ms=0;
|
||||
uint64_t receive_ms=0;
|
||||
std::string mode;
|
||||
int64_t ack_signal=0;
|
||||
int64_t ack_signal_avg=0;
|
||||
uint64_t connected=0;
|
||||
uint64_t inactive=0;
|
||||
uint64_t tx_retries=0;
|
||||
std::string venue_id;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,176 +3,206 @@
|
||||
//
|
||||
|
||||
#include "RESTAPI_CertObjects.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
using OpenWifi::RESTAPI_utils::field_to_json;
|
||||
using OpenWifi::RESTAPI_utils::field_from_json;
|
||||
|
||||
namespace OpenWifi {
|
||||
namespace CertObjects {
|
||||
void CertificateEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"id", id);
|
||||
field_to_json(Obj,"entity", entity);
|
||||
field_to_json(Obj,"creator", creator);
|
||||
field_to_json(Obj,"type", type);
|
||||
field_to_json(Obj,"status", status);
|
||||
field_to_json(Obj,"certificate", certificate);
|
||||
field_to_json(Obj,"key", key);
|
||||
field_to_json(Obj,"devid", devid);
|
||||
field_to_json(Obj,"cas", cas);
|
||||
field_to_json(Obj,"manufacturer", manufacturer);
|
||||
field_to_json(Obj,"model", model);
|
||||
field_to_json(Obj,"redirector", redirector);
|
||||
field_to_json(Obj,"commonName", commonName);
|
||||
field_to_json(Obj,"certificateId", certificateId);
|
||||
field_to_json(Obj,"batch", batch);
|
||||
field_to_json(Obj,"created", created);
|
||||
field_to_json(Obj,"modified", modified);
|
||||
field_to_json(Obj,"revoked", revoked);
|
||||
field_to_json(Obj,"revokeCount", revokeCount);
|
||||
}
|
||||
namespace OpenWifi::CertObjects {
|
||||
void CertificateEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"id", id);
|
||||
field_to_json(Obj,"entity", entity);
|
||||
field_to_json(Obj,"creator", creator);
|
||||
field_to_json(Obj,"type", type);
|
||||
field_to_json(Obj,"status", status);
|
||||
field_to_json(Obj,"certificate", certificate);
|
||||
field_to_json(Obj,"key", key);
|
||||
field_to_json(Obj,"devid", devid);
|
||||
field_to_json(Obj,"cas", cas);
|
||||
field_to_json(Obj,"manufacturer", manufacturer);
|
||||
field_to_json(Obj,"model", model);
|
||||
field_to_json(Obj,"redirector", redirector);
|
||||
field_to_json(Obj,"commonName", commonName);
|
||||
field_to_json(Obj,"certificateId", certificateId);
|
||||
field_to_json(Obj,"batch", batch);
|
||||
field_to_json(Obj,"created", created);
|
||||
field_to_json(Obj,"modified", modified);
|
||||
field_to_json(Obj,"revoked", revoked);
|
||||
field_to_json(Obj,"revokeCount", revokeCount);
|
||||
field_to_json(Obj,"synched", synched);
|
||||
}
|
||||
|
||||
bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"id", id);
|
||||
field_from_json(Obj,"entity", entity);
|
||||
field_from_json(Obj,"creator", creator);
|
||||
field_from_json(Obj,"type", type);
|
||||
field_from_json(Obj,"status", status);
|
||||
field_from_json(Obj,"certificate", certificate);
|
||||
field_from_json(Obj,"key", key);
|
||||
field_from_json(Obj,"devid", devid);
|
||||
field_from_json(Obj,"cas", cas);
|
||||
field_from_json(Obj,"manufacturer", manufacturer);
|
||||
field_from_json(Obj,"model", model);
|
||||
field_from_json(Obj,"redirector", redirector);
|
||||
field_from_json(Obj,"commonName", commonName);
|
||||
field_from_json(Obj,"certificateId", certificateId);
|
||||
field_from_json(Obj,"batch", batch);
|
||||
field_from_json(Obj,"created", created);
|
||||
field_from_json(Obj,"modified", modified);
|
||||
field_from_json(Obj,"revoked", revoked);
|
||||
field_from_json(Obj,"revokeCount", revokeCount);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"id", id);
|
||||
field_from_json(Obj,"entity", entity);
|
||||
field_from_json(Obj,"creator", creator);
|
||||
field_from_json(Obj,"type", type);
|
||||
field_from_json(Obj,"status", status);
|
||||
field_from_json(Obj,"certificate", certificate);
|
||||
field_from_json(Obj,"key", key);
|
||||
field_from_json(Obj,"devid", devid);
|
||||
field_from_json(Obj,"cas", cas);
|
||||
field_from_json(Obj,"manufacturer", manufacturer);
|
||||
field_from_json(Obj,"model", model);
|
||||
field_from_json(Obj,"redirector", redirector);
|
||||
field_from_json(Obj,"commonName", commonName);
|
||||
field_from_json(Obj,"certificateId", certificateId);
|
||||
field_from_json(Obj,"batch", batch);
|
||||
field_from_json(Obj,"created", created);
|
||||
field_from_json(Obj,"modified", modified);
|
||||
field_from_json(Obj,"revoked", revoked);
|
||||
field_from_json(Obj,"revokeCount", revokeCount);
|
||||
field_from_json(Obj,"synched", synched);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EntityEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"id", id);
|
||||
field_to_json(Obj,"creator", creator);
|
||||
field_to_json(Obj,"name", name);
|
||||
field_to_json(Obj,"description", description);
|
||||
field_to_json(Obj,"defaultRedirector", defaultRedirector);
|
||||
field_to_json(Obj,"apiKey", apiKey);
|
||||
field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
|
||||
field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
|
||||
field_to_json(Obj,"organization", organization);
|
||||
field_to_json(Obj,"created", created);
|
||||
field_to_json(Obj,"modified", modified);
|
||||
field_to_json(Obj,"suspended", suspended);
|
||||
field_to_json(Obj,"deleted", deleted);
|
||||
field_to_json(Obj,"notes", notes);
|
||||
}
|
||||
void EntityEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"id", id);
|
||||
field_to_json(Obj,"creator", creator);
|
||||
field_to_json(Obj,"name", name);
|
||||
field_to_json(Obj,"description", description);
|
||||
field_to_json(Obj,"defaultRedirector", defaultRedirector);
|
||||
field_to_json(Obj,"apiKey", apiKey);
|
||||
field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
|
||||
field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
|
||||
field_to_json(Obj,"organization", organization);
|
||||
field_to_json(Obj,"created", created);
|
||||
field_to_json(Obj,"modified", modified);
|
||||
field_to_json(Obj,"suspended", suspended);
|
||||
field_to_json(Obj,"deleted", deleted);
|
||||
field_to_json(Obj,"notes", notes);
|
||||
}
|
||||
|
||||
bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"id", id);
|
||||
field_from_json(Obj,"creator", creator);
|
||||
field_from_json(Obj,"name", name);
|
||||
field_from_json(Obj,"description", description);
|
||||
field_from_json(Obj,"defaultRedirector", defaultRedirector);
|
||||
field_from_json(Obj,"apiKey", apiKey);
|
||||
field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
|
||||
field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
|
||||
field_from_json(Obj,"organization", organization);
|
||||
field_from_json(Obj,"created", created);
|
||||
field_from_json(Obj,"modified", modified);
|
||||
field_from_json(Obj,"suspended", suspended);
|
||||
field_from_json(Obj,"deleted", deleted);
|
||||
field_from_json(Obj,"notes", notes);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"id", id);
|
||||
field_from_json(Obj,"creator", creator);
|
||||
field_from_json(Obj,"name", name);
|
||||
field_from_json(Obj,"description", description);
|
||||
field_from_json(Obj,"defaultRedirector", defaultRedirector);
|
||||
field_from_json(Obj,"apiKey", apiKey);
|
||||
field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
|
||||
field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
|
||||
field_from_json(Obj,"organization", organization);
|
||||
field_from_json(Obj,"created", created);
|
||||
field_from_json(Obj,"modified", modified);
|
||||
field_from_json(Obj,"suspended", suspended);
|
||||
field_from_json(Obj,"deleted", deleted);
|
||||
field_from_json(Obj,"notes", notes);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BatchEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"id", id);
|
||||
field_to_json(Obj,"entity", entity);
|
||||
field_to_json(Obj,"creator", creator);
|
||||
field_to_json(Obj,"name", name);
|
||||
field_to_json(Obj,"description", description);
|
||||
field_to_json(Obj,"manufacturer", manufacturer);
|
||||
field_to_json(Obj,"model", model);
|
||||
field_to_json(Obj,"redirector", redirector);
|
||||
field_to_json(Obj,"commonNames", commonNames);
|
||||
field_to_json(Obj,"jobHistory", jobHistory);
|
||||
field_to_json(Obj,"notes", notes);
|
||||
field_to_json(Obj,"submitted", submitted);
|
||||
field_to_json(Obj,"started", started);
|
||||
field_to_json(Obj,"completed", completed);
|
||||
field_to_json(Obj,"modified", modified);
|
||||
}
|
||||
void BatchEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"id", id);
|
||||
field_to_json(Obj,"entity", entity);
|
||||
field_to_json(Obj,"creator", creator);
|
||||
field_to_json(Obj,"name", name);
|
||||
field_to_json(Obj,"description", description);
|
||||
field_to_json(Obj,"manufacturer", manufacturer);
|
||||
field_to_json(Obj,"model", model);
|
||||
field_to_json(Obj,"redirector", redirector);
|
||||
field_to_json(Obj,"commonNames", commonNames);
|
||||
field_to_json(Obj,"jobHistory", jobHistory);
|
||||
field_to_json(Obj,"notes", notes);
|
||||
field_to_json(Obj,"submitted", submitted);
|
||||
field_to_json(Obj,"started", started);
|
||||
field_to_json(Obj,"completed", completed);
|
||||
field_to_json(Obj,"modified", modified);
|
||||
}
|
||||
|
||||
bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"id", id);
|
||||
field_from_json(Obj,"entity", entity);
|
||||
field_from_json(Obj,"creator", creator);
|
||||
field_from_json(Obj,"name", name);
|
||||
field_from_json(Obj,"description", description);
|
||||
field_from_json(Obj,"manufacturer", manufacturer);
|
||||
field_from_json(Obj,"model", model);
|
||||
field_from_json(Obj,"redirector", redirector);
|
||||
field_from_json(Obj,"commonNames", commonNames);
|
||||
field_from_json(Obj,"jobHistory", jobHistory);
|
||||
field_from_json(Obj,"notes", notes);
|
||||
field_from_json(Obj,"submitted", submitted);
|
||||
field_from_json(Obj,"started", started);
|
||||
field_from_json(Obj,"completed", completed);
|
||||
field_from_json(Obj,"modified", modified);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"id", id);
|
||||
field_from_json(Obj,"entity", entity);
|
||||
field_from_json(Obj,"creator", creator);
|
||||
field_from_json(Obj,"name", name);
|
||||
field_from_json(Obj,"description", description);
|
||||
field_from_json(Obj,"manufacturer", manufacturer);
|
||||
field_from_json(Obj,"model", model);
|
||||
field_from_json(Obj,"redirector", redirector);
|
||||
field_from_json(Obj,"commonNames", commonNames);
|
||||
field_from_json(Obj,"jobHistory", jobHistory);
|
||||
field_from_json(Obj,"notes", notes);
|
||||
field_from_json(Obj,"submitted", submitted);
|
||||
field_from_json(Obj,"started", started);
|
||||
field_from_json(Obj,"completed", completed);
|
||||
field_from_json(Obj,"modified", modified);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void JobEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"id", id);
|
||||
field_to_json(Obj,"entity", entity);
|
||||
field_to_json(Obj,"creator", creator);
|
||||
field_to_json(Obj,"batch", batch);
|
||||
field_to_json(Obj,"commonNames", commonNames);
|
||||
field_to_json(Obj,"completedNames", completedNames);
|
||||
field_to_json(Obj,"errorNames", errorNames);
|
||||
field_to_json(Obj,"status", status);
|
||||
field_to_json(Obj,"command", command);
|
||||
field_to_json(Obj,"parameters", parameters);
|
||||
field_to_json(Obj,"submitted", submitted);
|
||||
field_to_json(Obj,"started", started);
|
||||
field_to_json(Obj,"completed", completed);
|
||||
}
|
||||
void JobEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"id", id);
|
||||
field_to_json(Obj,"entity", entity);
|
||||
field_to_json(Obj,"creator", creator);
|
||||
field_to_json(Obj,"batch", batch);
|
||||
field_to_json(Obj,"commonNames", commonNames);
|
||||
field_to_json(Obj,"completedNames", completedNames);
|
||||
field_to_json(Obj,"errorNames", errorNames);
|
||||
field_to_json(Obj,"status", status);
|
||||
field_to_json(Obj,"command", command);
|
||||
field_to_json(Obj,"parameters", parameters);
|
||||
field_to_json(Obj,"submitted", submitted);
|
||||
field_to_json(Obj,"started", started);
|
||||
field_to_json(Obj,"completed", completed);
|
||||
}
|
||||
|
||||
bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"id", id);
|
||||
field_from_json(Obj,"entity", entity);
|
||||
field_from_json(Obj,"creator", creator);
|
||||
field_from_json(Obj,"batch", batch);
|
||||
field_from_json(Obj,"commonNames", commonNames);
|
||||
field_from_json(Obj,"completedNames", completedNames);
|
||||
field_from_json(Obj,"errorNames", errorNames);
|
||||
field_from_json(Obj,"status", status);
|
||||
field_from_json(Obj,"command", command);
|
||||
field_from_json(Obj,"parameters", parameters);
|
||||
field_from_json(Obj,"submitted", submitted);
|
||||
field_from_json(Obj,"started", started);
|
||||
field_from_json(Obj,"completed", completed);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"id", id);
|
||||
field_from_json(Obj,"entity", entity);
|
||||
field_from_json(Obj,"creator", creator);
|
||||
field_from_json(Obj,"batch", batch);
|
||||
field_from_json(Obj,"commonNames", commonNames);
|
||||
field_from_json(Obj,"completedNames", completedNames);
|
||||
field_from_json(Obj,"errorNames", errorNames);
|
||||
field_from_json(Obj,"status", status);
|
||||
field_from_json(Obj,"command", command);
|
||||
field_from_json(Obj,"parameters", parameters);
|
||||
field_from_json(Obj,"submitted", submitted);
|
||||
field_from_json(Obj,"started", started);
|
||||
field_from_json(Obj,"completed", completed);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DashBoardYearlyStats::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "year", year);
|
||||
field_to_json(Obj, "activeCerts", activeCerts);
|
||||
field_to_json(Obj, "revokedCerts", revokedCerts);
|
||||
}
|
||||
|
||||
void Dashboard::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"snapshot", snapshot);
|
||||
field_to_json(Obj,"numberOfIssuedCerts", numberOfIssuedCerts);
|
||||
field_to_json(Obj,"numberOfRevokedCerts", numberOfRevokedCerts);
|
||||
field_to_json(Obj,"activeCertsPerOrganization", activeCertsPerOrganization);
|
||||
field_to_json(Obj,"revokedCertsPerOrganization", revokedCertsPerOrganization);
|
||||
field_to_json(Obj,"numberOfRedirectors", numberOfRedirectors);
|
||||
field_to_json(Obj,"deviceTypes", deviceTypes);
|
||||
field_to_json(Obj,"monthlyNumberOfCerts", monthlyNumberOfCerts);
|
||||
field_to_json(Obj,"monthlyNumberOfCertsPerOrgPerYear", monthlyNumberOfCertsPerOrgPerYear);
|
||||
}
|
||||
|
||||
void Dashboard::reset() {
|
||||
snapshot=0;
|
||||
numberOfRevokedCerts = numberOfIssuedCerts = 0;
|
||||
activeCertsPerOrganization.clear();
|
||||
revokedCertsPerOrganization.clear();
|
||||
numberOfRedirectors.clear();
|
||||
deviceTypes.clear();
|
||||
monthlyNumberOfCerts.clear();
|
||||
monthlyNumberOfCertsPerOrgPerYear.clear();
|
||||
}
|
||||
}
|
||||
@@ -5,97 +5,118 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
namespace OpenWifi::CertObjects {
|
||||
|
||||
namespace CertObjects {
|
||||
struct CertificateEntry {
|
||||
OpenWifi::Types::UUID_t id;
|
||||
OpenWifi::Types::UUID_t entity;
|
||||
OpenWifi::Types::UUID_t creator;
|
||||
std::string type;
|
||||
std::string status;
|
||||
std::string certificate;
|
||||
std::string key;
|
||||
std::string devid;
|
||||
std::string cas;
|
||||
std::string manufacturer;
|
||||
std::string model;
|
||||
std::string redirector;
|
||||
std::string commonName;
|
||||
std::string certificateId;
|
||||
OpenWifi::Types::UUID_t batch;
|
||||
uint64_t created = 0;
|
||||
uint64_t modified = 0;
|
||||
uint64_t revoked = 0;
|
||||
uint64_t revokeCount = 0;
|
||||
uint64_t synched = 0;
|
||||
|
||||
struct CertificateEntry {
|
||||
OpenWifi::Types::UUID_t id;
|
||||
OpenWifi::Types::UUID_t entity;
|
||||
OpenWifi::Types::UUID_t creator;
|
||||
std::string type;
|
||||
std::string status;
|
||||
std::string certificate;
|
||||
std::string key;
|
||||
std::string devid;
|
||||
std::string cas;
|
||||
std::string manufacturer;
|
||||
std::string model;
|
||||
std::string redirector;
|
||||
std::string commonName;
|
||||
std::string certificateId;
|
||||
OpenWifi::Types::UUID_t batch;
|
||||
uint64_t created = 0;
|
||||
uint64_t modified = 0;
|
||||
uint64_t revoked = 0;
|
||||
uint64_t revokeCount = 0;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct EntityEntry {
|
||||
OpenWifi::Types::UUID_t id;
|
||||
OpenWifi::Types::UUID_t creator;
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string defaultRedirector;
|
||||
std::string apiKey;
|
||||
std::string serverEnrollmentProfile;
|
||||
std::string clientEnrollmentProfile;
|
||||
std::string organization;
|
||||
SecurityObjects::NoteInfoVec notes;
|
||||
bool suspended=false;
|
||||
bool deleted=false;
|
||||
uint64_t created = 0 ;
|
||||
uint64_t modified = 0 ;
|
||||
|
||||
struct EntityEntry {
|
||||
OpenWifi::Types::UUID_t id;
|
||||
OpenWifi::Types::UUID_t creator;
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string defaultRedirector;
|
||||
std::string apiKey;
|
||||
std::string serverEnrollmentProfile;
|
||||
std::string clientEnrollmentProfile;
|
||||
std::string organization;
|
||||
SecurityObjects::NoteInfoVec notes;
|
||||
bool suspended=false;
|
||||
bool deleted=false;
|
||||
uint64_t created = 0 ;
|
||||
uint64_t modified = 0 ;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct BatchEntry {
|
||||
OpenWifi::Types::UUID_t id;
|
||||
OpenWifi::Types::UUID_t entity;
|
||||
OpenWifi::Types::UUID_t creator;
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string manufacturer;
|
||||
std::string model;
|
||||
std::string redirector;
|
||||
std::vector<std::string> commonNames;
|
||||
std::vector<std::string> jobHistory;
|
||||
SecurityObjects::NoteInfoVec notes;
|
||||
uint64_t submitted = 0 ;
|
||||
uint64_t started = 0 ;
|
||||
uint64_t completed = 0 ;
|
||||
uint64_t modified = 0 ;
|
||||
|
||||
struct BatchEntry {
|
||||
OpenWifi::Types::UUID_t id;
|
||||
OpenWifi::Types::UUID_t entity;
|
||||
OpenWifi::Types::UUID_t creator;
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string manufacturer;
|
||||
std::string model;
|
||||
std::string redirector;
|
||||
std::vector<std::string> commonNames;
|
||||
std::vector<std::string> jobHistory;
|
||||
SecurityObjects::NoteInfoVec notes;
|
||||
uint64_t submitted = 0 ;
|
||||
uint64_t started = 0 ;
|
||||
uint64_t completed = 0 ;
|
||||
uint64_t modified = 0 ;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct JobEntry {
|
||||
OpenWifi::Types::UUID_t id;
|
||||
OpenWifi::Types::UUID_t entity;
|
||||
OpenWifi::Types::UUID_t creator;
|
||||
OpenWifi::Types::UUID_t batch;
|
||||
std::string command;
|
||||
OpenWifi::Types::StringVec commonNames;
|
||||
OpenWifi::Types::StringVec completedNames;
|
||||
OpenWifi::Types::StringVec errorNames;
|
||||
Types::StringPairVec parameters;
|
||||
std::string status;
|
||||
uint64_t submitted=0;
|
||||
uint64_t started=0;
|
||||
uint64_t completed=0;
|
||||
|
||||
struct JobEntry {
|
||||
OpenWifi::Types::UUID_t id;
|
||||
OpenWifi::Types::UUID_t entity;
|
||||
OpenWifi::Types::UUID_t creator;
|
||||
OpenWifi::Types::UUID_t batch;
|
||||
std::string command;
|
||||
OpenWifi::Types::StringVec commonNames;
|
||||
OpenWifi::Types::StringVec completedNames;
|
||||
OpenWifi::Types::StringVec errorNames;
|
||||
Types::StringPairVec parameters;
|
||||
std::string status;
|
||||
uint64_t submitted=0;
|
||||
uint64_t started=0;
|
||||
uint64_t completed=0;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct DashBoardYearlyStats {
|
||||
uint64_t year=0;
|
||||
OpenWifi::Types::Counted3DMapSII activeCerts;
|
||||
OpenWifi::Types::Counted3DMapSII revokedCerts;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
|
||||
struct Dashboard {
|
||||
uint64_t snapshot=0;
|
||||
uint64_t numberOfIssuedCerts=0;
|
||||
uint64_t numberOfRevokedCerts=0;
|
||||
OpenWifi::Types::CountedMap activeCertsPerOrganization;
|
||||
OpenWifi::Types::CountedMap revokedCertsPerOrganization;
|
||||
OpenWifi::Types::CountedMap numberOfRedirectors;
|
||||
OpenWifi::Types::CountedMap deviceTypes;
|
||||
OpenWifi::Types::CountedMap monthlyNumberOfCerts;
|
||||
std::vector<DashBoardYearlyStats> monthlyNumberOfCertsPerOrgPerYear;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
void reset();
|
||||
};
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -233,10 +233,10 @@ namespace OpenWifi::FMSObjects {
|
||||
UnknownFirmwares_.clear();
|
||||
totalSecondsOld_.clear();
|
||||
numberOfDevices = 0 ;
|
||||
snapshot = std::time(nullptr);
|
||||
snapshot = OpenWifi::Now();
|
||||
}
|
||||
|
||||
bool DeviceReport::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
bool DeviceReport::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
|
||||
return true;
|
||||
@@ -273,4 +273,37 @@ namespace OpenWifi::FMSObjects {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeviceCurrentInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "serialNumber",serialNumber);
|
||||
field_to_json(Obj, "revision", revision);
|
||||
field_to_json(Obj, "upgraded", upgraded);
|
||||
}
|
||||
|
||||
bool DeviceCurrentInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "serialNumber",serialNumber);
|
||||
field_from_json(Obj, "revision", revision);
|
||||
field_from_json(Obj, "upgraded", upgraded);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeviceCurrentInfoList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "devices",devices);
|
||||
}
|
||||
|
||||
bool DeviceCurrentInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "devices",devices);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifndef UCENTRALFMS_RESTAPI_FMSOBJECTS_H
|
||||
#define UCENTRALFMS_RESTAPI_FMSOBJECTS_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RESTAPI_SecurityObjects.h"
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
@@ -29,7 +27,7 @@ namespace OpenWifi::FMSObjects {
|
||||
std::string location;
|
||||
std::string uploader;
|
||||
std::string digest;
|
||||
bool latest=0;
|
||||
bool latest=false;
|
||||
SecurityObjects::NoteInfoVec notes;
|
||||
uint64_t created=0;
|
||||
|
||||
@@ -141,7 +139,21 @@ namespace OpenWifi::FMSObjects {
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct DeviceCurrentInfo {
|
||||
std::string serialNumber;
|
||||
std::string revision;
|
||||
uint64_t upgraded=0;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct DeviceCurrentInfoList {
|
||||
std::vector<DeviceCurrentInfo> devices;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif //UCENTRALFMS_RESTAPI_FMSOBJECTS_H
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace OpenWifi::GWObjects {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Device::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool Device::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"serialNumber",SerialNumber);
|
||||
field_from_json(Obj,"deviceType",DeviceType);
|
||||
@@ -156,7 +156,7 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj,"executionTime", executionTime);
|
||||
}
|
||||
|
||||
bool DefaultConfiguration::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"name",Name);
|
||||
field_from_json(Obj,"configuration",Configuration);
|
||||
@@ -175,7 +175,7 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj,"created", created);
|
||||
}
|
||||
|
||||
bool BlackListedDevice::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool BlackListedDevice::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"serialNumber",serialNumber);
|
||||
field_from_json(Obj,"author",author);
|
||||
@@ -264,7 +264,7 @@ namespace OpenWifi::GWObjects {
|
||||
lastContact.clear();
|
||||
associations.clear();
|
||||
numberOfDevices = 0 ;
|
||||
snapshot = std::time(nullptr);
|
||||
snapshot = OpenWifi::Now();
|
||||
}
|
||||
|
||||
void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const{
|
||||
@@ -272,5 +272,120 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj,"capabilities", capabilities);
|
||||
};
|
||||
|
||||
void ScriptRequest::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"serialNumber",serialNumber);
|
||||
field_to_json(Obj,"timeout",timeout);
|
||||
field_to_json(Obj,"type",type);
|
||||
field_to_json(Obj,"script",script);
|
||||
field_to_json(Obj,"scriptId",scriptId);
|
||||
field_to_json(Obj,"when",when);
|
||||
}
|
||||
|
||||
bool ScriptRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"serialNumber",serialNumber);
|
||||
field_from_json(Obj,"timeout",timeout);
|
||||
field_from_json(Obj,"type",type);
|
||||
field_from_json(Obj,"script",script);
|
||||
field_from_json(Obj,"scriptId",scriptId);
|
||||
field_from_json(Obj,"when",when);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
void RadiusProxyPoolList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"pools",pools);
|
||||
}
|
||||
|
||||
bool RadiusProxyPoolList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"pools",pools);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RadiusProxyPool::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"name",name);
|
||||
field_to_json(Obj,"description",description);
|
||||
field_to_json(Obj,"authConfig",authConfig);
|
||||
field_to_json(Obj,"acctConfig",acctConfig);
|
||||
field_to_json(Obj,"coaConfig",coaConfig);
|
||||
field_to_json(Obj,"useByDefault",useByDefault);
|
||||
}
|
||||
|
||||
bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"name",name);
|
||||
field_from_json(Obj,"description",description);
|
||||
field_from_json(Obj,"authConfig",authConfig);
|
||||
field_from_json(Obj,"acctConfig",acctConfig);
|
||||
field_from_json(Obj,"coaConfig",coaConfig);
|
||||
field_from_json(Obj,"useByDefault",useByDefault);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RadiusProxyServerConfig::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"strategy",strategy);
|
||||
field_to_json(Obj,"monitor",monitor);
|
||||
field_to_json(Obj,"monitorMethod",monitorMethod);
|
||||
field_to_json(Obj,"methodParameters",methodParameters);
|
||||
field_to_json(Obj,"servers",servers);
|
||||
}
|
||||
|
||||
bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"strategy",strategy);
|
||||
field_from_json(Obj,"monitor",monitor);
|
||||
field_from_json(Obj,"monitorMethod",monitorMethod);
|
||||
field_from_json(Obj,"methodParameters",methodParameters);
|
||||
field_from_json(Obj,"servers",servers);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RadiusProxyServerEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"name",name);
|
||||
field_to_json(Obj,"ip",ip);
|
||||
field_to_json(Obj,"port",port);
|
||||
field_to_json(Obj,"weight",weight);
|
||||
field_to_json(Obj,"secret",secret);
|
||||
field_to_json(Obj,"certificate",certificate);
|
||||
field_to_json(Obj,"radsec",radsec);
|
||||
field_to_json(Obj,"radsec_secret",radsec_secret);
|
||||
field_to_json(Obj,"radsec_port",radsec_port);
|
||||
field_to_json(Obj,"radsec_cacerts",radsec_cacerts);
|
||||
field_to_json(Obj,"radsec_cert",radsec_cert);
|
||||
field_to_json(Obj,"radsec_key",radsec_key);
|
||||
}
|
||||
|
||||
bool RadiusProxyServerEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"name",name);
|
||||
field_from_json(Obj,"ip",ip);
|
||||
field_from_json(Obj,"port",port);
|
||||
field_from_json(Obj,"weight",weight);
|
||||
field_from_json(Obj,"secret",secret);
|
||||
field_from_json(Obj,"certificate",certificate);
|
||||
field_from_json(Obj,"radsec",radsec);
|
||||
field_from_json(Obj,"radsec_port",radsec_port);
|
||||
field_from_json(Obj,"radsec_secret",radsec_secret);
|
||||
field_from_json(Obj,"radsec_cacerts",radsec_cacerts);
|
||||
field_from_json(Obj,"radsec_cert",radsec_cert);
|
||||
field_from_json(Obj,"radsec_key",radsec_key);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace OpenWifi::GWObjects {
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
void to_json_with_status(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
void Print() const;
|
||||
};
|
||||
|
||||
@@ -124,7 +124,7 @@ namespace OpenWifi::GWObjects {
|
||||
uint64_t Created;
|
||||
uint64_t LastModified;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct CommandDetails {
|
||||
@@ -156,7 +156,7 @@ namespace OpenWifi::GWObjects {
|
||||
std::string author;
|
||||
uint64_t created;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct RttySessionDetails {
|
||||
@@ -199,4 +199,63 @@ namespace OpenWifi::GWObjects {
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
|
||||
struct ScriptRequest {
|
||||
uint64_t timeout=30;
|
||||
std::string serialNumber;
|
||||
std::string type;
|
||||
std::string script;
|
||||
std::string scriptId;
|
||||
uint64_t when=0;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct RadiusProxyServerEntry {
|
||||
std::string name;
|
||||
std::string ip;
|
||||
uint16_t port=0;
|
||||
uint64_t weight=0;
|
||||
std::string secret;
|
||||
std::string certificate;
|
||||
bool radsec=false;
|
||||
uint16_t radsec_port=2084;
|
||||
std::string radsec_secret;
|
||||
std::string radsec_key;
|
||||
std::string radsec_cert;
|
||||
std::string radsec_cacerts;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct RadiusProxyServerConfig {
|
||||
std::string strategy;
|
||||
bool monitor=false;
|
||||
std::string monitorMethod;
|
||||
std::vector<std::string> methodParameters;
|
||||
std::vector<RadiusProxyServerEntry> servers;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct RadiusProxyPool {
|
||||
std::string name;
|
||||
std::string description;
|
||||
RadiusProxyServerConfig authConfig;
|
||||
RadiusProxyServerConfig acctConfig;
|
||||
RadiusProxyServerConfig coaConfig;
|
||||
bool useByDefault=false;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct RadiusProxyPoolList {
|
||||
std::vector<RadiusProxyPool> pools;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ namespace OpenWifi::ProvObjects {
|
||||
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||
field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
|
||||
field_to_json( Obj,"devices",devices);
|
||||
field_to_json( Obj,"rrm",rrm);
|
||||
field_to_json( Obj,"deviceRules",deviceRules);
|
||||
field_to_json( Obj,"sourceIP",sourceIP);
|
||||
field_to_json( Obj,"variables", variables);
|
||||
field_to_json( Obj,"managementPolicies", managementPolicies);
|
||||
@@ -111,7 +111,7 @@ namespace OpenWifi::ProvObjects {
|
||||
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||
field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
|
||||
field_from_json( Obj,"devices",devices);
|
||||
field_from_json( Obj,"rrm",rrm);
|
||||
field_from_json( Obj,"deviceRules",deviceRules);
|
||||
field_from_json( Obj,"sourceIP",sourceIP);
|
||||
field_from_json( Obj,"variables", variables);
|
||||
field_from_json( Obj,"managementPolicies", managementPolicies);
|
||||
@@ -154,13 +154,14 @@ namespace OpenWifi::ProvObjects {
|
||||
field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
|
||||
field_to_json( Obj,"contacts",contacts);
|
||||
field_to_json( Obj,"location",location);
|
||||
field_to_json( Obj,"rrm",rrm);
|
||||
field_to_json( Obj,"deviceRules",deviceRules);
|
||||
field_to_json( Obj,"sourceIP",sourceIP);
|
||||
field_to_json( Obj,"variables", variables);
|
||||
field_to_json( Obj,"managementPolicies", managementPolicies);
|
||||
field_to_json( Obj,"managementRoles", managementRoles);
|
||||
field_to_json( Obj,"maps", maps);
|
||||
field_to_json( Obj,"configurations", configurations);
|
||||
field_to_json( Obj,"boards", boards);
|
||||
}
|
||||
|
||||
bool Venue::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
@@ -177,13 +178,14 @@ namespace OpenWifi::ProvObjects {
|
||||
field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
|
||||
field_from_json( Obj,"contacts",contacts);
|
||||
field_from_json( Obj,"location",location);
|
||||
field_from_json( Obj,"rrm",rrm);
|
||||
field_from_json( Obj,"deviceRules",deviceRules);
|
||||
field_from_json( Obj,"sourceIP",sourceIP);
|
||||
field_from_json( Obj,"variables", variables);
|
||||
field_from_json( Obj,"managementPolicies", managementPolicies);
|
||||
field_from_json( Obj,"managementRoles", managementRoles);
|
||||
field_from_json( Obj,"maps", maps);
|
||||
field_from_json( Obj,"configurations", configurations);
|
||||
field_from_json( Obj,"boards", boards);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
@@ -191,6 +193,89 @@ namespace OpenWifi::ProvObjects {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Operator::to_json(Poco::JSON::Object &Obj) const {
|
||||
info.to_json(Obj);
|
||||
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||
field_to_json( Obj,"managementRoles",managementRoles);
|
||||
field_to_json( Obj,"deviceRules",deviceRules);
|
||||
field_to_json( Obj,"variables",variables);
|
||||
field_to_json( Obj,"defaultOperator",defaultOperator);
|
||||
field_to_json( Obj,"sourceIP",sourceIP);
|
||||
field_to_json( Obj,"registrationId",registrationId);
|
||||
}
|
||||
|
||||
bool Operator::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
info.from_json(Obj);
|
||||
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||
field_from_json( Obj,"managementRoles",managementRoles);
|
||||
field_from_json( Obj,"deviceRules",deviceRules);
|
||||
field_from_json( Obj,"variables",variables);
|
||||
field_from_json( Obj,"defaultOperator",defaultOperator);
|
||||
field_from_json( Obj,"sourceIP",sourceIP);
|
||||
field_from_json( Obj,"registrationId",registrationId);
|
||||
return true;
|
||||
} catch(...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void OperatorList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json( Obj,"operators",operators);
|
||||
}
|
||||
|
||||
bool OperatorList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json( Obj,"operators",operators);
|
||||
return true;
|
||||
} catch(...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ServiceClass::to_json(Poco::JSON::Object &Obj) const {
|
||||
info.to_json(Obj);
|
||||
field_to_json( Obj,"operatorId",operatorId);
|
||||
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||
field_to_json( Obj,"cost",cost);
|
||||
field_to_json( Obj,"currency",currency);
|
||||
field_to_json( Obj,"period",period);
|
||||
field_to_json( Obj,"billingCode",billingCode);
|
||||
field_to_json( Obj,"variables",variables);
|
||||
field_to_json( Obj,"defaultService",defaultService);
|
||||
}
|
||||
|
||||
bool ServiceClass::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
info.from_json(Obj);
|
||||
field_from_json( Obj,"operatorId",operatorId);
|
||||
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||
field_from_json( Obj,"cost",cost);
|
||||
field_from_json( Obj,"currency",currency);
|
||||
field_from_json( Obj,"period",period);
|
||||
field_from_json( Obj,"billingCode",billingCode);
|
||||
field_from_json( Obj,"variables",variables);
|
||||
field_from_json( Obj,"defaultService",defaultService);
|
||||
return true;
|
||||
} catch(...) {
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
void ServiceClassList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json( Obj,"serviceClasses",serviceClasses);
|
||||
}
|
||||
|
||||
bool ServiceClassList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json( Obj,"serviceClasses",serviceClasses);
|
||||
return true;
|
||||
} catch(...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void UserInfoDigest::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json( Obj,"id",id);
|
||||
field_to_json( Obj,"entity",loginId);
|
||||
@@ -271,6 +356,92 @@ namespace OpenWifi::ProvObjects {
|
||||
return false;
|
||||
}
|
||||
|
||||
void OperatorLocation::to_json(Poco::JSON::Object &Obj) const {
|
||||
info.to_json(Obj);
|
||||
field_to_json( Obj,"type",type);
|
||||
field_to_json( Obj,"buildingName",buildingName);
|
||||
field_to_json( Obj,"addressLines",addressLines);
|
||||
field_to_json( Obj,"city",city);
|
||||
field_to_json( Obj,"state",state);
|
||||
field_to_json( Obj,"postal",postal);
|
||||
field_to_json( Obj,"country",country);
|
||||
field_to_json( Obj,"phones",phones);
|
||||
field_to_json( Obj,"mobiles",mobiles);
|
||||
field_to_json( Obj,"geoCode",geoCode);
|
||||
field_to_json( Obj,"operatorId",operatorId);
|
||||
field_to_json( Obj,"subscriberDeviceId",subscriberDeviceId);
|
||||
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||
}
|
||||
|
||||
bool OperatorLocation::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
info.from_json(Obj);
|
||||
field_from_json( Obj,"type", type);
|
||||
field_from_json( Obj,"buildingName",buildingName);
|
||||
field_from_json( Obj,"addressLines",addressLines);
|
||||
field_from_json( Obj,"city",city);
|
||||
field_from_json( Obj,"state",state);
|
||||
field_from_json( Obj,"postal",postal);
|
||||
field_from_json( Obj,"country",country);
|
||||
field_from_json( Obj,"phones",phones);
|
||||
field_from_json( Obj,"mobiles",mobiles);
|
||||
field_from_json( Obj,"geoCode",geoCode);
|
||||
field_from_json( Obj,"operatorId",operatorId);
|
||||
field_from_json( Obj,"subscriberDeviceId",subscriberDeviceId);
|
||||
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SubLocation::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json( Obj,"type",type);
|
||||
field_to_json( Obj,"buildingName",buildingName);
|
||||
field_to_json( Obj,"addressLines",addressLines);
|
||||
field_to_json( Obj,"city",city);
|
||||
field_to_json( Obj,"state",state);
|
||||
field_to_json( Obj,"postal",postal);
|
||||
field_to_json( Obj,"country",country);
|
||||
field_to_json( Obj,"phones",phones);
|
||||
field_to_json( Obj,"mobiles",mobiles);
|
||||
field_to_json( Obj,"geoCode",geoCode);
|
||||
}
|
||||
|
||||
bool SubLocation::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json( Obj,"type", type);
|
||||
field_from_json( Obj,"buildingName",buildingName);
|
||||
field_from_json( Obj,"addressLines",addressLines);
|
||||
field_from_json( Obj,"city",city);
|
||||
field_from_json( Obj,"state",state);
|
||||
field_from_json( Obj,"postal",postal);
|
||||
field_from_json( Obj,"country",country);
|
||||
field_from_json( Obj,"phones",phones);
|
||||
field_from_json( Obj,"mobiles",mobiles);
|
||||
field_from_json( Obj,"geoCode",geoCode);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void OperatorLocationList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json( Obj, "locations", locations);
|
||||
}
|
||||
|
||||
bool OperatorLocationList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json( Obj, "locations", locations);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Contact::to_json(Poco::JSON::Object &Obj) const {
|
||||
info.to_json(Obj);
|
||||
field_to_json( Obj,"type", to_string(type));
|
||||
@@ -317,6 +488,100 @@ namespace OpenWifi::ProvObjects {
|
||||
return false;
|
||||
}
|
||||
|
||||
void OperatorContact::to_json(Poco::JSON::Object &Obj) const {
|
||||
info.to_json(Obj);
|
||||
field_to_json( Obj,"type", type);
|
||||
field_to_json( Obj,"title",title);
|
||||
field_to_json( Obj,"salutation",salutation);
|
||||
field_to_json( Obj,"firstname",firstname);
|
||||
field_to_json( Obj,"lastname",lastname);
|
||||
field_to_json( Obj,"initials",initials);
|
||||
field_to_json( Obj,"visual",visual);
|
||||
field_to_json( Obj,"mobiles",mobiles);
|
||||
field_to_json( Obj,"phones",phones);
|
||||
field_to_json( Obj,"primaryEmail",primaryEmail);
|
||||
field_to_json( Obj,"secondaryEmail",secondaryEmail);
|
||||
field_to_json( Obj,"accessPIN",accessPIN);
|
||||
field_to_json( Obj,"operatorId",operatorId);
|
||||
field_to_json( Obj,"subscriberDeviceId",subscriberDeviceId);
|
||||
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||
}
|
||||
|
||||
bool OperatorContact::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
info.from_json(Obj);
|
||||
field_from_json( Obj,"type", type);
|
||||
field_from_json( Obj,"title",title);
|
||||
field_from_json( Obj,"salutation",salutation);
|
||||
field_from_json( Obj,"firstname",firstname);
|
||||
field_from_json( Obj,"lastname",lastname);
|
||||
field_from_json( Obj,"initials",initials);
|
||||
field_from_json( Obj,"visual",visual);
|
||||
field_from_json( Obj,"mobiles",mobiles);
|
||||
field_from_json( Obj,"phones",phones);
|
||||
field_from_json( Obj,"primaryEmail",primaryEmail);
|
||||
field_from_json( Obj,"secondaryEmail",secondaryEmail);
|
||||
field_from_json( Obj,"accessPIN",accessPIN);
|
||||
field_from_json( Obj,"operatorId",operatorId);
|
||||
field_from_json( Obj,"subscriberDeviceId",subscriberDeviceId);
|
||||
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SubContact::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json( Obj,"type", type);
|
||||
field_to_json( Obj,"title",title);
|
||||
field_to_json( Obj,"salutation",salutation);
|
||||
field_to_json( Obj,"firstname",firstname);
|
||||
field_to_json( Obj,"lastname",lastname);
|
||||
field_to_json( Obj,"initials",initials);
|
||||
field_to_json( Obj,"visual",visual);
|
||||
field_to_json( Obj,"mobiles",mobiles);
|
||||
field_to_json( Obj,"phones",phones);
|
||||
field_to_json( Obj,"primaryEmail",primaryEmail);
|
||||
field_to_json( Obj,"secondaryEmail",secondaryEmail);
|
||||
field_to_json( Obj,"accessPIN",accessPIN);
|
||||
}
|
||||
|
||||
bool SubContact::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json( Obj,"type", type);
|
||||
field_from_json( Obj,"title",title);
|
||||
field_from_json( Obj,"salutation",salutation);
|
||||
field_from_json( Obj,"firstname",firstname);
|
||||
field_from_json( Obj,"lastname",lastname);
|
||||
field_from_json( Obj,"initials",initials);
|
||||
field_from_json( Obj,"visual",visual);
|
||||
field_from_json( Obj,"mobiles",mobiles);
|
||||
field_from_json( Obj,"phones",phones);
|
||||
field_from_json( Obj,"primaryEmail",primaryEmail);
|
||||
field_from_json( Obj,"secondaryEmail",secondaryEmail);
|
||||
field_from_json( Obj,"accessPIN",accessPIN);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void OperatorContactList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json( Obj, "contacts", contacts);
|
||||
}
|
||||
|
||||
bool OperatorContactList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json( Obj, "contacts", contacts);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void InventoryTag::to_json(Poco::JSON::Object &Obj) const {
|
||||
info.to_json(Obj);
|
||||
field_to_json( Obj, "serialNumber", serialNumber);
|
||||
@@ -329,7 +594,7 @@ namespace OpenWifi::ProvObjects {
|
||||
field_to_json( Obj, "location", location);
|
||||
field_to_json( Obj, "contact", contact);
|
||||
field_to_json( Obj, "deviceConfiguration",deviceConfiguration);
|
||||
field_to_json( Obj, "rrm",rrm);
|
||||
field_to_json( Obj,"deviceRules",deviceRules);
|
||||
field_to_json( Obj, "managementPolicy",managementPolicy);
|
||||
field_to_json( Obj, "state",state);
|
||||
field_to_json( Obj, "devClass",devClass);
|
||||
@@ -350,7 +615,7 @@ namespace OpenWifi::ProvObjects {
|
||||
field_from_json( Obj,"location",location);
|
||||
field_from_json( Obj,"contact",contact);
|
||||
field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
|
||||
field_from_json( Obj,"rrm",rrm);
|
||||
field_from_json( Obj,"deviceRules",deviceRules);
|
||||
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||
field_from_json( Obj,"state",state);
|
||||
field_from_json( Obj,"devClass",devClass);
|
||||
@@ -421,16 +686,14 @@ namespace OpenWifi::ProvObjects {
|
||||
info.to_json(Obj);
|
||||
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||
field_to_json( Obj,"deviceTypes",deviceTypes);
|
||||
field_to_json( Obj,"configuration",configuration);
|
||||
field_to_json( Obj,"inUse",inUse);
|
||||
field_to_json( Obj,"variables",variables);
|
||||
field_to_json( Obj,"rrm",rrm);
|
||||
field_to_json( Obj,"firmwareUpgrade",firmwareUpgrade);
|
||||
field_to_json( Obj,"firmwareRCOnly",firmwareRCOnly);
|
||||
field_to_json( Obj,"subscriberOnly",subscriberOnly);
|
||||
field_to_json( Obj,"entity", entity);
|
||||
field_to_json( Obj,"venue", venue);
|
||||
field_to_json( Obj,"subscriber", subscriber);
|
||||
field_to_json( Obj,"configuration",configuration);
|
||||
field_to_json( Obj,"inUse",inUse);
|
||||
field_to_json( Obj,"variables",variables);
|
||||
field_to_json( Obj,"deviceRules",deviceRules);
|
||||
}
|
||||
|
||||
bool DeviceConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
@@ -438,16 +701,14 @@ namespace OpenWifi::ProvObjects {
|
||||
info.from_json(Obj);
|
||||
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||
field_from_json( Obj,"deviceTypes",deviceTypes);
|
||||
field_from_json( Obj,"configuration",configuration);
|
||||
field_from_json( Obj,"inUse",inUse);
|
||||
field_from_json( Obj,"variables",variables);
|
||||
field_from_json( Obj,"rrm",rrm);
|
||||
field_from_json( Obj,"firmwareUpgrade",firmwareUpgrade);
|
||||
field_from_json( Obj,"firmwareRCOnly",firmwareRCOnly);
|
||||
field_from_json( Obj,"subscriberOnly",subscriberOnly);
|
||||
field_from_json( Obj,"entity", entity);
|
||||
field_from_json( Obj,"venue", venue);
|
||||
field_from_json( Obj,"subscriber", subscriber);
|
||||
field_from_json( Obj,"configuration",configuration);
|
||||
field_from_json( Obj,"deviceRules",deviceRules);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
@@ -526,46 +787,16 @@ namespace OpenWifi::ProvObjects {
|
||||
return false;
|
||||
}
|
||||
|
||||
void field_to_json(Poco::JSON::Object &Obj, const char * FieldName, ACLACCESS A) {
|
||||
switch(A) {
|
||||
case READ: Obj.set(FieldName,"read"); break;
|
||||
case MODIFY: Obj.set(FieldName,"modify"); break;
|
||||
case CREATE: Obj.set(FieldName,"create"); break;
|
||||
case DELETE: Obj.set(FieldName,"delete"); break;
|
||||
case NONE:
|
||||
default:
|
||||
Obj.set(FieldName,"none");
|
||||
}
|
||||
}
|
||||
|
||||
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char * FieldName, ACLACCESS &A) {
|
||||
if(Obj->has(FieldName)) {
|
||||
auto V = Obj->getValue<std::string>(FieldName);
|
||||
if(V=="read")
|
||||
A = READ;
|
||||
else if(V=="modify")
|
||||
A = MODIFY;
|
||||
else if(V=="create")
|
||||
A = CREATE;
|
||||
else if(V=="delete")
|
||||
A = DELETE;
|
||||
else if(V=="none")
|
||||
A = NONE;
|
||||
else
|
||||
throw Poco::Exception("invalid JSON");
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectACL::to_json(Poco::JSON::Object &Obj) const {
|
||||
RESTAPI_utils::field_to_json(Obj, "users", users);
|
||||
RESTAPI_utils::field_to_json(Obj, "roles", roles);
|
||||
field_to_json(Obj, "users", users);
|
||||
field_to_json(Obj, "roles", roles);
|
||||
field_to_json(Obj, "access", access);
|
||||
}
|
||||
|
||||
bool ObjectACL::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
RESTAPI_utils::field_from_json(Obj, "users", users);
|
||||
RESTAPI_utils::field_from_json(Obj, "roles", roles);
|
||||
field_from_json(Obj, "users", users);
|
||||
field_from_json(Obj, "roles", roles);
|
||||
field_from_json(Obj, "access", access);
|
||||
return true;
|
||||
} catch(...) {
|
||||
@@ -575,12 +806,12 @@ namespace OpenWifi::ProvObjects {
|
||||
}
|
||||
|
||||
void ObjectACLList::to_json(Poco::JSON::Object &Obj) const {
|
||||
RESTAPI_utils::field_to_json(Obj, "list", list);
|
||||
field_to_json(Obj, "list", list);
|
||||
}
|
||||
|
||||
bool ObjectACLList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
RESTAPI_utils::field_from_json(Obj, "list", list);
|
||||
field_from_json(Obj, "list", list);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
@@ -588,46 +819,15 @@ namespace OpenWifi::ProvObjects {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string to_string(VISIBILITY A) {
|
||||
switch(A) {
|
||||
case PUBLIC: return "public";
|
||||
case SELECT: return "select";
|
||||
case PRIVATE:
|
||||
default:
|
||||
return "private";
|
||||
}
|
||||
}
|
||||
|
||||
void field_to_json(Poco::JSON::Object &Obj, const char * FieldName, VISIBILITY A) {
|
||||
Obj.set(FieldName,to_string(A));
|
||||
}
|
||||
|
||||
VISIBILITY visibility_from_string(const std::string &V) {
|
||||
if(V=="public")
|
||||
return PUBLIC;
|
||||
else if(V=="select")
|
||||
return SELECT;
|
||||
else if(V=="private")
|
||||
return PRIVATE;
|
||||
throw Poco::Exception("invalid json");
|
||||
}
|
||||
|
||||
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char * FieldName, VISIBILITY &A) {
|
||||
if(Obj->has(FieldName)) {
|
||||
auto V = Obj->getValue<std::string>(FieldName);
|
||||
A = visibility_from_string(V);
|
||||
}
|
||||
}
|
||||
|
||||
void Map::to_json(Poco::JSON::Object &Obj) const {
|
||||
info.to_json(Obj);
|
||||
RESTAPI_utils::field_to_json( Obj,"data",data);
|
||||
RESTAPI_utils::field_to_json( Obj,"entity",entity);
|
||||
RESTAPI_utils::field_to_json( Obj,"creator",creator);
|
||||
field_to_json( Obj,"data",data);
|
||||
field_to_json( Obj,"entity",entity);
|
||||
field_to_json( Obj,"creator",creator);
|
||||
field_to_json( Obj,"visibility",visibility);
|
||||
RESTAPI_utils::field_to_json( Obj,"access",access);
|
||||
RESTAPI_utils::field_to_json( Obj,"managementPolicy", managementPolicy);
|
||||
RESTAPI_utils::field_to_json( Obj,"venue", venue);
|
||||
field_to_json( Obj,"access",access);
|
||||
field_to_json( Obj,"managementPolicy", managementPolicy);
|
||||
field_to_json( Obj,"venue", venue);
|
||||
}
|
||||
|
||||
bool Map::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
@@ -636,7 +836,7 @@ namespace OpenWifi::ProvObjects {
|
||||
RESTAPI_utils::field_from_json( Obj,"data",data);
|
||||
RESTAPI_utils::field_from_json( Obj,"entity",entity);
|
||||
RESTAPI_utils::field_from_json( Obj,"creator",creator);
|
||||
field_from_json( Obj,"visibility",visibility);
|
||||
RESTAPI_utils::field_from_json( Obj,"visibility",visibility);
|
||||
RESTAPI_utils::field_from_json( Obj,"access",access);
|
||||
RESTAPI_utils::field_from_json( Obj,"managementPolicy", managementPolicy);
|
||||
RESTAPI_utils::field_from_json( Obj,"venue", venue);
|
||||
@@ -647,6 +847,20 @@ namespace OpenWifi::ProvObjects {
|
||||
return false;
|
||||
}
|
||||
|
||||
void SerialNumberList::to_json(Poco::JSON::Object &Obj) const {
|
||||
RESTAPI_utils::field_to_json( Obj,"serialNumbers",serialNumbers);
|
||||
}
|
||||
|
||||
bool SerialNumberList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
RESTAPI_utils::field_from_json( Obj,"serialNumbers",serialNumbers);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void MapList::to_json(Poco::JSON::Object &Obj) const {
|
||||
RESTAPI_utils::field_to_json( Obj,"list",list);
|
||||
}
|
||||
@@ -663,31 +877,35 @@ namespace OpenWifi::ProvObjects {
|
||||
|
||||
void SignupEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||
info.to_json(Obj);
|
||||
RESTAPI_utils::field_to_json( Obj,"email", email);
|
||||
RESTAPI_utils::field_to_json( Obj,"userId", userId);
|
||||
RESTAPI_utils::field_to_json( Obj,"macAddress", macAddress);
|
||||
RESTAPI_utils::field_to_json( Obj,"serialNumber", serialNumber);
|
||||
RESTAPI_utils::field_to_json( Obj,"submitted", submitted);
|
||||
RESTAPI_utils::field_to_json( Obj,"completed", completed);
|
||||
RESTAPI_utils::field_to_json( Obj,"status", status);
|
||||
RESTAPI_utils::field_to_json( Obj,"error", error);
|
||||
RESTAPI_utils::field_to_json( Obj,"statusCode", statusCode);
|
||||
RESTAPI_utils::field_to_json( Obj,"deviceID", deviceID);
|
||||
field_to_json( Obj,"email", email);
|
||||
field_to_json( Obj,"userId", userId);
|
||||
field_to_json( Obj,"macAddress", macAddress);
|
||||
field_to_json( Obj,"serialNumber", serialNumber);
|
||||
field_to_json( Obj,"submitted", submitted);
|
||||
field_to_json( Obj,"completed", completed);
|
||||
field_to_json( Obj,"status", status);
|
||||
field_to_json( Obj,"error", error);
|
||||
field_to_json( Obj,"statusCode", statusCode);
|
||||
field_to_json( Obj,"deviceID", deviceID);
|
||||
field_to_json( Obj,"registrationId",registrationId);
|
||||
field_to_json( Obj,"operatorId",operatorId);
|
||||
}
|
||||
|
||||
bool SignupEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
info.from_json(Obj);
|
||||
RESTAPI_utils::field_from_json( Obj,"email", email);
|
||||
RESTAPI_utils::field_from_json( Obj,"userId", userId);
|
||||
RESTAPI_utils::field_from_json( Obj,"macAddress", macAddress);
|
||||
RESTAPI_utils::field_from_json( Obj,"serialNumber", serialNumber);
|
||||
RESTAPI_utils::field_from_json( Obj,"submitted", submitted);
|
||||
RESTAPI_utils::field_from_json( Obj,"completed", completed);
|
||||
RESTAPI_utils::field_from_json( Obj,"status", status);
|
||||
RESTAPI_utils::field_from_json( Obj,"error", error);
|
||||
RESTAPI_utils::field_from_json( Obj,"statusCode", statusCode);
|
||||
RESTAPI_utils::field_from_json( Obj,"deviceID", deviceID);
|
||||
field_from_json( Obj,"email", email);
|
||||
field_from_json( Obj,"userId", userId);
|
||||
field_from_json( Obj,"macAddress", macAddress);
|
||||
field_from_json( Obj,"serialNumber", serialNumber);
|
||||
field_from_json( Obj,"submitted", submitted);
|
||||
field_from_json( Obj,"completed", completed);
|
||||
field_from_json( Obj,"status", status);
|
||||
field_from_json( Obj,"error", error);
|
||||
field_from_json( Obj,"statusCode", statusCode);
|
||||
field_from_json( Obj,"deviceID", deviceID);
|
||||
field_from_json( Obj,"registrationId",registrationId);
|
||||
field_from_json( Obj,"operatorId",operatorId);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
@@ -696,18 +914,18 @@ namespace OpenWifi::ProvObjects {
|
||||
}
|
||||
|
||||
void Variable::to_json(Poco::JSON::Object &Obj) const {
|
||||
RESTAPI_utils::field_to_json( Obj,"type", type);
|
||||
RESTAPI_utils::field_to_json( Obj,"weight", weight);
|
||||
RESTAPI_utils::field_to_json( Obj,"prefix", prefix);
|
||||
RESTAPI_utils::field_to_json( Obj,"value", value);
|
||||
field_to_json( Obj,"type", type);
|
||||
field_to_json( Obj,"weight", weight);
|
||||
field_to_json( Obj,"prefix", prefix);
|
||||
field_to_json( Obj,"value", value);
|
||||
}
|
||||
|
||||
bool Variable::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
RESTAPI_utils::field_from_json( Obj,"type", type);
|
||||
RESTAPI_utils::field_from_json( Obj,"weight", weight);
|
||||
RESTAPI_utils::field_from_json( Obj,"prefix", prefix);
|
||||
RESTAPI_utils::field_from_json( Obj,"value", value);
|
||||
field_from_json( Obj,"type", type);
|
||||
field_from_json( Obj,"weight", weight);
|
||||
field_from_json( Obj,"prefix", prefix);
|
||||
field_from_json( Obj,"value", value);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
@@ -716,12 +934,12 @@ namespace OpenWifi::ProvObjects {
|
||||
}
|
||||
|
||||
void VariableList::to_json(Poco::JSON::Object &Obj) const {
|
||||
RESTAPI_utils::field_to_json( Obj,"variables", variables);
|
||||
field_to_json( Obj,"variables", variables);
|
||||
}
|
||||
|
||||
bool VariableList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
RESTAPI_utils::field_from_json( Obj,"variables", variables);
|
||||
field_from_json( Obj,"variables", variables);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
@@ -731,25 +949,25 @@ namespace OpenWifi::ProvObjects {
|
||||
|
||||
void VariableBlock::to_json(Poco::JSON::Object &Obj) const {
|
||||
info.to_json(Obj);
|
||||
RESTAPI_utils::field_to_json( Obj,"variables", variables);
|
||||
RESTAPI_utils::field_to_json( Obj,"entity", entity);
|
||||
RESTAPI_utils::field_to_json( Obj,"venue", venue);
|
||||
RESTAPI_utils::field_to_json( Obj,"subscriber", subscriber);
|
||||
RESTAPI_utils::field_to_json( Obj,"inventory", inventory);
|
||||
RESTAPI_utils::field_to_json( Obj,"configurations", configurations);
|
||||
RESTAPI_utils::field_to_json( Obj,"managementPolicy", managementPolicy);
|
||||
field_to_json( Obj,"variables", variables);
|
||||
field_to_json( Obj,"entity", entity);
|
||||
field_to_json( Obj,"venue", venue);
|
||||
field_to_json( Obj,"subscriber", subscriber);
|
||||
field_to_json( Obj,"inventory", inventory);
|
||||
field_to_json( Obj,"configurations", configurations);
|
||||
field_to_json( Obj,"managementPolicy", managementPolicy);
|
||||
}
|
||||
|
||||
bool VariableBlock::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
info.from_json(Obj);
|
||||
RESTAPI_utils::field_from_json( Obj,"variables", variables);
|
||||
RESTAPI_utils::field_from_json( Obj,"entity", entity);
|
||||
RESTAPI_utils::field_from_json( Obj,"venue", venue);
|
||||
RESTAPI_utils::field_from_json( Obj,"subscriber", subscriber);
|
||||
RESTAPI_utils::field_from_json( Obj,"inventory", inventory);
|
||||
RESTAPI_utils::field_from_json( Obj,"configurations", configurations);
|
||||
RESTAPI_utils::field_from_json( Obj,"managementPolicy", managementPolicy);
|
||||
field_from_json( Obj,"variables", variables);
|
||||
field_from_json( Obj,"entity", entity);
|
||||
field_from_json( Obj,"venue", venue);
|
||||
field_from_json( Obj,"subscriber", subscriber);
|
||||
field_from_json( Obj,"inventory", inventory);
|
||||
field_from_json( Obj,"configurations", configurations);
|
||||
field_from_json( Obj,"managementPolicy", managementPolicy);
|
||||
return true;
|
||||
} catch(...) {
|
||||
}
|
||||
@@ -757,12 +975,94 @@ namespace OpenWifi::ProvObjects {
|
||||
}
|
||||
|
||||
void VariableBlockList::to_json(Poco::JSON::Object &Obj) const {
|
||||
RESTAPI_utils::field_to_json( Obj,"variableBlocks", variableBlocks);
|
||||
field_to_json( Obj,"variableBlocks", variableBlocks);
|
||||
}
|
||||
|
||||
bool VariableBlockList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
RESTAPI_utils::field_from_json( Obj,"variableBlocks", variableBlocks);
|
||||
field_from_json( Obj,"variableBlocks", variableBlocks);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ConfigurationDetails::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json( Obj,"configuration", configuration);
|
||||
field_to_json( Obj,"rrm", rrm);
|
||||
field_to_json( Obj,"firmwareRCOnly", firmwareRCOnly);
|
||||
field_to_json( Obj,"firmwareUpgrade", firmwareUpgrade);
|
||||
}
|
||||
|
||||
bool ConfigurationDetails::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json( Obj,"configuration", configuration);
|
||||
field_from_json( Obj,"rrm", rrm);
|
||||
field_from_json( Obj,"firmwareRCOnly", firmwareRCOnly);
|
||||
field_from_json( Obj,"firmwareUpgrade", firmwareUpgrade);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SubscriberDevice::to_json(Poco::JSON::Object &Obj) const {
|
||||
info.to_json(Obj);
|
||||
field_to_json( Obj,"serialNumber", serialNumber);
|
||||
field_to_json( Obj,"deviceType", deviceType);
|
||||
field_to_json( Obj,"operatorId", operatorId);
|
||||
field_to_json( Obj,"subscriberId", subscriberId);
|
||||
field_to_json( Obj,"location", location);
|
||||
field_to_json( Obj,"contact", contact);
|
||||
field_to_json( Obj,"managementPolicy", managementPolicy);
|
||||
field_to_json( Obj,"serviceClass", serviceClass);
|
||||
field_to_json( Obj,"qrCode", qrCode);
|
||||
field_to_json( Obj,"geoCode", geoCode);
|
||||
field_to_json( Obj,"deviceRules",deviceRules);
|
||||
field_to_json( Obj,"state", state);
|
||||
field_to_json( Obj,"locale", locale);
|
||||
field_to_json( Obj,"billingCode", billingCode);
|
||||
field_to_json( Obj,"configuration", configuration);
|
||||
field_to_json( Obj,"suspended", suspended);
|
||||
field_to_json( Obj,"realMacAddress", realMacAddress);
|
||||
}
|
||||
|
||||
bool SubscriberDevice::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
info.from_json(Obj);
|
||||
field_from_json( Obj,"serialNumber", serialNumber);
|
||||
field_from_json( Obj,"deviceType", deviceType);
|
||||
field_from_json( Obj,"operatorId", operatorId);
|
||||
field_from_json( Obj,"subscriberId", subscriberId);
|
||||
field_from_json( Obj,"location", location);
|
||||
field_from_json( Obj,"contact", contact);
|
||||
field_from_json( Obj,"managementPolicy", managementPolicy);
|
||||
field_from_json( Obj,"serviceClass", serviceClass);
|
||||
field_from_json( Obj,"qrCode", qrCode);
|
||||
field_from_json( Obj,"geoCode", geoCode);
|
||||
field_from_json( Obj,"deviceRules",deviceRules);
|
||||
field_from_json( Obj,"state", state);
|
||||
field_from_json( Obj,"locale", locale);
|
||||
field_from_json( Obj,"billingCode", billingCode);
|
||||
field_from_json( Obj,"configuration", configuration);
|
||||
field_from_json( Obj,"suspended", suspended);
|
||||
field_from_json( Obj,"realMacAddress", realMacAddress);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SubscriberDeviceList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json( Obj,"subscriberDevices", subscriberDevices);
|
||||
}
|
||||
|
||||
bool SubscriberDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json( Obj,"subscriberDevices", subscriberDevices);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
@@ -771,18 +1071,18 @@ namespace OpenWifi::ProvObjects {
|
||||
}
|
||||
|
||||
void VenueDeviceList::to_json(Poco::JSON::Object &Obj) const {
|
||||
RESTAPI_utils::field_to_json(Obj,"id",id);
|
||||
RESTAPI_utils::field_to_json(Obj,"name",name);
|
||||
RESTAPI_utils::field_to_json(Obj,"description",description);
|
||||
RESTAPI_utils::field_to_json(Obj,"devices",devices);
|
||||
field_to_json(Obj,"id",id);
|
||||
field_to_json(Obj,"name",name);
|
||||
field_to_json(Obj,"description",description);
|
||||
field_to_json(Obj,"devices",devices);
|
||||
}
|
||||
|
||||
bool VenueDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
RESTAPI_utils::field_from_json(Obj,"id",id);
|
||||
RESTAPI_utils::field_from_json(Obj,"name",name);
|
||||
RESTAPI_utils::field_from_json(Obj,"description",description);
|
||||
RESTAPI_utils::field_from_json(Obj,"devices",devices);
|
||||
field_from_json(Obj,"id",id);
|
||||
field_from_json(Obj,"name",name);
|
||||
field_from_json(Obj,"description",description);
|
||||
field_from_json(Obj,"devices",devices);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
@@ -791,7 +1091,7 @@ namespace OpenWifi::ProvObjects {
|
||||
}
|
||||
|
||||
bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) {
|
||||
uint64_t Now = std::time(nullptr);
|
||||
uint64_t Now = OpenWifi::Now();
|
||||
if(O->has("name"))
|
||||
I.name = O->get("name").toString();
|
||||
|
||||
@@ -835,11 +1135,29 @@ namespace OpenWifi::ProvObjects {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I) {
|
||||
bool CreateObjectInfo([[maybe_unused]] const SecurityObjects::UserInfo &U, ObjectInfo &I) {
|
||||
I.modified = I.created = OpenWifi::Now();
|
||||
I.id = MicroService::CreateUUID();
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeviceRules::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"rcOnly",rcOnly);
|
||||
field_to_json(Obj,"rrm",rrm);
|
||||
field_to_json(Obj,"firmwareUpgrade",firmwareUpgrade);
|
||||
}
|
||||
|
||||
bool DeviceRules::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"rcOnly",rcOnly);
|
||||
field_from_json(Obj,"rrm",rrm);
|
||||
field_from_json(Obj,"firmwareUpgrade",firmwareUpgrade);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -33,6 +33,13 @@ namespace OpenWifi::ProvObjects {
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct SerialNumberList {
|
||||
Types::UUIDvec_t serialNumbers;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct ManagementPolicyEntry {
|
||||
Types::UUIDvec_t users;
|
||||
Types::UUIDvec_t resources;
|
||||
@@ -55,6 +62,15 @@ namespace OpenWifi::ProvObjects {
|
||||
};
|
||||
typedef std::vector<ManagementPolicy> ManagementPolicyVec;
|
||||
|
||||
struct DeviceRules {
|
||||
std::string rcOnly{"inherit"};
|
||||
std::string rrm{"inherit"};
|
||||
std::string firmwareUpgrade{"inherit"};
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct Entity {
|
||||
ObjectInfo info;
|
||||
Types::UUID_t parent;
|
||||
@@ -65,7 +81,7 @@ namespace OpenWifi::ProvObjects {
|
||||
Types::UUID_t managementPolicy;
|
||||
Types::UUIDvec_t deviceConfiguration;
|
||||
Types::UUIDvec_t devices;
|
||||
std::string rrm;
|
||||
DeviceRules deviceRules;
|
||||
Types::StringVec sourceIP;
|
||||
Types::UUIDvec_t variables;
|
||||
Types::UUIDvec_t managementPolicies;
|
||||
@@ -100,13 +116,14 @@ namespace OpenWifi::ProvObjects {
|
||||
Types::UUIDvec_t deviceConfiguration;
|
||||
Types::UUIDvec_t contacts;
|
||||
std::string location;
|
||||
std::string rrm;
|
||||
DeviceRules deviceRules;
|
||||
Types::StringVec sourceIP;
|
||||
Types::UUIDvec_t variables;
|
||||
Types::UUIDvec_t configurations;
|
||||
Types::UUIDvec_t maps;
|
||||
Types::UUIDvec_t managementPolicies;
|
||||
Types::UUIDvec_t managementRoles;
|
||||
Types::UUIDvec_t boards;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
@@ -192,6 +209,51 @@ namespace OpenWifi::ProvObjects {
|
||||
};
|
||||
typedef std::vector<Location> LocationVec;
|
||||
|
||||
struct OperatorLocation {
|
||||
ObjectInfo info;
|
||||
std::string type;
|
||||
std::string buildingName;
|
||||
Types::StringVec addressLines;
|
||||
std::string city;
|
||||
std::string state;
|
||||
std::string postal;
|
||||
std::string country;
|
||||
Types::StringVec phones;
|
||||
Types::StringVec mobiles;
|
||||
std::string geoCode;
|
||||
Types::UUID_t operatorId;
|
||||
Types::UUID_t subscriberDeviceId;
|
||||
Types::UUID_t managementPolicy;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
typedef std::vector<Location> LocationVec;
|
||||
|
||||
struct SubLocation {
|
||||
std::string type;
|
||||
std::string buildingName;
|
||||
Types::StringVec addressLines;
|
||||
std::string city;
|
||||
std::string state;
|
||||
std::string postal;
|
||||
std::string country;
|
||||
Types::StringVec phones;
|
||||
Types::StringVec mobiles;
|
||||
std::string geoCode;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct OperatorLocationList {
|
||||
std::vector<OperatorLocation> locations;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
|
||||
enum ContactType {
|
||||
CT_SUBSCRIBER, CT_USER, CT_INSTALLER, CT_CSR, CT_MANAGER,
|
||||
CT_BUSINESSOWNER, CT_TECHNICIAN, CT_CORPORATE, CT_UNKNOWN
|
||||
@@ -255,6 +317,55 @@ namespace OpenWifi::ProvObjects {
|
||||
};
|
||||
typedef std::vector<Contact> ContactVec;
|
||||
|
||||
struct OperatorContact {
|
||||
ObjectInfo info;
|
||||
std::string type;
|
||||
std::string title;
|
||||
std::string salutation;
|
||||
std::string firstname;
|
||||
std::string lastname;
|
||||
std::string initials;
|
||||
std::string visual;
|
||||
Types::StringVec mobiles;
|
||||
Types::StringVec phones;
|
||||
std::string primaryEmail;
|
||||
std::string secondaryEmail;
|
||||
std::string accessPIN;
|
||||
Types::UUID_t operatorId;
|
||||
Types::UUID_t subscriberDeviceId;
|
||||
Types::UUID_t managementPolicy;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct SubContact {
|
||||
std::string type;
|
||||
std::string title;
|
||||
std::string salutation;
|
||||
std::string firstname;
|
||||
std::string lastname;
|
||||
std::string initials;
|
||||
std::string visual;
|
||||
Types::StringVec mobiles;
|
||||
Types::StringVec phones;
|
||||
std::string primaryEmail;
|
||||
std::string secondaryEmail;
|
||||
std::string accessPIN;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct OperatorContactList {
|
||||
std::vector<OperatorContact> contacts;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
typedef std::vector<OperatorContact> OperatorContactVec;
|
||||
|
||||
struct DeviceConfigurationElement {
|
||||
std::string name;
|
||||
std::string description;
|
||||
@@ -267,15 +378,13 @@ namespace OpenWifi::ProvObjects {
|
||||
typedef std::vector<DeviceConfigurationElement> DeviceConfigurationElementVec;
|
||||
|
||||
struct DeviceConfiguration {
|
||||
ObjectInfo info;
|
||||
ObjectInfo info;
|
||||
Types::UUID_t managementPolicy;
|
||||
Types::StringVec deviceTypes;
|
||||
DeviceConfigurationElementVec configuration;
|
||||
Types::StringVec inUse;
|
||||
Types::UUIDvec_t variables;
|
||||
std::string rrm;
|
||||
std::string firmwareUpgrade;
|
||||
bool firmwareRCOnly=false;
|
||||
DeviceRules deviceRules;
|
||||
bool subscriberOnly=false;
|
||||
std::string venue;
|
||||
std::string entity;
|
||||
@@ -286,6 +395,7 @@ namespace OpenWifi::ProvObjects {
|
||||
};
|
||||
typedef std::vector<DeviceConfiguration> DeviceConfigurationVec;
|
||||
|
||||
|
||||
struct InventoryTag {
|
||||
ObjectInfo info;
|
||||
std::string serialNumber;
|
||||
@@ -298,7 +408,7 @@ namespace OpenWifi::ProvObjects {
|
||||
std::string location;
|
||||
std::string contact;
|
||||
std::string deviceConfiguration;
|
||||
std::string rrm;
|
||||
DeviceRules deviceRules;
|
||||
Types::UUID_t managementPolicy;
|
||||
std::string state;
|
||||
std::string devClass;
|
||||
@@ -361,20 +471,20 @@ namespace OpenWifi::ProvObjects {
|
||||
};
|
||||
|
||||
struct UuidList {
|
||||
std::vector<std::string> list;
|
||||
Types::UUIDvec_t list;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
enum ACLACCESS {
|
||||
NONE, READ, MODIFY, CREATE, DELETE
|
||||
NONE = 0, READ=1, MODIFY=2, CREATE=3, DELETE=4
|
||||
};
|
||||
|
||||
struct ObjectACL {
|
||||
UuidList users;
|
||||
UuidList roles;
|
||||
ACLACCESS access = NONE;
|
||||
uint64_t access = (uint64_t) NONE;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
@@ -387,19 +497,12 @@ namespace OpenWifi::ProvObjects {
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
enum VISIBILITY {
|
||||
PUBLIC, PRIVATE, SELECT
|
||||
};
|
||||
|
||||
std::string to_string(VISIBILITY A);
|
||||
VISIBILITY visibility_from_string(const std::string &V);
|
||||
|
||||
struct Map {
|
||||
ObjectInfo info;
|
||||
std::string data;
|
||||
std::string entity;
|
||||
std::string creator;
|
||||
VISIBILITY visibility = PRIVATE;
|
||||
std::string visibility{"private"};
|
||||
ObjectACLList access;
|
||||
Types::UUID_t managementPolicy;
|
||||
std::string venue;
|
||||
@@ -437,6 +540,8 @@ namespace OpenWifi::ProvObjects {
|
||||
uint64_t error=0;
|
||||
uint64_t statusCode=0;
|
||||
std::string deviceID;
|
||||
std::string registrationId;
|
||||
std::string operatorId;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
@@ -480,6 +585,27 @@ namespace OpenWifi::ProvObjects {
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct Operator {
|
||||
ObjectInfo info;
|
||||
Types::UUID_t managementPolicy;
|
||||
Types::UUIDvec_t managementRoles;
|
||||
DeviceRules deviceRules;
|
||||
std::vector<Variable> variables;
|
||||
bool defaultOperator=false;
|
||||
Types::StringVec sourceIP;
|
||||
std::string registrationId;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct OperatorList {
|
||||
std::vector<Operator> operators;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct VenueDeviceList {
|
||||
std::string id;
|
||||
std::string name;
|
||||
@@ -490,6 +616,68 @@ namespace OpenWifi::ProvObjects {
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct ServiceClass {
|
||||
ObjectInfo info;
|
||||
Types::UUID_t operatorId;
|
||||
Types::UUID_t managementPolicy;
|
||||
double cost=0.0;
|
||||
std::string currency;
|
||||
std::string period;
|
||||
std::string billingCode;
|
||||
std::vector<Variable> variables;
|
||||
bool defaultService=false;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct ServiceClassList {
|
||||
std::vector<ServiceClass> serviceClasses;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct ConfigurationDetails {
|
||||
DeviceConfigurationElementVec configuration;
|
||||
std::string rrm{"inherit"};
|
||||
std::string firmwareUpgrade{"inherit"};
|
||||
std::string firmwareRCOnly{"inherit"};
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct SubscriberDevice {
|
||||
ObjectInfo info;
|
||||
std::string serialNumber;
|
||||
std::string deviceType;
|
||||
Types::UUID_t operatorId;
|
||||
Types::UUID_t subscriberId;
|
||||
SubLocation location;
|
||||
SubContact contact;
|
||||
Types::UUID_t managementPolicy;
|
||||
Types::UUID_t serviceClass;
|
||||
std::string qrCode;
|
||||
std::string geoCode;
|
||||
DeviceRules deviceRules;
|
||||
std::string state;
|
||||
std::string locale;
|
||||
std::string billingCode;
|
||||
DeviceConfigurationElementVec configuration;
|
||||
bool suspended=false;
|
||||
std::string realMacAddress;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct SubscriberDeviceList {
|
||||
std::vector<SubscriberDevice> subscriberDevices;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I);
|
||||
bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I);
|
||||
|
||||
@@ -95,6 +95,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_from_json(Obj, "PortalLogin", PortalLogin_);
|
||||
return true;
|
||||
} catch(...) {
|
||||
std::cout << "Cannot parse: AclTemplate" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -112,6 +113,8 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json(Obj,"userMustChangePassword",userMustChangePassword);
|
||||
field_to_json(Obj,"errorCode", errorCode);
|
||||
Obj.set("aclTemplate",AclTemplateObj);
|
||||
field_to_json(Obj,"errorCode", errorCode);
|
||||
field_to_json(Obj,"lastRefresh", lastRefresh_);
|
||||
}
|
||||
|
||||
bool WebToken::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
@@ -128,9 +131,10 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_from_json(Obj, "created", created_);
|
||||
field_from_json(Obj, "username", username_);
|
||||
field_from_json(Obj, "userMustChangePassword",userMustChangePassword);
|
||||
field_from_json(Obj,"lastRefresh", lastRefresh_);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
std::cout << "Cannot parse: WebToken" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -141,14 +145,14 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json(Obj,"primary", primary);
|
||||
}
|
||||
|
||||
bool MobilePhoneNumber::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool MobilePhoneNumber::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"number",number);
|
||||
field_from_json(Obj,"verified",verified);
|
||||
field_from_json(Obj,"primary",primary);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
std::cout << "Cannot parse: MobilePhoneNumber" << std::endl;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@@ -158,13 +162,13 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json(Obj,"method", method);
|
||||
}
|
||||
|
||||
bool MfaAuthInfo::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool MfaAuthInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"enabled",enabled);
|
||||
field_from_json(Obj,"method",method);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
std::cout << "Cannot parse: MfaAuthInfo" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -175,14 +179,14 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json(Obj, "authenticatorSecret", authenticatorSecret);
|
||||
}
|
||||
|
||||
bool UserLoginLoginExtensions::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool UserLoginLoginExtensions::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "mobiles",mobiles);
|
||||
field_from_json(Obj, "mfa",mfa);
|
||||
field_from_json(Obj, "authenticatorSecret", authenticatorSecret);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
std::cout << "Cannot parse: UserLoginLoginExtensions" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -194,7 +198,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json(Obj, "method", method);
|
||||
}
|
||||
|
||||
bool MFAChallengeRequest::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool MFAChallengeRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"uuid",uuid);
|
||||
field_from_json(Obj,"question",question);
|
||||
@@ -202,7 +206,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_from_json(Obj,"method",method);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
std::cout << "Cannot parse: MFAChallengeRequest" << std::endl;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@@ -210,16 +214,15 @@ namespace OpenWifi::SecurityObjects {
|
||||
void MFAChallengeResponse::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "uuid", uuid);
|
||||
field_to_json(Obj, "answer", answer);
|
||||
|
||||
}
|
||||
|
||||
bool MFAChallengeResponse::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool MFAChallengeResponse::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"uuid",uuid);
|
||||
field_from_json(Obj,"answer",answer);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
std::cout << "Cannot parse: MFAChallengeResponse" << std::endl;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -296,11 +299,25 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_from_json(Obj,"signingUp",signingUp);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
|
||||
std::cout << "Cannot parse: UserInfo" << std::endl;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
void UserInfoList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"users",users);
|
||||
}
|
||||
|
||||
bool UserInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"users",users);
|
||||
return true;
|
||||
} catch (...) {
|
||||
std::cout << "Cannot parse: InternalServiceInfo" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void InternalServiceInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"privateURI",privateURI);
|
||||
field_to_json(Obj,"publicURI",publicURI);
|
||||
@@ -314,7 +331,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_from_json(Obj,"token",token);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
std::cout << "Cannot parse: InternalServiceInfo" << std::endl;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@@ -332,7 +349,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_from_json(Obj, "services", services);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
std::cout << "Cannot parse: InternalSystemServices" << std::endl;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@@ -354,7 +371,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_from_json(Obj, "authenticationType", authenticationType);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
std::cout << "Cannot parse: SystemEndpoint" << std::endl;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
@@ -368,7 +385,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_from_json(Obj, "endpoints", endpoints);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
std::cout << "Cannot parse: SystemEndpointList" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -387,7 +404,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_from_json(Obj, "userInfo", userinfo);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
std::cout << "Cannot parse: UserInfoAndPolicy" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -398,14 +415,14 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json(Obj,"note", note);
|
||||
}
|
||||
|
||||
bool NoteInfo::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool NoteInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"created",created);
|
||||
field_from_json(Obj,"created",created);
|
||||
field_from_json(Obj,"createdBy",createdBy);
|
||||
field_from_json(Obj,"note",note);
|
||||
field_from_json(Obj,"note", note);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
std::cout << "Cannot parse: NoteInfo" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -416,20 +433,20 @@ namespace OpenWifi::SecurityObjects {
|
||||
SecurityObjects::NoteInfoVec NIV;
|
||||
NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(Obj->get("notes").toString());
|
||||
for(auto const &i:NIV) {
|
||||
SecurityObjects::NoteInfo ii{.created=(uint64_t)std::time(nullptr), .createdBy=UInfo.email, .note=i.note};
|
||||
SecurityObjects::NoteInfo ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UInfo.email, .note=i.note};
|
||||
Notes.push_back(ii);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
std::cout << "Cannot parse: MergeNotes" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes) {
|
||||
for(auto const &i:NewNotes) {
|
||||
SecurityObjects::NoteInfo ii{.created=(uint64_t)std::time(nullptr), .createdBy=UInfo.email, .note=i.note};
|
||||
SecurityObjects::NoteInfo ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UInfo.email, .note=i.note};
|
||||
ExistingNotes.push_back(ii);
|
||||
}
|
||||
return true;
|
||||
@@ -440,13 +457,13 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json<ResourceAccessType>(Obj,"access", access, ResourceAccessTypeToString);
|
||||
}
|
||||
|
||||
bool ProfileAction::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool ProfileAction::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"resource",resource);
|
||||
field_from_json<ResourceAccessType>(Obj,"access",access,ResourceAccessTypeFromString );
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
std::cout << "Cannot parse: ProfileAction" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -460,7 +477,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json(Obj,"notes", notes);
|
||||
}
|
||||
|
||||
bool SecurityProfile::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool SecurityProfile::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"id",id);
|
||||
field_from_json(Obj,"name",name);
|
||||
@@ -470,7 +487,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_from_json(Obj,"notes",notes);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
std::cout << "Cannot parse: SecurityProfile" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -479,12 +496,12 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json(Obj, "profiles", profiles);
|
||||
}
|
||||
|
||||
bool SecurityProfileList::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool SecurityProfileList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"profiles",profiles);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
std::cout << "Cannot parse: SecurityProfileList" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -505,7 +522,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json(Obj,"userAction",userAction);
|
||||
}
|
||||
|
||||
bool ActionLink::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool ActionLink::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"id",id);
|
||||
field_from_json(Obj,"action",action);
|
||||
@@ -522,7 +539,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_from_json(Obj,"userAction",userAction);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
std::cout << "Cannot parse: ActionLink" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -533,14 +550,14 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json(Obj,"data",data);
|
||||
}
|
||||
|
||||
bool Preferences::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool Preferences::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"id",id);
|
||||
field_from_json(Obj,"modified",modified);
|
||||
field_from_json(Obj,"data",data);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
std::cout << "Cannot parse: Preferences" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -552,7 +569,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json(Obj,"email",email);
|
||||
}
|
||||
|
||||
bool SubMfaConfig::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool SubMfaConfig::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"id",id);
|
||||
field_from_json(Obj,"type",type);
|
||||
@@ -560,7 +577,7 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_from_json(Obj,"email",email);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
std::cout << "Cannot parse: SubMfaConfig" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -574,9 +591,10 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json(Obj,"expires",expires);
|
||||
field_to_json(Obj,"idleTimeout",idleTimeout);
|
||||
field_to_json(Obj,"revocationDate",revocationDate);
|
||||
field_to_json(Obj,"lastRefresh", lastRefresh);
|
||||
}
|
||||
|
||||
bool Token::from_json(Poco::JSON::Object::Ptr &Obj) {
|
||||
bool Token::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"token",token);
|
||||
field_from_json(Obj,"refreshToken",refreshToken);
|
||||
@@ -586,9 +604,10 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_from_json(Obj,"expires",expires);
|
||||
field_from_json(Obj,"idleTimeout",idleTimeout);
|
||||
field_from_json(Obj,"revocationDate",revocationDate);
|
||||
field_from_json(Obj,"lastRefresh", lastRefresh);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
std::cout << "Cannot parse: Token" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -9,14 +9,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/Data/LOB.h"
|
||||
#include "Poco/Data/LOBStream.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
uint64_t Now();
|
||||
namespace SecurityObjects {
|
||||
|
||||
|
||||
typedef std::string USER_ID_TYPE;
|
||||
|
||||
struct AclTemplate {
|
||||
@@ -26,8 +28,13 @@ namespace OpenWifi {
|
||||
bool Delete_ = true;
|
||||
bool PortalLogin_ = true;
|
||||
|
||||
AclTemplate() noexcept = default;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj); };
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
static_assert( std::is_nothrow_move_constructible_v<AclTemplate> );
|
||||
|
||||
struct WebToken {
|
||||
std::string access_token_;
|
||||
@@ -41,6 +48,7 @@ namespace OpenWifi {
|
||||
uint64_t idle_timeout_=0;
|
||||
AclTemplate acl_template_;
|
||||
uint64_t created_=0;
|
||||
uint64_t lastRefresh_=0;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
@@ -54,11 +62,12 @@ namespace OpenWifi {
|
||||
std::string UserTypeToString(USER_ROLE U);
|
||||
|
||||
struct NoteInfo {
|
||||
uint64_t created = std::time(nullptr);
|
||||
uint64_t created=0; // = OpenWifi::Now();
|
||||
std::string createdBy;
|
||||
std::string note;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
typedef std::vector<NoteInfo> NoteInfoVec;
|
||||
|
||||
@@ -68,7 +77,7 @@ namespace OpenWifi {
|
||||
bool primary = false;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct MfaAuthInfo {
|
||||
@@ -76,7 +85,7 @@ namespace OpenWifi {
|
||||
std::string method;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct UserLoginLoginExtensions {
|
||||
@@ -85,17 +94,17 @@ namespace OpenWifi {
|
||||
std::string authenticatorSecret;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct MFAChallengeRequest {
|
||||
std::string uuid;
|
||||
std::string question;
|
||||
std::string method;
|
||||
uint64_t created = std::time(nullptr);
|
||||
uint64_t created = OpenWifi::Now();
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct MFAChallengeResponse {
|
||||
@@ -103,7 +112,7 @@ namespace OpenWifi {
|
||||
std::string answer;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct UserInfo {
|
||||
@@ -145,6 +154,13 @@ namespace OpenWifi {
|
||||
};
|
||||
typedef std::vector<UserInfo> UserInfoVec;
|
||||
|
||||
struct UserInfoList {
|
||||
std::vector<UserInfo> users;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
// bool append_from_json(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes);
|
||||
bool MergeNotes(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes);
|
||||
bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes);
|
||||
@@ -208,7 +224,7 @@ namespace OpenWifi {
|
||||
std::string resource;
|
||||
ResourceAccessType access;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
typedef std::vector<ProfileAction> ProfileActionVec;
|
||||
|
||||
@@ -220,14 +236,14 @@ namespace OpenWifi {
|
||||
std::string role;
|
||||
NoteInfoVec notes;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
typedef std::vector<SecurityProfile> SecurityProfileVec;
|
||||
|
||||
struct SecurityProfileList {
|
||||
SecurityProfileVec profiles;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
enum LinkActions {
|
||||
@@ -247,14 +263,14 @@ namespace OpenWifi {
|
||||
std::string locale;
|
||||
std::string message;
|
||||
uint64_t sent=0;
|
||||
uint64_t created=std::time(nullptr);
|
||||
uint64_t created=OpenWifi::Now();
|
||||
uint64_t expires=0;
|
||||
uint64_t completed=0;
|
||||
uint64_t canceled=0;
|
||||
bool userAction=true;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct Preferences {
|
||||
@@ -262,7 +278,7 @@ namespace OpenWifi {
|
||||
uint64_t modified;
|
||||
Types::StringPairVec data;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct SubMfaConfig {
|
||||
@@ -272,7 +288,7 @@ namespace OpenWifi {
|
||||
std::string email;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct Token {
|
||||
@@ -284,9 +300,10 @@ namespace OpenWifi {
|
||||
uint64_t expires=0;
|
||||
uint64_t idleTimeout=0;
|
||||
uint64_t revocationDate=0;
|
||||
uint64_t lastRefresh=0;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct Avatar {
|
||||
@@ -294,7 +311,7 @@ namespace OpenWifi {
|
||||
std::string type;
|
||||
uint64_t created=0;
|
||||
std::string name;
|
||||
Poco::Data::LOB<char> avatar;
|
||||
Poco::Data::BLOB avatar;
|
||||
};
|
||||
|
||||
struct LoginRecordInfo {
|
||||
|
||||
@@ -280,6 +280,7 @@ namespace OpenWifi::SubObjects {
|
||||
field_to_json(Obj, "ipv6", ipv6);
|
||||
field_to_json(Obj, "tx", tx);
|
||||
field_to_json(Obj, "rx", rx);
|
||||
field_to_json(Obj, "manufacturer", manufacturer);
|
||||
}
|
||||
|
||||
bool Association::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
@@ -293,6 +294,7 @@ namespace OpenWifi::SubObjects {
|
||||
field_from_json(Obj, "ipv6", ipv6);
|
||||
field_from_json(Obj, "tx", tx);
|
||||
field_from_json(Obj, "rx", rx);
|
||||
field_from_json(Obj, "manufacturer", manufacturer);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
@@ -324,6 +326,7 @@ namespace OpenWifi::SubObjects {
|
||||
field_to_json(Obj, "ipv6", ipv6);
|
||||
field_to_json(Obj, "tx", tx);
|
||||
field_to_json(Obj, "rx", rx);
|
||||
field_to_json(Obj, "manufacturer", manufacturer);
|
||||
}
|
||||
|
||||
bool Client::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
@@ -335,6 +338,7 @@ namespace OpenWifi::SubObjects {
|
||||
field_from_json(Obj, "ipv6", ipv6);
|
||||
field_from_json(Obj, "tx", tx);
|
||||
field_from_json(Obj, "rx", rx);
|
||||
field_from_json(Obj, "manufacturer", manufacturer);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
@@ -562,4 +566,38 @@ namespace OpenWifi::SubObjects {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void StatsEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "timestamp", timestamp);
|
||||
field_to_json(Obj, "tx", tx);
|
||||
field_to_json(Obj, "rx", rx);
|
||||
}
|
||||
|
||||
bool StatsEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "timestamp", timestamp);
|
||||
field_from_json(Obj, "tx", tx);
|
||||
field_from_json(Obj, "rx", rx);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void StatsBlock::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "modified", modified);
|
||||
field_to_json(Obj, "external", external);
|
||||
field_to_json(Obj, "internal", internal);
|
||||
}
|
||||
|
||||
bool StatsBlock::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "modified", modified);
|
||||
field_from_json(Obj, "external", external);
|
||||
field_from_json(Obj, "internal", internal);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -157,6 +157,7 @@ namespace OpenWifi::SubObjects {
|
||||
std::string ipv6;
|
||||
uint64_t tx=0;
|
||||
uint64_t rx=0;
|
||||
std::string manufacturer;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
@@ -179,6 +180,7 @@ namespace OpenWifi::SubObjects {
|
||||
std::string ipv6;
|
||||
uint64_t tx=0;
|
||||
uint64_t rx=0;
|
||||
std::string manufacturer;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
@@ -298,6 +300,23 @@ namespace OpenWifi::SubObjects {
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct StatsEntry {
|
||||
uint64_t timestamp=0;
|
||||
uint64_t tx=0;
|
||||
uint64_t rx=0;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct StatsBlock {
|
||||
uint64_t modified=0;
|
||||
std::vector<StatsEntry> external, internal;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
}
|
||||
|
||||
#endif //OWSUB_RESTAPI_SUBOBJECTS_H
|
||||
|
||||
@@ -10,27 +10,28 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void Archiver::onTimer(Poco::Timer &timer){
|
||||
auto Now = std::time(nullptr);
|
||||
void Archiver::onTimer([[maybe_unused]] Poco::Timer &timer){
|
||||
Utils::SetThreadName("strg-archiver");
|
||||
auto now = OpenWifi::Now();
|
||||
for(const auto &i:DBs_) {
|
||||
if (!Poco::icompare(i.DBName, "healthchecks")) {
|
||||
Logger().information("Archiving HealthChecks...");
|
||||
StorageService()->RemoveHealthChecksRecordsOlderThan(
|
||||
Now - (i.HowManyDays * 24 * 60 * 60));
|
||||
now - (i.HowManyDays * 24 * 60 * 60));
|
||||
} else if (!Poco::icompare(i.DBName, "statistics")) {
|
||||
Logger().information("Archiving Statistics...");
|
||||
StorageService()->RemoveStatisticsRecordsOlderThan(
|
||||
Now - (i.HowManyDays * 24 * 60 * 60));
|
||||
now - (i.HowManyDays * 24 * 60 * 60));
|
||||
} else if (!Poco::icompare(i.DBName, "devicelogs")) {
|
||||
Logger().information("Archiving Device Logs...");
|
||||
StorageService()->RemoveDeviceLogsRecordsOlderThan(
|
||||
Now - (i.HowManyDays * 24 * 60 * 60));
|
||||
now - (i.HowManyDays * 24 * 60 * 60));
|
||||
} else if (!Poco::icompare(i.DBName, "commandlist")) {
|
||||
Logger().information("Archiving Command History...");
|
||||
StorageService()->RemoveCommandListRecordsOlderThan(
|
||||
Now - (i.HowManyDays * 24 * 60 * 60));
|
||||
now - (i.HowManyDays * 24 * 60 * 60));
|
||||
} else {
|
||||
Logger().information(Poco::format("Cannot archive DB '%s'", i.DBName));
|
||||
Logger().information(fmt::format("Cannot archive DB '{}'", i.DBName));
|
||||
}
|
||||
}
|
||||
AppServiceRegistry().Set("lastStorageArchiverRun", (uint64_t) Now);
|
||||
@@ -90,7 +91,7 @@ namespace OpenWifi {
|
||||
|
||||
int NextRun = CalculateDelta(RunAtHour_,RunAtMin_);
|
||||
|
||||
Logger().information(Poco::format("Next run in %d seconds.",NextRun));
|
||||
Logger().information(fmt::format("Next run in {} seconds.",NextRun));
|
||||
|
||||
Timer_.setStartInterval( NextRun * 1000);
|
||||
Timer_.setPeriodicInterval(24 * 60 * 60 * 1000); // 1 hours
|
||||
|
||||
@@ -85,17 +85,18 @@ namespace OpenWifi {
|
||||
bool CreateDefaultDevice(std::string & SerialNumber, std::string & Capabilities, std::string & Firmware, std::string &Compatible,const Poco::Net::IPAddress & IPAddress);
|
||||
|
||||
bool GetDevice(std::string &SerialNumber, GWObjects::Device &);
|
||||
bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices);
|
||||
bool GetDevices(uint64_t From, uint64_t HowMany, const std::string & Select, std::vector<GWObjects::Device> &Devices);
|
||||
bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices, const std::string & orderBy="");
|
||||
// bool GetDevices(uint64_t From, uint64_t HowMany, const std::string & Select, std::vector<GWObjects::Device> &Devices, const std::string & orderBy="");
|
||||
bool DeleteDevice(std::string &SerialNumber);
|
||||
bool UpdateDevice(GWObjects::Device &);
|
||||
bool DeviceExists(std::string & SerialNumber);
|
||||
bool SetConnectInfo(std::string &SerialNumber, std::string &Firmware);
|
||||
bool GetDeviceCount(uint64_t & Count);
|
||||
bool GetDeviceSerialNumbers(uint64_t From, uint64_t HowMany, std::vector<std::string> & SerialNumbers);
|
||||
bool GetDeviceSerialNumbers(uint64_t From, uint64_t HowMany, std::vector<std::string> & SerialNumbers, const std::string & orderBy="");
|
||||
bool GetDeviceFWUpdatePolicy(std::string & SerialNumber, std::string & Policy);
|
||||
bool SetDevicePassword(std::string & SerialNumber, std::string & Password);
|
||||
bool UpdateSerialNumberCache();
|
||||
void GetDeviceDbFieldList( Types::StringVec & Fields);
|
||||
|
||||
bool ExistingConfiguration(std::string &SerialNumber, uint64_t CurrentConfig, std::string &NewConfig, uint64_t &);
|
||||
|
||||
@@ -128,10 +129,12 @@ namespace OpenWifi {
|
||||
bool DeleteCommand( std::string &UUID );
|
||||
bool GetReadyToExecuteCommands( uint64_t Offset, uint64_t HowMany, std::vector<GWObjects::CommandDetails> & Commands );
|
||||
bool CommandExecuted(std::string & UUID);
|
||||
bool CommandCompleted(std::string & UUID, const Poco::JSON::Object::Ptr & ReturnVars, const std::chrono::duration<double, std::milli> & execution_time, bool FullCommand);
|
||||
bool AttachFileToCommand(std::string & UUID);
|
||||
bool CommandCompleted(std::string & UUID, const Poco::JSON::Object & ReturnVars, const std::chrono::duration<double, std::milli> & execution_time, bool FullCommand);
|
||||
// bool AttachFileToCommand(std::string & UUID);
|
||||
bool AttachFileDataToCommand(std::string & UUID, const std::stringstream &s);
|
||||
bool CancelWaitFile( std::string & UUID, std::string & ErrorText );
|
||||
bool GetAttachedFile(std::string & UUID, const std::string & SerialNumber, const std::string & FileName, std::string &Type);
|
||||
// bool GetAttachedFile(std::string & UUID, const std::string & SerialNumber, const std::string & FileName, std::string &Type);
|
||||
bool GetAttachedFileContent(std::string & UUID, const std::string & SerialNumber, std::string & FileContent, std::string &Type);
|
||||
bool RemoveAttachedFile(std::string & UUID);
|
||||
bool SetCommandResult(std::string & UUID, std::string & Result);
|
||||
bool GetNewestCommands(std::string &SerialNumber, uint64_t HowMany, std::vector<GWObjects::CommandDetails> & Commands);
|
||||
|
||||
@@ -16,11 +16,14 @@ namespace OpenWifi {
|
||||
TelemetryClient::TelemetryClient(
|
||||
std::string UUID,
|
||||
uint64_t SerialNumber,
|
||||
Poco::SharedPtr<Poco::Net::WebSocket> WSock,
|
||||
std::unique_ptr<Poco::Net::WebSocket> WSock,
|
||||
Poco::Net::SocketReactor& Reactor,
|
||||
Poco::Logger &Logger):
|
||||
UUID_(std::move(UUID)), SerialNumber_(SerialNumber), WS_(std::move(WSock)),Reactor_(Reactor), Logger_(Logger) {
|
||||
std::cout << "Telemetry client creation" << std::endl;
|
||||
UUID_(std::move(UUID)),
|
||||
SerialNumber_(SerialNumber),
|
||||
Reactor_(Reactor),
|
||||
Logger_(Logger),
|
||||
WS_(std::move(WSock)) {
|
||||
try {
|
||||
std::thread T([this]() { this->CompleteStartup(); });
|
||||
T.detach();
|
||||
@@ -31,14 +34,11 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void TelemetryClient::CompleteStartup() {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
try {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
Socket_ = *WS_;
|
||||
CId_ = Utils::FormatIPv6(Socket_.peerAddress().toString());
|
||||
|
||||
// auto SS = static_cast<Poco::Net::SecureStreamSocketImpl*>((WS_->impl()));
|
||||
// SS->havePeerCertificate();
|
||||
|
||||
if (TelemetryStream()->RegisterClient(UUID_, this)) {
|
||||
auto TS = Poco::Timespan(240, 0);
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace OpenWifi {
|
||||
*WS_, Poco::NObserver<TelemetryClient, Poco::Net::ErrorNotification>(
|
||||
*this, &TelemetryClient::OnSocketError));
|
||||
Registered_ = true;
|
||||
Logger().information(Poco::format("CONNECTION(%s): completed.", CId_));
|
||||
Logger().information(fmt::format("CONNECTION({}): Connection completed.", CId_));
|
||||
return;
|
||||
}
|
||||
} catch (const Poco::Net::SSLException &E) {
|
||||
@@ -69,7 +69,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
TelemetryClient::~TelemetryClient() {
|
||||
Logger().information("Closing telemetry session.");
|
||||
Logger().information(fmt::format("CONNECTION({}): Closing connection.", CId_));
|
||||
if(Registered_ && WS_)
|
||||
{
|
||||
Reactor_.removeEventHandler(*WS_,
|
||||
@@ -81,23 +81,18 @@ namespace OpenWifi {
|
||||
Reactor_.removeEventHandler(*WS_,
|
||||
Poco::NObserver<TelemetryClient,
|
||||
Poco::Net::ErrorNotification>(*this,&TelemetryClient::OnSocketError));
|
||||
(*WS_).close();
|
||||
Socket_.shutdown();
|
||||
} else {
|
||||
if(WS_)
|
||||
(*WS_).close();
|
||||
Socket_.shutdown();
|
||||
}
|
||||
WS_->close();
|
||||
}
|
||||
|
||||
bool TelemetryClient::Send(const std::string &Payload) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
auto BytesSent = WS_->sendFrame(Payload.c_str(),(int)Payload.size());
|
||||
size_t BytesSent = WS_->sendFrame(Payload.c_str(),(int)Payload.size());
|
||||
return BytesSent == Payload.size();
|
||||
}
|
||||
|
||||
void TelemetryClient::SendTelemetryShutdown() {
|
||||
Logger().information(Poco::format("TELEMETRY-SHUTDOWN(%s): Closing.",CId_));
|
||||
Logger().information(fmt::format("TELEMETRY-SHUTDOWN({}): Closing.",CId_));
|
||||
auto Device = DeviceRegistry()->GetDeviceConnection(SerialNumber_);
|
||||
if(Device) {
|
||||
if(Device->WSConn_)
|
||||
@@ -107,22 +102,20 @@ namespace OpenWifi {
|
||||
delete this;
|
||||
}
|
||||
|
||||
void TelemetryClient::OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
Logger().information(Poco::format("SOCKET-SHUTDOWN(%s): Orderly shutdown.", CId_));
|
||||
void TelemetryClient::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf) {
|
||||
Logger().information(fmt::format("SOCKET-SHUTDOWN({}): Orderly shutdown.", CId_));
|
||||
SendTelemetryShutdown();
|
||||
}
|
||||
|
||||
void TelemetryClient::OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
Logger().information(Poco::format("SOCKET-ERROR(%s): Closing.",CId_));
|
||||
void TelemetryClient::OnSocketError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf) {
|
||||
Logger().information(fmt::format("SOCKET-ERROR({}): Closing.",CId_));
|
||||
SendTelemetryShutdown();
|
||||
}
|
||||
|
||||
void TelemetryClient::OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
void TelemetryClient::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
try
|
||||
{
|
||||
std::lock_guard Guard(Mutex_);
|
||||
ProcessIncomingFrame();
|
||||
}
|
||||
catch (const Poco::Exception & E)
|
||||
@@ -132,11 +125,11 @@ namespace OpenWifi {
|
||||
}
|
||||
catch (const std::exception & E) {
|
||||
std::string W = E.what();
|
||||
Logger().information(Poco::format("std::exception caught: %s. Connection terminated with %s",W,CId_));
|
||||
Logger().information(fmt::format("std::exception caught: {}. Connection terminated with {}",W,CId_));
|
||||
SendTelemetryShutdown();
|
||||
}
|
||||
catch ( ... ) {
|
||||
Logger().information(Poco::format("Unknown exception for %s. Connection terminated.",CId_));
|
||||
Logger().information(fmt::format("Unknown exception for {}. Connection terminated.",CId_));
|
||||
SendTelemetryShutdown();
|
||||
}
|
||||
}
|
||||
@@ -153,16 +146,16 @@ namespace OpenWifi {
|
||||
Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
||||
|
||||
if (IncomingSize == 0 && flags == 0 && Op == 0) {
|
||||
Logger().information(Poco::format("DISCONNECT(%s): device has disconnected.", CId_));
|
||||
Logger().information(fmt::format("DISCONNECT({}): device has disconnected.", CId_));
|
||||
MustDisconnect = true;
|
||||
} else {
|
||||
if (Op == Poco::Net::WebSocket::FRAME_OP_PING) {
|
||||
Logger().debug(Poco::format("WS-PING(%s): received. PONG sent back.", CId_));
|
||||
Logger().debug(fmt::format("WS-PING({}): received. PONG sent back.", CId_));
|
||||
WS_->sendFrame("", 0,
|
||||
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
|
||||
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
||||
} else if (Op == Poco::Net::WebSocket::FRAME_OP_CLOSE) {
|
||||
Logger().information(Poco::format("DISCONNECT(%s): device wants to disconnect.", CId_));
|
||||
Logger().information(fmt::format("DISCONNECT({}): device wants to disconnect.", CId_));
|
||||
MustDisconnect = true ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace OpenWifi {
|
||||
TelemetryClient(
|
||||
std::string UUID,
|
||||
uint64_t SerialNumber,
|
||||
Poco::SharedPtr<Poco::Net::WebSocket> WSock,
|
||||
std::unique_ptr<Poco::Net::WebSocket> WSock,
|
||||
Poco::Net::SocketReactor& Reactor,
|
||||
Poco::Logger &Logger);
|
||||
~TelemetryClient();
|
||||
@@ -40,7 +40,7 @@ namespace OpenWifi {
|
||||
Poco::Logger &Logger_;
|
||||
Poco::Net::StreamSocket Socket_;
|
||||
std::string CId_;
|
||||
Poco::SharedPtr<Poco::Net::WebSocket> WS_;
|
||||
std::unique_ptr<Poco::Net::WebSocket> WS_;
|
||||
bool Registered_=false;
|
||||
void SendTelemetryShutdown();
|
||||
void CompleteStartup();
|
||||
|
||||
@@ -16,13 +16,17 @@ namespace OpenWifi {
|
||||
int TelemetryStream::Start() {
|
||||
Running_ = true;
|
||||
Messages_->Readable_ += Poco::delegate(this,&TelemetryStream::onMessage);
|
||||
ReactorPool_.Start("TelemetryWebSocketPool_");
|
||||
// ReactorPool_.Start("TelemetryWebSocketPool_");
|
||||
Thr_.start(Reactor_);
|
||||
Utils::SetThreadName(Thr_,"telemetry-svr");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TelemetryStream::Stop() {
|
||||
Logger().notice("Stopping reactors...");
|
||||
ReactorPool_.Stop();
|
||||
// ReactorPool_.Stop();
|
||||
Reactor_.stop();
|
||||
Thr_.join();
|
||||
if(Running_) {
|
||||
Running_ = false;
|
||||
Messages_->Readable_ -= Poco::delegate( this, &TelemetryStream::onMessage);
|
||||
@@ -129,7 +133,4 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -47,16 +47,17 @@ namespace OpenWifi {
|
||||
void UpdateEndPoint(uint64_t SerialNumber, const std::string &PayLoad);
|
||||
bool RegisterClient(const std::string &UUID, TelemetryClient *Client);
|
||||
void DeRegisterClient(const std::string &UUID);
|
||||
Poco::Net::SocketReactor & NextReactor() { return ReactorPool_.NextReactor(); }
|
||||
Poco::Net::SocketReactor & NextReactor() { return Reactor_; }
|
||||
|
||||
void onMessage(bool& b);
|
||||
|
||||
private:
|
||||
std::atomic_bool Running_=false;
|
||||
volatile std::atomic_bool Running_=false;
|
||||
std::map<std::string, TelemetryClient *> Clients_; // uuid -> client
|
||||
std::map<uint64_t, std::set<std::string>> SerialNumbers_; // serialNumber -> uuid
|
||||
ReactorPool ReactorPool_;
|
||||
Poco::Net::SocketReactor Reactor_;
|
||||
std::unique_ptr<FIFO<QueueUpdate>> Messages_=std::make_unique<FIFO<QueueUpdate>>(100);
|
||||
Poco::Thread Thr_;
|
||||
|
||||
TelemetryStream() noexcept:
|
||||
SubSystemServer("TelemetryServer", "TELEMETRY-SVR", "openwifi.telemetry") {
|
||||
|
||||
142
src/VenueBroadcaster.h
Normal file
142
src/VenueBroadcaster.h
Normal file
@@ -0,0 +1,142 @@
|
||||
//
|
||||
// Created by stephane bourque on 2022-07-16.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "sdks/sdk_prov.h"
|
||||
#include "DeviceRegistry.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class VenueBroadcastNotification : public Poco::Notification {
|
||||
public:
|
||||
VenueBroadcastNotification(const std::string &SourceSerialNumber, const std::string &Data, uint64_t TimeStamp) :
|
||||
SourceSerialNumber_(SourceSerialNumber),
|
||||
Data_(Data),
|
||||
TimeStamp_(TimeStamp) {
|
||||
|
||||
}
|
||||
std::string SourceSerialNumber_;
|
||||
std::string Data_;
|
||||
uint64_t TimeStamp_=OpenWifi::Now();
|
||||
};
|
||||
|
||||
class VenueBroadcaster : public SubSystemServer, Poco::Runnable {
|
||||
public:
|
||||
static auto instance() {
|
||||
static auto instance_ = new VenueBroadcaster;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
inline int Start() override {
|
||||
Enabled_ = MicroService::instance().ConfigGetBool("venue_broadcast.enabled",true);
|
||||
if(Enabled_) {
|
||||
BroadcastManager_.start(*this);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void Stop() override {
|
||||
if(Enabled_ && Running_) {
|
||||
BroadcastQueue_.wakeUpAll();
|
||||
BroadcastManager_.wakeUp();
|
||||
BroadcastManager_.join();
|
||||
}
|
||||
}
|
||||
|
||||
inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
|
||||
Logger().information("Reinitializing.");
|
||||
}
|
||||
|
||||
|
||||
struct VenueInfo {
|
||||
uint64_t timestamp=OpenWifi::Now();
|
||||
Types::StringVec serialNumbers;
|
||||
};
|
||||
|
||||
inline bool FindSerialNumberList(const std::string &Source, OpenWifi::Types::StringVec & SerialNumbers) {
|
||||
// Can we find our serial number in any of the lists so far...
|
||||
for(const auto &venue:Venues_) {
|
||||
auto entry = std::find(venue.second.serialNumbers.begin(),venue.second.serialNumbers.end(),Source);
|
||||
if(entry!=venue.second.serialNumbers.end() && (OpenWifi::Now()-venue.second.timestamp)<600) {
|
||||
SerialNumbers = venue.second.serialNumbers;
|
||||
auto entry2 = std::find(SerialNumbers.begin(),SerialNumbers.end(),Source);
|
||||
SerialNumbers.erase(entry2);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// get the venue from Prov and the serial numbers.
|
||||
Types::UUID_t Venue;
|
||||
Types::StringVec TmpSerialNumbers;
|
||||
if(OpenWifi::SDK::Prov::GetSerialNumbersForVenueOfSerialNumber(Source,Venue,TmpSerialNumbers,Logger())) {
|
||||
std::sort(TmpSerialNumbers.begin(),TmpSerialNumbers.end());
|
||||
VenueInfo V{.timestamp=OpenWifi::Now(), .serialNumbers=TmpSerialNumbers};
|
||||
Venues_[Venue] = V;
|
||||
auto p = std::find(TmpSerialNumbers.begin(),TmpSerialNumbers.end(),Source);
|
||||
if(p!=TmpSerialNumbers.end()) {
|
||||
TmpSerialNumbers.erase(p);
|
||||
SerialNumbers = TmpSerialNumbers;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void SendToDevice(const std::string &SerialNumber,const std::string &Payload) {
|
||||
DeviceRegistry()->SendFrame(SerialNumber,Payload);
|
||||
}
|
||||
|
||||
inline void run() final {
|
||||
Running_ = true;
|
||||
Utils::SetThreadName("venue-bcast");
|
||||
Poco::AutoPtr<Poco::Notification> NextNotification(BroadcastQueue_.waitDequeueNotification());
|
||||
while (NextNotification && Running_) {
|
||||
auto Notification = dynamic_cast<VenueBroadcastNotification *>(NextNotification.get());
|
||||
if (Notification != nullptr) {
|
||||
Types::StringVec SerialNumbers;
|
||||
if(FindSerialNumberList(Notification->SourceSerialNumber_,SerialNumbers)) {
|
||||
Poco::JSON::Object Payload;
|
||||
Payload.set("jsonrpc","2.0");
|
||||
Payload.set("method","venue_broadcast");
|
||||
Poco::JSON::Object ParamBlock;
|
||||
ParamBlock.set("serial",Notification->SourceSerialNumber_);
|
||||
ParamBlock.set("timestamp",Notification->TimeStamp_);
|
||||
ParamBlock.set("data",Notification->Data_);
|
||||
Payload.set("params", ParamBlock);
|
||||
std::ostringstream o;
|
||||
Payload.stringify(o);
|
||||
for(const auto &Device:SerialNumbers) {
|
||||
SendToDevice(Device,o.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
NextNotification = BroadcastQueue_.waitDequeueNotification();
|
||||
}
|
||||
Running_=false;
|
||||
}
|
||||
|
||||
inline void Broadcast(const std::string &SourceSerial, const std::string &Data, uint64_t TimeStamp) {
|
||||
BroadcastQueue_.enqueueNotification(new VenueBroadcastNotification(SourceSerial,Data,TimeStamp));
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
std::atomic_bool Running_=false;
|
||||
bool Enabled_=false;
|
||||
Poco::NotificationQueue BroadcastQueue_;
|
||||
Poco::Thread BroadcastManager_;
|
||||
|
||||
std::map<OpenWifi::Types::UUID_t,VenueInfo> Venues_;
|
||||
|
||||
VenueBroadcaster() noexcept:
|
||||
SubSystemServer("VenueBroadcaster", "VENUE-BCAST", "venue.broacast")
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
inline auto VenueBroadcaster() { return VenueBroadcaster::instance(); }
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,74 +17,81 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class WSConnection {
|
||||
static constexpr int BufSize = 128000;
|
||||
public:
|
||||
WSConnection(Poco::Net::StreamSocket& Socket, Poco::Net::SocketReactor& Reactor);
|
||||
~WSConnection();
|
||||
class WSConnection {
|
||||
static constexpr int BufSize = 128000;
|
||||
public:
|
||||
WSConnection(Poco::Net::StreamSocket& Socket, Poco::Net::SocketReactor& Reactor);
|
||||
~WSConnection();
|
||||
|
||||
void ProcessJSONRPCEvent(Poco::JSON::Object::Ptr & Doc);
|
||||
void ProcessJSONRPCResult(Poco::JSON::Object::Ptr & Doc);
|
||||
void ProcessIncomingFrame();
|
||||
bool Send(const std::string &Payload);
|
||||
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
||||
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf);
|
||||
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf);
|
||||
bool LookForUpgrade(uint64_t UUID);
|
||||
static bool ExtractBase64CompressedData(const std::string & CompressedData, std::string & UnCompressedData, uint64_t compress_sz);
|
||||
void LogException(const Poco::Exception &E);
|
||||
inline Poco::Logger & Logger() { return Logger_; }
|
||||
bool SetWebSocketTelemetryReporting(uint64_t interval, uint64_t TelemetryWebSocketTimer);
|
||||
bool SetKafkaTelemetryReporting(uint64_t interval, uint64_t TelemetryKafkaTimer);
|
||||
bool StopWebSocketTelemetry();
|
||||
bool StopKafkaTelemetry();
|
||||
inline bool GetTelemetryParameters(bool & Reporting, uint64_t & Interval,
|
||||
uint64_t & WebSocketTimer, uint64_t & KafkaTimer,
|
||||
uint64_t &WebSocketCount, uint64_t & KafkaCount,
|
||||
uint64_t &WebSocketPackets,
|
||||
uint64_t &KafkaPackets ) const {
|
||||
Reporting = TelemetryReporting_;
|
||||
WebSocketTimer = TelemetryWebSocketTimer_;
|
||||
KafkaTimer = TelemetryKafkaTimer_;
|
||||
WebSocketCount = TelemetryWebSocketRefCount_;
|
||||
KafkaCount = TelemetryKafkaRefCount_;
|
||||
Interval = TelemetryInterval_;
|
||||
WebSocketPackets = TelemetryWebSocketPackets_;
|
||||
KafkaPackets = TelemetryKafkaPackets_;
|
||||
return true;
|
||||
}
|
||||
void ProcessJSONRPCEvent(Poco::JSON::Object::Ptr & Doc);
|
||||
void ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc);
|
||||
void ProcessIncomingFrame();
|
||||
void ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc);
|
||||
|
||||
private:
|
||||
std::recursive_mutex Mutex_;
|
||||
Poco::Logger &Logger_;
|
||||
Poco::Net::StreamSocket Socket_;
|
||||
Poco::Net::SocketReactor & Reactor_;
|
||||
std::unique_ptr<Poco::Net::WebSocket> WS_;
|
||||
std::string SerialNumber_;
|
||||
uint64_t SerialNumberInt_=0;
|
||||
std::string Compatible_;
|
||||
std::shared_ptr<DeviceRegistry::ConnectionEntry> Conn_;
|
||||
bool Registered_ = false ;
|
||||
std::string CId_;
|
||||
std::string CN_;
|
||||
GWObjects::CertificateValidation CertValidation_ = GWObjects::CertificateValidation::NO_CERTIFICATE;
|
||||
uint64_t Errors_=0;
|
||||
bool Connected_=false;
|
||||
uint64_t ConnectionId_=0;
|
||||
Poco::Net::IPAddress PeerAddress_;
|
||||
mutable std::atomic_bool TelemetryReporting_ = false;
|
||||
mutable uint64_t TelemetryWebSocketRefCount_ = 0;
|
||||
mutable uint64_t TelemetryKafkaRefCount_ = 0;
|
||||
mutable uint64_t TelemetryWebSocketTimer_ = 0;
|
||||
mutable uint64_t TelemetryKafkaTimer_ = 0 ;
|
||||
mutable uint64_t TelemetryInterval_ = 0;
|
||||
mutable uint64_t TelemetryWebSocketPackets_=0;
|
||||
mutable uint64_t TelemetryKafkaPackets_=0;
|
||||
bool Send(const std::string &Payload);
|
||||
|
||||
void CompleteStartup();
|
||||
bool StartTelemetry();
|
||||
bool StopTelemetry();
|
||||
void UpdateCounts();
|
||||
};
|
||||
bool SendRadiusAuthenticationData(const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusAccountingData(const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusCoAData(const unsigned char * buffer, std::size_t size);
|
||||
|
||||
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
||||
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf);
|
||||
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf);
|
||||
bool LookForUpgrade(const uint64_t UUID, uint64_t & UpgradedUUID);
|
||||
static bool ExtractBase64CompressedData(const std::string & CompressedData, std::string & UnCompressedData, uint64_t compress_sz);
|
||||
void LogException(const Poco::Exception &E);
|
||||
inline Poco::Logger & Logger() { return Logger_; }
|
||||
bool SetWebSocketTelemetryReporting(uint64_t interval, uint64_t TelemetryWebSocketTimer);
|
||||
bool SetKafkaTelemetryReporting(uint64_t interval, uint64_t TelemetryKafkaTimer);
|
||||
bool StopWebSocketTelemetry();
|
||||
bool StopKafkaTelemetry();
|
||||
inline bool GetTelemetryParameters(bool & Reporting, uint64_t & Interval,
|
||||
uint64_t & WebSocketTimer, uint64_t & KafkaTimer,
|
||||
uint64_t &WebSocketCount, uint64_t & KafkaCount,
|
||||
uint64_t &WebSocketPackets,
|
||||
uint64_t &KafkaPackets ) const {
|
||||
Reporting = TelemetryReporting_;
|
||||
WebSocketTimer = TelemetryWebSocketTimer_;
|
||||
KafkaTimer = TelemetryKafkaTimer_;
|
||||
WebSocketCount = TelemetryWebSocketRefCount_;
|
||||
KafkaCount = TelemetryKafkaRefCount_;
|
||||
Interval = TelemetryInterval_;
|
||||
WebSocketPackets = TelemetryWebSocketPackets_;
|
||||
KafkaPackets = TelemetryKafkaPackets_;
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::recursive_mutex Mutex_;
|
||||
Poco::Logger &Logger_;
|
||||
Poco::Net::StreamSocket Socket_;
|
||||
Poco::Net::SocketReactor & Reactor_;
|
||||
std::unique_ptr<Poco::Net::WebSocket> WS_;
|
||||
std::string SerialNumber_;
|
||||
uint64_t SerialNumberInt_=0;
|
||||
std::string Compatible_;
|
||||
std::shared_ptr<DeviceRegistry::ConnectionEntry> Conn_;
|
||||
volatile bool Registered_ = false ;
|
||||
std::string CId_;
|
||||
std::string CN_;
|
||||
GWObjects::CertificateValidation CertValidation_ = GWObjects::CertificateValidation::NO_CERTIFICATE;
|
||||
uint64_t Errors_=0;
|
||||
volatile bool Connected_=false;
|
||||
uint64_t ConnectionId_=0;
|
||||
Poco::Net::IPAddress PeerAddress_;
|
||||
volatile std::atomic_bool TelemetryReporting_ = false;
|
||||
volatile uint64_t TelemetryWebSocketRefCount_ = 0;
|
||||
volatile uint64_t TelemetryKafkaRefCount_ = 0;
|
||||
uint64_t TelemetryWebSocketTimer_ = 0;
|
||||
uint64_t TelemetryKafkaTimer_ = 0 ;
|
||||
uint64_t TelemetryInterval_ = 0;
|
||||
volatile uint64_t TelemetryWebSocketPackets_=0;
|
||||
volatile uint64_t TelemetryKafkaPackets_=0;
|
||||
|
||||
void CompleteStartup();
|
||||
bool StartTelemetry();
|
||||
bool StopTelemetry();
|
||||
void UpdateCounts();
|
||||
};
|
||||
|
||||
}
|
||||
@@ -9,22 +9,38 @@
|
||||
#include "Poco/Environment.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class ReactorPool {
|
||||
class ReactorThreadPool {
|
||||
public:
|
||||
explicit ReactorPool(unsigned int NumberOfThreads = Poco::Environment::processorCount())
|
||||
: NumberOfThreads_(NumberOfThreads) {}
|
||||
explicit ReactorThreadPool() {
|
||||
if(Poco::Environment::processorCount()>8)
|
||||
NumberOfThreads_ = Poco::Environment::processorCount()/2;
|
||||
else
|
||||
NumberOfThreads_ = 2;
|
||||
Start("ReactorThreadPool");
|
||||
}
|
||||
|
||||
~ ReactorThreadPool() {
|
||||
Stop();
|
||||
}
|
||||
|
||||
void Start(const std::string & ThreadNamePrefix) {
|
||||
for (auto i = 0; i < NumberOfThreads_; ++i) {
|
||||
for (uint64_t i = 0; i < NumberOfThreads_; ++i) {
|
||||
auto NewReactor = std::make_unique<Poco::Net::SocketReactor>();
|
||||
auto NewThread = std::make_unique<Poco::Thread>();
|
||||
NewThread->setStackSize(2000000);
|
||||
NewThread->start(*NewReactor);
|
||||
NewThread->setName(ThreadNamePrefix + std::to_string(i));
|
||||
std::string ThreadName{ThreadNamePrefix + "#" + std::to_string(i)};
|
||||
Utils::SetThreadName(*NewThread,ThreadName.c_str());
|
||||
Reactors_.emplace_back(std::move(NewReactor));
|
||||
Threads_.emplace_back(std::move(NewThread));
|
||||
}
|
||||
}
|
||||
|
||||
inline static auto instance() {
|
||||
static auto instance_ = new ReactorThreadPool;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
void Stop() {
|
||||
for (auto &i : Reactors_)
|
||||
i->stop();
|
||||
@@ -34,15 +50,18 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
Poco::Net::SocketReactor &NextReactor() {
|
||||
std::lock_guard G(Mutex_);
|
||||
NextReactor_++;
|
||||
NextReactor_ %= NumberOfThreads_;
|
||||
return *Reactors_[NextReactor_];
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int NumberOfThreads_;
|
||||
unsigned int NextReactor_ = 0;
|
||||
std::mutex Mutex_;
|
||||
uint64_t NumberOfThreads_;
|
||||
uint64_t NextReactor_ = 0;
|
||||
std::vector<std::unique_ptr<Poco::Net::SocketReactor>> Reactors_;
|
||||
std::vector<std::unique_ptr<Poco::Thread>> Threads_;
|
||||
};
|
||||
inline auto ReactorThreadPool() { return ReactorThreadPool::instance(); }
|
||||
}
|
||||
@@ -8,71 +8,77 @@
|
||||
|
||||
#include "Poco/Net/HTTPHeaderStream.h"
|
||||
#include "Poco/JSON/Array.h"
|
||||
#include "Poco/Net/Context.h"
|
||||
|
||||
#include "ConfigurationCache.h"
|
||||
#include "TelemetryStream.h"
|
||||
#include "WS_Server.h"
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
bool WebSocketServer::ValidateCertificate(const std::string & ConnectionId, const Poco::Crypto::X509Certificate & Certificate) {
|
||||
if(IsCertOk()) {
|
||||
Logger().debug(Poco::format("CERTIFICATE(%s): issuer='%s' cn='%s'", ConnectionId, Certificate.issuerName(),Certificate.commonName()));
|
||||
if(!Certificate.issuedBy(*IssuerCert_)) {
|
||||
Logger().debug(Poco::format("CERTIFICATE(%s): issuer mismatch. Local='%s' Incoming='%s'", ConnectionId, IssuerCert_->issuerName(), Certificate.issuerName()));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
bool WebSocketServer::ValidateCertificate(const std::string & ConnectionId, const Poco::Crypto::X509Certificate & Certificate) {
|
||||
if(IsCertOk()) {
|
||||
Logger().debug(fmt::format("CERTIFICATE({}): issuer='{}' cn='{}'", ConnectionId, Certificate.issuerName(),Certificate.commonName()));
|
||||
if(!Certificate.issuedBy(*IssuerCert_)) {
|
||||
Logger().debug(fmt::format("CERTIFICATE({}): issuer mismatch. Local='{}' Incoming='{}'", ConnectionId, IssuerCert_->issuerName(), Certificate.issuerName()));
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int WebSocketServer::Start() {
|
||||
// ReactorPool_.Start("DeviceReactorPool_");
|
||||
for(const auto & Svr : ConfigServersList_ ) {
|
||||
Logger().notice( fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}",
|
||||
Svr.Address(),
|
||||
Svr.Port(),
|
||||
Svr.KeyFile(),Svr.CertFile()));
|
||||
|
||||
Svr.LogCert(Logger());
|
||||
if(!Svr.RootCA().empty())
|
||||
Svr.LogCas(Logger());
|
||||
|
||||
auto Sock{Svr.CreateSecureSocket(Logger())};
|
||||
|
||||
if(!IsCertOk()) {
|
||||
IssuerCert_ = std::make_unique<Poco::Crypto::X509Certificate>(Svr.IssuerCertFile());
|
||||
Logger().information( fmt::format("Certificate Issuer Name:{}",IssuerCert_->issuerName()));
|
||||
}
|
||||
auto NewSocketAcceptor = std::make_unique<ws_server_reactor_type_t>(Sock, Reactor_); // , 2 /*Poco::Environment::processorCount()*2) */ );
|
||||
Acceptors_.push_back(std::move(NewSocketAcceptor));
|
||||
}
|
||||
|
||||
int WebSocketServer::Start() {
|
||||
ReactorPool_.Start("DeviceReactorPool_");
|
||||
for(const auto & Svr : ConfigServersList_ ) {
|
||||
Logger().notice(Poco::format("Starting: %s:%s Keyfile:%s CertFile: %s", Svr.Address(), std::to_string(Svr.Port()),
|
||||
Svr.KeyFile(),Svr.CertFile()));
|
||||
|
||||
Svr.LogCert(Logger());
|
||||
if(!Svr.RootCA().empty())
|
||||
Svr.LogCas(Logger());
|
||||
|
||||
auto Sock{Svr.CreateSecureSocket(Logger())};
|
||||
|
||||
if(!IsCertOk()) {
|
||||
IssuerCert_ = std::make_unique<Poco::Crypto::X509Certificate>(Svr.IssuerCertFile());
|
||||
Logger().information(Poco::format("Certificate Issuer Name:%s",IssuerCert_->issuerName()));
|
||||
}
|
||||
auto NewSocketAcceptor = std::make_unique<Poco::Net::ParallelSocketAcceptor<WSConnection, Poco::Net::SocketReactor>>(Sock, Reactor_, Poco::Environment::processorCount()*2);
|
||||
Acceptors_.push_back(std::move(NewSocketAcceptor));
|
||||
}
|
||||
|
||||
auto ProvString = MicroService::instance().ConfigGetString("autoprovisioning.process","default");
|
||||
if(ProvString!="default") {
|
||||
auto Tokens = Poco::StringTokenizer(ProvString, ",");
|
||||
for (const auto &i : Tokens) {
|
||||
if (i == "prov")
|
||||
LookAtProvisioning_ = true;
|
||||
else
|
||||
UseDefaultConfig_ = true;
|
||||
}
|
||||
} else {
|
||||
UseDefaultConfig_ = true;
|
||||
auto ProvString = MicroService::instance().ConfigGetString("autoprovisioning.process","default");
|
||||
if(ProvString!="default") {
|
||||
auto Tokens = Poco::StringTokenizer(ProvString, ",");
|
||||
for (const auto &i : Tokens) {
|
||||
if (i == "prov")
|
||||
LookAtProvisioning_ = true;
|
||||
else
|
||||
UseDefaultConfig_ = true;
|
||||
}
|
||||
} else {
|
||||
UseDefaultConfig_ = true;
|
||||
}
|
||||
|
||||
SimulatorId_ = MicroService::instance().ConfigGetString("simulatorid","");
|
||||
SimulatorEnabled_ = !SimulatorId_.empty();
|
||||
SimulatorId_ = MicroService::instance().ConfigGetString("simulatorid","");
|
||||
SimulatorEnabled_ = !SimulatorId_.empty();
|
||||
|
||||
ReactorThread_.start(Reactor_);
|
||||
ReactorThread_.setStackSize(3000000);
|
||||
ReactorThread_.start(Reactor_);
|
||||
Utils::SetThreadName(ReactorThread_,"device-reactor");
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WebSocketServer::Stop() {
|
||||
Logger().notice("Stopping reactors...");
|
||||
ReactorPool_.Stop();
|
||||
Reactor_.stop();
|
||||
ReactorThread_.join();
|
||||
}
|
||||
void WebSocketServer::Stop() {
|
||||
Logger().notice("Stopping reactors...");
|
||||
// ReactorPool_.Stop();
|
||||
Reactor_.stop();
|
||||
ReactorThread_.join();
|
||||
}
|
||||
|
||||
} //namespace
|
||||
} //namespace
|
||||
@@ -18,57 +18,59 @@
|
||||
#include "Poco/AutoPtr.h"
|
||||
#include "Poco/Net/SocketReactor.h"
|
||||
#include "Poco/Net/ParallelSocketAcceptor.h"
|
||||
#include "Poco/Net/SocketAcceptor.h"
|
||||
|
||||
#include "WS_Connection.h"
|
||||
#include "WS_ReactorPool.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class WebSocketServer : public SubSystemServer {
|
||||
public:
|
||||
static auto instance() {
|
||||
static auto instance_ = new WebSocketServer;
|
||||
return instance_;
|
||||
}
|
||||
class WebSocketServer : public SubSystemServer {
|
||||
public:
|
||||
static auto instance() {
|
||||
static auto instance_ = new WebSocketServer;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
bool IsCertOk() { return IssuerCert_!= nullptr; }
|
||||
bool ValidateCertificate(const std::string & ConnectionId, const Poco::Crypto::X509Certificate & Certificate);
|
||||
Poco::Net::SocketReactor & GetNextReactor() { return ReactorPool_.NextReactor(); }
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
bool IsCertOk() { return IssuerCert_!= nullptr; }
|
||||
bool ValidateCertificate(const std::string & ConnectionId, const Poco::Crypto::X509Certificate & Certificate);
|
||||
// Poco::Net::SocketReactor & GetNextReactor() { return ReactorPool_.NextReactor(); }
|
||||
|
||||
inline bool IsSimSerialNumber(const std::string & SerialNumber) const {
|
||||
return IsSim(SerialNumber) && SerialNumber == SimulatorId_;
|
||||
}
|
||||
inline bool IsSimSerialNumber(const std::string & SerialNumber) const {
|
||||
return IsSim(SerialNumber) && SerialNumber == SimulatorId_;
|
||||
}
|
||||
|
||||
inline static bool IsSim(const std::string & SerialNumber) {
|
||||
return SerialNumber.substr(0,6) == "53494d";
|
||||
}
|
||||
inline static bool IsSim(const std::string & SerialNumber) {
|
||||
return SerialNumber.substr(0,6) == "53494d";
|
||||
}
|
||||
|
||||
inline bool IsSimEnabled() const {
|
||||
return SimulatorEnabled_;
|
||||
}
|
||||
inline bool IsSimEnabled() const {
|
||||
return SimulatorEnabled_;
|
||||
}
|
||||
|
||||
inline bool UseProvisioning() const { return LookAtProvisioning_; }
|
||||
inline bool UseDefaults() const { return UseDefaultConfig_; }
|
||||
inline bool UseProvisioning() const { return LookAtProvisioning_; }
|
||||
inline bool UseDefaults() const { return UseDefaultConfig_; }
|
||||
|
||||
private:
|
||||
std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_;
|
||||
std::vector<std::unique_ptr<Poco::Net::ParallelSocketAcceptor<WSConnection, Poco::Net::SocketReactor>>> Acceptors_;
|
||||
Poco::Net::SocketReactor Reactor_;
|
||||
Poco::Thread ReactorThread_;
|
||||
ReactorPool ReactorPool_;
|
||||
std::string SimulatorId_;
|
||||
bool LookAtProvisioning_ = false;
|
||||
bool UseDefaultConfig_ = true;
|
||||
bool SimulatorEnabled_=false;
|
||||
private:
|
||||
std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_;
|
||||
// typedef std::unique_ptr<Poco::Net::ParallelSocketAcceptor<WSConnection, Poco::Net::SocketReactor>> ws_server_reactor_type_t;
|
||||
typedef Poco::Net::SocketAcceptor<WSConnection> ws_server_reactor_type_t;
|
||||
std::vector<std::unique_ptr<ws_server_reactor_type_t>> Acceptors_;
|
||||
Poco::Net::SocketReactor Reactor_;
|
||||
Poco::Thread ReactorThread_;
|
||||
std::string SimulatorId_;
|
||||
bool LookAtProvisioning_ = false;
|
||||
bool UseDefaultConfig_ = true;
|
||||
bool SimulatorEnabled_=false;
|
||||
|
||||
WebSocketServer() noexcept:
|
||||
SubSystemServer("WebSocketServer", "WS-SVR", "ucentral.websocket") {
|
||||
WebSocketServer() noexcept:
|
||||
SubSystemServer("WebSocketServer", "WS-SVR", "ucentral.websocket") {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
inline auto WebSocketServer() { return WebSocketServer::instance(); }
|
||||
inline auto WebSocketServer() { return WebSocketServer::instance(); }
|
||||
|
||||
} //namespace
|
||||
} //namespace
|
||||
@@ -13,9 +13,10 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
static const std::string GitUCentralJSONSchemaFile{"https://raw.githubusercontent.com/blogic/ucentral-schema/main/ucentral.schema.json"};
|
||||
static const std::string GitUCentralJSONSchemaFile{
|
||||
"https://raw.githubusercontent.com/blogic/ucentral-schema/main/ucentral.schema.json"};
|
||||
|
||||
static json DefaultUCentralSchema = R"(
|
||||
static json DefaultUCentralSchema = R"(
|
||||
|
||||
{
|
||||
"$id": "https://openwrt.org/ucentral.schema.json",
|
||||
@@ -418,7 +419,7 @@ namespace OpenWifi {
|
||||
},
|
||||
"allow-dfs": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
"default": true
|
||||
},
|
||||
"channel-mode": {
|
||||
"type": "string",
|
||||
@@ -518,7 +519,7 @@ namespace OpenWifi {
|
||||
"maximum": 4050
|
||||
},
|
||||
"proto": {
|
||||
"decription": "The L2 vlan tag that shall be added (1q,1ad) ",
|
||||
"decription": "The L2 vlan tag that shall be added (1q,1ad ) ",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"802.1ad",
|
||||
@@ -669,6 +670,47 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
},
|
||||
"interface.ipv4.port-forward": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"protocol": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"tcp",
|
||||
"udp",
|
||||
"any"
|
||||
],
|
||||
"default": "any"
|
||||
},
|
||||
"external-port": {
|
||||
"type": [
|
||||
"integer",
|
||||
"string"
|
||||
],
|
||||
"minimum": 0,
|
||||
"maximum": 65535,
|
||||
"format": "uc-portrange"
|
||||
},
|
||||
"internal-address": {
|
||||
"type": "string",
|
||||
"format": "ipv4",
|
||||
"example": "0.0.0.120"
|
||||
},
|
||||
"internal-port": {
|
||||
"type": [
|
||||
"integer",
|
||||
"string"
|
||||
],
|
||||
"minimum": 0,
|
||||
"maximum": 65535,
|
||||
"format": "uc-portrange"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"external-port",
|
||||
"internal-address"
|
||||
]
|
||||
},
|
||||
"interface.ipv4": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -722,6 +764,12 @@ namespace OpenWifi {
|
||||
"items": {
|
||||
"$ref": "#/$defs/interface.ipv4.dhcp-lease"
|
||||
}
|
||||
},
|
||||
"port-forward": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/interface.ipv4.port-forward"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -751,6 +799,96 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
},
|
||||
"interface.ipv6.port-forward": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"protocol": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"tcp",
|
||||
"udp",
|
||||
"any"
|
||||
],
|
||||
"default": "any"
|
||||
},
|
||||
"external-port": {
|
||||
"type": [
|
||||
"integer",
|
||||
"string"
|
||||
],
|
||||
"minimum": 0,
|
||||
"maximum": 65535,
|
||||
"format": "uc-portrange"
|
||||
},
|
||||
"internal-address": {
|
||||
"type": "string",
|
||||
"format": "ipv6",
|
||||
"example": "::1234:abcd"
|
||||
},
|
||||
"internal-port": {
|
||||
"type": [
|
||||
"integer",
|
||||
"string"
|
||||
],
|
||||
"minimum": 0,
|
||||
"maximum": 65535,
|
||||
"format": "uc-portrange"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"external-port",
|
||||
"internal-address"
|
||||
]
|
||||
},
|
||||
"interface.ipv6.traffic-allow": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"protocol": {
|
||||
"type": "string",
|
||||
"default": "any"
|
||||
},
|
||||
"source-address": {
|
||||
"type": "string",
|
||||
"format": "uc-cidr6",
|
||||
"example": "2001:db8:1234:abcd::/64",
|
||||
"default": "::/0"
|
||||
},
|
||||
"source-ports": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": [
|
||||
"integer",
|
||||
"string"
|
||||
],
|
||||
"minimum": 0,
|
||||
"maximum": 65535,
|
||||
"format": "uc-portrange"
|
||||
}
|
||||
},
|
||||
"destination-address": {
|
||||
"type": "string",
|
||||
"format": "ipv6",
|
||||
"example": "::1000"
|
||||
},
|
||||
"destination-ports": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": [
|
||||
"integer",
|
||||
"string"
|
||||
],
|
||||
"minimum": 0,
|
||||
"maximum": 65535,
|
||||
"format": "uc-portrange"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"destination-address"
|
||||
]
|
||||
},
|
||||
"interface.ipv6": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -782,6 +920,18 @@ namespace OpenWifi {
|
||||
},
|
||||
"dhcpv6": {
|
||||
"$ref": "#/$defs/interface.ipv6.dhcpv6"
|
||||
},
|
||||
"port-forward": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/interface.ipv6.port-forward"
|
||||
}
|
||||
},
|
||||
"traffic-allow": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/$defs/interface.ipv6.traffic-allow"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -866,7 +1016,7 @@ namespace OpenWifi {
|
||||
},
|
||||
"gateway-fqdn": {
|
||||
"type": "string",
|
||||
"format": "fqdn",
|
||||
"format": "uc-fqdn",
|
||||
"default": "ucentral.splash"
|
||||
},
|
||||
"max-clients": {
|
||||
@@ -901,6 +1051,7 @@ namespace OpenWifi {
|
||||
"psk",
|
||||
"psk2",
|
||||
"psk-mixed",
|
||||
"psk2-radius",
|
||||
"wpa",
|
||||
"wpa2",
|
||||
"wpa-mixed",
|
||||
@@ -961,6 +1112,10 @@ namespace OpenWifi {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"reduced-neighbor-reporting": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"lci": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -1527,6 +1682,11 @@ namespace OpenWifi {
|
||||
"decription": "This option allows embedding custom vendor specific IEs inside the beacons of a BSS in AP mode.",
|
||||
"type": "string"
|
||||
},
|
||||
"fils-discovery-interval": {
|
||||
"type": "integer",
|
||||
"default": 20,
|
||||
"maximum": 10000
|
||||
},
|
||||
"encryption": {
|
||||
"$ref": "#/$defs/interface.ssid.encryption"
|
||||
},
|
||||
@@ -2087,6 +2247,10 @@ namespace OpenWifi {
|
||||
"auto-channel": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"ipv6": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2193,7 +2357,7 @@ namespace OpenWifi {
|
||||
"properties": {
|
||||
"fqdn": {
|
||||
"type": "string",
|
||||
"format": "fqdn"
|
||||
"format": "uc-fqdn"
|
||||
},
|
||||
"suffix-matching": {
|
||||
"type": "boolean",
|
||||
@@ -2444,7 +2608,7 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
}
|
||||
)"_json;
|
||||
)"_json;
|
||||
|
||||
class custom_error_handler : public nlohmann::json_schema::basic_error_handler
|
||||
{
|
||||
@@ -2459,9 +2623,18 @@ namespace OpenWifi {
|
||||
void ConfigurationValidator::Init() {
|
||||
if(Initialized_)
|
||||
return;
|
||||
|
||||
std::string GitSchema;
|
||||
if(MicroService::instance().ConfigGetBool("ucentral.datamodel.internal",true)) {
|
||||
RootSchema_ = DefaultUCentralSchema;
|
||||
Logger().information("Using uCentral validation from built-in default.");
|
||||
Initialized_ = Working_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if(Utils::wgets(GitUCentralJSONSchemaFile, GitSchema)) {
|
||||
auto GitURI = MicroService::instance().ConfigGetString("ucentral.datamodel.uri",GitUCentralJSONSchemaFile);
|
||||
if(Utils::wgets(GitURI, GitSchema)) {
|
||||
RootSchema_ = json::parse(GitSchema);
|
||||
Logger().information("Using uCentral validation schema from GIT.");
|
||||
} else {
|
||||
@@ -2527,6 +2700,17 @@ namespace OpenWifi {
|
||||
return IsCIDRv4(value) || IsCIDRv6(value);
|
||||
}
|
||||
|
||||
static inline bool IsPortRangeIsValid(const std::string &r) {
|
||||
const auto ports = Poco::StringTokenizer("-",r,Poco::StringTokenizer::TOK_TRIM);
|
||||
|
||||
for(const auto &port:ports) {
|
||||
uint32_t port_num = std::stoul(port);
|
||||
if(port_num==0 || port_num>65535)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConfigurationValidator::my_format_checker(const std::string &format, const std::string &value)
|
||||
{
|
||||
static const std::regex host_regex{"^(?=.{1,254}$)((?=[a-z0-9-]{1,63}\\.)(xn--+)?[a-z0-9]+(-[a-z0-9]+)*\\.)+[a-z]{2,63}$"};
|
||||
@@ -2577,6 +2761,14 @@ namespace OpenWifi {
|
||||
} catch (...) {
|
||||
}
|
||||
throw std::invalid_argument(value + " is not a valid URI: should be something like https://hello.world.com.");
|
||||
} else if(format == "uc-portrange") {
|
||||
try {
|
||||
if(IsPortRangeIsValid(value))
|
||||
return;
|
||||
throw std::invalid_argument(value + " is not a valid port range: should an integer between 1-65535 or a port range like post-port.");
|
||||
} catch (...) {
|
||||
}
|
||||
throw std::invalid_argument(value + " is not a valid port range: should an integer between 1-65535 or a port range like post-port.");
|
||||
} else if(format == "ip") {
|
||||
if (IsIP(value))
|
||||
return;
|
||||
@@ -2614,7 +2806,7 @@ namespace OpenWifi {
|
||||
return true;
|
||||
}
|
||||
|
||||
void ConfigurationValidator::reinitialize(Poco::Util::Application &self) {
|
||||
void ConfigurationValidator::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
||||
Logger().information("Reinitializing.");
|
||||
Working_ = Initialized_ = false;
|
||||
Init();
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace OpenWifi::KafkaTopics {
|
||||
static const std::string SERVICE_EVENTS{"service_events"};
|
||||
static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"};
|
||||
static const std::string DEVICE_TELEMETRY{"device_telemetry"};
|
||||
static const std::string PROVISIONING_CHANGE{"provisioning_change"};
|
||||
|
||||
namespace ServiceEvents {
|
||||
static const std::string EVENT_JOIN{"join"};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user