Compare commits

..

736 Commits

Author SHA1 Message Date
Stephane Bourque
351633f215 Merge pull request #156 from Telecominfraproject/master
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-16 09:06:03 -07:00
Stephane Bourque
5ec9d6a2c8 Merge pull request #155 from Telecominfraproject/WIFI-9977
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-16 08:38:50 -07:00
stephb9959
3abb24919f Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-16 08:37:02 -07:00
Stephane Bourque
089446c3b4 Merge pull request #154 from Telecominfraproject/master
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-15 23:10:57 -07:00
Stephane Bourque
345195dd1e Merge pull request #153 from Telecominfraproject/WIFI-9977
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-15 23:09:58 -07:00
stephb9959
21db12bcc6 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 23:07:32 -07:00
stephb9959
be01cfb142 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 22:57:54 -07:00
stephb9959
55645c5da4 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 22:32:26 -07:00
stephb9959
aa0316462f Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 22:31:08 -07:00
stephb9959
ebb3c8fed0 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 22:21:22 -07:00
stephb9959
4fb788def4 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 22:08:57 -07:00
stephb9959
5b1e048be3 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 22:04:54 -07:00
stephb9959
03ebc88672 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 21:58:46 -07:00
stephb9959
80bb7ffa07 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 21:57:22 -07:00
stephb9959
1776a70a0e Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 21:47:24 -07:00
stephb9959
3a0de1fee9 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 21:35:12 -07:00
stephb9959
8414ed719b Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 21:08:13 -07:00
stephb9959
eebb18fccf Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 21:00:27 -07:00
stephb9959
1e59b8e160 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 20:43:23 -07:00
stephb9959
6da673e754 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 20:39:56 -07:00
stephb9959
ee4cb53517 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 20:34:11 -07:00
stephb9959
61da6aa317 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 16:50:55 -07:00
stephb9959
bbbadd3a23 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 16:44:52 -07:00
stephb9959
855eb0dc13 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 16:36:05 -07:00
stephb9959
0601aaf340 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 16:35:00 -07:00
stephb9959
100d0302be Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 16:29:37 -07:00
stephb9959
1fe4dbf49f Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 16:24:29 -07:00
stephb9959
720222137c Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 16:18:39 -07:00
stephb9959
d464b8a6f4 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 16:11:58 -07:00
stephb9959
019a995bdd Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 16:09:08 -07:00
stephb9959
f70a8f1732 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 16:08:16 -07:00
stephb9959
0c79d2a632 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 15:56:44 -07:00
stephb9959
1d16bd352a Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 15:46:02 -07:00
stephb9959
88564f2a77 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 15:33:52 -07:00
stephb9959
1907ab9623 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 15:30:01 -07:00
stephb9959
60e50b2af4 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 15:24:11 -07:00
stephb9959
cd24a45c87 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 15:17:46 -07:00
stephb9959
cab25f6fd7 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 15:04:55 -07:00
stephb9959
23c5879a4b Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 14:55:59 -07:00
stephb9959
4e90422e7c Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 14:43:57 -07:00
stephb9959
e75983019a Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 14:25:20 -07:00
stephb9959
a6afef5f8e Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 14:15:56 -07:00
stephb9959
15e45f32a1 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 14:11:19 -07:00
stephb9959
4c7e1807a2 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 14:01:21 -07:00
stephb9959
301b24415c Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 14:00:34 -07:00
stephb9959
da0698ab9b Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 13:57:27 -07:00
stephb9959
f8454e6b83 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 13:52:54 -07:00
stephb9959
cfaab404e9 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 13:49:58 -07:00
stephb9959
e5f98cda04 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 13:44:54 -07:00
stephb9959
bd8fece423 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 13:36:18 -07:00
stephb9959
68a707fe57 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 13:31:09 -07:00
stephb9959
e02a5595a1 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 12:44:21 -07:00
Stephane Bourque
744c1143fb Merge pull request #152 from Telecominfraproject/WIFI-9977
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-15 11:16:01 -07:00
stephb9959
41423a6d5f Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 11:15:25 -07:00
stephb9959
060c8673e7 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 11:14:42 -07:00
Stephane Bourque
1210ae821b Merge pull request #151 from Telecominfraproject/WIFI-9977
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-15 10:49:12 -07:00
stephb9959
1a2e4cc184 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 10:48:18 -07:00
Stephane Bourque
e32ace120b Merge pull request #150 from Telecominfraproject/WIFI-9977
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-15 10:33:55 -07:00
stephb9959
3f2c046a96 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 10:32:21 -07:00
Stephane Bourque
9459bb022c Merge pull request #149 from Telecominfraproject/WIFI-9977
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-15 10:16:04 -07:00
stephb9959
9526a2639a Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 10:14:56 -07:00
Stephane Bourque
2051467c0b Merge pull request #148 from Telecominfraproject/WIFI-9977
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-15 07:47:53 -07:00
stephb9959
bacaa9959c Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 07:46:36 -07:00
Stephane Bourque
875ee6bfd1 Merge pull request #147 from Telecominfraproject/WIFI-9977
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-15 07:42:16 -07:00
stephb9959
8f966fa80c Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 07:41:13 -07:00
stephb9959
d9ac843134 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-15 07:07:18 -07:00
Stephane Bourque
4abedcddf0 Merge pull request #146 from Telecominfraproject/master
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-14 20:57:21 -07:00
Stephane Bourque
c14abf8aa0 Merge pull request #145 from Telecominfraproject/WIFI-9977
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-14 20:55:33 -07:00
stephb9959
d779fca535 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-14 20:50:46 -07:00
stephb9959
7e1d545f26 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-14 20:43:38 -07:00
stephb9959
9c2d60ed3a Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-14 20:22:58 -07:00
Stephane Bourque
b8516cad84 Merge pull request #144 from Telecominfraproject/WIFI-9977
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-14 15:52:37 -07:00
stephb9959
eba979d9da Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-14 15:47:58 -07:00
stephb9959
d163f7522d Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-14 15:34:53 -07:00
stephb9959
132fdafd32 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-14 15:29:00 -07:00
stephb9959
3d6527f30b Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-14 15:17:02 -07:00
stephb9959
dc114de8fa Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-14 15:16:11 -07:00
stephb9959
0592537b71 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-14 15:16:04 -07:00
stephb9959
eddaaa0cd6 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-14 08:03:33 -07:00
stephb9959
46e72369ae Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-14 07:28:32 -07:00
Stephane Bourque
3fc3af68ee Merge pull request #143 from Telecominfraproject/master
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-14 00:03:17 -07:00
Stephane Bourque
58648d7dc5 Merge pull request #142 from Telecominfraproject/WIFI-9977
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-13 23:59:54 -07:00
stephb9959
b2bd6aab9e Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 23:58:42 -07:00
stephb9959
3781f5283f Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 23:42:47 -07:00
stephb9959
7b990a7d2f Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 23:14:33 -07:00
Stephane Bourque
eca43e1d57 Merge pull request #141 from Telecominfraproject/master
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-13 17:23:18 -07:00
Stephane Bourque
c1347fc3b8 Merge pull request #140 from Telecominfraproject/WIFI-9977
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-13 15:51:42 -07:00
stephb9959
888fcbbcd3 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 15:50:31 -07:00
stephb9959
4e4156c420 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 15:45:51 -07:00
stephb9959
ee98a7b8a5 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 14:24:54 -07:00
stephb9959
0b5518d265 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 14:21:38 -07:00
stephb9959
7bc0656f25 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 13:53:53 -07:00
stephb9959
177a8b40ee Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 12:54:43 -07:00
Stephane Bourque
85ee78f35e Merge pull request #139 from Telecominfraproject/WIFI-9977
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-13 12:08:11 -07:00
stephb9959
9043b3a558 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 11:59:10 -07:00
stephb9959
4d2d488812 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 11:53:09 -07:00
stephb9959
adf226f2e8 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 11:48:24 -07:00
stephb9959
749d425d80 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 11:40:55 -07:00
stephb9959
a6f9deb315 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 11:35:41 -07:00
stephb9959
f4236408fc Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 11:30:03 -07:00
stephb9959
377c7bfc0b Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 11:20:27 -07:00
stephb9959
2e3efd97e4 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 11:08:28 -07:00
stephb9959
58abf04e42 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 11:07:40 -07:00
stephb9959
5e002899b5 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 10:45:04 -07:00
stephb9959
d43c8f63ab Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-13 08:27:54 -07:00
Stephane Bourque
07a64877bb Merge pull request #138 from Telecominfraproject/master
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-12 21:24:20 -07:00
Stephane Bourque
a00ba50920 Merge pull request #137 from Telecominfraproject/WIFI-10084
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-12 20:39:33 -07:00
stephb9959
c2fa87d6bd Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 20:38:12 -07:00
stephb9959
ab0b36a96f Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 20:31:18 -07:00
stephb9959
89f8047e2f Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 20:20:15 -07:00
stephb9959
1515c9bb6a Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 20:11:54 -07:00
stephb9959
b53e6f44fa Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 14:16:10 -07:00
stephb9959
769c9c90f6 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 12:31:16 -07:00
stephb9959
dc0eb35376 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 12:02:29 -07:00
stephb9959
e6b497f0b4 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 11:21:07 -07:00
stephb9959
bab9d869b1 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 10:52:42 -07:00
stephb9959
a9127d4fcf Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 10:35:30 -07:00
stephb9959
fea78abe9b Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 10:27:10 -07:00
stephb9959
bd72993fa5 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 10:11:48 -07:00
stephb9959
7d74694bf9 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 10:01:30 -07:00
stephb9959
8e84a0f1f3 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 09:50:24 -07:00
stephb9959
98c8f29555 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 09:41:04 -07:00
stephb9959
42a4ee0864 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 09:28:59 -07:00
stephb9959
fcce86acf4 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 09:03:41 -07:00
stephb9959
31aad8b41b Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 08:18:25 -07:00
stephb9959
a828039445 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 08:03:07 -07:00
stephb9959
6905aeaeec Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 07:53:16 -07:00
Stephane Bourque
3293b7b71d Merge pull request #136 from Telecominfraproject/WIFI-10084
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-12 00:31:03 -07:00
stephb9959
2d6df5ea29 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 00:29:01 -07:00
stephb9959
e466f76b75 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 00:28:12 -07:00
stephb9959
170b97514b Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 00:20:54 -07:00
stephb9959
a463bb60dd Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 00:20:03 -07:00
stephb9959
9bbb12b674 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-12 00:05:05 -07:00
stephb9959
46cc41e065 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 23:53:15 -07:00
stephb9959
1776643579 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 23:40:46 -07:00
stephb9959
c0d9aca88a Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 23:22:39 -07:00
stephb9959
88018335da Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 23:08:01 -07:00
stephb9959
7ce7927c95 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 22:56:38 -07:00
stephb9959
5b797cf937 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 22:43:53 -07:00
stephb9959
cd615e8f2b Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 22:33:17 -07:00
stephb9959
cf3f0fe67f Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 21:57:51 -07:00
stephb9959
b80e92f3dc Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 21:50:53 -07:00
stephb9959
11034bd4fd Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 14:31:25 -07:00
stephb9959
01980892b1 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 14:24:14 -07:00
stephb9959
f4d4405663 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 14:18:24 -07:00
stephb9959
a8370dc8dd Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 14:17:43 -07:00
stephb9959
861c4d0dee Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 14:12:15 -07:00
stephb9959
8c70e833ea Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 14:08:03 -07:00
stephb9959
f8928bbec2 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 13:42:00 -07:00
stephb9959
0b7e474e01 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 13:40:22 -07:00
stephb9959
14f0bb75d1 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 12:37:20 -07:00
stephb9959
32d37a3b9c Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 12:27:12 -07:00
stephb9959
24391c5ac4 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 12:23:39 -07:00
stephb9959
7ac47dfaa0 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 12:16:05 -07:00
stephb9959
fd77d6ef37 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 11:32:02 -07:00
stephb9959
04c9deffd3 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 11:23:55 -07:00
stephb9959
f8bc00cb55 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 11:15:48 -07:00
stephb9959
f2ae0b6bd4 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 11:11:25 -07:00
stephb9959
1904b34c84 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 11:07:13 -07:00
stephb9959
23ea21d2b4 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 10:57:06 -07:00
stephb9959
276572a8a5 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 10:29:10 -07:00
stephb9959
b9bd5ca6a5 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 10:27:41 -07:00
stephb9959
201a4dd6e7 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 10:18:57 -07:00
Stephane Bourque
769eb83744 Merge pull request #135 from Telecominfraproject/WIFI-10084
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-11 10:09:31 -07:00
stephb9959
66a30c4f37 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 10:06:22 -07:00
Stephane Bourque
2a744e2fde Merge pull request #134 from Telecominfraproject/WIFI-10084
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-11 09:43:00 -07:00
stephb9959
f212aa2e8c Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 09:30:47 -07:00
stephb9959
fc478bd304 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 09:11:39 -07:00
stephb9959
6e8a2478c4 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 09:01:46 -07:00
stephb9959
eceb5a9034 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 08:48:55 -07:00
stephb9959
782acea8c7 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 08:47:18 -07:00
stephb9959
524d392e83 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 08:39:08 -07:00
Stephane Bourque
885f1affeb Merge pull request #133 from Telecominfraproject/WIFI-10084
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-11 07:22:44 -07:00
stephb9959
50abf75a0a Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 07:21:53 -07:00
TIP Automation User
4af6427814 Chg: update image tag in helm values to v2.6.0 2022-07-11 11:13:53 +00:00
TIP Automation User
2a6ec50ce1 Chg: update image tag in helm values to v2.6.0-RC5 2022-07-11 11:02:32 +00:00
Stephane Bourque
4497dc655b Merge pull request #132 from Telecominfraproject/master
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
2022-07-10 16:41:15 -07:00
Stephane Bourque
1e2d04ad07 Merge pull request #131 from Telecominfraproject/WIFI-10084
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
2022-07-10 16:10:40 -07:00
stephb9959
5874d3f1fd Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 16:09:06 -07:00
stephb9959
a4abbe6ef3 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 16:06:37 -07:00
stephb9959
41e3cbb2b2 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 16:00:13 -07:00
stephb9959
1f77083973 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 15:52:36 -07:00
stephb9959
b08f993a20 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 15:40:34 -07:00
stephb9959
113baa625e Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 15:34:49 -07:00
stephb9959
3765d22815 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 15:33:47 -07:00
stephb9959
24d492903b Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 15:27:09 -07:00
stephb9959
3b4fd70522 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 14:54:45 -07:00
stephb9959
19cf9101fe Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 14:43:49 -07:00
stephb9959
004319e7ad Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 14:36:17 -07:00
stephb9959
94893d1185 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 14:28:57 -07:00
stephb9959
13dce2f3e8 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 14:28:16 -07:00
stephb9959
ea7bc3c52f Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 14:13:36 -07:00
stephb9959
0235a13841 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 14:07:54 -07:00
stephb9959
be33c88337 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 13:58:40 -07:00
stephb9959
0456f638c9 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 11:32:09 -07:00
stephb9959
83ada79ca3 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 11:29:25 -07:00
stephb9959
913d1e571d Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 11:22:33 -07:00
stephb9959
8f98e510db Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 11:17:51 -07:00
stephb9959
fb0da90b63 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 11:04:44 -07:00
stephb9959
1e1dec51ab Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 11:01:34 -07:00
stephb9959
c35602e30e Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 10:47:26 -07:00
stephb9959
4c90a777e0 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 10:36:38 -07:00
stephb9959
9abfa4bad5 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 10:30:23 -07:00
stephb9959
7ecd0c9891 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 10:09:41 -07:00
stephb9959
6e25ccdd87 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 10:08:10 -07:00
stephb9959
a8f970eaf2 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 09:52:23 -07:00
stephb9959
9f4d362a6d Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10084
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 08:02:46 -07:00
TIP Automation User
5f3f9e93d2 Chg: update image tag in helm values to v2.6.0-RC4 2022-07-09 12:17:30 +00:00
stephb9959
c84f05cd22 Merge remote-tracking branch 'origin/master' 2022-07-08 23:10:01 -07:00
stephb9959
a532520044 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-08 23:09:34 -07:00
Stephane Bourque
6d82ee355e Merge pull request #130 from Telecominfraproject/master
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-07 21:24:48 -07:00
Stephane Bourque
02c3b2fe2e Merge pull request #129 from Telecominfraproject/WIFI-9977v3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-07 20:54:24 -07:00
stephb9959
cce4a7ec93 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 20:52:40 -07:00
Stephane Bourque
9aef183dc2 Merge pull request #128 from Telecominfraproject/WIFI-9977v3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-07 12:08:40 -07:00
stephb9959
60a3365a9e https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 11:59:04 -07:00
stephb9959
6c052d7afe https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 11:57:57 -07:00
Stephane Bourque
88eae31b7f Merge pull request #127 from Telecominfraproject/WIFI-9977v3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-06 23:41:42 -07:00
stephb9959
d59f6e3dfc https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 23:39:46 -07:00
Stephane Bourque
c97566f625 Merge pull request #126 from Telecominfraproject/WIFI-9977v3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-06 22:59:51 -07:00
stephb9959
1fb41a9460 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 22:55:50 -07:00
stephb9959
cfec8a1cbc https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 22:55:39 -07:00
stephb9959
7a84640c71 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 22:52:44 -07:00
Stephane Bourque
0d2276ff5a Merge pull request #125 from Telecominfraproject/WIFI-9977v3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-06 22:25:36 -07:00
stephb9959
d227f83384 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 22:23:28 -07:00
stephb9959
acb4d91a3d https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 22:20:48 -07:00
Stephane Bourque
72b2913cc5 Merge pull request #124 from Telecominfraproject/WIFI-9977v3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-06 22:03:47 -07:00
stephb9959
746ef603e2 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 22:02:51 -07:00
stephb9959
ab792f7239 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 22:02:42 -07:00
Stephane Bourque
c4bb577763 Merge pull request #123 from Telecominfraproject/WIFI-9977v3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-06 21:41:49 -07:00
stephb9959
3caf67102e https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 21:41:15 -07:00
Stephane Bourque
8a3ade14ae Merge pull request #122 from Telecominfraproject/WIFI-9977v3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-06 21:26:06 -07:00
stephb9959
4199b859ad https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 21:24:36 -07:00
stephb9959
be1b571f7f https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 21:10:29 -07:00
Stephane Bourque
3002e17fd2 Merge pull request #121 from Telecominfraproject/WIFI-9977v3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-06 21:04:22 -07:00
stephb9959
0d1a794e10 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 21:00:50 -07:00
stephb9959
2aa7d97c80 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 19:23:47 -07:00
Stephane Bourque
0d3a0cbf03 Merge pull request #120 from Telecominfraproject/WIFI-9977v3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-06 16:26:07 -07:00
stephb9959
1d8cb5447b https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 16:25:10 -07:00
Stephane Bourque
3526a7abd9 Merge pull request #119 from Telecominfraproject/WIFI-9977v3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-06 16:01:04 -07:00
stephb9959
d7ec9a3552 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 15:59:29 -07:00
Stephane Bourque
9f567e0e69 Merge pull request #118 from Telecominfraproject/WIFI-9977v3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-06 15:30:56 -07:00
stephb9959
b16a410f1d https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 15:29:39 -07:00
Stephane Bourque
0955f23dfc Merge pull request #117 from Telecominfraproject/WIFI-9977v3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-06 14:52:21 -07:00
stephb9959
bd10ebc19c https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 14:50:58 -07:00
stephb9959
f74c5b496f https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 14:50:07 -07:00
stephb9959
6e961be74e https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 14:42:28 -07:00
Stephane Bourque
c92d22f3cb Merge pull request #116 from Telecominfraproject/WIFI-9977v3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-06 12:13:18 -07:00
stephb9959
e1770dc6a2 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 10:47:43 -07:00
Stephane Bourque
eace417fd3 Merge pull request #115 from Telecominfraproject/WIFI-9977v3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-06 08:45:20 -07:00
stephb9959
ec3b5ededc https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-06 08:39:12 -07:00
Stephane Bourque
4c6a0ab9e2 Merge pull request #114 from Telecominfraproject/master
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-05 15:29:44 -07:00
Stephane Bourque
78a6b011f8 Merge pull request #113 from Telecominfraproject/RADSEC-proxy
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-05 15:01:37 -07:00
stephb9959
a5450418b3 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-05 14:23:21 -07:00
stephb9959
c74aa0d89f https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-05 13:36:38 -07:00
stephb9959
5f5e887f91 https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-04 23:26:10 -07:00
stephb9959
54a9290589 https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-04 23:23:52 -07:00
stephb9959
24be35c974 https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-04 23:18:12 -07:00
Stephane Bourque
937d2818c0 Merge pull request #112 from Telecominfraproject/RTTYv3
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
2022-07-04 21:44:59 -07:00
stephb9959
f014960b3a https://telecominfraproject.atlassian.net/browse/WIFI-10040
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-04 13:57:13 -07:00
stephb9959
cc5b319141 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-01 08:00:28 -07:00
Stephane Bourque
d5e7a6661f Merge pull request #111 from Telecominfraproject/RTTYv3
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-07-01 06:53:53 -07:00
stephb9959
3368782471 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 23:30:13 -07:00
stephb9959
2f013557a9 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 23:22:50 -07:00
stephb9959
09595abc8c https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 23:22:30 -07:00
stephb9959
5104ab1dc3 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 23:18:22 -07:00
stephb9959
8f3b2f795f https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 22:59:14 -07:00
stephb9959
9779ee669b https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 22:55:58 -07:00
stephb9959
f7187749a1 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 22:51:03 -07:00
stephb9959
ddec407856 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 22:47:11 -07:00
stephb9959
4650ac592a https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 22:39:13 -07:00
stephb9959
bc5c9e30cf https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 22:19:45 -07:00
stephb9959
1b53398e1e https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 22:14:39 -07:00
stephb9959
7b59a981dd https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 22:02:19 -07:00
stephb9959
ec3cb6586f https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 21:41:33 -07:00
stephb9959
c40be95aa8 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 21:29:35 -07:00
stephb9959
ba8edb7f74 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 20:51:00 -07:00
stephb9959
ea14936a1d https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 20:42:03 -07:00
stephb9959
676f131ca9 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 20:39:55 -07:00
stephb9959
2e1fc663c8 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 20:29:27 -07:00
stephb9959
cd9ef2ed2a https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 17:02:17 -07:00
stephb9959
4a1a903656 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 16:59:00 -07:00
stephb9959
f6409fc063 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 16:38:23 -07:00
stephb9959
6af855f6ca https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 16:33:39 -07:00
stephb9959
bec81bc380 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 16:31:15 -07:00
stephb9959
0e4e4156a1 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 16:07:51 -07:00
stephb9959
2aa60a5676 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 15:59:58 -07:00
stephb9959
8b396e51ff https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 15:48:15 -07:00
Stephane Bourque
01f53d7b78 Merge pull request #110 from Telecominfraproject/WIFI-9828
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-06-30 15:47:01 -07:00
stephb9959
b3c188701f https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 14:31:12 -07:00
stephb9959
7eb4c9e38b https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 11:00:42 -07:00
stephb9959
c93c34c042 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 10:53:37 -07:00
stephb9959
418f8d31ae https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 10:44:14 -07:00
stephb9959
77c0c191f7 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 10:12:49 -07:00
stephb9959
f0f4cf54bb https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 10:06:30 -07:00
stephb9959
917abf1d7f https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 09:43:05 -07:00
stephb9959
b4e7e4e26b https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 09:27:33 -07:00
stephb9959
9d0a146859 https://telecominfraproject.atlassian.net/browse/WIFI-9877
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 09:13:46 -07:00
Stephane Bourque
2efed5e626 Merge pull request #109 from Telecominfraproject/master
https://telecominfraproject.atlassian.net/browse/WIFI-9828
2022-06-30 08:11:03 -07:00
Stephane Bourque
7420b72b23 Merge pull request #108 from Telecominfraproject/oui_download_url
properties: update default OUI download URL everywhere
2022-06-30 07:25:57 -07:00
Stephane Bourque
5fc675484c Merge pull request #107 from Telecominfraproject/WIFI-9828
https://telecominfraproject.atlassian.net/browse/WIFI-9828
2022-06-30 07:12:49 -07:00
Stijn Tintel
38ad11542b properties: update default OUI download URL everywhere
The URL https://linuxnet.ca/ieee/oui.txt times out:

  OUI-SVR: [Information] Start: Retrieving OUI file: https://linuxnet.ca/ieee/oui.txt
  OUI-SVR: [Error] Timeout: connect timed out: 24.222.55.20:443

It was replaced with a working URL in the following commit:
7e5e998265 ("Updated the OUI db download link")

Let's use the new URL everywhere for consistency.

Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
2022-06-30 16:19:44 +03:00
stephb9959
63f2a4085a https://telecominfraproject.atlassian.net/browse/WIFI-9828
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-30 00:17:39 -07:00
Stephane Bourque
fea70efb2d Merge pull request #106 from Telecominfraproject/WIFI-9828
Wifi 9828
2022-06-30 00:15:26 -07:00
stephb9959
da42c9845f https://telecominfraproject.atlassian.net/browse/WIFI-9828
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 23:47:47 -07:00
stephb9959
ed46778bd4 https://telecominfraproject.atlassian.net/browse/WIFI-9828
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 23:35:14 -07:00
stephb9959
1f7c0b7fdf https://telecominfraproject.atlassian.net/browse/WIFI-9828
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 23:22:58 -07:00
stephb9959
15ec31fc89 https://telecominfraproject.atlassian.net/browse/WIFI-9828
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 23:13:38 -07:00
stephb9959
d2a0d6da8a https://telecominfraproject.atlassian.net/browse/WIFI-9828
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 23:08:52 -07:00
stephb9959
77cae31031 https://telecominfraproject.atlassian.net/browse/WIFI-9828
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 22:41:36 -07:00
stephb9959
6cab1caf6c https://telecominfraproject.atlassian.net/browse/WIFI-9828
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 22:10:28 -07:00
Stephane Bourque
faf7881c87 Merge pull request #105 from Telecominfraproject/master
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-06-29 22:00:03 -07:00
Stephane Bourque
eea8203869 Merge pull request #104 from Telecominfraproject/WiFi-9620-CoA
https://telecominfraproject.atlassian.net/browse/WIFI-9977
2022-06-29 18:31:24 -07:00
stephb9959
040397aa8e https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 17:20:56 -07:00
stephb9959
bba92aa9b8 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 17:20:14 -07:00
stephb9959
c332a3946d https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 17:19:12 -07:00
stephb9959
02e677f849 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 17:07:07 -07:00
stephb9959
a26f7c03c1 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 17:05:43 -07:00
stephb9959
9181ae01cc https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 17:00:23 -07:00
stephb9959
7825b00d2e https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 16:50:51 -07:00
stephb9959
8b895c2088 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 16:30:39 -07:00
stephb9959
49d39d37a1 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 16:23:06 -07:00
stephb9959
406d59d5d7 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 15:55:21 -07:00
stephb9959
186d12c78a https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 15:49:36 -07:00
stephb9959
421c24c961 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 15:16:49 -07:00
stephb9959
e00c835680 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 15:12:54 -07:00
stephb9959
3f972ebb4a https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 14:55:58 -07:00
stephb9959
cf8d29e66f https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 14:45:13 -07:00
stephb9959
d5e11d246a https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 12:29:01 -07:00
stephb9959
6ac29199e0 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 11:53:14 -07:00
stephb9959
2f9452d6ef https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 11:10:24 -07:00
stephb9959
caed454e1a https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 11:05:50 -07:00
stephb9959
30916cbed1 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 10:54:35 -07:00
stephb9959
81899788a9 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 10:23:53 -07:00
stephb9959
e1590cbe90 https://telecominfraproject.atlassian.net/browse/WIFI-9977
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 10:22:30 -07:00
stephb9959
bcbc212436 https://telecominfraproject.atlassian.net/browse/WIFI-9976
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 10:09:02 -07:00
stephb9959
520671684b https://telecominfraproject.atlassian.net/browse/WIFI-9976
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 10:04:48 -07:00
Stephane Bourque
eacf9c0450 Merge pull request #102 from Telecominfraproject/WiFi-9620-CoA
https://telecominfraproject.atlassian.net/browse/WIFI-9952
2022-06-29 09:41:30 -07:00
stephb9959
bef4c3ed5c https://telecominfraproject.atlassian.net/browse/WIFI-9952
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-29 09:14:57 -07:00
stephb9959
4fe6254bf2 https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-28 09:45:18 -07:00
stephb9959
63ba3d633d https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-28 08:28:48 -07:00
stephb9959
1255cf0a56 https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-28 08:09:00 -07:00
stephb9959
7a6f2a517c https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-28 07:57:29 -07:00
stephb9959
6c15908ed6 https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-28 07:49:31 -07:00
stephb9959
d0a7670fff https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-28 07:40:06 -07:00
stephb9959
17d6253cfe https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-28 07:28:42 -07:00
stephb9959
ab592305ce https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-28 07:11:34 -07:00
stephb9959
0da527e1d7 https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-28 07:06:16 -07:00
stephb9959
d3848a6f8b https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-28 06:54:51 -07:00
stephb9959
c522c22d31 https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-28 06:48:20 -07:00
stephb9959
783886662f https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-28 06:44:19 -07:00
stephb9959
56ab9b1409 https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-28 06:29:20 -07:00
stephb9959
67e86a0edf https://telecominfraproject.atlassian.net/browse/WIFI-9952
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-27 20:30:44 -07:00
stephb9959
70c12a5b77 https://telecominfraproject.atlassian.net/browse/WIFI-9952
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-27 17:24:48 -07:00
stephb9959
03f2e2d457 https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-27 14:20:41 -07:00
stephb9959
ed12331d20 https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-27 14:13:38 -07:00
stephb9959
ec0c295c7c https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-27 14:10:53 -07:00
stephb9959
2438bd7ca7 https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-27 14:09:08 -07:00
stephb9959
18d18f68c5 https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-27 13:58:11 -07:00
stephb9959
120f94a95a https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-27 13:51:16 -07:00
stephb9959
7b9cda8c3d https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-27 13:42:59 -07:00
stephb9959
0d116119ed https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-27 09:27:28 -07:00
stephb9959
b9a7f53a92 https://telecominfraproject.atlassian.net/browse/WIFI-9959
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-27 08:23:33 -07:00
Johann Hoffmann
ee3aa66b11 Always re-generate config file if TEMPLATE_CONFIG is set to true
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-24 18:58:17 +02:00
Johann Hoffmann
459029d5d7 Always re-generate config file if TEMPLATE_CONFIG is set to true
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-24 18:17:05 +02:00
stephb9959
bfe0ff4481 https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-24 08:00:47 -07:00
stephb9959
b70a95d12b https://telecominfraproject.atlassian.net/browse/WIFI-9620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-24 07:51:23 -07:00
Stephane Bourque
8280ff46db Update PROTOCOL.md
Fixing protocol properties file entries.

Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-24 07:46:06 -07:00
Stephane Bourque
59da808bcd Update PROTOCOL.md
Fixed some formatting.

Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-24 07:36:19 -07:00
TIP Automation User
dbc785aca6 Chg: update image tag in helm values to v2.6.0-RC3 2022-06-23 19:01:18 +00:00
jaspreetsachdev
5207579645 Merge pull request #99 from Telecominfraproject/master
Fixes for WIFI-9537
2022-06-23 14:51:35 -04:00
Stephane Bourque
840c22e0d1 Merge pull request #98 from Telecominfraproject/WIFI-9620
Wifi 9620
2022-06-23 11:02:37 -07:00
stephb9959
996e410fde Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9537
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-23 11:01:01 -07:00
stephb9959
521dcc2eed Removal of extraneous logging and debug statements.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-23 09:42:19 -07:00
stephb9959
4d73467b8a New RADIUS routing algorithm
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-23 09:03:30 -07:00
stephb9959
515444d223 New RADIUS routing algorithm
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-23 09:02:28 -07:00
stephb9959
dccda306d4 New RADIUS routing algorithm
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-23 09:00:25 -07:00
stephb9959
3fd5c59994 Updating radius configuration file template
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-22 23:03:03 -07:00
stephb9959
87fee4ecd2 Updating radius configuration file template
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-22 22:25:55 -07:00
stephb9959
b37e7d4c5d Updating radius configuration file template
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-22 22:13:25 -07:00
stephb9959
f8c21f0c68 Fixing: https://telecominfraproject.atlassian.net/browse/WIFI-9537
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-22 22:02:52 -07:00
stephb9959
f74c098b99 Fixing: https://telecominfraproject.atlassian.net/browse/WIFI-9537
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-22 22:00:01 -07:00
stephb9959
1619cec197 Fixing: https://telecominfraproject.atlassian.net/browse/WIFI-9537
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-22 21:49:10 -07:00
stephb9959
62211b6e8b Adding deviceping command to CLI.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-22 21:36:20 -07:00
stephb9959
1bebe0729a Improving Radius router.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-22 12:03:43 -07:00
stephb9959
6a8a6aa851 Fixing compile warning.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-22 11:54:47 -07:00
stephb9959
4b6880a306 Fixing https://telecominfraproject.atlassian.net/browse/WIFI-9537
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-22 11:52:50 -07:00
stephb9959
3d252116dd Changing b64 libs
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-21 10:52:50 -07:00
stephb9959
2fc5e69145 Removing DST parameter
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-21 10:33:49 -07:00
stephb9959
8d2e85d0ee Removing DST parameter
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-21 10:18:32 -07:00
stephb9959
d1efdc93a4 Removing DST parameter
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-21 10:10:19 -07:00
stephb9959
c27627302f Fixing Base64 encoding
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-21 09:21:57 -07:00
stephb9959
ae18fead11 Adding temporary routing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-20 23:17:39 -07:00
stephb9959
75a6300ffb Move to proper TIP RADIUS dictionary
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>

Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-20 10:20:27 -07:00
stephb9959
f84a4c83d0 Fixing RADIUS packet decoding offset
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-18 22:37:43 -07:00
TIP Automation User
b882f07eef Chg: update image tag in helm values to v2.6.0-RC2 2022-06-17 13:39:08 +00:00
Johann Hoffmann
d5c8cb5837 [WIFI-9534] Add condition to avoid deleting default and release branch images
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-17 13:49:54 +02:00
stephb9959
a09f2ec7bd Troubleshooting failed Radius parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-16 14:08:28 -07:00
stephb9959
7af9be5845 Troubleshooting failed Radius parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-16 11:08:47 -07:00
stephb9959
bc6e7d538b Fix: failure to send CoA response to CoA server
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-16 09:16:37 -07:00
stephb9959
59ed9df3c9 Bad serialnumber RADIUS packet filtering.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-16 09:02:57 -07:00
stephb9959
0f46a6ded0 Runt RADIUS packet filtering.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-16 08:59:01 -07:00
stephb9959
ef09214187 Wrong CoA socket address
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-16 08:52:29 -07:00
stephb9959
aa4631b55d Adding radius config secret in config processing, for living lab and cli commands.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-15 23:36:05 -07:00
stephb9959
08b59e04ee Adding radius config sampel for living lab and cli commands.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-15 16:44:21 -07:00
stephb9959
3455297cd6 Adding radius config sampel for living lab and cli commands.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-15 16:44:08 -07:00
Stephane Bourque
8f4e585c88 Merge pull request #97 from Telecominfraproject/WIFI-9537
Wifi 9537
2022-06-15 16:07:39 -07:00
stephb9959
350ccd5371 Fixing strategy parsing
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-15 15:57:50 -07:00
stephb9959
b89c0773c5 Merge remote-tracking branch 'origin/WIFI-9620' into WIFI-9620 2022-06-15 15:35:56 -07:00
stephb9959
d03cd6a6df Initial Work
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-15 15:35:22 -07:00
stephb9959
142a04ffc3 Initial Work
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-15 15:03:45 -07:00
stephb9959
bb519eb84b Resolve conflict
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-15 13:17:24 -07:00
stephb9959
2b8e496bbc Merge remote-tracking branch 'origin/master' 2022-06-15 07:29:29 -07:00
stephb9959
776a781a87 README.md typos and clarifications.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-15 07:29:21 -07:00
Johann Hoffmann
f5d66365b8 Temporarily disable cleanup for merges into release branches
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-15 14:49:30 +02:00
stephb9959
fd8b021225 Merge remote-tracking branch 'origin/master' 2022-06-08 09:54:17 -07:00
stephb9959
1d2b54b6cf Adding IE parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-08 09:54:09 -07:00
Dmitry Dunaev
07ed169c08 Merge pull request #95 from Telecominfraproject/fix/wifi-9174--dep-charts-2.6
[WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
2022-06-03 15:48:45 +03:00
Dmitry Dunaev
f33b6c94be [WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-06-03 15:47:27 +03:00
Dmitry Dunaev
b073246293 Merge pull request #94 from Telecominfraproject/fix/wifi-9174--dep-charts
[WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
2022-06-03 15:42:24 +03:00
Dmitry Dunaev
8205cb7336 [WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-06-03 15:40:09 +03:00
stephb9959
9339ae893a Adding IE parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 23:15:26 -07:00
stephb9959
ce483ba51c Adding IE parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 21:59:03 -07:00
stephb9959
85a7de67fb Adding IE parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 21:44:26 -07:00
stephb9959
abdabe7da3 Adding IE parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 21:10:13 -07:00
stephb9959
669af7640c Initial commit.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 15:49:10 -07:00
stephb9959
83c46c44aa Initial commit.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 15:39:04 -07:00
stephb9959
7b2ba4fed4 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 14:04:10 -07:00
stephb9959
ef5aa26991 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 12:28:20 -07:00
stephb9959
92b25846d2 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 12:24:37 -07:00
stephb9959
77663f9184 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 12:23:48 -07:00
stephb9959
61c7ab3267 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 11:48:41 -07:00
stephb9959
8ae0006343 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 10:54:50 -07:00
stephb9959
64a1fa1c85 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 10:49:34 -07:00
stephb9959
2b9c90d5e6 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 10:11:15 -07:00
stephb9959
565cee2373 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 10:06:52 -07:00
stephb9959
36c5c9c5b6 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 10:02:23 -07:00
stephb9959
837c3d5570 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 09:59:27 -07:00
stephb9959
2a71721548 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 09:50:59 -07:00
stephb9959
055bdcf937 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-02 09:36:27 -07:00
stephb9959
221ee05298 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-01 23:51:57 -07:00
stephb9959
afb8252dc2 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-01 23:51:07 -07:00
stephb9959
77f86d139f Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-01 23:39:52 -07:00
stephb9959
b2353b6a0e Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-01 23:39:10 -07:00
stephb9959
bf4b9b0d63 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-01 23:33:09 -07:00
stephb9959
e51236f0ca Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-01 23:30:31 -07:00
stephb9959
5be8ad75ed Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-01 23:04:09 -07:00
stephb9959
054e3e1591 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-01 11:43:02 -07:00
stephb9959
06366f875c Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-01 11:21:59 -07:00
stephb9959
64d3f8c3ee Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-01 10:25:19 -07:00
stephb9959
8878445e03 Adding more IEs parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-01 10:00:23 -07:00
stephb9959
ea30684f0c Framework update.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-01 08:43:39 -07:00
stephb9959
ebf08a63f1 Framework update.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-01 08:31:05 -07:00
stephb9959
e9e7db9ac0 Framework update.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-31 23:55:15 -07:00
stephb9959
7f9d03ed34 Framework update.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-31 14:00:24 -07:00
stephb9959
084483b028 Framework update.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-31 12:33:16 -07:00
stephb9959
285dbacd12 Changes for script command for devices: remove UCI and added TIMEOUT.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-29 09:19:19 -07:00
stephb9959
8f79d70753 Adding WifiScan Parsing WLAN_EID_SUPPORTED_REGULATORY_CLASSES
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 23:16:26 -07:00
stephb9959
6d20481d64 Adding WifiScan Parsing WLAN_EID_SUPPORTED_REGULATORY_CLASSES
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 23:06:44 -07:00
stephb9959
7da4bbba61 Adding WifiScan Parsing WLAN_EID_SUPPORTED_REGULATORY_CLASSES
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 22:34:34 -07:00
stephb9959
ff955d8b2f Adding WifiScan Parsing WLAN_EID_SUPPORTED_REGULATORY_CLASSES
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 22:33:48 -07:00
stephb9959
29d615393f Adding WifiScan Parsing WLAN_EID_SUPPORTED_REGULATORY_CLASSES
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 22:21:05 -07:00
stephb9959
2a716e6c66 Adding WifiScan Parsing WLAN_EID_SUPPORTED_REGULATORY_CLASSES
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 22:16:21 -07:00
stephb9959
b662dcf88c Adding WifiScan Parsing WLAN_EID_SUPPORTED_REGULATORY_CLASSES
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 22:05:28 -07:00
stephb9959
253ffbf111 Adding WifiScan Parsing WLAN_EID_SUPPORTED_REGULATORY_CLASSES
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 22:03:33 -07:00
stephb9959
dfd689512b Adding WifiScan Parsing WLAN_EID_SUPPORTED_REGULATORY_CLASSES
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 22:00:07 -07:00
stephb9959
cee2705bf8 Adding WifiScan Parsing WLAN_EID_SUPPORTED_REGULATORY_CLASSES
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 21:12:07 -07:00
stephb9959
af1e293bde Adding WifiScan Parsing WLAN_EID_SUPPORTED_REGULATORY_CLASSES
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 21:02:13 -07:00
stephb9959
58266eb239 Adding WifiScan Parsing WLAN_EID_SUPPORTED_REGULATORY_CLASSES
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 20:57:05 -07:00
stephb9959
87dc357c9f Adding WifiScan Parsing WLAN_EID_SUPPORTED_REGULATORY_CLASSES
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 20:54:02 -07:00
stephb9959
02798de88a Adding WifiScan Parsing ERP Info
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 20:35:11 -07:00
stephb9959
d7bd812f97 Adding WifiScan Parsing ERP Info
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 20:25:23 -07:00
stephb9959
b692a7868e Fixing wifiscan country parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 20:06:38 -07:00
stephb9959
f57dfc62c0 Fixing wifiscan country parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 19:58:41 -07:00
stephb9959
21794d669e Fixing wifiscan country parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 16:28:48 -07:00
stephb9959
2139093a73 Fixing wifiscan country parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 16:27:08 -07:00
stephb9959
bc1f0670fb Fixing wifiscan country parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 16:21:02 -07:00
stephb9959
a0b0a169fa Merge remote-tracking branch 'origin/master'
# Conflicts:
#	src/framework/ConfigurationValidator.cpp
2022-05-27 16:20:07 -07:00
stephb9959
7feb9f3655 Fixing wifiscan country parsing.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 16:18:43 -07:00
stephb9959
3878d8abe6 Adding latest data model.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 07:39:59 -07:00
stephb9959
770b5969f8 Adding latest data model.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 07:36:57 -07:00
stephb9959
00bca216fc Merge remote-tracking branch 'origin/master'
# Conflicts:
#	src/framework/ConfigurationValidator.cpp
2022-05-27 07:32:34 -07:00
Stephane Bourque
64eb7748d1 Adding latest data model.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-05-27 07:31:52 -07:00
Stephane Bourque
8ed351ad17 Merge pull request #93 from Telecominfraproject/WIFI8096
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-8096
2022-05-26 23:51:20 -07:00
stephb9959
4a71be0558 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-8096
Signed-off-by: Stephane Bourque <stephane.bourque@arilia.com>
2022-05-26 23:12:44 -07:00
stephb9959
d6434666b4 Adding latest data model. 2022-05-26 22:27:24 -07:00
stephb9959
747c84de4a Adding latest data model. 2022-05-26 22:23:34 -07:00
stephb9959
538bdb25b1 Adding latest data model. 2022-05-26 22:12:44 -07:00
stephb9959
07229e7e1f Adding latest data model. 2022-05-26 10:30:30 -07:00
stephb9959
a63a1785e2 Adding latest data model. 2022-05-26 09:21:17 -07:00
stephb9959
14820bd9c8 Adding latest data model. 2022-05-26 09:18:41 -07:00
stephb9959
aeeb333c62 Adding latest data model. 2022-05-26 09:13:33 -07:00
stephb9959
caa8f8c5a5 Adding latest data model. 2022-05-26 08:30:27 -07:00
stephb9959
02aada469b Adding ies request during WifiScan 2022-05-26 07:41:44 -07:00
stephb9959
020f9aea16 Adding ies request during WifiScan 2022-05-26 07:36:52 -07:00
stephb9959
a8d5717fd5 Adding ies request during WifiScan 2022-05-26 07:36:09 -07:00
stephb9959
51dd030419 Adding ies request during WifiScan 2022-05-26 07:11:07 -07:00
stephb9959
6a83895efc Adding ies request during WifiScan 2022-05-25 23:57:09 -07:00
stephb9959
c5e2574ab1 Adding ies request during WifiScan 2022-05-25 23:50:25 -07:00
stephb9959
5a1828eaea Adding ies request during WifiScan 2022-05-25 23:45:47 -07:00
stephb9959
c62f5a16f5 Adding ies request during WifiScan 2022-05-25 23:35:14 -07:00
stephb9959
b6e778ada3 Adding ies request during WifiScan 2022-05-25 23:26:42 -07:00
stephb9959
1b34ec8a78 Adding ies request during WifiScan 2022-05-25 22:43:02 -07:00
stephb9959
57eb7312c8 Adding ies request during WifiScan 2022-05-25 22:38:55 -07:00
stephb9959
368cdb72d4 Adding ies request during WifiScan 2022-05-25 22:36:30 -07:00
stephb9959
712d326560 Adding ies request during WifiScan 2022-05-25 22:33:49 -07:00
stephb9959
11df029ec0 Adding ies request during WifiScan 2022-05-25 22:32:13 -07:00
stephb9959
020542b751 Adding ies request during WifiScan 2022-05-25 22:28:14 -07:00
stephb9959
4b19163091 Adding ies request during WifiScan 2022-05-25 22:24:54 -07:00
stephb9959
852ae3fde7 Adding ies request during WifiScan 2022-05-25 22:22:30 -07:00
stephb9959
1ab9729ec1 Adding ies request during WifiScan 2022-05-25 22:17:55 -07:00
stephb9959
9b1711fff6 Adding ies request during WifiScan 2022-05-25 22:11:23 -07:00
stephb9959
929bc79136 Adding ies request during WifiScan 2022-05-25 22:05:00 -07:00
stephb9959
e8fec5075f Adding ies request during WifiScan 2022-05-25 21:59:44 -07:00
stephb9959
0bae840106 Adding ies request during WifiScan 2022-05-25 21:52:02 -07:00
stephb9959
bf519637aa Adding ies request during WifiScan 2022-05-25 21:47:24 -07:00
stephb9959
b15dc2b517 Adding ies request during WifiScan 2022-05-25 21:41:58 -07:00
stephb9959
44f2843a7f Adding ies request during WifiScan 2022-05-25 21:05:40 -07:00
stephb9959
e2eda25764 Adding ies request during WifiScan 2022-05-25 10:48:36 -07:00
stephb9959
b2411d97d6 Adding ies request during WifiScan 2022-05-25 10:46:20 -07:00
stephb9959
4a61f57912 Adding ies request during WifiScan 2022-05-25 10:38:27 -07:00
stephb9959
1cafe0b6fc Adding ies request during WifiScan 2022-05-25 10:27:33 -07:00
stephb9959
20763dedf6 Adding ies request during WifiScan 2022-05-25 10:15:23 -07:00
stephb9959
80c0a3c07e Adding ies request during WifiScan 2022-05-25 10:01:41 -07:00
stephb9959
0138cfdede Adding ies request during WifiScan 2022-05-25 09:56:26 -07:00
stephb9959
066bad7953 Adding ies request during WifiScan 2022-05-25 09:51:51 -07:00
stephb9959
2ca1508be1 Adding ies request during WifiScan 2022-05-25 09:45:28 -07:00
stephb9959
737e49a376 Adding ies request during WifiScan 2022-05-25 09:23:01 -07:00
stephb9959
251a4c2310 Adding ies request during WifiScan 2022-05-24 11:37:33 -07:00
stephb9959
4e4ad418b6 Merge remote-tracking branch 'origin/master' 2022-05-24 11:30:29 -07:00
stephb9959
b07c381bf7 Adding ies request during WifiScan 2022-05-24 11:30:21 -07:00
TIP Automation User
e3375a4510 Chg: update image tag in helm values to v2.6.0-RC1 2022-05-23 12:12:39 +00:00
Dmitry Dunaev
6134c37d2b [WIFI-7555] Fix: helm path
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-05-23 15:09:38 +03:00
Johann Hoffmann
5e42202264 Enable CI for pull requests in release branches
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-05-23 13:13:39 +02:00
stephb9959
2f389599f8 Radius Proxy Configuration and routing. 2022-05-22 22:23:31 -07:00
stephb9959
36b633fcb7 Radius Proxy 2022-05-20 10:20:09 -07:00
stephb9959
5a1d56399c Fixed the memory reporting in the dashboard. 2022-05-19 22:59:02 -07:00
stephb9959
8ebb92b95a Adding ability to list devices ordered by field names. 2022-05-19 22:45:29 -07:00
stephb9959
69716f50c0 Framework update. 2022-05-19 16:10:53 -07:00
stephb9959
580e4ce052 Fixing Radius Proxy Processing. 2022-05-19 00:41:23 -07:00
stephb9959
ab663be084 Fixing Radius Proxy Processing. 2022-05-18 21:45:09 -07:00
stephb9959
d5350b4283 Adding RadiusProxy processing. 2022-05-18 21:42:48 -07:00
stephb9959
873d77adf0 Adding RadiusProxy processing. 2022-05-18 21:35:11 -07:00
stephb9959
530555ff26 Adding RadiusProxy processing. 2022-05-18 15:55:50 -07:00
stephb9959
3db8892e58 Adding RadiusProxy processing. 2022-05-18 10:23:34 -07:00
stephb9959
c1ba58be6e Adding RadiusProxy processing. 2022-05-18 10:20:56 -07:00
stephb9959
0750be2d81 Adding RadiusProxy processing. 2022-05-18 10:06:59 -07:00
stephb9959
adec21906f Adding RadiusProxy processing. 2022-05-18 10:04:11 -07:00
stephb9959
80b5c6f3b5 Merge remote-tracking branch 'origin/master' 2022-05-18 09:25:30 -07:00
stephb9959
e29a7589f2 Adding RadiusProxy processing. 2022-05-18 09:24:37 -07:00
Dmitry Dunaev
8255ff3218 Merge pull request #92 from Telecominfraproject/feature/wifi-7873--iploc-support
[WIFI-7873] Add: support for ipinfo
2022-05-18 15:35:53 +03:00
Dmitry Dunaev
5b70cdfe53 [WIFI-7873] Add: support for ipinfo
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-05-18 15:35:20 +03:00
stephb9959
2e94733c8d Framework update. 2022-05-17 12:48:02 -07:00
stephb9959
3d62625cf6 Framework update. 2022-05-17 12:34:22 -07:00
stephb9959
eb0eae90b6 Hardening Kafka errors in producer when there is a kafka disconnection. 2022-05-17 12:15:18 -07:00
stephb9959
d7dc43f0de Adding command to run script. 2022-05-15 13:44:19 -07:00
stephb9959
3c6ec00695 Adding command to run script. 2022-05-13 10:09:43 -07:00
stephb9959
eb705dfeb1 Framework update. 2022-05-12 23:18:57 -07:00
stephb9959
46bd78ba15 Framework update. 2022-05-12 23:09:28 -07:00
stephb9959
e730c60ebc Only allowing root users to run scripts. 2022-05-12 12:14:14 -07:00
stephb9959
3329781bc2 Fixing: https://telecominfraproject.atlassian.net/browse/WIFI-7909 2022-05-12 12:08:52 -07:00
stephb9959
dfcc59a7b8 Fixing: https://telecominfraproject.atlassian.net/browse/WIFI-7909 2022-05-12 12:08:18 -07:00
Stephane Bourque
b72fb379cd Merge pull request #90 from Telecominfraproject/feature/WIFI-7714
test_scripts/curl: add option to stream telemetry data to Kafka
2022-05-12 12:01:26 -07:00
stephb9959
74db8cd36d Fixing: https://telecominfraproject.atlassian.net/browse/WIFI-7909 2022-05-12 11:55:43 -07:00
stephb9959
1219a70da2 Fixing: https://telecominfraproject.atlassian.net/browse/WIFI-7909 2022-05-12 11:54:40 -07:00
stephb9959
dc95a8632a Adding new script command. 2022-05-12 08:50:22 -07:00
Stephane Bourque
8b0ecb464b Remove DEBUG/Add Script
Adding scripting definition to the protocol.
2022-05-11 10:08:03 -07:00
stephb9959
9f863c1cc2 Fixes for https://telecominfraproject.atlassian.net/browse/WIFI-7851 2022-05-11 08:22:10 -07:00
stephb9959
fda6f8b2d9 Fixes for https://telecominfraproject.atlassian.net/browse/WIFI-7851 2022-05-11 08:19:19 -07:00
stephb9959
9703ed035a RTTY troubleshooting. 2022-05-11 08:17:17 -07:00
stephb9959
4117ed927a RTTY troubleshooting. 2022-05-11 08:12:30 -07:00
stephb9959
8980eaa5ba RTTY troubleshooting. 2022-05-11 08:10:11 -07:00
stephb9959
d3d1ccee81 RTTY troubleshooting. 2022-05-11 07:42:00 -07:00
stephb9959
4a0aaa8f6b RTTY troubleshooting. 2022-05-11 07:26:04 -07:00
stephb9959
85e84e0672 RTTY troubleshooting. 2022-05-11 07:23:20 -07:00
stephb9959
7d63852d94 RTTY troubleshooting. 2022-05-11 07:17:34 -07:00
stephb9959
698a2b2fcb RTTY troubleshooting. 2022-05-11 07:04:15 -07:00
stephb9959
62e1c6eb0f RTTY troubleshooting. 2022-05-11 06:59:08 -07:00
stephb9959
1a8fa724d6 RTTY troubleshooting. 2022-05-11 06:54:02 -07:00
stephb9959
b4088519cf RTTY troubleshooting. 2022-05-11 06:45:44 -07:00
Stijn Tintel
58ce304e53 test_scripts/curl: add option to stream telemetry data to Kafka
Signed-off-by: Stijn Tintel <stijn@linux-ipv6.be>
2022-05-11 13:57:20 +03:00
stephb9959
9fbc77a85a RTTY troubleshooting. 2022-05-10 23:15:59 -07:00
stephb9959
623c4c43d4 RTTY troubleshooting. 2022-05-10 22:47:39 -07:00
stephb9959
63ea97b435 RTTY troubleshooting. 2022-05-10 22:34:42 -07:00
stephb9959
d9f3d92736 RTTY troubleshooting. 2022-05-10 22:20:39 -07:00
stephb9959
7fc2239e59 RTTY troubleshooting. 2022-05-10 21:36:44 -07:00
stephb9959
badfe61d6a RTTY troubleshooting. 2022-05-10 21:16:30 -07:00
stephb9959
ab57221040 RTTY troubleshooting. 2022-05-10 21:06:18 -07:00
stephb9959
5ae62b8892 RTTY troubleshooting. 2022-05-10 20:43:54 -07:00
stephb9959
c5425fc9cf RTTY troubleshooting. 2022-05-10 20:16:26 -07:00
stephb9959
dbdc14891c RTTY troubleshooting. 2022-05-10 20:11:08 -07:00
stephb9959
f4b4627c78 RTTY troubleshooting. 2022-05-10 20:10:40 -07:00
stephb9959
35dbe47571 RTTY troubleshooting. 2022-05-10 20:00:25 -07:00
stephb9959
a97337234e RTTY troubleshooting. 2022-05-10 19:54:05 -07:00
stephb9959
a87b8de6e3 RTTY troubleshooting. 2022-05-10 19:52:56 -07:00
stephb9959
949d7a54ad RTTY troubleshooting. 2022-05-10 19:46:56 -07:00
stephb9959
5a3c97a529 RTTY troubleshooting. 2022-05-10 19:32:16 -07:00
stephb9959
0772898160 RTTY troubleshooting. 2022-05-10 19:25:41 -07:00
stephb9959
638ed3f5c8 RTTY troubleshooting. 2022-05-10 19:04:43 -07:00
stephb9959
d996e9e05e RTTY troubleshooting. 2022-05-10 18:43:59 -07:00
stephb9959
58fd622980 RTTY troubleshooting. 2022-05-10 16:20:32 -07:00
stephb9959
29113ac39c RTTY troubleshooting. 2022-05-10 16:08:15 -07:00
stephb9959
f947f472b9 RTTY troubleshooting. 2022-05-10 16:06:02 -07:00
stephb9959
393763fb9e RTTY troubleshooting. 2022-05-10 15:46:50 -07:00
stephb9959
eced94910d RTTY troubleshooting. 2022-05-10 15:36:59 -07:00
stephb9959
df000f35ee RTTY troubleshooting. 2022-05-10 11:03:10 -07:00
stephb9959
24d2de568f RTTY troubleshooting. 2022-05-10 10:53:57 -07:00
stephb9959
8508396ae6 RTTY troubleshooting. 2022-05-10 10:31:13 -07:00
stephb9959
9f6d38e6b7 RTTY troubleshooting. 2022-05-10 10:20:00 -07:00
stephb9959
b8f3b9b37a Framework update. 2022-05-10 08:56:19 -07:00
stephb9959
71cdcb5909 Framework update. 2022-05-10 07:46:23 -07:00
stephb9959
e92e852dcb Merge remote-tracking branch 'origin/master' 2022-05-10 07:45:54 -07:00
stephb9959
0ac5b3a39d Adding "Content-Type: application/json" to commands for https://telecominfraproject.atlassian.net/browse/WIFI-7867 2022-05-10 07:45:45 -07:00
Johann Hoffmann
3fbf460f81 Wait for AP to connect until timeout
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-05-10 10:50:24 +02:00
stephb9959
9b7db5c095 Framework Update. 2022-05-09 10:29:22 -07:00
stephb9959
eb9e88b54a Framework Update. 2022-05-09 09:58:49 -07:00
stephb9959
952b1c4562 Adding DEBUG for device. 2022-05-08 09:52:05 -07:00
stephb9959
cec50beecf Framework update. 2022-05-08 08:49:18 -07:00
stephb9959
2048107866 Error Framework migration. 2022-05-07 21:58:43 -07:00
stephb9959
2d72a15ec0 Error Framework migration. 2022-05-06 23:11:07 -07:00
stephb9959
d5c36aa2e9 Error Framework migration. 2022-05-06 23:10:40 -07:00
stephb9959
41079d9f0b Adding Notification. 2022-05-06 10:27:09 -07:00
stephb9959
a47977b029 Framework update. 2022-05-05 21:28:52 -07:00
stephb9959
e20b71181f Framework update. 2022-05-05 21:19:11 -07:00
stephb9959
4f29e5a650 WebSocket Notification Framework update 2022-05-05 20:48:16 -07:00
stephb9959
e168c7b2c7 WebSocket Notification Framework update 2022-05-05 20:28:56 -07:00
stephb9959
1f6de95f16 WebSocket Notification Framework update 2022-05-05 20:26:08 -07:00
stephb9959
96995730c6 Proper Reactor Pool sizing. 2022-05-05 19:39:51 -07:00
stephb9959
9d000ca84d Proper Reactor Pool sizing. 2022-05-05 16:52:28 -07:00
stephb9959
9af6deaec3 Proper Reactor Pool sizing. 2022-05-05 16:08:38 -07:00
stephb9959
aaa13e1e2f Proper Reactor Pool sizing. 2022-05-05 15:26:11 -07:00
stephb9959
bd0419fb0c Proper Reactor Pool sizing. 2022-05-05 15:18:13 -07:00
stephb9959
656efd0d57 Proper Reactor Pool sizing. 2022-05-05 15:11:01 -07:00
stephb9959
863ff017b0 Increasing timeout for WifiScan. 2022-05-05 09:28:40 -07:00
stephb9959
8c26cc37d7 Increasing timeout for WifiScan. 2022-05-05 07:49:50 -07:00
stephb9959
4e9c26cd04 Cleaning up extra logging. 2022-05-04 23:51:31 -07:00
stephb9959
d098bca86f Cleaning up extra logging. 2022-05-04 23:38:00 -07:00
stephb9959
9980c2b175 Cleaning up extra logging. 2022-05-04 23:32:57 -07:00
stephb9959
a52daae4a5 Cleaning up extra logging. 2022-05-04 23:27:00 -07:00
stephb9959
1d8af05302 Cleaning up extra logging. 2022-05-04 23:06:22 -07:00
stephb9959
2efccedfba Fixing trace logging. 2022-05-04 22:57:46 -07:00
stephb9959
243b615814 Fixing OUI Caching issue. 2022-05-04 22:33:38 -07:00
stephb9959
dc37bcb5ff Fixing OUI Caching issue. 2022-05-04 22:19:35 -07:00
stephb9959
edac1d6ceb Fixing OUI Caching issue. 2022-05-04 22:11:19 -07:00
stephb9959
64848d8fdd Fixing OUI Caching issue. 2022-05-04 22:01:41 -07:00
stephb9959
c874b7633d Removing unused ReactorPool 2022-05-04 21:54:46 -07:00
stephb9959
2ca85970e4 Removing unused ReactorPool 2022-05-04 21:49:05 -07:00
stephb9959
0184aa8879 Removing unused ReactorPool 2022-05-04 21:35:56 -07:00
stephb9959
ac05fe833e Removing unused ReactorPool 2022-05-04 21:31:17 -07:00
stephb9959
998a686179 Removing unused ReactorPool 2022-05-04 21:27:04 -07:00
stephb9959
288b5e207f Trace queue ageing fix. 2022-05-04 18:32:56 -07:00
stephb9959
2ec0c923c3 Trace queue ageing fix. 2022-05-04 18:06:58 -07:00
stephb9959
4c9dd0cef7 Trace queue ageing fix. 2022-05-04 14:39:15 -07:00
stephb9959
8f16abd4ff Trace fixed. 2022-05-04 14:26:51 -07:00
stephb9959
c706ea4118 Trace fixed. 2022-05-04 12:24:16 -07:00
stephb9959
9c2fef1ee4 Trace fixed. 2022-05-04 12:07:49 -07:00
stephb9959
1648acca32 Trace fixed. 2022-05-04 11:59:16 -07:00
stephb9959
c11c0281ce Trace Upload failure. 2022-05-04 11:52:23 -07:00
stephb9959
58ee7344bf Trace Upload failure. 2022-05-04 11:47:59 -07:00
stephb9959
6c9dac79d5 Trace Upload failure. 2022-05-04 11:34:04 -07:00
stephb9959
7aa284e92c Trace Upload failure. 2022-05-04 11:29:43 -07:00
stephb9959
933b41e7c1 Trace Upload failure. 2022-05-04 11:17:54 -07:00
stephb9959
a39e586bc1 Trace Upload failure. 2022-05-04 11:11:51 -07:00
stephb9959
4e81683bcd Trace Upload failure. 2022-05-04 11:05:22 -07:00
stephb9959
6a74297cb3 Trace Upload failure. 2022-05-04 11:01:12 -07:00
stephb9959
67764ec5c1 Trace Upload failure. 2022-05-04 10:55:57 -07:00
stephb9959
ebbcd99453 Trace Upload failure. 2022-05-04 10:52:00 -07:00
stephb9959
3719df39fe Trace Upload failure. 2022-05-04 10:37:02 -07:00
stephb9959
70670117a7 Trace Upload failure. 2022-05-04 10:10:56 -07:00
stephb9959
31f77b84d6 Trace Upload failure. 2022-05-04 09:53:51 -07:00
stephb9959
924e2f0775 Trace Upload failure. 2022-05-04 09:50:37 -07:00
stephb9959
cb61ce3f9e Trace Upload failure. 2022-05-04 09:49:49 -07:00
stephb9959
d97033d6cf Trace Upload failure. 2022-05-04 09:48:56 -07:00
stephb9959
c2f547da0c Trace Upload failure. 2022-05-04 09:35:07 -07:00
stephb9959
7cc60e6063 Trace Upload failure. 2022-05-04 09:19:42 -07:00
stephb9959
4f117199f0 Merge remote-tracking branch 'origin/master' 2022-05-04 09:05:05 -07:00
stephb9959
0d444c4bc9 Trace Upload failure. 2022-05-04 09:04:57 -07:00
Johann Hoffmann
87646944dd Support older releases in test_service CLI command
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-05-04 17:24:33 +02:00
stephb9959
13c9633964 Trace Upload failure. 2022-05-04 08:19:36 -07:00
stephb9959
ab77f1371d Merge remote-tracking branch 'origin/master' 2022-05-04 07:55:24 -07:00
stephb9959
4ac71c4af2 Trace Upload failure. 2022-05-04 07:54:52 -07:00
Johann Hoffmann
1ca1fffa26 Add FLAGS variable in curl request
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-05-04 11:34:45 +02:00
stephb9959
4e623ab182 Trace Upload failure. 2022-05-03 23:44:09 -07:00
stephb9959
fb27ea8528 Trace Upload failure. 2022-05-03 23:30:52 -07:00
stephb9959
bc20d66694 Adding proper loggin to RTTYS 2022-05-03 23:15:25 -07:00
stephb9959
beadcd50e7 Adding proper loggin to RTTYS 2022-05-03 23:05:32 -07:00
stephb9959
5d1c9b10da Adding proper loggin to RTTYS 2022-05-03 22:58:38 -07:00
stephb9959
7e877b74a7 Adding proper loggin to RTTYS 2022-05-03 22:49:41 -07:00
stephb9959
47b569aa59 Adding proper loggin to RTTYS 2022-05-03 22:45:06 -07:00
stephb9959
2afa4b64e8 Adding proper loggin to RTTYS 2022-05-03 22:35:13 -07:00
stephb9959
315bad5451 Adding proper loggin to RTTYS 2022-05-03 22:18:02 -07:00
stephb9959
c8fa1d5405 Adding proper loggin to RTTYS 2022-05-03 22:07:52 -07:00
stephb9959
40a28015bd Adding proper loggin to RTTYS 2022-05-03 22:07:00 -07:00
stephb9959
4a25b0ba99 Adding proper loggin to RTTYS 2022-05-03 21:29:33 -07:00
stephb9959
9ea7ab14df Adding proper loggin to RTTYS 2022-05-03 21:25:39 -07:00
stephb9959
aa692d9f30 Adding proper loggin to RTTYS 2022-05-03 20:56:15 -07:00
stephb9959
044d978c46 Fixing CORS issues in RTTY WebService 2022-05-03 20:05:08 -07:00
stephb9959
b767dd3aa4 Fixing CORS issues in RTTY WebService 2022-05-03 19:55:57 -07:00
stephb9959
9acbd6cef6 Framework update 2022-05-03 19:22:42 -07:00
stephb9959
a20ec0587e Framework update 2022-05-03 18:57:03 -07:00
stephb9959
28b72a6303 Framework update 2022-05-03 18:02:46 -07:00
stephb9959
9540fc9a5f Fixing command manager 2022-05-03 17:24:58 -07:00
stephb9959
18eac29b1a Fixing command manager 2022-05-03 17:09:58 -07:00
stephb9959
76b2255716 Framework Update 2022-05-03 08:38:32 -07:00
stephb9959
17377aa8bc Fix missing dates for notes on device. 2022-05-03 07:35:39 -07:00
stephb9959
d1a50fcf22 Fixing RTTYs failure to detect bad socket. 2022-05-02 23:37:08 -07:00
stephb9959
cccd8f8fbd Fixing RTTYs failure to detect bad socket. 2022-05-02 22:42:37 -07:00
stephb9959
9c37d0760d Fixing RTTYs failure to detect bad socket. 2022-05-02 22:08:06 -07:00
stephb9959
90d56197e6 Fixing RTTYs failure t odetect bad socket. 2022-05-02 21:55:11 -07:00
stephb9959
6b91065468 Fixing FileUploader for NoSecurityAPI(). 2022-05-02 21:48:53 -07:00
stephb9959
f851957523 Framework Update 2022-05-02 13:53:21 -07:00
stephb9959
ec0574bfdf Framework Update 2022-05-02 11:43:51 -07:00
stephb9959
6bc279ac32 Framework Update 2022-05-02 11:26:59 -07:00
stephb9959
1cdb5ef2e3 Framework Update 2022-05-02 10:37:48 -07:00
stephb9959
d85854a1f2 Fixing NoAPISecurity for RTTY Server 2022-05-01 21:17:29 -07:00
stephb9959
e0d6fb0bcc Fixing NoAPISecurity for RTTY Server 2022-05-01 11:10:47 -07:00
stephb9959
6e864c14a1 Fixing NoAPISecurity for RTTY Server 2022-05-01 10:35:24 -07:00
stephb9959
8e49ffa904 Fixing NoAPISecurity for RTTY Server 2022-04-30 22:42:14 -07:00
stephb9959
4db50c0ed2 Added firmware updated notification. 2022-04-30 22:32:09 -07:00
stephb9959
191611bc24 New web socket notifications. 2022-04-30 22:20:34 -07:00
stephb9959
d10541afb7 New web socket notifications. 2022-04-30 21:42:04 -07:00
stephb9959
1887878088 New web socket notifications. 2022-04-29 14:20:45 -07:00
stephb9959
de3985191a New web socket notifications. 2022-04-29 14:08:38 -07:00
stephb9959
629a615f7c Framework Update. 2022-04-28 14:12:48 -07:00
stephb9959
ec947df8a0 Framework Update. 2022-04-28 12:57:24 -07:00
stephb9959
203095a6f7 Framework Update. 2022-04-28 12:55:57 -07:00
stephb9959
f71ce62c5b Framework Update. 2022-04-28 12:52:34 -07:00
stephb9959
89680d6be7 Framework Update. 2022-04-28 12:50:57 -07:00
stephb9959
e411f4f6ac Framework Update. 2022-04-28 12:48:45 -07:00
stephb9959
bbcb23b821 Framework Update. 2022-04-28 12:44:22 -07:00
stephb9959
75dfd49067 Framework Update. 2022-04-28 12:41:46 -07:00
stephb9959
39d4423a5e Framework Update. 2022-04-28 12:37:19 -07:00
stephb9959
6238fee522 Framework Update. 2022-04-28 12:27:14 -07:00
stephb9959
e301ea7cee Cleaning up logging for RTTYS. 2022-04-27 21:05:41 -07:00
stephb9959
42aff04610 Cleaning up logging for RTTYS. 2022-04-27 16:04:07 -07:00
stephb9959
345053bdba Cleaning up logging for RTTYS. 2022-04-27 09:28:06 -07:00
stephb9959
285fd26f99 Improving device command queue. 2022-04-27 08:38:08 -07:00
103 changed files with 10591 additions and 3012 deletions

View File

@@ -13,6 +13,7 @@ on:
pull_request:
branches:
- master
- 'release/*'
defaults:
run:

View File

@@ -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

View File

@@ -22,7 +22,7 @@ jobs:
path: wlan-cloud-ucentralgw
- name: Build package
working-directory: wlan-cloud-ucentralgw/chart
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
@@ -32,7 +32,7 @@ jobs:
helm package . -d dist
- name: Generate GitHub release body
working-directory: wlan-cloud-ucentralgw/chart
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
@@ -42,5 +42,5 @@ jobs:
- name: Create GitHub release
uses: softprops/action-gh-release@v1
with:
body_path: wlan-cloud-ucentralgw/chart/release.txt
files: wlan-cloud-ucentralgw/chart/dist/*
body_path: wlan-cloud-ucentralgw/helm/release.txt
files: wlan-cloud-ucentralgw/helm/dist/*

View File

@@ -67,6 +67,8 @@ 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
@@ -97,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
@@ -117,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)
if(NOT SMALL_BUILD)

182
MICRO_SERVICE_PROTOCOL.md Normal file
View 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
```

View File

@@ -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,19 @@ 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>
}
```
### Controller commands
Most controller commands include a `when` member. This is a UTC clock time asking the AP
@@ -180,7 +193,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 +207,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 +246,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 +258,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 +277,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 +290,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 +306,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 +319,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 +333,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 +390,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 +411,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 +425,7 @@ and the controller.
```
The device should answer:
```
```json
{ "jsonrpc" : "2.0" ,
"result" : {
"serial" : <serial number> ,
@@ -395,7 +448,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 +465,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 +491,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 +499,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 +531,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 +545,7 @@ message will be returned "soon".
```
The device should answer:
```
```json
{ "jsonrpc" : "2.0" ,
"result" : {
"serial" : <serial number> ,
@@ -507,7 +561,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 +575,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 +591,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 +604,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 +618,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 +633,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 +651,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 +667,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 +678,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 +689,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 +740,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 +749,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
```

View File

@@ -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 ..

2
build
View File

@@ -1 +1 @@
42
144

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@ if [ "$SELFSIGNED_CERTS" = 'true' ]; then
update-ca-certificates
fi
if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWGW_CONFIG"/owgw.properties ]]; then
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"} \

View File

@@ -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"

View File

@@ -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

View File

@@ -9,7 +9,7 @@ fullnameOverride: ""
images:
owgw:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owgw
tag: master
tag: v2.6.0
pullPolicy: Always
# regcred:
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
@@ -215,8 +215,9 @@ 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

View File

@@ -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:

View File

@@ -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
#############################

41
pcap/radius Normal file
View 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
View File

@@ -0,0 +1 @@
192.168.178.1

BIN
pcap/radius.pcapng Normal file

Binary file not shown.

72
radius_config_sample.json Normal file
View 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!"
}
]
}
}
]
}

View File

@@ -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,38 +19,48 @@
namespace OpenWifi {
void CommandManager::run() {
Utils::SetThreadName("cmd-mgr");
Running_ = true;
Poco::AutoPtr<Poco::Notification> NextMsg(ResponseQueue_.waitDequeueNotification());
while(NextMsg && Running_) {
auto Resp = dynamic_cast<RPCResponseNotification*>(NextMsg.get());
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));
return;
} 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 {
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));
}
}
}
uint64_t ID = Payload.get(uCentralProtocol::ID);
if(ID<2) {
Logger().debug(fmt::format("({}): Ignoring RPC response.", SerialNumber));
return;
}
auto Idx = CommandTagIndex{.Id = ID, .SerialNumber = SerialNumber};
auto RPC = OutStandingRequests_.find(Idx);
if (RPC == OutStandingRequests_.end()) {
Logger().warning(fmt::format("({}): Outdated RPC {}", 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, 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));
}
NextMsg = ResponseQueue_.waitDequeueNotification();
}
@@ -70,15 +79,11 @@ namespace OpenWifi {
CommandRunnerTimer_.setPeriodicInterval(30 * 1000); // 1 hours
CommandRunnerTimer_.start(*CommandRunnerCallback_);
// RPCResponseQueue_->Readable_ += Poco::delegate(this,&CommandManager::onRPCAnswer);
// RPCResponseQueue_->Writable_ += Poco::delegate(this,&CommandManager::onRPCAnswer);
return 0;
}
void CommandManager::Stop() {
Logger().notice("Stopping...");
// RPCResponseQueue_->Readable_ -= Poco::delegate(this,&CommandManager::onRPCAnswer);
// RPCResponseQueue_->Writable_ -= Poco::delegate(this,&CommandManager::onRPCAnswer);
Running_ = false;
JanitorTimer_.stop();
CommandRunnerTimer_.stop();
@@ -94,24 +99,29 @@ namespace OpenWifi {
void CommandManager::onJanitorTimer([[maybe_unused]] Poco::Timer & timer) {
std::lock_guard G(Mutex_);
Logger().information(
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) {
Logger().debug(fmt::format("Timing out {}", i->second->uuid));
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.");
}
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))
{
@@ -128,9 +138,8 @@ namespace OpenWifi {
Poco::JSON::Parser P;
bool Sent;
Logger().information(fmt::format("Parsing: {}", Cmd.UUID));
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>();
Logger().information(fmt::format("Parsed: {}", Cmd.UUID));
auto Result = PostCommandDisk( Cmd.SerialNumber,
Cmd.Command,
*Params,
@@ -138,24 +147,25 @@ namespace OpenWifi {
Sent);
if(Sent) {
StorageService()->SetCommandExecuted(Cmd.UUID);
std::lock_guard M(Mutex_);
OutstandingUUIDs_.insert(Cmd.UUID);
Logger().information(fmt::format("{}: Sent command '{}-{}'", Cmd.SerialNumber, Cmd.Command, Cmd.UUID));
MyLogger.information(fmt::format("{}: Queued command.", Cmd.UUID));
} else {
Logger().information(fmt::format("{}: Could not send command '{}-{}'", Cmd.SerialNumber, Cmd.Command, Cmd.UUID));
MyLogger.information(fmt::format("{}: Could queue command.", Cmd.UUID));
}
} catch (const Poco::Exception &E) {
Logger().information(fmt::format("{}: Failed command '{}-{}'", Cmd.SerialNumber, Cmd.Command, Cmd.UUID));
Logger().log(E);
MyLogger.information(fmt::format("{}: Failed. Command marked as completed.", Cmd.UUID));
MyLogger.log(E);
StorageService()->SetCommandExecuted(Cmd.UUID);
} catch (...) {
Logger().information(fmt::format("{}: Exception - hard fail - Failed command '{}-{}'", Cmd.SerialNumber, Cmd.Command, Cmd.UUID));
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,
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,
@@ -186,9 +196,6 @@ namespace OpenWifi {
CompleteRPC.set(uCentralProtocol::METHOD, Method);
CompleteRPC.set(uCentralProtocol::PARAMS, Params);
Poco::JSON::Stringifier::stringify(CompleteRPC, ToSend);
Logger().information(
fmt::format("({}): Sending command '{}', ID: {}", SerialNumber, Method, Idx.Id));
Object->submitted = std::chrono::high_resolution_clock::now();
Object->uuid = UUID;
if(disk_only) {
@@ -202,46 +209,13 @@ namespace OpenWifi {
}
}
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::onRPCAnswer(bool &b) {
if(b) {
RPCResponse Resp;
auto S = RPCResponseQueue_->Read(Resp);
const std::string & SerialNumber = Resp.serialNumber;
std::lock_guard M(Mutex_);
if(S) {
if(!Resp.payload.has(uCentralProtocol::ID)){
Logger().error(fmt::format("({}): Invalid RPC response.", SerialNumber));
return;
}
uint64_t ID = Resp.payload.get(uCentralProtocol::ID);
if(ID<2) {
Logger().debug(fmt::format("({}): Ignoring RPC response.", SerialNumber));
return;
}
auto Idx = CommandTagIndex{.Id = ID, .SerialNumber = SerialNumber};
auto RPC = OutStandingRequests_.find(Idx);
if (RPC == OutStandingRequests_.end()) {
Logger().warning(fmt::format("({}): Outdated RPC {}", 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, Resp.payload, rpc_execution_time, true);
if(RPC->second->rpc_entry) {
RPC->second->rpc_entry->set_value(Resp.payload);
}
OutstandingUUIDs_.erase(RPC->second->uuid);
OutStandingRequests_.erase(Idx);
Logger().information(fmt::format("({}): Received RPC answer {}", SerialNumber, ID));
}
}
}
*/
} // namespace

View File

@@ -154,16 +154,15 @@ namespace OpenWifi {
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_;
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_;
// std::unique_ptr<FIFO<RPCResponse>> RPCResponseQueue_=std::make_unique<FIFO<RPCResponse>>(100);
Poco::NotificationQueue ResponseQueue_;
std::shared_ptr<promise_type_t> PostCommand(

View File

@@ -24,6 +24,7 @@
#include "framework/MicroService.h"
#include "FindCountry.h"
#include "rttys/RTTYS_server.h"
#include "RADIUS_proxy_server.h"
namespace OpenWifi {
class Daemon *Daemon::instance() {
@@ -36,6 +37,7 @@ namespace OpenWifi {
StorageService(),
SerialNumberCache(),
ConfigurationValidator(),
WebSocketClientServer(),
OUIServer(),
FindCountryFromIP(),
DeviceRegistry(),
@@ -44,7 +46,8 @@ namespace OpenWifi {
StorageArchiver(),
TelemetryStream(),
RTTYS_server(),
WebSocketServer()
WebSocketServer(),
RADIUS_proxy_server()
});
return &instance;
}
@@ -85,6 +88,8 @@ namespace OpenWifi {
void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) {
AutoProvisioning_ = config().getBool("openwifi.autoprovisioning",false);
DeviceTypes_ = DefaultDeviceTypes;
WebSocketProcessor_ = std::make_unique<GwWebSocketClient>(logger());
}
[[nodiscard]] std::string Daemon::IdentifyDevice(const std::string & Id ) const {

View File

@@ -27,6 +27,7 @@
#include "Dashboard.h"
#include "framework/MicroService.h"
#include "framework/OpenWifiTypes.h"
#include "GwWebSocketClient.h"
namespace OpenWifi {
@@ -56,7 +57,7 @@ namespace OpenWifi {
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(); }

View File

@@ -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();

View File

@@ -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 ;
@@ -139,6 +139,57 @@ namespace OpenWifi {
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;
Device->second->Conn_.VerifiedCertificate = GWObjects::NO_CERTIFICATE;
}
}
return false;
}
void DeviceRegistry::SetPendingUUID(uint64_t SerialNumber, uint64_t PendingUUID) {
std::lock_guard Guard(Mutex_);
auto Device = Devices_.find(SerialNumber);

View File

@@ -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_;

View File

@@ -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(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));
} 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);
@@ -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(fmt::format("FILE-UPLOADER: uploading trace for {}", 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(fmt::format("Error occurred while performing upload. Error='{}'",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_;

View File

@@ -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
View 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
View 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_; }
};
}

View File

@@ -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);
@@ -42,18 +45,11 @@ namespace OpenWifi {
bool OUIServer::GetFile(const std::string &FileName) {
try {
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()) {
auto LastModified = F.getLastModified();
auto Delta = OpenWifi::Now() - LastModified.epochTime();
if((Delta / (24*60*60)) < 1)
return true;
F.remove();
}
OS.open(FileName);
Poco::StreamCopier::copyStream(*pStr, OS);
OS.close();
@@ -102,32 +98,48 @@ namespace OpenWifi {
}
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(fmt::format("New OUI file {} 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;
}

View File

@@ -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")

1830
src/ParseWifiScan.h Normal file

File diff suppressed because it is too large Load Diff

211
src/RADIUS_helpers.h Normal file
View 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
View 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
View 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(); }
}

View File

@@ -11,6 +11,7 @@
#include "DeviceRegistry.h"
#include "StorageService.h"
#include "framework/ow_constants.h"
#include "ParseWifiScan.h"
namespace OpenWifi::RESTAPI_RPC {
void SetCommandStatus(GWObjects::CommandDetails &Cmd,
@@ -22,9 +23,12 @@ namespace OpenWifi::RESTAPI_RPC {
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,10 +40,13 @@ 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;
}
@@ -51,81 +58,88 @@ namespace OpenWifi::RESTAPI_RPC {
std::shared_ptr<CommandManager::promise_type_t> rpc_endpoint =
CommandManager()->PostCommand(Cmd.SerialNumber, Cmd.Command, Params, Cmd.UUID, Sent);
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);
}
Logger.information(fmt::format("{}: Command sent.", Cmd.UUID));
Poco::JSON::Object L;
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) {
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)) {
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 (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->ReturnObject(*ObjectToReturn);
} else {
Poco::JSON::Object O;
Cmd.to_json(O);
Handler->ReturnObject(O);
}
Logger.information( fmt::format("Command({}): completed in {:.3f}ms.", Cmd.UUID, Cmd.executionTime));
return;
} else {
SetCommandStatus(Cmd, Request, Response, Handler,
Storage::COMMAND_FAILED, Logger);
Logger.information(fmt::format(
"Invalid response for command '{}'. Missing status.", Cmd.UUID));
return;
}
} else {
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_FAILED,
Logger);
Logger.information(fmt::format(
"Invalid response for command '{}'. Missing status.", Cmd.UUID));
return;
}
} else if (rpc_result == std::future_status::timeout) {
Logger.information(fmt::format(
"Timeout2 for command '{}'.", Cmd.UUID));
SetCommandStatus(Cmd, Request, Response, Handler, Storage::COMMAND_TIMEDOUT,
Logger);
return;
} else {
Logger.information(fmt::format(
"Pending completion for command '{}'.", 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(fmt::format(
"Pending completion for command '{}'.", 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);
}
}

View File

@@ -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);

View File

@@ -45,6 +45,6 @@ namespace OpenWifi {
if (StorageService()->DeleteCommand(CommandUUID)) {
return OK();
}
return InternalError();
return InternalError(RESTAPI::Errors::NoRecordsDeleted);
}
}

View File

@@ -40,6 +40,6 @@ namespace OpenWifi {
if (StorageService()->DeleteCommands(SerialNumber, QB_.StartDate, QB_.EndDate)) {
return OK();
}
InternalError();
InternalError(RESTAPI::Errors::NoRecordsDeleted);
}
}

View File

@@ -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;

File diff suppressed because it is too large Load Diff

View File

@@ -45,6 +45,7 @@ namespace OpenWifi {
void Rtty();
void Telemetry();
void Ping();
void Script();
static auto PathName() { return std::list<std::string>{"/api/v1/device/{serialNumber}/{command}"}; };
void DoGet() final;

View File

@@ -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);
@@ -111,7 +111,6 @@ namespace OpenWifi {
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;

View File

@@ -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);
@@ -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;

View File

@@ -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() {

View 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_);
}
}

View 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;
};
}

View File

@@ -16,11 +16,10 @@
#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 {
@@ -44,6 +43,7 @@ namespace OpenWifi {
RESTAPI_blacklist,
RESTAPI_blacklist_list,
RESTAPI_iptocountry_handler,
RESTAPI_radiusProxyConfig_handler,
RESTAPI_capabilities_handler, RESTAPI_telemetryWebSocket>(Path,Bindings,L, S, 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);
}
}

View File

@@ -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 {
@@ -29,10 +30,15 @@ void RESTAPI_telemetryWebSocket::DoGet() {
if(!TelemetryStream()->IsValidEndPoint(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;
}
}
}

View File

@@ -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(fmt::format("serial_number_search: {}", 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;
}
}

View File

@@ -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 auto PathName() { return std::list<std::string>{"/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);
};
}

View File

@@ -14,7 +14,7 @@ namespace OpenWifi::AnalyticsObjects {
void Report::reset() {
}
void Report::to_json(Poco::JSON::Object &Obj) const {
void Report::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const {
}
void VenueInfo::to_json(Poco::JSON::Object &Obj) const {
@@ -167,6 +167,23 @@ namespace OpenWifi::AnalyticsObjects {
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) {
@@ -184,6 +201,21 @@ namespace OpenWifi::AnalyticsObjects {
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(...) {
@@ -203,6 +235,24 @@ namespace OpenWifi::AnalyticsObjects {
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) {
@@ -218,6 +268,25 @@ namespace OpenWifi::AnalyticsObjects {
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(...) {
@@ -247,7 +316,7 @@ namespace OpenWifi::AnalyticsObjects {
void RadioTimePoint::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"band",band);
field_to_json(Obj,"radio_channel",radio_channel);
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);
@@ -256,12 +325,16 @@ namespace OpenWifi::AnalyticsObjects {
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,"radio_channel",radio_channel);
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);
@@ -270,6 +343,28 @@ namespace OpenWifi::AnalyticsObjects {
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(...) {
@@ -282,7 +377,15 @@ namespace OpenWifi::AnalyticsObjects {
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) {
@@ -291,7 +394,15 @@ namespace OpenWifi::AnalyticsObjects {
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(...) {
@@ -307,6 +418,7 @@ namespace OpenWifi::AnalyticsObjects {
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) {
@@ -318,6 +430,49 @@ namespace OpenWifi::AnalyticsObjects {
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(...) {
@@ -327,11 +482,13 @@ namespace OpenWifi::AnalyticsObjects {
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(...) {
@@ -357,4 +514,111 @@ namespace OpenWifi::AnalyticsObjects {
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;
}
}

View File

@@ -109,6 +109,14 @@ namespace OpenWifi {
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;
@@ -121,9 +129,26 @@ namespace OpenWifi {
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> tidstat;
std::vector<TIDstat_entry> tidstats;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -159,9 +184,18 @@ namespace OpenWifi {
std::string bssid,
mode,
ssid;
uint64_t band=0;
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);
};
@@ -184,7 +218,18 @@ namespace OpenWifi {
rx_dropped_pct = 0.0,
tx_dropped_pct = 0.0,
rx_packets_bw = 0.0,
tx_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);
@@ -192,15 +237,20 @@ namespace OpenWifi {
struct RadioTimePoint {
uint64_t band = 0,
radio_channel = 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;
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);
@@ -208,13 +258,14 @@ namespace OpenWifi {
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 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);
@@ -245,9 +296,34 @@ namespace OpenWifi {
};
struct DeviceTimePointList {
std::vector<DeviceTimePoint> points;
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);
};
@@ -286,5 +362,61 @@ namespace OpenWifi {
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);
};
}
}

View File

@@ -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();
}
}

View File

@@ -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);
};
}
}

View File

@@ -233,7 +233,7 @@ namespace OpenWifi::FMSObjects {
UnknownFirmwares_.clear();
totalSecondsOld_.clear();
numberOfDevices = 0 ;
snapshot = std::time(nullptr);
snapshot = OpenWifi::Now();
}
bool DeviceReport::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) {
@@ -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;
}
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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);
};
}

View File

@@ -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,7 +154,7 @@ 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);
@@ -178,7 +178,7 @@ 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);
@@ -197,9 +197,7 @@ namespace OpenWifi::ProvObjects {
info.to_json(Obj);
field_to_json( Obj,"managementPolicy",managementPolicy);
field_to_json( Obj,"managementRoles",managementRoles);
field_to_json( Obj,"rrm",rrm);
field_to_json( Obj,"firmwareUpgrade",firmwareUpgrade);
field_to_json( Obj,"firmwareRCOnly",firmwareRCOnly);
field_to_json( Obj,"deviceRules",deviceRules);
field_to_json( Obj,"variables",variables);
field_to_json( Obj,"defaultOperator",defaultOperator);
field_to_json( Obj,"sourceIP",sourceIP);
@@ -211,9 +209,7 @@ namespace OpenWifi::ProvObjects {
info.from_json(Obj);
field_from_json( Obj,"managementPolicy",managementPolicy);
field_from_json( Obj,"managementRoles",managementRoles);
field_from_json( Obj,"rrm",rrm);
field_from_json( Obj,"firmwareUpgrade",firmwareUpgrade);
field_from_json( Obj,"firmwareRCOnly",firmwareRCOnly);
field_from_json( Obj,"deviceRules",deviceRules);
field_from_json( Obj,"variables",variables);
field_from_json( Obj,"defaultOperator",defaultOperator);
field_from_json( Obj,"sourceIP",sourceIP);
@@ -598,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);
@@ -619,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);
@@ -690,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) {
@@ -707,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(...) {
@@ -896,6 +888,7 @@ namespace OpenWifi::ProvObjects {
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) {
@@ -912,6 +905,7 @@ namespace OpenWifi::ProvObjects {
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(...) {
@@ -994,6 +988,26 @@ namespace OpenWifi::ProvObjects {
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);
@@ -1006,7 +1020,7 @@ namespace OpenWifi::ProvObjects {
field_to_json( Obj,"serviceClass", serviceClass);
field_to_json( Obj,"qrCode", qrCode);
field_to_json( Obj,"geoCode", geoCode);
field_to_json( Obj,"rrm", rrm);
field_to_json( Obj,"deviceRules",deviceRules);
field_to_json( Obj,"state", state);
field_to_json( Obj,"locale", locale);
field_to_json( Obj,"billingCode", billingCode);
@@ -1028,7 +1042,7 @@ namespace OpenWifi::ProvObjects {
field_from_json( Obj,"serviceClass", serviceClass);
field_from_json( Obj,"qrCode", qrCode);
field_from_json( Obj,"geoCode", geoCode);
field_from_json( Obj,"rrm", rrm);
field_from_json( Obj,"deviceRules",deviceRules);
field_from_json( Obj,"state", state);
field_from_json( Obj,"locale", locale);
field_from_json( Obj,"billingCode", billingCode);
@@ -1077,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();
@@ -1127,41 +1141,17 @@ namespace OpenWifi::ProvObjects {
return true;
}
void WebSocketNotificationContent::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"title",title);
field_to_json(Obj,"type",type);
field_to_json(Obj,"success",success);
field_to_json(Obj,"errors",errors);
field_to_json(Obj,"warnings",warnings);
field_to_json(Obj,"timeStamp",timeStamp);
field_to_json(Obj,"details",details);
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 WebSocketNotificationContent::from_json(const Poco::JSON::Object::Ptr &Obj) {
bool DeviceRules::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"title",title);
field_from_json(Obj,"type",type);
field_from_json(Obj,"success",success);
field_from_json(Obj,"errors",errors);
field_from_json(Obj,"warnings",warnings);
field_from_json(Obj,"timeStamp",timeStamp);
field_from_json(Obj,"details",details);
return true;
} catch(...) {
}
return false;
}
void WebSocketNotification::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"notification_id",notification_id);
field_to_json(Obj,"content",content);
}
bool WebSocketNotification::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"notification_id",notification_id);
field_from_json(Obj,"content",content);
field_from_json(Obj,"rcOnly",rcOnly);
field_from_json(Obj,"rrm",rrm);
field_from_json(Obj,"firmwareUpgrade",firmwareUpgrade);
return true;
} catch(...) {

View File

@@ -62,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;
@@ -72,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;
@@ -107,7 +116,7 @@ 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;
@@ -375,9 +384,7 @@ namespace OpenWifi::ProvObjects {
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;
@@ -401,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;
@@ -534,6 +541,7 @@ namespace OpenWifi::ProvObjects {
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);
@@ -581,9 +589,7 @@ namespace OpenWifi::ProvObjects {
ObjectInfo info;
Types::UUID_t managementPolicy;
Types::UUIDvec_t managementRoles;
std::string rrm;
std::string firmwareUpgrade;
bool firmwareRCOnly=true;
DeviceRules deviceRules;
std::vector<Variable> variables;
bool defaultOperator=false;
Types::StringVec sourceIP;
@@ -632,6 +638,16 @@ namespace OpenWifi::ProvObjects {
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;
@@ -644,7 +660,7 @@ namespace OpenWifi::ProvObjects {
Types::UUID_t serviceClass;
std::string qrCode;
std::string geoCode;
std::string rrm;
DeviceRules deviceRules;
std::string state;
std::string locale;
std::string billingCode;
@@ -663,28 +679,6 @@ namespace OpenWifi::ProvObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct WebSocketNotificationContent {
std::string title,
type,
details;
std::vector<std::string> success,
errors,
warnings;
uint64_t timeStamp=std::time(nullptr);
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct WebSocketNotification {
inline static uint64_t xid=1;
uint64_t notification_id=++xid;
WebSocketNotificationContent content;
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);
bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I);

View File

@@ -113,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) {
@@ -129,6 +131,7 @@ 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;
@@ -430,7 +433,7 @@ 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);
}
}
@@ -443,7 +446,7 @@ namespace OpenWifi::SecurityObjects {
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;
@@ -588,6 +591,7 @@ 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(const Poco::JSON::Object::Ptr &Obj) {
@@ -600,6 +604,7 @@ 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;

View File

@@ -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,7 +62,7 @@ namespace OpenWifi {
std::string UserTypeToString(USER_ROLE U);
struct NoteInfo {
uint64_t created=0; // = std::time(nullptr);
uint64_t created=0; // = OpenWifi::Now();
std::string createdBy;
std::string note;
@@ -93,7 +101,7 @@ namespace OpenWifi {
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(const Poco::JSON::Object::Ptr &Obj);
@@ -255,7 +263,7 @@ 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;
@@ -292,6 +300,7 @@ 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(const Poco::JSON::Object::Ptr &Obj);
@@ -302,7 +311,6 @@ namespace OpenWifi {
std::string type;
uint64_t created=0;
std::string name;
// Poco::Data::LOB<char> avatar;
Poco::Data::BLOB avatar;
};

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -11,6 +11,7 @@
namespace OpenWifi {
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")) {

View File

@@ -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 &);
@@ -129,9 +130,11 @@ namespace OpenWifi {
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 & ReturnVars, const std::chrono::duration<double, std::milli> & execution_time, bool FullCommand);
bool AttachFileToCommand(std::string & UUID);
// 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);

View File

@@ -16,7 +16,7 @@ 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)),
@@ -24,7 +24,6 @@ namespace OpenWifi {
Reactor_(Reactor),
Logger_(Logger),
WS_(std::move(WSock)) {
std::cout << "Telemetry client creation" << std::endl;
try {
std::thread T([this]() { this->CompleteStartup(); });
T.detach();
@@ -35,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);
@@ -60,7 +56,7 @@ namespace OpenWifi {
*WS_, Poco::NObserver<TelemetryClient, Poco::Net::ErrorNotification>(
*this, &TelemetryClient::OnSocketError));
Registered_ = true;
Logger().information(fmt::format("CONNECTION({}): completed.", CId_));
Logger().information(fmt::format("CONNECTION({}): Connection completed.", CId_));
return;
}
} catch (const Poco::Net::SSLException &E) {
@@ -73,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_,
@@ -85,13 +81,8 @@ 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) {
@@ -112,21 +103,19 @@ namespace OpenWifi {
}
void TelemetryClient::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf) {
std::lock_guard Guard(Mutex_);
Logger().information(fmt::format("SOCKET-SHUTDOWN({}): Orderly shutdown.", CId_));
SendTelemetryShutdown();
}
void TelemetryClient::OnSocketError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf) {
std::lock_guard Guard(Mutex_);
Logger().information(fmt::format("SOCKET-ERROR({}): Closing.",CId_));
SendTelemetryShutdown();
}
void TelemetryClient::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
std::lock_guard Guard(Mutex_);
try
{
std::lock_guard Guard(Mutex_);
ProcessIncomingFrame();
}
catch (const Poco::Exception & E)

View File

@@ -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();

View File

@@ -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 {
}
}
}
}

View File

@@ -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") {

View File

@@ -11,6 +11,8 @@
#include "Poco/Net/NetException.h"
#include "Poco/Net/SSLException.h"
#include "Poco/Base64Decoder.h"
#include "Poco/Base64Encoder.h"
#include "Poco/zlib.h"
#include "WS_Server.h"
@@ -18,13 +20,16 @@
#include "CommandManager.h"
#include "StateUtils.h"
#include "ConfigurationCache.h"
#include "SerialNumberCache.h"
#include "Daemon.h"
#include "TelemetryStream.h"
#include "CentralConfig.h"
#include "FindCountry.h"
#include "framework/WebSocketClientNotifications.h"
#include "RADIUS_proxy_server.h"
namespace OpenWifi {
void WSConnection::LogException(const Poco::Exception &E) {
Logger().information(fmt::format("EXCEPTION({}): {}", CId_, E.displayText()));
}
@@ -41,9 +46,9 @@ namespace OpenWifi {
PeerAddress_ = SS->peerAddress().host();
CId_ = Utils::FormatIPv6(SS->peerAddress().toString());
if (!SS->secure()) {
Logger().error(fmt::format("{}: Connection is NOT secure.", CId_));
poco_error(Logger(),fmt::format("{}: Connection is NOT secure.", CId_));
} else {
Logger().debug(fmt::format("{}: Connection is secure.", CId_));
poco_trace(Logger(),fmt::format("{}: Connection is secure.", CId_));
}
if (SS->havePeerCertificate()) {
@@ -55,15 +60,15 @@ namespace OpenWifi {
if (WebSocketServer()->ValidateCertificate(CId_, PeerCert)) {
CN_ = Poco::trim(Poco::toLower(PeerCert.commonName()));
CertValidation_ = GWObjects::MISMATCH_SERIAL;
Logger().debug(fmt::format("{}: Valid certificate: CN={}", CId_, CN_));
poco_trace(Logger(),fmt::format("{}: Valid certificate: CN={}", CId_, CN_));
} else {
Logger().debug(fmt::format("{}: Certificate is not valid", CId_));
poco_error(Logger(),fmt::format("{}: Certificate is not valid", CId_));
}
} catch (const Poco::Exception &E) {
LogException(E);
}
} else {
Logger().error(fmt::format("{}: No certificates available..", CId_));
poco_error(Logger(),fmt::format("{}: No certificates available..", CId_));
}
if (WebSocketServer::IsSim(CN_) && !WebSocketServer()->IsSimEnabled()) {
@@ -108,7 +113,7 @@ namespace OpenWifi {
Reactor_.addEventHandler(*WS_, Poco::NObserver<WSConnection, Poco::Net::ErrorNotification>(
*this, &WSConnection::OnSocketError));
Registered_ = true;
Logger().information(fmt::format("CONNECTION({}): completed.", CId_));
poco_debug(Logger(),fmt::format("CONNECTION({}): completed.", CId_));
return;
} catch (const Poco::Net::CertificateValidationException &E) {
Logger().error(fmt::format("CONNECTION({}): Poco::Exception Certificate Validation failed during connection. Device will have to retry.",
@@ -149,11 +154,10 @@ namespace OpenWifi {
WSConnection::WSConnection(Poco::Net::StreamSocket &socket, [[maybe_unused]] Poco::Net::SocketReactor &reactor)
: Logger_(WebSocketServer()->Logger()) ,
Socket_(socket),
Reactor_(WebSocketServer()->GetNextReactor())
Reactor_(ReactorThreadPool()->NextReactor())
{
std::thread T([=]() { CompleteStartup(); });
T.detach();
// CompleteStartup();
}
static void NotifyKafkaDisconnect(const std::string & SerialNumber) {
@@ -161,7 +165,7 @@ namespace OpenWifi {
Poco::JSON::Object Disconnect;
Poco::JSON::Object Details;
Details.set(uCentralProtocol::SERIALNUMBER, SerialNumber);
Details.set(uCentralProtocol::TIMESTAMP, std::time(nullptr));
Details.set(uCentralProtocol::TIMESTAMP, OpenWifi::Now());
Disconnect.set(uCentralProtocol::DISCONNECTION, Details);
Poco::JSON::Stringifier Stringify;
std::ostringstream OS;
@@ -173,6 +177,7 @@ namespace OpenWifi {
WSConnection::~WSConnection() {
poco_debug(Logger(),fmt::format("{}: Removing connection for {}.", CId_, SerialNumber_));
if (ConnectionId_)
DeviceRegistry()->UnRegister(SerialNumberInt_, ConnectionId_);
@@ -198,23 +203,28 @@ namespace OpenWifi {
std::thread t([s]() { NotifyKafkaDisconnect(s); });
t.detach();
}
WebSocketClientNotificationDeviceDisconnected(SerialNumber_);
}
bool WSConnection::LookForUpgrade(uint64_t UUID) {
bool WSConnection::LookForUpgrade(const uint64_t UUID, uint64_t & UpgradedUUID) {
// A UUID of zero means ignore updates for that connection.
if (UUID == 0)
return false;
uint64_t GoodConfig = ConfigurationCache().CurrentConfig(SerialNumberInt_);
if (GoodConfig && (GoodConfig == UUID || GoodConfig == Conn_->Conn_.PendingUUID))
if (GoodConfig && (GoodConfig == UUID || GoodConfig == Conn_->Conn_.PendingUUID)) {
UpgradedUUID = UUID;
return false;
}
GWObjects::Device D;
if (StorageService()->GetDevice(SerialNumber_, D)) {
// This is the case where the cache is empty after a restart. So GoodConfig will 0. If the device already has the right UUID, we just return.
if (D.UUID == UUID) {
UpgradedUUID = UUID;
ConfigurationCache().Add(SerialNumberInt_, UUID);
return false;
}
@@ -224,11 +234,13 @@ namespace OpenWifi {
// is newer.
Config::Config Cfg(D.Configuration);
D.UUID = UUID+2;
UpgradedUUID = D.UUID;
Cfg.SetUUID(D.UUID);
D.Configuration = Cfg.get();
StorageService()->UpdateDevice(D);
}
UpgradedUUID = D.UUID;
Conn_->Conn_.PendingUUID = D.UUID;
GWObjects::CommandDetails Cmd;
Cmd.SerialNumber = SerialNumber_;
@@ -254,44 +266,13 @@ namespace OpenWifi {
StorageService()->AddCommand(SerialNumber_, Cmd, Storage::COMMAND_EXECUTED);
CommandManager()->PostCommand(SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
WebSocketClientNotificationDeviceConfigurationChange(D.SerialNumber, UUID, UpgradedUUID);
return true;
}
return false;
}
bool WSConnection::ExtractBase64CompressedData(const std::string &CompressedData,
std::string &UnCompressedData, uint64_t compress_sz ) {
std::istringstream ifs(CompressedData);
Poco::Base64Decoder b64in(ifs);
std::ostringstream ofs;
Poco::StreamCopier::copyStream(b64in, ofs);
int factor = 20;
unsigned long MaxSize = compress_sz ? (unsigned long) (compress_sz + 5000) : (unsigned long) (ofs.str().size() * factor);
while(true) {
std::vector<uint8_t> UncompressedBuffer(MaxSize);
unsigned long FinalSize = MaxSize;
auto status = uncompress((uint8_t *)&UncompressedBuffer[0], &FinalSize,
(uint8_t *)ofs.str().c_str(), ofs.str().size());
if(status==Z_OK) {
UncompressedBuffer[FinalSize] = 0;
UnCompressedData = (char *)&UncompressedBuffer[0];
return true;
}
if(status==Z_BUF_ERROR) {
if(factor<300) {
factor+=10;
MaxSize = ofs.str().size() * factor;
continue;
} else {
return false;
}
}
return false;
}
return false;
}
void WSConnection::ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc) {
CommandManager()->PostCommandResult(SerialNumber_, *Doc);
}
@@ -323,7 +304,7 @@ namespace OpenWifi {
compress_sz = ParamsObj->get("compress_sz");
}
if (ExtractBase64CompressedData(CompressedData, UncompressedData, compress_sz)) {
if (Utils::ExtractBase64CompressedData(CompressedData, UncompressedData, compress_sz)) {
poco_trace(Logger(),fmt::format("EVENT({}): Found compressed payload expanded to '{}'.",
CId_, UncompressedData));
Poco::JSON::Parser Parser;
@@ -366,7 +347,7 @@ namespace OpenWifi {
}
if (Conn_ != nullptr)
Conn_->Conn_.LastContact = std::time(nullptr);
Conn_->Conn_.LastContact = OpenWifi::Now();
switch (EventType) {
case uCentralProtocol::Events::ET_CONNECT: {
@@ -383,14 +364,14 @@ namespace OpenWifi {
Conn_->Conn_.UUID = UUID;
Conn_->Conn_.Firmware = Firmware;
Conn_->Conn_.PendingUUID = 0;
Conn_->Conn_.LastContact = std::time(nullptr);
Conn_->Conn_.LastContact = OpenWifi::Now();
Conn_->Conn_.Address = Utils::FormatIPv6(WS_->peerAddress().toString());
CId_ = SerialNumber_ + "@" + CId_;
// We need to verify the certificate if we have one
if ((!CN_.empty() && Utils::SerialNumberMatch(CN_, SerialNumber_)) ||
WebSocketServer()->IsSimSerialNumber(CN_)) {
CertValidation_ = GWObjects::VERIFIED;
poco_information(Logger(), fmt::format("CONNECT({}): Fully validated and authenticated device..", CId_));
poco_information(Logger(), fmt::format("CONNECT({}): Fully validated and authenticated device.", CId_));
} else {
if (CN_.empty())
poco_information(Logger(), fmt::format("CONNECT({}): Not authenticated or validated.", CId_));
@@ -418,28 +399,35 @@ namespace OpenWifi {
if(!Firmware.empty() && Firmware!=DeviceInfo.Firmware) {
DeviceInfo.Firmware = Firmware;
Updated = true;
WebSocketClientNotificationDeviceFirmwareUpdated(SerialNumber_, Firmware);
}
if(DeviceInfo.locale != Conn_->Conn_.locale) {
DeviceInfo.locale = Conn_->Conn_.locale;
Updated = true;
}
if(Compatible_ != DeviceInfo.DeviceType) {
DeviceInfo.DeviceType = Compatible_;
Updated = true;
}
if(Updated) {
StorageService()->UpdateDevice(DeviceInfo);
}
LookForUpgrade(UUID);
uint64_t UpgradedUUID=0;
LookForUpgrade(UUID,UpgradedUUID);
Conn_->Conn_.UUID = UpgradedUUID;
}
Conn_->Conn_.Compatible = Compatible_;
WebSocketClientNotificationDeviceConnected(SerialNumber_);
if (KafkaManager()->Enabled()) {
Poco::JSON::Stringifier Stringify;
ParamsObj->set(uCentralProtocol::CONNECTIONIP, CId_);
ParamsObj->set("locale", Conn_->Conn_.locale );
ParamsObj->set(uCentralProtocol::TIMESTAMP, std::time(nullptr));
ParamsObj->set(uCentralProtocol::TIMESTAMP, OpenWifi::Now());
std::ostringstream OS;
Stringify.condense(ParamsObj, OS);
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_, OS.str());
@@ -475,13 +463,14 @@ namespace OpenWifi {
CId_, UUID, request_uuid));
}
Conn_->Conn_.UUID = UUID;
uint64_t UpgradedUUID;
LookForUpgrade(UUID,UpgradedUUID);
Conn_->Conn_.UUID = UpgradedUUID;
Conn_->LastStats = StateStr;
LookForUpgrade(UUID);
GWObjects::Statistics Stats{
.SerialNumber = SerialNumber_, .UUID = UUID, .Data = StateStr};
Stats.Recorded = std::time(nullptr);
Stats.Recorded = OpenWifi::Now();
StorageService()->AddStatisticsData(Stats);
if (!request_uuid.empty()) {
StorageService()->SetCommandResult(request_uuid, StateStr);
@@ -496,6 +485,12 @@ namespace OpenWifi {
Stringify.condense(ParamsObj, OS);
KafkaManager()->PostMessage(KafkaTopics::STATE, SerialNumber_, OS.str());
}
WebSocketNotification<WebNotificationSingleDevice> N;
N.content.serialNumber = SerialNumber_;
N.type = "device_statistics";
WebSocketClientServer()->SendNotification(N);
} else {
poco_warning(Logger(), fmt::format("STATE({}): Invalid request. Missing serial, uuid, or state", CId_));
}
@@ -529,13 +524,14 @@ namespace OpenWifi {
UUID, request_uuid));
}
Conn_->Conn_.UUID = UUID;
LookForUpgrade(UUID);
uint64_t UpgradedUUID;
LookForUpgrade(UUID,UpgradedUUID);
Conn_->Conn_.UUID = UpgradedUUID;
GWObjects::HealthCheck Check;
Check.SerialNumber = SerialNumber_;
Check.Recorded = std::time(nullptr);
Check.Recorded = OpenWifi::Now();
Check.UUID = UUID;
Check.Data = CheckData;
Check.Sanity = Sanity;
@@ -550,7 +546,7 @@ namespace OpenWifi {
if (KafkaManager()->Enabled()) {
Poco::JSON::Stringifier Stringify;
std::ostringstream OS;
ParamsObj->set("timestamp", std::time(nullptr));
ParamsObj->set("timestamp", OpenWifi::Now());
Stringify.condense(ParamsObj, OS);
KafkaManager()->PostMessage(KafkaTopics::HEALTHCHECK, SerialNumber_, OS.str());
}
@@ -722,27 +718,38 @@ namespace OpenWifi {
if (TelemetryReporting_) {
if (ParamsObj->has("data")) {
auto Payload = ParamsObj->get("data").extract<Poco::JSON::Object::Ptr>();
Payload->set("timestamp", std::time(nullptr));
Payload->set("timestamp", OpenWifi::Now());
std::ostringstream SS;
Payload->stringify(SS);
auto now=OpenWifi::Now();
if (TelemetryWebSocketRefCount_) {
std::cout << SerialNumber_ << ": Updating WebSocket telemetry" << std::endl;
TelemetryWebSocketPackets_++;
Conn_->Conn_.websocketPackets = TelemetryWebSocketPackets_;
TelemetryStream()->UpdateEndPoint(SerialNumberInt_, SS.str());
if(now<TelemetryWebSocketTimer_) {
// std::cout << SerialNumber_ << ": Updating WebSocket telemetry" << std::endl;
TelemetryWebSocketPackets_++;
Conn_->Conn_.websocketPackets = TelemetryWebSocketPackets_;
TelemetryStream()->UpdateEndPoint(SerialNumberInt_, SS.str());
} else {
StopWebSocketTelemetry();
}
}
if (TelemetryKafkaRefCount_ && KafkaManager()->Enabled()) {
std::cout << SerialNumber_ << ": Updating Kafka telemetry" << std::endl;
TelemetryKafkaPackets_++;
Conn_->Conn_.kafkaPackets = TelemetryKafkaPackets_;
KafkaManager()->PostMessage(KafkaTopics::DEVICE_TELEMETRY, SerialNumber_,
SS.str());
if (TelemetryKafkaRefCount_) {
if(KafkaManager()->Enabled() && now<TelemetryKafkaTimer_) {
// std::cout << SerialNumber_ << ": Updating Kafka telemetry" << std::endl;
TelemetryKafkaPackets_++;
Conn_->Conn_.kafkaPackets = TelemetryKafkaPackets_;
KafkaManager()->PostMessage(KafkaTopics::DEVICE_TELEMETRY, SerialNumber_,
SS.str());
} else {
StopKafkaTelemetry();
}
}
} else {
std::cout << SerialNumber_ << ": Invalid telemetry" << std::endl;
poco_debug(Logger(),fmt::format("TELEMETRY({}): Invalid telemetry packet.",SerialNumber_));
}
} else {
std::cout << SerialNumber_ << ":Ignoring telemetry" << std::endl;
// if we are ignoring telemetry, then close it down on the device.
poco_debug(Logger(),fmt::format("TELEMETRY({}): Stopping runaway telemetry.",SerialNumber_));
StopTelemetry();
}
} break;
@@ -756,7 +763,7 @@ namespace OpenWifi {
}
bool WSConnection::StartTelemetry() {
std::cout << "Start telemetry for " << SerialNumber_ << std::endl;
// std::cout << "Start telemetry for " << SerialNumber_ << std::endl;
poco_information(Logger(), fmt::format("TELEMETRY({}): Starting.", CId_));
Poco::JSON::Object StartMessage;
StartMessage.set("jsonrpc", "2.0");
@@ -779,7 +786,7 @@ namespace OpenWifi {
}
bool WSConnection::StopTelemetry() {
std::cout << "Stop telemetry for " << SerialNumber_ << std::endl;
// std::cout << "Stop telemetry for " << SerialNumber_ << std::endl;
poco_information(Logger(), fmt::format("TELEMETRY({}): Stopping.", CId_));
Poco::JSON::Object StopMessage;
StopMessage.set("jsonrpc", "2.0");
@@ -806,10 +813,11 @@ namespace OpenWifi {
}
bool WSConnection::SetWebSocketTelemetryReporting(uint64_t Interval,
uint64_t TelemetryWebSocketTimer) {
uint64_t LifeTime) {
std::lock_guard G(Mutex_);
TelemetryWebSocketRefCount_++;
TelemetryInterval_ = TelemetryInterval_ ? std::min(Interval, TelemetryInterval_) : Interval;
auto TelemetryWebSocketTimer = LifeTime + OpenWifi::Now();
TelemetryWebSocketTimer_ = std::max(TelemetryWebSocketTimer, TelemetryWebSocketTimer_);
UpdateCounts();
if (!TelemetryReporting_) {
@@ -819,10 +827,11 @@ namespace OpenWifi {
return true;
}
bool WSConnection::SetKafkaTelemetryReporting(uint64_t Interval, uint64_t TelemetryKafkaTimer) {
bool WSConnection::SetKafkaTelemetryReporting(uint64_t Interval, uint64_t LifeTime) {
std::lock_guard G(Mutex_);
TelemetryKafkaRefCount_++;
TelemetryInterval_ = TelemetryInterval_ ? std::min(Interval, TelemetryInterval_) : Interval;
auto TelemetryKafkaTimer = LifeTime + OpenWifi::Now();
TelemetryKafkaTimer_ = std::max(TelemetryKafkaTimer, TelemetryKafkaTimer_);
UpdateCounts();
if (!TelemetryReporting_) {
@@ -939,7 +948,7 @@ namespace OpenWifi {
PingDetails.set(uCentralProtocol::SERIALNUMBER, SerialNumber_);
PingDetails.set(uCentralProtocol::COMPATIBLE, Compatible_);
PingDetails.set(uCentralProtocol::CONNECTIONIP, CId_);
PingDetails.set(uCentralProtocol::TIMESTAMP, std::time(nullptr));
PingDetails.set(uCentralProtocol::TIMESTAMP, OpenWifi::Now());
PingDetails.set("locale", Conn_->Conn_.locale );
PingObject.set(uCentralProtocol::PING, PingDetails);
Poco::JSON::Stringifier Stringify;
@@ -976,10 +985,15 @@ namespace OpenWifi {
fmt::format("INVALID-PAYLOAD({}): Payload is not JSON-RPC 2.0: {}",
CId_, IncomingMessageStr));
}
} else if (IncomingJSON->has(uCentralProtocol::RADIUS)) {
ProcessIncomingRadiusData(IncomingJSON);
} else {
poco_warning(Logger(), fmt::format(
"FRAME({}): illegal transaction header, missing 'jsonrpc'", CId_));
Errors_++;
std::ostringstream iS;
IncomingJSON->stringify(iS);
std::cout << iS.str() << std::endl;
poco_warning(Logger(), fmt::format(
"FRAME({}): illegal transaction header, missing 'jsonrpc'", CId_));
Errors_++;
}
return;
} break;
@@ -1044,6 +1058,8 @@ namespace OpenWifi {
CId_, std::string{E.what()}, IncomingMessageStr));
return delete this;
} catch (...) {
poco_error(Logger(),fmt::format("Device {} must be disconnected. Unknown exception.", CId_));
std::cout << "Device " << CId_ << " must be disconnected due to exception..." << std::endl;
return delete this;
}
@@ -1063,4 +1079,64 @@ namespace OpenWifi {
return BytesSent == Payload.size();
}
std::string Base64Encode(const unsigned char *buffer, std::size_t size) {
return Utils::base64encode(buffer,size);
}
std::string Base64Decode(const std::string &F) {
std::istringstream ifs(F);
Poco::Base64Decoder b64in(ifs);
std::ostringstream ofs;
Poco::StreamCopier::copyStream(b64in, ofs);
return ofs.str();
}
bool WSConnection::SendRadiusAuthenticationData(const unsigned char * buffer, std::size_t size) {
Poco::JSON::Object Answer;
Answer.set(uCentralProtocol::RADIUS,uCentralProtocol::RADIUSAUTH);
Answer.set(uCentralProtocol::RADIUSDATA, Base64Encode(buffer,size));
std::ostringstream Payload;
Answer.stringify(Payload);
return Send(Payload.str());
}
bool WSConnection::SendRadiusAccountingData(const unsigned char * buffer, std::size_t size) {
Poco::JSON::Object Answer;
Answer.set(uCentralProtocol::RADIUS,uCentralProtocol::RADIUSACCT);
Answer.set(uCentralProtocol::RADIUSDATA, Base64Encode(buffer,size));
std::ostringstream Payload;
Answer.stringify(Payload);
return Send(Payload.str());
}
bool WSConnection::SendRadiusCoAData(const unsigned char * buffer, std::size_t size) {
Poco::JSON::Object Answer;
Answer.set(uCentralProtocol::RADIUS,uCentralProtocol::RADIUSCOA);
Answer.set(uCentralProtocol::RADIUSDATA, Base64Encode(buffer,size));
std::ostringstream Payload;
Answer.stringify(Payload);
return Send(Payload.str());
}
void WSConnection::ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc) {
if( Doc->has(uCentralProtocol::RADIUSDATA)) {
auto Type = Doc->get(uCentralProtocol::RADIUS).toString();
if(Type==uCentralProtocol::RADIUSACCT) {
auto Data = Doc->get(uCentralProtocol::RADIUSDATA).toString();
auto DecodedData = Base64Decode(Data);
RADIUS_proxy_server()->SendAccountingData(SerialNumber_,DecodedData.c_str(),DecodedData.size());
} else if(Type==uCentralProtocol::RADIUSAUTH) {
auto Data = Doc->get(uCentralProtocol::RADIUSDATA).toString();
auto DecodedData = Base64Decode(Data);
RADIUS_proxy_server()->SendAuthenticationData(SerialNumber_,DecodedData.c_str(),DecodedData.size());
} else if(Type==uCentralProtocol::RADIUSCOA) {
auto Data = Doc->get(uCentralProtocol::RADIUSDATA).toString();
auto DecodedData = Base64Decode(Data);
RADIUS_proxy_server()->SendCoAData(SerialNumber_,DecodedData.c_str(),DecodedData.size());
}
}
}
}

View File

@@ -26,11 +26,18 @@ namespace OpenWifi {
void ProcessJSONRPCEvent(Poco::JSON::Object::Ptr & Doc);
void ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc);
void ProcessIncomingFrame();
void ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc);
bool Send(const std::string &Payload);
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(uint64_t UUID);
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_; }
@@ -64,22 +71,22 @@ namespace OpenWifi {
uint64_t SerialNumberInt_=0;
std::string Compatible_;
std::shared_ptr<DeviceRegistry::ConnectionEntry> Conn_;
bool Registered_ = false ;
volatile bool Registered_ = false ;
std::string CId_;
std::string CN_;
GWObjects::CertificateValidation CertValidation_ = GWObjects::CertificateValidation::NO_CERTIFICATE;
uint64_t Errors_=0;
bool Connected_=false;
volatile 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;
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();

View File

@@ -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 (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:
uint64_t NumberOfThreads_;
uint64_t 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(); }
}

View File

@@ -28,7 +28,7 @@ namespace OpenWifi {
}
int WebSocketServer::Start() {
ReactorPool_.Start("DeviceReactorPool_");
// ReactorPool_.Start("DeviceReactorPool_");
for(const auto & Svr : ConfigServersList_ ) {
Logger().notice( fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}",
Svr.Address(),
@@ -45,7 +45,7 @@ namespace OpenWifi {
IssuerCert_ = std::make_unique<Poco::Crypto::X509Certificate>(Svr.IssuerCertFile());
Logger().information( fmt::format("Certificate Issuer Name:{}",IssuerCert_->issuerName()));
}
auto NewSocketAcceptor = std::make_unique<Poco::Net::ParallelSocketAcceptor<WSConnection, Poco::Net::SocketReactor>>(Sock, Reactor_, Poco::Environment::processorCount()*2);
auto NewSocketAcceptor = std::make_unique<ws_server_reactor_type_t>(Sock, Reactor_); // , 2 /*Poco::Environment::processorCount()*2) */ );
Acceptors_.push_back(std::move(NewSocketAcceptor));
}
@@ -65,14 +65,16 @@ namespace OpenWifi {
SimulatorId_ = MicroService::instance().ConfigGetString("simulatorid","");
SimulatorEnabled_ = !SimulatorId_.empty();
ReactorThread_.setStackSize(3000000);
ReactorThread_.start(Reactor_);
Utils::SetThreadName(ReactorThread_,"device-reactor");
return 0;
}
void WebSocketServer::Stop() {
Logger().notice("Stopping reactors...");
ReactorPool_.Stop();
// ReactorPool_.Stop();
Reactor_.stop();
ReactorThread_.join();
}

View File

@@ -18,6 +18,7 @@
#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"
@@ -35,7 +36,7 @@ namespace OpenWifi {
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(); }
// Poco::Net::SocketReactor & GetNextReactor() { return ReactorPool_.NextReactor(); }
inline bool IsSimSerialNumber(const std::string & SerialNumber) const {
return IsSim(SerialNumber) && SerialNumber == SimulatorId_;
@@ -54,10 +55,11 @@ namespace OpenWifi {
private:
std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_;
std::vector<std::unique_ptr<Poco::Net::ParallelSocketAcceptor<WSConnection, Poco::Net::SocketReactor>>> Acceptors_;
// 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_;
ReactorPool ReactorPool_;
std::string SimulatorId_;
bool LookAtProvisioning_ = false;
bool UseDefaultConfig_ = true;

View File

@@ -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",
@@ -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,8 +2608,7 @@ namespace OpenWifi {
}
}
}
)"_json;
)"_json;
class custom_error_handler : public nlohmann::json_schema::basic_error_handler
{
@@ -2460,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 {
@@ -2528,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}$"};
@@ -2578,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;

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,193 @@
//
// Created by stephane bourque on 2022-05-05.
//
#pragma once
#include "framework/MicroService.h"
namespace OpenWifi {
struct WebNotificationSingleDevice {
std::string serialNumber;
inline void to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber);
}
inline bool from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber);
return true;
} catch (...) {
}
return false;
}
};
struct WebNotificationSingleDeviceConfigurationChange {
std::string serialNumber;
uint64_t oldUUID;
uint64_t newUUID;
inline void to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber);
RESTAPI_utils::field_to_json(Obj,"oldUUID", oldUUID);
RESTAPI_utils::field_to_json(Obj,"newUUID", newUUID);
}
inline bool from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber);
RESTAPI_utils::field_from_json(Obj,"oldUUID", oldUUID);
RESTAPI_utils::field_from_json(Obj,"newUUID", newUUID);
return true;
} catch (...) {
}
return false;
}
};
struct WebNotificationSingleDeviceFirmwareChange {
std::string serialNumber;
std::string newFirmware;
inline void to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber);
RESTAPI_utils::field_to_json(Obj,"newFirmware", newFirmware);
}
inline bool from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber);
RESTAPI_utils::field_from_json(Obj,"newFirmware", newFirmware);
return true;
} catch (...) {
}
return false;
}
};
inline void WebSocketClientNotificationDeviceConfigurationChange(const std::string &SerialNumber, uint64_t oldUUID, uint64_t newUUID) {
WebSocketNotification<WebNotificationSingleDeviceConfigurationChange> N;
N.content.serialNumber = SerialNumber;
N.content.oldUUID = oldUUID;
N.content.newUUID = newUUID;
N.type = "device_configuration_upgrade";
WebSocketClientServer()->SendNotification(N);
}
inline void WebSocketClientNotificationDeviceFirmwareUpdated(const std::string &SerialNumber, const std::string &Firmware) {
WebSocketNotification<WebNotificationSingleDeviceFirmwareChange> N;
N.content.serialNumber = SerialNumber;
N.content.newFirmware = Firmware;
N.type = "device_firmware_upgrade";
WebSocketClientServer()->SendNotification(N);
}
inline void WebSocketClientNotificationDeviceConnected(const std::string &SerialNumber) {
WebSocketNotification<WebNotificationSingleDevice> N;
N.content.serialNumber = SerialNumber;
N.type = "device_connection";
WebSocketClientServer()->SendNotification(N);
}
inline void WebSocketClientNotificationDeviceDisconnected(const std::string & SerialNumber) {
WebSocketNotification<WebNotificationSingleDevice> N;
N.content.serialNumber = SerialNumber;
N.type = "device_disconnection";
WebSocketClientServer()->SendNotification(N);
}
struct WebSocketNotificationJobContent {
std::string title,
details,
jobId;
std::vector<std::string> success,
error,
warning;
uint64_t timeStamp=OpenWifi::Now();
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
inline void WebSocketNotificationJobContent::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"title",title);
RESTAPI_utils::field_to_json(Obj,"jobId",jobId);
RESTAPI_utils::field_to_json(Obj,"success",success);
RESTAPI_utils::field_to_json(Obj,"error",error);
RESTAPI_utils::field_to_json(Obj,"warning",warning);
RESTAPI_utils::field_to_json(Obj,"timeStamp",timeStamp);
RESTAPI_utils::field_to_json(Obj,"details",details);
}
inline bool WebSocketNotificationJobContent::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"title",title);
RESTAPI_utils::field_from_json(Obj,"jobId",jobId);
RESTAPI_utils::field_from_json(Obj,"success",success);
RESTAPI_utils::field_from_json(Obj,"error",error);
RESTAPI_utils::field_from_json(Obj,"warning",warning);
RESTAPI_utils::field_from_json(Obj,"timeStamp",timeStamp);
RESTAPI_utils::field_from_json(Obj,"details",details);
return true;
} catch(...) {
}
return false;
}
typedef WebSocketNotification<WebSocketNotificationJobContent> WebSocketClientNotificationVenueUpdateJob_t;
inline void WebSocketClientNotificationVenueUpdateJobCompletionToUser( const std::string & User, WebSocketClientNotificationVenueUpdateJob_t &N) {
N.type = "venue_configuration_update";
WebSocketClientServer()->SendUserNotification(User,N);
}
struct WebSocketNotificationRebootList {
std::string title,
details,
jobId;
std::vector<std::string> success,
warning;
uint64_t timeStamp=OpenWifi::Now();
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef WebSocketNotification<WebSocketNotificationRebootList> WebSocketClientNotificationVenueRebootList_t;
inline void WebSocketNotificationRebootList::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"title",title);
RESTAPI_utils::field_to_json(Obj,"jobId",jobId);
RESTAPI_utils::field_to_json(Obj,"success",success);
RESTAPI_utils::field_to_json(Obj,"warning",warning);
RESTAPI_utils::field_to_json(Obj,"timeStamp",timeStamp);
RESTAPI_utils::field_to_json(Obj,"details",details);
}
inline bool WebSocketNotificationRebootList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"title",title);
RESTAPI_utils::field_from_json(Obj,"jobId",jobId);
RESTAPI_utils::field_from_json(Obj,"success",success);
RESTAPI_utils::field_from_json(Obj,"warning",warning);
RESTAPI_utils::field_from_json(Obj,"timeStamp",timeStamp);
RESTAPI_utils::field_from_json(Obj,"details",details);
return true;
} catch(...) {
}
return false;
}
inline void WebSocketClientNotificationVenueRebootCompletionToUser( const std::string & User, WebSocketClientNotificationVenueRebootList_t &N) {
N.type = "venue_rebooter";
WebSocketClientServer()->SendUserNotification(User,N);
}
} // namespace OpenWifi

View File

@@ -133,6 +133,37 @@ namespace ORM {
return R;
}
inline std::string WHERE_AND_(std::string Result) {
return Result;
}
template <typename T, typename... Args> std::string WHERE_AND_(std::string Result, const char *fieldName, const T &Value, Args... args) {
if constexpr(std::is_same_v<T,std::string>)
{
if(!Value.empty()) {
if(!Result.empty())
Result += " and ";
Result += fieldName;
Result += '=';
Result += "'";
Result += Escape(Value);
Result += "'";
}
} else {
if(!Result.empty())
Result += " and ";
Result += fieldName ;
Result += '=';
Result += std::to_string(Value);
}
return WHERE_AND_(Result,args...);
}
template <typename... Args> std::string WHERE_AND(Args... args) {
std::string Result;
return WHERE_AND_(Result, args...);
}
enum SqlComparison { EQ = 0, NEQ, LT, LTE, GT, GTE };
enum SqlBinaryOp { AND = 0 , OR };
@@ -156,12 +187,8 @@ namespace ORM {
}
inline std::string to_string(const Poco::Data::BLOB &blob) {
auto Content = blob.content();
std::string result;
result.reserve(Content.size());
for(const auto &c:Content) {
result += (char) c;
}
result.assign(blob.begin(),blob.end());
return result;
}
@@ -212,7 +239,8 @@ namespace ORM {
int Place=0;
for(const auto &i:Fields) {
FieldNames_[i.Name] = Place;
std::string FieldName = Poco::toLower(i.Name);
FieldNames_[FieldName] = Place;
if(!first) {
CreateFields_ += ", ";
SelectFields_ += ", ";
@@ -222,9 +250,9 @@ namespace ORM {
SelectList_ += "(";
}
CreateFields_ += i.Name + " " + FieldTypeToChar(Type_, i.Type,i.Size) + (i.Index ? " unique primary key" : "");
SelectFields_ += i.Name ;
UpdateFields_ += i.Name + "=?";
CreateFields_ += FieldName + " " + FieldTypeToChar(Type_, i.Type,i.Size) + (i.Index ? " unique primary key" : "");
SelectFields_ += FieldName ;
UpdateFields_ += FieldName + "=?";
SelectList_ += "?";
first = false;
Place++;
@@ -239,12 +267,13 @@ namespace ORM {
IndexLine = std::string("CREATE INDEX IF NOT EXISTS ") + j.Name + std::string(" ON ") + TableName_+ " (";
bool first_entry=true;
for(const auto &k:j.Entries) {
assert(FieldNames_.find(k.FieldName) != FieldNames_.end());
auto IndexFieldName = Poco::toLower(k.FieldName);
assert(ValidFieldName(IndexFieldName));
if(!first_entry) {
IndexLine += " , ";
}
first_entry = false;
IndexLine += k.FieldName + std::string(" ") + std::string(k.Type == Indextype::ASC ? "ASC" : "DESC") ;
IndexLine += IndexFieldName + std::string(" ") + std::string(k.Type == Indextype::ASC ? "ASC" : "DESC") ;
}
IndexLine += " )";
IndexCreation_.template emplace_back(IndexLine);
@@ -259,12 +288,13 @@ namespace ORM {
IndexLine += " INDEX " + j.Name + " ( " ;
bool first_entry=true;
for(const auto &k:j.Entries) {
assert(FieldNames_.find(k.FieldName) != FieldNames_.end());
auto IndexFieldName = Poco::toLower(k.FieldName);
assert(FieldNames_.find(IndexFieldName) != FieldNames_.end());
if(!first_entry) {
IndexLine += " ,";
}
first_entry = false;
IndexLine += k.FieldName + std::string(k.Type == Indextype::ASC ? " ASC" : " DESC");
IndexLine += IndexFieldName + std::string(k.Type == Indextype::ASC ? " ASC" : " DESC");
}
IndexLine += " ) ";
}
@@ -279,27 +309,27 @@ namespace ORM {
[[nodiscard]] const std::string & UpdateFields() const { return UpdateFields_; };
inline std::string OP(field_name_t F, SqlComparison O , bool V) {
assert( FieldNames_.find(F) != FieldNames_.end() );
assert(ValidFieldName(F));
return std::string{"("} + F + SQLCOMPS[O] + (V ? "true" : "false") + ")" ;
}
inline std::string OP(field_name_t F, SqlComparison O , int V) {
assert( FieldNames_.find(F) != FieldNames_.end() );
assert(ValidFieldName(F));
return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ;
}
inline std::string OP(field_name_t F, SqlComparison O , uint64_t V) {
assert( FieldNames_.find(F) != FieldNames_.end() );
assert(ValidFieldName(F));
return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ;
}
std::string OP(field_name_t F, SqlComparison O , const std::string & V) {
assert( FieldNames_.find(F) != FieldNames_.end() );
assert(ValidFieldName(F));
return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ;
}
std::string OP(field_name_t F, SqlComparison O , const char * V) {
assert( FieldNames_.find(F) != FieldNames_.end() );
assert(ValidFieldName(F));
return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ;
}
@@ -421,7 +451,7 @@ namespace ORM {
template<typename T> bool GetRecord(field_name_t FieldName, const T & Value, RecordType & R) {
try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
assert(ValidFieldName(FieldName));
if(Cache_) {
if(Cache_->GetFromCache(FieldName, Value, R))
@@ -459,7 +489,7 @@ namespace ORM {
typename T0, typename T1> bool GR(field_name_t FieldName, T & R,T0 &V0, T1 &V1) {
try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
assert( ValidFieldName(FieldName) );
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session);
@@ -517,7 +547,7 @@ namespace ORM {
template <typename T> bool UpdateRecord(field_name_t FieldName, const T & Value, const RecordType & R) {
try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
assert( ValidFieldName(FieldName) );
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Update(Session);
@@ -571,7 +601,7 @@ namespace ORM {
template <typename T> bool GetNameAndDescription(field_name_t FieldName, const T & Value, std::string & Name, std::string & Description ) {
try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
assert( ValidFieldName(FieldName) );
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session);
RecordTuple RT;
@@ -598,7 +628,7 @@ namespace ORM {
template <typename T> bool DeleteRecord(field_name_t FieldName, const T & Value) {
try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
assert( ValidFieldName(FieldName) );
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Delete(Session);
@@ -636,7 +666,7 @@ namespace ORM {
bool Exists(field_name_t FieldName, const std::string & Value) {
try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
assert( ValidFieldName(FieldName) );
RecordType R;
if(GetRecord(FieldName,Value,R))
@@ -689,7 +719,7 @@ namespace ORM {
}
if(!ItemList.empty())
ItemList += " , ";
auto hint = FieldNames_.find(T[0]);
auto hint = FieldNames_.find(Poco::toLower(T[0]));
if(hint==FieldNames_.end()) {
return false;
}
@@ -725,7 +755,7 @@ namespace ORM {
template <typename X> bool ManipulateVectorMember( X T, field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID, bool Add) {
try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
assert( ValidFieldName(FieldName) );
RecordType R;
if(GetRecord(FieldName, ParentUUID, R)) {
@@ -874,6 +904,15 @@ namespace ORM {
return false;
}
inline bool ValidFieldName(const std::string &FieldName) {
return FieldNames_.find(Poco::toLower(FieldName)) != FieldNames_.end();
}
inline bool ValidFieldName(const char *FieldName) {
std::string Field{FieldName};
return ValidFieldName(Field);
}
[[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
if(From<1) From=0;
switch(Type_) {
@@ -890,12 +929,17 @@ namespace ORM {
Poco::Logger & Logger() { return Logger_; }
bool DeleteRecordsFromCache(const char *FieldName, const std::string &Value ) {
inline bool DeleteRecordsFromCache(const char *FieldName, const std::string &Value ) {
if(Cache_)
Cache_->Delete(FieldName, Value);
return true;
}
inline void GetFieldNames( OpenWifi::Types::StringVec & F) {
for(const auto &[field,_]:FieldNames_)
F.push_back(field);
}
protected:
std::string TableName_;
OpenWifi::DBType Type_;

View File

@@ -5,6 +5,7 @@
#pragma once
#include <string>
#include <cstring>
#include "Poco/String.h"
#if defined(__GNUC__)
@@ -18,92 +19,187 @@
#endif
namespace OpenWifi::RESTAPI::Errors {
static const std::string MissingUUID{"Missing UUID."};
static const std::string MissingSerialNumber{"Missing Serial Number."};
static const std::string InternalError{"Internal error. Please try later."};
static const std::string InvalidJSONDocument{"Invalid JSON document."};
static const std::string UnsupportedHTTPMethod{"Unsupported HTTP Method"};
static const std::string StillInUse{"Element still in use."};
static const std::string CouldNotBeDeleted{"Element could not be deleted."};
static const std::string NameMustBeSet{"The name property must be set."};
static const std::string ConfigBlockInvalid{"Configuration block type invalid."};
static const std::string UnknownId{"Unknown UUID."};
static const std::string InvalidDeviceTypes{"Unknown or invalid device type(s)."};
static const std::string RecordNotCreated{"Record could not be created."};
static const std::string RecordNotUpdated{"Record could not be updated."};
static const std::string UnknownManagementPolicyUUID{"Unknown management policy UUID."};
static const std::string CannotDeleteRoot{"Root Entity cannot be removed, only modified."};
static const std::string MustCreateRootFirst{"Root entity must be created first."};
static const std::string ParentUUIDMustExist{"Parent UUID must exist."};
static const std::string ConfigurationMustExist{"Configuration must exist."};
static const std::string MissingOrInvalidParameters{"Invalid or missing parameters."};
static const std::string UnknownSerialNumber{"Unknown Serial Number."};
static const std::string InvalidSerialNumber{"Invalid Serial Number."};
static const std::string SerialNumberExists{"Serial Number already exists."};
static const std::string ValidNonRootUUID{"Must be a non-root, and valid UUID."};
static const std::string VenueMustExist{"Venue does not exist."};
static const std::string NotBoth{"You cannot specify both Entity and Venue"};
static const std::string EntityMustExist{"Entity must exist."};
static const std::string ParentOrEntityMustBeSet{"Parent or Entity must be set."};
static const std::string ContactMustExist{"Contact must exist."};
static const std::string LocationMustExist{"Location must exist."};
static const std::string OnlyWSSupported{"This endpoint only supports WebSocket."};
static const std::string SerialNumberMismatch{"Serial Number mismatch."};
static const std::string InvalidCommand{"Invalid command."};
static const std::string NoRecordsDeleted{"No records deleted."};
static const std::string DeviceNotConnected{"Device is not currently connected."};
static const std::string CannotCreateWS{"Telemetry system could not create WS endpoint. Please try again."};
static const std::string BothDeviceTypeRevision{"Both deviceType and revision must be set."};
static const std::string IdOrSerialEmpty{"SerialNumber and Id must not be empty."};
static const std::string MissingUserID{"Missing user ID."};
static const std::string IdMustBe0{"To create a user, you must set the ID to 0"};
static const std::string InvalidUserRole{"Invalid userRole."};
static const std::string InvalidEmailAddress{"Invalid email address."};
static const std::string PasswordRejected{"Password was rejected. This maybe an old password."};
static const std::string InvalidIPRanges{"Invalid IP range specifications."};
static const std::string InvalidLOrderBy{"Invalid orderBy specification."};
static const std::string NeedMobileNumber{"You must provide at least one validated phone number."};
static const std::string BadMFAMethod{"MFA only supports sms or email."};
static const std::string InvalidCredentials{"Invalid credentials (username/password)."};
static const std::string InvalidPassword{"Password does not conform to basic password rules."};
static const std::string UserPendingVerification{"User access denied pending email verification."};
static const std::string PasswordMustBeChanged{"Password must be changed."};
static const std::string UnrecognizedRequest{"Ill-formed request. Please consult documentation."};
static const std::string MissingAuthenticationInformation{"Missing authentication information."};
static const std::string InsufficientAccessRights{"Insufficient access rights to complete the operation."};
static const std::string ExpiredToken{"Token has expired, user must login."};
static const std::string SubscriberMustExist{"Subscriber must exist."};
static const std::string AuthenticatorVerificationIncomplete{"Authenticator validation is not complete."};
static const std::string SMSCouldNotBeSentRetry{"SMS could not be sent to validate device, try later or change the phone number."};
static const std::string SMSCouldNotValidate{"Code and number could not be validated"};
static const std::string InvalidDeviceClass{"Invalid device class. Must be: any, venue, entity, or subscriber"};
static const std::string SerialNumberAlreadyProvisioned{"This device has already been provisioned to a subscriber."};
static const std::string SerialNumberNotTheProperClass{"Device is not available to subscribers. It ahs been assigned to another class of devices."};
static const std::string UserAlreadyExists{"Username already exists."};
static const std::string NotImplemented{"Function not implemented."};
static const std::string VariableMustExist{"Specified variable does not exist."};
static const std::string InvalidEntityType{"Invalid entity type."};
static const std::string CannotDeleteSubEntity{"Cannot delete the default subscriber entity."};
static const std::string OperatorIdMustExist{"Missing or bad Operator ID"};
static const std::string CannotDeleteDefaultOperator{"Cannot delete the default operator."};
static const std::string CannotCreateDefaultOperator{"Cannot create the default operator."};
static const std::string InvalidRRM{"Invalid RRM value."};
static const std::string InvalidIPAddresses{"Invalid IP addresses."};
static const std::string InvalidBillingCode{"Empty of invalid billing code."};
static const std::string InvalidBillingPeriod{"Invalid billing period."};
static const std::string InvalidSubscriberId{"Invalid subscriber ID."};
static const std::string InvalidContactId{"Invalid contact ID."};
static const std::string InvalidLocationId{"Invalid location ID."};
static const std::string InvalidContactType{"Invalid contact type."};
static const std::string InvalidLocationType{"Invalid location type."};
static const std::string InvalidOperatorId{"Invalid operator ID."};
static const std::string InvalidServiceClassId{"Invalid service class ID."};
static const std::string InvalidSubscriberDeviceId{"Invalid subscriber device ID."};
static const std::string InvalidRegistrationOperatorId{"Invalid registration operator ID."};
static const std::string InvalidRegistrationOperatorName{"Invalid registration operator name."};
static const std::string RegistrationNameDuplicate{"Registration name must be unique."};
struct msg { uint64_t err_num; std::string err_txt; };
static const struct msg Error404{404,"Resource does not exist."};
static const struct msg SUCCESS{0,"No error."};
static const struct msg PASSWORD_CHANGE_REQUIRED{1,"Password change required"};
static const struct msg INVALID_CREDENTIALS{2,"Invalid credentials."};
static const struct msg PASSWORD_ALREADY_USED{3,"Password already used."};
static const struct msg USERNAME_PENDING_VERIFICATION{4,"Username pending verification."};
static const struct msg PASSWORD_INVALID{5,"Password is invalid"};
static const struct msg INTERNAL_ERROR{6,"Internal error."};
static const struct msg ACCESS_DENIED{7,"Access denied."};
static const struct msg INVALID_TOKEN{8,"Invalid token."};
static const struct msg EXPIRED_TOKEN{9,"Expired token."};
static const struct msg RATE_LIMIT_EXCEEDED{10,"Rate limit exceeded."};
static const struct msg BAD_MFA_TRANSACTION{11,"Bad MFA transaction."};
static const struct msg MFA_FAILURE{12,"MFA failure."};
static const struct msg SECURITY_SERVICE_UNREACHABLE{13,"Security service is unreachable, try again later."};
static const struct msg CANNOT_REFRESH_TOKEN{14,"Cannot refresh token."};
static const struct msg MissingUUID{1000,"Missing UUID."};
static const struct msg MissingSerialNumber{1001,"Missing Serial Number."};
static const struct msg InternalError{1002,"Internal error. Please try later."};
static const struct msg InvalidJSONDocument{1003,"Invalid JSON document."};
static const struct msg UnsupportedHTTPMethod{1004,"Unsupported HTTP Method"};
static const struct msg StillInUse{1005,"Element still in use."};
static const struct msg CouldNotBeDeleted{1006,"Element could not be deleted."};
static const struct msg NameMustBeSet{1007,"The name property must be set."};
static const struct msg ConfigBlockInvalid{1008,"Configuration block type invalid."};
static const struct msg UnknownId{1009,"Unknown UUID."};
static const struct msg InvalidDeviceTypes{1010,"Unknown or invalid device type(s)."};
static const struct msg RecordNotCreated{1011,"Record could not be created."};
static const struct msg RecordNotUpdated{1012,"Record could not be updated."};
static const struct msg UnknownManagementPolicyUUID{1013,"Unknown management policy UUID."};
static const struct msg CannotDeleteRoot{1014,"Root Entity cannot be removed, only modified."};
static const struct msg MustCreateRootFirst{1015,"Root entity must be created first."};
static const struct msg ParentUUIDMustExist{1016,"Parent UUID must exist."};
static const struct msg ConfigurationMustExist{1017,"Configuration must exist."};
static const struct msg MissingOrInvalidParameters{1018,"Invalid or missing parameters."};
static const struct msg UnknownSerialNumber{1019,"Unknown Serial Number."};
static const struct msg InvalidSerialNumber{1020,"Invalid Serial Number."};
static const struct msg SerialNumberExists{1021,"Serial Number already exists."};
static const struct msg ValidNonRootUUID{1022,"Must be a non-root, and valid UUID."};
static const struct msg VenueMustExist{1023,"Venue does not exist."};
static const struct msg NotBoth{1024,"You cannot specify both Entity and Venue"};
static const struct msg EntityMustExist{1025,"Entity must exist."};
static const struct msg ParentOrEntityMustBeSet{1026,"Parent or Entity must be set."};
static const struct msg ContactMustExist{1027,"Contact must exist."};
static const struct msg LocationMustExist{1028,"Location must exist."};
static const struct msg OnlyWSSupported{1029,"This endpoint only supports WebSocket."};
static const struct msg SerialNumberMismatch{1030,"Serial Number mismatch."};
static const struct msg InvalidCommand{1031,"Invalid command."};
static const struct msg NoRecordsDeleted{1032,"No records deleted."};
static const struct msg DeviceNotConnected{1033,"Device is not currently connected."};
static const struct msg CannotCreateWS{1034,"Telemetry system could not create WS endpoint. Please try again."};
static const struct msg BothDeviceTypeRevision{1035,"Both deviceType and revision must be set."};
static const struct msg IdOrSerialEmpty{1036,"SerialNumber and Id must not be empty."};
static const struct msg MissingUserID{1037,"Missing user ID."};
static const struct msg IdMustBe0{1038,"To create a user, you must set the ID to 0"};
static const struct msg InvalidUserRole{1039,"Invalid userRole."};
static const struct msg InvalidEmailAddress{1040,"Invalid email address."};
static const struct msg PasswordRejected{1041,"Password was rejected. This maybe an old password."};
static const struct msg InvalidIPRanges{1042,"Invalid IP range specifications."};
static const struct msg InvalidLOrderBy{1043,"Invalid orderBy specification."};
static const struct msg NeedMobileNumber{1044,"You must provide at least one validated phone number."};
static const struct msg BadMFAMethod{1045,"MFA only supports sms or email."};
static const struct msg InvalidCredentials{1046,"Invalid credentials (username/password)."};
static const struct msg InvalidPassword{1047,"Password does not conform to basic password rules."};
static const struct msg UserPendingVerification{1048,"User access denied pending email verification."};
static const struct msg PasswordMustBeChanged{1049,"Password must be changed."};
static const struct msg UnrecognizedRequest{1050,"Ill-formed request. Please consult documentation."};
static const struct msg MissingAuthenticationInformation{1051,"Missing authentication information."};
static const struct msg InsufficientAccessRights{1052,"Insufficient access rights to complete the operation."};
static const struct msg ExpiredToken{1053,"Token has expired, user must login."};
static const struct msg SubscriberMustExist{1054,"Subscriber must exist."};
static const struct msg AuthenticatorVerificationIncomplete{1055,"Authenticator validation is not complete."};
static const struct msg SMSCouldNotBeSentRetry{1056,"SMS could not be sent to validate device, try later or change the phone number."};
static const struct msg SMSCouldNotValidate{1057,"Code and number could not be validated"};
static const struct msg InvalidDeviceClass{1058,"Invalid device class. Must be: any, venue, entity, or subscriber"};
static const struct msg SerialNumberAlreadyProvisioned{1059,"This device has already been provisioned to a subscriber."};
static const struct msg SerialNumberNotTheProperClass{1060,"Device is not available to subscribers. It ahs been assigned to another class of devices."};
static const struct msg UserAlreadyExists{1061,"Username already exists."};
static const struct msg NotImplemented{1062,"Function not implemented."};
static const struct msg VariableMustExist{1063,"Specified variable does not exist."};
static const struct msg InvalidEntityType{1064,"Invalid entity type."};
static const struct msg CannotDeleteSubEntity{1065,"Cannot delete the default subscriber entity."};
static const struct msg OperatorIdMustExist{1066,"Missing or bad Operator ID"};
static const struct msg CannotDeleteDefaultOperator{1067,"Cannot delete the default operator."};
static const struct msg CannotCreateDefaultOperator{1068,"Cannot create the default operator."};
static const struct msg InvalidRRM{1069,"Invalid RRM value."};
static const struct msg InvalidIPAddresses{1070,"Invalid IP addresses."};
static const struct msg InvalidBillingCode{1071,"Empty of invalid billing code."};
static const struct msg InvalidBillingPeriod{1072,"Invalid billing period."};
static const struct msg InvalidSubscriberId{1073,"Invalid subscriber ID."};
static const struct msg InvalidContactId{1074,"Invalid contact ID."};
static const struct msg InvalidLocationId{1075,"Invalid location ID."};
static const struct msg InvalidContactType{1076,"Invalid contact type."};
static const struct msg InvalidLocationType{1077,"Invalid location type."};
static const struct msg InvalidOperatorId{1078,"Invalid operator ID."};
static const struct msg InvalidServiceClassId{1079,"Invalid service class ID."};
static const struct msg InvalidSubscriberDeviceId{1080,"Invalid subscriber device ID."};
static const struct msg InvalidRegistrationOperatorId{1081,"Invalid registration operator ID."};
static const struct msg InvalidRegistrationOperatorName{1082,"Invalid registration operator name."};
static const struct msg RegistrationNameDuplicate{1083,"Registration name must be unique."};
static const struct msg SMSMFANotEnabled{1084,"SMS is not enabled in the security service."};
static const struct msg EMailMFANotEnabled{1085,"email is not enabled in the security service."};
static const struct msg TOTInvalidCode{1086,"Invalid code."};
static const struct msg TOTInvalidIndex{1087,"Invalid index."};
static const struct msg TOTRepeatedCode{1088,"Code is repeated. Must be new code."};
static const struct msg TOTInvalidProtocol{1089,"Invalid protocol sequence."};
static const struct msg TOTNoSession{1090,"No validation session present."};
static const struct msg SignupAlreadySigned{1091,"Code is repeated. Must be new code."};
static const struct msg SignupEmailCheck{1092,"Waiting for email check completion."};
static const struct msg SignupWaitingForDevice{1093,"Waiting for device."};
static const struct msg SMSMissingPhoneNumber{1094,"Missing phone number"};
static const struct msg SMSTryLater{1095,"SMS could not be sent. Verify the number or try again later."};
static const struct msg SMSMissingChallenge{1096,"Missing 'challengeCode'"};
static const struct msg MustHaveConfigElement{1097,"Must have 'configuration' element."};
static const struct msg ModelIDListCannotBeEmpty{1098,"Model ID list cannot be empty."};
static const struct msg DefConfigNameExists{1099,"Configuration name already exists."};
static const struct msg SubNoDeviceActivated{1100,"No devices activated yet."};
static const struct msg SubConfigNotRefreshed{1101,"Configuration could not be refreshed."};
static const struct msg ProvServiceNotAvailable{1102,"Provisioning service not available yet."};
static const struct msg SSIDInvalidPassword{1103,"Invalid password length. Must be 8 characters or greater, and a maximum of 32 characters."};
static const struct msg InvalidStartingIPAddress{1104,"Invalid starting/ending IP address."};
static const struct msg SubnetFormatError{1105,"Subnet must be in format like 192.168.1.1/24."};
static const struct msg DeviceModeError{1106,"Device mode subnet must be of the form 192.168.1.1/24."};
static const struct msg BadDeviceMode{1107,"Mode must be bridge, nat, or manual."};
static const struct msg DefaultGatewayFormat{1108,"Default gateway must be in format like 192.168.1.1."};
static const struct msg PrimaryDNSFormat{1109,"Primary DNS must be an IP address i.e. 192.168.1.1."};
static const struct msg SecondaryDNSFormat{1110,"Secondary DNS must be an IP address i.e. 192.168.1.1."};
static const struct msg BadConnectionType{1111,"Internet Connection must be automatic, bridge, pppoe, or manual."};
static const struct msg InvalidDeviceID{1112,"Invalid deviceID."};
static const struct msg InvalidVisibilityAttribute{1113,"Invalid visibility attribute."};
static const struct msg UnknownConfigurationSection{1114,"Unknown section."};
static const struct msg CannotValidatePhoneNumber{1115,"Phone number could not be validated."};
static const struct msg RootUsersNoOwners{1116,"ROOT users may not have owners."};
static const struct msg PartnerMustHaveEntity{1118,"Partner user must belong to an entity."};
static const struct msg RootCannotModifyUsers{1119,"ROOT may not modify user roles."};
static const struct msg CertificateNotIssued{1120,"Certificate was not issued."};
static const struct msg IncompleteCertificate{1121,"Incomplete certificate information. Cannot be downloaded. You must delete and recreate."};
static const struct msg InvalidCertificateType{1122,"Invalid certificate type."};
static const struct msg InvalidDeviceName{1123,"Invalid device name."};
static const struct msg InvalidRedirectorName{1124,"Invalid redirector name"};
static const struct msg CommonNameAlreadyExists{1125,"A device/server of this name already exists"};
static const struct msg CertificateAlreadyExists{1126,"A certificate for this device already exists."};
static const struct msg CannotCreateCertTryAgain{1127,"Device certificate could not be created. Please try later."};
static const struct msg CouldNotRevoke{1128,"Certificate could not be revoked."};
static const struct msg CouldNotModifyCert{1129,"Certificate could not me modified. Please verify the information you supplied."};
static const struct msg BatchCertNoCreated{1130,"Certificates have not been created for this batch."};
static const struct msg BatchTooBig{1131,"Illegal number of MAC Addresses: must be between 1 and 1000."};
static const struct msg OutstandingJobs{1132,"Batch has running outstanding jobs. Please wait until job is finished."};
static const struct msg InvalidSMSNotificationList{1133,"Invalid SMS Notification list."};
static const struct msg InvalidEMailNotificationList{1134,"Invalid email Notification list."};
static const struct msg CannotChangeCommanNames{1135,"You cannot provide new/modified common names after jobs have been run for a batch."};
static const struct msg FailedToVerifyDigicert{1136,"Failed to verify the DigiCert information provided."};
static const struct msg CouldNotPerformCommand{1137,"Could not perform command."};
static const struct msg PoolNameInvalid{1138,"Pool name is invalid."};
static const struct msg InvalidRadiusProxyStrategy{1139,"Strategy name must be: random, round_robin, weighted."};
static const struct msg InvalidRadiusProxyMonitorMethod{1140,"monitorMethod must be: none, https, radius."};
static const struct msg MustHaveAtLeastOneRadiusServer{1141,"Must have at least one RADIUS server."};
static const struct msg InvalidRadiusServerEntry{1142,"RADIUS Server IP address invalid or port missing."};
static const struct msg InvalidRadiusServerWeigth{1143,"RADIUS Server IP weight cannot be 0."};
}
namespace OpenWifi::RESTAPI::Protocol {
static const char * CAPABILITIES = "capabilities";
static const char * LOGS = "logs";
@@ -207,6 +303,9 @@ namespace OpenWifi::RESTAPI::Protocol {
static const char * TIMES = "times";
static const char * UPTIME = "uptime";
static const char * START = "start";
static const char * DEBUG = "debug";
static const char * SCRIPT = "script";
static const char * TIMEOUT = "timeout";
static const char * NEWPASSWORD = "newPassword";
static const char * USERS = "users";
@@ -272,6 +371,8 @@ namespace OpenWifi::uCentralProtocol {
static const char *CONFIG = "config";
static const char *EMPTY_JSON_DOC = "{}";
static const char *RESULT = "result";
static const char *RESULT_64 = "result_64";
static const char *RESULT_SZ = "result_sz";
static const char *REQUEST = "request";
static const char *PERFORM = "perform";
static const char *CONFIGURE = "configure";
@@ -284,6 +385,7 @@ namespace OpenWifi::uCentralProtocol {
static const char *DURATION = "duration";
static const char *PATTERN = "pattern";
static const char *LEDS = "leds";
static const char *DEBUG = "debug";
static const char *ON = "on";
static const char *OFF = "off";
static const char *BLINK = "blink";
@@ -318,7 +420,18 @@ namespace OpenWifi::uCentralProtocol {
static const char *CONNECTIONIP = "connectionIp";
static const char *TELEMETRY = "telemetry";
static const char *BANDWIDTH = "bandwidth";
}
static const char *SCRIPT = "script";
static const char *TYPE = "type";
static const char *RADIUS = "radius";
static const char *RADIUSDATA = "data";
static const char *RADIUSACCT = "acct";
static const char *RADIUSAUTH = "auth";
static const char *RADIUSCOA = "coa";
static const char *RADIUSDST = "dst";
static const char *IES = "ies";
}
namespace OpenWifi::uCentralProtocol::Events {
@@ -347,25 +460,28 @@ namespace OpenWifi::uCentralProtocol::Events {
ET_TELEMETRY
};
inline static EVENT_MSG EventFromString(const std::string & Method) {
static std::vector<std::pair<const char *,EVENT_MSG>> Values{
{ CFGPENDING , ET_CFGPENDING },
{ CONNECT, ET_CONNECT },
{ CRASHLOG, ET_CRASHLOG },
{ DEVICEUPDATE, ET_DEVICEUPDATE },
{ HEALTHCHECK, ET_HEALTHCHECK },
{ LOG, ET_LOG },
{ PING, ET_PING },
{ RECOVERY, ET_RECOVERY },
{ STATE, ET_STATE },
{ TELEMETRY, ET_TELEMETRY }
};
std::string L = Poco::toLower(Method);
auto hint = std::find_if(cbegin(Values),cend(Values),[&](const std::pair<const char *,EVENT_MSG> &v) ->bool { return strcmp(v.first,L.c_str())==0; });
if(hint == cend(Values))
return ET_UNKNOWN;
return hint->second;
inline EVENT_MSG EventFromString(const std::string & Method) {
if(strcmp(STATE,Method.c_str())==0)
return ET_STATE;
else if(strcmp(HEALTHCHECK,Method.c_str())==0)
return ET_HEALTHCHECK;
else if(strcmp(CONNECT,Method.c_str())==0)
return ET_CONNECT;
else if(strcmp(CFGPENDING,Method.c_str())==0)
return ET_CFGPENDING;
else if(strcmp(CRASHLOG,Method.c_str())==0)
return ET_CRASHLOG;
else if(strcmp(DEVICEUPDATE,Method.c_str())==0)
return ET_DEVICEUPDATE;
else if(strcmp(LOG,Method.c_str())==0)
return ET_LOG;
else if(strcmp(PING,Method.c_str())==0)
return ET_PING;
else if(strcmp(RECOVERY,Method.c_str())==0)
return ET_RECOVERY;
else if(strcmp(TELEMETRY,Method.c_str())==0)
return ET_TELEMETRY;
return ET_UNKNOWN;
};
}

View File

@@ -8,85 +8,75 @@
namespace OpenWifi {
RTTYS_ClientConnection::RTTYS_ClientConnection(std::unique_ptr<Poco::Net::WebSocket> WS, std::string &Id,
Poco::Net::SocketReactor &Reactor)
: WS_(std::move(WS)),
Id_(std::move(Id)),
SR_(Reactor),
Logger_(RTTYS_server()->Logger()) {
RTTYS_server()->Register(Id_, this);
if(RTTYS_server()->CanConnect(Id_,this)) {
Logger().information(fmt::format("{}: Starting WS connection, session: {}.", Id_, RTTYS_server()->DeviceSessionID(Id_)));
SR_.addEventHandler(*WS_,
Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ReadableNotification>(
*this, &RTTYS_ClientConnection::onSocketReadable));
SR_.addEventHandler(*WS_,
Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ShutdownNotification>(
*this, &RTTYS_ClientConnection::onSocketShutdown));
auto DoLogin = [this]() -> void {
int tries = 0 ;
while(tries < 10) {
if(RTTYS_server()->Login(this->Id_)) {
Logger().information(fmt::format("{}: WS client connected to device, session: {}.", Id_, RTTYS_server()->DeviceSessionID(Id_)));
this->Connected_=true;
return;
}
std::this_thread::sleep_for(2000ms);
tries++;
}
Logger().information(fmt::format("{}: WS client could not connect to device, session: {}.", Id_, RTTYS_server()->DeviceSessionID(Id_)));
delete this;
};
std::thread CompleteConnection(DoLogin);
CompleteConnection.detach();
} else {
Logger().information(fmt::format("{}: WS client cannot be connected.", Id_));
RTTYS_server()->DeRegister(Id_, this);
delete this;
RTTYS_ClientConnection::RTTYS_ClientConnection(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response,
Poco::Net::SocketReactor &reactor,
const std::string &Id)
:
Reactor_(reactor),
Id_(Id),
Logger_(Poco::Logger::get(fmt::format("RTTY-client({})",Id_)))
{
Logger_.information("Starting connection");
Valid_ = true;
WS_ = std::make_unique<Poco::Net::WebSocket>(request,response);
Reactor_.addEventHandler(
*WS_, Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ReadableNotification>(
*this, &RTTYS_ClientConnection::onSocketReadable));
Reactor_.addEventHandler(
*WS_, Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ShutdownNotification>(
*this, &RTTYS_ClientConnection::onSocketShutdown));
}
}
RTTYS_ClientConnection::~RTTYS_ClientConnection() {
Logger().information(fmt::format("{}: WS client disconnecting.", Id_));
if(Connected_) {
SR_.removeEventHandler(
*WS_, Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ReadableNotification>(
*this, &RTTYS_ClientConnection::onSocketReadable));
SR_.removeEventHandler(
*WS_, Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ShutdownNotification>(
*this, &RTTYS_ClientConnection::onSocketShutdown));
}
WS_->close();
if(Connected_) {
RTTYS_server()->Logout(Id_);
RTTYS_server()->DeRegister(Id_, this);
if(Valid_) {
MyGuard G(Mutex_);
EndConnection(false);
}
}
void RTTYS_ClientConnection::Close() {
void RTTYS_ClientConnection::EndConnection(bool SendNotification) {
if(Valid_) {
Valid_=false;
try {
Reactor_.removeEventHandler(
*WS_, Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ReadableNotification>(
*this, &RTTYS_ClientConnection::onSocketReadable));
Reactor_.removeEventHandler(
*WS_, Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ShutdownNotification>(
*this, &RTTYS_ClientConnection::onSocketShutdown));
// WS_->shutdown();
if (SendNotification)
RTTYS_server()->NotifyClientDisconnect(Id_, this);
} catch(...) {
}
Logger_.information("Disconnected.");
}
}
void RTTYS_ClientConnection::onSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
int flags;
auto n = WS_->receiveFrame(Buffer_, sizeof(Buffer_), flags);
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
switch(Op) {
MyGuard G(Mutex_);
bool MustDisconnect = false;
try {
int flags;
auto n = WS_->receiveFrame(Buffer_, sizeof(Buffer_), 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;
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;
} break;
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
if (n == 0)
return delete this;
std::string s((char*)Buffer_, n);
// std::cout << "TEXT:" << s << std::endl;
if (n == 0) {
Logger_.information("Socket readable shutdown.");
MustDisconnect = true;
} else {
std::string s((char *)Buffer_, n);
try {
auto Doc = nlohmann::json::parse(s);
if (Doc.contains("type")) {
@@ -94,50 +84,82 @@ namespace OpenWifi {
if (Type == "winsize") {
auto cols = Doc["cols"];
auto rows = Doc["rows"];
if(!RTTYS_server()->WindowSize(Id_,cols, rows)) {
return delete this;
if (!RTTYS_server()->WindowSize(Id_, cols, rows)) {
Logger_.information("Winsize shutdown.");
MustDisconnect = true;
}
}
}
} catch (...) {
// just ignore parse errors
Logger_.information("Frame text exception shutdown.");
MustDisconnect = true;
}
}
break;
} break;
case Poco::Net::WebSocket::FRAME_OP_BINARY: {
if (n == 0)
return delete this;
if(!RTTYS_server()->SendKeyStrokes(Id_,Buffer_,n)) {
return delete this;
if (n == 0) {
Logger_.information("Frame binary size shutdown.");
MustDisconnect = true;
} else {
poco_trace(Logger_, fmt::format("Sending {} key strokes to device.", n));
if (!RTTYS_server()->SendKeyStrokes(Id_, Buffer_, n)) {
Logger_.information("Sendkeystrokes shutdown.");
MustDisconnect = true;
}
}
break;
} break;
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
return delete this;
}
break;
default:
{
Logger_.information("Frame frame close shutdown.");
MustDisconnect = true;
} break;
default: {
}
}
} catch (...) {
Logger_.information("Frame readable shutdown.");
MustDisconnect = true;
}
if(MustDisconnect)
EndConnection();
}
void RTTYS_ClientConnection::SendData( const u_char *Buf, size_t len ) {
WS_->sendFrame(Buf, len, Poco::Net::WebSocket::FRAME_FLAG_FIN | Poco::Net::WebSocket::FRAME_OP_BINARY);
if(!Valid_)
return;
// MyGuard G(Mutex_);
try {
WS_->sendFrame(Buf, len,
Poco::Net::WebSocket::FRAME_FLAG_FIN |
Poco::Net::WebSocket::FRAME_OP_BINARY);
return;
} catch (...) {
Logger_.information("SendData shutdown.");
}
MyGuard G(Mutex_);
EndConnection();
}
void RTTYS_ClientConnection::SendData( const std::string &s , bool login) {
if(login) {
RTTYS_server()->LoginDone(Id_);
void RTTYS_ClientConnection::SendData( const std::string &s) {
if(!Valid_)
return;
// MyGuard G(Mutex_);
try {
WS_->sendFrame(s.c_str(), s.length());
return;
} catch (...) {
Logger_.information("SendData shutdown.");
}
WS_->sendFrame( s.c_str(), s.length());
MyGuard G(Mutex_);
EndConnection();
}
void RTTYS_ClientConnection::onSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
RTTYS_server()->Close(Id_);
delete this;
MyGuard G(Mutex_);
Logger_.information("Socket shutdown.");
EndConnection();
}
}

View File

@@ -12,28 +12,41 @@
#include "Poco/FIFOBuffer.h"
namespace OpenWifi {
enum class connection_state {
initialized, waiting_for_login, connected, aborting, shutting_down, done
};
class RTTYS_ClientConnection {
public:
RTTYS_ClientConnection(std::unique_ptr<Poco::Net::WebSocket> WS, std::string &Id,
Poco::Net::SocketReactor &Reactor);
RTTYS_ClientConnection(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response,
Poco::Net::SocketReactor & reactor,
const std::string &Id);
~RTTYS_ClientConnection();
void onSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
void onSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf);
void SendData( const u_char *Buf, size_t len );
void SendData( const std::string & S, bool login=false);
void SendData( const std::string & S );
void Close();
[[nodiscard]] inline std::string ID() { return Id_; }
[[nodiscard]] inline bool Valid() { return Valid_; }
using MyMutexType = std::recursive_mutex;
using MyGuard = std::lock_guard<MyMutexType>;
private:
std::unique_ptr<Poco::Net::WebSocket> WS_;
std::string Id_;
std::string Sid_;
Poco::Net::SocketReactor &SR_;
std::atomic_bool Connected_=false;
Poco::Logger & Logger_;
u_char Buffer_[16000]{0};
Poco::Net::SocketReactor &Reactor_;
std::string Id_;
std::unique_ptr<Poco::Net::WebSocket> WS_;
Poco::Logger &Logger_;
std::string Sid_;
std::atomic_bool Valid_=false;
u_char Buffer_[64000]{0};
MyMutexType Mutex_;
// volatile connection_state state_ = connection_state::initialized;
void EndConnection(bool SendNotification=true);
inline Poco::Logger & Logger() { return Logger_; }
};
}

View File

@@ -9,26 +9,30 @@
namespace OpenWifi {
RTTY_Client_WebSocketRequestHandler::RTTY_Client_WebSocketRequestHandler(Poco::Net::SocketReactor &R)
:R_(R) {
RTTYS_Client_WebSocketRequestHandler::RTTYS_Client_WebSocketRequestHandler(Poco::Logger & L)
:Logger_(L) {
}
void RTTY_Client_WebSocketRequestHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
void RTTYS_Client_WebSocketRequestHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response) {
Poco::URI uri(request.getURI());
const auto P = uri.getPath();
// std::cout << "WS: " << P << std::endl;
const auto & P = uri.getPath();
auto T = Poco::StringTokenizer(P, "/");
if (T.count() != 3)
return;
if (T[1] != "connect")
return;
if(!RTTYS_server()->ValidId(T[2])) {
response.setStatus(Poco::Net::HTTPResponse::HTTP_NOT_FOUND);
response.send();
return;
}
try {
Poco::Thread::current()->setName(fmt::format("WebRTTYRequest_WSHandler_{}", T[2]));
auto ws_ptr = std::make_unique<Poco::Net::WebSocket>(request, response);
new RTTYS_ClientConnection(std::move(ws_ptr), T[2], R_);
RTTYS_server()->CreateNewClient(request,response,T[2]);
} catch (...) {
RTTYS_server()->Logger().warning("Exception during WS creation");
Logger_.warning("Exception during WS creation");
}
};
@@ -47,30 +51,51 @@ namespace OpenWifi {
return false;
}
static void AddCORS(Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse & Response, Poco::Logger & Logger_, uint64_t id) {
Logger_.information(fmt::format("{}: Adding CORS", id));
inline void ProcessOptions(Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response) {
Response.setVersion(Poco::Net::HTTPMessage::HTTP_1_1);
Response.setChunkedTransferEncoding(true);
auto Origin = Request.find("Origin");
if (Origin != Request.end()) {
Response.set("Access-Control-Allow-Origin", Origin->second);
Response.set("Vary", "Origin");
} else {
Response.set("Access-Control-Allow-Origin", "*");
}
auto Referer = Request.find("Referer");
if(Referer!=Request.end()) {
Response.set("Access-Control-Allow-Origin", Referer->second);
} else {
Response.set("Access-Control-Allow-Origin", "*");
}
Response.set("Access-Control-Allow-Headers", "*");
Response.set("Access-Control-Allow-Methods", "GET, OPTIONS");
auto RequestHeaders = Request.find("Access-Control-Request-Headers");
if(RequestHeaders!=Request.end())
Response.set("Access-Control-Allow-Headers", RequestHeaders->second);
Response.set("Vary", "Origin, Accept-Encoding");
Response.set("Access-Control-Allow-Credentials", "true");
Response.set("Access-Control-Max-Age", "86400");
Response.set("Access-Control-Allow-Methods", "GET, OPTIONS, HEAD");
Response.set("Connection", "Keep-Alive");
Response.set("Keep-Alive", "timeout=120");
Response.set("Accept-Ranges","bytes");
Response.set("Keep-Alive", "timeout=30, max=1000");
Response.setContentLength(0);
Response.setStatus(Poco::Net::HTTPResponse::HTTP_OK);
Response.send();
}
inline void SetCommonHeaders(Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response, bool CloseConnection) {
Response.setVersion(Poco::Net::HTTPMessage::HTTP_1_1);
Response.setChunkedTransferEncoding(true);
Response.setContentType("application/json");
auto Origin = Request.find("Origin");
if (Origin != Request.end()) {
Response.set("Access-Control-Allow-Origin", Origin->second);
} else {
Response.set("Access-Control-Allow-Origin", "*");
}
Response.set("Vary", "Origin, Accept-Encoding");
if(CloseConnection) {
Response.set("Connection", "close");
Response.setKeepAlive(false);
} else {
Response.setKeepAlive(true);
Response.set("Connection", "Keep-Alive");
Response.set("Keep-Alive", "timeout=30, max=1000");
}
}
static inline std::atomic_uint64_t rtty_ws_id = 1;
@@ -78,22 +103,21 @@ namespace OpenWifi {
void PageRequestHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response) {
Poco::Logger & Logger_ = RTTYS_server()->Logger();
uint64_t id = rtty_ws_id++;
Utils::SetThreadName("rt:webserver");
[[maybe_unused]] uint64_t id = rtty_ws_id++;
Logger_.information(fmt::format("{}: Starting request.",id));
poco_debug(Logger(),fmt::format("{}: Starting request.",id));
Poco::URI uri(request.getURI());
auto Path = uri.getPath();
if(request.getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) {
AddCORS(request,response, Logger_, id);
return ProcessOptions(request, response);
}
if(request.getMethod() != Poco::Net::HTTPRequest::HTTP_GET) {
SetCommonHeaders(request,response,false);
response.setStatus(Poco::Net::HTTPResponse::HTTP_METHOD_NOT_ALLOWED);
response.send();
Logger_.information(fmt::format("{}: Finishing OPTIONS request.",id));
return;
} else if(request.getMethod() == Poco::Net::HTTPRequest::HTTP_HEAD){
AddCORS(request,response, Logger_, id);
response.send();
Logger_.information(fmt::format("{}: Finishing HEAD request.",id));
return;
}
@@ -104,51 +128,48 @@ namespace OpenWifi {
if (ParsedPath.count() > 1) {
if (ParsedPath[1] == "connect") {
response.redirect(Poco::replace(Path,"/connect/","/rtty/"));
RTTYS_server()->Logger().information(fmt::format("redirect: {}",Path));
poco_debug(Logger(),fmt::format("{}: Redirect: {}",id,Path));
return;
} else if (ParsedPath[1] == "authorized") {
AddCORS(request,response, Logger_, id);
SetCommonHeaders(request,response, false);
nlohmann::json doc;
doc["authorized"] = true;
response.setContentType("application/json");
std::ostream &answer = response.send();
answer << to_string(doc);
Logger_.information(fmt::format("{}: Finishing authorization request.",id));
poco_debug(Logger(),fmt::format("{}: Finishing authorization request.",id));
return;
} else if (ParsedPath[1] == "fontsize") {
AddCORS(request,response, Logger_, id);
SetCommonHeaders(request,response, false);
nlohmann::json doc;
doc["size"] = 16;
response.setContentType("application/json");
std::ostream &answer = response.send();
answer << to_string(doc);
Logger_.information(fmt::format("{}: Finishing fonstize request.",id));
poco_debug(Logger(),fmt::format("{}: Finishing font size request.",id));
return;
}
}
Path = RTTYS_server()->UIAssets() + Path;
}
// std::cout << id << ": Serving path '" << Path << "'" << std::endl;
// simple test to block .. or ~ in path names.
if(Path.find("../")!=std::string::npos) {
Logger_.information(fmt::format("{}: Finishing request.",id));
poco_debug(Logger(),fmt::format("{}: Finishing request.",id));
return;
}
if(Path.find("~/")!=std::string::npos) {
Logger_.information(fmt::format("{}: Finishing request.",id));
poco_debug(Logger(),fmt::format("{}: Finishing request.",id));
return;
}
Poco::File F(Path);
AddCORS(request,response, Logger_, id);
SetCommonHeaders(request,response, false);
if(!F.exists()) {
// std::cout << id << ": Path " << Path << " does not exist" << std::endl;
Path = RTTYS_server()->UIAssets() + "/index.html";
response.sendFile(Path,"text/html");
Logger_.information(fmt::format("{}: Finishing request.",id));
poco_debug(Logger(),fmt::format("{}: Finishing request.",id));
return;
}
Poco::Path P(Path);
@@ -165,7 +186,7 @@ namespace OpenWifi {
} else if (Ext == "css") {
Type = "text/css; charset=utf-8";
if(IsFileGZipped(Path)) {
Logger_.information(fmt::format("{}: Downloading UI Assets.",id));
poco_debug(Logger(),fmt::format("{}: Downloading UI Assets.",id));
response.set("Content-Encoding", "gzip");
}
} else if (Ext == "ico")
@@ -179,22 +200,22 @@ namespace OpenWifi {
response.setContentLength(F.getSize());
response.sendFile(Path, Type);
Logger_.information(fmt::format("{}: Finishing request.",id));
poco_debug(Logger(),fmt::format("{}: Finishing request.",id));
}
RTTY_Client_RequestHandlerFactory::RTTY_Client_RequestHandlerFactory(Poco::Net::SocketReactor &R)
: Reactor_(R) {}
RTTYS_Client_RequestHandlerFactory::RTTYS_Client_RequestHandlerFactory(Poco::Logger & L)
: Logger_(L) {}
Poco::Net::HTTPRequestHandler *
RTTY_Client_RequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &request) {
RTTYS_Client_RequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &request) {
try {
if (request.find("Upgrade") != request.end() &&
Poco::icompare(request["Upgrade"], "websocket") == 0) {
Poco::Thread::current()->setName("WebRTTYRequest_WSHandler");
return new RTTY_Client_WebSocketRequestHandler(Reactor_);
return new RTTYS_Client_WebSocketRequestHandler(Logger_);
} else {
Poco::Thread::current()->setName("WebRTTYRequest_PageHandler");
return new PageRequestHandler;
return new PageRequestHandler(Logger_);
}
} catch (...) {

View File

@@ -10,31 +10,39 @@
#include "Poco/Net/WebSocket.h"
namespace OpenWifi {
class RTTY_Client_WebSocketRequestHandler : public Poco::Net::HTTPRequestHandler {
class RTTYS_Client_WebSocketRequestHandler : public Poco::Net::HTTPRequestHandler {
public:
explicit RTTY_Client_WebSocketRequestHandler(Poco::Net::SocketReactor &R);
explicit RTTYS_Client_WebSocketRequestHandler(Poco::Logger &L);
void handleRequest(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response) override;
private:
Poco::Net::SocketReactor &R_;
Poco::Logger &Logger_;
};
class PageRequestHandler : public Poco::Net::HTTPRequestHandler {
public:
PageRequestHandler(Poco::Logger &L)
: Logger_(L) {
}
void handleRequest(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response) override;
private:
Poco::Logger & Logger_;
inline Poco::Logger &Logger() { return Logger_; }
};
class RTTY_Client_RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
class RTTYS_Client_RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
explicit RTTY_Client_RequestHandlerFactory(Poco::Net::SocketReactor &R);
explicit RTTYS_Client_RequestHandlerFactory(Poco::Logger &L);
Poco::Net::HTTPRequestHandler *
createRequestHandler(const Poco::Net::HTTPServerRequest &request) override;
private:
Poco::Net::SocketReactor &Reactor_;
Poco::Logger &Logger_;
};
}

View File

@@ -4,188 +4,244 @@
#include "RTTYS_device.h"
#include "rttys/RTTYS_server.h"
#include "rttys/RTTYS_ClientConnection.h"
#include "Poco/Net/SecureStreamSocketImpl.h"
#include "Poco/Net/StreamSocket.h"
namespace OpenWifi {
RTTY_Device_ConnectionHandler::RTTY_Device_ConnectionHandler(const Poco::Net::StreamSocket & socket) :
Poco::Net::TCPServerConnection(socket),
Logger_(RTTYS_server()->Logger()) {
conn_id_ = global_device_connection_id++;
RTTYS_Device_ConnectionHandler::RTTYS_Device_ConnectionHandler(Poco::Net::StreamSocket& socket, Poco::Net::SocketReactor & reactor):
socket_(socket),
reactor_(reactor),
Logger_(Poco::Logger::get(fmt::format("RTTY-device({})",socket_.peerAddress().toString())))
{
// std::thread T([=]() { CompleteConnection(); });
// T.detach();
CompleteConnection();
}
RTTY_Device_ConnectionHandler::~RTTY_Device_ConnectionHandler() {
running_ = false;
while(!loop_done_) {
Poco::Thread::sleep(10);
}
RTTYS_server()->DeRegister(id_, this);
}
void RTTY_Device_ConnectionHandler::AddCommand(u_char C) {
std::lock_guard G(M_);
// std::cout << conn_id_ << ": Adding command " << (int)C << std::endl;
commands_.push_back(C);
}
bool RTTY_Device_ConnectionHandler::ProcessCommands() {
std::lock_guard G(M_);
if(!commands_.empty()) {
// std::cout << conn_id_ << ": Commands: " << commands_.size() << std::endl;
for(const auto &i:commands_) {
// std::cout << "Command: " << (int)i << std::endl;
if(i==msgTypeLogin) {
// std::cout << "Doing login..." << std::endl;
Login();
void RTTYS_Device_ConnectionHandler::CompleteConnection() {
try {
valid_=true;
device_address_ = socket_.peerAddress();
if (MicroService::instance().NoAPISecurity()) {
poco_information(Logger(),"Unsecured connection.");
} else {
auto SS = dynamic_cast<Poco::Net::SecureStreamSocketImpl *>(socket_.impl());
while (true) {
auto V = SS->completeHandshake();
if (V == 1)
break;
}
else if(i==msgTypeLogout) {
// std::cout << "Doing logout..." << std::endl;
Logout();
if ((SS->secure())) {
poco_information(Logger(), "Secure connection.");
}
}
commands_.clear();
reactor_.addEventHandler(
socket_,
Poco::NObserver<RTTYS_Device_ConnectionHandler, Poco::Net::ReadableNotification>(
*this, &RTTYS_Device_ConnectionHandler::onSocketReadable));
reactor_.addEventHandler(
socket_,
Poco::NObserver<RTTYS_Device_ConnectionHandler, Poco::Net::ShutdownNotification>(
*this, &RTTYS_Device_ConnectionHandler::onSocketShutdown));
} catch (...) {
poco_warning(Logger(), "Device caused exception while completing connection.");
Guard G(M_);
EndConnection();
}
return true;
}
RTTYS_Device_ConnectionHandler::~RTTYS_Device_ConnectionHandler() {
if(valid_) {
Guard G(M_);
poco_warning(Logger(), "Device connection being deleted.");
EndConnection(false);
}
}
void RTTY_Device_ConnectionHandler::run() {
running_ = true ;
void RTTYS_Device_ConnectionHandler::EndConnection(bool SendNotification) {
try {
if(valid_) {
valid_ = false;
reactor_.removeEventHandler(
socket_,
Poco::NObserver<RTTYS_Device_ConnectionHandler, Poco::Net::ReadableNotification>(
*this, &RTTYS_Device_ConnectionHandler::onSocketReadable));
reactor_.removeEventHandler(
socket_,
Poco::NObserver<RTTYS_Device_ConnectionHandler, Poco::Net::ShutdownNotification>(
*this, &RTTYS_Device_ConnectionHandler::onSocketShutdown));
if(SendNotification)
RTTYS_server()->NotifyDeviceDisconnect(Id_,this);
poco_information(Logger(), "Connection done.");
socket_.close();
}
} catch (...) {
Poco::Timespan pollTimeOut(0,100);
Poco::Timespan pollError(0,1);
Poco::Timespan recvTimeOut(120,0);
}
}
socket().setKeepAlive(true);
socket().setNoDelay(true);
socket().setReceiveBufferSize(64000);
socket().setLinger(false,0);
socket().setSendBufferSize(64000);
socket().setReceiveTimeout(recvTimeOut);
[[maybe_unused]] static void dump(unsigned char *p,uint l) {
for(uint i=0;i<l;i++) {
std::cout << std::hex << (uint) p[i] << " ";
if(i % 16 == 0)
std::cout << std::endl;
}
std::cout << std::dec << std::endl ;
}
while(running_) {
void RTTYS_Device_ConnectionHandler::onSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
bool good = true;
if(!ProcessCommands()) {
running_=false;
break;
Guard G(M_);
try {
auto received_bytes = socket_.receiveBytes(inBuf_);
if (received_bytes == 0) {
poco_information(Logger(), fmt::format("{}: Device Closing connection - 0 bytes received.",Id_));
return EndConnection();
}
std::lock_guard G(M_);
if (socket().poll(pollError, Poco::Net::Socket::SELECT_ERROR) == true) {
running_=false;
continue;
}
while (inBuf_.isReadable() && good) {
uint32_t msg_len = 0;
if (waiting_for_bytes_ != 0) {
if (socket().poll(pollTimeOut, Poco::Net::Socket::SELECT_READ) == false) {
continue;
}
int received = socket().receiveBytes(inBuf_);
if(received<0) {
running_ = false;
continue;
}
if(received==0) {
continue;
}
while (!inBuf_.isEmpty() && running_) {
// std::cout << conn_id_ << ": processing buffer" << std::endl;
std::size_t msg_len;
if (waiting_for_bytes_ == 0) {
u_char header[3]{0};
inBuf_.read((char *)&header[0], 3);
last_command_ = header[0];
msg_len = header[1] * 256 + header[2];
} else {
msg_len = received;
if (inBuf_.used() >= 3) {
auto *head = (unsigned char *)inBuf_.begin();
last_command_ = head[0];
msg_len = head[1] * 256 + head[2];
inBuf_.drain(3);
} else {
good = false;
if (!good)
std::cout << "do_msgTypeTermData:5 " << inBuf_.used() << std::endl;
continue;
}
}
switch (last_command_) {
case msgTypeRegister: {
do_msgTypeRegister(msg_len);
good = do_msgTypeRegister(msg_len);
} break;
case msgTypeLogin: {
do_msgTypeLogin(msg_len);
good = do_msgTypeLogin(msg_len);
} break;
case msgTypeLogout: {
do_msgTypeLogout(msg_len);
good = do_msgTypeLogout(msg_len);
} break;
case msgTypeTermData: {
do_msgTypeTermData(msg_len);
good = do_msgTypeTermData(msg_len);
} break;
case msgTypeWinsize: {
do_msgTypeWinsize(msg_len);
good = do_msgTypeWinsize(msg_len);
} break;
case msgTypeCmd: {
do_msgTypeCmd(msg_len);
good = do_msgTypeCmd(msg_len);
} break;
case msgTypeHeartbeat: {
do_msgTypeHeartbeat(msg_len);
good = do_msgTypeHeartbeat(msg_len);
} break;
case msgTypeFile: {
do_msgTypeFile(msg_len);
good = do_msgTypeFile(msg_len);
} break;
case msgTypeHttp: {
do_msgTypeHttp(msg_len);
good = do_msgTypeHttp(msg_len);
} break;
case msgTypeAck: {
do_msgTypeAck(msg_len);
good = do_msgTypeAck(msg_len);
} break;
case msgTypeMax: {
do_msgTypeMax(msg_len);
good = do_msgTypeMax(msg_len);
} break;
default:
Logger().warning(fmt::format("{}: ID:{} Unknown command {}", conn_id_, id_, (int)last_command_));
running_ = false;
continue;
default: {
poco_warning(Logger(),
fmt::format("{}: Unknown command {} from device. GW closing connection.", Id_,
(int)last_command_));
good = false;
}
}
}
} catch (const Poco::Exception &E) {
good = false;
Logger().log(E,__FILE__,__LINE__);
poco_warning(Logger(),fmt::format("{}: Exception. GW closing connection.", Id_));
} catch (const std::exception &E) {
poco_warning(Logger(),fmt::format("{}: Exception. GW closing connection.", Id_));
good = false;
}
if(!good) {
return EndConnection();
}
}
void RTTYS_Device_ConnectionHandler::onSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf) {
Guard G(M_);
poco_information(Logger(),fmt::format("{}: Connection being closed - socket shutdown.",Id_));
EndConnection();
}
bool RTTYS_Device_ConnectionHandler::SendToClient(const u_char *Buf, int Len) {
return RTTYS_server()->SendToClient(Id_, Buf, Len);
}
bool RTTYS_Device_ConnectionHandler::SendToClient(const std::string &S) {
return RTTYS_server()->SendToClient(Id_, S);
}
bool RTTYS_Device_ConnectionHandler::KeyStrokes(const u_char *buf, size_t len) {
if(!valid_)
return false;
if(len<=(sizeof(small_buf_)-3)) {
small_buf_[0] = msgTypeTermData;
small_buf_[1] = (len & 0xff00) >> 8;
small_buf_[2] = (len & 0x00ff);
memcpy(&small_buf_[3],buf,len);
try {
socket_.sendBytes(small_buf_,len+3);
return true;
} catch (...) {
return false;
}
} else {
auto Msg = std::make_unique<unsigned char []>(len + 3);
Msg.get()[0] = msgTypeTermData;
Msg.get()[1] = (len & 0xff00) >> 8;
Msg.get()[2] = (len & 0x00ff);
memcpy((void *)(Msg.get() + 3), buf, len);
try {
socket_.sendBytes(Msg.get(), len + 3);
return true;
} catch (...) {
return false;
}
}
Logger().information(fmt::format("{}: ID:{} Exiting", conn_id_, id_));
loop_done_=true;
RTTYS_server()->DeRegister(id_, this);
std::cout << conn_id_ << ": loop exiting" << std::endl;
}
/*
unsigned char Msg[64];
Msg[0] = msgTypeTermData;
Msg[1] = (len & 0xff00) >> 8;
Msg[2] = (len & 0x00ff);
void RTTY_Device_ConnectionHandler::Stop() {
running_ = true;
}
void RTTY_Device_ConnectionHandler::SendToClient(const u_char *Buf, int Len) {
RTTYS_server()->SendToClient(id_, Buf, Len);
}
void RTTY_Device_ConnectionHandler::SendToClient(const std::string &S) {
RTTYS_server()->SendToClient(id_, S);
}
bool RTTY_Device_ConnectionHandler::KeyStrokes(const u_char *buf, size_t len) {
std::lock_guard G(M_);
u_char outBuf[16]{0};
if(len>(sizeof(outBuf)-5))
return false;
auto total_len = 3 + 1 + len-1;
outBuf[0] = msgTypeTermData;
outBuf[1] = 0 ;
outBuf[2] = len +1-1;
outBuf[3] = sid_;
memcpy( &outBuf[4], &buf[1], len-1);
Poco::Net::SocketBufVec MsgParts{ Poco::Net::SocketBuf{ .iov_base=Msg, .iov_len=3},
Poco::Net::SocketBuf{ .iov_base=(unsigned char *)buf, .iov_len=len}};
try {
socket().sendBytes(outBuf, total_len);
socket_.sendBytes(MsgParts);
return true;
} catch (...) {
return false;
}
return false;
*/
}
bool RTTY_Device_ConnectionHandler::WindowSize(int cols, int rows) {
std::lock_guard G(M_);
bool RTTYS_Device_ConnectionHandler::WindowSize(int cols, int rows) {
if(!valid_)
return false;
// Guard G(M_);
u_char outBuf[8]{0};
outBuf[0] = msgTypeWinsize;
outBuf[1] = 0 ;
@@ -196,7 +252,7 @@ namespace OpenWifi {
outBuf[6] = rows >> 8;
outBuf[7] = rows & 0x00ff;
try {
socket().sendBytes(outBuf, 8);
socket_.sendBytes(outBuf, 8);
return true;
} catch (...) {
@@ -204,35 +260,40 @@ namespace OpenWifi {
return false;
}
bool RTTY_Device_ConnectionHandler::Login() {
std::lock_guard G(M_);
bool RTTYS_Device_ConnectionHandler::Login() {
if(!valid_)
return false;
// Guard G(M_);
u_char outBuf[3]{0};
outBuf[0] = msgTypeLogin;
outBuf[1] = 0;
outBuf[2] = 0;
try {
socket().sendBytes(outBuf, 3);
socket_.sendBytes(outBuf, 3);
} catch (const Poco::IOException &E) {
// std::cout << "1 " << E.what() << " " << E.name() << " "<< E.className() << " "<< E.message() << std::endl;
return false;
} catch (const Poco::Exception &E) {
// std::cout << "2 " << E.what() << " " << E.name() << std::endl;
return false;
}
Logger().debug(fmt::format("{}: Device {} login", conn_id_, id_));
poco_information(Logger(),fmt::format("{}: Device login", Id_));
return true;
}
bool RTTY_Device_ConnectionHandler::Logout() {
std::lock_guard G(M_);
bool RTTYS_Device_ConnectionHandler::Logout() {
if(!valid_)
return false;
Guard G(M_);
u_char outBuf[4]{0};
outBuf[0] = msgTypeLogout;
outBuf[1] = 0;
outBuf[2] = 1;
outBuf[3] = sid_;
Logger().debug(fmt::format("{}: ID:{} Logout", conn_id_, id_));
poco_information(Logger(),fmt::format("{}: Logout", Id_));
try {
socket().sendBytes(outBuf, 4);
socket_.sendBytes(outBuf, 4);
return true;
} catch (...) {
@@ -240,7 +301,7 @@ namespace OpenWifi {
return false;
}
std::string RTTY_Device_ConnectionHandler::ReadString() {
std::string RTTYS_Device_ConnectionHandler::ReadString() {
std::string Res;
while(inBuf_.used()) {
@@ -255,16 +316,16 @@ namespace OpenWifi {
return Res;
}
void RTTY_Device_ConnectionHandler::do_msgTypeRegister([[maybe_unused]] std::size_t msg_len) {
socket().receiveBytes(inBuf_);
id_ = ReadString();
desc_ = ReadString();
token_ = ReadString();
serial_ = RTTYS_server()->SerialNumber(id_);
bool RTTYS_Device_ConnectionHandler::do_msgTypeRegister([[maybe_unused]] std::size_t msg_len) {
bool good = true;
try {
Id_ = ReadString();
desc_ = ReadString();
token_ = ReadString();
Poco::Thread::current()->setName(fmt::format("RTTY-device-thread-{}:{}:{}", conn_id_, id_, serial_));
Logger().debug(fmt::format("{}: ID:{} Serial:{} Description:{} Device registration", conn_id_, id_, serial_, desc_));
if (RTTYS_server()->Register(id_, token_, this)) {
poco_information(Logger(),
fmt::format("{}: Description:{} Device registration", Id_, desc_));
RTTYS_server()->NotifyDeviceRegistration(Id_,token_,this);
u_char OutBuf[8];
OutBuf[0] = msgTypeRegister;
OutBuf[1] = 0;
@@ -273,18 +334,20 @@ namespace OpenWifi {
OutBuf[4] = 'O';
OutBuf[5] = 'K';
OutBuf[6] = 0;
if(socket().sendBytes(OutBuf, 7) !=7) {
Logger().debug(fmt::format("{}: ID:{} Serial:{} Description:{} Could not complete registration", conn_id_, id_, serial_, desc_));
running_ = false;
if (socket_.sendBytes(OutBuf, 7) != 7) {
poco_information(Logger(),
fmt::format("{}: Description:{} Could not send data to complete registration",
Id_, desc_));
good = false;
}
} else {
Logger().debug(fmt::format("{}: ID:{} Serial:{} Description:{} Could not complete registration", conn_id_, id_, serial_, desc_));
running_ = false;
} catch (...) {
good = false;
}
return good;
}
void RTTY_Device_ConnectionHandler::do_msgTypeLogin([[maybe_unused]] std::size_t msg_len) {
Logger().debug(fmt::format("{}: ID:{} Serial:{} Asking for login", conn_id_, id_, serial_));
bool RTTYS_Device_ConnectionHandler::do_msgTypeLogin([[maybe_unused]] std::size_t msg_len) {
poco_information(Logger(),fmt::format("{}: Asking for login", Id_));
nlohmann::json doc;
char Error;
inBuf_.read(&Error, 1);
@@ -292,66 +355,79 @@ namespace OpenWifi {
doc["type"] = "login";
doc["err"] = Error;
const auto login_msg = to_string(doc);
SendToClient(login_msg);
return SendToClient(login_msg);
}
void RTTY_Device_ConnectionHandler::do_msgTypeLogout([[maybe_unused]] std::size_t msg_len) {
Logger().debug(fmt::format("{}: ID:{} Serial:{} Asking for logout", conn_id_, id_, serial_));
bool RTTYS_Device_ConnectionHandler::do_msgTypeLogout([[maybe_unused]] std::size_t msg_len) {
poco_information(Logger(),fmt::format("{}: Asking for logout", Id_));
return true;
}
void RTTY_Device_ConnectionHandler::do_msgTypeTermData(std::size_t msg_len) {
if(waiting_for_bytes_!=0) {
// std::cout << conn_id_ << ": S2:" << inBuf_.used() << std::endl;
auto to_read = std::min(inBuf_.used(),waiting_for_bytes_);
inBuf_.read(&scratch_[0], to_read);
SendToClient((u_char *)&scratch_[0], (int) to_read);
if(to_read<waiting_for_bytes_)
waiting_for_bytes_ -= to_read;
else
bool RTTYS_Device_ConnectionHandler::do_msgTypeTermData(std::size_t msg_len) {
bool good;
if(waiting_for_bytes_>0) {
if(inBuf_.used()<waiting_for_bytes_) {
waiting_for_bytes_ = waiting_for_bytes_ - inBuf_.used();
good = SendToClient((unsigned char *)inBuf_.begin(), (int) inBuf_.used());
if(!good) std::cout << "do_msgTypeTermData:1" << std::endl;
inBuf_.drain();
} else {
good = SendToClient((unsigned char *)inBuf_.begin(), waiting_for_bytes_);
if(!good) std::cout << "do_msgTypeTermData:2" << std::endl;
inBuf_.drain(waiting_for_bytes_);
waiting_for_bytes_ = 0 ;
}
} else {
if(inBuf_.used()<msg_len) {
// std::cout << conn_id_ << ": S1:" << msg_len << std::endl;
auto read_count = inBuf_.read(&scratch_[0], inBuf_.used());
SendToClient((u_char *)&scratch_[0], read_count);
waiting_for_bytes_ = msg_len - read_count;
good = SendToClient((unsigned char *)inBuf_.begin(), inBuf_.used());
if(!good) std::cout << "do_msgTypeTermData:3" << std::endl;
waiting_for_bytes_ = msg_len - inBuf_.used();
inBuf_.drain();
} else {
// std::cout << conn_id_ << ": S0:" << msg_len << std::endl;
inBuf_.read(&scratch_[0], msg_len);
SendToClient((u_char *)&scratch_[0], (int)msg_len);
waiting_for_bytes_=0;
waiting_for_bytes_ = 0 ;
good = SendToClient((unsigned char *)inBuf_.begin(), msg_len);
if(!good) std::cout << "do_msgTypeTermData:4" << std::endl;
inBuf_.drain(msg_len);
}
}
return good;
}
void RTTY_Device_ConnectionHandler::do_msgTypeWinsize([[maybe_unused]] std::size_t msg_len) {
Logger().debug(fmt::format("{}: ID:{} Serial:{} Asking for msgTypeWinsize", conn_id_, id_, serial_));
bool RTTYS_Device_ConnectionHandler::do_msgTypeWinsize([[maybe_unused]] std::size_t msg_len) {
poco_information(Logger(),fmt::format("{}: Asking for msgTypeWinsize", Id_));
return true;
}
void RTTY_Device_ConnectionHandler::do_msgTypeCmd([[maybe_unused]] std::size_t msg_len) {
Logger().debug(fmt::format("{}: ID:{} Serial:{} Asking for msgTypeCmd", conn_id_, id_, serial_));
bool RTTYS_Device_ConnectionHandler::do_msgTypeCmd([[maybe_unused]] std::size_t msg_len) {
poco_information(Logger(),fmt::format("{}: Asking for msgTypeCmd", Id_));
return true;
}
void RTTY_Device_ConnectionHandler::do_msgTypeHeartbeat([[maybe_unused]] std::size_t msg_len) {
// std::cout << conn_id_ << ": Device msgTypeHeartbeat: " << std::endl;
bool RTTYS_Device_ConnectionHandler::do_msgTypeHeartbeat([[maybe_unused]] std::size_t msg_len) {
if(!RTTYS_server()->ValidClient(Id_))
return false;
u_char MsgBuf[3]{0};
MsgBuf[0] = msgTypeHeartbeat;
socket().sendBytes(MsgBuf, 3);
return socket_.sendBytes(MsgBuf, 3)==3;
}
void RTTY_Device_ConnectionHandler::do_msgTypeFile([[maybe_unused]] std::size_t msg_len) {
Logger().debug(fmt::format("{}: ID:{} Serial:{} Asking for msgTypeFile", conn_id_, id_, serial_));
bool RTTYS_Device_ConnectionHandler::do_msgTypeFile([[maybe_unused]] std::size_t msg_len) {
poco_information(Logger(),fmt::format("{}: Asking for msgTypeFile", Id_));
return true;
}
void RTTY_Device_ConnectionHandler::do_msgTypeHttp([[maybe_unused]] std::size_t msg_len) {
Logger().debug(fmt::format("{}: ID:{} Serial:{} Asking for msgTypeHttp", conn_id_, id_, serial_));
bool RTTYS_Device_ConnectionHandler::do_msgTypeHttp([[maybe_unused]] std::size_t msg_len) {
poco_information(Logger(),fmt::format("{}: Asking for msgTypeHttp", Id_));
return true;
}
void RTTY_Device_ConnectionHandler::do_msgTypeAck([[maybe_unused]] std::size_t msg_len) {
Logger().debug(fmt::format("{}: ID:{} Serial:{} Asking for msgTypeAck", conn_id_, id_, serial_));
bool RTTYS_Device_ConnectionHandler::do_msgTypeAck([[maybe_unused]] std::size_t msg_len) {
poco_information(Logger(),fmt::format("{}: Asking for msgTypeAck", Id_));
return true;
}
void RTTY_Device_ConnectionHandler::do_msgTypeMax([[maybe_unused]] std::size_t msg_len) {
Logger().debug(fmt::format("{}: ID:{} Serial:{} Asking for msgTypeMax", conn_id_, id_, serial_));
bool RTTYS_Device_ConnectionHandler::do_msgTypeMax([[maybe_unused]] std::size_t msg_len) {
poco_information(Logger(),fmt::format("{}: Asking for msgTypeMax", Id_));
return true;
}
}

View File

@@ -7,77 +7,79 @@
#include <array>
#include "framework/MicroService.h"
#include "Poco/FIFOBuffer.h"
#include "Poco/Net/TCPServerConnectionFactory.h"
namespace OpenWifi {
inline static const std::size_t RTTY_DEVICE_BUFSIZE=64000;
constexpr std::size_t RTTY_DEVICE_BUFSIZE=64000;
inline static std::atomic_uint64_t global_device_connection_id = 1;
class RTTYS_Device_ConnectionHandler{
public:
enum RTTY_MSG_TYPE {
msgTypeRegister = 0,
msgTypeLogin,
msgTypeLogout,
msgTypeTermData,
msgTypeWinsize,
msgTypeCmd,
msgTypeHeartbeat,
msgTypeFile,
msgTypeHttp,
msgTypeAck,
msgTypeMax };
class RTTY_Device_ConnectionHandler : public Poco::Net::TCPServerConnection {
public:
enum RTTY_MSG_TYPE {
msgTypeRegister = 0,
msgTypeLogin,
msgTypeLogout,
msgTypeTermData,
msgTypeWinsize,
msgTypeCmd,
msgTypeHeartbeat,
msgTypeFile,
msgTypeHttp,
msgTypeAck,
msgTypeMax };
explicit RTTYS_Device_ConnectionHandler(Poco::Net::StreamSocket& socket, Poco::Net::SocketReactor& reactor);
~RTTYS_Device_ConnectionHandler();
explicit RTTY_Device_ConnectionHandler(const Poco::Net::StreamSocket & socket) ;
~RTTY_Device_ConnectionHandler();
bool Login();
bool Logout();
void run() final;
bool Login();
bool Logout();
void Stop();
[[nodiscard]] bool SendToClient(const u_char *buf, int len);
[[nodiscard]] bool SendToClient(const std::string &S);
[[nodiscard]] bool WindowSize(int cols, int rows);
[[nodiscard]] bool KeyStrokes(const u_char *buf, size_t len);
std::string ReadString();
// inline auto SessionID() const { return conn_id_; }
void SendToClient(const u_char *buf, int len);
void SendToClient(const std::string &S);
bool WindowSize(int cols, int rows);
bool KeyStrokes(const u_char *buf, size_t len);
std::string ReadString();
inline auto SessionID() const { return conn_id_; }
void AddCommand(u_char C);
void onSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
void onSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf);
private:
std::atomic_bool running_=false;
std::atomic_bool loop_done_=false;
std::recursive_mutex M_;
Poco::Logger &Logger_;
std::string id_;
std::string token_;
std::string desc_;
std::string serial_;
char sid_=0;
Poco::FIFOBuffer inBuf_{64000};
std::array<char,32000> scratch_{0};
std::size_t waiting_for_bytes_{0};
u_char last_command_=0;
uint64_t conn_id_=0;
std::vector<u_char> commands_;
using My_mutex_type = std::recursive_mutex;
using Guard = std::lock_guard<My_mutex_type>;
inline Poco::Logger & Logger() { return Logger_; }
inline Poco::Logger &Logger() { return Logger_; }
inline bool Valid() { return valid_; }
void do_msgTypeRegister(std::size_t msg_len);
void do_msgTypeLogin(std::size_t msg_len);
void do_msgTypeLogout(std::size_t msg_len);
void do_msgTypeTermData(std::size_t msg_len);
void do_msgTypeWinsize(std::size_t msg_len);
void do_msgTypeCmd(std::size_t msg_len);
void do_msgTypeHeartbeat(std::size_t msg_len);
void do_msgTypeFile(std::size_t msg_len);
void do_msgTypeHttp(std::size_t msg_len);
void do_msgTypeAck(std::size_t msg_len);
void do_msgTypeMax(std::size_t msg_len);
private:
Poco::Net::StreamSocket socket_;
Poco::Net::SocketReactor &reactor_;
Poco::FIFOBuffer inBuf_{RTTY_DEVICE_BUFSIZE};
Poco::Logger &Logger_;
bool ProcessCommands();
};
std::atomic_bool valid_=false;
Poco::Net::SocketAddress device_address_;
My_mutex_type M_;
std::string Id_;
std::string token_;
std::string desc_;
char sid_=0;
std::size_t waiting_for_bytes_{0};
u_char last_command_=0;
unsigned char small_buf_[64];
void EndConnection(bool SendNotification=true) ;
void CompleteConnection();
[[nodiscard]] bool do_msgTypeRegister(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeLogin(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeLogout(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeTermData(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeWinsize(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeCmd(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeHeartbeat(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeFile(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeHttp(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeAck(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeMax(std::size_t msg_len);
};
}

View File

@@ -13,284 +13,292 @@ namespace OpenWifi {
Internal_ = MicroService::instance().ConfigGetBool("rtty.internal",false);
if(Internal_) {
int DSport = MicroService::instance().ConfigGetInt("rtty.port", 5912);
int CSport = MicroService::instance().ConfigGetInt("rtty.viewport", 5913);
RTTY_UIAssets_ =
MicroService::instance().ConfigPath("rtty.assets", "$OWGW_ROOT/rtty_ui");
int DSport = (int) MicroService::instance().ConfigGetInt("rtty.port", 5912);
int CSport = (int) MicroService::instance().ConfigGetInt("rtty.viewport", 5913);
RTTY_UIAssets_ = MicroService::instance().ConfigPath("rtty.assets", "$OWGW_ROOT/rtty_ui");
auto CertFileName = MicroService::instance().ConfigPath("openwifi.restapi.host.0.cert");
auto KeyFileName = MicroService::instance().ConfigPath("openwifi.restapi.host.0.key");
auto RootCa = MicroService::instance().ConfigPath("openwifi.restapi.host.0.rootca");
Poco::Crypto::X509Certificate Root(RootCa);
const auto & CertFileName = MicroService::instance().ConfigPath("openwifi.restapi.host.0.cert");
const auto & KeyFileName = MicroService::instance().ConfigPath("openwifi.restapi.host.0.key");
const auto & RootCa = MicroService::instance().ConfigPath("openwifi.restapi.host.0.rootca");
auto DeviceSecureContext = new Poco::Net::Context(Poco::Net::Context::SERVER_USE,
KeyFileName, CertFileName, "",
Poco::Net::Context::VERIFY_RELAXED);
auto TcpServerParams = new Poco::Net::TCPServerParams();
TcpServerParams->setMaxThreads(50);
TcpServerParams->setMaxQueued(100);
TcpServerParams->setThreadIdleTime(Poco::Timespan(10,0));
DeviceSecureContext->addCertificateAuthority(Root);
DeviceSecureContext->disableStatelessSessionResumption();
DeviceSecureContext->enableSessionCache();
DeviceSecureContext->setSessionCacheSize(0);
DeviceSecureContext->setSessionTimeout(10);
DeviceSecureContext->enableExtendedCertificateVerification(true);
SSL_CTX *SSLCtxDevice = DeviceSecureContext->sslContext();
SSL_CTX_dane_enable(SSLCtxDevice);
if(MicroService::instance().NoAPISecurity()) {
Poco::Net::ServerSocket DeviceSocket(DSport, 64);
DeviceAcceptor_ = std::make_unique<Poco::Net::SocketAcceptor<RTTYS_Device_ConnectionHandler>>(DeviceSocket,DeviceReactor_);
} else {
auto DeviceSecureContext = new Poco::Net::Context(Poco::Net::Context::SERVER_USE,
KeyFileName, CertFileName, "",
Poco::Net::Context::VERIFY_RELAXED);
Poco::Crypto::X509Certificate DeviceRoot(RootCa);
DeviceSecureContext->addCertificateAuthority(DeviceRoot);
DeviceSecureContext->disableStatelessSessionResumption();
DeviceSecureContext->enableSessionCache();
DeviceSecureContext->setSessionCacheSize(0);
DeviceSecureContext->setSessionTimeout(10);
DeviceSecureContext->enableExtendedCertificateVerification(true);
SSL_CTX *SSLCtxDevice = DeviceSecureContext->sslContext();
SSL_CTX_dane_enable(SSLCtxDevice);
Poco::Net::SecureServerSocket DeviceSocket(DSport, 64, DeviceSecureContext);
Poco::Net::TCPServerParams* pParams = new Poco::Net::TCPServerParams();
pParams->setMaxThreads(50);
pParams->setMaxQueued(100);
// pParams->setThreadIdleTime(100);
Poco::Net::SecureServerSocket DeviceSocket(DSport, 64, DeviceSecureContext);
DeviceAcceptor_ = std::make_unique<Poco::Net::SocketAcceptor<RTTYS_Device_ConnectionHandler>>(DeviceSocket,DeviceReactor_);
}
DeviceReactorThread_.start(DeviceReactor_);
Utils::SetThreadName(DeviceReactorThread_,"rt:devreactor");
DeviceAcceptor_ = std::make_unique<Poco::Net::TCPServer>(new Poco::Net::TCPServerConnectionFactoryImpl<RTTY_Device_ConnectionHandler>(), DeviceSocket, pParams);
DeviceAcceptor_->start();
auto WebServerHttpParams = new Poco::Net::HTTPServerParams;
WebServerHttpParams->setMaxThreads(50);
WebServerHttpParams->setMaxQueued(200);
WebServerHttpParams->setKeepAlive(true);
auto ClientSecureContext =
new Poco::Net::Context(Poco::Net::Context::SERVER_USE, KeyFileName, CertFileName,
"", Poco::Net::Context::VERIFY_RELAXED);
ClientSecureContext->addCertificateAuthority(Root);
ClientSecureContext->disableStatelessSessionResumption();
ClientSecureContext->enableSessionCache();
ClientSecureContext->setSessionCacheSize(0);
ClientSecureContext->setSessionTimeout(10);
ClientSecureContext->enableExtendedCertificateVerification(true);
SSL_CTX *SSLCtxClient = ClientSecureContext->sslContext();
SSL_CTX_dane_enable(SSLCtxClient);
if(MicroService::instance().NoAPISecurity()) {
Poco::Net::ServerSocket ClientSocket(CSport, 64);
ClientSocket.setNoDelay(true);
WebServer_ = std::make_unique<Poco::Net::HTTPServer>(new RTTYS_Client_RequestHandlerFactory(Logger()), ClientSocket, WebServerHttpParams);
} else {
auto WebClientSecureContext = new Poco::Net::Context(Poco::Net::Context::SERVER_USE, KeyFileName, CertFileName,
"", Poco::Net::Context::VERIFY_RELAXED);
Poco::Crypto::X509Certificate WebRoot(RootCa);
WebClientSecureContext->addCertificateAuthority(WebRoot);
WebClientSecureContext->disableStatelessSessionResumption();
WebClientSecureContext->enableSessionCache();
WebClientSecureContext->setSessionCacheSize(0);
WebClientSecureContext->setSessionTimeout(10);
WebClientSecureContext->enableExtendedCertificateVerification(true);
SSL_CTX *SSLCtxClient = WebClientSecureContext->sslContext();
SSL_CTX_dane_enable(SSLCtxClient);
Poco::Net::SecureServerSocket ClientSocket(CSport, 64, ClientSecureContext);
ClientSocket.setNoDelay(true);
auto HttpParams = new Poco::Net::HTTPServerParams;
HttpParams->setMaxThreads(50);
HttpParams->setMaxQueued(200);
HttpParams->setKeepAlive(true);
WebServer_ = std::make_unique<Poco::Net::HTTPServer>(
new RTTY_Client_RequestHandlerFactory(ClientReactor_), ClientSocket, HttpParams);
ClientReactorThread_.setName("RTTYWebServerClientThread");
ClientReactorThread_.start(ClientReactor_);
Poco::Net::SecureServerSocket ClientSocket(CSport, 64, WebClientSecureContext);
ClientSocket.setNoDelay(true);
WebServer_ = std::make_unique<Poco::Net::HTTPServer>(new RTTYS_Client_RequestHandlerFactory(Logger()), ClientSocket, WebServerHttpParams);
};
WebServer_->start();
ClientReactorThread_.start(ClientReactor_);
Utils::SetThreadName(ClientReactorThread_,"rt:clntreactor");
}
GCCallBack_ = std::make_unique<Poco::TimerCallback<RTTYS_server>>(*this, &RTTYS_server::onTimer);
Timer_.setStartInterval(30 * 1000); // first run in 30 seconds
Timer_.setPeriodicInterval(20 * 1000);
Timer_.start(*GCCallBack_);
NotificationManager_.start(*this);
return 0;
}
void RTTYS_server::Stop() {
if(Internal_) {
NotificationManagerRunning_=false;
ResponseQueue_.wakeUpAll();
NotificationManager_.wakeUp();
NotificationManager_.join();
Timer_.stop();
WebServer_->stopAll();
DeviceAcceptor_->stop();
WebServer_->stop();
DeviceAcceptor_->unregisterAcceptor();
DeviceReactor_.stop();
DeviceReactorThread_.join();
ClientReactor_.stop();
ClientReactorThread_.join();
}
}
void RTTYS_server::Register(const std::string &Id, RTTYS_ClientConnection *Client) {
std::lock_guard G(M_);
auto It = EndPoints_.find(Id);
if(It!=EndPoints_.end()) {
It->second.Client = Client;
It->second.ClientConnected = OpenWifi::Now();
void RTTYS_server::onTimer([[maybe_unused]] Poco::Timer & timer) {
poco_debug(Logger(),"Removing stale connections.");
Utils::SetThreadName("rt:janitor");
static int count = 0;
// MutexLockerDbg L(__func__ ,M_);
std::unique_lock G(M_);
for(auto element=EndPoints_.begin();element!=EndPoints_.end();) {
if(element->second->TooOld()) {
auto c = fmt::format("Removing {}. Serial: {} Device connection time: {}s. Client connection time: {}s",
element->first,
element->second->SerialNumber(),
element->second->TimeDeviceConnected(),
element->second->TimeClientConnected());
Logger().information(c);
TotalConnectedClientTime_ += element->second->TimeClientConnected();
TotalConnectedDeviceTime_ += element->second->TimeDeviceConnected();
element = EndPoints_.erase(element);
} else {
++element;
}
}
FailedDevices.clear();
FailedClients.clear();
count++;
if(count==10) {
count=0;
Logger().information(fmt::format("Total connections:{} Total Device Connection Time: {}s Total Client Connection Time: {}s Device failures: {} Client failures: {}",
TotalEndPoints_,
TotalConnectedDeviceTime_,
TotalConnectedClientTime_,
FaildedNumDevices_,
FailedNumClients_));
}
}
void RTTYS_server::CreateNewClient(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response, const std::string &id) {
auto NewClient = new RTTYS_ClientConnection(request, response, ClientReactor_, id);
NotifyClientRegistration(id,NewClient);
}
void RTTYS_server::run() {
Utils::SetThreadName("rtty-mgr");
NotificationManagerRunning_ = true;
Poco::AutoPtr<Poco::Notification> NextNotification(ResponseQueue_.waitDequeueNotification());
while (NextNotification && NotificationManagerRunning_) {
auto Notification = dynamic_cast<RTTYS_Notification *>(NextNotification.get());
if (Notification != nullptr) {
std::unique_lock G(M_);
auto It = EndPoints_.find(Notification->id_);
if (It != EndPoints_.end()) {
switch (Notification->type_) {
case RTTYS_Notification_type::device_disconnection: {
It->second->DisconnectDevice();
} break;
case RTTYS_Notification_type::client_disconnection: {
It->second->DisconnectClient();
} break;
case RTTYS_Notification_type::device_registration: {
auto ptr = std::unique_ptr<RTTYS_Device_ConnectionHandler>{Notification->device_};
It->second->SetDevice(std::move(ptr));
if(!It->second->Joined() && It->second->ValidClient()) {
It->second->Join();
It->second->Login();
}
} break;
case RTTYS_Notification_type::client_registration: {
auto ptr = std::unique_ptr<RTTYS_ClientConnection>{Notification->client_};
It->second->SetClient(std::move(ptr));
if(!It->second->Joined() && It->second->ValidDevice()) {
It->second->Join();
It->second->Login();
}
} break;
case RTTYS_Notification_type::unknown: {
} break;
};
} else {
if(Notification->type_==RTTYS_Notification_type::device_registration) {
FaildedNumDevices_++;
auto ptr = std::unique_ptr<RTTYS_Device_ConnectionHandler>{Notification->device_};
FailedDevices.push_back(std::move(ptr));
} else if(Notification->type_==RTTYS_Notification_type::client_registration) {
FailedNumClients_++;
auto ptr = std::unique_ptr<RTTYS_ClientConnection>{Notification->client_};
FailedClients.push_back(std::move(ptr));
}
}
}
NextNotification = ResponseQueue_.waitDequeueNotification();
}
}
bool RTTYS_server::SendToClient(const std::string &Id, const u_char *Buf, std::size_t Len) {
std::lock_guard G(M_);
auto It = EndPoints_.find(Id);
if(It!=EndPoints_.end() && It->second.Client!= nullptr) {
It->second.Client->SendData(Buf,Len);
return true;
std::shared_lock Guard(M_);
try {
auto It = EndPoints_.find(Id);
if (It != EndPoints_.end()) {
return It->second->SendToClient(Buf,Len);
}
} catch(const Poco::Exception &E) {
Logger().log(E);
} catch (...) {
std::cout << "Exception in SendToClient 1" << std::endl;
}
return false;
}
bool RTTYS_server::SendToClient(const std::string &Id, const std::string &s) {
std::lock_guard G(M_);
auto It = EndPoints_.find(Id);
if(It!=EndPoints_.end() && It->second.Client!= nullptr) {
It->second.Client->SendData(s);
return true;
}
return false;
}
void RTTYS_server::DeRegister(const std::string &Id, RTTYS_ClientConnection *Client) {
std::lock_guard G(M_);
auto It = EndPoints_.find(Id);
if(It==EndPoints_.end() && It->second.Client==Client) {
if(It->second.Device!= nullptr) {
It->second.Device->Stop();
std::shared_lock Guard(M_);
try {
auto It = EndPoints_.find(Id);
if (It != EndPoints_.end()) {
return It->second->SendToClient(s);
}
It->second.ClientConnected=0;
It->second.Client= nullptr;
}
}
bool RTTYS_server::Register(const std::string &Id, const std::string &Token, RTTY_Device_ConnectionHandler *Device) {
std::lock_guard G(M_);
auto It = EndPoints_.find(Id);
if(It!=EndPoints_.end()) {
It->second.Device = Device;
It->second.Token = Token;
It->second.DeviceConnected = OpenWifi::Now();
Logger().information(fmt::format("Creating session: {}, device:'{}'",Id,It->second.SerialNumber));
return true;
} catch(const Poco::Exception &E) {
Logger().log(E);
} catch (...) {
std::cout << "Exception in SendToClient 2" << std::endl;
}
return false;
}
void RTTYS_server::DeRegister(const std::string &Id, RTTY_Device_ConnectionHandler *Device) {
std::lock_guard G(M_);
bool RTTYS_server::ValidClient(const std::string &Id) {
std::shared_lock Guard(M_);
auto It = EndPoints_.find(Id);
if(It!=EndPoints_.end() && It->second.Device==Device) {
It->second.Device = nullptr;
It->second.DeviceConnected = 0 ;
return;
}
return It!=EndPoints_.end() && It->second->ValidClient();
}
bool RTTYS_server::SendKeyStrokes(const std::string &Id, const u_char *buffer, std::size_t s) {
std::lock_guard G(M_);
bool RTTYS_server::SendKeyStrokes(const std::string &Id, const u_char *buffer, std::size_t len) {
std::shared_lock Guard(M_);
auto It=EndPoints_.find(Id);
if(It==EndPoints_.end()) {
return false;
}
if(It->second.Device!= nullptr)
return It->second.Device->KeyStrokes(buffer,s);
try {
return It->second->KeyStrokes(buffer, len);
} catch(const Poco::Exception &E) {
Logger().log(E);
} catch (...) {
}
return false;
}
bool RTTYS_server::WindowSize(const std::string &Id, int cols, int rows) {
std::lock_guard G(M_);
std::shared_lock Guard(M_);
auto It=EndPoints_.find(Id);
if(It==EndPoints_.end()) {
return false;
}
if(It->second.Device!= nullptr)
return It->second.Device->WindowSize(cols,rows);
try {
return It->second->WindowSize(cols,rows);
} catch(const Poco::Exception &E) {
Logger().log(E);
} catch (...) {
}
return false;
}
bool RTTYS_server::CreateEndPoint(const std::string &Id, const std::string & Token, const std::string & UserName, const std::string & SerialNumber ) {
std::lock_guard G(M_);
std::unique_lock Guard(M_);
EndPoint E;
E.Done = false;
E.Token = Token;
E.TimeStamp = std::time(nullptr);
E.SerialNumber = SerialNumber;
E.UserName = UserName;
EndPoints_[Id] = E;
auto NewEP = std::make_unique<RTTYS_EndPoint>(Token, SerialNumber, UserName );
EndPoints_[Id] = std::move(NewEP);
++TotalEndPoints_;
return true;
}
std::string RTTYS_server::SerialNumber(const std::string & Id) {
std::lock_guard G(M_);
auto It = EndPoints_.find(Id);
if(It==EndPoints_.end())
return "";
return It->second.SerialNumber;
}
void RTTYS_server::LoginDone(const std::string & Id) {
std::lock_guard G(M_);
auto It = EndPoints_.find(Id);
if(It==EndPoints_.end())
return;
Logger().information(fmt::format("User: {}, Serial: {} logged in.",It->second.UserName, It->second.SerialNumber ));
}
bool RTTYS_server::ValidEndPoint(const std::string &Id, const std::string &Token) {
std::lock_guard G(M_);
auto It = EndPoints_.find(Id);
if(It==EndPoints_.end()) {
return false;
}
uint64_t Now = std::time(nullptr);
return ((It->second.Token == Token) && ((Now-It->second.TimeStamp)<30));
}
bool RTTYS_server::CanConnect( const std::string &Id, RTTYS_ClientConnection *Conn) {
std::lock_guard G(M_);
auto It = EndPoints_.find(Id);
if(It!=EndPoints_.end() && It->second.Client==Conn) {
It->second.ClientConnected = std::time(nullptr);
return true;
}
return false;
}
bool RTTYS_server::IsDeviceRegistered( const std::string &Id, const std::string &Token, [[maybe_unused]] RTTY_Device_ConnectionHandler *Conn) {
std::lock_guard G(M_);
auto It = EndPoints_.find(Id);
if(It == EndPoints_.end() || It->second.Token != Token )
return false;
return true;
}
uint64_t RTTYS_server::DeviceSessionID(const std::string & Id) {
auto it = EndPoints_.find(Id);
if(it==EndPoints_.end()) {
std::cout << "No ID found" << std::endl;
return 0;
} else {
if(it->second.Device== nullptr) {
std::cout << "No device for ID found" << std::endl;
return 0;
} else {
return it->second.Device->SessionID();
}
}
bool RTTYS_server::ValidId(const std::string &Token) {
std::shared_lock Guard(M_);
return EndPoints_.find(Token) != EndPoints_.end();
}
bool RTTYS_server::Login(const std::string & Id) {
std::lock_guard G(M_);
std::shared_lock Guard(M_);
auto It = EndPoints_.find(Id);
if(It == EndPoints_.end()) {
std::cout << "cannot find login " << Id << std::endl;
auto ep = EndPoints_.find(Id);
if(ep == EndPoints_.end()) {
return false;
}
if(It->second.Device!= nullptr) {
// std::cout << "login " << Id << " session " << It->second.Device->SessionID() << std::endl;
// It->second.Device->AddCommand(RTTY_Device_ConnectionHandler::msgTypeLogin);
// std::cout << "login done" << Id << std::endl;
return It->second.Device->Login();
try {
return ep->second->Login();
} catch(const Poco::Exception &E) {
Logger().log(E);
} catch (...) {
}
std::cout << "no device so cannot login " << Id << std::endl;
return false;
}
bool RTTYS_server::Logout(const std::string & Id) {
std::lock_guard G(M_);
auto It = EndPoints_.find(Id);
if(It == EndPoints_.end()) {
return false;
}
if(It->second.Device!= nullptr)
It->second.Device->Logout();
return true;
}
bool RTTYS_server::Close(const std::string & Id) {
std::lock_guard G(M_);
auto It = EndPoints_.find(Id);
if(It == EndPoints_.end()) {
return false;
}
if(It->second.Device!= nullptr)
It->second.Device->Stop();
return true;
}
}

View File

@@ -7,16 +7,205 @@
#include "framework/MicroService.h"
#include "Poco/Net/SocketReactor.h"
#include "Poco/Net/SocketAcceptor.h"
// #include "rttys/RTTYS_ClientConnection.h"
#include "Poco/Timer.h"
#include "rttys/RTTYS_device.h"
#include "rttys/RTTYS_ClientConnection.h"
#include <shared_mutex>
namespace OpenWifi {
class RTTY_Device_ConnectionHandler;
class RTTYS_Device_ConnectionHandler;
class RTTYS_ClientConnection;
class RTTYS_server : public SubSystemServer
template <typename T> class MutexLockerDbg {
public:
MutexLockerDbg(const std::string &name, T &L) :
name_(name),
L_(L)
{
std::cout << name_ << ":L:0:" << Poco::Thread::current()->name() << ":" << Poco::Thread::currentTid() << std::endl;
L_.lock();
std::cout << name_ << ":L:1:" << Poco::Thread::current()->name() << ":" << Poco::Thread::currentTid() << std::endl;
}
~MutexLockerDbg() {
std::cout << name_ << ":U:0:" << Poco::Thread::current()->name() << ":" << Poco::Thread::currentTid() << std::endl;
L_.unlock();
std::cout << name_ << ":U:1:" << Poco::Thread::current()->name() << ":" << Poco::Thread::currentTid() << std::endl;
}
private:
std::string name_;
T & L_;
};
enum class RTTYS_Notification_type {
unknown,
device_disconnection,
client_disconnection,
client_registration,
device_registration
};
class RTTYS_Notification: public Poco::Notification {
public:
RTTYS_Notification(const RTTYS_Notification_type &type, const std::string &id,
RTTYS_Device_ConnectionHandler * device) :
type_(type),
id_(id),
device_(device) {
}
RTTYS_Notification(const RTTYS_Notification_type &type, const std::string &id,
RTTYS_ClientConnection * client) :
type_(type),
id_(id),
client_(client) {
}
RTTYS_Notification(const RTTYS_Notification_type &type,
const std::string &id,
const std::string &token,
RTTYS_Device_ConnectionHandler * device) :
type_(type),
id_(id),
token_(token),
device_(device) {
}
RTTYS_Notification_type type_=RTTYS_Notification_type::unknown;
std::string id_;
std::string token_;
RTTYS_Device_ConnectionHandler *device_= nullptr;
RTTYS_ClientConnection *client_ = nullptr;
};
class RTTYS_EndPoint {
public:
RTTYS_EndPoint(const std::string &Token, const std::string &SerialNumber, const std::string &UserName ):
Token_(Token),
SerialNumber_(SerialNumber),
UserName_(UserName)
{
Created_ = std::chrono::high_resolution_clock::now();
}
inline void SetClient(std::unique_ptr<RTTYS_ClientConnection> Client) {
ClientConnected_ = std::chrono::high_resolution_clock::now();
Client_ = std::move(Client);
}
inline void SetDevice(std::unique_ptr<RTTYS_Device_ConnectionHandler> Device) {
DeviceConnected_ = std::chrono::high_resolution_clock::now();
Device_ = std::move(Device);
}
inline bool Login() {
if(Device_!= nullptr) {
return Device_->Login();
}
return false;
}
RTTYS_EndPoint & operator=(RTTYS_EndPoint Other) {
Other.Client_ = std::move(Client_);
Other.Device_ = std::move(Device_);
return *this;
}
inline void DisconnectClient() {
ClientDisconnected_ = std::chrono::high_resolution_clock::now();
}
inline void DisconnectDevice() {
DeviceDisconnected_ = std::chrono::high_resolution_clock::now();
}
[[nodiscard]] inline bool TooOld() {
std::chrono::time_point<std::chrono::high_resolution_clock> now = std::chrono::high_resolution_clock::now();
if(ClientDisconnected_!=std::chrono::time_point<std::chrono::high_resolution_clock>{0s} && (now-ClientDisconnected_)>15s) {
if(DeviceDisconnected_==std::chrono::time_point<std::chrono::high_resolution_clock>{0s}) {
DeviceDisconnected_ = std::chrono::high_resolution_clock::now();
}
return true;
}
if(DeviceDisconnected_!=std::chrono::time_point<std::chrono::high_resolution_clock>{0s} && (now-DeviceDisconnected_)>15s) {
if(ClientDisconnected_==std::chrono::time_point<std::chrono::high_resolution_clock>{0s}) {
ClientDisconnected_ = std::chrono::high_resolution_clock::now();
}
return true;
}
if(!Joined_ && (now-Created_)>30s) {
return true;
}
// std::cout << ClientDisconnected_ << " " << ClientConnected_ << " " << DeviceDisconnected_ << " " << DeviceConnected_ << std::endl;
return false;
}
bool SendToClient(const u_char *Buf, std::size_t Len) {
if(Client_!= nullptr && Client_->Valid()) {
Client_->SendData(Buf,Len);
return true;
}
std::cout << "SendToClientFailure: " << (Client_!= nullptr) << " " << Client_->Valid() << std::endl;
return false;
}
inline bool KeyStrokes(const u_char *buffer, std::size_t len) {
if( Device_!= nullptr && Device_->Valid() )
return Device_->KeyStrokes(buffer,len);
return false;
}
inline bool WindowSize( int cols, int rows) {
if(Device_!= nullptr && Device_->Valid())
return Device_->WindowSize(cols,rows);
return false;
}
[[nodiscard]] inline bool ValidClient() const {
return Client_!= nullptr && Client_->Valid();
}
[[nodiscard]] inline bool ValidDevice() const {
return Device_!= nullptr && Device_->Valid();
}
[[nodiscard]] inline bool Joined() volatile const { return Joined_; }
void Join() {
Joined_=true;
}
inline bool SendToClient(const std::string &S) {
if(Client_!= nullptr && Client_->Valid()) {
Client_->SendData(S);
return true;
}
return false;
}
[[nodiscard]] inline const std::string & UserName() const { return UserName_; }
[[nodiscard]] inline const std::string & SerialNumber() const { return SerialNumber_; }
[[nodiscard]] inline auto TimeDeviceConnected() const { return std::chrono::duration<double>{DeviceDisconnected_ - DeviceConnected_}.count(); }
[[nodiscard]] inline auto TimeClientConnected() const { return std::chrono::duration<double>{ClientDisconnected_ - ClientConnected_}.count(); }
private:
std::string Token_;
std::string SerialNumber_;
std::string UserName_;
std::unique_ptr<RTTYS_ClientConnection> Client_;
std::unique_ptr<RTTYS_Device_ConnectionHandler> Device_;
std::string Id_;
std::chrono::time_point<std::chrono::high_resolution_clock>
Created_{0s},DeviceDisconnected_{0s},
ClientDisconnected_{0s},DeviceConnected_{0s} ,ClientConnected_{0s};
volatile bool Joined_=false;
};
class RTTYS_server : public SubSystemServer, Poco::Runnable
{
public:
static auto instance() {
@@ -29,51 +218,71 @@ namespace OpenWifi {
inline auto UIAssets() { return RTTY_UIAssets_; }
void Register(const std::string &Id, RTTYS_ClientConnection *Client);
void DeRegister(const std::string &Id, RTTYS_ClientConnection *Client);
bool Register(const std::string &Id, const std::string &Token, RTTY_Device_ConnectionHandler *Device);
void DeRegister(const std::string &Id, RTTY_Device_ConnectionHandler *Device);
bool CreateEndPoint(const std::string &Id, const std::string & Token, const std::string & UserName, const std::string & SerialNumber );
std::string SerialNumber(const std::string & Id);
void LoginDone(const std::string & Id);
bool ValidEndPoint(const std::string &Id, const std::string &Token);
bool CanConnect( const std::string &Id, RTTYS_ClientConnection *Conn);
bool IsDeviceRegistered( const std::string &Id, const std::string &Token, [[maybe_unused]] RTTY_Device_ConnectionHandler *Conn);
bool Login(const std::string & Id_);
bool Logout(const std::string & Id_);
bool Close(const std::string & Id_);
uint64_t DeviceSessionID(const std::string & Id);
bool SendKeyStrokes(const std::string &Id, const u_char *buffer, std::size_t s);
bool WindowSize(const std::string &Id, int cols, int rows);
bool SendToClient(const std::string &id, const u_char *Buf, std::size_t Len);
bool SendToClient(const std::string &id, const std::string &s);
bool ValidClient(const std::string &id);
bool ValidId(const std::string &Id);
struct EndPoint {
std::string Token;
RTTYS_ClientConnection * Client = nullptr;
RTTY_Device_ConnectionHandler * Device = nullptr;
uint64_t TimeStamp = std::time(nullptr);
uint64_t DeviceConnected = 0;
uint64_t ClientConnected = 0;
std::string UserName;
std::string SerialNumber;
bool Done = false;
};
void run() final;
inline void NotifyDeviceDisconnect(const std::string &id, RTTYS_Device_ConnectionHandler *device) {
ResponseQueue_.enqueueNotification(new RTTYS_Notification(RTTYS_Notification_type::device_disconnection,id,device));
}
inline void NotifyClientDisconnect(const std::string &id, RTTYS_ClientConnection *client) {
ResponseQueue_.enqueueNotification(new RTTYS_Notification(RTTYS_Notification_type::client_disconnection,id,client));
}
inline void NotifyDeviceRegistration(const std::string &id, const std::string &token, RTTYS_Device_ConnectionHandler *device) {
ResponseQueue_.enqueueNotification(new RTTYS_Notification(RTTYS_Notification_type::device_registration,id,token,device));
}
inline void NotifyClientRegistration(const std::string &id, RTTYS_ClientConnection *client) {
ResponseQueue_.enqueueNotification(new RTTYS_Notification(RTTYS_Notification_type::client_registration,id,client));
}
void CreateNewClient(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response, const std::string &id);
void onTimer(Poco::Timer & timer);
inline bool UseInternal() const {
return Internal_;
}
private:
std::recursive_mutex M_;
Poco::Net::SocketReactor ClientReactor_;
Poco::Thread ClientReactorThread_;
std::string RTTY_UIAssets_;
std::atomic_bool Internal_ = false;
inline Poco::Net::SocketReactor & ClientReactor() { return ClientReactor_; }
private:
Poco::Net::SocketReactor ClientReactor_;
Poco::Net::SocketReactor DeviceReactor_;
Poco::Thread ClientReactorThread_;
std::string RTTY_UIAssets_;
bool Internal_ = false;
std::map<std::string,std::unique_ptr<RTTYS_EndPoint>> EndPoints_; // id, endpoint
std::unique_ptr<Poco::Net::HTTPServer> WebServer_;
std::unique_ptr<Poco::Net::SocketAcceptor<RTTYS_Device_ConnectionHandler>> DeviceAcceptor_;
Poco::Thread DeviceReactorThread_;
Poco::NotificationQueue ResponseQueue_;
mutable bool NotificationManagerRunning_=false;
Poco::Thread NotificationManager_;
Poco::Timer Timer_;
std::unique_ptr<Poco::TimerCallback<RTTYS_server>> GCCallBack_;
std::list<std::unique_ptr<RTTYS_Device_ConnectionHandler>> FailedDevices;
std::list<std::unique_ptr<RTTYS_ClientConnection>> FailedClients;
mutable std::shared_mutex M_;
uint64_t TotalEndPoints_=0;
uint64_t FaildedNumDevices_=0;
uint64_t FailedNumClients_=0;
double TotalConnectedDeviceTime_=0.0;
double TotalConnectedClientTime_=0.0;
std::map<std::string, EndPoint> EndPoints_; // id, endpoint
std::unique_ptr<Poco::Net::HTTPServer> WebServer_;
std::unique_ptr<Poco::Net::TCPServer> DeviceAcceptor_;
explicit RTTYS_server() noexcept:
SubSystemServer("RTTY_Server", "RTTY-SVR", "rtty.server")

View File

@@ -20,7 +20,7 @@ bool Storage::CreateDeviceCapabilities(std::string &SerialNumber, std::string &C
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement UpSert(Sess);
uint64_t Now = std::time(nullptr);
uint64_t Now = OpenWifi::Now();
std::string St{ "insert into Capabilities (SerialNumber, Capabilities, FirstUpdate, LastUpdate) values(?,?,?,?) on conflict (SerialNumber) do "
" update set Capabilities=?, LastUpdate=?"};
UpSert << ConvertParams(St),
@@ -44,7 +44,7 @@ bool Storage::CreateDeviceCapabilities(std::string &SerialNumber, std::string &C
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement UpSert(Sess);
uint64_t Now = std::time(nullptr);
uint64_t Now = OpenWifi::Now();
OpenWifi::Config::Capabilities Caps(Capabilities);
Compat = Caps.Compatible();
if(!Caps.Compatible().empty() && !Caps.Platform().empty())

View File

@@ -202,8 +202,6 @@ typedef Poco::Tuple<
std::string FullQuery = IntroStatement + DateSelector +
" ORDER BY Submitted ASC " + ComputeRange(Offset, HowMany);
// std::cout << "Offset: " << Offset << " >> " << FullQuery << std::endl;
Select << FullQuery,
Poco::Data::Keywords::into(Records);
Select.execute();
@@ -396,7 +394,7 @@ typedef Poco::Tuple<
}
return true;
} catch (const Poco::Exception &E) {
Logger().warning(fmt::format("{}: Failed with: {}", std::string(__func__), E.displayText()));
Logger().log(E);
}
return false;
}
@@ -430,7 +428,7 @@ typedef Poco::Tuple<
}
return true;
} catch (const Poco::Exception &E) {
Logger().warning(fmt::format("{}: Failed with: {}", std::string(__func__), E.displayText()));
Logger().log(E);
}
return false;
}
@@ -451,7 +449,7 @@ typedef Poco::Tuple<
return true;
} catch (const Poco::Exception &E) {
Logger().warning(fmt::format("{}: Failed with: {}", std::string(__func__), E.displayText()));
Logger().log(E);
}
return false;
@@ -503,7 +501,7 @@ typedef Poco::Tuple<
return true;
} catch (const Poco::Exception &E) {
Logger().warning(fmt::format("{}: Failed with: {}", std::string(__func__), E.displayText()));
Logger().log(E);
}
return false;
@@ -536,16 +534,81 @@ typedef Poco::Tuple<
}
bool Storage::AttachFileToCommand(std::string &UUID) {
/* bool Storage::AttachFileToCommand(std::string &UUID) {
try {
Poco::Data::Session Sess = Pool_->get();
uint64_t Now = time(nullptr);
uint64_t Now = OpenWifi::Now();
uint64_t WaitForFile = 0;
Poco::Data::Statement Update(Sess);
std::cout << __LINE__ << std::endl;
Poco::File FileName = FileUploader()->Path() + "/" + UUID;
std::cout << __LINE__ << std::endl;
uint64_t Size = FileName.getSize();
std::cout << __LINE__ << std::endl;
std::string St{
"UPDATE CommandList SET WaitingForFile=?, AttachDate=?, AttachSize=? WHERE UUID=?"};
std::cout << __LINE__ << std::endl;
Update << ConvertParams(St),
Poco::Data::Keywords::use(WaitForFile),
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Size),
Poco::Data::Keywords::use(UUID);
Update.execute();
std::cout << __LINE__ << std::endl;
if (FileName.getSize() < FileUploader()->MaxSize()) {
Poco::Data::BLOB TheBlob;
std::cout << __LINE__ << std::endl;
std::ifstream f(FileName.path(), std::ios::binary);
std::ostringstream SS;
Poco::StreamCopier::copyStream(f, SS);
TheBlob.appendRaw((const unsigned char *)SS.str().c_str(),SS.str().size());
std::cout << "Attach file size: " << SS.str().size() << std::endl;
std::cout << __LINE__ << std::endl;
Poco::Data::Statement Insert(Sess);
std::string FileType{"trace"};
std::cout << __LINE__ << std::endl;
std::string St2{
"INSERT INTO FileUploads (UUID,Type,Created,FileContent) VALUES(?,?,?,?)"};
std::cout << __LINE__ << std::endl;
Insert << ConvertParams(St2), Poco::Data::Keywords::use(UUID),
Poco::Data::Keywords::use(FileType),
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(TheBlob);
Insert.execute();
std::cout << __LINE__ << std::endl;
FileName.remove();
return true;
} else {
Logger().warning(fmt::format("File {} is too large.", FileName.path()));
}
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
*/
bool Storage::AttachFileDataToCommand(std::string & UUID, const std::stringstream & FileContent) {
try {
Poco::Data::Session Sess = Pool_->get();
uint64_t Now = OpenWifi::Now();
uint64_t WaitForFile = 0;
Poco::Data::Statement Update(Sess);
Poco::File FileName = FileUploader()->Path() + "/" + UUID;
uint64_t Size = FileName.getSize();
uint64_t Size = FileContent.str().size();
std::string St{
"UPDATE CommandList SET WaitingForFile=?, AttachDate=?, AttachSize=? WHERE UUID=?"};
@@ -557,19 +620,12 @@ typedef Poco::Tuple<
Poco::Data::Keywords::use(UUID);
Update.execute();
Poco::Data::LOB<char> L;
Poco::Data::LOBOutputStream OL(L);
if (Size < FileUploader()->MaxSize()) {
if (FileName.getSize() < FileUploader()->MaxSize()) {
Poco::Data::BLOB TheBlob;
TheBlob.appendRaw((const unsigned char *)FileContent.str().c_str(),FileContent.str().size());
std::ifstream f(FileName.path(), std::ios::binary);
Poco::StreamCopier::copyStream(f, OL);
/*
"UUID VARCHAR(64) PRIMARY KEY, "
"Type VARCHAR(32), "
"Created BIGINT, "
"FileContent BYTEA"
*/
Poco::Data::Statement Insert(Sess);
std::string FileType{"trace"};
@@ -579,30 +635,21 @@ typedef Poco::Tuple<
Insert << ConvertParams(St2), Poco::Data::Keywords::use(UUID),
Poco::Data::Keywords::use(FileType),
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(L);
Poco::Data::Keywords::use(TheBlob);
Insert.execute();
FileName.remove();
return true;
} else {
Logger().warning(fmt::format("File {} is too large.", FileName.path()));
Logger().warning(fmt::format("File {} is too large.", UUID));
}
} catch (const Poco::Exception &E) {
Logger().warning(fmt::format("{}: Failed with: {}", std::string(__func__), E.displayText()));
Logger().log(E);
}
return false;
}
bool Storage::GetAttachedFile(std::string &UUID, const std::string & SerialNumber, const std::string &FileName, std::string &Type) {
/* bool Storage::GetAttachedFile(std::string &UUID, const std::string & SerialNumber, const std::string &FileName, std::string &Type) {
try {
Poco::Data::LOB<char> L;
/*
"UUID VARCHAR(64) PRIMARY KEY, "
"Type VARCHAR(32), "
"Created BIGINT, "
"FileContent BYTEA"
*/
Poco::Data::BLOB L;
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select1(Sess);
@@ -626,10 +673,55 @@ typedef Poco::Tuple<
Poco::Data::Keywords::use(UUID);
Select2.execute();
Poco::Data::LOBInputStream IL(L);
std::ofstream f(FileName, std::ios::binary);
Poco::StreamCopier::copyStream(IL, f);
// Poco::Data::BLOBInputStream IL(L);
std::ofstream f(FileName, std::ios::binary | std::ios::trunc );
auto Content = L.content();
std::string SS(L.content().begin(),L.content().end());
f << SS;
std::cout << "Get Attach Size: " << L.content().size() << std::endl;
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
*/
bool Storage::GetAttachedFileContent(std::string &UUID, const std::string & SerialNumber, std::string &FileContent, std::string &Type) {
try {
Poco::Data::BLOB L;
/*
"UUID VARCHAR(64) PRIMARY KEY, "
"Type VARCHAR(32), "
"Created BIGINT, "
"FileContent BYTEA"
*/
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select1(Sess);
std::string TmpSerialNumber;
std::string st1{"SELECT SerialNumber FROM CommandList WHERE UUID=?"};
Select1 << ConvertParams(st1),
Poco::Data::Keywords::into(TmpSerialNumber),
Poco::Data::Keywords::use(UUID);
Select1.execute();
if(TmpSerialNumber!=SerialNumber) {
return false;
}
std::string St2{"SELECT FileContent, Type FROM FileUploads WHERE UUID=?"};
Poco::Data::Statement Select2(Sess);
Select2 << ConvertParams(St2),
Poco::Data::Keywords::into(L),
Poco::Data::Keywords::into(Type),
Poco::Data::Keywords::use(UUID);
Select2.execute();
FileContent.assign(L.content().begin(),L.content().end());
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -651,7 +743,7 @@ typedef Poco::Tuple<
return true;
} catch (const Poco::Exception &E) {
Logger().warning(fmt::format("{}: Failed with: {}", std::string(__func__), E.displayText()));
Logger().log(E);
}
return false;
}
@@ -709,7 +801,7 @@ typedef Poco::Tuple<
}
return true;
} catch(const Poco::Exception &E) {
Logger().warning(fmt::format("{}: Failed with: {}", std::string(__func__), E.displayText()));
Logger().log(E);
}
return false;
}

View File

@@ -66,7 +66,7 @@ namespace OpenWifi {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
std::string St{"SELECT FROM DefaultConfigs WHERE Name=?"};
std::string St{"SELECT name FROM DefaultConfigs WHERE Name=?"};
Select << ConvertParams(St) ,
Poco::Data::Keywords::into(TmpName) ,
Name;

View File

@@ -46,7 +46,7 @@ namespace OpenWifi {
"subscriber, "
"entity, "
"modified, "
"locale "
"locale"
};
const static std::string DB_DeviceUpdateFields{
@@ -169,12 +169,16 @@ namespace OpenWifi {
return false;
}
bool Storage::GetDeviceSerialNumbers(uint64_t From, uint64_t HowMany, std::vector<std::string> &SerialNumbers) {
bool Storage::GetDeviceSerialNumbers(uint64_t From, uint64_t HowMany, std::vector<std::string> &SerialNumbers, const std::string & orderBy) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
std::string st{"SELECT SerialNumber From Devices ORDER BY SerialNumber ASC " };
std::string st;
if(orderBy.empty())
st = "SELECT SerialNumber From Devices ORDER BY SerialNumber ASC ";
else
st = "SELECT SerialNumber From Devices " + orderBy;
Select << st + ComputeRange(From, HowMany),
Poco::Data::Keywords::into(SerialNumbers);
@@ -244,7 +248,7 @@ namespace OpenWifi {
if (Select.rowsExtracted()==0) {
Config::Config Cfg(DeviceDetails.Configuration);
uint64_t Now = std::time(nullptr);
uint64_t Now = OpenWifi::Now();
DeviceDetails.modified = OpenWifi::Now();
DeviceDetails.CreationTimestamp = DeviceDetails.LastConfigurationDownload =
@@ -351,7 +355,7 @@ namespace OpenWifi {
D.MACAddress = Utils::SerialToMAC(SerialNumber);
D.Manufacturer = Caps.Model();
D.Firmware = Firmware;
D.Notes = SecurityObjects::NoteInfoVec { SecurityObjects::NoteInfo{ (uint64_t)std::time(nullptr), "", "Auto-provisioned."}};
D.Notes = SecurityObjects::NoteInfoVec { SecurityObjects::NoteInfo{ (uint64_t)OpenWifi::Now(), "", "Auto-provisioned."}};
CreateDeviceCapabilities(SerialNumber, Capabilities);
@@ -410,7 +414,7 @@ namespace OpenWifi {
if(TmpFirmware != Firmware) {
Poco::Data::Statement Update(Sess);
std::string St2{"UPDATE Devices SET Firmware=?, LastFWUpdate=? WHERE SerialNumber=?"};
uint64_t Now = std::time(nullptr);
uint64_t Now = OpenWifi::Now();
Update << ConvertParams(St2),
Poco::Data::Keywords::use(Firmware),
@@ -522,7 +526,7 @@ namespace OpenWifi {
NewDeviceDetails.modified = OpenWifi::Now();
ConvertDeviceRecord(NewDeviceDetails,R);
// NewDeviceDetails.LastConfigurationChange = std::time(nullptr);
// NewDeviceDetails.LastConfigurationChange = OpenWifi::Now();
std::string St2{"UPDATE Devices SET " +
DB_DeviceUpdateFields +
" WHERE SerialNumber=?"};
@@ -539,13 +543,19 @@ namespace OpenWifi {
return false;
}
bool Storage::GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices) {
bool Storage::GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices, const std::string & orderBy) {
DeviceRecordList Records;
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
std::string st{"SELECT " + DB_DeviceSelectFields + " FROM Devices ORDER BY SerialNumber ASC " + ComputeRange(From, HowMany)};
// std::string st{"SELECT " + DB_DeviceSelectFields + " FROM Devices " + orderBy.empty() ? " ORDER BY SerialNumber ASC " + ComputeRange(From, HowMany)};
std::string st = fmt::format("SELECT {} FROM Devices {} {}",
DB_DeviceSelectFields,
orderBy.empty() ? " ORDER BY SerialNumber ASC " : orderBy ,
ComputeRange(From, HowMany));
Select << ConvertParams(st),
Poco::Data::Keywords::into(Records);
Select.execute();
@@ -645,7 +655,7 @@ namespace OpenWifi {
static const uint64_t SECONDS_HOUR = 60*60;
static std::string ComputeUpLastContactTag(uint64_t T1) {
uint64_t T = T1 - std::time(nullptr);
uint64_t T = T1 - OpenWifi::Now();
if( T>SECONDS_MONTH) return ">month";
if( T>SECONDS_WEEK) return ">week";
if( T>SECONDS_DAY) return ">day";
@@ -677,8 +687,10 @@ namespace OpenWifi {
return ">75%";
}
static std::string ComputeFreeMemoryTag(uint64_t Free, uint64_t Total) {
auto V = 100.0 * ((float)Free/(float(Total)));
static std::string ComputeUsedMemoryTag(uint64_t Free, uint64_t Total) {
if(Total==0)
return "< 5%";
auto V = 100.0 * ((float)(Total-Free)/(float(Total)));
if(V<5.0) return "< 5%";
if(V<25.0) return "< 25%";
if(V<50.0) return "< 50%";
@@ -735,7 +747,7 @@ namespace OpenWifi {
auto Memory = Unit->getObject("memory");
uint64_t Free = Memory->get("free");
uint64_t Total = Memory->get("total");
UpdateCountedMap(Dashboard.memoryUsed, ComputeFreeMemoryTag(Free, Total));
UpdateCountedMap(Dashboard.memoryUsed, ComputeUsedMemoryTag(Free, Total));
}
if (Unit->has("load")) {
auto Load = Unit->getArray("load");
@@ -765,5 +777,12 @@ namespace OpenWifi {
}
return false;
}
void Storage::GetDeviceDbFieldList( Types::StringVec & FieldList) {
const auto fields = Poco::StringTokenizer(DB_DeviceSelectFields,",",Poco::StringTokenizer::TOK_TRIM);
for(const auto &field:fields)
FieldList.push_back(field);
}
}

View File

@@ -41,7 +41,7 @@ namespace OpenWifi {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Insert(Sess);
Logger().information("Device:" + Stats.SerialNumber + " Stats size:" + std::to_string(Stats.Data.size()));
poco_debug(Logger(),"Device:" + Stats.SerialNumber + " Stats size:" + std::to_string(Stats.Data.size()));
std::string St{"INSERT INTO Statistics ( " +
DB_StatsSelectFields +
" ) VALUES ( " +

View File

@@ -0,0 +1,54 @@
{
"pools": [
{
"acctConfig": {
"methodParameters": [],
"monitor": false,
"monitorMethod": "none",
"servers": [
{
"ip": "69.157.193.71",
"name": "svr1",
"port": 1813,
"weight": 10,
"secret": "testing123"
}
],
"strategy": "random"
},
"authConfig": {
"methodParameters": [],
"monitor": false,
"monitorMethod": "none",
"servers": [
{
"ip": "69.157.193.71",
"name": "svr1",
"port": 1812,
"weight": 10,
"secret": "testing123"
}
],
"strategy": "weighted"
},
"coaConfig": {
"methodParameters": [],
"monitor": false,
"monitorMethod": "none",
"servers": [
{
"ip": "69.157.193.71",
"name": "svr1",
"port": 3799,
"weight": 10,
"secret": "testing123"
}
],
"strategy": "round_robin"
},
"description": "master pool",
"name": "master",
"useByDefault" : true
}
]
}

View File

@@ -0,0 +1,89 @@
{
"pools" :
[
{
"name" : "pool1_name",
"description" : "This is the big pool 1",
"authPolicy" : "weighted",
"acctPolicy" : "round-robin",
"authMonitor" : true ,
"authMonitorMethod" : {
},
"acctMonitor" : false,
"authServers" : [{
"name" : "server 1 in pool 1",
"ip" : "1.2.3.4",
"port" : 1812,
"weight" : 50
},
{
"name" : "server 2 in pool 1",
"ip" : "1.2.3.5",
"port" : 1812,
"weight" : 25
},
{
"name" : "server 3 in pool 1",
"ip" : "1.2.3.6",
"port" : 1812,
"weight" : 25
}
],
"acctServers" : [{
"name" : "server 1 in pool 1",
"ip" : "1.2.3.4",
"port" : 1813
},
{
"name" : "server 2 in pool 1",
"ip" : "1.2.3.5",
"port" : 1813
},
{
"name" : "server 3 in pool 1",
"ip" : "1.2.3.6",
"port" : 1813
}
]
},
{
"name" : "pool2_name",
"description" : "This is the big pool 2",
"authServers" : [{
"name" : "server 1 in pool 2",
"ip" : "1.2.4.4",
"port" : 1812
},
{
"name" : "server 2 in pool 2",
"ip" : "1.2.4.5",
"port" : 1812
},
{
"name" : "server 3 in pool 2",
"ip" : "1.2.4.6",
"port" : 1812
}
],
"acctServers" : [{
"name" : "server 1 in pool 2",
"ip" : "1.2.4.4",
"port" : 1813,
"weight" : 25
},
{
"name" : "server 2 in pool 2",
"ip" : "1.2.4.5",
"port" : 1813,
"weight" : 25
},
{
"name" : "server 3 in pool 2",
"ip" : "1.2.4.6",
"port" : 1813,
"weight" : 25
}
]
}
]
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,54 @@
{
"pools": [
{
"acctConfig": {
"methodParameters": [],
"monitor": false,
"monitorMethod": "none",
"servers": [
{
"ip": "69.157.193.71",
"name": "svr1",
"port": 1813,
"weight": 10,
"secret": "testing123"
}
],
"strategy": "random"
},
"authConfig": {
"methodParameters": [],
"monitor": false,
"monitorMethod": "none",
"servers": [
{
"ip": "69.157.193.71",
"name": "svr1",
"port": 1812,
"weight": 10,
"secret": "testing123"
}
],
"strategy": "weighted"
},
"coaConfig": {
"methodParameters": [],
"monitor": false,
"monitorMethod": "none",
"servers": [
{
"ip": "69.157.193.71",
"name": "svr1",
"port": 3799,
"weight": 10,
"secret": "testing123"
}
],
"strategy": "round_robin"
},
"description": "master pool",
"name": "master",
"useByDefault" : true
}
]
}

View File

@@ -0,0 +1,50 @@
{
"pools" : [
{
"name" : "master" ,
"description" : "master pool",
"authConfig" : {
"strategy" : "weighted",
"monitor" : false,
"monitorMethod" : "none",
"methodParameters" : [],
"servers" : [ {
"name" : "svr1",
"ip" : "69.157.193.71",
"port" : 1812,
"weight" : 10,
"secret" : "my_secret!"
}
]
},
"acctConfig" : {
"strategy" : "random",
"monitor" : false,
"monitorMethod" : "none",
"methodParameters" : [],
"servers" : [ {
"name" : "svr1",
"ip" : "69.157.193.71",
"port" : 1813,
"weight" : 10,
"secret" : "my_secret!"
}
]
},
"coaConfig" : {
"strategy" : "round_robin",
"monitor" : false,
"monitorMethod" : "none",
"methodParameters" : [],
"servers" : [ {
"name" : "svr1",
"ip" : "69.157.193.71",
"port" : 3799,
"weight" : 10,
"secret" : "my_secret!"
}
]
}
}
]
}

Some files were not shown because too many files have changed in this diff Show More