Compare commits

...

227 Commits

Author SHA1 Message Date
Automation User - kinaraauto
5cb4325ae0 chore: updated package.json, updated helm/Chart.yaml, updated helm/values.yaml, updated CMakeLists.txt, updated version, created CHANGELOG.md, bumped 3.0.2 -> 3.0.3 2024-06-19 12:07:08 +00:00
Adam Capparelli
1042487e65 Merge pull request #6 from kinarasystems/devices
includeProvisioned flag is now checked for countOnly.
2024-06-19 08:06:51 -04:00
Adam Capparelli
dacb903046 includeProvisioned flag is now checked for countOnly.
Signed-off-by: Adam Capparelli <adam.capparelli@mail.utoronto.ca>
2024-06-19 07:56:18 -04:00
Carsten Schafer
a092912dd5 GH version bump and building changes 2024-06-11 16:29:20 -04:00
Adam Capparelli
30c093f820 Merge pull request #5 from kinarasystems/rbac
Remove whitelisted APIs.
2024-06-03 08:27:58 -04:00
Adam Capparelli
b61016d593 Remove whitelisted APIs.
Signed-off-by: Adam Capparelli <adam.capparelli@mail.utoronto.ca>
2024-06-03 08:17:44 -04:00
Adam Capparelli
7cf9e4da72 Remove whitelisted APIs.
Signed-off-by: Adam Capparelli <adam.capparelli@mail.utoronto.ca>
2024-06-03 08:02:12 -04:00
Adam Capparelli
d6637427f7 Merge pull request #4 from kinarasystems/rbac
Implement simple RBAC with whitelist
2024-05-29 08:38:28 -04:00
Adam Capparelli
a9fd0280dd Add Simple RBAC for owgw.
Signed-off-by: Adam Capparelli <adam.capparelli@mail.utoronto.ca>
2024-05-29 08:04:23 -04:00
i-chvets
4671047add Merge branch 'Telecominfraproject:master' into kinara 2024-05-21 15:22:12 -04:00
Stephane Bourque
26a89f3eb5 Merge pull request #347 from kinarasystems/wifi_13539_feat_devices_api
WIFI-13539 Feat: devices api update to include preprovisioned
2024-03-26 22:06:26 -07:00
Bhavesh Patel
b055711993 adding includeProvisioned parameter to GET devices REST call to get non provisioned APs easily
Signed-off-by: Bhavesh Patel <bhavesh.patel@kinarasystems.com>
2024-03-21 14:42:08 -04:00
Bhavesh Patel
fcdb7423ef adding nonProvisioned parameter to GET devices API call
Signed-off-by: Bhavesh Patel <bhavesh.patel@kinarasystems.com>
2024-03-21 14:18:34 -04:00
i-chvets
51ee3f1de2 Merge branch 'Telecominfraproject:master' into kinara 2024-03-21 14:09:14 -04:00
Stephane Bourque
f286d5fb48 Merge pull request #344 from Telecominfraproject/WIFI-12939
WIFI-12939: change to TIP repos for libraries
2024-03-19 13:03:35 -07:00
Stephane Bourque
0d70601c64 Merge pull request #346 from Telecominfraproject/WIFI-13522
https://telecominfraproject.atlassian.net/browse/WIFI-13522
2024-03-19 13:01:41 -07:00
stephb9959
a493defc99 https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 12:55:54 -07:00
stephb9959
fb3e1288ae https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 12:53:36 -07:00
stephb9959
ce52e05104 https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 12:28:01 -07:00
stephb9959
920b922121 https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 11:57:36 -07:00
stephb9959
3732cfd07e https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 10:55:41 -07:00
stephb9959
9e772b8c91 https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 10:46:28 -07:00
stephb9959
92252d09dc https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 10:45:18 -07:00
stephb9959
28636c3e1e https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 10:16:00 -07:00
Stephane Bourque
8e44f1e85c Merge pull request #345 from Telecominfraproject/WIFI-13507
https://telecominfraproject.atlassian.net/browse/WIFI-13507
2024-03-15 23:26:27 -07:00
stephb9959
b77d40fbf8 https://telecominfraproject.atlassian.net/browse/WIFI-13507
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-15 23:23:13 -07:00
Stephane Bourque
574172b8bf Merge pull request #343 from Telecominfraproject/WIFI-13507
https://telecominfraproject.atlassian.net/browse/WIFI-13507
2024-03-15 09:06:19 -07:00
stephb9959
794b31591d https://telecominfraproject.atlassian.net/browse/WIFI-13507
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-15 09:05:21 -07:00
Stephane Bourque
66aee07105 Merge pull request #342 from Telecominfraproject/WIFI-13507
https://telecominfraproject.atlassian.net/browse/WIFI-13507
2024-03-15 08:49:08 -07:00
stephb9959
86685f17d6 https://telecominfraproject.atlassian.net/browse/WIFI-13507
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-15 08:48:13 -07:00
Stephane Bourque
08f683c15a Merge pull request #341 from Telecominfraproject/WIFI-13507
https://telecominfraproject.atlassian.net/browse/WIFI-13507
2024-03-15 08:06:50 -07:00
stephb9959
7fea477f55 https://telecominfraproject.atlassian.net/browse/WIFI-13507
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-15 08:05:20 -07:00
Stephane Bourque
f22b3e3995 Merge pull request #340 from Telecominfraproject/WIFI-13507
https://telecominfraproject.atlassian.net/browse/WIFI-13507
2024-03-15 08:00:48 -07:00
stephb9959
3a1011a662 https://telecominfraproject.atlassian.net/browse/WIFI-13507
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-14 22:54:59 -07:00
stephb9959
6595b37ae4 https://telecominfraproject.atlassian.net/browse/WIFI-13507
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-14 22:38:52 -07:00
stephb9959
05b6a9474b https://telecominfraproject.atlassian.net/browse/WIFI-13507
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-14 22:26:31 -07:00
Carsten Schafer
1de94be447 WIFI-12939: change to TIP repos for libraries
Signed-off-by: Carsten Schafer <Carsten.Schafer@kinarasystems.com>
2024-03-14 15:11:23 -04:00
Stephane Bourque
aa8486c71b Merge pull request #339 from Telecominfraproject/WIFI-13447
https://telecominfraproject.atlassian.net/browse/WIFI-13447
2024-03-13 14:19:32 -07:00
stephb9959
e75d3cfdbb https://telecominfraproject.atlassian.net/browse/WIFI-13447
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-13 14:07:10 -07:00
bhaveshpatel88
9825685a75 Merge pull request #2 from kinarasystems/devices_api
Devices api
2024-03-06 17:34:14 -05:00
Bhavesh Patel
13883fb9ed adding includeProvisioned parameter to GET devices REST call to get non provisioned APs easily 2024-03-06 17:05:29 -05:00
Bhavesh Patel
37b1c96691 Merge remote-tracking branch 'origin/kinara' into devices_api 2024-03-06 16:51:28 -05:00
Stephane Bourque
1a0a6d4a70 Merge pull request #338 from Telecominfraproject/WIFI-13450
https://telecominfraproject.atlassian.net/browse/WIFI-13450
2024-03-05 21:47:06 -08:00
stephb9959
071922c555 https://telecominfraproject.atlassian.net/browse/WIFI-13450
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-04 22:41:51 -08:00
Carsten Schafer
c375ceb8a7 Helm chart changes 2024-03-01 10:41:25 -05:00
stephb9959
4e4b69e672 https://telecominfraproject.atlassian.net/browse/WIFI-13450
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-29 17:35:11 -08:00
stephb9959
3d8f7c1162 https://telecominfraproject.atlassian.net/browse/WIFI-13450
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-29 14:19:12 -08:00
stephb9959
2bf60dbb3f https://telecominfraproject.atlassian.net/browse/WIFI-13450
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-29 11:03:14 -08:00
stephb9959
44bc27e9d4 https://telecominfraproject.atlassian.net/browse/WIFI-13450
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-29 10:58:57 -08:00
stephb9959
f328a72b85 https://telecominfraproject.atlassian.net/browse/WIFI-13450
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-29 10:58:13 -08:00
Carsten Schafer
f86149ef6e Only one ci.yml needed 2024-02-29 11:04:15 -05:00
Carsten Schafer
0ab00622b3 Add CI stuff 2024-02-29 08:54:07 -05:00
stephb9959
4cbceb9366 https://telecominfraproject.atlassian.net/browse/WIFI-13447
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-28 23:06:48 -08:00
bhaveshpatel88
1a25fec25e Merge pull request #1 from kinarasystems/roles_permissions
Roles permissions
2024-02-27 16:03:28 -05:00
Carsten Schafer
34cac94581 New kinara specific ci.yaml 2024-02-26 16:44:25 -05:00
stephb9959
921267c00a https://telecominfraproject.atlassian.net/browse/WIFI-13434
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-21 08:39:11 -08:00
stephb9959
d63cbce602 https://telecominfraproject.atlassian.net/browse/WIFI-13434
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-20 17:19:26 -08:00
stephb9959
094bba4747 https://telecominfraproject.atlassian.net/browse/WIFI-13434
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-20 13:27:17 -08:00
Bhavesh Patel
332addc21b adding nonProvisioned parameter to GET devices API call 2024-02-20 14:19:17 -05:00
Carsten Schafer
063f3243a8 Merge remote-tracking branch 'github/master' into roles_permissions 2024-02-09 10:39:36 -05:00
Bhavesh Patel
bbc8033dc4 Adding Roles and Permissions 2024-02-09 10:18:48 -05:00
stephb9959
5bee5b1372 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-31 12:11:00 -08:00
stephb9959
45357ad567 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-25 20:35:21 -08:00
stephb9959
8e984a8f0e https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-25 12:50:46 -08:00
stephb9959
4e7babc25f https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-23 22:04:59 -08:00
stephb9959
1acabd4986 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-23 09:57:07 -08:00
stephb9959
d839646dd8 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-22 20:28:34 -08:00
TonyXu-FX
1710cd2131 [user-backend] Moved models and permissions into enum 2024-01-18 12:26:12 -05:00
stephb9959
31b52f9bd2 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 10:38:09 -08:00
stephb9959
97bc19b949 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 10:30:40 -08:00
stephb9959
c252e6c5c7 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 10:22:10 -08:00
stephb9959
cef012c333 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 10:16:53 -08:00
stephb9959
6513980525 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 10:14:35 -08:00
stephb9959
adc055f3e8 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 10:08:27 -08:00
stephb9959
6d991e5a48 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 10:02:48 -08:00
stephb9959
ec5031ca83 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 09:39:11 -08:00
stephb9959
19e4e92d92 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 07:07:36 -08:00
stephb9959
37feb6a44c https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-11 15:54:24 -08:00
stephb9959
2aaab1207b https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-11 15:42:01 -08:00
Stephane Bourque
7896b071da Merge pull request #337 from Telecominfraproject/WIFI-13280
https://telecominfraproject.atlassian.net/browse/WIFI-13280
2024-01-11 15:18:46 -08:00
stephb9959
e073576692 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-11 11:45:19 -08:00
stephb9959
65ad9ff96e https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-11 09:21:14 -08:00
stephb9959
08e7900889 https://telecominfraproject.atlassian.net/browse/WIFI-13273
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-10 23:01:43 -08:00
stephb9959
8554481186 https://telecominfraproject.atlassian.net/browse/WIFI-13273
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-08 10:58:32 -08:00
stephb9959
2b246fe1ee https://telecominfraproject.atlassian.net/browse/WIFI-13273
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-05 13:03:57 -08:00
stephb9959
bd37534223 https://telecominfraproject.atlassian.net/browse/WIFI-13273
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-05 12:59:39 -08:00
stephb9959
aa862d3fcf https://telecominfraproject.atlassian.net/browse/WIFI-13273
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-05 12:54:53 -08:00
stephb9959
c6c6eaa4a5 https://telecominfraproject.atlassian.net/browse/WIFI-13273
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-05 12:21:26 -08:00
stephb9959
ffe86a3994 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 22:37:35 -08:00
stephb9959
52123f7dcc https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 22:29:39 -08:00
stephb9959
e430c522ba https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 22:13:49 -08:00
stephb9959
93c236aa79 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 14:25:15 -08:00
stephb9959
c802e35c12 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 14:16:02 -08:00
stephb9959
a59d49e096 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 14:04:08 -08:00
stephb9959
5756d59519 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 14:00:25 -08:00
stephb9959
35aa6fb99d https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 13:39:23 -08:00
stephb9959
fa6d0aa714 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 13:27:10 -08:00
stephb9959
91147f3fbb https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 13:17:03 -08:00
stephb9959
15f3eaa02e https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 13:04:25 -08:00
stephb9959
6305e92399 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 12:48:58 -08:00
stephb9959
3714fd5f05 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 12:00:01 -08:00
stephb9959
19497b88ce https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 11:53:13 -08:00
stephb9959
6a35dc93bf https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 11:46:02 -08:00
stephb9959
8004aa6676 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 11:43:42 -08:00
stephb9959
2c654d3471 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 11:37:25 -08:00
stephb9959
df67141a98 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 11:21:47 -08:00
stephb9959
071330d7f8 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 11:15:09 -08:00
stephb9959
90f23dca73 https://telecominfraproject.atlassian.net/browse/WIFI-13256
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 08:10:01 -08:00
stephb9959
500688edb7 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-15 13:29:00 -08:00
Stephane Bourque
222b98d019 Merge pull request #334 from Telecominfraproject/sqlopt1
https://telecominfraproject.atlassian.net/browse/WIFI-13240
2023-12-15 11:49:00 -08:00
stephb9959
915a2c936d https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-15 10:48:13 -08:00
stephb9959
e1bf6a9ab7 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-14 07:23:48 -08:00
stephb9959
58fc925a2f https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-13 21:21:20 -08:00
stephb9959
3dda87b41f https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-13 07:19:25 -08:00
stephb9959
a5fe59086a https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-13 07:17:22 -08:00
stephb9959
c66b936c1e https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-13 07:16:09 -08:00
stephb9959
0e763cf034 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-13 07:12:58 -08:00
stephb9959
eb441d71aa https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-12 21:39:14 -08:00
stephb9959
082153a229 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-11 09:47:13 -08:00
TonyXu-FX
877ce485a0 [user-backend] Add comments/documentation 2023-12-11 10:34:11 -05:00
TonyXu-FX
581ecd0a70 [user-backend] Add permissions for scripts 2023-12-10 21:24:01 -05:00
stephb9959
25a03ca801 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 21:44:27 -08:00
stephb9959
0d549137de https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 21:27:54 -08:00
stephb9959
40e814cab8 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 21:15:27 -08:00
stephb9959
e40d53f3e5 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 21:08:20 -08:00
stephb9959
607507ce9a https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 21:00:32 -08:00
stephb9959
b3ec5b1e81 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 20:59:00 -08:00
stephb9959
c52d3c92f6 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 20:08:48 -08:00
stephb9959
d1216a8ac4 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 19:14:34 -08:00
stephb9959
c27f0390f8 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 11:48:10 -08:00
stephb9959
052d379e2b https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 11:37:38 -08:00
stephb9959
4eda1b813f https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 11:10:32 -08:00
stephb9959
5364adf509 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 11:08:47 -08:00
stephb9959
3b5580a525 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 09:46:20 -08:00
stephb9959
644918fa14 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 08:28:54 -08:00
stephb9959
8cdd398a6e https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 07:35:34 -08:00
stephb9959
9f7f4683df https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 06:59:39 -08:00
stephb9959
1c6e35fa8b https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-03 13:16:52 -08:00
stephb9959
af17823df0 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-03 12:03:51 -08:00
stephb9959
0cff2163bb https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-03 10:10:42 -08:00
stephb9959
0a5fe39bde https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 23:06:18 -08:00
stephb9959
c42feca957 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 22:23:31 -08:00
stephb9959
d3c5b17733 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 14:53:20 -08:00
stephb9959
30bc8e8283 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 14:07:50 -08:00
stephb9959
336c94a25a https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 13:23:46 -08:00
stephb9959
84f42e5a7d https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 13:04:23 -08:00
stephb9959
17752fdefe https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 12:56:53 -08:00
stephb9959
ef300b0349 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 12:53:32 -08:00
stephb9959
9c4ecb6165 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 12:12:53 -08:00
stephb9959
efd099b6fa https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 12:10:42 -08:00
stephb9959
15805dcaf6 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 12:07:52 -08:00
stephb9959
e5ed1750cc https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 12:05:53 -08:00
stephb9959
87d74568f2 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 10:45:00 -08:00
stephb9959
0cca3caa9b https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 10:40:13 -08:00
stephb9959
1d22e1153f https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 09:57:13 -08:00
stephb9959
f3ccc49647 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 09:44:27 -08:00
stephb9959
46fb410108 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 09:37:53 -08:00
stephb9959
fc680a6bc4 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 09:37:15 -08:00
stephb9959
246f9c8aad https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 08:44:37 -08:00
stephb9959
3f06f00a88 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-01 23:51:18 -08:00
stephb9959
0288d905b7 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-01 23:44:15 -08:00
stephb9959
135b63c021 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-01 23:00:09 -08:00
stephb9959
12e07fa65f https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-01 22:27:47 -08:00
stephb9959
567c2d1514 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-01 14:15:46 -08:00
stephb9959
b9bd768ca6 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-01 11:11:43 -08:00
stephb9959
f2dec010ee https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-01 10:17:16 -08:00
stephb9959
329d8d4441 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-01 10:02:41 -08:00
stephb9959
d4dbbeb54b https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 22:43:34 -08:00
stephb9959
b1c6884d49 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 22:30:54 -08:00
stephb9959
3ffa35bb14 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 22:30:01 -08:00
stephb9959
bd06722948 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 22:09:24 -08:00
stephb9959
8c70ec5280 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 22:08:25 -08:00
stephb9959
6c13d845f1 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 20:08:10 -08:00
stephb9959
77cc0b250b https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 19:44:54 -08:00
stephb9959
a3c424d8fe https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 15:39:14 -08:00
stephb9959
3f834a967b https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 15:15:40 -08:00
stephb9959
4120aefcd4 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 15:11:00 -08:00
stephb9959
909ee66ef0 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 15:02:17 -08:00
stephb9959
c3ad34d84b https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 14:41:48 -08:00
stephb9959
fbb9f40529 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 13:53:46 -08:00
stephb9959
5f6300bb17 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 13:44:01 -08:00
stephb9959
0bcfb26579 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 13:08:17 -08:00
stephb9959
5b199bc4f5 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 12:55:25 -08:00
stephb9959
4c6fb85542 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 12:53:28 -08:00
stephb9959
63993789ca https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 12:51:13 -08:00
stephb9959
cc9d4c5f68 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 12:42:57 -08:00
stephb9959
50fa1de62c https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 12:40:18 -08:00
stephb9959
14ef6608d6 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 12:29:01 -08:00
stephb9959
8e48d30d6a https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 12:17:06 -08:00
stephb9959
46c6321674 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 12:05:13 -08:00
stephb9959
77f67fe545 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 11:53:19 -08:00
stephb9959
ceda1fc8f6 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 09:31:57 -08:00
stephb9959
5b1a4fb9c0 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 09:25:43 -08:00
stephb9959
2ddc0d3117 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 09:13:25 -08:00
stephb9959
2cfc6c30e9 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 08:58:44 -08:00
stephb9959
0318b475f5 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 08:57:02 -08:00
stephb9959
c5c2dc1a1e https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-30 08:38:50 -08:00
stephb9959
7b899adb88 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-29 23:31:20 -08:00
stephb9959
aa472ed79e https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-29 22:50:45 -08:00
stephb9959
1778912264 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-29 22:18:58 -08:00
stephb9959
142bc4f271 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-29 22:04:42 -08:00
stephb9959
a01d006d4e https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-29 21:54:02 -08:00
stephb9959
135a195081 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-29 10:58:22 -08:00
stephb9959
ef7cb883fb https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-29 09:10:38 -08:00
stephb9959
2e361a41d7 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-29 09:09:10 -08:00
stephb9959
84281ec58e https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-29 08:54:39 -08:00
stephb9959
3560871f44 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-29 08:21:09 -08:00
stephb9959
b072f1e2ab https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-29 07:46:06 -08:00
stephb9959
72173ed4b5 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-28 23:11:14 -08:00
stephb9959
ff53d4ba2e https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-28 22:44:29 -08:00
stephb9959
81721b4a61 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-28 22:01:32 -08:00
stephb9959
3619be1832 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-28 21:57:48 -08:00
stephb9959
a8fc823b94 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-28 21:23:58 -08:00
stephb9959
a8a33013be https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-28 14:59:11 -08:00
stephb9959
9560f908a6 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-28 14:25:06 -08:00
stephb9959
8400b8cfcb https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-28 14:14:29 -08:00
stephb9959
82897f5b76 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-28 13:55:49 -08:00
stephb9959
4b472fd112 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-28 13:44:06 -08:00
stephb9959
ecb6312f0f https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-28 13:43:48 -08:00
stephb9959
0aba846277 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-28 13:40:35 -08:00
stephb9959
5be884ef98 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-28 13:30:26 -08:00
stephb9959
10c890a196 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-28 08:19:26 -08:00
stephb9959
0974abd510 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-27 22:27:50 -08:00
stephb9959
8dbbfc3298 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-27 14:56:48 -08:00
stephb9959
c981ae14ee https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-27 13:43:07 -08:00
stephb9959
97547068d7 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-27 13:30:25 -08:00
stephb9959
16cc443786 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-27 13:05:52 -08:00
105 changed files with 7842 additions and 1887 deletions

View File

@@ -1,19 +1,19 @@
name: CI
name: Build Docker image
on:
push:
paths-ignore:
- 'openapi/**'
- '**.md'
- 'version'
- 'package*.json'
- 'helm/*.yaml'
- 'CMakeLists.txt'
branches:
- master
- 'release/*'
tags:
- 'v*'
- kinara
pull_request:
branches:
- master
- 'release/*'
- kinara
defaults:
run:
@@ -21,81 +21,102 @@ defaults:
jobs:
docker:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
env:
DOCKER_REGISTRY_URL: tip-tip-wlan-cloud-ucentral.jfrog.io
DOCKER_REGISTRY_USERNAME: ucentral
ECR_REGISTRY: 471112855615.dkr.ecr.us-east-1.amazonaws.com
ECR_REPOSITORY: owgw
AWS_REGION: us-east-1
steps:
- name: Checkout actions repo
uses: actions/checkout@v3
with:
repository: Telecominfraproject/.github
path: github
- name: Checkout source
uses: actions/checkout@v4
with:
path: build
token: ${{ secrets.GIT_PUSH_PAT }}
persist-credentials: true
- name: Build and push Docker image
uses: ./github/composite-actions/docker-image-build
with:
image_name: owgw
registry: tip-tip-wlan-cloud-ucentral.jfrog.io
registry_user: ucentral
registry_password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
- name: Checkout dot github repo
uses: actions/checkout@v4
with:
repository: kinarasystems/.github
ref: main
path: tools
token: ${{ secrets.GIT_PUSH_PAT }}
- name: Notify on failure via Slack
if: failure() && github.ref == 'refs/heads/master'
uses: rtCamp/action-slack-notify@v2
env:
SLACK_USERNAME: GitHub Actions failure notifier
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_COLOR: "${{ job.status }}"
SLACK_ICON: https://raw.githubusercontent.com/quintessence/slack-icons/master/images/github-logo-slack-icon.png
SLACK_TITLE: Docker build failed for OWGW service
- name: Bump version and checkin
if: github.ref == 'refs/heads/kinara'
id: bump-version
run: |
cd build
../tools/utils/setup-git-credentials "${{ secrets.GIT_PUSH_PAT}}"
../tools/utils/ver-bump -b -a -p -V kv -y helm/Chart.yaml -Y helm/values.yaml -M CMakeLists.txt
trigger-testing:
if: startsWith(github.ref, 'refs/pull/')
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
GITHUB_REF: ${{ github.ref }}
run: |
cd build
version=$(cat version)
../tools/utils/docker_build \
-m kinara \
-b "$GITHUB_REF" \
-t "$IMAGE_TAG" \
-r "$ECR_REGISTRY/$ECR_REPOSITORY" \
-v "kv${version}"
- name: Notify via Teams
#if: failure() && github.ref == 'refs/heads/kinara'
if: always()
uses: skitionek/notify-microsoft-teams@master
with:
webhook_url: ${{ secrets.MS_TEAMS_WEBHOOK }}
needs: ${{ toJson(needs) }}
job: ${{ toJson(job) }}
steps: ${{ toJson(steps) }}
dry_run: False
deploy-to-dev:
runs-on: ubuntu-latest
needs: docker
steps:
- name: Get base branch name and set as output
id: get_base_branch
run: |
echo "branch=$(echo ${GITHUB_BASE_REF##*/} | sed 's/master/main/g')" >> $GITHUB_OUTPUT
- name: Checkout actions repo
uses: actions/checkout@v3
with:
repository: Telecominfraproject/.github
path: github
- name: Trigger testing of OpenWifi Docker Compose deployment and wait for result
uses: ./github/composite-actions/trigger-workflow-and-wait
env:
BASE_BRANCH: ${{ steps.get_base_branch.outputs.branch }}
with:
owner: Telecominfraproject
repo: wlan-testing
workflow: ow_docker-compose.yml
token: ${{ secrets.WLAN_TESTING_PAT }}
ref: master
inputs: '{"deployment_version": "${{ env.BASE_BRANCH }}", "owgw_version": "${{ github.sha }}", "owsec_version": "${{ env.BASE_BRANCH }}", "owfms_version": "${{ env.BASE_BRANCH }}", "owprov_version": "${{ env.BASE_BRANCH }}", "owanalytics_version": "${{ env.BASE_BRANCH }}", "owsub_version": "${{ env.BASE_BRANCH }}", "microservice": "owgw"}'
trigger-deploy-to-dev:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master'
if: github.ref == 'refs/heads/kinara'
env:
DEPLOY_NAME: owgw
AWS_DEFAULT_REGION: us-east-1
AWS_NAMESPACE: kic-dev1
AWS_EKS_NAME: kinara-dev
KUBECTL_VERSION: "v1.27.14"
needs:
- docker
steps:
- name: Checkout actions repo
uses: actions/checkout@v3
with:
repository: Telecominfraproject/.github
path: github
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_DEFAULT_REGION }}
- name: Trigger deployment of the latest version to dev instance and wait for result
uses: ./github/composite-actions/trigger-workflow-and-wait
with:
owner: Telecominfraproject
repo: wlan-testing
workflow: ucentralgw-dev-deployment.yaml
token: ${{ secrets.WLAN_TESTING_PAT }}
ref: master
inputs: '{"force_latest": "true"}'
- name: Fetch kubeconfig
run: |
aws eks update-kubeconfig --name ${{ env.AWS_EKS_NAME }} --region ${{ env.AWS_DEFAULT_REGION }}
- name: Install kubectl
run: |
curl -s -LO "https://dl.k8s.io/release/${{ env.KUBECTL_VERSION }}/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
- name: Rolling update of deployment
run: |
kubectl rollout restart deployment/${{ env.DEPLOY_NAME }} -n ${{ env.AWS_NAMESPACE }}

View File

@@ -1,26 +0,0 @@
name: Clean up PR Docker images
on:
pull_request:
branches:
- master
types: [ closed ]
defaults:
run:
shell: bash
jobs:
cleanup:
runs-on: ubuntu-latest
steps:
- name: Cleanup Docker image with PR branch tag
run: |
export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
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

@@ -1,24 +0,0 @@
name: Ensure Jira issue is linked
on:
pull_request:
types: [opened, edited, reopened, synchronize]
branches:
- 'release/*'
jobs:
check_for_issue_key:
runs-on: ubuntu-latest
steps:
- name: Checkout actions repo
uses: actions/checkout@v3
with:
repository: Telecominfraproject/.github
path: github
- name: Run JIRA check
uses: ./github/composite-actions/enforce-jira-issue-key
with:
jira_base_url: ${{ secrets.TIP_JIRA_URL }}
jira_user_email: ${{ secrets.TIP_JIRA_USER_EMAIL }}
jira_api_token: ${{ secrets.TIP_JIRA_API_TOKEN }}

View File

@@ -1,41 +0,0 @@
name: Update OpenAPI docs on GitHub Pages
on:
push:
paths:
- 'openapi/**'
branches:
- master
workflow_dispatch:
defaults:
run:
shell: bash
jobs:
docsgen:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Generate static HTML page with docs from OpenAPI definition
run: |
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli:v6.2.1 generate -i https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentralgw/master/openapi/owgw.yaml -g html2 --skip-validate-spec -o /local/
- name: Update OpenAPI docs
run: |
mkdir tmp-docs
mv index.html tmp-docs/index.html
mkdir -p ~/.ssh
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
echo https://tip-automation:${{ secrets.GIT_PUSH_PAT }}@github.com > ~/.git-credentials
git config --global credential.helper store
git config --global user.email "tip-automation@telecominfraproject.com"
git config --global user.name "TIP Automation User"
git pull
git checkout gh-pages || git checkout -b gh-pages
rm -rf docs
mv tmp-docs docs
git add docs
git commit -m'Update OpenAPI docs for GitHub pages'
git push --set-upstream origin gh-pages

View File

@@ -1,46 +0,0 @@
name: Release chart package
on:
push:
tags:
- 'v*'
defaults:
run:
shell: bash
jobs:
helm-package:
runs-on: ubuntu-20.04
env:
HELM_REPO_URL: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
HELM_REPO_USERNAME: ucentral
steps:
- name: Checkout uCentral assembly chart repo
uses: actions/checkout@v3
with:
path: wlan-cloud-ucentralgw
- name: Build package
working-directory: wlan-cloud-ucentralgw/helm
run: |
helm plugin install https://github.com/aslafy-z/helm-git --version 0.10.0
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm dependency update
mkdir dist
helm package . -d dist
- name: Generate GitHub release body
working-directory: wlan-cloud-ucentralgw/helm
run: |
pip3 install yq -q
echo "Docker image - tip-tip-wlan-cloud-ucentral.jfrog.io/owgw:$GITHUB_REF_NAME" > release.txt
echo "Helm charted may be attached to this release" >> release.txt
echo "Deployment artifacts may be found in https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/$GITHUB_REF_NAME" >> release.txt
- name: Create GitHub release
uses: softprops/action-gh-release@v1
with:
body_path: wlan-cloud-ucentralgw/helm/release.txt
files: wlan-cloud-ucentralgw/helm/dist/*

3
.gitignore vendored
View File

@@ -21,10 +21,11 @@ _deps
/docker-compose/.env
/docker-compose/.env_*
/cmake-build/
/uploads/
test_scripts/curl/token.json
.vscode/c_cpp_properties.json
test_scripts/curl/result.json
*.swp
helm/charts/*
!helm/charts/.gitkeep
/portal-test/
/src/ow_version.h

2
.idea/.gitignore generated vendored
View File

@@ -6,3 +6,5 @@
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/
# GitHub Copilot persisted chat sessions
/copilot/chatSessions

3
.idea/misc.xml generated
View File

@@ -1,5 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Black">
<option name="sdkName" value="Python 3.9 (wlan-cloud-ucentralgw)" />
</component>
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
<component name="CidrRootsConfiguration">
<excludeRoots>

View File

@@ -1,5 +1,5 @@
# Building from source
In order to build the OWGW, you will need to install its dependencies, which includes the following:
In order to build OWGW, you will need to install its dependencies, which includes the following:
- cmake
- boost
- POCO 1.10.1 or later
@@ -12,43 +12,43 @@ In order to build the OWGW, you will need to install its dependencies, which inc
The build is done in 2 parts. The first part is to build a local copy of the framework tailored to your environment. This
framework is called [Poco](https://github.com/pocoproject/poco). The version used in this project has a couple of fixes
from the master copy needed for cmake. Please use the version of this [Poco fix](https://github.com/AriliaWireless/poco). Building
from the master copy needed for cmake. Please use the version of this [Poco fix](https://github.com/Telecominfraproject/wlan-cloud-lib-poco). Building
Poco may take several minutes depending on the platform you are building on.
## Ubuntu
These instructions have proven to work on Ubuntu 20.4.
```bash
sudo apt install git cmake g++ libssl-dev libmariadb-dev
sudo apt install libpq-dev libaprutil1-dev apache2-dev libboost-all-dev
sudo apt install librdkafka-dev // default-libmysqlclient-dev
sudo apt install nlohmann-json-dev
sudo apt install git cmake g++ libssl-dev libmariadb-dev \
libpq-dev libaprutil1-dev apache2-dev libboost-all-dev \
librdkafka-dev // default-libmysqlclient-dev \
nlohmann-json-dev
cd ~
git clone https://github.com/AriliaWireless/poco --branch poco-tip-v2
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1 poco
cd poco
mkdir cmake-build
cd cmake-build
cmake ..
cmake --build . --config Release
sudo cmake --build . --target install
cd ../..
cd ~
git clone https://github.com/AriliaWireless/cppkafka --branch tip-v1
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch tip-v1 cppkafka
cd cppkafka
mkdir cmake-build
cd cmake-build
cmake ..
cmake --build . --config Release
sudo cmake --build . --target install
cd ../..
cd ~
git clone https://github.com/AriliaWireless/valijson --branch tip-v1
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-valijson --branch tip-v1 valijson
cd valijson
mkdir cmake-build
cd cmake-build
cmake ..
cmake --build . --config Release
sudo cmake --build . --target install
cd ../..
git clone https://github.com/fmtlib/fmt --branch 9.0.0 /fmtlib
cd fmtlib
@@ -57,56 +57,59 @@ cd cmake-build
cmake ..
make
make install
cd ../..
cd ~
git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralgw
cd wlan-cloud-ucentralgw
mkdir cmake-build
cd cmake-build
cmake ..
make -j 8
cd ../..
```
## Fedora
The following instructions have proven to work on Fedora 33
```bash
sudo yum install cmake g++ openssl-devel mysql-devel mysql apr-util-devel boost boost-devel
sudo yum install yaml-cpp-devel lua-devel
sudo yum install cmake g++ openssl-devel mysql-devel mysql apr-util-devel boost boost-devel \
yaml-cpp-devel lua-devel
sudo dnf install postgresql.x86_64 librdkafka-devel
sudo dnf install postgresql-devel json-devel
git clone https://github.com/AriliaWireless/poco --branch poco-tip-v2
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1 poco
cd poco
mkdir cmake-build
cd cmake-build
cmake ..
cmake --build . --config Release
sudo cmake --build . --target install
cd ../..
git clone https://github.com/AriliaWireless/cppkafka --branch tip-v1
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch tip-v1 cppkafka
cd cppkafka
mkdir cmake-build
cd cmake-build
cmake ..
cmake --build . --config Release
sudo cmake --build . --target install
cd ../..
cd ~
git clone https://github.com/AriliaWireless/valijson --branch tip-v1
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-valijson --branch tip-v1 valijson
cd valijson
mkdir cmake-build
cd cmake-build
cmake ..
cmake --build . --config Release
sudo cmake --build . --target install
cd ../..
cd ~
git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralgw
cd wlan-cloud-ucentralgw
mkdir cmake-build
cd cmake-build
cmake ..
make
cd ../..
```
## macOS Build
@@ -125,7 +128,7 @@ brew install openssl \
nlohmann-json \
fmt
git clone https://github.com/AriliaWireless/poco --branch poco-tip-v2
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1 poco
pushd poco
mkdir cmake-build
push cmake-build
@@ -135,7 +138,7 @@ sudo cmake --build . --target install
popd
popd
git clone https://github.com/AriliaWireless/cppkafka --branch tip-v1
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch tip-v1 cppkafka
pushd cppkafka
mkdir cmake-build
pushd cmake-build
@@ -145,10 +148,10 @@ sudo cmake --build . --target install
popd
popd
git clone https://github.com/AriliaWireless/valijson --branch tip-v1
cd valijson
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-valijson --branch tip-v1 valijson
pushd valijson
mkdir cmake-build
cd cmake-build
pushd cmake-build
cmake ..
cmake --build . --config Release
sudo cmake --build . --target install
@@ -171,20 +174,23 @@ support. You can build with only SQLite support by not installing the packages f
adding -DSMALL_BUILD=1 on the cmake build line.
```bash
sudo apt install git cmake g++ libssl-dev libaprutil1-dev apache2-dev libboost-all-dev libyaml-cpp-dev
git clone https://github.com/stephb9959/poco
sudo apt install git cmake g++ libssl-dev libaprutil1-dev apache2-dev \
libboost-all-dev libyaml-cpp-dev
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1 poco
cd poco
mkdir cmake-build
cd cmake-build
cmake ..
cmake --build . --config Release
sudo cmake --build . --target install
cd ../..
cd ~
git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralgw
cd wlan-cloud-ucentralgw
mkdir cmake-build
cd cmake-build
cmake -DSMALL_BUILD=1 ..
make
cd ../..
```

4
CHANGELOG.md Normal file
View File

@@ -0,0 +1,4 @@
## 3.0.3 (June 19, 2024)
- chore: updated package.json, updated helm/Chart.yaml, updated helm/values.yaml, updated CMakeLists.txt, updated version, created CHANGELOG.md, bumped 3.0.2 -> 3.0.3
- Merge pull request #6 from kinarasystems/devices

View File

@@ -1,7 +1,8 @@
cmake_minimum_required(VERSION 3.13)
project(owgw VERSION 3.0.0)
project(owgw VERSION 3.0.3)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
if(UNIX AND APPLE)
set(OPENSSL_ROOT_DIR /usr/local/opt/openssl)
@@ -148,6 +149,7 @@ add_executable( owgw
src/RESTAPI/RESTAPI_script_handler.cpp src/RESTAPI/RESTAPI_script_handler.h
src/RESTAPI/RESTAPI_regulatory.cpp src/RESTAPI/RESTAPI_regulatory.h
src/RESTAPI/RESTAPI_radiussessions_handler.cpp src/RESTAPI/RESTAPI_radiussessions_handler.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
@@ -175,7 +177,7 @@ add_executable( owgw
src/SDKcalls.cpp
src/SDKcalls.h
src/StateUtils.cpp src/StateUtils.h
src/AP_WS_ReactorPool.h
src/AP_WS_Reactor_Pool.h
src/AP_WS_Connection.h
src/AP_WS_Connection.cpp
src/TelemetryClient.h src/TelemetryClient.cpp
@@ -211,7 +213,8 @@ add_executable( owgw
src/RegulatoryInfo.cpp src/RegulatoryInfo.h
src/RADIUSSessionTracker.cpp src/RADIUSSessionTracker.h
src/libs/Scheduler.h src/libs/InterruptableSleep.h src/libs/ctpl_stl.h src/libs/Cron.h
src/GenericScheduler.cpp src/GenericScheduler.h src/framework/default_device_types.h src/AP_WS_Process_rebootLog.cpp src/AP_WS_ConfigAutoUpgrader.cpp src/AP_WS_ConfigAutoUpgrader.h src/RESTAPI/RESTAPI_default_firmwares.cpp src/RESTAPI/RESTAPI_default_firmwares.h src/RESTAPI/RESTAPI_default_firmware.cpp src/RESTAPI/RESTAPI_default_firmware.h src/storage/storage_def_firmware.cpp src/firmware_revision_cache.h src/sdks/sdk_fms.h)
src/GenericScheduler.cpp src/GenericScheduler.h src/framework/default_device_types.h src/AP_WS_Process_rebootLog.cpp src/AP_WS_ConfigAutoUpgrader.cpp src/AP_WS_ConfigAutoUpgrader.h src/RESTAPI/RESTAPI_default_firmwares.cpp src/RESTAPI/RESTAPI_default_firmwares.h src/RESTAPI/RESTAPI_default_firmware.cpp src/RESTAPI/RESTAPI_default_firmware.h src/storage/storage_def_firmware.cpp src/firmware_revision_cache.h src/sdks/sdk_fms.h
src/AP_WS_LookForUpgrade.cpp)
if(NOT SMALL_BUILD)

View File

@@ -17,8 +17,8 @@ FROM build-base AS poco-build
ARG POCO_VERSION
ADD https://api.github.com/repos/AriliaWireless/poco/git/refs/tags/${POCO_VERSION} version.json
RUN git clone https://github.com/AriliaWireless/poco --branch ${POCO_VERSION} /poco
ADD https://api.github.com/repos/Telecominfraproject/wlan-cloud-lib-poco/git/refs/tags/${POCO_VERSION} version.json
RUN git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch ${POCO_VERSION} /poco
WORKDIR /poco
RUN mkdir cmake-build
@@ -31,8 +31,8 @@ FROM build-base AS cppkafka-build
ARG CPPKAFKA_VERSION
ADD https://api.github.com/repos/AriliaWireless/cppkafka/git/refs/tags/${CPPKAFKA_VERSION} version.json
RUN git clone https://github.com/AriliaWireless/cppkafka --branch ${CPPKAFKA_VERSION} /cppkafka
ADD https://api.github.com/repos/Telecominfraproject/wlan-cloud-lib-cppkafka/git/refs/tags/${CPPKAFKA_VERSION} version.json
RUN git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch ${CPPKAFKA_VERSION} /cppkafka
WORKDIR /cppkafka
RUN mkdir cmake-build
@@ -45,8 +45,8 @@ FROM build-base AS valijson-build
ARG VALIJASON_VERSION
ADD https://api.github.com/repos/AriliaWireless/valijson/git/refs/tags/${VALIJASON_VERSION} version.json
RUN git clone https://github.com/AriliaWireless/valijson --branch ${VALIJASON_VERSION} /valijson
ADD https://api.github.com/repos/Telecominfraproject/wlan-cloud-lib-valijson/git/refs/tags/${VALIJASON_VERSION} version.json
RUN git clone https://github.com/Telecominfraproject/wlan-cloud-lib-valijson --branch ${VALIJASON_VERSION} /valijson
WORKDIR /valijson
RUN mkdir cmake-build

View File

@@ -355,6 +355,39 @@ The device should answer:
- 1 : the device is busy but will reboot soon. `text` may indicate why.
- 2 : the device will not reboot. `text` contains information as to why.
#### Controller wants to power-cycle PoE port(s)
Controller sends this command to power-cycle 1 or more PoE ports
```json
{ "jsonrpc" : "2.0" ,
"method" : "powercycle" ,
"params" : {
"serial" : <serial number> ,
"ports" : [ { "name" : "Ethernet1", "cycle" : 5000}, { "name" : "Ethernet8", "cycle" : 10000 } ],
"when" : Optional - <UTC time when to reboot, 0 mean immediately, this is a suggestion>
},
"id" : <some number>
}
```
The device should answer:
```json
{ "jsonrpc" : "2.0" ,
"result" : {
"serial" : <serial number> ,
"status" : {
"error" : 0 or an error number,
"text" : [ "Error 1" , "Error 2" ],
"when" : <time when this will be performed as UTC seconds>,
},
"id" : <same id from request>
}
```
###### Error codes
- 0 : is rebooting at `when` seconds.
- 1 : the device is busy but will reboot soon. `text` may indicate why.
- 2 : the device will not reboot. `text` contains information as to why.
#### Controller wants the device to upgrade its firmware
Controller sends this command when it believes the device should upgrade its firmware.
```json

2
build
View File

@@ -1 +1 @@
10
95

21
buildaws Executable file
View File

@@ -0,0 +1,21 @@
#!/bin/bash
set -e
[ -z "$AWS_PROFILE" ] && echo "Please set AWS_PROFILE" && exit 1
registry="471112855615.dkr.ecr.us-east-1.amazonaws.com"
repo="owgw"
aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin "$registry"
img="$registry/$repo"
if [ -n "$1" ] ; then
version="$1"
else
version="latest"
fi
#date > about.txt
#id=$(git rev-parse HEAD)
#br=$(git branch --show-current)
#echo "$br" >> about.txt
#echo "$id" >> about.txt
#echo "Built manually via $0" >> about.txt
#docker build --no-cache -t $img:$version .
docker build -t $img:$version .
docker push $img:$version

20
buildit Executable file
View File

@@ -0,0 +1,20 @@
#!/bin/bash
set -e
repo="owgw"
[ -z "$REMOTE_DOCKER_HOST" ] && echo "Please set DOCKER_HOST" && exit 1
[ -z "$REMOTE_DOCKER_PASSWORD" ] && echo "Please set DOCKER_PASSWORD" && exit 1
img="$REMOTE_DOCKER_HOST/kinara/$repo"
if [ -n "$1" ] ; then
version="$1"
else
version="latest"
fi
#date > about.txt
#id=$(git rev-parse HEAD)
#br=$(git branch --show-current)
#echo "$br" >> about.txt
#echo "$id" >> about.txt
#echo "Built manually via $0" >> about.txt
#docker build --no-cache -t $img:$version .
docker build -t $img:$version .
docker push $img:$version

View File

@@ -1,18 +1,18 @@
apiVersion: v2
appVersion: "1.0"
appVersion: "3.0.3"
description: A Helm chart for Kubernetes
name: owgw
version: 0.1.0
dependencies:
- name: postgresql
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
version: 10.9.2
condition: postgresql.enabled
- name: mysql
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
version: 8.8.3
condition: mysql.enabled
- name: mariadb
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
version: 9.4.2
condition: mariadb.enabled
- name: postgresql
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
version: 10.9.2
condition: postgresql.enabled
- name: mysql
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
version: 8.8.3
condition: mysql.enabled
- name: mariadb
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
version: 9.4.2
condition: mariadb.enabled

View File

@@ -2,24 +2,21 @@
replicaCount: 1
strategyType: Recreate
revisionHistoryLimit: 2
nameOverride: ""
fullnameOverride: ""
images:
owgw:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owgw
tag: master
repository: 471112855615.dkr.ecr.us-east-1.amazonaws.com/owgw
tag: kv3.0.3
pullPolicy: Always
# regcred:
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
# username: username
# password: password
# regcred:
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
# username: username
# password: password
dockerize:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/dockerize
tag: 0.16.0
repository: 471112855615.dkr.ecr.us-east-1.amazonaws.com/wait-ready
tag: latest
pullPolicy: IfNotPresent
services:
owgw:
type: ClusterIP
@@ -62,7 +59,6 @@ services:
servicePort: 3799
targetPort: 3799
protocol: UDP
checks:
owgw:
liveness:
@@ -73,33 +69,31 @@ checks:
exec:
command:
- /readiness_check
ingresses:
restapi:
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- restapi.chart-example.local
- restapi.chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
serviceName: owgw
servicePort: restapi
- path: /
pathType: ImplementationSpecific
serviceName: owgw
servicePort: restapi
fileuploader:
enabled: false
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- fileuploader.chart-example.local
- fileuploader.chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
serviceName: owgw
servicePort: fileuploader
- path: /
pathType: ImplementationSpecific
serviceName: owgw
servicePort: fileuploader
volumes:
owgw:
- name: config
@@ -125,18 +119,17 @@ volumes:
volumeDefinition: |
persistentVolumeClaim:
claimName: {{ template "owgw.fullname" . }}-pvc
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# requests:
# cpu: 100m
# memory: 128Mi
# limits:
# cpu: 100m
# memory: 128Mi
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# requests:
# cpu: 100m
# memory: 128Mi
# limits:
# cpu: 100m
# memory: 128Mi
securityContext:
fsGroup: 1000
@@ -151,18 +144,12 @@ securityContext:
# value: "2"
#- name: net.ipv4.tcp_keepalive_time
# value: "45"
nodeSelector: {}
tolerations: []
affinity: {}
podAnnotations: {}
podSecurityPolicy:
enabled: false
persistence:
enabled: true
# storageClassName: "-"
@@ -170,7 +157,6 @@ persistence:
- ReadWriteOnce
size: 10Gi
annotations: {}
# Application
public_env_variables:
OWGW_ROOT: /owgw-data
@@ -180,12 +166,10 @@ public_env_variables:
# NOTE in order for readiness check to use system info you need to set READINESS_METHOD to "systeminfo" and set OWSEC to the OWSEC's REST API endpoint
#READINESS_METHOD: systeminfo
#OWSEC: gw-qa01.cicd.lab.wlan.tip.build:16001
secret_env_variables:
# NOTE in order for readiness check to use system info method you need to override these values to the real OWSEC credentials
OWSEC_USERNAME: tip@ucentral.com
OWSEC_PASSWORD: openwifi
configProperties:
# -> Public part
# Websocket
@@ -310,7 +294,6 @@ configProperties:
archiver.db.2.keep: 7
archiver.db.3.name: commandlist
archiver.db.3.keep: 7
# -> Secret part
# Websocket
ucentral.websocket.host.0.key.password: mypassword
@@ -332,10 +315,8 @@ configProperties:
## MySQL
storage.type.mysql.username: stephb
storage.type.mysql.password: snoopy99
# NOTE: List of required certificates may be found in "certs" key. Alternative way to pass required certificates is to create external secret with all required certificates and set secret name in "existingCertsSecret" key. Details may be found in https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/main/chart#tldr
existingCertsSecret: ""
certs:
clientcas.pem: ""
issuer.pem: ""
@@ -345,66 +326,53 @@ certs:
root.pem: ""
websocket-cert.pem: ""
websocket-key.pem: ""
certsCAs:
issuer.pem: ""
root.pem: ""
# PostgreSQL (https://github.com/bitnami/charts/tree/master/bitnami/postgresql)
postgresql:
enabled: false
image:
registry: docker.io
repository: bitnami/postgresql
tag: 11.13.0-debian-10-r0
postgresqlPostgresPassword: "rootPassword"
postgresqlUsername: stephb
postgresqlPassword: snoopy99
postgresqlDatabase: owgw
persistence:
enabled: true
storageClass: ""
size: 8Gi
# MySQL (https://github.com/bitnami/charts/tree/master/bitnami/mysql)
mysql:
enabled: false
image:
registry: docker.io
repository: bitnami/mysql
tag: 8.0.26-debian-10-r10
auth:
rootPassword: rootPassword
database: owgw
username: stephb
password: snoopy99
primary:
persistence:
enabled: true
storageClass: ""
size: 8Gi
# MariaDB (https://github.com/bitnami/charts/tree/master/bitnami/mariadb)
mariadb:
enabled: false
image:
registry: docker.io
repository: bitnami/mariadb
tag: 10.5.12-debian-10-r0
auth:
rootPassword: rootPassword
database: owgw
username: stephb
password: snoopy99
primary:
persistence:
enabled: true

85
ols_samples/sample1.json Normal file
View File

@@ -0,0 +1,85 @@
{
"ethernet": [
{
"select-ports": [
"Ethernet0",
"Ethernet1",
"Ethernet2",
"Ethernet3",
"Ethernet4",
"Ethernet5",
"Ethernet6",
"Ethernet7"
],
"speed": 2500,
"duplex": "full",
"enabled": true,
"poe": {
"admin-mode": true,
"power-limit": 60000
}
},
{
"select-ports": [
"Ethernet8",
"Ethernet9"
],
"speed": 10000,
"duplex": "full",
"media": "sfp-forced-1000sfp"
}
],
"interfaces": [
{
"name": "VLAN1",
"vlan": {
"id": 1
},
"ipv4": {
"addressing": "dynamic"
},
"ethernet": [
{
"select-ports": [
"Ethernet0",
"Ethernet1",
"Ethernet2",
"Ethernet3",
"Ethernet4",
"Ethernet5",
"Ethernet6",
"Ethernet7",
"Ethernet8",
"Ethernet9"
],
"vlan-tag": "un-tagged"
}
]
}
],
"metrics": {
"dhcp-snooping": {
"filters": [
"ack",
"discover",
"offer",
"request",
"solicit",
"reply",
"renew"
]
},
"health": {
"interval": 60
},
"statistics": {
"interval": 120,
"types": []
}
},
"unit": {
"leds-active": true,
"usage-threshold": 95
},
"uuid": 1678263900
}

View File

@@ -42,12 +42,10 @@ components:
schemas:
DeviceType:
type: string
default: AP
default: ap
enum:
- AP
- SWITCH
- IOT
- MESH
- ap
- switch
DeviceRestrictionsKeyInfo:
type: object
@@ -157,6 +155,9 @@ components:
lastRecordedContact:
type: integer
format: int64
blackListed:
type: boolean
readOnly: true
DeviceWithStatus:
type: object
@@ -281,6 +282,9 @@ components:
format: float
connectReason:
type: string
blackListed:
type: boolean
readOnly: true
DeviceList:
type: object
@@ -545,6 +549,12 @@ components:
lastModified:
type: integer
format: int64
platform:
type: string
enum:
- ap
- switch
default: ap
DefaultConfigurationList:
properties:
@@ -1566,6 +1576,30 @@ components:
format: base64
description: This is a base64 encoded string of the certificate bundle (the current bundle .tar.gz file from the PKI portal)
PowerCycleRequest:
type: object
properties:
serial:
type: string
when:
type: integer
format: int64
ports:
type: array
items:
type: object
properties:
name:
type: string
example:
- Ethernet0
cycle:
type: integer
default: 10000
minimum: 1
maximum: 60000
description: off time in milliseconds
paths:
/devices:
get:
@@ -1657,6 +1691,22 @@ paths:
type: integer
default: 70
required: false
- in: query
description: return only devices matching a certain platform of AP or SWITCH
name: platform
schema:
type: string
default: ALL
enum:
- all
- ap
- switch
required: false
- in: query
description: only devices which are not provisioned
name: includeProvisioned
schema:
type: boolean
responses:
200:
description: List devices
@@ -3006,6 +3056,34 @@ paths:
404:
$ref: '#/components/responses/NotFound'
/device/{serialNumber}/powercycle:
post:
tags:
- Commands
summary: Perform PoE power cycle for some PoE ports.
operationId: performPowerCycle
parameters:
- in: path
name: serialNumber
schema:
type: string
required: true
requestBody:
description: Certificate update details
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/PowerCycleRequest'
responses:
200:
$ref: '#/components/responses/Success'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/ouis:
get:
tags:

View File

@@ -145,7 +145,7 @@ storage.type.sqlite.db = devices.db
storage.type.sqlite.idletime = 120
storage.type.sqlite.maxsessions = 128
storage.type.postgresql.maxsessions = 64
storage.type.postgresql.maxsessions = 250
storage.type.postgresql.idletime = 60
storage.type.postgresql.host = ${STORAGE_TYPE_POSTGRESQL_HOST}
storage.type.postgresql.username = ${STORAGE_TYPE_POSTGRESQL_USERNAME}

15
package.json Normal file
View File

@@ -0,0 +1,15 @@
{
"name": "owgw",
"version": "3.0.3",
"description": "This is the Kinara version of OpenWifi OWGW",
"author": "Kinara Systems",
"homepage": "https://kinarasystems.com",
"repository": {
"type": "git",
"url": "https://github.com/kinarasystems/wlan-cloud-ucentralgw"
},
"keywords": [
"owgw",
"gateway"
]
}

View File

@@ -9,14 +9,14 @@
namespace OpenWifi {
int AP_WS_ConfigAutoUpgrader::Start() {
int AP_WS_ConfigAutoUpgradeAgent::Start() {
poco_notice(Logger(), "Starting...");
QueueManager_.start(*this);
return 0;
}
void AP_WS_ConfigAutoUpgrader::Stop() {
void AP_WS_ConfigAutoUpgradeAgent::Stop() {
poco_notice(Logger(), "Stopping...");
Running_ = false;
Queue_.wakeUpAll();
@@ -24,7 +24,7 @@ namespace OpenWifi {
poco_notice(Logger(), "Stopped...");
}
void AP_WS_ConfigAutoUpgrader::run() {
void AP_WS_ConfigAutoUpgradeAgent::run() {
Utils::SetThreadName("auto:cfgmgr");
Running_ = true;

View File

@@ -28,14 +28,14 @@ namespace OpenWifi {
std::uint64_t pending_config_=0;
};
class AP_WS_ConfigAutoUpgrader : public SubSystemServer, Poco::Runnable {
class AP_WS_ConfigAutoUpgradeAgent : public SubSystemServer, Poco::Runnable {
public:
int Start() final;
void Stop() final;
void run() final;
static auto instance() {
static auto instance = new AP_WS_ConfigAutoUpgrader;
static auto instance = new AP_WS_ConfigAutoUpgradeAgent;
return instance;
}
@@ -126,12 +126,12 @@ namespace OpenWifi {
mutable std::mutex CacheMutex_;
std::map<std::uint64_t, ConfigurationCacheEntry> Cache_;
AP_WS_ConfigAutoUpgrader() noexcept
AP_WS_ConfigAutoUpgradeAgent() noexcept
: SubSystemServer("AutoConfigUpgrade", "AUTO-CFG-MGR", "auto.config.updater") {
}
};
inline auto AP_WS_ConfigAutoUpgrader() { return AP_WS_ConfigAutoUpgrader::instance(); }
inline auto AP_WS_ConfigAutoUpgradeAgent() { return AP_WS_ConfigAutoUpgradeAgent::instance(); }
} // namespace OpenWifi

View File

@@ -2,56 +2,49 @@
// Created by stephane bourque on 2022-02-03.
//
#include "AP_WS_Connection.h"
#include "Poco/Base64Decoder.h"
#include "Poco/Net/Context.h"
#include "Poco/Net/HTTPServerRequestImpl.h"
#include "Poco/Net/HTTPServerResponseImpl.h"
#include "Poco/Net/NetException.h"
#include "Poco/Net/SSLException.h"
#include "Poco/Net/SecureStreamSocketImpl.h"
#include "Poco/Net/WebSocketImpl.h"
#include "Poco/zlib.h"
#include <Poco/Base64Decoder.h>
#include <Poco/Net/Context.h>
#include <Poco/Net/HTTPServerRequestImpl.h>
#include <Poco/Net/HTTPServerResponseImpl.h>
#include <Poco/Net/NetException.h>
#include <Poco/Net/SSLException.h>
#include <Poco/Net/SecureStreamSocketImpl.h>
#include <Poco/Net/WebSocketImpl.h>
#include "AP_WS_Server.h"
#include "CentralConfig.h"
#include "CommandManager.h"
#include "ConfigurationCache.h"
#include "StorageService.h"
#include "TelemetryStream.h"
#include <framework/KafkaManager.h>
#include <framework/MicroServiceFuncs.h>
#include <framework/utils.h>
#include <framework/ow_constants.h>
#include "GWKafkaEvents.h"
#include "UI_GW_WebSocketNotifications.h"
#include "framework/KafkaManager.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.h"
#include <fmt/format.h>
#include "fmt/format.h"
#include "framework/ow_constants.h"
#include "RADIUSSessionTracker.h"
#include "RADIUS_proxy_server.h"
#include <AP_WS_Connection.h>
#include <AP_WS_Server.h>
#include <CentralConfig.h>
#include <CommandManager.h>
#include <StorageService.h>
#include <RADIUSSessionTracker.h>
#include <RADIUS_proxy_server.h>
#include <GWKafkaEvents.h>
#include <UI_GW_WebSocketNotifications.h>
namespace OpenWifi {
#define DBL \
{ \
std::cout << __LINE__ << " ID: " << ConnectionId_ << " Ser: " << SerialNumber_ \
<< std::endl; \
}
void AP_WS_Connection::LogException(const Poco::Exception &E) {
poco_information(Logger_, fmt::format("EXCEPTION({}): {}", CId_, E.displayText()));
}
AP_WS_Connection::AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response,
uint64_t connection_id, Poco::Logger &L,
Poco::Net::SocketReactor &R)
: Logger_(L), Reactor_(R) {
State_.sessionId = connection_id;
uint64_t session_id, Poco::Logger &L,
std::pair<std::shared_ptr<Poco::Net::SocketReactor>, std::shared_ptr<LockedDbSession>> R)
: Logger_(L) {
Reactor_ = R.first;
DbSession_ = R.second;
State_.sessionId = session_id;
WS_ = std::make_unique<Poco::Net::WebSocket>(request, response);
auto TS = Poco::Timespan(360, 0);
@@ -61,29 +54,86 @@ namespace OpenWifi {
WS_->setNoDelay(false);
WS_->setKeepAlive(true);
WS_->setBlocking(false);
Reactor_.addEventHandler(*WS_,
Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
*this, &AP_WS_Connection::OnSocketReadable));
Reactor_.addEventHandler(*WS_,
Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
*this, &AP_WS_Connection::OnSocketShutdown));
Reactor_.addEventHandler(*WS_,
Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
*this, &AP_WS_Connection::OnSocketError));
Registered_ = true;
Valid_ = true;
uuid_ = MicroServiceRandom(std::numeric_limits<std::uint64_t>::max()-1);
AP_WS_Server()->IncrementConnectionCount();
}
void AP_WS_Connection::Start() {
Registered_ = true;
LastContact_ = Utils::Now();
Reactor_->addEventHandler(*WS_,
Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
*this, &AP_WS_Connection::OnSocketReadable));
Reactor_->addEventHandler(*WS_,
Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
*this, &AP_WS_Connection::OnSocketShutdown));
Reactor_->addEventHandler(*WS_,
Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
*this, &AP_WS_Connection::OnSocketError));
}
AP_WS_Connection::~AP_WS_Connection() {
std::lock_guard G(ConnectionMutex_);
AP_WS_Server()->DecrementConnectionCount();
EndConnection();
poco_debug(Logger_, fmt::format("TERMINATION({}): Session={}, Connection removed.", SerialNumber_,
State_.sessionId));
}
static void NotifyKafkaDisconnect(const std::string &SerialNumber, std::uint64_t uuid) {
try {
Poco::JSON::Object Disconnect;
Poco::JSON::Object Details;
Details.set(uCentralProtocol::SERIALNUMBER, SerialNumber);
Details.set(uCentralProtocol::TIMESTAMP, Utils::Now());
Details.set(uCentralProtocol::UUID,uuid);
Disconnect.set(uCentralProtocol::DISCONNECTION, Details);
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber, Disconnect);
} catch (...) {
}
}
void AP_WS_Connection::EndConnection() {
bool expectedValue=false;
if (Dead_.compare_exchange_strong(expectedValue,true,std::memory_order_release,std::memory_order_relaxed)) {
if(!SerialNumber_.empty() && State_.LastContact!=0) {
StorageService()->SetDeviceLastRecordedContact(SerialNumber_, State_.LastContact);
}
if (Registered_) {
Registered_ = false;
Reactor_->removeEventHandler(
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
*this, &AP_WS_Connection::OnSocketReadable));
Reactor_->removeEventHandler(
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
*this, &AP_WS_Connection::OnSocketShutdown));
Reactor_->removeEventHandler(
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
*this, &AP_WS_Connection::OnSocketError));
Registered_=false;
}
WS_->close();
if(!SerialNumber_.empty()) {
DeviceDisconnectionCleanup(SerialNumber_, uuid_);
}
AP_WS_Server()->AddCleanupSession(State_.sessionId, SerialNumberInt_);
}
}
bool AP_WS_Connection::ValidatedDevice() {
if(Dead_)
return false;
if (DeviceValidated_)
return true;
if (!Valid_)
return false;
std::lock_guard Lock(ConnectionMutex_);
try {
auto SockImpl = dynamic_cast<Poco::Net::WebSocketImpl *>(WS_->impl());
auto SS =
@@ -98,7 +148,6 @@ namespace OpenWifi {
poco_warning(Logger_, fmt::format("TLS-CONNECTION({}): Session={} Connection is "
"NOT secure. Device is not allowed.",
CId_, State_.sessionId));
EndConnection();
return false;
}
@@ -111,7 +160,6 @@ namespace OpenWifi {
Logger_,
fmt::format("TLS-CONNECTION({}): Session={} No certificates available..", CId_,
State_.sessionId));
EndConnection();
return false;
}
@@ -122,11 +170,19 @@ namespace OpenWifi {
fmt::format("TLS-CONNECTION({}): Session={} Device certificate is not "
"valid. Device is not allowed.",
CId_, State_.sessionId));
EndConnection();
return false;
}
CN_ = Poco::trim(Poco::toLower(PeerCert.commonName()));
if(!Utils::ValidSerialNumber(CN_)) {
poco_trace(Logger_,
fmt::format("TLS-CONNECTION({}): Session={} Invalid serial number: CN={}", CId_,
State_.sessionId, CN_));
return false;
}
SerialNumber_ = CN_;
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
State_.VerifiedCertificate = GWObjects::VALID_CERTIFICATE;
poco_trace(Logger_,
fmt::format("TLS-CONNECTION({}): Session={} Valid certificate: CN={}", CId_,
@@ -136,31 +192,27 @@ namespace OpenWifi {
poco_warning(Logger_, fmt::format("TLS-CONNECTION({}): Session={} Sim Device {} is "
"not allowed. Disconnecting.",
CId_, State_.sessionId, CN_));
EndConnection();
return false;
}
if(AP_WS_Server::IsSim(CN_)) {
if(AP_WS_Server::IsSim(SerialNumber_)) {
State_.VerifiedCertificate = GWObjects::SIMULATED;
Simulated_ = true;
}
std::string reason, author;
std::uint64_t created;
if (!CN_.empty() && StorageService()->IsBlackListed(CN_, reason, author, created)) {
if (!CN_.empty() && StorageService()->IsBlackListed(SerialNumberInt_, reason, author, created)) {
DeviceBlacklistedKafkaEvent KE(Utils::SerialNumberToInt(CN_), Utils::Now(), reason, author, created, CId_);
poco_warning(
Logger_,
fmt::format(
"TLS-CONNECTION({}): Session={} Device {} is black listed. Disconnecting.",
CId_, State_.sessionId, CN_));
EndConnection();
return false;
}
State_.certificateExpiryDate = PeerCert.expiresOn().timestamp().epochTime();
SerialNumber_ = CN_;
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
poco_trace(Logger_,
fmt::format("TLS-CONNECTION({}): Session={} CN={} Completed. (t={})", CId_,
@@ -224,149 +276,14 @@ namespace OpenWifi {
return false;
}
static void NotifyKafkaDisconnect(const std::string &SerialNumber, std::uint64_t uuid) {
try {
Poco::JSON::Object Disconnect;
Poco::JSON::Object Details;
Details.set(uCentralProtocol::SERIALNUMBER, SerialNumber);
Details.set(uCentralProtocol::TIMESTAMP, Utils::Now());
Details.set(uCentralProtocol::UUID,uuid);
Disconnect.set(uCentralProtocol::DISCONNECTION, Details);
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber, Disconnect);
} catch (...) {
}
}
AP_WS_Connection::~AP_WS_Connection() {
Valid_ = false;
EndConnection();
}
void DeviceDisconnectionCleanup(const std::string &SerialNumber, std::uint64_t uuid) {
void AP_WS_Connection::DeviceDisconnectionCleanup(const std::string &SerialNumber, std::uint64_t uuid) {
if (KafkaManager()->Enabled()) {
NotifyKafkaDisconnect(SerialNumber, uuid);
}
RADIUSSessionTracker()->DeviceDisconnect(SerialNumber);
}
void AP_WS_Connection::EndConnection(bool DeleteSession) {
Valid_ = false;
if (!Dead_.test_and_set()) {
if(!SerialNumber_.empty() && State_.LastContact!=0) {
StorageService()->SetDeviceLastRecordedContact(SerialNumber_, State_.LastContact);
}
if (Registered_) {
Registered_ = false;
Reactor_.removeEventHandler(
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
*this, &AP_WS_Connection::OnSocketReadable));
Reactor_.removeEventHandler(
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
*this, &AP_WS_Connection::OnSocketShutdown));
Reactor_.removeEventHandler(
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
*this, &AP_WS_Connection::OnSocketError));
}
WS_->close();
if(!SerialNumber_.empty()) {
std::thread Cleanup(DeviceDisconnectionCleanup,SerialNumber_, uuid_);
Cleanup.detach();
}
bool SessionDeleted = false;
if(DeleteSession)
SessionDeleted = AP_WS_Server()->EndSession(State_.sessionId, SerialNumberInt_);
if (SessionDeleted || !DeleteSession) {
GWWebSocketNotifications::SingleDevice_t N;
N.content.serialNumber = SerialNumber_;
GWWebSocketNotifications::DeviceDisconnected(N);
}
}
}
bool AP_WS_Connection::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 == State_.PendingUUID)) {
UpgradedUUID = UUID;
return false;
}
GWObjects::Device D;
if (StorageService()->GetDevice(SerialNumber_, D)) {
if(D.pendingUUID!=0 && UUID==D.pendingUUID) {
// so we sent an upgrade to a device, and now it is completing now...
UpgradedUUID = D.pendingUUID;
StorageService()->CompleteDeviceConfigurationChange(SerialNumber_);
return true;
}
// 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;
}
Config::Config Cfg(D.Configuration);
if (UUID > D.UUID) {
// so we have a problem, the device has a newer config than we have. So we need to
// make sure our config is newer.
D.UUID = UUID + 2;
UpgradedUUID = D.UUID;
}
Cfg.SetUUID(D.UUID);
D.Configuration = Cfg.get();
State_.PendingUUID = UpgradedUUID = D.UUID;
GWObjects::CommandDetails Cmd;
Cmd.SerialNumber = SerialNumber_;
Cmd.UUID = MicroServiceCreateUUID();
Cmd.SubmittedBy = uCentralProtocol::SUBMITTED_BY_SYSTEM;
Cmd.Status = uCentralProtocol::PENDING;
Cmd.Command = uCentralProtocol::CONFIGURE;
Poco::JSON::Parser P;
auto ParsedConfig = P.parse(D.Configuration).extract<Poco::JSON::Object::Ptr>();
Poco::JSON::Object Params;
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
Params.set(uCentralProtocol::UUID, D.UUID);
Params.set(uCentralProtocol::WHEN, 0);
Params.set(uCentralProtocol::CONFIG, ParsedConfig);
std::ostringstream O;
Poco::JSON::Stringifier::stringify(Params, O);
Cmd.Details = O.str();
poco_information(Logger_,
fmt::format("CFG-UPGRADE({}): Current ID: {}, newer configuration {}.",
CId_, UUID, D.UUID));
bool Sent;
StorageService()->AddCommand(SerialNumber_, Cmd,
Storage::CommandExecutionType::COMMAND_EXECUTED);
CommandManager()->PostCommand(
CommandManager()->Next_RPC_ID(), APCommands::to_apcommand(Cmd.Command.c_str()),
SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent, false, false);
GWWebSocketNotifications::SingleDeviceConfigurationChange_t Notification;
Notification.content.serialNumber = D.SerialNumber;
Notification.content.oldUUID = UUID;
Notification.content.newUUID = UpgradedUUID;
GWWebSocketNotifications::DeviceConfigurationChange(Notification);
return true;
}
return false;
GWWebSocketNotifications::SingleDevice_t N;
N.content.serialNumber = SerialNumber;
GWWebSocketNotifications::DeviceDisconnected(N);
}
void AP_WS_Connection::ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc) {
@@ -447,7 +364,7 @@ namespace OpenWifi {
std::string reason, author;
std::uint64_t created;
if (StorageService()->IsBlackListed(Serial, reason, author, created)) {
if (StorageService()->IsBlackListed(SerialNumberInt_, reason, author, created)) {
DeviceBlacklistedKafkaEvent KE(Utils::SerialNumberToInt(CN_), Utils::Now(), reason, author, created, CId_);
Poco::Exception E(
fmt::format("BLACKLIST({}): device is blacklisted and not allowed to connect.",
@@ -578,17 +495,17 @@ namespace OpenWifi {
}
bool AP_WS_Connection::SetWebSocketTelemetryReporting(
uint64_t RPCID, uint64_t Interval, uint64_t LifeTime,
std::uint64_t RPCID, std::uint64_t Interval, std::uint64_t LifeTime,
const std::vector<std::string> &TelemetryTypes) {
std::unique_lock Lock(TelemetryMutex_);
TelemetryWebSocketRefCount_++;
TelemetryInterval_ = TelemetryInterval_
? (Interval < TelemetryInterval_ ? Interval : TelemetryInterval_)
? (Interval < (std::uint64_t)TelemetryInterval_ ? Interval : (std::uint64_t )TelemetryInterval_)
: Interval;
auto TelemetryWebSocketTimer = LifeTime + Utils::Now();
TelemetryWebSocketTimer_ = TelemetryWebSocketTimer > TelemetryWebSocketTimer_
? TelemetryWebSocketTimer
: TelemetryWebSocketTimer_;
TelemetryWebSocketTimer_ = TelemetryWebSocketTimer > (std::uint64_t)TelemetryWebSocketTimer_
? (std::uint64_t)TelemetryWebSocketTimer
: (std::uint64_t)TelemetryWebSocketTimer_;
UpdateCounts();
if (!TelemetryReporting_) {
TelemetryReporting_ = true;
@@ -604,11 +521,11 @@ namespace OpenWifi {
std::unique_lock Lock(TelemetryMutex_);
TelemetryKafkaRefCount_++;
TelemetryInterval_ = TelemetryInterval_
? (Interval < TelemetryInterval_ ? Interval : TelemetryInterval_)
? (Interval < (std::uint64_t)TelemetryInterval_ ? (std::uint64_t)Interval : (std::uint64_t)TelemetryInterval_)
: Interval;
auto TelemetryKafkaTimer = LifeTime + Utils::Now();
TelemetryKafkaTimer_ =
TelemetryKafkaTimer > TelemetryKafkaTimer_ ? TelemetryKafkaTimer : TelemetryKafkaTimer_;
TelemetryKafkaTimer > (std::uint64_t)TelemetryKafkaTimer_ ? (std::uint64_t)TelemetryKafkaTimer : (std::uint64_t)TelemetryKafkaTimer_;
UpdateCounts();
if (!TelemetryReporting_) {
TelemetryReporting_ = true;
@@ -644,49 +561,50 @@ namespace OpenWifi {
void AP_WS_Connection::OnSocketShutdown(
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
poco_trace(Logger_, fmt::format("SOCKET-SHUTDOWN({}): Closing.", CId_));
// std::lock_guard G(ConnectionMutex_);
return EndConnection();
}
void AP_WS_Connection::OnSocketError(
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
poco_trace(Logger_, fmt::format("SOCKET-ERROR({}): Closing.", CId_));
// std::lock_guard G(ConnectionMutex_);
return EndConnection();
}
void AP_WS_Connection::OnSocketReadable(
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
if (!Valid_)
if (Dead_) // we are dead, so we do not process anything.
return;
if (!AP_WS_Server()->Running())
return EndConnection();
std::lock_guard G(ConnectionMutex_);
if (!ValidatedDevice())
return;
try {
return ProcessIncomingFrame();
} catch (const Poco::Exception &E) {
Logger_.log(E);
return EndConnection();
} catch (const std::exception &E) {
std::string W = E.what();
poco_information(
Logger_,
fmt::format("std::exception caught: {}. Connection terminated with {}", W, CId_));
return EndConnection();
} catch (...) {
poco_information(Logger_,
fmt::format("Unknown exception for {}. Connection terminated.", CId_));
return EndConnection();
State_.LastContact = LastContact_ = Utils::Now();
if (AP_WS_Server()->Running() && (DeviceValidated_ || ValidatedDevice())) {
try {
return ProcessIncomingFrame();
} catch (const Poco::Exception &E) {
Logger_.log(E);
} catch (const std::exception &E) {
std::string W = E.what();
poco_information(
Logger_, fmt::format("std::exception caught: {}. Connection terminated with {}",
W, CId_));
} catch (...) {
poco_information(
Logger_, fmt::format("Unknown exception for {}. Connection terminated.", CId_));
}
}
EndConnection();
}
void AP_WS_Connection::ProcessIncomingFrame() {
Poco::Buffer<char> IncomingFrame(0);
bool KillConnection=false;
try {
int Op, flags;
int Op, flags;
auto IncomingSize = WS_->receiveFrame(IncomingFrame, flags);
Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
@@ -706,83 +624,81 @@ namespace OpenWifi {
State_.LastContact = Utils::Now();
switch (Op) {
case Poco::Net::WebSocket::FRAME_OP_PING: {
poco_trace(Logger_, fmt::format("WS-PING({}): received. PONG sent back.", CId_));
WS_->sendFrame("", 0,
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
case Poco::Net::WebSocket::FRAME_OP_PING: {
poco_trace(Logger_, fmt::format("WS-PING({}): received. PONG sent back.", CId_));
WS_->sendFrame("", 0,
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
if (KafkaManager()->Enabled()) {
Poco::JSON::Object PingObject;
Poco::JSON::Object PingDetails;
PingDetails.set(uCentralProtocol::FIRMWARE, State_.Firmware);
PingDetails.set(uCentralProtocol::SERIALNUMBER, SerialNumber_);
PingDetails.set(uCentralProtocol::COMPATIBLE, Compatible_);
PingDetails.set(uCentralProtocol::CONNECTIONIP, CId_);
PingDetails.set(uCentralProtocol::TIMESTAMP, Utils::Now());
PingDetails.set(uCentralProtocol::UUID, uuid_);
PingDetails.set("locale", State_.locale);
PingObject.set(uCentralProtocol::PING, PingDetails);
poco_trace(Logger_,fmt::format("Sending PING for {}", SerialNumber_));
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_,PingObject);
}
return;
} break;
if (KafkaManager()->Enabled()) {
Poco::JSON::Object PingObject;
Poco::JSON::Object PingDetails;
PingDetails.set(uCentralProtocol::FIRMWARE, State_.Firmware);
PingDetails.set(uCentralProtocol::SERIALNUMBER, SerialNumber_);
PingDetails.set(uCentralProtocol::COMPATIBLE, Compatible_);
PingDetails.set(uCentralProtocol::CONNECTIONIP, CId_);
PingDetails.set(uCentralProtocol::TIMESTAMP, Utils::Now());
PingDetails.set(uCentralProtocol::UUID, uuid_);
PingDetails.set("locale", State_.locale);
PingObject.set(uCentralProtocol::PING, PingDetails);
poco_trace(Logger_,fmt::format("Sending PING for {}", SerialNumber_));
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_,PingObject);
}
} break;
case Poco::Net::WebSocket::FRAME_OP_PONG: {
poco_trace(Logger_, fmt::format("PONG({}): received and ignored.", CId_));
return;
} break;
case Poco::Net::WebSocket::FRAME_OP_PONG: {
poco_trace(Logger_, fmt::format("PONG({}): received and ignored.", CId_));
} break;
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
poco_trace(Logger_,
fmt::format("FRAME({}): Frame received (length={}, flags={}). Msg={}",
CId_, IncomingSize, flags, IncomingFrame.begin()));
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
poco_trace(Logger_,
fmt::format("FRAME({}): Frame received (length={}, flags={}). Msg={}",
CId_, IncomingSize, flags, IncomingFrame.begin()));
Poco::JSON::Parser parser;
auto ParsedMessage = parser.parse(IncomingFrame.begin());
auto IncomingJSON = ParsedMessage.extract<Poco::JSON::Object::Ptr>();
Poco::JSON::Parser parser;
auto ParsedMessage = parser.parse(IncomingFrame.begin());
auto IncomingJSON = ParsedMessage.extract<Poco::JSON::Object::Ptr>();
if (IncomingJSON->has(uCentralProtocol::JSONRPC)) {
if (IncomingJSON->has(uCentralProtocol::METHOD) &&
IncomingJSON->has(uCentralProtocol::PARAMS)) {
ProcessJSONRPCEvent(IncomingJSON);
} else if (IncomingJSON->has(uCentralProtocol::RESULT) &&
IncomingJSON->has(uCentralProtocol::ID)) {
poco_trace(Logger_, fmt::format("RPC-RESULT({}): payload: {}", CId_,
IncomingFrame.begin()));
ProcessJSONRPCResult(IncomingJSON);
if (IncomingJSON->has(uCentralProtocol::JSONRPC)) {
if (IncomingJSON->has(uCentralProtocol::METHOD) &&
IncomingJSON->has(uCentralProtocol::PARAMS)) {
ProcessJSONRPCEvent(IncomingJSON);
} else if (IncomingJSON->has(uCentralProtocol::RESULT) &&
IncomingJSON->has(uCentralProtocol::ID)) {
poco_trace(Logger_, fmt::format("RPC-RESULT({}): payload: {}", CId_,
IncomingFrame.begin()));
ProcessJSONRPCResult(IncomingJSON);
} else {
poco_warning(
Logger_,
fmt::format("INVALID-PAYLOAD({}): Payload is not JSON-RPC 2.0: {}",
CId_, IncomingFrame.begin()));
}
} else if (IncomingJSON->has(uCentralProtocol::RADIUS)) {
ProcessIncomingRadiusData(IncomingJSON);
} else {
std::ostringstream iS;
IncomingJSON->stringify(iS);
poco_warning(
Logger_,
fmt::format("INVALID-PAYLOAD({}): Payload is not JSON-RPC 2.0: {}",
CId_, IncomingFrame.begin()));
fmt::format("FRAME({}): illegal transaction header, missing 'jsonrpc': {}",
CId_, iS.str()));
Errors_++;
}
} else if (IncomingJSON->has(uCentralProtocol::RADIUS)) {
ProcessIncomingRadiusData(IncomingJSON);
} else {
std::ostringstream iS;
IncomingJSON->stringify(iS);
std::cout << iS.str() << std::endl;
poco_warning(
Logger_,
fmt::format("FRAME({}): illegal transaction header, missing 'jsonrpc'",
CId_));
} break;
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
poco_information(Logger_,
fmt::format("CLOSE({}): Device is closing its connection.", CId_));
KillConnection=true;
} break;
default: {
poco_warning(Logger_, fmt::format("UNKNOWN({}): unknown WS Frame operation: {}",
CId_, std::to_string(Op)));
Errors_++;
return;
}
return;
} break;
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
poco_information(Logger_,
fmt::format("CLOSE({}): Device is closing its connection.", CId_));
return EndConnection();
} break;
default: {
poco_warning(Logger_, fmt::format("UNKNOWN({}): unknown WS Frame operation: {}",
CId_, std::to_string(Op)));
} break;
}
} catch (const Poco::Net::ConnectionResetException &E) {
poco_warning(Logger_,
@@ -790,21 +706,21 @@ namespace OpenWifi {
CId_, E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
State_.sessionId));
return EndConnection();
KillConnection=true;
} catch (const Poco::JSON::JSONException &E) {
poco_warning(Logger_,
fmt::format("JSONException({}): Text:{} Payload:{} Session:{}", CId_,
E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
State_.sessionId));
return EndConnection();
KillConnection=true;
} catch (const Poco::Net::WebSocketException &E) {
poco_warning(Logger_,
fmt::format("WebSocketException({}): Text:{} Payload:{} Session:{}", CId_,
E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
State_.sessionId));
return EndConnection();
KillConnection=true;
} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) {
poco_warning(
Logger_,
@@ -813,54 +729,54 @@ namespace OpenWifi {
CId_, E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
State_.sessionId));
return EndConnection();
KillConnection=true;
} catch (const Poco::Net::SSLException &E) {
poco_warning(Logger_,
fmt::format("SSLException({}): Text:{} Payload:{} Session:{}", CId_,
E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
State_.sessionId));
return EndConnection();
KillConnection=true;
} catch (const Poco::Net::NetException &E) {
poco_warning(Logger_,
fmt::format("NetException({}): Text:{} Payload:{} Session:{}", CId_,
E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
State_.sessionId));
return EndConnection();
KillConnection=true;
} catch (const Poco::IOException &E) {
poco_warning(Logger_,
fmt::format("IOException({}): Text:{} Payload:{} Session:{}", CId_,
E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
State_.sessionId));
return EndConnection();
KillConnection=true;
} catch (const Poco::Exception &E) {
poco_warning(Logger_,
fmt::format("Exception({}): Text:{} Payload:{} Session:{}", CId_,
E.displayText(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
State_.sessionId));
return EndConnection();
KillConnection=true;
} catch (const std::exception &E) {
poco_warning(Logger_,
fmt::format("std::exception({}): Text:{} Payload:{} Session:{}", CId_,
E.what(),
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
State_.sessionId));
return EndConnection();
KillConnection=true;
} catch (...) {
poco_error(Logger_, fmt::format("UnknownException({}): Device must be disconnected. "
"Unknown exception. Session:{}",
CId_, State_.sessionId));
return EndConnection();
KillConnection=true;
}
if (Errors_ < 10)
if (!KillConnection && Errors_ < 10)
return;
poco_warning(Logger_, fmt::format("DISCONNECTING({}): Too many errors", CId_));
return EndConnection();
poco_warning(Logger_, fmt::format("DISCONNECTING({}): ConnectionException: {} Errors: {}", CId_, KillConnection, Errors_ ));
EndConnection();
}
bool AP_WS_Connection::Send(const std::string &Payload) {
@@ -972,4 +888,36 @@ namespace OpenWifi {
}
}
}
void AP_WS_Connection::SetLastStats(const std::string &LastStats) {
RawLastStats_ = LastStats;
try {
Poco::JSON::Parser P;
auto Stats = P.parse(LastStats).extract<Poco::JSON::Object::Ptr>();
State_.hasGPS = Stats->isObject("gps");
auto Unit = Stats->getObject("unit");
auto Memory = Unit->getObject("memory");
std::uint64_t TotalMemory = Memory->get("total");
std::uint64_t FreeMemory = Memory->get("free");
if (TotalMemory > 0) {
State_.memoryUsed =
(100.0 * ((double)TotalMemory - (double)FreeMemory)) / (double)TotalMemory;
}
if (Unit->isArray("load")) {
Poco::JSON::Array::Ptr Load = Unit->getArray("load");
if (Load->size() > 1) {
State_.load = Load->get(1);
}
}
if (Unit->isArray("temperature")) {
Poco::JSON::Array::Ptr Temperature = Unit->getArray("temperature");
if (Temperature->size() > 1) {
State_.temperature = Temperature->get(0);
}
}
} catch (const Poco::Exception &E) {
poco_error(Logger_, "Failed to parse last stats: " + E.displayText());
}
}
} // namespace OpenWifi

View File

@@ -14,8 +14,10 @@
#include "Poco/Net/SocketReactor.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/WebSocket.h"
#include <Poco/Data/Session.h>
#include "RESTObjects/RESTAPI_GWobjects.h"
#include <AP_WS_Reactor_Pool.h>
namespace OpenWifi {
@@ -25,16 +27,17 @@ namespace OpenWifi {
public:
explicit AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response, uint64_t connection_id,
Poco::Logger &L, Poco::Net::SocketReactor &R);
Poco::Logger &L, std::pair<std::shared_ptr<Poco::Net::SocketReactor>, std::shared_ptr<LockedDbSession>> R);
~AP_WS_Connection();
void EndConnection(bool DeleteSession=true);
void EndConnection();
void ProcessJSONRPCEvent(Poco::JSON::Object::Ptr &Doc);
void ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc);
void ProcessIncomingFrame();
void ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc);
[[nodiscard]] bool Send(const std::string &Payload);
[[nodiscard]] inline bool MustBeSecureRTTY() const { return RTTYMustBeSecure_; }
bool SendRadiusAuthenticationData(const unsigned char *buffer, std::size_t size);
bool SendRadiusAccountingData(const unsigned char *buffer, std::size_t size);
@@ -43,10 +46,7 @@ namespace OpenWifi {
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, uint64_t &UpgradedUUID);
static bool ExtractBase64CompressedData(const std::string &CompressedData,
std::string &UnCompressedData,
uint64_t compress_sz);
bool LookForUpgrade(Poco::Data::Session &Session, uint64_t UUID, uint64_t &UpgradedUUID);
void LogException(const Poco::Exception &E);
inline Poco::Logger &Logger() { return Logger_; }
bool SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t interval,
@@ -59,81 +59,33 @@ namespace OpenWifi {
bool StopKafkaTelemetry(uint64_t RPCID);
inline void GetLastStats(std::string &LastStats) {
std::lock_guard G(ConnectionMutex_);
LastStats = RawLastStats_;
}
inline void SetLastStats(const std::string &LastStats) {
std::lock_guard G(ConnectionMutex_);
RawLastStats_ = LastStats;
try {
Poco::JSON::Parser P;
auto Stats = P.parse(LastStats).extract<Poco::JSON::Object::Ptr>();
hasGPS = Stats->isObject("gps");
auto Unit = Stats->getObject("unit");
auto Memory = Unit->getObject("memory");
std::uint64_t TotalMemory = Memory->get("total");
std::uint64_t FreeMemory = Memory->get("free");
if(TotalMemory>0) {
memory_used_ =
(100.0 * ((double)TotalMemory - (double)FreeMemory)) / (double)TotalMemory;
}
if(Unit->isArray("load")) {
Poco::JSON::Array::Ptr Load = Unit->getArray("load");
if(Load->size()>1) {
cpu_load_ = Load->get(1);
}
}
if(Unit->isArray("temperature")) {
Poco::JSON::Array::Ptr Temperature = Unit->getArray("temperature");
if(Temperature->size()>1) {
temperature_ = Temperature->get(0);
}
}
} catch (...) {
if(!Dead_) {
std::lock_guard G(ConnectionMutex_);
LastStats = RawLastStats_;
}
}
inline void SetLastHealthCheck(const GWObjects::HealthCheck &H) {
std::lock_guard G(ConnectionMutex_);
RawLastHealthcheck_ = H;
}
inline void GetLastHealthCheck(GWObjects::HealthCheck &H) {
std::lock_guard G(ConnectionMutex_);
H = RawLastHealthcheck_;
if(!Dead_) {
std::lock_guard G(ConnectionMutex_);
H = RawLastHealthcheck_;
}
}
inline void GetState(GWObjects::ConnectionState &State) const {
std::lock_guard G(ConnectionMutex_);
State = State_;
inline void GetState(GWObjects::ConnectionState &State) {
if(!Dead_) {
std::lock_guard G(ConnectionMutex_);
State = State_;
}
}
inline bool HasGPS() { return hasGPS; }
inline void GetRestrictions(GWObjects::DeviceRestrictions &R) const {
inline GWObjects::DeviceRestrictions GetRestrictions() {
std::lock_guard G(ConnectionMutex_);
R = Restrictions_;
return Restrictions_;
}
void Process_connect(Poco::JSON::Object::Ptr ParamsObj, const std::string &Serial);
void Process_state(Poco::JSON::Object::Ptr ParamsObj);
void Process_healthcheck(Poco::JSON::Object::Ptr ParamsObj);
void Process_log(Poco::JSON::Object::Ptr ParamsObj);
void Process_crashlog(Poco::JSON::Object::Ptr ParamsObj);
void Process_ping(Poco::JSON::Object::Ptr ParamsObj);
void Process_cfgpending(Poco::JSON::Object::Ptr ParamsObj);
void Process_recovery(Poco::JSON::Object::Ptr ParamsObj);
void Process_deviceupdate(Poco::JSON::Object::Ptr ParamsObj, std::string &Serial);
void Process_telemetry(Poco::JSON::Object::Ptr ParamsObj);
void Process_venuebroadcast(Poco::JSON::Object::Ptr ParamsObj);
void Process_event(Poco::JSON::Object::Ptr ParamsObj);
void Process_wifiscan(Poco::JSON::Object::Ptr ParamsObj);
void Process_alarm(Poco::JSON::Object::Ptr ParamsObj);
void Process_rebootLog(Poco::JSON::Object::Ptr ParamsObj);
bool ValidatedDevice();
[[nodiscard]] inline bool HasGPS() const { return hasGPS_; }
[[nodiscard]] bool ValidatedDevice();
inline bool GetTelemetryParameters(bool &Reporting, uint64_t &Interval,
uint64_t &WebSocketTimer, uint64_t &KafkaTimer,
@@ -153,18 +105,14 @@ namespace OpenWifi {
friend class AP_WS_Server;
inline GWObjects::DeviceRestrictions Restrictions() const {
std::lock_guard G(ConnectionMutex_);
return Restrictions_;
}
inline bool MustBeSecureRtty() const { return RttyMustBeSecure_; }
void Start();
private:
mutable std::mutex ConnectionMutex_;
mutable std::recursive_mutex ConnectionMutex_;
std::mutex TelemetryMutex_;
Poco::Logger &Logger_;
Poco::Net::SocketReactor &Reactor_;
std::shared_ptr<Poco::Net::SocketReactor> Reactor_;
std::shared_ptr<LockedDbSession> DbSession_;
std::unique_ptr<Poco::Net::WebSocket> WS_;
std::string SerialNumber_;
uint64_t SerialNumberInt_ = 0;
@@ -175,34 +123,56 @@ namespace OpenWifi {
uint64_t Errors_ = 0;
Poco::Net::IPAddress PeerAddress_;
volatile bool TelemetryReporting_ = false;
volatile uint64_t TelemetryWebSocketRefCount_ = 0;
volatile uint64_t TelemetryKafkaRefCount_ = 0;
volatile uint64_t TelemetryWebSocketTimer_ = 0;
volatile uint64_t TelemetryKafkaTimer_ = 0;
volatile uint64_t TelemetryInterval_ = 0;
volatile uint64_t TelemetryWebSocketPackets_ = 0;
volatile uint64_t TelemetryKafkaPackets_ = 0;
std::atomic_uint64_t TelemetryWebSocketRefCount_ = 0;
std::atomic_uint64_t TelemetryKafkaRefCount_ = 0;
std::atomic_uint64_t TelemetryWebSocketTimer_ = 0;
std::atomic_uint64_t TelemetryKafkaTimer_ = 0;
std::atomic_uint64_t TelemetryInterval_ = 0;
std::atomic_uint64_t TelemetryWebSocketPackets_ = 0;
std::atomic_uint64_t TelemetryKafkaPackets_ = 0;
GWObjects::ConnectionState State_;
std::string RawLastStats_;
Utils::CompressedString RawLastStats_;
GWObjects::HealthCheck RawLastHealthcheck_;
std::chrono::time_point<std::chrono::high_resolution_clock> ConnectionStart_ =
std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> ConnectionCompletionTime_{0.0};
std::atomic_flag Dead_ = false;
std::atomic<bool> Dead_ = false;
std::atomic_bool DeviceValidated_ = false;
std::atomic_bool Valid_ = false;
OpenWifi::GWObjects::DeviceRestrictions Restrictions_;
bool RttyMustBeSecure_ = false;
bool RTTYMustBeSecure_ = false;
bool hasGPS_=false;
std::double_t memory_used_=0.0, cpu_load_ = 0.0, temperature_ = 0.0;
std::uint64_t uuid_=0;
bool Simulated_=false;
std::atomic_uint64_t LastContact_=0;
static inline std::atomic_uint64_t ConcurrentStartingDevices_ = 0;
bool StartTelemetry(uint64_t RPCID, const std::vector<std::string> &TelemetryTypes);
bool StopTelemetry(uint64_t RPCID);
void UpdateCounts();
bool hasGPS=false;
std::double_t memory_used_=0.0, cpu_load_ = 0.0, temperature_ = 0.0;
std::uint64_t uuid_=0;
bool Simulated_=false;
static void DeviceDisconnectionCleanup(const std::string &SerialNumber, std::uint64_t uuid);
void SetLastStats(const std::string &LastStats);
void Process_connect(Poco::JSON::Object::Ptr ParamsObj, const std::string &Serial);
void Process_state(Poco::JSON::Object::Ptr ParamsObj);
void Process_healthcheck(Poco::JSON::Object::Ptr ParamsObj);
void Process_log(Poco::JSON::Object::Ptr ParamsObj);
void Process_crashlog(Poco::JSON::Object::Ptr ParamsObj);
void Process_ping(Poco::JSON::Object::Ptr ParamsObj);
void Process_cfgpending(Poco::JSON::Object::Ptr ParamsObj);
void Process_recovery(Poco::JSON::Object::Ptr ParamsObj);
void Process_deviceupdate(Poco::JSON::Object::Ptr ParamsObj, std::string &Serial);
void Process_telemetry(Poco::JSON::Object::Ptr ParamsObj);
void Process_venuebroadcast(Poco::JSON::Object::Ptr ParamsObj);
void Process_event(Poco::JSON::Object::Ptr ParamsObj);
void Process_wifiscan(Poco::JSON::Object::Ptr ParamsObj);
void Process_alarm(Poco::JSON::Object::Ptr ParamsObj);
void Process_rebootLog(Poco::JSON::Object::Ptr ParamsObj);
inline void SetLastHealthCheck(const GWObjects::HealthCheck &H) {
RawLastHealthcheck_ = H;
}
};
} // namespace OpenWifi

View File

@@ -0,0 +1,111 @@
#include <AP_WS_Connection.h>
#include "ConfigurationCache.h"
#include "UI_GW_WebSocketNotifications.h"
#include "CommandManager.h"
namespace OpenWifi {
bool AP_WS_Connection::LookForUpgrade(Poco::Data::Session &Session, 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 = GetCurrentConfigurationID(SerialNumberInt_);
if (GoodConfig && (GoodConfig == UUID || GoodConfig == State_.PendingUUID)) {
UpgradedUUID = UUID;
State_.PendingUUID = 0;
return false;
}
GWObjects::Device D;
if (!StorageService()->GetDevice(Session,SerialNumber_, D)) {
return false;
}
if(State_.PendingUUID!=0 && UUID==State_.PendingUUID) {
// so we sent an upgrade to a device, and now it is completing now...
UpgradedUUID = UUID;
StorageService()->CompleteDeviceConfigurationChange(Session, SerialNumber_);
State_.PendingUUID = 0;
return true;
}
// dont upgrade a switch if it does not have a real config. Config will always be more than 20 characters
if (D.DeviceType==Platforms::SWITCH && D.Configuration.size()<20) {
return false;
}
Config::Config Cfg(D.Configuration);
// if this is a broken device (UUID==0) just fix it
auto StoredConfigurationUUID = Cfg.UUID();
if(D.UUID==0) {
D.UUID = StoredConfigurationUUID;
}
if (D.UUID == UUID) {
D.UUID = UpgradedUUID = UUID;
State_.PendingUUID = D.pendingUUID = 0;
D.pendingConfiguration.clear();
D.pendingConfigurationCmd.clear();
StorageService()->UpdateDevice(Session, D);
SetCurrentConfigurationID(SerialNumberInt_, UUID);
// std::cout << __LINE__ << ": " << SerialNumber_ << " GoodConfig: " << GoodConfig << " UUID:" << UUID << " Pending:" << State_.PendingUUID << std::endl;
return false;
}
if (UUID > D.UUID) {
// so we have a problem, the device has a newer config than we have. So we need to
// make sure our config is newer.
D.UUID = UUID + 2;
UpgradedUUID = D.UUID;
// std::cout << __LINE__ << ": " << SerialNumber_ << " GoodConfig: " << GoodConfig << " UUID:" << UUID << " Pending:" << State_.PendingUUID << std::endl;
}
Cfg.SetUUID(D.UUID);
D.Configuration = Cfg.get();
D.pendingUUID = State_.PendingUUID = UpgradedUUID = D.UUID;
StorageService()->UpdateDevice(Session, D);
GWObjects::CommandDetails Cmd;
Cmd.SerialNumber = SerialNumber_;
Cmd.UUID = MicroServiceCreateUUID();
Cmd.SubmittedBy = uCentralProtocol::SUBMITTED_BY_SYSTEM;
Cmd.Status = uCentralProtocol::PENDING;
Cmd.Command = uCentralProtocol::CONFIGURE;
Poco::JSON::Parser P;
auto ParsedConfig = P.parse(D.Configuration).extract<Poco::JSON::Object::Ptr>();
Poco::JSON::Object Params;
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
Params.set(uCentralProtocol::UUID, D.UUID);
Params.set(uCentralProtocol::WHEN, 0);
Params.set(uCentralProtocol::CONFIG, ParsedConfig);
std::ostringstream O;
Poco::JSON::Stringifier::stringify(Params, O);
Cmd.Details = O.str();
poco_information(Logger_,
fmt::format("CFG-UPGRADE({}): Current ID: {}, newer configuration {}.",
CId_, UUID, D.UUID));
bool Sent;
StorageService()->AddCommand(SerialNumber_, Cmd,
Storage::CommandExecutionType::COMMAND_EXECUTED);
CommandManager()->PostCommand(
CommandManager()->Next_RPC_ID(), APCommands::to_apcommand(Cmd.Command.c_str()),
SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent, false, false);
GWWebSocketNotifications::SingleDeviceConfigurationChange_t Notification;
Notification.content.serialNumber = D.SerialNumber;
Notification.content.oldUUID = UUID;
Notification.content.newUUID = UpgradedUUID;
GWWebSocketNotifications::DeviceConfigurationChange(Notification);
// std::cout << __LINE__ << ": " << SerialNumber_ << " GoodConfig: " << GoodConfig << " UUID:" << UUID <<
// " Pending:" << State_.PendingUUID << " Upgraded:" << UpgradedUUID << std::endl;
return true;
}
}

View File

@@ -71,9 +71,8 @@ namespace OpenWifi {
CommandManager()->ClearQueue(SerialNumberInt_);
AP_WS_Server()->SetSessionDetails(State_.sessionId, SerialNumberInt_);
AP_WS_Server()->StartSession(State_.sessionId, SerialNumberInt_);
std::lock_guard Lock(ConnectionMutex_);
Config::Capabilities Caps(Capabilities);
Compatible_ = Caps.Compatible();
@@ -84,6 +83,8 @@ namespace OpenWifi {
State_.Address = Utils::FormatIPv6(WS_->peerAddress().toString());
CId_ = SerialNumber_ + "@" + CId_;
auto &Platform = Caps.Platform();
if(ParamsObj->has("reason")) {
State_.connectReason = ParamsObj->get("reason").toString();
}
@@ -100,36 +101,24 @@ namespace OpenWifi {
Restrictions_.from_json(RestrictionObject);
}
if (Capabilities->has("developer")) {
if (Capabilities->has("developer") && !Capabilities->isNull("developer")) {
Restrictions_.developer = Capabilities->getValue<bool>("developer");
}
if(Capabilities->has("secure-rtty")) {
RttyMustBeSecure_ = Capabilities->getValue<bool>("secure-rtty");
RTTYMustBeSecure_ = Capabilities->getValue<bool>("secure-rtty");
}
State_.locale = FindCountryFromIP()->Get(IP);
GWObjects::Device DeviceInfo;
auto DeviceExists = StorageService()->GetDevice(SerialNumber_, DeviceInfo);
std::lock_guard DbSessionLock(DbSession_->Mutex());
auto DeviceExists = StorageService()->GetDevice(DbSession_->Session(), SerialNumber_, DeviceInfo);
if (Daemon()->AutoProvisioning() && !DeviceExists) {
// check the firmware version. if this is too old, we cannot let that device connect yet, we must
// force a firmware upgrade
GWObjects::DefaultFirmware MinimumFirmware;
if(FirmwareRevisionCache()->DeviceMustUpgrade(Compatible_, Firmware, MinimumFirmware)) {
/*
{ "jsonrpc" : "2.0" ,
"method" : "upgrade" ,
"params" : {
"serial" : <serial number> ,
"when" : Optional - <UTC time when to upgrade the firmware, 0 mean immediate, this is a suggestion>,
"uri" : <URI to download the firmware>,
"FWsignature" : <string representation of the signature for the FW> (optional)
},
"id" : <some number>
}
*/
Poco::JSON::Object UpgradeCommand, Params;
UpgradeCommand.set(uCentralProtocol::JSONRPC,uCentralProtocol::JSONRPC_VERSION);
UpgradeCommand.set(uCentralProtocol::METHOD,uCentralProtocol::UPGRADE);
@@ -157,7 +146,7 @@ namespace OpenWifi {
}
return;
} else {
StorageService()->CreateDefaultDevice(
StorageService()->CreateDefaultDevice( DbSession_->Session(),
SerialNumber_, Caps, Firmware, PeerAddress_,
State_.VerifiedCertificate == GWObjects::SIMULATED);
}
@@ -166,7 +155,7 @@ namespace OpenWifi {
poco_warning(Logger(),fmt::format("Device {} is a {} from {} and cannot be provisioned.",SerialNumber_,Compatible_, CId_));
return EndConnection();
} else if (DeviceExists) {
StorageService()->UpdateDeviceCapabilities(SerialNumber_, Caps);
StorageService()->UpdateDeviceCapabilities(DbSession_->Session(), SerialNumber_, Caps);
int Updated{0};
if (!Firmware.empty()) {
if (Firmware != DeviceInfo.Firmware) {
@@ -217,8 +206,13 @@ namespace OpenWifi {
++Updated;
}
if (Compatible_ != DeviceInfo.DeviceType) {
DeviceInfo.DeviceType = Compatible_;
if (Compatible_ != DeviceInfo.Compatible) {
DeviceInfo.Compatible = Compatible_;
++Updated;
}
if (Platform != DeviceInfo.DeviceType) {
DeviceInfo.DeviceType = Platform;
++Updated;
}
@@ -238,12 +232,13 @@ namespace OpenWifi {
}
if (Updated) {
StorageService()->UpdateDevice(DeviceInfo);
StorageService()->UpdateDevice(DbSession_->Session(), DeviceInfo);
}
}
if(!Simulated_) {
uint64_t UpgradedUUID = 0;
LookForUpgrade(UUID, UpgradedUUID);
if(!Simulated_) {
uint64_t UpgradedUUID = 0;
if (LookForUpgrade(DbSession_->Session(), UUID, UpgradedUUID)) {
State_.UUID = UpgradedUUID;
}
}

View File

@@ -29,7 +29,7 @@ namespace OpenWifi {
.Recorded = Utils::Now(),
.LogType = 1,
.UUID = ParamsObj->get(uCentralProtocol::UUID)};
StorageService()->AddLog(DeviceLog);
StorageService()->AddLog(*DbSession_, DeviceLog);
DeviceLogKafkaEvent E(DeviceLog);
} else {
poco_warning(Logger_, fmt::format("LOG({}): Missing parameters.", CId_));

View File

@@ -21,7 +21,7 @@ namespace OpenWifi {
if (ParamsObj->has("currentPassword")) {
auto Password = ParamsObj->get("currentPassword").toString();
StorageService()->SetDevicePassword(Serial, Password);
StorageService()->SetDevicePassword(*DbSession_,Serial, Password);
poco_trace(
Logger_,
fmt::format("DEVICE-UPDATE({}): Device is updating its login password.", Serial));

View File

@@ -3,6 +3,7 @@
//
#include "AP_WS_Connection.h"
#include "AP_WS_Server.h"
#include "StorageService.h"
#include "fmt/format.h"
@@ -25,6 +26,7 @@ namespace OpenWifi {
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
auto Sanity = ParamsObj->get(uCentralProtocol::SANITY);
State_.sanity = Sanity;
auto CheckData = ParamsObj->get(uCentralProtocol::DATA).toString();
if (CheckData.empty())
CheckData = uCentralProtocol::EMPTY_JSON_DOC;
@@ -48,14 +50,14 @@ namespace OpenWifi {
Check.Data = CheckData;
Check.Sanity = Sanity;
StorageService()->AddHealthCheckData(Check);
StorageService()->AddHealthCheckData(*DbSession_, Check);
if (!request_uuid.empty()) {
StorageService()->SetCommandResult(request_uuid, CheckData);
}
SetLastHealthCheck(Check);
if (KafkaManager()->Enabled()) {
if (KafkaManager()->Enabled() && !AP_WS_Server()->KafkaDisableHealthChecks()) {
KafkaManager()->PostMessage(KafkaTopics::HEALTHCHECK, SerialNumber_, *ParamsObj);
}
} else {

View File

@@ -36,7 +36,7 @@ namespace OpenWifi {
.Recorded = (uint64_t)time(nullptr),
.LogType = 0,
.UUID = State_.UUID};
StorageService()->AddLog(DeviceLog);
StorageService()->AddLog(*DbSession_, DeviceLog);
DeviceLogKafkaEvent E(DeviceLog);
} else {
poco_warning(Logger_, fmt::format("LOG({}): Missing parameters.", CId_));

View File

@@ -35,7 +35,7 @@ namespace OpenWifi {
.Recorded = ParamsObj->get(uCentralProtocol::DATE),
.LogType = 2,
.UUID = ParamsObj->get(uCentralProtocol::UUID)};
StorageService()->AddLog(DeviceLog);
StorageService()->AddLog(*DbSession_, DeviceLog);
DeviceLogKafkaEvent E(DeviceLog);
} else {
poco_warning(Logger_, fmt::format("REBOOT-LOG({}): Missing parameters.", CId_));

View File

@@ -35,7 +35,7 @@ namespace OpenWifi {
.LogType = 1,
.UUID = 0};
StorageService()->AddLog(DeviceLog);
StorageService()->AddLog(*DbSession_, DeviceLog);
if (ParamsObj->get(uCentralProtocol::REBOOT).toString() == "true") {
GWObjects::CommandDetails Cmd;

View File

@@ -3,6 +3,7 @@
//
#include "AP_WS_Connection.h"
#include "AP_WS_Server.h"
#include "StateUtils.h"
#include "StorageService.h"
@@ -39,25 +40,27 @@ namespace OpenWifi {
UUID, request_uuid));
}
std::lock_guard Guard(DbSession_->Mutex());
if(!Simulated_) {
uint64_t UpgradedUUID;
LookForUpgrade(UUID, UpgradedUUID);
LookForUpgrade(DbSession_->Session(), UUID, UpgradedUUID);
State_.UUID = UpgradedUUID;
}
SetLastStats(StateStr);
GWObjects::Statistics Stats{
.SerialNumber = SerialNumber_, .UUID = UUID, .Data = StateStr};
Stats.Recorded = Utils::Now();
StorageService()->AddStatisticsData(Stats);
StorageService()->AddStatisticsData(DbSession_->Session(),Stats);
if (!request_uuid.empty()) {
StorageService()->SetCommandResult(request_uuid, StateStr);
}
StateUtils::ComputeAssociations(StateObj, State_.Associations_2G,
State_.Associations_5G, State_.Associations_6G);
State_.Associations_5G, State_.Associations_6G, State_.uptime);
if (KafkaManager()->Enabled()) {
if (KafkaManager()->Enabled() && !AP_WS_Server()->KafkaDisableState()) {
KafkaManager()->PostMessage(KafkaTopics::STATE, SerialNumber_, *ParamsObj);
}

View File

@@ -35,8 +35,7 @@ namespace OpenWifi {
}
if (TelemetryWebSocketRefCount_) {
if (now < TelemetryWebSocketTimer_) {
// std::cout << SerialNumber_ << ": Updating WebSocket telemetry" <<
// std::endl;
TelemetryWebSocketPackets_++;
State_.websocketPackets = TelemetryWebSocketPackets_;
TelemetryStream()->NotifyEndPoint(SerialNumberInt_, KafkaPayload);
@@ -46,7 +45,6 @@ namespace OpenWifi {
}
if (TelemetryKafkaRefCount_) {
if (KafkaManager()->Enabled() && now < TelemetryKafkaTimer_) {
// std::cout << SerialNumber_ << ": Updating Kafka telemetry" << std::endl;
TelemetryKafkaPackets_++;
State_.kafkaPackets = TelemetryKafkaPackets_;
KafkaManager()->PostMessage(KafkaTopics::DEVICE_TELEMETRY, SerialNumber_,

View File

@@ -1,62 +0,0 @@
//
// Created by stephane bourque on 2022-02-03.
//
#pragma once
#include <mutex>
#include <string>
#include "Poco/Environment.h"
#include "Poco/Net/SocketAcceptor.h"
#include "framework/utils.h"
namespace OpenWifi {
class AP_WS_ReactorThreadPool {
public:
explicit AP_WS_ReactorThreadPool() {
NumberOfThreads_ = Poco::Environment::processorCount() * 4;
if (NumberOfThreads_ == 0)
NumberOfThreads_ = 4;
}
~AP_WS_ReactorThreadPool() { Stop(); }
void Start() {
for (uint64_t i = 0; i < NumberOfThreads_; ++i) {
auto NewReactor = std::make_unique<Poco::Net::SocketReactor>();
auto NewThread = std::make_unique<Poco::Thread>();
NewThread->start(*NewReactor);
std::string ThreadName{"ap:react:" + std::to_string(i)};
Utils::SetThreadName(*NewThread, ThreadName.c_str());
Reactors_.emplace_back(std::move(NewReactor));
Threads_.emplace_back(std::move(NewThread));
}
}
void Stop() {
for (auto &i : Reactors_)
i->stop();
for (auto &i : Threads_) {
i->join();
}
Reactors_.clear();
Threads_.clear();
}
Poco::Net::SocketReactor &NextReactor() {
std::lock_guard Lock(Mutex_);
NextReactor_++;
NextReactor_ %= NumberOfThreads_;
return *Reactors_[NextReactor_];
}
private:
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_;
};
} // namespace OpenWifi

77
src/AP_WS_Reactor_Pool.h Normal file
View File

@@ -0,0 +1,77 @@
//
// Created by stephane bourque on 2022-02-03.
//
#pragma once
#include <mutex>
#include <string>
#include <framework/utils.h>
#include <Poco/Environment.h>
#include <Poco/Net/SocketAcceptor.h>
#include <Poco/Data/SessionPool.h>
#include <StorageService.h>
namespace OpenWifi {
class AP_WS_ReactorThreadPool {
public:
explicit AP_WS_ReactorThreadPool(Poco::Logger &Logger) : Logger_(Logger) {
NumberOfThreads_ = Poco::Environment::processorCount() * 4;
if (NumberOfThreads_ == 0)
NumberOfThreads_ = 8;
NumberOfThreads_ = std::min(NumberOfThreads_, (std::uint64_t) 128);
}
~AP_WS_ReactorThreadPool() { Stop(); }
void Start() {
Reactors_.reserve(NumberOfThreads_);
DbSessions_.reserve(NumberOfThreads_);
Threads_.reserve(NumberOfThreads_);
Logger_.information(fmt::format("WebSocket Processor: starting {} threads.", NumberOfThreads_));
for (uint64_t i = 0; i < NumberOfThreads_; ++i) {
auto NewReactor = std::make_shared<Poco::Net::SocketReactor>();
auto NewThread = std::make_unique<Poco::Thread>();
NewThread->start(*NewReactor);
std::string ThreadName{"ap:react:" + std::to_string(i)};
Utils::SetThreadName(*NewThread, ThreadName.c_str());
Reactors_.emplace_back(std::move(NewReactor));
Threads_.emplace_back(std::move(NewThread));
DbSessions_.emplace_back(std::make_shared<LockedDbSession>());
}
Logger_.information(fmt::format("WebSocket Processor: {} threads started.", NumberOfThreads_));
}
void Stop() {
for (auto &i : Reactors_)
i->stop();
for (auto &i : Threads_) {
i->join();
}
Reactors_.clear();
Threads_.clear();
DbSessions_.clear();
}
auto NextReactor() {
std::lock_guard Lock(Mutex_);
NextReactor_++;
NextReactor_ %= NumberOfThreads_;
return std::make_pair(Reactors_[NextReactor_], DbSessions_[NextReactor_]);
}
private:
std::mutex Mutex_;
uint64_t NumberOfThreads_;
uint64_t NextReactor_ = 0;
std::vector<std::shared_ptr<Poco::Net::SocketReactor>> Reactors_;
std::vector<std::unique_ptr<Poco::Thread>> Threads_;
std::vector<std::shared_ptr<LockedDbSession>> DbSessions_;
Poco::Logger &Logger_;
};
} // namespace OpenWifi

View File

@@ -6,32 +6,66 @@
// Arilia Wireless Inc.
//
#include "Poco/Net/Context.h"
#include "Poco/Net/HTTPHeaderStream.h"
#include "Poco/Net/HTTPServerRequest.h"
#include <Poco/Net/Context.h>
#include <Poco/Net/HTTPHeaderStream.h>
#include <Poco/Net/HTTPServerRequest.h>
#include "AP_WS_Connection.h"
#include "AP_WS_Server.h"
#include "ConfigurationCache.h"
#include "TelemetryStream.h"
#include <AP_WS_Connection.h>
#include <AP_WS_Server.h>
#include <ConfigurationCache.h>
#include <TelemetryStream.h>
#include "UI_GW_WebSocketNotifications.h"
#include "fmt/format.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.h"
#include <fmt/format.h>
#include <framework/MicroServiceFuncs.h>
#include <framework/utils.h>
#include <framework/KafkaManager.h>
#include <UI_GW_WebSocketNotifications.h>
namespace OpenWifi {
void AP_WS_RequestHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response) {
try {
AP_WS_Server()->AddConnection(
id_, std::make_shared<AP_WS_Connection>(request, response, id_, Logger_,
AP_WS_Server()->NextReactor()));
} catch (...) {
poco_warning(Logger_, "Exception during WS creation");
class AP_WS_RequestHandler : public Poco::Net::HTTPRequestHandler {
public:
explicit AP_WS_RequestHandler(Poco::Logger &L, std::uint64_t session_id) : Logger_(L),
session_id_(session_id) {
};
void handleRequest( Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response) override {
try {
auto NewConnection = std::make_shared<AP_WS_Connection>(request, response, session_id_, Logger_,
AP_WS_Server()->NextReactor());
AP_WS_Server()->AddConnection(NewConnection);
NewConnection->Start();
} catch (...) {
poco_warning(Logger_, "Exception during WS creation");
}
};
private:
Poco::Logger &Logger_;
std::uint64_t session_id_;
};
class AP_WS_RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
inline explicit AP_WS_RequestHandlerFactory(Poco::Logger &L) : Logger_(L) {}
inline Poco::Net::HTTPRequestHandler *
createRequestHandler(const Poco::Net::HTTPServerRequest &request) override {
if (request.find("Upgrade") != request.end() &&
Poco::icompare(request["Upgrade"], "websocket") == 0) {
Utils::SetThreadName("ws:conn-init");
session_id_++;
return new AP_WS_RequestHandler(Logger_, session_id_);
} else {
return nullptr;
}
}
private:
Poco::Logger &Logger_;
inline static std::atomic_uint64_t session_id_ = 0;
};
bool AP_WS_Server::ValidateCertificate(const std::string &ConnectionId,
@@ -57,7 +91,7 @@ namespace OpenWifi {
SessionTimeOut_ = MicroServiceConfigGetInt("openwifi.session.timeout", 10*60);
Reactor_pool_ = std::make_unique<AP_WS_ReactorThreadPool>();
Reactor_pool_ = std::make_unique<AP_WS_ReactorThreadPool>(Logger());
Reactor_pool_->Start();
for (const auto &Svr : ConfigServersList_) {
@@ -135,6 +169,9 @@ namespace OpenWifi {
WebServerHttpParams);
WebServers_.push_back(std::move(NewWebServer));
}
KafkaDisableState_ = MicroServiceConfigGetBool("openwifi.kafka.disablestate", false);
KafkaDisableHealthChecks_ = MicroServiceConfigGetBool("openwifi.kafka.disablehealthchecks", false);
}
for (auto &server : WebServers_) {
@@ -156,243 +193,398 @@ namespace OpenWifi {
UseDefaultConfig_ = true;
}
SimulatorId_ = MicroServiceConfigGetString("simulatorid", "");
SimulatorId_ = Poco::toLower(MicroServiceConfigGetString("simulatorid", ""));
SimulatorEnabled_ = !SimulatorId_.empty();
Utils::SetThreadName(ReactorThread_, "dev:react:head");
GarbageCollectorCallback_ = std::make_unique<Poco::TimerCallback<AP_WS_Server>>(
*this, &AP_WS_Server::onGarbageCollecting);
Timer_.setStartInterval(10 * 1000);
Timer_.setPeriodicInterval(10 * 1000); // every minute
Timer_.start(*GarbageCollectorCallback_, MicroServiceTimerPool());
Running_ = true;
GarbageCollector_.setName("ws:garbage");
GarbageCollector_.start(*this);
std::thread CleanupThread([this](){ CleanupSessions(); });
CleanupThread.detach();
return 0;
}
void AP_WS_Server::onGarbageCollecting([[maybe_unused]] Poco::Timer &timer) {
static uint64_t last_log = Utils::Now(), last_zombie_run = 0;
auto now = Utils::Now();
void AP_WS_Server::CleanupSessions() {
{
{
std::lock_guard SessionLock(SessionMutex_);
if (!Garbage_.empty()) {
Garbage_.clear();
while(Running_) {
std::this_thread::sleep_for(std::chrono::seconds(10));
while(Running_ && !CleanupSessions_.empty()) {
std::pair<uint64_t, uint64_t> Session;
{
std::lock_guard G(CleanupMutex_);
Session = CleanupSessions_.front();
CleanupSessions_.pop_front();
}
}
uint64_t total_connected_time = 0;
if(now-last_zombie_run > 20) {
poco_information(Logger(), fmt::format("Garbage collecting..."));
std::vector<std::uint64_t> SessionsToRemove;
NumberOfConnectedDevices_ = 0;
NumberOfConnectingDevices_ = 0;
AverageDeviceConnectionTime_ = 0;
last_zombie_run = now;
for(int hashIndex=0;hashIndex<256;hashIndex++) {
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto hint = SerialNumbers_[hashIndex].begin();
while (hint != end(SerialNumbers_[hashIndex])) {
if (hint->second.second == nullptr) {
hint = SerialNumbers_[hashIndex].erase(hint);
} else if ((now - hint->second.second->State_.LastContact) >
SessionTimeOut_) {
hint->second.second->EndConnection(false);
poco_information(
Logger(),
fmt::format(
"{}: Session seems idle. Controller disconnecting device.",
hint->second.second->SerialNumber_));
SessionsToRemove.emplace_back(hint->second.first);
Garbage_.push_back(hint->second.second);
hint = SerialNumbers_[hashIndex].erase(hint);
} else if (hint->second.second->State_.Connected) {
NumberOfConnectedDevices_++;
total_connected_time += (now - hint->second.second->State_.started);
hint++;
} else {
NumberOfConnectingDevices_++;
hint++;
}
}
}
if(SessionsToRemove.empty()) {
poco_information(Logger(), fmt::format("Removing {} sessions.", SessionsToRemove.size()));
std::lock_guard Lock(SessionMutex_);
for (const auto &Session : SessionsToRemove) {
Sessions_.erase(Session);
}
}
AverageDeviceConnectionTime_ =
NumberOfConnectedDevices_ > 0 ? total_connected_time / NumberOfConnectedDevices_
: 0;
poco_information(Logger(), fmt::format("Garbage collecting done..."));
} else {
std::lock_guard SessionLock(SessionMutex_);
NumberOfConnectedDevices_ = Sessions_.size();
AverageDeviceConnectionTime_ += 10;
}
if ((now - last_log) > 120) {
last_log = now;
poco_information(Logger(),
fmt::format("Active AP connections: {} Connecting: {} Average connection time: {} seconds",
NumberOfConnectedDevices_, NumberOfConnectingDevices_,
AverageDeviceConnectionTime_));
poco_trace(this->Logger(),fmt::format("Cleaning up session: {} for device: {}", Session.first, Utils::IntToSerialNumber(Session.second)));
EndSession(Session.first, Session.second);
}
}
}
GWWebSocketNotifications::NumberOfConnection_t Notification;
Notification.content.numberOfConnectingDevices = NumberOfConnectingDevices_;
Notification.content.numberOfDevices = NumberOfConnectedDevices_;
Notification.content.averageConnectedTime = AverageDeviceConnectionTime_;
GetTotalDataStatistics(Notification.content.tx,Notification.content.rx);
GWWebSocketNotifications::NumberOfConnections(Notification);
void AP_WS_Server::run() {
uint64_t last_log = Utils::Now(),
last_zombie_run = 0,
last_garbage_run = 0;
Poco::JSON::Object KafkaNotification;
Notification.to_json(KafkaNotification);
Poco::Logger &LocalLogger = Poco::Logger::create(
"WS-Session-Janitor", Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel());
Poco::JSON::Object FullEvent;
FullEvent.set("type", "load-update");
FullEvent.set("timestamp", now);
FullEvent.set("payload", KafkaNotification);
while(Running_) {
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, "system", FullEvent);
if(!Poco::Thread::trySleep(30000)) {
break;
}
LocalLogger.information(fmt::format("Garbage collecting starting run." ));
uint64_t total_connected_time = 0, now = Utils::Now();
if(now-last_zombie_run > 60) {
try {
poco_information(LocalLogger,
fmt::format("Garbage collecting zombies... (step 1)"));
NumberOfConnectingDevices_ = 0;
AverageDeviceConnectionTime_ = 0;
int waits = 0;
for (int hashIndex = 0; hashIndex < MACHash::HashMax(); hashIndex++) {
last_zombie_run = now;
waits = 0;
while (true) {
if (SerialNumbersMutex_[hashIndex].try_lock()) {
waits = 0;
auto hint = SerialNumbers_[hashIndex].begin();
while (hint != end(SerialNumbers_[hashIndex])) {
if (hint->second == nullptr) {
poco_information(
LocalLogger,
fmt::format("Dead device found in hash index {}", hashIndex));
hint = SerialNumbers_[hashIndex].erase(hint);
} else {
auto Device = hint->second;
auto RightNow = Utils::Now();
if (Device->Dead_) {
AddCleanupSession(Device->State_.sessionId, Device->SerialNumberInt_);
++hint;
// hint = SerialNumbers_[hashIndex].erase(hint);
} else if (RightNow > Device->LastContact_ &&
(RightNow - Device->LastContact_) > SessionTimeOut_) {
poco_information(
LocalLogger,
fmt::format(
"{}: Session seems idle. Controller disconnecting device.",
Device->SerialNumber_));
// hint = SerialNumbers_[hashIndex].erase(hint);
AddCleanupSession(Device->State_.sessionId, Device->SerialNumberInt_);
++hint;
} else {
if (Device->State_.Connected) {
total_connected_time +=
(RightNow - Device->State_.started);
}
++hint;
}
}
}
SerialNumbersMutex_[hashIndex].unlock();
break;
} else if (waits < 5) {
waits++;
Poco::Thread::trySleep(10);
} else {
break;
}
}
}
poco_information(LocalLogger, fmt::format("Garbage collecting zombies... (step 2)"));
LeftOverSessions_ = 0;
for (int i = 0; i < SessionHash::HashMax(); i++) {
waits = 0;
while (true) {
if (SessionMutex_[i].try_lock()) {
waits = 0;
auto hint = Sessions_[i].begin();
auto RightNow = Utils::Now();
while (hint != end(Sessions_[i])) {
if (hint->second == nullptr) {
hint = Sessions_[i].erase(hint);
} else if (hint->second->Dead_) {
// hint = Sessions_[i].erase(hint);
AddCleanupSession(hint->second->State_.sessionId, hint->second->SerialNumberInt_);
++hint;
} else if (RightNow > hint->second->LastContact_ &&
(RightNow - hint->second->LastContact_) >
SessionTimeOut_) {
poco_information(
LocalLogger,
fmt::format("{}: Session seems idle. Controller disconnecting device.",
hint->second->SerialNumber_));
AddCleanupSession(hint->second->State_.sessionId, hint->second->SerialNumberInt_);
++hint;
// hint = Sessions_[i].erase(hint);
} else {
++LeftOverSessions_;
++hint;
}
}
SessionMutex_[i].unlock();
break;
} else if (waits < 5) {
Poco::Thread::trySleep(10);
waits++;
} else {
break;
}
}
}
AverageDeviceConnectionTime_ = NumberOfConnectedDevices_ > 0
? total_connected_time / NumberOfConnectedDevices_
: 0;
poco_information(LocalLogger, fmt::format("Garbage collecting zombies done..."));
} catch (const Poco::Exception &E) {
poco_error(LocalLogger, fmt::format("Poco::Exception: Garbage collecting zombies failed: {}", E.displayText()));
} catch (const std::exception &E) {
poco_error(LocalLogger, fmt::format("std::exception: Garbage collecting zombies failed: {}", E.what()));
} catch (...) {
poco_error(LocalLogger, fmt::format("exception:Garbage collecting zombies failed: {}", "unknown"));
}
}
if(NumberOfConnectedDevices_) {
if (last_garbage_run > 0) {
AverageDeviceConnectionTime_ += (now - last_garbage_run);
}
}
try {
if ((now - last_log) > 60) {
last_log = now;
poco_information(
LocalLogger,
fmt::format("Active AP connections: {} Connecting: {} Average connection time: {} seconds. Left Over Sessions: {}",
NumberOfConnectedDevices_, NumberOfConnectingDevices_,
AverageDeviceConnectionTime_, LeftOverSessions_));
}
GWWebSocketNotifications::NumberOfConnection_t Notification;
Notification.content.numberOfConnectingDevices = NumberOfConnectingDevices_;
Notification.content.numberOfDevices = NumberOfConnectedDevices_;
Notification.content.averageConnectedTime = AverageDeviceConnectionTime_;
GetTotalDataStatistics(Notification.content.tx, Notification.content.rx);
GWWebSocketNotifications::NumberOfConnections(Notification);
Poco::JSON::Object KafkaNotification;
Notification.to_json(KafkaNotification);
Poco::JSON::Object FullEvent;
FullEvent.set("type", "load-update");
FullEvent.set("timestamp", now);
FullEvent.set("payload", KafkaNotification);
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, "system", FullEvent);
LocalLogger.information(fmt::format("Garbage collection finished run."));
last_garbage_run = now;
} catch (const Poco::Exception &E) {
LocalLogger.error(fmt::format("Poco::Exception: Garbage collecting failed: {}", E.displayText()));
} catch (const std::exception &E) {
LocalLogger.error(fmt::format("std::exception: Garbage collecting failed: {}", E.what()));
} catch (...) {
LocalLogger.error(fmt::format("exception:Garbage collecting failed: {}", "unknown"));
}
}
LocalLogger.information(fmt::format("Garbage collector done for the day." ));
}
void AP_WS_Server::Stop() {
poco_information(Logger(), "Stopping...");
Running_ = false;
Timer_.stop();
GarbageCollector_.wakeUp();
GarbageCollector_.join();
for (auto &server : WebServers_) {
server->stopAll();
}
Reactor_pool_->Stop();
Reactor_.stop();
ReactorThread_.join();
poco_information(Logger(), "Stopped...");
}
bool AP_WS_Server::GetStatistics(uint64_t SerialNumber, std::string &Statistics) const {
auto hashIndex = Utils::CalculateMacAddressHash(SerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
if (Device == SerialNumbers_[hashIndex].end() || Device->second.second == nullptr) {
return false;
bool AP_WS_Server::GetHealthDevices(std::uint64_t lowLimit, std::uint64_t highLimit, std::vector<std::string> & SerialNumbers) {
SerialNumbers.clear();
for(int i=0;i<SessionHash::HashMax();i++) {
std::lock_guard Lock(SessionMutex_[i]);
for (const auto &connection : Sessions_[i]) {
if (connection.second->RawLastHealthcheck_.Sanity >= lowLimit &&
connection.second->RawLastHealthcheck_.Sanity <= highLimit) {
SerialNumbers.push_back(connection.second->SerialNumber_);
}
}
}
Device->second.second->GetLastStats(Statistics);
return true;
}
bool AP_WS_Server::GetStatistics(uint64_t SerialNumber, std::string &Statistics) const {
std::shared_ptr<AP_WS_Connection> Connection;
{
auto hashIndex = MACHash::Hash(SerialNumber);
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == SerialNumbers_[hashIndex].end() || DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
}
Connection->GetLastStats(Statistics);
return true;
}
bool AP_WS_Server::GetState(uint64_t SerialNumber, GWObjects::ConnectionState &State) const {
auto hashIndex = Utils::CalculateMacAddressHash(SerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
if (Device == SerialNumbers_[hashIndex].end() || Device->second.second == nullptr) {
return false;
std::shared_ptr<AP_WS_Connection> Connection;
{
auto hashIndex = MACHash::Hash(SerialNumber);
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == SerialNumbers_[hashIndex].end() ||
DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
}
Device->second.second->GetState(State);
Connection->GetState(State);
return true;
}
bool AP_WS_Server::GetHealthcheck(uint64_t SerialNumber,
GWObjects::HealthCheck &CheckData) const {
auto hashIndex = Utils::CalculateMacAddressHash(SerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
if (Device == SerialNumbers_[hashIndex].end() || Device->second.second == nullptr) {
return false;
std::shared_ptr<AP_WS_Connection> Connection;
{
auto hashIndex = MACHash::Hash(SerialNumber);
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
if (Device == SerialNumbers_[hashIndex].end() || Device->second == nullptr) {
return false;
}
Connection = Device->second;
}
Device->second.second->GetLastHealthCheck(CheckData);
Connection->GetLastHealthCheck(CheckData);
return true;
}
void AP_WS_Server::SetSessionDetails(uint64_t connection_id, uint64_t SerialNumber) {
std::lock_guard SessionLock(SessionMutex_);
auto Conn = Sessions_.find(connection_id);
if (Conn == end(Sessions_))
return;
auto hashIndex = Utils::CalculateMacAddressHash(SerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto CurrentSerialNumber = SerialNumbers_[hashIndex].find(SerialNumber);
if ((CurrentSerialNumber == SerialNumbers_[hashIndex].end()) ||
(CurrentSerialNumber->second.first < connection_id)) {
SerialNumbers_[hashIndex][SerialNumber] = std::make_pair(connection_id, Conn->second);
return;
void AP_WS_Server::StartSession(uint64_t session_id, uint64_t SerialNumber) {
auto sessionHash = SessionHash::Hash(session_id);
std::shared_ptr<AP_WS_Connection> Connection;
{
std::lock_guard SessionLock(SessionMutex_[sessionHash]);
auto SessionHint = Sessions_[sessionHash].find(session_id);
if (SessionHint == end(Sessions_[sessionHash])) {
return;
}
Connection = SessionHint->second;
Sessions_[sessionHash].erase(SessionHint);
}
auto deviceHash = MACHash::Hash(SerialNumber);
std::lock_guard DeviceLock(SerialNumbersMutex_[deviceHash]);
SerialNumbers_[deviceHash][SerialNumber] = Connection;
}
bool AP_WS_Server::EndSession(uint64_t session_id, uint64_t SerialNumber) {
std::lock_guard SessionLock(SessionMutex_);
auto Session = Sessions_.find(session_id);
if (Session == end(Sessions_))
return false;
Garbage_.push_back(Session->second);
auto hashIndex = Utils::CalculateMacAddressHash(SerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
if (Device == end(SerialNumbers_[hashIndex])) {
Sessions_.erase(Session);
return false;
{
poco_trace(Logger(), fmt::format("Ending session 1: {} for device: {}", session_id, Utils::IntToSerialNumber(SerialNumber)));
auto sessionHash = SessionHash::Hash(session_id);
std::lock_guard SessionLock(SessionMutex_[sessionHash]);
Sessions_[sessionHash].erase(session_id);
poco_trace(Logger(), fmt::format("Ended session 1: {} for device: {}", session_id, Utils::IntToSerialNumber(SerialNumber)));
}
if (Device->second.first == session_id) {
Sessions_.erase(Session);
SerialNumbers_[hashIndex].erase(Device);
return true;
{
auto hashIndex = MACHash::Hash(SerialNumber);
poco_trace(Logger(), fmt::format("Ending session 2.0: {} for device: {} hi:{}", session_id, Utils::IntToSerialNumber(SerialNumber), hashIndex));
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
poco_trace(Logger(), fmt::format("Ending session 2.1: {} for device: {} hi:{}", session_id, Utils::IntToSerialNumber(SerialNumber), hashIndex));
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
poco_trace(Logger(), fmt::format("Ending session 2.2: {} for device: {} hi:{}", session_id, Utils::IntToSerialNumber(SerialNumber), hashIndex));
if (DeviceHint == SerialNumbers_[hashIndex].end()
|| DeviceHint->second == nullptr
|| DeviceHint->second->State_.sessionId != session_id) {
poco_trace(Logger(), fmt::format("Did not end session 2: {} for device: {}", session_id, Utils::IntToSerialNumber(SerialNumber)));
return false;
}
SerialNumbers_[hashIndex].erase(DeviceHint);
poco_trace(Logger(), fmt::format("Ended session 2: {} for device: {}", session_id, Utils::IntToSerialNumber(SerialNumber)));
}
Sessions_.erase(Session);
return false;
return true;
}
bool AP_WS_Server::Connected(uint64_t SerialNumber,
GWObjects::DeviceRestrictions &Restrictions) const {
auto hashIndex = Utils::CalculateMacAddressHash(SerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
if (Device == end(SerialNumbers_[hashIndex]) || Device->second.second == nullptr) {
std::shared_ptr<AP_WS_Connection> Connection;
{
auto hashIndex = MACHash::Hash(SerialNumber);
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
}
if(Connection->Dead_) {
return false;
}
Device->second.second->GetRestrictions(Restrictions);
return Device->second.second->State_.Connected;
Restrictions = Connection->GetRestrictions();
return Connection->State_.Connected;
}
bool AP_WS_Server::Connected(uint64_t SerialNumber) const {
auto hashIndex = Utils::CalculateMacAddressHash(SerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
if (Device == end(SerialNumbers_[hashIndex]) || Device->second.second == nullptr) {
std::shared_ptr<AP_WS_Connection> Connection;
{
auto hashIndex = MACHash::Hash(SerialNumber);
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
}
if(Connection->Dead_) {
return false;
}
return Device->second.second->State_.Connected;
return Connection->State_.Connected;
}
bool AP_WS_Server::SendFrame(uint64_t SerialNumber, const std::string &Payload) const {
auto hashIndex = Utils::CalculateMacAddressHash(SerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
if (Device == end(SerialNumbers_[hashIndex]) || Device->second.second == nullptr) {
auto hashIndex = MACHash::Hash(SerialNumber);
std::shared_ptr<AP_WS_Connection> Connection;
{
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
}
if(Connection->Dead_) {
return false;
}
try {
return Device->second.second->Send(Payload);
return Connection->Send(Payload);
} catch (...) {
poco_debug(Logger(), fmt::format(": SendFrame: Could not send data to device '{}'",
Utils::IntToSerialNumber(SerialNumber)));
@@ -401,48 +593,64 @@ namespace OpenWifi {
}
void AP_WS_Server::StopWebSocketTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
auto hashIndex = Utils::CalculateMacAddressHash(SerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
if (Device == end(SerialNumbers_[hashIndex]) || Device->second.second == nullptr) {
return;
std::shared_ptr<AP_WS_Connection> Connection;
{
auto hashIndex = MACHash::Hash(SerialNumber);
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
if (Device == end(SerialNumbers_[hashIndex]) || Device->second == nullptr) {
return;
}
Connection = Device->second;
}
Device->second.second->StopWebSocketTelemetry(RPCID);
Connection->StopWebSocketTelemetry(RPCID);
}
void
AP_WS_Server::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber,
uint64_t Interval, uint64_t Lifetime,
const std::vector<std::string> &TelemetryTypes) {
auto hashIndex = Utils::CalculateMacAddressHash(SerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
if (Device == end(SerialNumbers_[hashIndex]) || Device->second.second == nullptr) {
return;
std::shared_ptr<AP_WS_Connection> Connection;
{
auto hashIndex = MACHash::Hash(SerialNumber);
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return;
}
Connection = DeviceHint->second;
}
Device->second.second->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime, TelemetryTypes);
Connection->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime, TelemetryTypes);
}
void AP_WS_Server::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber,
uint64_t Interval, uint64_t Lifetime,
const std::vector<std::string> &TelemetryTypes) {
auto hashIndex = Utils::CalculateMacAddressHash(SerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
if (Device == end(SerialNumbers_[hashIndex]) || Device->second.second == nullptr) {
return;
std::shared_ptr<AP_WS_Connection> Connection;
{
auto hashIndex = MACHash::Hash(SerialNumber);
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return;
}
Connection = DeviceHint->second;
}
Device->second.second->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime, TelemetryTypes);
Connection->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime, TelemetryTypes);
}
void AP_WS_Server::StopKafkaTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
auto hashIndex = Utils::CalculateMacAddressHash(SerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
if (Device == end(SerialNumbers_[hashIndex]) || Device->second.second == nullptr) {
return;
std::shared_ptr<AP_WS_Connection> Connection;
{
auto hashIndex = MACHash::Hash(SerialNumber);
std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return;
}
Connection = DeviceHint->second;
}
Device->second.second->StopKafkaTelemetry(RPCID);
Connection->StopKafkaTelemetry(RPCID);
}
void AP_WS_Server::GetTelemetryParameters(
@@ -451,14 +659,18 @@ namespace OpenWifi {
uint64_t &TelemetryWebSocketCount, uint64_t &TelemetryKafkaCount,
uint64_t &TelemetryWebSocketPackets, uint64_t &TelemetryKafkaPackets) {
auto hashIndex = Utils::CalculateMacAddressHash(SerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
if (Device == end(SerialNumbers_[hashIndex]) || Device->second.second == nullptr) {
return;
std::shared_ptr<AP_WS_Connection> Connection;
{
auto hashIndex = MACHash::Hash(SerialNumber);
std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return;
}
Connection = DeviceHint->second;
}
Device->second.second->GetTelemetryParameters(TelemetryRunning, TelemetryInterval,
Connection->GetTelemetryParameters(TelemetryRunning, TelemetryInterval,
TelemetryWebSocketTimer, TelemetryKafkaTimer,
TelemetryWebSocketCount, TelemetryKafkaCount,
TelemetryWebSocketPackets, TelemetryKafkaPackets);
@@ -467,16 +679,24 @@ namespace OpenWifi {
bool AP_WS_Server::SendRadiusAccountingData(const std::string &SerialNumber,
const unsigned char *buffer, std::size_t size) {
auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber);
auto hashIndex = Utils::CalculateMacAddressHash(IntSerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(IntSerialNumber);
if (Device == end(SerialNumbers_[hashIndex]) || Device->second.second == nullptr) {
std::shared_ptr<AP_WS_Connection> Connection;
{
auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber);
auto hashIndex = MACHash::Hash(IntSerialNumber);
std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(IntSerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
}
if(Connection->Dead_) {
return false;
}
try {
return Device->second.second->SendRadiusAccountingData(buffer, size);
return Connection->SendRadiusAccountingData(buffer, size);
} catch (...) {
poco_debug(
Logger(),
@@ -488,16 +708,24 @@ namespace OpenWifi {
bool AP_WS_Server::SendRadiusAuthenticationData(const std::string &SerialNumber,
const unsigned char *buffer, std::size_t size) {
auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber);
auto hashIndex = Utils::CalculateMacAddressHash(IntSerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(IntSerialNumber);
if (Device == end(SerialNumbers_[hashIndex]) || Device->second.second == nullptr) {
std::shared_ptr<AP_WS_Connection> Connection;
{
auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber);
auto hashIndex = MACHash::Hash(IntSerialNumber);
std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(IntSerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
}
if(Connection->Dead_) {
return false;
}
try {
return Device->second.second->SendRadiusAuthenticationData(buffer, size);
return Connection->SendRadiusAuthenticationData(buffer, size);
} catch (...) {
poco_debug(
Logger(),
@@ -509,16 +737,23 @@ namespace OpenWifi {
bool AP_WS_Server::SendRadiusCoAData(const std::string &SerialNumber,
const unsigned char *buffer, std::size_t size) {
auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber);
auto hashIndex = Utils::CalculateMacAddressHash(IntSerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto Device = SerialNumbers_[hashIndex].find(IntSerialNumber);
if (Device == end(SerialNumbers_[hashIndex]) || Device->second.second == nullptr) {
return false;
std::shared_ptr<AP_WS_Connection> Connection;
{
auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber);
auto hashIndex = MACHash::Hash(IntSerialNumber);
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(IntSerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
}
if(Connection->Dead_) {
return false;
}
try {
return Device->second.second->SendRadiusCoAData(buffer, size);
return Connection->SendRadiusCoAData(buffer, size);
} catch (...) {
poco_debug(Logger(),
fmt::format(": SendRadiusCoAData: Could not send data to device '{}'",

View File

@@ -24,46 +24,51 @@
#include "Poco/Timer.h"
#include "AP_WS_Connection.h"
#include "AP_WS_ReactorPool.h"
#include "AP_WS_Reactor_Pool.h"
#include "framework/SubSystemServer.h"
#include "framework/utils.h"
namespace OpenWifi {
class AP_WS_RequestHandler : public Poco::Net::HTTPRequestHandler {
constexpr uint MACHashMax = 256;
constexpr uint MACHashMask = MACHashMax-1;
class MACHash {
public:
explicit AP_WS_RequestHandler(Poco::Logger &L, uint64_t id) : Logger_(L), id_(id){};
void handleRequest(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response) override;
private:
Poco::Logger &Logger_;
uint64_t id_ = 0;
};
class AP_WS_RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
inline explicit AP_WS_RequestHandlerFactory(Poco::Logger &L) : Logger_(L) {}
inline Poco::Net::HTTPRequestHandler *
createRequestHandler(const Poco::Net::HTTPServerRequest &request) override {
if (request.find("Upgrade") != request.end() &&
Poco::icompare(request["Upgrade"], "websocket") == 0) {
Utils::SetThreadName("ws:conn-init");
return new AP_WS_RequestHandler(Logger_, id_++);
} else {
return nullptr;
[[nodiscard]] static inline uint16_t Hash(std::uint64_t value) {
uint8_t hash = 0, i=6;
while(i) {
hash ^= (value & MACHashMask) + 1;
value >>= 8;
--i;
}
return hash;
}
private:
Poco::Logger &Logger_;
inline static uint64_t id_ = 1;
[[nodiscard]] static inline uint16_t Hash(const std::string & value) {
return Hash(Utils::MACToInt(value));
}
[[nodiscard]] static inline uint16_t HashMax() {
return MACHashMax;
}
};
class AP_WS_Server : public SubSystemServer {
constexpr uint SessionHashMax = 256;
constexpr uint SessionHashMask = SessionHashMax-1;
class SessionHash {
public:
[[nodiscard]] static inline uint16_t Hash(std::uint64_t value) {
return (value & SessionHashMask);
}
[[nodiscard]] static inline uint16_t HashMax() {
return SessionHashMax;
}
};
class AP_WS_Server : public SubSystemServer, public Poco::Runnable {
public:
static auto instance() {
static auto instance_ = new AP_WS_Server;
@@ -77,48 +82,50 @@ namespace OpenWifi {
const Poco::Crypto::X509Certificate &Certificate);
inline bool IsSimSerialNumber(const std::string &SerialNumber) const {
return IsSim(Poco::toLower(SerialNumber)) &&
Poco::toLower(SerialNumber) == Poco::toLower(SimulatorId_);
return IsSim(SerialNumber) &&
SerialNumber == SimulatorId_;
}
inline static bool IsSim(const std::string &SerialNumber) {
return SerialNumber.substr(0, 6) == "53494d";
}
inline bool IsSimEnabled() const { return SimulatorEnabled_; }
inline bool AllowSerialNumberMismatch() const { return AllowSerialNumberMismatch_; }
inline uint64_t MismatchDepth() const { return MismatchDepth_; }
inline bool UseProvisioning() const { return LookAtProvisioning_; }
inline bool UseDefaults() const { return UseDefaultConfig_; }
[[nodiscard]] inline Poco::Net::SocketReactor &NextReactor() {
void run() override; // Garbage collector thread.
[[nodiscard]] inline bool IsSimEnabled() const { return SimulatorEnabled_; }
[[nodiscard]] inline bool AllowSerialNumberMismatch() const { return AllowSerialNumberMismatch_; }
[[nodiscard]] inline uint64_t MismatchDepth() const { return MismatchDepth_; }
[[nodiscard]] inline bool UseProvisioning() const { return LookAtProvisioning_; }
[[nodiscard]] inline bool UseDefaults() const { return UseDefaultConfig_; }
[[nodiscard]] inline bool Running() const { return Running_; }
[[nodiscard]] inline std::pair<std::shared_ptr<Poco::Net::SocketReactor>, std::shared_ptr<LockedDbSession>> NextReactor() {
return Reactor_pool_->NextReactor();
}
[[nodiscard]] inline bool Running() const { return Running_; }
inline void AddConnection(uint64_t session_id,
std::shared_ptr<AP_WS_Connection> Connection) {
std::lock_guard Lock(SessionMutex_);
Sessions_[session_id] = std::move(Connection);
inline void AddConnection(std::shared_ptr<AP_WS_Connection> Connection) {
std::uint64_t sessionHash = SessionHash::Hash(Connection->State_.sessionId);
std::lock_guard SessionLock(SessionMutex_[sessionHash]);
if(Sessions_[sessionHash].find(Connection->State_.sessionId)==end(Sessions_[sessionHash])) {
Sessions_[sessionHash][Connection->State_.sessionId] = std::move(Connection);
}
}
inline bool DeviceRequiresSecureRtty(uint64_t serialNumber) const {
auto hashIndex = Utils::CalculateMacAddressHash(serialNumber);
std::lock_guard G(SerialNumbersMutex_[hashIndex]);
auto Connection = SerialNumbers_[hashIndex].find(serialNumber);
if (Connection==end(SerialNumbers_[hashIndex]) || Connection->second.second==nullptr)
return false;
return Connection->second.second->RttyMustBeSecure_;
[[nodiscard]] inline bool DeviceRequiresSecureRTTY(uint64_t serialNumber) const {
std::shared_ptr<AP_WS_Connection> Connection;
{
auto hashIndex = MACHash::Hash(serialNumber);
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(serialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr)
return false;
Connection = DeviceHint->second;
}
return Connection->RTTYMustBeSecure_;
}
inline bool GetStatistics(const std::string &SerialNumber, std::string &Statistics) const {
return GetStatistics(Utils::SerialNumberToInt(SerialNumber), Statistics);
}
bool GetStatistics(uint64_t SerialNumber, std::string &Statistics) const;
[[nodiscard]] bool GetStatistics(uint64_t SerialNumber, std::string &Statistics) const;
inline bool GetState(const std::string &SerialNumber,
GWObjects::ConnectionState &State) const {
@@ -134,13 +141,7 @@ namespace OpenWifi {
bool Connected(uint64_t SerialNumber, GWObjects::DeviceRestrictions &Restrictions) const;
bool Connected(uint64_t SerialNumber) const;
inline bool SendFrame(const std::string &SerialNumber, const std::string &Payload) const {
return SendFrame(Utils::SerialNumberToInt(SerialNumber), Payload);
}
bool SendFrame(uint64_t SerialNumber, const std::string &Payload) const;
bool SendRadiusAuthenticationData(const std::string &SerialNumber,
const unsigned char *buffer, std::size_t size);
bool SendRadiusAccountingData(const std::string &SerialNumber, const unsigned char *buffer,
@@ -148,9 +149,8 @@ namespace OpenWifi {
bool SendRadiusCoAData(const std::string &SerialNumber, const unsigned char *buffer,
std::size_t size);
void SetSessionDetails(uint64_t connection_id, uint64_t SerialNumber);
bool EndSession(uint64_t connection_id, uint64_t serial_number);
bool EndSessionUnSafe(uint64_t session_id, uint64_t serial_number);
void StartSession(uint64_t session_id, uint64_t SerialNumber);
bool EndSession(uint64_t session_id, uint64_t SerialNumber);
void SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber,
uint64_t Interval, uint64_t Lifetime,
const std::vector<std::string> &TelemetryTypes);
@@ -167,7 +167,9 @@ namespace OpenWifi {
uint64_t &TelemetryWebSocketPackets,
uint64_t &TelemetryKafkaPackets);
void onGarbageCollecting(Poco::Timer &timer);
bool GetHealthDevices(std::uint64_t lowLimit, std::uint64_t highLimit, std::vector<std::string> & SerialNumbers);
// bool ExtendedAttributes(const std::string &serialNumber, bool & hasGPS, std::uint64_t &Sanity,
// std::double_t &MemoryUsed, std::double_t &Load, std::double_t &Temperature);
inline void AverageDeviceStatistics(uint64_t &Connections, uint64_t &AverageConnectionTime,
uint64_t &NumberOfConnectingDevices) const {
@@ -176,94 +178,80 @@ namespace OpenWifi {
NumberOfConnectingDevices = NumberOfConnectingDevices_;
}
inline bool SendFrame(const std::string &SerialNumber, const std::string &Payload) const {
return SendFrame(Utils::SerialNumberToInt(SerialNumber), Payload);
}
inline void AddRX(std::uint64_t bytes) {
std::lock_guard G(StatsMutex_);
RX_ += bytes;
}
inline void AddTX(std::uint64_t bytes) {
std::lock_guard G(StatsMutex_);
TX_ += bytes;
}
inline void GetTotalDataStatistics(std::uint64_t &TX, std::uint64_t &RX) const {
std::lock_guard G(StatsMutex_);
TX = TX_;
RX = RX_;
}
// TOD: move to hash based map.
inline bool GetHealthDevices(std::uint64_t lowLimit, std::uint64_t highLimit, std::vector<std::string> & SerialNumbers) {
std::lock_guard Lock(SessionMutex_);
for(const auto &connection:Sessions_) {
if( connection.second->RawLastHealthcheck_.Sanity>=lowLimit &&
connection.second->RawLastHealthcheck_.Sanity<=highLimit) {
SerialNumbers.push_back(connection.second->SerialNumber_);
}
}
return true;
bool KafkaDisableState() const { return KafkaDisableState_; }
bool KafkaDisableHealthChecks() const { return KafkaDisableHealthChecks_; }
inline void IncrementConnectionCount() {
++NumberOfConnectedDevices_;
}
inline bool ExtendedAttributes(const std::string &serialNumber,
bool & hasGPS,
std::uint64_t &Sanity,
std::double_t &MemoryUsed,
std::double_t &Load,
std::double_t &Temperature
) {
auto serialNumberInt = Utils::SerialNumberToInt(serialNumber);
auto hashIndex = Utils::CalculateMacAddressHash(serialNumberInt);
std::lock_guard G(SerialNumbersMutex_[hashIndex]);
auto session_hint = SerialNumbers_[hashIndex].find(Utils::SerialNumberToInt(serialNumber));
if(session_hint==end(SerialNumbers_[hashIndex])) {
return false;
}
hasGPS = session_hint->second.second->hasGPS;
Sanity = session_hint->second.second->RawLastHealthcheck_.Sanity;
MemoryUsed = session_hint->second.second->memory_used_;
Load = session_hint->second.second->cpu_load_;
Temperature = session_hint->second.second->temperature_;
return true;
inline void DecrementConnectionCount() {
--NumberOfConnectedDevices_;
}
inline void AddCleanupSession(uint64_t session_id, uint64_t SerialNumber) {
std::lock_guard G(CleanupMutex_);
CleanupSessions_.emplace_back(session_id, SerialNumber);
}
void CleanupSessions();
private:
mutable std::mutex SessionMutex_;
mutable std::mutex StatsMutex_;
std::array<std::mutex,SessionHashMax> SessionMutex_;
std::array<std::map<std::uint64_t, std::shared_ptr<AP_WS_Connection>>,SessionHashMax> Sessions_;
using SerialNumberMap = std::map<uint64_t /* serial number */,
std::shared_ptr<AP_WS_Connection>>;
std::array<SerialNumberMap,MACHashMax> SerialNumbers_;
mutable std::array<std::mutex,MACHashMax> SerialNumbersMutex_;
std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_;
std::list<std::unique_ptr<Poco::Net::HTTPServer>> WebServers_;
Poco::ThreadPool DeviceConnectionPool_{"ws:dev-pool", 4, 256};
Poco::Net::SocketReactor Reactor_;
Poco::Thread ReactorThread_;
std::string SimulatorId_;
Poco::ThreadPool DeviceConnectionPool_{"ws:dev-pool", 2, 64};
bool LookAtProvisioning_ = false;
bool UseDefaultConfig_ = true;
bool SimulatorEnabled_ = false;
bool AllowSerialNumberMismatch_ = true;
Poco::Thread CleanupThread_;
std::mutex CleanupMutex_;
std::deque<std::pair<uint64_t, uint64_t>> CleanupSessions_;
std::unique_ptr<AP_WS_ReactorThreadPool> Reactor_pool_;
std::atomic_bool Running_ = false;
std::map<std::uint64_t, std::shared_ptr<AP_WS_Connection>> Sessions_;
using SerialNumberMap = std::map<uint64_t /* serial number */, std::pair<uint64_t /* session id*/,
std::shared_ptr<AP_WS_Connection>>>;
std::uint64_t MismatchDepth_ = 2;
std::array<SerialNumberMap,256> SerialNumbers_;
mutable std::array<std::mutex,256> SerialNumbersMutex_;
std::atomic_bool AllowSerialNumberMismatch_ = true;
std::atomic_uint64_t MismatchDepth_ = 2;
std::uint64_t NumberOfConnectedDevices_ = 0;
std::uint64_t AverageDeviceConnectionTime_ = 0;
std::atomic_uint64_t NumberOfConnectedDevices_ = 0;
std::atomic_uint64_t AverageDeviceConnectionTime_ = 0;
std::uint64_t NumberOfConnectingDevices_ = 0;
std::uint64_t SessionTimeOut_ = 10*60;
std::uint64_t LeftOverSessions_ = 0;
std::atomic_uint64_t TX_=0,RX_=0;
std::vector<std::shared_ptr<AP_WS_Connection>> Garbage_;
std::atomic_bool KafkaDisableState_=false,
KafkaDisableHealthChecks_=false;
std::unique_ptr<Poco::TimerCallback<AP_WS_Server>> GarbageCollectorCallback_;
Poco::Timer Timer_;
Poco::Thread GarbageCollector_;
Poco::Thread GarbageCollector_;
AP_WS_Server() noexcept
: SubSystemServer("WebSocketServer", "WS-SVR", "ucentral.websocket") {}

View File

@@ -10,6 +10,7 @@
#include <string>
#include "framework/MicroServiceFuncs.h"
#include "framework/ow_constants.h"
#include "CentralConfig.h"
#include "nlohmann/json.hpp"
@@ -34,7 +35,7 @@ namespace OpenWifi {
std::lock_guard G(Mutex_);
if (!PlatformsLoaded_)
LoadPlatforms();
auto P = Poco::toUpper(Caps.Platform());
auto P = Poco::toLower(Caps.Platform());
auto Hint = Platforms_.find(Caps.Compatible());
if (Hint == Platforms_.end()) {
Platforms_.insert(std::make_pair(Caps.Compatible(), P));
@@ -68,7 +69,7 @@ namespace OpenWifi {
auto Hint = Platforms_.find(DeviceType);
if (Hint == Platforms_.end())
return "AP";
return Platforms::AP;
return Hint->second;
}
@@ -110,7 +111,7 @@ namespace OpenWifi {
i >> cache;
for (const auto &[Type, Platform] : cache.items()) {
Platforms_[Type] = Platform;
Platforms_[Type] = Poco::toLower(to_string(Platform));
}
} catch (...) {
}

View File

@@ -204,6 +204,17 @@ namespace OpenWifi::Config {
return false;
}
std::uint64_t Config::UUID() {
try {
Poco::JSON::Parser Parser;
auto object = Parser.parse(Config_).extract<Poco::JSON::Object::Ptr>();
if (object->has("uuid"))
return object->get("uuid");
} catch (...) {
}
return 0;
}
bool Config::Valid() {
try {
Poco::JSON::Parser Parser;

View File

@@ -23,6 +23,7 @@ namespace OpenWifi::Config {
[[nodiscard]] std::string get() { return Config_; };
[[nodiscard]] std::string Default();
[[nodiscard]] Poco::JSON::Object::Ptr to_json();
[[nodiscard]] std::uint64_t UUID();
private:
void Init();

View File

@@ -45,11 +45,9 @@ namespace OpenWifi {
std::lock_guard Lock(LocalMutex_);
auto RPC = OutStandingRequests_.find(ID);
if (RPC == OutStandingRequests_.end()) {
// std::cout << __LINE__ << std::endl;
poco_debug(Logger(), fmt::format("({}): RPC {} cannot be found.",
SerialNumberStr, ID));
} else if (RPC->second.SerialNumber != Resp->SerialNumber_) {
// std::cout << __LINE__ << std::endl;
poco_debug(
Logger(),
fmt::format("({}): RPC {} serial number mismatch {}!={}.",
@@ -60,7 +58,6 @@ namespace OpenWifi {
std::chrono::duration<double, std::milli> rpc_execution_time =
std::chrono::high_resolution_clock::now() -
RPC->second.submitted;
// std::cout << __LINE__ << std::endl;
poco_debug(Logger(),
fmt::format("({}): Received RPC answer {}. Command={}",
SerialNumberStr, ID,
@@ -140,7 +137,6 @@ namespace OpenWifi {
}
}
} else {
// std::cout << __LINE__ << std::endl;
}
Command.State = 0;
@@ -163,7 +159,6 @@ namespace OpenWifi {
if (Command.rpc_entry) {
TmpRpcEntry = Command.rpc_entry;
}
// std::cout << __LINE__ << " State=" << Command.State << std::endl;
if (Command.State == 2) {
// look at the payload to see if we should continue or not...
if (Payload->has("result")) {
@@ -173,12 +168,10 @@ namespace OpenWifi {
std::uint64_t Error = Status->get("error");
if (Error == 0) {
// std::cout << __LINE__ << std::endl;
StorageService()->CommandCompleted(Command.UUID, Payload,
rpc_execution_time, true);
Command.State = 1;
} else {
// std::cout << __LINE__ << std::endl;
StorageService()->CommandCompleted(Command.UUID, Payload,
rpc_execution_time, true);
std::string ErrorTxt = Status->get("result");
@@ -186,14 +179,11 @@ namespace OpenWifi {
Command.State = 0;
}
} else {
// std::cout << __LINE__ << std::endl;
}
} else {
// std::cout << __LINE__ << std::endl;
Command.State = 0;
}
} else if (Command.State == 1) {
// std::cout << "Completing script 2 phase commit." << std::endl;
StorageService()->CommandCompleted(Command.UUID, Payload, rpc_execution_time, true);
if (Command.Deferred) {
Reply = false;
@@ -202,7 +192,6 @@ namespace OpenWifi {
}
if (Command.State == 0) {
// std::cout << __LINE__ << " State=" << Command.State << std::endl;
OutStandingRequests_.erase(Command.Id);
}
if (Reply && TmpRpcEntry != nullptr)
@@ -262,8 +251,6 @@ namespace OpenWifi {
for (auto request = OutStandingRequests_.begin(); request != OutStandingRequests_.end();) {
std::chrono::duration<double, std::milli> delta = now - request->second.submitted;
if (delta > 10min) {
// std::cout << __LINE__ << " -->> " << request->second.Id <<
// std::endl;
MyLogger.debug(fmt::format("{}: Command={} for {} Timed out.", request->second.UUID,
APCommands::to_string(request->second.Command),
Utils::IntToSerialNumber(request->second.SerialNumber)));
@@ -275,8 +262,6 @@ namespace OpenWifi {
StorageService()->SetCommandTimedOut(request->second.UUID);
request = OutStandingRequests_.erase(request);
} else {
// std::cout << __LINE__ << " -->> " << request->second.Id <<
// std::endl;
++request;
}
}

View File

@@ -11,12 +11,12 @@
namespace OpenWifi {
class ConfigurationCache {
public:
static ConfigurationCache &instance() {
static ConfigurationCache instance;
static auto instance() {
static auto instance = new ConfigurationCache;
return instance;
}
inline uint64_t CurrentConfig(uint64_t SerialNumber) {
inline uint64_t GetCurrentConfig(std::uint64_t SerialNumber) {
std::lock_guard G(Mutex_);
const auto Hint = Cache_.find(SerialNumber);
if (Hint == end(Cache_))
@@ -24,25 +24,25 @@ namespace OpenWifi {
return Hint->second;
}
inline void Add(uint64_t SerialNumber, uint64_t Id) {
inline void SetCurrentConfig(std::uint64_t SerialNumber, uint64_t Id) {
std::lock_guard G(Mutex_);
Cache_[SerialNumber] = Id;
}
private:
std::recursive_mutex Mutex_;
std::mutex Mutex_;
std::map<uint64_t, uint64_t> Cache_;
};
inline uint64_t GetCurrentConfigurationID(uint64_t SerialNumber) {
return ConfigurationCache::instance().CurrentConfig(SerialNumber);
inline auto GetCurrentConfigurationID(std::uint64_t SerialNumber) {
return ConfigurationCache::instance()->GetCurrentConfig(SerialNumber);
}
inline void SetCurrentConfigurationID(const std::string &SerialNumber, uint64_t ID) {
return ConfigurationCache::instance().Add(Utils::SerialNumberToInt(SerialNumber), ID);
inline void SetCurrentConfigurationID(const std::string &SerialNumber, std::uint64_t ID) {
return ConfigurationCache::instance()->SetCurrentConfig(Utils::SerialNumberToInt(SerialNumber), ID);
}
inline void SetCurrentConfigurationID(uint64_t SerialNumber, uint64_t ID) {
return ConfigurationCache::instance().Add(SerialNumber, ID);
inline void SetCurrentConfigurationID(uint64_t SerialNumber, std::uint64_t ID) {
return ConfigurationCache::instance()->SetCurrentConfig(SerialNumber, ID);
}
} // namespace OpenWifi

View File

@@ -49,7 +49,7 @@ namespace OpenWifi {
SignatureManager(), AP_WS_Server(),
RegulatoryInfo(),
RADIUSSessionTracker(),
AP_WS_ConfigAutoUpgrader(),
AP_WS_ConfigAutoUpgradeAgent(),
FirmwareRevisionCache()
});
return &instance;
@@ -78,7 +78,7 @@ namespace OpenWifi {
if (Id == DeviceType)
return Type;
}
return "AP";
return Platforms::AP;
}
void DaemonPostInitialization(Poco::Util::Application &self) {

View File

@@ -21,7 +21,6 @@ namespace OpenWifi {
void DeviceDashboard::Generate(GWObjects::Dashboard &D, Poco::Logger &Logger) {
if (GeneratingDashboard_.load()) {
// std::cout << "Trying to generate dashboard but already being generated" << std::endl;
while (GeneratingDashboard_.load()) {
Poco::Thread::trySleep(100);
}
@@ -31,7 +30,6 @@ namespace OpenWifi {
GeneratingDashboard_ = true;
ValidDashboard_ = false;
try {
// std::cout << "Generating dashboard." << std::endl;
poco_information(Logger, "DASHBOARD: Generating a new dashboard.");
GWObjects::Dashboard NewData;
StorageService()->AnalyzeCommands(NewData.commands);

View File

@@ -8,12 +8,12 @@
#pragma once
#include "Poco/Net/HTTPRequestHandler.h"
#include "Poco/Net/HTTPRequestHandlerFactory.h"
#include "Poco/Net/HTTPServer.h"
#include "Poco/Net/HTTPServerRequest.h"
#include <Poco/Net/HTTPRequestHandler.h>
#include <Poco/Net/HTTPRequestHandlerFactory.h>
#include <Poco/Net/HTTPServer.h>
#include <Poco/Net/HTTPServerRequest.h>
#include "framework/SubSystemServer.h"
#include <framework/SubSystemServer.h>
namespace OpenWifi {

View File

@@ -50,12 +50,22 @@ namespace OpenWifi {
class DeviceConfigurationChangeKafkaEvent : public GWKafkaEvents {
public:
DeviceConfigurationChangeKafkaEvent(std::uint64_t serialNumber,
std::uint64_t timestamp, const Poco::JSON::Object::Ptr config)
std::uint64_t timestamp,
const Poco::JSON::Object::Ptr config)
: GWKafkaEvents(serialNumber, "unit.configuration_change", timestamp), config_(config) {
}
~DeviceConfigurationChangeKafkaEvent() {
payload_->set("configuration", *config_);
if(config_!= nullptr) {
std::ostringstream os;
config_->stringify(os);
if(os.str().size()> KafkaManager()->KafkaManagerMaximumPayloadSize()) {
payload_->set("configuration", "{}");
payload_->set("configurationTooBig", true);
} else {
payload_->set("configuration", *config_);
}
}
Send();
}

View File

@@ -1753,7 +1753,6 @@ namespace OpenWifi {
nlohmann::json new_ie;
nlohmann::json content;
// std::cout << BufferToHex(&data[0],data.size()) << std::endl;
uint offset = 0;
auto sub_ie = data[offset++];
switch (sub_ie) {
@@ -1788,7 +1787,6 @@ namespace OpenWifi {
try {
nlohmann::json D = nlohmann::json::parse(ofs.str());
// std::cout << "Start of parsing wifi" << std::endl;
if (D.contains("status")) {
auto Status = D["status"];
if (Status.contains("scan") && Status["scan"].is_array()) {
@@ -1803,8 +1801,6 @@ namespace OpenWifi {
if (ie.contains("type") && ie.contains("data")) {
uint64_t ie_type = ie["type"];
std::string ie_data = ie["data"];
// std::cout << "TYPE:" << ie_type << " DATA:" << ie_data
// << std::endl;
auto data = Base64Decode2Vec(ie_data);
if (ie_type == ieee80211_eid::WLAN_EID_COUNTRY) {
new_ies.push_back(WFS_WLAN_EID_COUNTRY(data));
@@ -1858,18 +1854,12 @@ namespace OpenWifi {
} else if (ie_type == ieee80211_eid::WLAN_EID_EXTENSION) {
new_ies.push_back(WFS_WLAN_EID_EXTENSION(data));
} else {
// std::cout
// << "Skipping IE: no parsing available: " << ie_type
// << std::endl;
new_ies.push_back(ie);
}
} else {
// std::cout << "Skipping IE: no data and type" <<
// std::endl;
new_ies.push_back(ie);
}
} catch (...) {
// std::cout << "Skipping IE: exception" << std::endl;
Logger.information(fmt::format("Error parsing IEs"));
new_ies.push_back(ie);
}
@@ -1877,7 +1867,6 @@ namespace OpenWifi {
scan_entry["ies"] = new_ies;
ParsedScan.push_back(scan_entry);
} else {
// std::cout << "Skipping scan" << std::endl;
ParsedScan.push_back(scan_entry);
}
}
@@ -1886,7 +1875,6 @@ namespace OpenWifi {
}
}
Result << to_string(D);
// std::cout << "End of parsing wifi" << std::endl;
return true;
} catch (const Poco::Exception &E) {
Logger.log(E);

View File

@@ -177,15 +177,6 @@ namespace OpenWifi {
} else {
session_hint->second->lastTransaction = Utils::Now();
}
/*
if(ap_hint!=AccountingSessions_.end()) {
std::cout << "Auth table:" << std::endl;
for(const auto &session:ap_hint->second) {
std::cout << Notification.SerialNumber_ << ": Index: " << session.first << ": ID: " << session.second->accountingSessionId << " MID:" << session.second->accountingMultiSessionId << std::endl;
}
}
*/
}
std::uint32_t GetUiInt32(const std::uint8_t *buf) {
@@ -423,15 +414,15 @@ namespace OpenWifi {
}
void RADIUSSessionTracker::DisconnectSession(const std::string &SerialNumber) {
poco_information(Logger(),fmt::format("{}: Disconnecting.", SerialNumber));
std::lock_guard Guard(Mutex_);
auto hint = AccountingSessions_.find(SerialNumber);
if(hint==end(AccountingSessions_)) {
return;
}
poco_information(Logger(),fmt::format("{}: Disconnecting.", SerialNumber));
// we need to go through all sessions and send an accounting stop
for(const auto &session:hint->second) {
poco_debug(Logger(), fmt::format("Stopping accounting for {}:{}", SerialNumber, session.first ));

View File

@@ -75,8 +75,10 @@ namespace OpenWifi {
} else if ((Utils::Now() - LastKeepAlive) > Pool_.radsecKeepAlive) {
RADIUS::RadiusOutputPacket P(Pool_.authConfig.servers[ServerIndex_].radsecSecret);
P.MakeStatusMessage(Pool_.authConfig.servers[ServerIndex_].name);
poco_trace(Logger_, fmt::format("{}: Keep-Alive message.", Pool_.authConfig.servers[ServerIndex_].name));
Socket_->sendBytes(P.Data(), P.Len());
if(Type_!=GWObjects::RadiusEndpointType::generic) {
poco_trace(Logger_, fmt::format("{}: Keep-Alive message.", Pool_.authConfig.servers[ServerIndex_].name));
Socket_->sendBytes(P.Data(), P.Len());
}
LastKeepAlive = Utils::Now();
}
Poco::Thread::trySleep(2000);
@@ -163,17 +165,16 @@ namespace OpenWifi {
fmt::format("Unknown packet: Type: {} (type={}) Length={}",
P.PacketType(), P.PacketTypeInt(), P.BufferLen()));
}
return;
} else {
poco_warning(Logger_, "Invalid packet received. Resetting the connection.");
Disconnect();
}
} catch (const Poco::Exception &E) {
Logger_.log(E);
Disconnect();
} catch (...) {
Disconnect();
poco_warning(Logger_, "Exception occurred. Resetting the connection.");
}
Disconnect();
}
inline void
@@ -324,7 +325,7 @@ namespace OpenWifi {
ofs << OpenRoamingRootCert;
ofs.close();
Poco::Net::Context::Ptr SecureContext = Poco::AutoPtr<Poco::Net::Context>(
auto SecureContext = Poco::AutoPtr<Poco::Net::Context>(
new Poco::Net::Context(Poco::Net::Context::TLS_CLIENT_USE, ""));
if (Pool_.acctConfig.servers[ServerIndex_].allowSelfSigned) {
@@ -430,7 +431,7 @@ namespace OpenWifi {
DecodeFile(CaCertFiles_[CaCertFiles_.size() - 1]->path(), cert);
}
Poco::Net::Context::Ptr SecureContext =
auto SecureContext =
Poco::AutoPtr<Poco::Net::Context>(new Poco::Net::Context(
Poco::Net::Context::TLS_CLIENT_USE, KeyFile_.path(), CertFile_.path(), ""));
if (Pool_.acctConfig.servers[ServerIndex_].allowSelfSigned) {
@@ -498,7 +499,9 @@ namespace OpenWifi {
}
inline bool Connect_Generic() {
if (TryAgain_) {
poco_information(Logger_, fmt::format("Connecting {}", Pool_.name));
if (TryAgain_ && !Connected_) {
std::lock_guard G(LocalMutex_);
Poco::Net::SocketAddress AuthSockAddrV4(
@@ -520,26 +523,6 @@ namespace OpenWifi {
MicroServiceConfigGetInt("radius.proxy.coa.port", DEFAULT_RADIUS_CoA_PORT));
CoASocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV4, true, true);
/*
AuthenticationSocketV6_ =
std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV6, true, true);
Poco::Net::SocketAddress AuthSockAddrV6(
Poco::Net::AddressFamily::IPv6,
MicroServiceConfigGetInt("radius.proxy.authentication.port",
DEFAULT_RADIUS_AUTHENTICATION_PORT));
Poco::Net::SocketAddress AcctSockAddrV6(
Poco::Net::AddressFamily::IPv6,
MicroServiceConfigGetInt("radius.proxy.accounting.port",
DEFAULT_RADIUS_ACCOUNTING_PORT));
AccountingSocketV6_ =
std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV6, true, true);
Poco::Net::SocketAddress CoASockAddrV6(
Poco::Net::AddressFamily::IPv6,
MicroServiceConfigGetInt("radius.proxy.coa.port", DEFAULT_RADIUS_CoA_PORT));
CoASocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV6, true, true);
*/
Reactor_.addEventHandler(
*AuthenticationSocketV4_,
Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
@@ -551,7 +534,27 @@ namespace OpenWifi {
Reactor_.addEventHandler(
*CoASocketV4_, Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
*this, &RADIUS_Destination::OnCoASocketReadable));
/*
Poco::Net::SocketAddress AuthSockAddrV6(
Poco::Net::AddressFamily::IPv6,
MicroServiceConfigGetInt("radius.proxy.authentication.port",
DEFAULT_RADIUS_AUTHENTICATION_PORT));
AuthenticationSocketV6_ =
std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV6, true, true);
Poco::Net::SocketAddress AcctSockAddrV6(
Poco::Net::AddressFamily::IPv6,
MicroServiceConfigGetInt("radius.proxy.accounting.port",
DEFAULT_RADIUS_AUTHENTICATION_PORT));
AccountingSocketV6_ =
std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV6, true, true);
Poco::Net::SocketAddress CoASockAddrV6(
Poco::Net::AddressFamily::IPv6,
MicroServiceConfigGetInt("radius.proxy.coa.port", DEFAULT_RADIUS_CoA_PORT));
CoASocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV6, true, true);
Reactor_.addEventHandler(
*AuthenticationSocketV6_,
Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
@@ -565,6 +568,7 @@ namespace OpenWifi {
*CoASocketV6_, Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
*this, &RADIUS_Destination::OnCoASocketReadable));
*/
Connected_ = true;
}
return true;
}
@@ -590,6 +594,8 @@ namespace OpenWifi {
if (Connected_) {
std::lock_guard G(LocalMutex_);
if(Type_==GWObjects::RadiusEndpointType::generic) {
poco_information(Logger_, fmt::format("Disconnecting {} generic server. Releasing all UDP resources.", Pool_.name));
if(AuthenticationSocketV4_) {
Reactor_.removeEventHandler(
*AuthenticationSocketV4_,
@@ -617,7 +623,8 @@ namespace OpenWifi {
CoASocketV4_.reset();
}
/* if(AuthenticationSocketV6_) {
/*
if(AuthenticationSocketV6_) {
Reactor_.removeEventHandler(
*AuthenticationSocketV6_,
Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
@@ -646,7 +653,6 @@ namespace OpenWifi {
*/
} else {
if(Socket_!=nullptr) {
std::lock_guard G(LocalMutex_);
Reactor_.removeEventHandler(
*Socket_, Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
*this, &RADIUS_Destination::onData));
@@ -660,9 +666,9 @@ namespace OpenWifi {
Socket_->close();
}
}
Connected_ = false;
}
Connected_ = false;
poco_information(Logger_, "Disconnecting.");
poco_information(Logger_, fmt::format("Disconnecting {}", Pool_.name));
}
static void DecodeFile(const std::string &filename, const std::string &s) {
@@ -724,7 +730,8 @@ namespace OpenWifi {
std::unique_ptr<Poco::Net::DatagramSocket> AuthenticationSocketV4_;
std::unique_ptr<Poco::Net::DatagramSocket> CoASocketV4_;
/* std::unique_ptr<Poco::Net::DatagramSocket> CoASocketV6_;
/*
std::unique_ptr<Poco::Net::DatagramSocket> CoASocketV6_;
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV6_;
std::unique_ptr<Poco::Net::DatagramSocket> AuthenticationSocketV6_;
*/

View File

@@ -63,7 +63,7 @@ namespace OpenWifi {
poco_debug(Logger(), fmt::format("BLACKLIST-POST: {}", D.serialNumber));
Poco::toLowerInPlace(D.serialNumber);
if (StorageService()->IsBlackListed(D.serialNumber)) {
if (StorageService()->IsBlackListed(Utils::MACToInt(D.serialNumber))) {
return BadRequest(RESTAPI::Errors::SerialNumberExists);
}

View File

@@ -56,17 +56,27 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if (DefConfig.Models.empty()) {
if (DefConfig.models.empty()) {
return BadRequest(RESTAPI::Errors::ModelIDListCannotBeEmpty);
}
std::vector<std::string> Error;
if (!ValidateUCentralConfiguration(DefConfig.Configuration, Error,
GetBoolParameter("strict", false))) {
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
DefConfig.platform = DefConfig.platform.empty() ? Platforms::AP : DefConfig.platform;
if(DefConfig.platform != Platforms::AP && DefConfig.platform != Platforms::SWITCH) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
DefConfig.Created = DefConfig.LastModified = Utils::Now();
if(DefConfig.configuration.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
std::string Error;
if (!ValidateUCentralConfiguration(ConfigurationValidator::GetType(DefConfig.platform),
DefConfig.configuration, Error,
GetBoolParameter("strict", false))) {
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid, Error);
}
DefConfig.created = DefConfig.lastModified = Utils::Now();
if (StorageService()->CreateDefaultConfiguration(Name, DefConfig)) {
return OK();
}
@@ -88,19 +98,31 @@ namespace OpenWifi {
return NotFound();
}
if (!NewConfig.Configuration.empty()) {
std::vector<std::string> Error;
if (!ValidateUCentralConfiguration(NewConfig.Configuration, Error,
GetBoolParameter("strict", false))) {
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
}
Existing.Configuration = NewConfig.Configuration;
if(Existing.platform.empty()) {
Existing.platform = Platforms::AP;
}
Existing.LastModified = Utils::Now();
AssignIfPresent(Obj, "description", Existing.Description);
if(ParsedBody_->has("platform")) {
if(NewConfig.platform.empty() || (NewConfig.platform != Platforms::AP && NewConfig.platform != Platforms::SWITCH)) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
Existing.platform = NewConfig.platform;
}
if (!NewConfig.configuration.empty()) {
std::string Error;
if (!ValidateUCentralConfiguration(ConfigurationValidator::GetType(Existing.platform),
NewConfig.configuration, Error,
GetBoolParameter("strict", false))) {
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid, Error);
}
Existing.configuration = NewConfig.configuration;
}
Existing.lastModified = Utils::Now();
AssignIfPresent(Obj, "description", Existing.description);
if (Obj->has("modelIds"))
Existing.Models = NewConfig.Models;
Existing.models = NewConfig.models;
if (StorageService()->UpdateDefaultConfiguration(Name, Existing)) {
GWObjects::DefaultConfiguration ModifiedConfig;

View File

@@ -87,7 +87,7 @@ namespace OpenWifi {
poco_debug(
Logger_,
fmt::format(
"Command rtty TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
"Command RTTY TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
TransactionId_, UUID, RPC, Poco::Thread::current()->id()));
return Rtty(UUID, RPC, 60000ms, Restrictions);
};
@@ -166,7 +166,8 @@ namespace OpenWifi {
{APCommands::Commands::rrm, false, true, &RESTAPI_device_commandHandler::RRM, 60000ms},
{APCommands::Commands::certupdate, false, true, &RESTAPI_device_commandHandler::CertUpdate, 60000ms},
{APCommands::Commands::transfer, false, true, &RESTAPI_device_commandHandler::Transfer, 60000ms},
{APCommands::Commands::script, false, true, &RESTAPI_device_commandHandler::Script, 60000ms}
{APCommands::Commands::script, false, true, &RESTAPI_device_commandHandler::Script, 60000ms},
{APCommands::Commands::powercycle, false, true, &RESTAPI_device_commandHandler::PowerCycle, 60000ms}
};
void RESTAPI_device_commandHandler::DoPost() {
@@ -653,13 +654,18 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
}
GWObjects::Device DeviceInfo;
if (!StorageService()->GetDevice(SerialNumber_, DeviceInfo)) {
return NotFound();
}
auto Configuration =
GetS(RESTAPI::Protocol::CONFIGURATION, Obj, uCentralProtocol::EMPTY_JSON_DOC);
std::vector<std::string> Error;
if (!ValidateUCentralConfiguration(Configuration, Error,
std::string Error;
if (!ValidateUCentralConfiguration(ConfigurationValidator::GetType(DeviceInfo.DeviceType),
Configuration, Error,
GetBoolParameter("strict", false))) {
CallCanceled("CONFIGURE", CMD_UUID, CMD_RPC, RESTAPI::Errors::ConfigBlockInvalid);
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid, Error);
}
auto When = GetWhen(Obj);
@@ -1169,7 +1175,7 @@ namespace OpenWifi {
if (RTTYS_server()->UseInternal()) {
std::uint64_t SN = Utils::SerialNumberToInt(SerialNumber_);
bool mTLS = AP_WS_Server()->DeviceRequiresSecureRtty(SN);
bool mTLS = AP_WS_Server()->DeviceRequiresSecureRTTY(SN);
auto Hash = Utils::ComputeHash(UserInfo_.webtoken.refresh_token_, Utils::Now());
Rtty.Token = Hash.substr(0, RTTY_DEVICE_TOKEN_LENGTH);
if (!RTTYS_server()->CreateEndPoint(Rtty.ConnectionId, Rtty.Token, Requester(),
@@ -1401,9 +1407,9 @@ namespace OpenWifi {
Cmd.WaitingForFile = 0;
Cmd.Status= "completed";
if(CommandManager()->FireAndForget(SerialNumber_, uCentralProtocol::RRM, Params)) {
Cmd.Status= "completed";
StorageService()->AddCommand(SerialNumber_, Cmd,
Storage::CommandExecutionType::COMMAND_COMPLETED);
Cmd.Status= "completed";
return OK();
}
Cmd.Status= "failed"; // should never happen
@@ -1501,4 +1507,45 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::PowerCycle(
const std::string &CMD_UUID, uint64_t CMD_RPC,
[[maybe_unused]] std::chrono::milliseconds timeout,
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
if(UserInfo_.userinfo.userRole != SecurityObjects::ROOT &&
UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) {
CallCanceled("RRM", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
poco_debug(Logger_, fmt::format("POWERCYCLE({},{}): TID={} user={} serial={}", CMD_UUID,
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
if(IsDeviceSimulated(SerialNumber_)) {
CallCanceled("RRM", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported);
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
}
GWObjects::PowerCycleRequest PR;
if(!PR.from_json(ParsedBody_)) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
GWObjects::CommandDetails Cmd;
Cmd.SerialNumber = SerialNumber_;
Cmd.SubmittedBy = Requester();
Cmd.UUID = CMD_UUID;
Cmd.Command = uCentralProtocol::POWERCYCLE;
std::ostringstream os;
ParsedBody_->stringify(os);
Cmd.Details = os.str();
Cmd.RunAt = PR.when;
Cmd.ErrorCode = 0;
Cmd.WaitingForFile = 0;
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::powercycle, false, Cmd,
*ParsedBody_, *Request, *Response, timeout, nullptr, this,
Logger_);
}
} // namespace OpenWifi

View File

@@ -68,6 +68,8 @@ namespace OpenWifi {
const GWObjects::DeviceRestrictions &R);
void Transfer(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
const GWObjects::DeviceRestrictions &R);
void PowerCycle(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
const GWObjects::DeviceRestrictions &R);
static auto PathName() {
return std::list<std::string>{"/api/v1/device/{serialNumber}/{command}"};

View File

@@ -101,9 +101,10 @@ namespace OpenWifi {
}
auto Config = Obj->get("configuration").toString();
Poco::JSON::Object Answer;
std::vector<std::string> Error;
std::string Error;
auto DeviceType = Poco::toLower(GetParameter("deviceType", Platforms::AP));
auto Res =
ValidateUCentralConfiguration(Config, Error, GetBoolParameter("strict", false));
ValidateUCentralConfiguration(ConfigurationValidator::GetType(DeviceType),Config, Error, GetBoolParameter("strict", false));
Answer.set("valid", Res);
if (!Error.empty())
Answer.set("error", Error);
@@ -123,12 +124,13 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
}
std::vector<std::string> Error;
std::string Error;
if (Device.Configuration.empty() ||
(!Device.Configuration.empty() &&
!ValidateUCentralConfiguration(Device.Configuration, Error,
!ValidateUCentralConfiguration(ConfigurationValidator::GetType(Device.DeviceType),
Device.Configuration, Error,
GetBoolParameter("strict", false)))) {
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid, Error);
}
for (auto &i : Device.Notes) {
@@ -169,10 +171,11 @@ namespace OpenWifi {
}
if (!NewDevice.Configuration.empty()) {
std::vector<std::string> Error;
if (!ValidateUCentralConfiguration(NewDevice.Configuration, Error,
std::string Error;
if (!ValidateUCentralConfiguration(ConfigurationValidator::GetType(Existing.DeviceType),
NewDevice.Configuration, Error,
GetBoolParameter("strict", false))) {
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid, Error);
}
Config::Config NewConfig(NewDevice.Configuration);
uint64_t NewConfigUUID = Utils::Now();

View File

@@ -82,15 +82,24 @@ namespace OpenWifi {
}
}
auto platform = Poco::toLower(GetParameter("platform", ""));
auto serialOnly = GetBoolParameter(RESTAPI::Protocol::SERIALONLY, false);
auto deviceWithStatus = GetBoolParameter(RESTAPI::Protocol::DEVICEWITHSTATUS, false);
auto completeInfo = GetBoolParameter("completeInfo", false);
auto includeProvisioned = GetBoolParameter("includeProvisioned", true);
if(!platform.empty() && (platform!=Platforms::AP && platform!=Platforms::SWITCH && platform!="all")) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(platform=="all")
platform="";
Poco::JSON::Object RetObj;
if (!QB_.Select.empty()) {
Poco::JSON::Array Objects;
for (auto &i : SelectedRecords()) {
auto SerialNumber = i;
auto &SerialNumber = i;
if (!Utils::ValidSerialNumber(i))
continue;
GWObjects::Device D;
@@ -116,14 +125,14 @@ namespace OpenWifi {
else
RetObj.set(RESTAPI::Protocol::DEVICES, Objects);
} else if (QB_.CountOnly == true) {
} else if (QB_.CountOnly) {
uint64_t Count = 0;
if (StorageService()->GetDeviceCount(Count)) {
if (StorageService()->GetDeviceCount(Count, platform, includeProvisioned)) {
return ReturnCountOnly(Count);
}
} else if (serialOnly) {
std::vector<std::string> SerialNumbers;
StorageService()->GetDeviceSerialNumbers(QB_.Offset, QB_.Limit, SerialNumbers, OrderBy);
StorageService()->GetDeviceSerialNumbers(QB_.Offset, QB_.Limit, SerialNumbers, OrderBy, platform, includeProvisioned);
Poco::JSON::Array Objects;
for (const auto &i : SerialNumbers) {
Objects.add(i);
@@ -141,7 +150,7 @@ namespace OpenWifi {
RetObj.set("serialNumbers", Objects);
} else {
std::vector<GWObjects::Device> Devices;
StorageService()->GetDevices(QB_.Offset, QB_.Limit, Devices, OrderBy);
StorageService()->GetDevices(QB_.Offset, QB_.Limit, Devices, OrderBy, platform, includeProvisioned);
Poco::JSON::Array Objects;
for (const auto &i : Devices) {
Poco::JSON::Object Obj;
@@ -175,10 +184,12 @@ namespace OpenWifi {
}
if(GetBoolParameter("simulatedDevices",false)) {
if(StorageService()->DeleteSimulatedDevice("")) {
return OK();
}
return NotFound();
auto F = []() ->void {
StorageService()->DeleteSimulatedDevice("");
};
std::thread T(F);
T.detach();
return OK();
}
if(!QB_.Select.empty() && !Utils::ValidSerialNumbers(QB_.Select)) {

View File

@@ -8,7 +8,7 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include <framework/RESTAPI_Handler.h>
namespace OpenWifi {
class RESTAPI_file : public RESTAPIHandler {

View File

@@ -23,8 +23,8 @@ namespace OpenWifi {
void RESTAPI_script_handler::DoDelete() {
std::string UUID = GetBinding("uuid", "");
if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT) {
return BadRequest(RESTAPI::Errors::ACCESS_DENIED);
if (!UserInfo_.userinfo.userPermissions[SecurityObjects::PM_SCRIPTS_GW][SecurityObjects::PT_DELETE]) {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if (UUID.empty()) {
@@ -40,8 +40,8 @@ namespace OpenWifi {
void RESTAPI_script_handler::DoPost() {
std::string UUID = GetBinding("uuid", "");
if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT) {
return BadRequest(RESTAPI::Errors::ACCESS_DENIED);
if (!UserInfo_.userinfo.userPermissions[SecurityObjects::PM_SCRIPTS_GW][SecurityObjects::PT_CREATE]) {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if (UUID.empty()) {
@@ -86,8 +86,8 @@ namespace OpenWifi {
void RESTAPI_script_handler::DoPut() {
std::string UUID = GetBinding("uuid", "");
if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT) {
return BadRequest(RESTAPI::Errors::ACCESS_DENIED);
if (!UserInfo_.userinfo.userPermissions[SecurityObjects::PM_SCRIPTS_GW][SecurityObjects::PT_UPDATE]) {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if (UUID.empty()) {

View File

@@ -7,6 +7,7 @@
#include "RESTAPI_ProvObjects.h"
#include "framework/utils.h"
#include <vector>
#include "framework/ow_constants.h"
namespace OpenWifi {

View File

@@ -12,6 +12,7 @@
#include "Daemon.h"
#ifdef TIP_GATEWAY_SERVICE
#include "AP_WS_Server.h"
#include "StorageService.h"
#include "CapabilitiesCache.h"
#include "RADIUSSessionTracker.h"
#endif
@@ -30,7 +31,7 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "serialNumber", SerialNumber);
#ifdef TIP_GATEWAY_SERVICE
field_to_json(Obj, "deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible));
field_to_json(Obj, "hasRADIUSSessions", RADIUSSessionTracker()->HasSessions(SerialNumber));
field_to_json(Obj, "blackListed", StorageService()->IsBlackListed(Utils::MACToInt(SerialNumber)));
#endif
field_to_json(Obj, "macAddress", MACAddress);
field_to_json(Obj, "manufacturer", Manufacturer);
@@ -68,9 +69,14 @@ namespace OpenWifi::GWObjects {
#ifdef TIP_GATEWAY_SERVICE
ConnectionState ConState;
if (AP_WS_Server()->GetState(SerialNumber, ConState)) {
#ifdef USE_MEDUSA_CLIENT
auto Res = GS()->GetState(SerialNumber);
if (Res.has_value()) {
Res.value().to_json(SerialNumber,Obj);
#else
if (AP_WS_Server()->GetState(SerialNumber, ConState)) {
ConState.to_json(SerialNumber,Obj);
#endif
} else {
field_to_json(Obj, "ipAddress", "");
field_to_json(Obj, "txBytes", (uint64_t)0);
@@ -166,14 +172,17 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "recorded", Recorded);
}
void DefaultConfiguration::to_json(Poco::JSON::Object &Obj) const {
EmbedDocument("configuration", Obj, Configuration);
field_to_json(Obj, "name", Name);
field_to_json(Obj, "modelIds", Models);
field_to_json(Obj, "description", Description);
field_to_json(Obj, "created", Created);
field_to_json(Obj, "lastModified", LastModified);
}
bool HealthCheck::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "UUID", UUID);
field_from_json(Obj, "sanity", Sanity);
field_from_json(Obj, "recorded", Recorded);
return true;
} catch(...) {
}
return false;
}
void DefaultFirmware::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "deviceType", deviceType);
@@ -222,12 +231,25 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "deferred", deferred);
}
void DefaultConfiguration::to_json(Poco::JSON::Object &Obj) const {
EmbedDocument("configuration", Obj, configuration);
field_to_json(Obj, "name", name);
field_to_json(Obj, "modelIds", models);
field_to_json(Obj, "description", description);
field_to_json(Obj, "created", created);
field_to_json(Obj, "lastModified", lastModified);
field_to_json(Obj, "platform", platform);
}
bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "name", Name);
field_from_json(Obj, "configuration", Configuration);
field_from_json(Obj, "modelIds", Models);
field_from_json(Obj, "description", Description);
field_from_json(Obj, "configuration", configuration);
field_from_json(Obj, "name", name);
field_from_json(Obj, "modelIds", models);
field_from_json(Obj, "description", description);
field_from_json(Obj, "created", created);
field_from_json(Obj, "lastModified", lastModified);
field_from_json(Obj, "platform", platform);
return true;
} catch (const Poco::Exception &E) {
}
@@ -276,13 +298,11 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "totalConnectionTime", Utils::Now() - started);
field_to_json(Obj, "certificateExpiryDate", certificateExpiryDate);
field_to_json(Obj, "connectReason", connectReason);
field_to_json(Obj, "uptime", uptime);
field_to_json(Obj, "compatible", Compatible);
#ifdef TIP_GATEWAY_SERVICE
hasRADIUSSessions = RADIUSSessionTracker()->HasSessions(SerialNumber);
AP_WS_Server()->ExtendedAttributes(SerialNumber, hasGPS, sanity,
memoryUsed,
load,
temperature);
#endif
field_to_json(Obj, "hasRADIUSSessions", hasRADIUSSessions );
field_to_json(Obj, "hasGPS", hasGPS);
@@ -314,6 +334,45 @@ namespace OpenWifi::GWObjects {
}
}
bool ConnectionState::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "compatible", Compatible);
field_from_json(Obj, "ipAddress", Address);
field_from_json(Obj, "txBytes", TX);
field_from_json(Obj, "rxBytes", RX);
field_from_json(Obj, "messageCount", MessageCount);
field_from_json(Obj, "UUID", UUID);
field_from_json(Obj, "connected", Connected);
field_from_json(Obj, "firmware", Firmware);
field_from_json(Obj, "lastContact", LastContact);
field_from_json(Obj, "associations_2G", Associations_2G);
field_from_json(Obj, "associations_5G", Associations_5G);
field_from_json(Obj, "associations_6G", Associations_6G);
field_from_json(Obj, "webSocketClients", webSocketClients);
field_from_json(Obj, "websocketPackets", websocketPackets);
field_from_json(Obj, "kafkaClients", kafkaClients);
field_from_json(Obj, "kafkaPackets", kafkaPackets);
field_from_json(Obj, "locale", locale);
field_from_json(Obj, "started", started);
field_from_json(Obj, "sessionId", sessionId);
field_from_json(Obj, "connectionCompletionTime", connectionCompletionTime);
field_from_json(Obj, "totalConnectionTime", totalConnectionTime);
field_from_json(Obj, "certificateExpiryDate", certificateExpiryDate);
field_from_json(Obj, "connectReason", connectReason);
field_from_json(Obj, "uptime", uptime);
field_from_json(Obj, "hasRADIUSSessions", hasRADIUSSessions );
field_from_json(Obj, "hasGPS", hasGPS);
field_from_json(Obj, "sanity", sanity);
field_from_json(Obj, "memoryUsed", memoryUsed);
field_from_json(Obj, "sanity", sanity);
field_from_json(Obj, "load", load);
field_from_json(Obj, "temperature", temperature);
return true;
} catch(const Poco::Exception &E) {
}
return false;
}
void DeviceConnectionStatistics::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "averageConnectionTime", averageConnectionTime);
field_to_json(Obj, "connectedDevices", connectedDevices);
@@ -711,7 +770,7 @@ namespace OpenWifi::GWObjects {
bool DeviceCertificateUpdateRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "serialNumber", serialNumber);
field_from_json(Obj, "serial", serialNumber);
field_from_json(Obj, "encodedCertificate", encodedCertificate);
return true;
} catch (const Poco::Exception &E) {
@@ -719,4 +778,25 @@ namespace OpenWifi::GWObjects {
return false;
}
bool PowerCyclePort::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "name", name);
field_from_json(Obj, "cycle", cycle);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
bool PowerCycleRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "serial", serialNumber);
field_from_json(Obj, "when", when);
field_from_json(Obj, "ports", ports);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
} // namespace OpenWifi::GWObjects

View File

@@ -49,8 +49,11 @@ namespace OpenWifi::GWObjects {
std::double_t load=0.0;
std::double_t temperature=0.0;
std::string connectReason;
std::uint64_t uptime=0;
std::uint64_t totalConnectionTime=0;
void to_json(const std::string &SerialNumber, Poco::JSON::Object &Obj) ;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct DeviceRestrictionsKeyInfo {
@@ -112,6 +115,7 @@ namespace OpenWifi::GWObjects {
std::uint64_t lastRecordedContact=0;
std::uint64_t certificateExpiryDate = 0;
std::string connectReason;
bool blackListed=false;
void to_json(Poco::JSON::Object &Obj) const;
void to_json_with_status(Poco::JSON::Object &Obj) const;
@@ -137,13 +141,15 @@ namespace OpenWifi::GWObjects {
};
struct HealthCheck {
std::string SerialNumber;
uint64_t UUID = 0;
std::string Data;
uint64_t Recorded = 0;
uint64_t Sanity = 0;
void to_json(Poco::JSON::Object &Obj) const;
};
std::string SerialNumber;
uint64_t UUID = 0;
std::string Data;
uint64_t Recorded = 0;
uint64_t Sanity = 0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Capabilities {
std::string Capabilities;
@@ -174,12 +180,13 @@ namespace OpenWifi::GWObjects {
};
struct DefaultConfiguration {
std::string Name;
std::string Configuration;
Types::StringVec Models;
std::string Description;
uint64_t Created;
uint64_t LastModified;
std::string name;
std::string configuration;
Types::StringVec models;
std::string description;
uint64_t created;
uint64_t lastModified;
std::string platform;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -513,4 +520,18 @@ namespace OpenWifi::GWObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct PowerCyclePort {
std::string name;
std::uint64_t cycle=10000;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct PowerCycleRequest {
std::string serialNumber;
std::uint64_t when;
std::vector<PowerCyclePort> ports;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
} // namespace OpenWifi::GWObjects

View File

@@ -587,6 +587,9 @@ namespace OpenWifi::ProvObjects {
field_to_json(Obj, "locale", locale);
field_to_json(Obj, "realMacAddress", realMacAddress);
field_to_json(Obj, "doNotAllowOverrides", doNotAllowOverrides);
field_to_json(Obj, "imported", imported);
field_to_json(Obj, "connected", connected);
field_to_json(Obj, "platform", platform);
}
bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -609,6 +612,9 @@ namespace OpenWifi::ProvObjects {
field_from_json(Obj, "locale", locale);
field_from_json(Obj, "realMacAddress", realMacAddress);
field_from_json(Obj, "doNotAllowOverrides", doNotAllowOverrides);
field_from_json(Obj, "imported", imported);
field_from_json(Obj, "connected", connected);
field_from_json(Obj, "platform", platform);
return true;
} catch (...) {
}

View File

@@ -490,9 +490,11 @@ namespace OpenWifi::ProvObjects {
std::string locale;
std::string realMacAddress;
bool doNotAllowOverrides = false;
std::uint64_t imported=0;
std::uint64_t connected=0;
std::string platform{Platforms::AP};
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};

View File

@@ -12,6 +12,8 @@
#include "RESTAPI_SecurityObjects.h"
#include "framework/RESTAPI_utils.h"
#include <stdlib.h>
using OpenWifi::RESTAPI_utils::field_from_json;
using OpenWifi::RESTAPI_utils::field_to_json;
@@ -282,6 +284,7 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj, "oauthUserInfo", oauthUserInfo);
field_to_json(Obj, "modified", modified);
field_to_json(Obj, "signingUp", signingUp);
Obj.set("userPermissions", permissions_to_json(userPermissions));
};
bool UserInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -318,6 +321,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj, "oauthUserInfo", oauthUserInfo);
field_from_json(Obj, "modified", modified);
field_from_json(Obj, "signingUp", signingUp);
userPermissions = permissions_from_json(Obj->getObject("userPermissions"));
return true;
} catch (const Poco::Exception &E) {
std::cout << "Cannot parse: UserInfo" << std::endl;
@@ -737,4 +741,218 @@ namespace OpenWifi::SecurityObjects {
return false;
}
PERMISSION_TYPE PermTypeFromString(const std::string &U) {
if (!Poco::icompare(U, "create"))
return PT_CREATE;
else if (!Poco::icompare(U, "update"))
return PT_UPDATE;
else if (!Poco::icompare(U, "delete"))
return PT_DELETE;
else if (!Poco::icompare(U, "readonly"))
return PT_READ_ONLY;
return PT_UNKNOWN;
}
std::string PermTypeToString(PERMISSION_TYPE U) {
switch (U) {
case PT_CREATE:
return "create";
case PT_UPDATE:
return "update";
case PT_DELETE:
return "delete";
case PT_READ_ONLY:
return "readonly";
case PT_UNKNOWN:
default:
return "unknown";
}
}
PERMISSION_MODEL PermModelFromString(const std::string &U) {
if (!Poco::icompare(U, "permissions"))
return PM_PERMISSIONS;
else if (!Poco::icompare(U, "venues"))
return PM_VENUES_PROV;
else if (!Poco::icompare(U, "venues_list"))
return PM_VENUES_LIST_PROV;
else if (!Poco::icompare(U, "entities"))
return PM_ENTITIES_PROV;
else if (!Poco::icompare(U, "entities_list"))
return PM_ENTITIES_LIST_PROV;
else if (!Poco::icompare(U, "inventory"))
return PM_INVENTORY_PROV;
else if (!Poco::icompare(U, "inventory_list"))
return PM_INVENTORY_LIST_PROV;
else if (!Poco::icompare(U, "managementpolicy"))
return PM_MANAGEMENTPOLICY_PROV;
else if (!Poco::icompare(U, "managementpolicy_list"))
return PM_MANAGEMENTPOLICY_LIST_PROV;
else if (!Poco::icompare(U, "managementrole"))
return PM_MANAGEMENTROLE_PROV;
else if (!Poco::icompare(U, "managementrole_list"))
return PM_MANAGEMENTROLE_LIST_PROV;
//GW
else if (!Poco::icompare(U, "scripts"))
return PM_SCRIPTS_GW;
else if (!Poco::icompare(U, "configure"))
return PM_DEVICE_CONFIGURE_GW;
else if (!Poco::icompare(U, "upgrade"))
return PM_DEVICE_UPGRADE_GW;
else if (!Poco::icompare(U, "factoryreset"))
return PM_DEVICE_FACTORY_GW;
else if (!Poco::icompare(U, "leds"))
return PM_DEVICE_LEDS_GW;
else if (!Poco::icompare(U, "trace"))
return PM_DEVICE_TRACE_GW;
else if (!Poco::icompare(U, "request"))
return PM_DEVICE_REQUEST_GW;
else if (!Poco::icompare(U, "wifiscan"))
return PM_DEVICE_WIFISCAN_GW;
else if (!Poco::icompare(U, "eventqueue"))
return PM_DEVICE_EVENTQUEUE_GW;
else if (!Poco::icompare(U, "telemetry"))
return PM_DEVICE_TELEMETRY_GW;
else if (!Poco::icompare(U, "ping"))
return PM_DEVICE_PING_GW;
else if (!Poco::icompare(U, "ap_script"))
return PM_DEVICE_SCRIPT_GW;
else if (!Poco::icompare(U, "rrm"))
return PM_DEVICE_RRM_GW;
else if (!Poco::icompare(U, "transfer"))
return PM_DEVICE_TRANSFER_GW;
else if (!Poco::icompare(U, "certupdate"))
return PM_DEVICE_CERTUPDATE_GW;
else if (!Poco::icompare(U, "powercycle"))
return PM_DEVICE_POWERCYCLE_GW;
else if (!Poco::icompare(U, "ap_logs"))
return PM_DEVICE_LOGS_GW;
else if (!Poco::icompare(U, "healthchecks"))
return PM_DEVICE_HEALTHCHECKS_GW;
else if (!Poco::icompare(U, "ap_capabilities"))
return PM_DEVICE_CAPABILITIES_GW;
else if (!Poco::icompare(U, "ap_statistics"))
return PM_DEVICE_STATISTICS_GW;
else if (!Poco::icompare(U, "ap_status"))
return PM_DEVICE_STATUS_GW;
else if (!Poco::icompare(U, "ap_rtty"))
return PM_DEVICE_RTTY_GW;
return PM_UNKNOWN;
}
std::string PermModelToString(PERMISSION_MODEL U) {
switch (U) {
case PM_PERMISSIONS:
return "permissions";
case PM_VENUES_PROV:
return "venues";
case PM_VENUES_LIST_PROV:
return "venues_list";
case PM_ENTITIES_PROV:
return "entities";
case PM_ENTITIES_LIST_PROV:
return "entities_list";
case PM_INVENTORY_PROV:
return "inventory";
case PM_INVENTORY_LIST_PROV:
return "inventory_list";
case PM_MANAGEMENTPOLICY_PROV:
return "managementpolicy";
case PM_MANAGEMENTPOLICY_LIST_PROV:
return "managementpolicy_list";
case PM_MANAGEMENTROLE_PROV:
return "managementrole";
case PM_MANAGEMENTROLE_LIST_PROV:
return "managementrole_list";
//Gateway
case PM_SCRIPTS_GW:
return "scripts";
case PM_DEVICE_CONFIGURE_GW:
return "configure";
case PM_DEVICE_UPGRADE_GW:
return "upgrade";
case PM_DEVICE_FACTORY_GW:
return "factoryreset";
case PM_DEVICE_LEDS_GW:
return "leds";
case PM_DEVICE_TRACE_GW:
return "trace";
case PM_DEVICE_REQUEST_GW:
return "request";
case PM_DEVICE_WIFISCAN_GW:
return "wifiscan";
case PM_DEVICE_EVENTQUEUE_GW:
return "eventqueue";
case PM_DEVICE_TELEMETRY_GW:
return "telemetry";
case PM_DEVICE_PING_GW:
return "ping";
case PM_DEVICE_SCRIPT_GW:
return "ap_script";
case PM_DEVICE_RRM_GW:
return "rrm";
case PM_DEVICE_TRANSFER_GW:
return "transfer";
case PM_DEVICE_CERTUPDATE_GW:
return "certupdate";
case PM_DEVICE_POWERCYCLE_GW:
return "powercycle";
case PM_DEVICE_LOGS_GW:
return "ap_logs";
case PM_DEVICE_HEALTHCHECKS_GW:
return "healthchecks";
case PM_DEVICE_CAPABILITIES_GW:
return "ap_capabilities";
case PM_DEVICE_STATISTICS_GW:
return "ap_statistics";
case PM_DEVICE_STATUS_GW:
return "ap_status";
case PM_DEVICE_RTTY_GW:
return "ap_rtty";
case PM_UNKNOWN:
default:
return "unknown";
}
}
/**
* Convert PermissionMap into a JSON object and return it
*/
Poco::JSON::Object permissions_to_json(const PermissionMap &Map) {
Poco::JSON::Object MapObj;
for (auto &[Model, Permissions] : Map) {
Poco::JSON::Object ModelObject;
for (auto &[Permission, Allowed] : Permissions) {
ModelObject.set(PermTypeToString(Permission), Allowed);
}
MapObj.set(PermModelToString(Model), ModelObject);
}
return MapObj;
}
/**
* Convert JSON object into a PermissionMap and return it
*/
PermissionMap permissions_from_json(const Poco::JSON::Object::Ptr &Obj) {
PermissionMap permissions;
if (Obj == nullptr) {
return permissions;
}
Poco::JSON::Object::ConstIterator it1;
for(it1 = Obj->begin(); it1 != Obj->end(); it1++) {
std::string model = it1->first;
Poco::JSON::Object::Ptr modelObj = it1->second.extract<Poco::JSON::Object::Ptr>();
Poco::JSON::Object::ConstIterator it2;
for(it2 = modelObj->begin(); it2 != modelObj->end(); it2++) {
std::string permission = it2->first;
bool allowed = it2->second;
permissions[PermModelFromString(model)]
[PermTypeFromString(permission)] = allowed;
}
}
return permissions;
}
} // namespace OpenWifi::SecurityObjects

View File

@@ -11,10 +11,15 @@
#include "Poco/Data/LOB.h"
#include "Poco/Data/LOBStream.h"
#include "Poco/JSON/Object.h"
#include "Poco/Net/HTTPRequest.h"
#include "framework/OpenWifiTypes.h"
#include "framework/utils.h"
#include <string>
#include <type_traits>
#include <iostream>
#include <fstream>
#include <map>
#include <set>
namespace OpenWifi {
uint64_t Now();
@@ -55,6 +60,10 @@ namespace OpenWifi {
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
// example entry {"/api/v1/device", {Poco::Net::HTTPRequest::HTTP_POST, Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE}}
const std::map<std::string, std::set<std::string>> API_WHITELIST = {
};
enum USER_ROLE {
UNKNOWN,
ROOT,
@@ -125,6 +134,72 @@ namespace OpenWifi {
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
// Represents particular permissions, i.e. what are you doing do the model
enum PERMISSION_TYPE {
PT_CREATE,
PT_DELETE,
PT_UPDATE,
PT_READ_ONLY,
PT_UNKNOWN
};
PERMISSION_TYPE PermTypeFromString(const std::string &U);
std::string PermTypeToString(PERMISSION_TYPE U);
// Represents a model that can be operated on
enum PERMISSION_MODEL {
//Security
PM_PERMISSIONS,
//Provisioning
PM_VENUES_PROV,
PM_VENUES_LIST_PROV,
PM_ENTITIES_PROV,
PM_ENTITIES_LIST_PROV,
PM_INVENTORY_PROV,
PM_INVENTORY_LIST_PROV,
PM_MANAGEMENTPOLICY_PROV,
PM_MANAGEMENTPOLICY_LIST_PROV,
PM_MANAGEMENTROLE_PROV,
PM_MANAGEMENTROLE_LIST_PROV,
//Gateway
PM_DEVICE_CONFIGURE_GW,
PM_DEVICE_UPGRADE_GW,
PM_DEVICE_REBOOT_GW,
PM_DEVICE_FACTORY_GW,
PM_DEVICE_LEDS_GW,
PM_DEVICE_TRACE_GW,
PM_DEVICE_REQUEST_GW,
PM_DEVICE_WIFISCAN_GW,
PM_DEVICE_EVENTQUEUE_GW,
PM_DEVICE_TELEMETRY_GW,
PM_DEVICE_PING_GW,
PM_DEVICE_SCRIPT_GW,
PM_DEVICE_RRM_GW,
PM_DEVICE_TRANSFER_GW,
PM_DEVICE_CERTUPDATE_GW,
PM_DEVICE_POWERCYCLE_GW,
PM_DEVICE_LOGS_GW,
PM_DEVICE_HEALTHCHECKS_GW,
PM_DEVICE_CAPABILITIES_GW,
PM_DEVICE_STATISTICS_GW,
PM_DEVICE_STATUS_GW,
PM_DEVICE_RTTY_GW,
PM_SCRIPTS_GW,
PM_UNKNOWN
};
PERMISSION_MODEL PermModelFromString(const std::string &U);
std::string PermModelToString(PERMISSION_MODEL U);
// Map a permission (e.g. create, delete) to true/false
typedef std::map<PERMISSION_TYPE, bool> ModelPermissionMap;
// Map a model (e.g. venues, devices) to permissions
typedef std::map<PERMISSION_MODEL, ModelPermissionMap> PermissionMap;
Poco::JSON::Object permissions_to_json(const SecurityObjects::PermissionMap &Map);
PermissionMap permissions_from_json(const Poco::JSON::Object::Ptr &Obj);
struct UserInfo {
std::string id;
std::string name;
@@ -149,6 +224,7 @@ namespace OpenWifi {
bool suspended = false;
bool blackListed = false;
USER_ROLE userRole;
PermissionMap userPermissions;
UserLoginLoginExtensions userTypeProprietaryInfo;
std::string securityPolicy;
uint64_t securityPolicyChange = 0;

View File

@@ -24,7 +24,7 @@ namespace OpenWifi::StateUtils {
}
bool ComputeAssociations(const Poco::JSON::Object::Ptr RawObject, uint64_t &Radios_2G,
uint64_t &Radios_5G, uint64_t &Radios_6G) {
uint64_t &Radios_5G, uint64_t &Radios_6G, uint64_t &UpTime ) {
Radios_2G = 0;
Radios_5G = 0;
Radios_6G = 0;
@@ -90,9 +90,15 @@ namespace OpenWifi::StateUtils {
}
}
}
// std::cout << Radios_2G << " " << Radios_5G << " " << Radios_6G << std::endl;
return true;
}
if(RawObject->has("unit") && !RawObject->isNull("unit") && RawObject->isObject("unit")) {
auto unit = RawObject->getObject("unit");
if(unit->has("uptime")) {
UpTime = unit->get("uptime");
}
}
return false;
}
} // namespace OpenWifi::StateUtils

View File

@@ -8,5 +8,5 @@
namespace OpenWifi::StateUtils {
bool ComputeAssociations(const Poco::JSON::Object::Ptr RawObject, uint64_t &Radios_2G,
uint64_t &Radios_5G, uint64_t &Radio_6G);
uint64_t &Radios_5G, uint64_t &Radio_6G, uint64_t &UpTime);
}

View File

@@ -22,6 +22,8 @@ namespace OpenWifi {
ScriptDB_->Create();
ScriptDB_->Initialize();
FixDeviceTypeBug();
return 0;
}

View File

@@ -16,6 +16,22 @@
namespace OpenWifi {
class LockedDbSession {
public:
explicit LockedDbSession();
~LockedDbSession() = default;
inline std::mutex &Mutex() { return *Mutex_; };
inline Poco::Data::Session &Session() {
if(!Session_->isConnected()) {
Session_->reconnect();
}
return *Session_;
};
private:
std::shared_ptr<Poco::Data::Session> Session_;
std::shared_ptr<std::mutex> Mutex_;
};
class Storage : public StorageClass {
public:
@@ -90,7 +106,8 @@ namespace OpenWifi {
// typedef std::map<std::string,std::string> DeviceCapabilitiesCache;
bool AddLog(const GWObjects::DeviceLog &Log);
bool AddLog(LockedDbSession &Session, const GWObjects::DeviceLog &Log);
bool AddStatisticsData(Poco::Data::Session &Session, const GWObjects::Statistics &Stats);
bool AddStatisticsData(const GWObjects::Statistics &Stats);
bool GetStatisticsData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate,
uint64_t Offset, uint64_t HowMany,
@@ -102,6 +119,7 @@ namespace OpenWifi {
std::vector<GWObjects::Statistics> &Stats);
bool AddHealthCheckData(const GWObjects::HealthCheck &Check);
bool AddHealthCheckData(LockedDbSession &Session, const GWObjects::HealthCheck &Check);
bool GetHealthCheckData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate,
uint64_t Offset, uint64_t HowMany,
std::vector<GWObjects::HealthCheck> &Checks);
@@ -115,16 +133,23 @@ namespace OpenWifi {
uint64_t &NewUUID);
bool RollbackDeviceConfigurationChange(std::string & SerialNumber);
bool CompleteDeviceConfigurationChange(Poco::Data::Session &Session, std::string & SerialNumber);
bool CompleteDeviceConfigurationChange(std::string & SerialNumber);
bool CreateDevice(LockedDbSession &Session, GWObjects::Device &);
bool CreateDevice(GWObjects::Device &);
bool CreateDefaultDevice(std::string &SerialNumber, const Config::Capabilities &Caps,
bool CreateDefaultDevice(Poco::Data::Session &Session,std::string &SerialNumber,
const Config::Capabilities &Caps,
std::string &Firmware, const Poco::Net::IPAddress &IPAddress,
bool simulated);
bool CreateDevice(Poco::Data::Session &Sess, GWObjects::Device &DeviceDetails);
bool GetDevice(std::string &SerialNumber, GWObjects::Device &);
bool GetDevice(LockedDbSession &Session, const std::string &SerialNumber, GWObjects::Device &);
bool GetDevice(Poco::Data::Session &Session, const std::string &SerialNumber, GWObjects::Device &DeviceDetails);
bool GetDevice(const std::string &SerialNumber, GWObjects::Device &);
bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices,
const std::string &orderBy = "");
const std::string &orderBy = "",
const std::string &platform = "",
bool includeProvisioned = true);
// 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);
@@ -132,14 +157,18 @@ namespace OpenWifi {
bool DeleteDevices(std::uint64_t OlderContact, bool SimulatedOnly);
bool UpdateDevice(GWObjects::Device &);
bool UpdateDevice(LockedDbSession &Session, GWObjects::Device &);
bool UpdateDevice(Poco::Data::Session &Sess, GWObjects::Device &NewDeviceDetails);
bool DeviceExists(std::string &SerialNumber);
bool SetConnectInfo(std::string &SerialNumber, std::string &Firmware);
bool GetDeviceCount(uint64_t &Count);
bool GetDeviceCount(uint64_t &Count, const std::string &platform = "", bool includeProvisioned = true);
bool GetDeviceSerialNumbers(uint64_t From, uint64_t HowMany,
std::vector<std::string> &SerialNumbers,
const std::string &orderBy = "");
const std::string &orderBy = "",
const std::string &platform = "",
bool includeProvisioned = true);
bool GetDeviceFWUpdatePolicy(std::string &SerialNumber, std::string &Policy);
bool SetDevicePassword(std::string &SerialNumber, std::string &Password);
bool SetDevicePassword(LockedDbSession &Session, std::string &SerialNumber, std::string &Password);
bool UpdateSerialNumberCache();
static void GetDeviceDbFieldList(Types::StringVec &Fields);
@@ -148,9 +177,11 @@ namespace OpenWifi {
bool UpdateDeviceCapabilities(std::string &SerialNumber,
const Config::Capabilities &Capabilities);
bool UpdateDeviceCapabilities(Poco::Data::Session &Session, std::string &SerialNumber,
const Config::Capabilities &Capabilities);
bool GetDeviceCapabilities(std::string &SerialNumber, GWObjects::Capabilities &);
bool DeleteDeviceCapabilities(std::string &SerialNumber);
bool CreateDeviceCapabilities(std::string &SerialNumber,
bool CreateDeviceCapabilities(Poco::Data::Session &Session, std::string &SerialNumber,
const Config::Capabilities &Capabilities);
bool InitCapabilitiesCache();
@@ -171,6 +202,7 @@ namespace OpenWifi {
bool GetDefaultConfigurations(uint64_t From, uint64_t HowMany,
std::vector<GWObjects::DefaultConfiguration> &Devices);
bool FindDefaultConfigurationForModel(const std::string &Model,
const std::string &Platform,
GWObjects::DefaultConfiguration &DefConfig);
uint64_t GetDefaultConfigurationsCount();
bool DefaultConfigurationAlreadyExists(std::string &Name);
@@ -222,15 +254,15 @@ namespace OpenWifi {
void RemovedExpiredCommands();
void RemoveTimedOutCommands();
bool RemoveOldCommands(std::string &SerilNumber, std::string &Command);
bool RemoveOldCommands(std::string &SerialNumber, std::string &Command);
bool AddBlackListDevices(std::vector<GWObjects::BlackListedDevice> &Devices);
bool AddBlackListDevice(GWObjects::BlackListedDevice &Device);
bool GetBlackListDevice(std::string &SerialNumber, GWObjects::BlackListedDevice &Device);
bool DeleteBlackListDevice(std::string &SerialNumber);
bool IsBlackListed(const std::string &SerialNumber, std::string &reason,
bool IsBlackListed(std::uint64_t SerialNumber, std::string &reason,
std::string &author, std::uint64_t &created);
bool IsBlackListed(const std::string &SerialNumber);
bool IsBlackListed(std::uint64_t SerialNumber);
bool InitializeBlackListCache();
bool GetBlackListDevices(uint64_t Offset, uint64_t HowMany,
std::vector<GWObjects::BlackListedDevice> &Devices);
@@ -245,7 +277,9 @@ namespace OpenWifi {
bool RemoveCommandListRecordsOlderThan(uint64_t Date);
bool RemoveUploadedFilesRecordsOlderThan(uint64_t Date);
bool SetDeviceLastRecordedContact(std::string & SeialNumber, std::uint64_t lastRecordedContact);
bool SetDeviceLastRecordedContact(LockedDbSession &Session, std::string & SerialNumber, std::uint64_t lastRecordedContact);
bool SetDeviceLastRecordedContact(std::string & SerialNumber, std::uint64_t lastRecordedContact);
bool SetDeviceLastRecordedContact(Poco::Data::Session & Session, std::string & SerialNumber, std::uint64_t lastRecordedContact);
int Create_Tables();
int Create_Statistics();
@@ -262,13 +296,24 @@ namespace OpenWifi {
bool AnalyzeCommands(Types::CountedMap &R);
bool AnalyzeDevices(GWObjects::Dashboard &D);
void FixDeviceTypeBug();
int Start() override;
void Stop() override;
inline Poco::Data::Session StartSession() {
return Pool_->get();
}
private:
std::unique_ptr<OpenWifi::ScriptDB> ScriptDB_;
};
inline auto StorageService() { return Storage::instance(); }
inline LockedDbSession::LockedDbSession() {
Session_ = std::make_shared<Poco::Data::Session>(Poco::Data::Session(StorageService()->StartSession()));
Mutex_ = std::make_shared<std::mutex>();
}
} // namespace OpenWifi

View File

@@ -111,7 +111,6 @@ namespace OpenWifi {
}
} break;
case TelemetryNotification::NotificationType::unregister: {
std::lock_guard G(Mutex_);
auto client = Clients_.find(Notification->Data_);
if (client != Clients_.end()) {

View File

@@ -23,7 +23,7 @@
#include "framework/SubSystemServer.h"
#include "AP_WS_ReactorPool.h"
#include "AP_WS_Reactor_Pool.h"
#include "TelemetryClient.h"
namespace OpenWifi {

View File

@@ -129,4 +129,26 @@ namespace OpenWifi {
return RetrieveApiKeyInformation(SessionToken, UInfo, TID, Expired, Contacted, Suspended);
}
/**
* Given a role, remove the cached user info for any user with that role
*/
void AuthClient::EmptyCacheForRole(const std::string &role) {
SecurityObjects::USER_ROLE roleEnum = SecurityObjects::UserTypeFromString(role);
Poco::JSON::Object::ConstIterator it;
std::set<std::string> tokens = Cache_.getAllKeys();
for(const std::string &token : tokens) {
auto UInfo = Cache_.get(token);
if (UInfo->userinfo.userRole == roleEnum) {
Cache_.remove(token);
}
}
tokens = ApiKeyCache_.getAllKeys();
for(const std::string &token : tokens) {
auto UInfo = ApiKeyCache_.get(token);
if (UInfo->UserInfo.userinfo.userRole == roleEnum) {
ApiKeyCache_.remove(token);
}
}
}
} // namespace OpenWifi

View File

@@ -61,6 +61,8 @@ namespace OpenWifi {
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool &Expired, bool &Contacted, bool &Suspended);
void EmptyCacheForRole(const std::string &role);
private:
Poco::ExpireLRUCache<std::string, OpenWifi::SecurityObjects::UserInfoAndPolicy> Cache_{
512, 1200000};

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@
#pragma once
#include "framework/SubSystemServer.h"
#include "framework/ow_constants.h"
#include <valijson/adapters/poco_json_adapter.hpp>
#include <valijson/constraints/constraint.hpp>
#include <valijson/constraints/constraint_visitor.hpp>
@@ -17,33 +17,42 @@
namespace OpenWifi {
class ConfigurationValidator : public SubSystemServer {
public:
enum class ConfigurationType { AP = 0 , SWITCH = 1};
static auto instance() {
static auto instance_ = new ConfigurationValidator;
return instance_;
}
bool Validate(const std::string &C, std::vector<std::string> &Errors, bool Strict);
bool Validate(ConfigurationType Type, const std::string &C, std::string &Errors, bool Strict);
int Start() override;
void Stop() override;
void reinitialize(Poco::Util::Application &self) override;
inline static ConfigurationType GetType(const std::string &type) {
std::string Type = Poco::toUpper(type);
if (Type == Platforms::AP)
return ConfigurationType::AP;
if (Type == Platforms::SWITCH)
return ConfigurationType::SWITCH;
return ConfigurationType::AP;
}
private:
bool Initialized_ = false;
bool Working_ = false;
void Init();
std::unique_ptr<valijson::Schema> RootSchema_;
std::unique_ptr<valijson::SchemaParser> SchemaParser_;
std::unique_ptr<valijson::adapters::PocoJsonAdapter> PocoJsonAdapter_;
Poco::JSON::Object::Ptr SchemaDocPtr_;
bool SetSchema(const std::string &SchemaStr);
std::array<valijson::Schema,2> RootSchema_;
bool SetSchema(ConfigurationType Type, const std::string &SchemaStr);
ConfigurationValidator()
: SubSystemServer("ConfigValidator", "CFG-VALIDATOR", "config.validator") {}
};
inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); }
inline bool ValidateUCentralConfiguration(const std::string &C, std::vector<std::string> &Error,
inline bool ValidateUCentralConfiguration(ConfigurationValidator::ConfigurationType Type, const std::string &C, std::string &Errors,
bool strict) {
return ConfigurationValidator::instance()->Validate(C, Error, strict);
return ConfigurationValidator::instance()->Validate(Type, C, Errors, strict);
}
} // namespace OpenWifi

View File

@@ -9,8 +9,6 @@
namespace OpenWifi {
EventBusManager::EventBusManager(Poco::Logger &L) : Logger_(L) {}
void EventBusManager::run() {
Running_ = true;
Utils::SetThreadName("fmwk:EventMgr");
@@ -18,9 +16,9 @@ namespace OpenWifi {
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg,
false);
while (Running_) {
Poco::Thread::trySleep((unsigned long)MicroServiceDaemonBusTimer());
if (!Running_)
break;
if(!Poco::Thread::trySleep((unsigned long)MicroServiceDaemonBusTimer())) {
break;
}
Msg = (MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE));
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(),
Msg, false);
@@ -31,7 +29,7 @@ namespace OpenWifi {
};
void EventBusManager::Start() {
poco_information(Logger(), "Starting...");
poco_information(Logger_, "Starting...");
if (KafkaManager()->Enabled()) {
Thread_.start(*this);
}
@@ -39,11 +37,11 @@ namespace OpenWifi {
void EventBusManager::Stop() {
if (KafkaManager()->Enabled()) {
poco_information(Logger(), "Stopping...");
poco_information(Logger_, "Stopping...");
Running_ = false;
Thread_.wakeUp();
Thread_.join();
poco_information(Logger(), "Stopped...");
poco_information(Logger_, "Stopped...");
}
}

View File

@@ -12,7 +12,16 @@ namespace OpenWifi {
class EventBusManager : public Poco::Runnable {
public:
explicit EventBusManager(Poco::Logger &L);
EventBusManager() :
Logger_(Poco::Logger::create(
"EventBusManager", Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel())) {
}
static auto instance() {
static auto instance_ = new EventBusManager;
return instance_;
}
void run() final;
void Start();
void Stop();
@@ -24,4 +33,6 @@ namespace OpenWifi {
Poco::Logger &Logger_;
};
inline auto EventBusManager() { return EventBusManager::instance(); }
} // namespace OpenWifi

View File

@@ -79,8 +79,10 @@ namespace OpenWifi {
Utils::SetThreadName("Kafka:Prod");
cppkafka::Configuration Config(
{{"client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "")},
{"metadata.broker.list",
MicroServiceConfigGetString("openwifi.kafka.brokerlist", "")}});
{"metadata.broker.list",MicroServiceConfigGetString("openwifi.kafka.brokerlist", "")} // ,
// {"send.buffer.bytes", KafkaManager()->KafkaManagerMaximumPayloadSize() }
}
);
AddKafkaSecurity(Config);
@@ -275,6 +277,7 @@ namespace OpenWifi {
int KafkaManager::Start() {
if (!KafkaEnabled_)
return 0;
MaxPayloadSize_ = MicroServiceConfigGetInt("openwifi.kafka.max.payload", 250000);
ConsumerThr_.Start();
ProducerThr_.Start();
return 0;

View File

@@ -94,11 +94,14 @@ namespace OpenWifi {
return ConsumerThr_.UnregisterTopicWatcher(Topic,Id);
}
std::uint64_t KafkaManagerMaximumPayloadSize() const { return MaxPayloadSize_; }
private:
bool KafkaEnabled_ = false;
std::string SystemInfoWrapper_;
KafkaProducer ProducerThr_;
KafkaConsumer ConsumerThr_;
std::uint64_t MaxPayloadSize_ = 250000;
void PartitionAssignment(const cppkafka::TopicPartitionList &partitions);
void PartitionRevocation(const cppkafka::TopicPartitionList &partitions);

View File

@@ -27,6 +27,7 @@ namespace OpenWifi::KafkaTopics {
inline const char * EVENT_LEAVE = "leave";
inline const char * EVENT_KEEP_ALIVE = "keep-alive";
inline const char * EVENT_REMOVE_TOKEN = "remove-token";
inline const char * EVENT_PERMISSIONS_UPDATE = "permissions-update";
namespace Fields {
inline const char * EVENT = "event";
@@ -37,6 +38,7 @@ namespace OpenWifi::KafkaTopics {
inline const char * KEY = "key";
inline const char * VRSN = "version";
inline const char * TOKEN = "token";
inline const char * ROLE = "role";
} // namespace Fields
} // namespace ServiceEvents
} // namespace OpenWifi::KafkaTopics

View File

@@ -1,4 +1,5 @@
//
//
// Created by stephane bourque on 2022-10-26.
//
@@ -29,13 +30,29 @@
#include "framework/WebSocketLogger.h"
#include "framework/utils.h"
#ifdef USE_MEDUSA_CLIENT
#include <medusa/MedusaClient.h>
#endif
namespace OpenWifi {
void MicroService::Exit(int Reason) { std::exit(Reason); }
static std::string MakeServiceListString(const Types::MicroServiceMetaMap &Services) {
std::string SvcList;
for (const auto &Svc : Services) {
if (SvcList.empty())
SvcList = Svc.second.Type;
else
SvcList += ", " + Svc.second.Type;
}
return SvcList;
}
void MicroService::BusMessageReceived([[maybe_unused]] const std::string &Key,
const std::string &Payload) {
std::lock_guard G(InfraMutex_);
Poco::Logger &BusLogger = EventBusManager()->Logger();
try {
Poco::JSON::Parser P;
auto Object = P.parse(Payload).extract<Poco::JSON::Object::Ptr>();
@@ -55,13 +72,10 @@ namespace OpenWifi {
Object->has(KafkaTopics::ServiceEvents::Fields::KEY)) {
auto PrivateEndPoint =
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString();
if (Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE &&
Services_.find(PrivateEndPoint) != Services_.end()) {
Services_[PrivateEndPoint].LastUpdate = Utils::Now();
} else if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) {
if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) {
Services_.erase(PrivateEndPoint);
poco_debug(
logger(),
poco_information(
BusLogger,
fmt::format(
"Service {} ID={} leaving system.",
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
@@ -69,14 +83,7 @@ namespace OpenWifi {
ID));
} else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN ||
Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) {
poco_debug(
logger(),
fmt::format(
"Service {} ID={} joining system.",
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
.toString(),
ID));
Services_[PrivateEndPoint] = Types::MicroServiceMeta{
auto ServiceInfo = Types::MicroServiceMeta{
.Id = ID,
.Type = Poco::toLower(
Object->get(KafkaTopics::ServiceEvents::Fields::TYPE)
@@ -94,20 +101,46 @@ namespace OpenWifi {
.toString(),
.LastUpdate = Utils::Now()};
std::string SvcList;
for (const auto &Svc : Services_) {
if (SvcList.empty())
SvcList = Svc.second.Type;
else
SvcList += ", " + Svc.second.Type;
auto s1 = MakeServiceListString(Services_);
auto PreviousSize = Services_.size();
Services_[PrivateEndPoint] = ServiceInfo;
auto CurrentSize = Services_.size();
if(Event == KafkaTopics::ServiceEvents::EVENT_JOIN) {
if(!s1.empty()) {
poco_information(
BusLogger,
fmt::format(
"Service {} ID={} is joining the system.",
Object
->get(
KafkaTopics::ServiceEvents::Fields::PRIVATE)
.toString(),
ID));
}
std::string SvcList;
for (const auto &Svc : Services_) {
if (SvcList.empty())
SvcList = Svc.second.Type;
else
SvcList += ", " + Svc.second.Type;
}
poco_information(
BusLogger,
fmt::format("Current list of microservices: {}", SvcList));
} else if(CurrentSize!=PreviousSize) {
poco_information(
BusLogger,
fmt::format(
"Service {} ID={} is being added back in.",
Object
->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
.toString(),
ID));
}
poco_information(
logger(),
fmt::format("Current list of microservices: {}", SvcList));
}
} else {
poco_error(
logger(),
poco_information(
BusLogger,
fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",
Event));
}
@@ -118,32 +151,49 @@ namespace OpenWifi {
Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString());
#endif
} else {
poco_error(
logger(),
poco_information(
BusLogger,
fmt::format("KAFKA-MSG: invalid event '{}', missing token", Event));
}
} else if (Event == KafkaTopics::ServiceEvents::EVENT_PERMISSIONS_UPDATE) {
if (Object->has(KafkaTopics::ServiceEvents::Fields::ROLE)) {
// Permissions of this role have updated, cached user info is now invalid
AuthClient()->EmptyCacheForRole(
Object->get(KafkaTopics::ServiceEvents::Fields::ROLE).toString());
} else {
poco_information(
logger(),
fmt::format("KAFKA-MSG: invalid event '{}', missing role", Event));
}
} else {
poco_error(logger(),
poco_information(BusLogger,
fmt::format("Unknown Event: {} Source: {}", Event, ID));
}
}
} else {
poco_error(logger(), "Bad bus message.");
std::ostringstream os;
Object->stringify(std::cout);
std::ostringstream os;
Object->stringify(std::cout);
poco_error(BusLogger, fmt::format("Bad bus message: {}", os.str()));
}
auto i = Services_.begin();
auto ServiceHint = Services_.begin();
auto now = Utils::Now();
for (; i != Services_.end();) {
if ((now - i->second.LastUpdate) > 60) {
i = Services_.erase(i);
auto si1 = Services_.size();
auto ss1 = MakeServiceListString(Services_);
while(ServiceHint!=Services_.end()) {
if ((now - ServiceHint->second.LastUpdate) > 120) {
poco_information(BusLogger, fmt::format("ZombieService: Removing service {}, ", ServiceHint->second.PublicEndPoint));
ServiceHint = Services_.erase(ServiceHint);
} else
++i;
++ServiceHint;
}
if(Services_.size() != si1) {
auto ss2 = MakeServiceListString(Services_);
poco_information(BusLogger, fmt::format("Current list of microservices: {} -> {}", ss1, ss2));
}
} catch (const Poco::Exception &E) {
logger().log(E);
BusLogger.log(E);
}
}
@@ -167,25 +217,29 @@ namespace OpenWifi {
Res.push_back(ServiceRec);
}
return Res;
}
void MicroService::LoadConfigurationFile() {
std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR, ".");
ConfigFileName_ =
ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_;
Poco::Path ConfigFile(ConfigFileName_);
if(ConfigContent_.empty()) {
std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR, ".");
ConfigFileName_ =
ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_;
Poco::Path ConfigFile(ConfigFileName_);
if (!ConfigFile.isFile()) {
std::cerr << DAEMON_APP_NAME << ": Configuration " << ConfigFile.toString()
<< " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR +
" env variable the path of the " + DAEMON_PROPERTIES_FILENAME +
" file."
<< std::endl;
std::exit(Poco::Util::Application::EXIT_CONFIG);
}
// loadConfiguration(ConfigFile.toString());
PropConfigurationFile_ = new Poco::Util::PropertyFileConfiguration(ConfigFile.toString());
if (!ConfigFile.isFile()) {
std::cerr << DAEMON_APP_NAME << ": Configuration " << ConfigFile.toString()
<< " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR +
" env variable the path of the " + DAEMON_PROPERTIES_FILENAME +
" file."
<< std::endl;
std::exit(Poco::Util::Application::EXIT_CONFIG);
}
PropConfigurationFile_ = new Poco::Util::PropertyFileConfiguration(ConfigFile.toString());
} else {
std::istringstream is(ConfigContent_);
PropConfigurationFile_ = new Poco::Util::PropertyFileConfiguration(is);
}
configPtr()->addWriteable(PropConfigurationFile_, PRIO_DEFAULT);
}
@@ -388,49 +442,69 @@ namespace OpenWifi {
void DaemonPostInitialization(Poco::Util::Application &self);
void MicroService::initialize(Poco::Util::Application &self) {
// add the default services
LoadConfigurationFile();
InitializeLoggingSystem();
void MicroService::StartEverything(Poco::Util::Application &self) {
LoadConfigurationFile();
InitializeLoggingSystem();
SubSystems_.push_back(KafkaManager());
SubSystems_.push_back(ALBHealthCheckServer());
SubSystems_.push_back(RESTAPI_ExtServer());
SubSystems_.push_back(RESTAPI_IntServer());
static bool InitializedBaseService=false;
if(!InitializedBaseService) {
InitializedBaseService = true;
SubSystems_.push_back(KafkaManager());
SubSystems_.push_back(ALBHealthCheckServer());
SubSystems_.push_back(RESTAPI_ExtServer());
SubSystems_.push_back(RESTAPI_IntServer());
#ifndef TIP_SECURITY_SERVICE
SubSystems_.push_back(AuthClient());
SubSystems_.push_back(AuthClient());
#endif
Poco::Net::initializeSSL();
Poco::Net::HTTPStreamFactory::registerFactory();
Poco::Net::HTTPSStreamFactory::registerFactory();
Poco::Net::FTPStreamFactory::registerFactory();
Poco::Net::FTPSStreamFactory::registerFactory();
Poco::File DataDir(ConfigPath("openwifi.system.data"));
DataDir_ = DataDir.path();
if (!DataDir.exists()) {
try {
DataDir.createDirectory();
} catch (const Poco::Exception &E) {
logger().log(E);
}
}
WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets", "");
if (WWWAssetsDir_.empty())
WWWAssetsDir_ = DataDir_;
Poco::Net::initializeSSL();
Poco::Net::HTTPStreamFactory::registerFactory();
Poco::Net::HTTPSStreamFactory::registerFactory();
Poco::Net::FTPStreamFactory::registerFactory();
Poco::Net::FTPSStreamFactory::registerFactory();
}
LoadMyConfig();
Poco::File DataDir(ConfigPath("openwifi.system.data"));
DataDir_ = DataDir.path();
if (!DataDir.exists()) {
try {
DataDir.createDirectory();
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
}
WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets", "");
if (WWWAssetsDir_.empty())
WWWAssetsDir_ = DataDir_;
AllowExternalMicroServices_ = ConfigGetBool("allowexternalmicroservices", true);
LoadMyConfig();
InitializeSubSystemServers();
ServerApplication::initialize(self);
DaemonPostInitialization(self);
AllowExternalMicroServices_ = ConfigGetBool("allowexternalmicroservices", true);
Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) {
this->BusMessageReceived(Key, Payload);
};
KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
InitializeSubSystemServers();
ServerApplication::initialize(self);
DaemonPostInitialization(self);
Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) {
this->BusMessageReceived(Key, Payload);
};
KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
}
void MicroService::StopEverything([[maybe_unused]] Poco::Util::Application &self) {
LoadConfigurationFile();
InitializeLoggingSystem();
Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) {
this->BusMessageReceived(Key, Payload);
};
KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
}
void MicroService::initialize([[maybe_unused]] Poco::Util::Application &self) {
#ifndef USE_MEDUSA_CLIENT
StartEverything(self);
#endif
}
void MicroService::uninitialize() {
@@ -530,14 +604,12 @@ namespace OpenWifi {
for (auto i : SubSystems_) {
i->Start();
}
EventBusManager_ = std::make_unique<EventBusManager>(Poco::Logger::create(
"EventBusManager", Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel()));
EventBusManager_->Start();
EventBusManager()->Start();
}
void MicroService::StopSubSystemServers() {
AddActivity("Stopping");
EventBusManager_->Stop();
EventBusManager()->Stop();
for (auto i = SubSystems_.rbegin(); i != SubSystems_.rend(); ++i) {
(*i)->Stop();
}
@@ -697,7 +769,7 @@ namespace OpenWifi {
auto APIKEY = Request.get("X-API-KEY");
return APIKEY == MyHash_;
} catch (const Poco::Exception &E) {
logger().log(E);
Logger_.log(E);
}
return false;
}
@@ -718,6 +790,8 @@ namespace OpenWifi {
MicroServiceErrorHandler ErrorHandler(*this);
Poco::ErrorHandler::set(&ErrorHandler);
Args_ = args;
if (!HelpRequested_) {
SavePID();
@@ -733,11 +807,18 @@ namespace OpenWifi {
poco_information(logger, "Starting as a daemon.");
}
#ifdef USE_MEDUSA_CLIENT
MedusaClient::instance()->SetSubSystems(SubSystems_);
MedusaClient::instance()->Start();
waitForTerminationRequest();
MedusaClient::instance()->Stop();
#else
poco_information(logger, fmt::format("System ID set to {}", ID_));
StartSubSystemServers();
waitForTerminationRequest();
StopSubSystemServers();
logger.notice(fmt::format("Stopped {}...", DAEMON_APP_NAME));
#endif
}
return Application::EXIT_OK;

View File

@@ -55,9 +55,6 @@ namespace OpenWifi {
#include "nlohmann/json.hpp"
#include "ow_version.h"
#define _OWDEBUG_ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
// #define _OWDEBUG_ Logger().debug(Poco::format("%s: %lu",__FILE__,__LINE__));
namespace OpenWifi {
class MicroService : public Poco::Util::ServerApplication {
@@ -70,7 +67,6 @@ namespace OpenWifi {
SubSystems_(std::move(Subsystems)), Logger_(Poco::Logger::get("FRAMEWORK")) {
instance_ = this;
RandomEngine_.seed(std::chrono::steady_clock::now().time_since_epoch().count());
// Logger_ = Poco::Logger::root().get("BASE-SVC");
}
inline static const char *ExtraConfigurationFilename = "/configuration_override.json";
@@ -92,7 +88,7 @@ namespace OpenWifi {
inline uint64_t DaemonBusTimer() const { return DAEMON_BUS_TIMER; };
[[nodiscard]] const std::string &AppName() { return DAEMON_APP_NAME; }
static inline uint64_t GetPID() { return Poco::Process::id(); };
[[nodiscard]] inline const std::string GetPublicAPIEndPoint() {
[[nodiscard]] inline std::string GetPublicAPIEndPoint() const {
return MyPublicEndPoint_ + "/api/v1";
};
[[nodiscard]] inline const std::string &GetUIURI() const { return UIURI_; };
@@ -107,7 +103,8 @@ namespace OpenWifi {
}
static MicroService &instance() { return *instance_; }
inline void Exit(int Reason);
inline void Exit(int Reason) { std::exit(Reason); }
void BusMessageReceived(const std::string &Key, const std::string &Payload);
Types::MicroServiceMetaVec GetServices(const std::string &Type);
Types::MicroServiceMetaVec GetServices();
@@ -115,7 +112,9 @@ namespace OpenWifi {
void Reload();
void LoadMyConfig();
void initialize(Poco::Util::Application &self) override;
void uninitialize() override;
void StartEverything(Poco::Util::Application &self);
void StopEverything(Poco::Util::Application &self);
void uninitialize() override;
void reinitialize(Poco::Util::Application &self) override;
void defineOptions(Poco::Util::OptionSet &options) override;
void handleHelp(const std::string &name, const std::string &value);
@@ -132,7 +131,7 @@ namespace OpenWifi {
void Reload(const std::string &Sub);
Types::StringVec GetSubSystems() const;
Types::StringPairVec GetLogLevels();
const Types::StringVec &GetLogLevelNames();
static const Types::StringVec &GetLogLevelNames();
uint64_t ConfigGetInt(const std::string &Key, uint64_t Default);
uint64_t ConfigGetInt(const std::string &Key);
uint64_t ConfigGetBool(const std::string &Key, bool Default);
@@ -166,12 +165,25 @@ namespace OpenWifi {
const std::string &FormatterPattern,
const std::string &root_env_var);
inline bool AllowExternalMicroServices() const { return AllowExternalMicroServices_; }
const ArgVec &Args() const { return Args_; }
inline void SetConfigContent(const std::string &Content) { ConfigContent_ = Content; }
inline std::optional<OpenWifi::Types::MicroServiceMeta> GetPrivateEndPointServiceKey( const std::string & ServicePrivateEndPoint ) {
std::lock_guard G(InfraMutex_);
auto K = Services_.find(ServicePrivateEndPoint);
if(K==end(Services_)) {
return std::nullopt;
}
return K->second;
}
private:
static MicroService *instance_;
bool HelpRequested_ = false;
std::string LogDir_;
std::string ConfigFileName_;
std::string ConfigContent_;
uint64_t ID_ = 1;
Poco::SharedPtr<Poco::Crypto::RSAKey> AppKey_;
bool DebugMode_ = false;
@@ -201,7 +213,7 @@ namespace OpenWifi {
Poco::JWT::Signer Signer_;
Poco::Logger &Logger_;
Poco::ThreadPool TimerPool_{"timer:pool", 2, 32};
std::unique_ptr<EventBusManager> EventBusManager_;
ArgVec Args_;
};
inline MicroService *MicroService::instance_ = nullptr;

View File

@@ -133,4 +133,8 @@ namespace OpenWifi {
return MicroService::instance().Hash();
}
std::optional<OpenWifi::Types::MicroServiceMeta> MicroServicePrivateAccessKey(const std::string &servicePrivateEndPoint) {
return MicroService::instance().GetPrivateEndPointServiceKey(servicePrivateEndPoint);
}
} // namespace OpenWifi

View File

@@ -23,7 +23,9 @@ namespace OpenWifi {
std::string MicroServiceConfigGetString(const std::string &Key,
const std::string &DefaultValue);
std::string MicroServiceAccessKey();
bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue);
std::optional<OpenWifi::Types::MicroServiceMeta> MicroServicePrivateAccessKey(const std::string &servicePrivateEndPoint);
bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue);
std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue);
std::string MicroServicePrivateEndPoint();
std::uint64_t MicroServiceID();

View File

@@ -60,9 +60,52 @@ namespace OpenWifi {
AlwaysAuthorize_(AlwaysAuthorize), Server_(Server), MyRates_(Profile),
TransactionId_(TransactionId) {}
inline int nthOccurrence(const std::string& str, const std::string& findMe, int nth) {
/*
Helper function to get the index of the nth occurence of string findMe in string str.
if there are not n occurrences of findMe in str, returns -1.
*/
size_t pos = 0;
int count = 0;
while(count != nth)
{
pos+=1;
pos = str.find(findMe, pos);
if (pos == std::string::npos)
return -1;
count++;
}
return pos;
}
inline bool RoleIsAuthorized([[maybe_unused]] const std::string &Path,
[[maybe_unused]] const std::string &Method,
[[maybe_unused]] std::string &Reason) {
// If user role is admin or root, authorized is true
if (UserInfo_.userinfo.userRole == SecurityObjects::USER_ROLE::ADMIN || UserInfo_.userinfo.userRole == SecurityObjects::USER_ROLE::ROOT) {
return true;
}
// We just want the /api/v1/x part of the path so we need to account for
// extra path variables as well as query variables.
std::string pathstubtmp = Path.substr(0, nthOccurrence(Path, "/", 3));
std::string pathstub = pathstubtmp.substr(0, nthOccurrence(pathstubtmp, "?", 1));
// Next check the pathstub against the whitelist
if (SecurityObjects::API_WHITELIST.find(pathstub) != SecurityObjects::API_WHITELIST.end()) {
std::set<std::string> allowed_methods = SecurityObjects::API_WHITELIST.at(pathstub);
// The API stub is in the whitelist, but we also need to check that this method is whitelisted for this stub.
if (allowed_methods.find(Method) != allowed_methods.end()) {
return true;
}
}
// At this point, the user is not root/admin and the API + method is not whitelisted, so we disallow any method that is not a GET.
if (Method != Poco::Net::HTTPRequest::HTTP_GET) {
return false;
}
return true;
}

View File

@@ -47,6 +47,8 @@ namespace OpenWifi {
}
Poco::Data::SessionPool &Pool() { return *Pool_; }
private:
inline int Setup_SQLite();
inline int Setup_MySQL();

View File

@@ -58,11 +58,9 @@ namespace OpenWifi {
void UI_WebSocketClientServer::run() {
Running_ = true;
while (Running_) {
Poco::Thread::trySleep(2000);
if (!Running_)
break;
if(!Poco::Thread::trySleep(2000)) {
break;
}
std::lock_guard G(LocalMutex_);
for (const auto i : ToBeRemoved_) {
// std::cout << "Erasing old WS UI connection..." << std::endl;

View File

@@ -7,57 +7,59 @@
#include <vector>
#include <string>
#include "ow_constants.h"
namespace OpenWifi {
inline const std::vector<std::pair<std::string, std::string>> DefaultDeviceTypeList{
{"actiontec_web7200", "AP"},
{"cig_wf186w", "AP"},
{"cig_wf188n", "AP"},
{"cig_wf194c4", "AP"},
{"cig_wf196", "AP"},
{"cig_wf196-ca", "AP"},
{"cig_wf196-ca-ath12", "AP"},
{"cig_wf196-us", "AP"},
{"cig_wf610d", "AP"},
{"cig_wf660a", "AP"},
{"cig_wf808", "AP"},
{"cybertan_eww622-a1", "AP"},
{"edgecore_eap101", "AP"},
{"edgecore_eap101-ath12", "AP"},
{"edgecore_eap102", "AP"},
{"edgecore_eap104", "AP"},
{"edgecore_eap104-ath12", "AP"},
{"edgecore_ecs4100-12ph", "AP"},
{"edgecore_ecw5211", "AP"},
{"edgecore_ecw5410", "AP"},
{"edgecore_oap100", "AP"},
{"edgecore_spw2ac1200", "SWITCH"},
{"edgecore_spw2ac1200-lan-poe", "SWITCH"},
{"edgecore_ssw2ac2600", "SWITCH"},
{"hfcl_ion4", "AP"},
{"hfcl_ion4x", "AP"},
{"hfcl_ion4x_2", "AP"},
{"hfcl_ion4xe", "AP"},
{"hfcl_ion4xi", "AP"},
{"indio_um-305ac", "AP"},
{"indio_um-305ax", "AP"},
{"indio_um-310ax-v1", "AP"},
{"indio_um-325ac", "AP"},
{"indio_um-510ac-v3", "AP"},
{"indio_um-510axm-v1", "AP"},
{"indio_um-510axp-v1", "AP"},
{"indio_um-550ac", "AP"},
{"linksys_e8450-ubi", "AP"},
{"linksys_ea6350-v4", "AP"},
{"linksys_ea8300", "AP"},
{"liteon_wpx8324", "AP"},
{"meshpp_s618_cp01", "AP"},
{"meshpp_s618_cp03", "AP"},
{"udaya_a5-id2", "AP"},
{"wallys_dr40x9", "AP"},
{"wallys_dr6018", "AP"},
{"wallys_dr6018_v4", "AP"},
{"x64_vm", "AP"},
{"yuncore_ax840", "AP"},
{"yuncore_fap640", "AP"},
{"yuncore_fap650", "AP"}};
{"actiontec_web7200", Platforms::AP},
{"cig_wf186w", Platforms::AP},
{"cig_wf188n", Platforms::AP},
{"cig_wf194c4", Platforms::AP},
{"cig_wf196", Platforms::AP},
{"cig_wf196-ca", Platforms::AP},
{"cig_wf196-ca-ath12", Platforms::AP},
{"cig_wf196-us", Platforms::AP},
{"cig_wf610d", Platforms::AP},
{"cig_wf660a", Platforms::AP},
{"cig_wf808", Platforms::AP},
{"cybertan_eww622-a1", Platforms::AP},
{"edgecore_eap101", Platforms::AP},
{"edgecore_eap101-ath12", Platforms::AP},
{"edgecore_eap102", Platforms::AP},
{"edgecore_eap104", Platforms::AP},
{"edgecore_eap104-ath12", Platforms::AP},
{"edgecore_ecs4100-12ph", Platforms::AP},
{"edgecore_ecw5211", Platforms::AP},
{"edgecore_ecw5410", Platforms::AP},
{"edgecore_oap100", Platforms::AP},
{"edgecore_spw2ac1200", Platforms::SWITCH},
{"edgecore_spw2ac1200-lan-poe", Platforms::SWITCH},
{"edgecore_ssw2ac2600", Platforms::SWITCH},
{"hfcl_ion4", Platforms::AP},
{"hfcl_ion4x", Platforms::AP},
{"hfcl_ion4x_2", Platforms::AP},
{"hfcl_ion4xe", Platforms::AP},
{"hfcl_ion4xi", Platforms::AP},
{"indio_um-305ac", Platforms::AP},
{"indio_um-305ax", Platforms::AP},
{"indio_um-310ax-v1", Platforms::AP},
{"indio_um-325ac", Platforms::AP},
{"indio_um-510ac-v3", Platforms::AP},
{"indio_um-510axm-v1", Platforms::AP},
{"indio_um-510axp-v1", Platforms::AP},
{"indio_um-550ac", Platforms::AP},
{"linksys_e8450-ubi", Platforms::AP},
{"linksys_ea6350-v4", Platforms::AP},
{"linksys_ea8300", Platforms::AP},
{"liteon_wpx8324", Platforms::AP},
{"meshpp_s618_cp01", Platforms::AP},
{"meshpp_s618_cp03", Platforms::AP},
{"udaya_a5-id2", Platforms::AP},
{"wallys_dr40x9", Platforms::AP},
{"wallys_dr6018", Platforms::AP},
{"wallys_dr6018_v4", Platforms::AP},
{"x64_vm", Platforms::AP},
{"yuncore_ax840", Platforms::AP},
{"yuncore_fap640", Platforms::AP},
{"yuncore_fap650", Platforms::AP}};
}

View File

@@ -576,8 +576,8 @@ namespace ORM {
bool UpdateRecord(field_name_t FieldName, const T &Value, const RecordType &R) {
try {
assert(ValidFieldName(FieldName));
Poco::Data::Session Session = Pool_.get();
Session.begin();
Poco::Data::Statement Update(Session);
RecordTuple RT;
@@ -593,6 +593,7 @@ namespace ORM {
Update.execute();
if (Cache_)
Cache_->UpdateCache(R);
Session.commit();
return true;
} catch (const Poco::Exception &E) {
Logger_.log(E);
@@ -662,6 +663,7 @@ namespace ORM {
assert(ValidFieldName(FieldName));
Poco::Data::Session Session = Pool_.get();
Session.begin();
Poco::Data::Statement Delete(Session);
std::string St = "delete from " + TableName_ + " where " + FieldName + "=?";
@@ -671,6 +673,7 @@ namespace ORM {
Delete.execute();
if (Cache_)
Cache_->Delete(FieldName, Value);
Session.commit();
return true;
} catch (const Poco::Exception &E) {
Logger_.log(E);
@@ -682,11 +685,13 @@ namespace ORM {
try {
assert(!WhereClause.empty());
Poco::Data::Session Session = Pool_.get();
Session.begin();
Poco::Data::Statement Delete(Session);
std::string St = "delete from " + TableName_ + " where " + WhereClause;
Delete << St;
Delete.execute();
Session.commit();
return true;
} catch (const Poco::Exception &E) {
Logger_.log(E);

View File

@@ -565,6 +565,7 @@ namespace OpenWifi::RESTAPI::Protocol {
static const char *TRANSFER = "transfer";
static const char *CERTUPDATE = "certupdate";
static const char *POWERCYCLE = "powercycle";
static const char *RRM = "rrm";
static const char *REQUIREMENTS = "requirements";
@@ -687,6 +688,7 @@ namespace OpenWifi::uCentralProtocol {
static const char *TRANSFER = "transfer";
static const char *CERTUPDATE = "certupdate";
static const char *POWERCYCLE = "powercycle";
static const char *RRM = "rrm";
static const char *ACTIONS = "actions";
@@ -785,6 +787,7 @@ namespace OpenWifi::APCommands {
rrm,
certupdate,
transfer,
powercycle,
unknown
};
@@ -799,7 +802,7 @@ namespace OpenWifi::APCommands {
RESTAPI::Protocol::EVENTQUEUE, RESTAPI::Protocol::TELEMETRY,
RESTAPI::Protocol::PING, RESTAPI::Protocol::SCRIPT,
RESTAPI::Protocol::RRM, RESTAPI::Protocol::CERTUPDATE,
RESTAPI::Protocol::TRANSFER
RESTAPI::Protocol::TRANSFER, RESTAPI::Protocol::POWERCYCLE
};
inline const char *to_string(Commands Cmd) { return uCentralAPCommands[(uint8_t)Cmd]; }
@@ -828,6 +831,11 @@ namespace OpenWifi::Provisioning::DeviceClass {
} // namespace OpenWifi::Provisioning::DeviceClass
namespace OpenWifi::Platforms {
static const std::string AP = "ap";
static const std::string SWITCH = "switch";
}
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif

View File

@@ -126,20 +126,6 @@ namespace OpenWifi::Utils {
[[nodiscard]] std::uint64_t ConvertDate(const std::string &d);
[[nodiscard]] inline uint8_t CalculateMacAddressHash(std::uint64_t value) {
uint8_t hash = 0, i=6;
while(i) {
hash ^= (value & 0xFF) + 1;
value >>= 8;
--i;
}
return hash;
}
[[nodiscard]] inline uint8_t CalculateMacAddressHash(const std::string & value) {
return CalculateMacAddressHash(MACToInt(value));
}
template <typename T> std::string int_to_hex(T i) {
std::stringstream stream;
stream << std::setfill('0') << std::setw(12) << std::hex << i;
@@ -330,5 +316,90 @@ namespace OpenWifi::Utils {
uint32_t Port;
};
class CompressedString {
public:
CompressedString() {
DecompressedSize_ = 0;
};
explicit CompressedString(const std::string &Data) : DecompressedSize_(Data.size()) {
CompressIt(Data);
}
CompressedString(const CompressedString &Data) {
this->DecompressedSize_ = Data.DecompressedSize_;
this->CompressedData_ = Data.CompressedData_;
}
CompressedString& operator=(const CompressedString& rhs) {
if (this != &rhs) {
this->DecompressedSize_ = rhs.DecompressedSize_;
this->CompressedData_ = rhs.CompressedData_;
}
return *this;
}
CompressedString& operator=(CompressedString&& rhs) {
if (this != &rhs) {
this->DecompressedSize_ = rhs.DecompressedSize_;
this->CompressedData_ = rhs.CompressedData_;
}
return *this;
}
~CompressedString() = default;
operator std::string() const {
return DecompressIt();
}
CompressedString &operator=(const std::string &Data) {
DecompressedSize_ = Data.size();
CompressIt(Data);
return *this;
}
auto CompressedSize() const { return CompressedData_.size(); }
auto DecompressedSize() const { return DecompressedSize_; }
private:
std::string CompressedData_;
std::size_t DecompressedSize_;
inline void CompressIt(const std::string &Data) {
z_stream strm; // = {0};
CompressedData_.resize(Data.size());
strm.next_in = (Bytef *)Data.data();
strm.avail_in = Data.size();
strm.next_out = (Bytef *)CompressedData_.data();
strm.avail_out = Data.size();
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY);
deflate(&strm, Z_FINISH);
deflateEnd(&strm);
CompressedData_.resize(strm.total_out);
}
[[nodiscard]] std::string DecompressIt() const {
std::string Result;
if(DecompressedSize_!=0) {
Result.resize(DecompressedSize_);
z_stream strm ; //= {0};
strm.next_in = (Bytef *)CompressedData_.data();
strm.avail_in = CompressedData_.size();
strm.next_out = (Bytef *)Result.data();
strm.avail_out = Result.size();
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
inflateInit2(&strm, 15 + 32);
inflate(&strm, Z_FINISH);
inflateEnd(&strm);
}
return Result;
}
};
} // namespace OpenWifi::Utils

View File

@@ -146,7 +146,7 @@ namespace OpenWifi {
auto WebClientSecureContext =
new Poco::Net::Context(Poco::Net::Context::SERVER_USE, KeyFileName,
CertFileName, "", Poco::Net::Context::VERIFY_RELAXED);
CertFileName, "", Poco::Net::Context::VERIFY_NONE);
Poco::Crypto::X509Certificate WebRoot(RootCaFileName);
WebClientSecureContext->addCertificateAuthority(WebRoot);
WebClientSecureContext->disableStatelessSessionResumption();

View File

@@ -56,10 +56,10 @@ namespace OpenWifi {
struct DeviceDetails {
std::string reason;
std::string author;
std::uint64_t created;
std::uint64_t created=Utils::Now();
};
static std::map<std::string, DeviceDetails> BlackListDevices;
static std::map<std::uint64_t , DeviceDetails> BlackListDevices;
static std::recursive_mutex BlackListMutex;
bool Storage::InitializeBlackListCache() {
@@ -78,7 +78,7 @@ namespace OpenWifi {
auto Reason = RSet[1].convert<std::string>();
auto Author = RSet[2].convert<std::string>();
auto Created = RSet[3].convert<std::uint64_t>();
BlackListDevices[SerialNumber] =
BlackListDevices[Utils::MACToInt(SerialNumber)] =
DeviceDetails{.reason = Reason, .author = Author, .created = Created};
More = RSet.moveNext();
}
@@ -93,6 +93,7 @@ namespace OpenWifi {
bool Storage::AddBlackListDevice(GWObjects::BlackListedDevice &Device) {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Insert(Sess);
std::string St{"INSERT INTO BlackList (" + DB_BlackListDeviceSelectFields + ") " +
@@ -102,9 +103,9 @@ namespace OpenWifi {
ConvertBlackListDeviceRecord(Device, T);
Insert << ConvertParams(St), Poco::Data::Keywords::use(T);
Insert.execute();
Sess.commit();
std::lock_guard G(BlackListMutex);
BlackListDevices[Device.serialNumber] = DeviceDetails{
BlackListDevices[Utils::MACToInt(Device.serialNumber)] = DeviceDetails{
.reason = Device.reason, .author = Device.author, .created = Device.created};
return true;
} catch (const Poco::Exception &E) {
@@ -130,6 +131,7 @@ namespace OpenWifi {
bool Storage::DeleteBlackListDevice(std::string &SerialNumber) {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Delete(Sess);
std::string St{"DELETE FROM BlackList WHERE SerialNumber=?"};
@@ -137,9 +139,9 @@ namespace OpenWifi {
Poco::toLowerInPlace(SerialNumber);
Delete << ConvertParams(St), Poco::Data::Keywords::use(SerialNumber);
Delete.execute();
Sess.commit();
std::lock_guard G(BlackListMutex);
BlackListDevices.erase(SerialNumber);
BlackListDevices.erase(Utils::MACToInt(SerialNumber));
return true;
} catch (const Poco::Exception &E) {
poco_warning(Logger(), fmt::format("{}: Failed with: {}", std::string(__func__),
@@ -177,6 +179,7 @@ namespace OpenWifi {
GWObjects::BlackListedDevice &Device) {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Update(Sess);
std::string St{"UPDATE BlackList SET " + DB_BlackListDeviceUpdateFields +
@@ -187,9 +190,9 @@ namespace OpenWifi {
Update << ConvertParams(St), Poco::Data::Keywords::use(T),
Poco::Data::Keywords::use(SerialNumber);
Update.execute();
Sess.commit();
std::lock_guard G(BlackListMutex);
BlackListDevices[Device.serialNumber] = DeviceDetails{
BlackListDevices[Utils::MACToInt(Device.serialNumber)] = DeviceDetails{
.reason = Device.reason, .author = Device.author, .created = Device.created};
return true;
@@ -233,10 +236,10 @@ namespace OpenWifi {
return BlackListDevices.size();
}
bool Storage::IsBlackListed(const std::string &SerialNumber, std::string &reason,
bool Storage::IsBlackListed(std::uint64_t SerialNumber, std::string &reason,
std::string &author, std::uint64_t &created) {
std::lock_guard G(BlackListMutex);
auto DeviceHint = BlackListDevices.find(Poco::toLower(SerialNumber));
auto DeviceHint = BlackListDevices.find(SerialNumber);
if (DeviceHint == end(BlackListDevices))
return false;
reason = DeviceHint->second.reason;
@@ -245,9 +248,9 @@ namespace OpenWifi {
return true;
}
bool Storage::IsBlackListed(const std::string &SerialNumber) {
bool Storage::IsBlackListed(std::uint64_t SerialNumber) {
std::lock_guard G(BlackListMutex);
auto DeviceHint = BlackListDevices.find(Poco::toLower(SerialNumber));
auto DeviceHint = BlackListDevices.find(SerialNumber);
return DeviceHint != end(BlackListDevices);
}
} // namespace OpenWifi

View File

@@ -17,11 +17,11 @@
namespace OpenWifi {
bool Storage::CreateDeviceCapabilities(std::string &SerialNumber,
bool Storage::CreateDeviceCapabilities(Poco::Data::Session &Session, std::string &SerialNumber,
const Config::Capabilities &Capabilities) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement UpSert(Sess);
Session.begin();
Poco::Data::Statement UpSert(Session);
std::string TCaps{Capabilities.AsString()};
uint64_t Now = Utils::Now();
@@ -33,6 +33,7 @@ namespace OpenWifi {
Poco::Data::Keywords::use(Now), Poco::Data::Keywords::use(TCaps),
Poco::Data::Keywords::use(Now);
UpSert.execute();
Session.commit();
return true;
} catch (const Poco::Exception &E) {
poco_warning(Logger(), fmt::format("{}: Failed with: {}", std::string(__func__),
@@ -41,11 +42,11 @@ namespace OpenWifi {
return false;
}
bool Storage::UpdateDeviceCapabilities(std::string &SerialNumber,
bool Storage::UpdateDeviceCapabilities(Poco::Data::Session &Session, std::string &SerialNumber,
const Config::Capabilities &Caps) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement UpSert(Sess);
Session.begin();
Poco::Data::Statement UpSert(Session);
uint64_t Now = Utils::Now();
if (!Caps.Compatible().empty() && !Caps.Platform().empty())
@@ -61,6 +62,7 @@ namespace OpenWifi {
Poco::Data::Keywords::use(Now), Poco::Data::Keywords::use(TCaps),
Poco::Data::Keywords::use(Now);
UpSert.execute();
Session.commit();
return true;
} catch (const Poco::Exception &E) {
poco_warning(Logger(), fmt::format("{}: Failed with: {}", std::string(__func__),
@@ -99,13 +101,14 @@ namespace OpenWifi {
bool Storage::DeleteDeviceCapabilities(std::string &SerialNumber) {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Delete(Sess);
std::string St{"DELETE FROM Capabilities WHERE SerialNumber=?"};
Delete << ConvertParams(St), Poco::Data::Keywords::use(SerialNumber);
Delete.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
poco_warning(Logger(), fmt::format("{}: Failed with: {}", std::string(__func__),

View File

@@ -105,6 +105,7 @@ namespace OpenWifi {
bool Storage::RemoveOldCommands(std::string &SerialNumber, std::string &Command) {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Delete(Sess);
std::string St{
@@ -112,8 +113,7 @@ namespace OpenWifi {
Delete << ConvertParams(St), Poco::Data::Keywords::use(SerialNumber),
Poco::Data::Keywords::use(Command);
Delete.execute();
Delete.reset(Sess);
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -146,6 +146,7 @@ namespace OpenWifi {
RemoveOldCommands(SerialNumber, Command.Command);
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Insert(Sess);
std::string St{"INSERT INTO CommandList ( " + DB_Command_SelectFields + " ) VALUES( " +
@@ -156,7 +157,7 @@ namespace OpenWifi {
Insert << ConvertParams(St), Poco::Data::Keywords::use(R);
Insert.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
@@ -215,6 +216,7 @@ namespace OpenWifi {
bool Storage::DeleteCommands(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate) {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Delete(Sess);
bool DatesIncluded = (FromDate != 0 || ToDate != 0);
@@ -237,8 +239,7 @@ namespace OpenWifi {
Delete << IntroStatement + DateSelector;
Delete.execute();
Delete.reset(Sess);
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -274,7 +275,6 @@ namespace OpenWifi {
if (Records.size() < HowMany)
Done = true;
}
Select.reset(Sess);
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -286,6 +286,7 @@ namespace OpenWifi {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Update(Sess);
std::string St{"UPDATE CommandList SET Status=?, Executed=?, Completed=?, "
@@ -299,7 +300,7 @@ namespace OpenWifi {
Poco::Data::Keywords::use(Command.ErrorCode), Poco::Data::Keywords::use(UUID);
Update.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
@@ -311,6 +312,7 @@ namespace OpenWifi {
bool Storage::SetCommandExecuted(std::string &CommandUUID) {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Update(Sess);
auto Now = Utils::Now();
@@ -321,6 +323,7 @@ namespace OpenWifi {
Update << ConvertParams(St), Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Status), Poco::Data::Keywords::use(CommandUUID);
Update.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -331,6 +334,7 @@ namespace OpenWifi {
void Storage::RemovedExpiredCommands() {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Update(Sess);
auto Now = Utils::Now(), Window = Now - CommandManager()->CommandTimeout();
@@ -341,8 +345,7 @@ namespace OpenWifi {
Update << ConvertParams(St), Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Status), Poco::Data::Keywords::use(Window);
Update.execute();
Update.reset(Sess);
Sess.commit();
} catch (const Poco::Exception &E) {
Logger().log(E);
}
@@ -351,6 +354,7 @@ namespace OpenWifi {
bool Storage::SetCommandLastTry(std::string &CommandUUID) {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Update(Sess);
auto Now = Utils::Now();
@@ -359,6 +363,7 @@ namespace OpenWifi {
Update << ConvertParams(St), Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(CommandUUID);
Update.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -369,6 +374,7 @@ namespace OpenWifi {
void Storage::RemoveTimedOutCommands() {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Update(Sess);
auto Now = Utils::Now(), Window = Now - CommandManager()->CommandTimeout();
@@ -377,7 +383,7 @@ namespace OpenWifi {
Update << ConvertParams(St), Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Window);
Update.execute();
Update.reset(Sess);
Sess.commit();
} catch (const Poco::Exception &E) {
Logger().log(E);
}
@@ -386,6 +392,7 @@ namespace OpenWifi {
bool Storage::SetCommandTimedOut(std::string &CommandUUID) {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Update(Sess);
auto Now = Utils::Now();
@@ -395,6 +402,7 @@ namespace OpenWifi {
Update << ConvertParams(St), Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Status), Poco::Data::Keywords::use(CommandUUID);
Update.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -425,6 +433,7 @@ namespace OpenWifi {
bool Storage::DeleteCommand(std::string &UUID) {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Delete(Sess);
std::string St{"DELETE FROM CommandList WHERE UUID=?"};
@@ -435,8 +444,7 @@ namespace OpenWifi {
St = "DELETE FROM FileUploads WHERE UUID=?";
Delete << ConvertParams(St), Poco::Data::Keywords::use(UUID);
Delete.execute();
Delete.reset(Sess);
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -510,6 +518,7 @@ namespace OpenWifi {
auto Now = Utils::Now();
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Update(Sess);
std::string St{"UPDATE CommandList SET Executed=? WHERE UUID=?"};
@@ -518,7 +527,7 @@ namespace OpenWifi {
Poco::Data::Keywords::use(UUID);
Update.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -555,6 +564,7 @@ namespace OpenWifi {
}
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Update(Sess);
auto Status = to_string(Storage::CommandExecutionType::COMMAND_COMPLETED);
@@ -566,6 +576,7 @@ namespace OpenWifi {
Poco::Data::Keywords::use(ResultStr), Poco::Data::Keywords::use(Status),
Poco::Data::Keywords::use(tET), Poco::Data::Keywords::use(UUID);
Update.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -603,6 +614,7 @@ namespace OpenWifi {
bool Storage::CancelWaitFile(std::string &UUID, std::string &ErrorText) {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
auto Now = Utils::Now();
uint64_t Size = 0, WaitForFile = 0;
@@ -616,6 +628,7 @@ namespace OpenWifi {
Poco::Data::Keywords::use(ErrorText), Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(UUID);
Update.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -631,6 +644,7 @@ namespace OpenWifi {
uint64_t Size = FileContent.str().size();
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Statement(Sess);
std::string StatementStr;
@@ -644,14 +658,14 @@ namespace OpenWifi {
Poco::Data::Keywords::use(Now), Poco::Data::Keywords::use(Size),
Poco::Data::Keywords::use(UUID);
Statement.execute();
Sess.commit();
if (Size < FileUploader()->MaxSize()) {
Poco::Data::BLOB TheBlob;
TheBlob.appendRaw((const unsigned char *)FileContent.str().c_str(),
FileContent.str().size());
Sess.begin();
Poco::Data::Statement Insert(Sess);
std::string FileType{Type};
@@ -662,10 +676,12 @@ namespace OpenWifi {
Poco::Data::Keywords::use(FileType), Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(TheBlob);
Insert.execute();
return true;
Sess.commit();
} else {
poco_warning(Logger(), fmt::format("File {} is too large.", UUID));
}
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
@@ -712,6 +728,7 @@ namespace OpenWifi {
bool Storage::SetCommandResult(std::string &UUID, std::string &Result) {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Update(Sess);
auto Now = Utils::Now();
@@ -722,6 +739,7 @@ namespace OpenWifi {
Poco::Data::Keywords::use(Result), Poco::Data::Keywords::use(Status),
Poco::Data::Keywords::use(UUID);
Update.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
@@ -733,13 +751,14 @@ namespace OpenWifi {
bool Storage::RemoveAttachedFile(std::string &UUID) {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Delete(Sess);
std::string St{"DELETE FROM FileUploads WHERE UUID=?"};
Delete << ConvertParams(St), Poco::Data::Keywords::use(UUID);
Delete.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
@@ -751,11 +770,13 @@ namespace OpenWifi {
bool Storage::RemoveUploadedFilesRecordsOlderThan(uint64_t Date) {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Delete(Sess);
std::string St1{"delete from FileUploads where Created<?"};
Delete << ConvertParams(St1), Poco::Data::Keywords::use(Date);
Delete.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -766,11 +787,13 @@ namespace OpenWifi {
bool Storage::RemoveCommandListRecordsOlderThan(uint64_t Date) {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Delete(Sess);
std::string St1{"delete from CommandList where Submitted<?"};
Delete << ConvertParams(St1), Poco::Data::Keywords::use(Date);
Delete.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);

View File

@@ -82,6 +82,7 @@ namespace OpenWifi {
if (!TmpName.empty())
return false;
Sess.begin();
Poco::Data::Statement Insert(Sess);
std::string St2{"INSERT INTO DefaultFirmwares ( " + DB_DefFirmware_SelectFields +
@@ -94,6 +95,7 @@ namespace OpenWifi {
Insert << ConvertParams(St2),
Poco::Data::Keywords::use(R);
Insert.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
@@ -107,6 +109,7 @@ namespace OpenWifi {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Delete(Sess);
Poco::toLowerInPlace(deviceType);
@@ -114,7 +117,7 @@ namespace OpenWifi {
Delete << ConvertParams(St), Poco::Data::Keywords::use(deviceType);
Delete.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
poco_warning(Logger(), fmt::format("{}: Failed with: {}", std::string(__func__),
@@ -125,9 +128,9 @@ namespace OpenWifi {
bool Storage::UpdateDefaultFirmware(GWObjects::DefaultFirmware &DefFirmware) {
try {
uint64_t Now = Utils::Now();
Poco::Data::Session Sess = Pool_->get();
uint64_t Now = time(nullptr);
Sess.begin();
Poco::Data::Statement Update(Sess);
DefFirmware.LastModified = Now;
Poco::toLowerInPlace(DefFirmware.deviceType);
@@ -143,7 +146,7 @@ namespace OpenWifi {
Poco::Data::Keywords::use(R),
Poco::Data::Keywords::use(DefFirmware.deviceType);
Update.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
poco_warning(Logger(), fmt::format("{}: Failed with: {}", std::string(__func__),

View File

@@ -19,37 +19,39 @@ namespace OpenWifi {
"Models TEXT, "
"Description TEXT, "
"Created BIGINT , "
"LastModified BIGINT)"};
"LastModified BIGINT, Platform TEXT )"};
const static std::string DB_DefConfig_SelectFields{"Name, "
"Configuration, "
"Models, "
"Description, "
"Created, "
"LastModified "};
"LastModified, Platform "};
const static std::string DB_DefConfig_InsertValues{"?,?,?,?,?,?"};
const static std::string DB_DefConfig_InsertValues{"?,?,?,?,?,?,?"};
typedef Poco::Tuple<std::string, std::string, std::string, std::string, uint64_t, uint64_t>
typedef Poco::Tuple<std::string, std::string, std::string, std::string, uint64_t, uint64_t, std::string>
DefConfigRecordTuple;
typedef std::vector<DefConfigRecordTuple> DefConfigRecordList;
void Convert(const DefConfigRecordTuple &R, GWObjects::DefaultConfiguration &T) {
T.Name = R.get<0>();
T.Configuration = R.get<1>();
T.Models = RESTAPI_utils::to_object_array(R.get<2>());
T.Description = R.get<3>();
T.Created = R.get<4>();
T.LastModified = R.get<5>();
T.name = R.get<0>();
T.configuration = R.get<1>();
T.models = RESTAPI_utils::to_object_array(R.get<2>());
T.description = R.get<3>();
T.created = R.get<4>();
T.lastModified = R.get<5>();
T.platform = R.get<6>();
}
void Convert(const GWObjects::DefaultConfiguration &R, DefConfigRecordTuple &T) {
T.set<0>(R.Name);
T.set<1>(R.Configuration);
T.set<2>(RESTAPI_utils::to_string(R.Models));
T.set<3>(R.Description);
T.set<4>(R.Created);
T.set<5>(R.LastModified);
T.set<0>(R.name);
T.set<1>(R.configuration);
T.set<2>(RESTAPI_utils::to_string(R.models));
T.set<3>(R.description);
T.set<4>(R.created);
T.set<5>(R.lastModified);
T.set<6>(R.platform);
}
bool Storage::CreateDefaultConfiguration(std::string &Name,
@@ -69,9 +71,10 @@ namespace OpenWifi {
if (!TmpName.empty())
return false;
Config::Config Cfg(DefConfig.Configuration);
Config::Config Cfg(DefConfig.configuration);
if (Cfg.Valid()) {
Sess.begin();
Poco::Data::Statement Insert(Sess);
std::string St{"INSERT INTO DefaultConfigs ( " + DB_DefConfig_SelectFields +
@@ -83,6 +86,7 @@ namespace OpenWifi {
Convert(DefConfig, R);
Insert << ConvertParams(St), Poco::Data::Keywords::use(R);
Insert.execute();
Sess.commit();
return true;
} else {
poco_warning(Logger(), "Cannot create device: invalid configuration.");
@@ -99,13 +103,14 @@ namespace OpenWifi {
try {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Delete(Sess);
std::string St{"DELETE FROM DefaultConfigs WHERE Name=?"};
Delete << ConvertParams(St), Poco::Data::Keywords::use(Name);
Delete.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
poco_warning(Logger(), fmt::format("{}: Failed with: {}", std::string(__func__),
@@ -117,14 +122,14 @@ namespace OpenWifi {
bool Storage::UpdateDefaultConfiguration(std::string &Name,
GWObjects::DefaultConfiguration &DefConfig) {
try {
uint64_t Now = Utils::Now();
Poco::Data::Session Sess = Pool_->get();
uint64_t Now = time(nullptr);
Sess.begin();
Poco::Data::Statement Update(Sess);
DefConfig.LastModified = Now;
DefConfig.lastModified = Now;
std::string St{"UPDATE DefaultConfigs SET Name=?, Configuration=?, Models=?, "
"Description=?, Created=? , LastModified=? WHERE Name=?"};
"Description=?, Created=? , LastModified=? , Platform=? WHERE Name=?"};
DefConfigRecordTuple R;
Convert(DefConfig, R);
@@ -132,6 +137,7 @@ namespace OpenWifi {
Update << ConvertParams(St), Poco::Data::Keywords::use(R),
Poco::Data::Keywords::use(Name);
Update.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
poco_warning(Logger(), fmt::format("{}: Failed with: {}", std::string(__func__),
@@ -215,31 +221,30 @@ namespace OpenWifi {
return false;
}
bool Storage::FindDefaultConfigurationForModel(const std::string &Model,
GWObjects::DefaultConfiguration &DefConfig) {
bool Storage::FindDefaultConfigurationForModel(const std::string &DeviceModel, const std::string &Platform,
GWObjects::DefaultConfiguration &Config) {
try {
DefConfigRecordList Records;
DefConfigRecordList DefConfigs;
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
Select << "SELECT " + DB_DefConfig_SelectFields + " FROM DefaultConfigs",
Poco::Data::Keywords::into(Records);
Poco::Data::Keywords::into(DefConfigs);
Select.execute();
for (const auto &i : Records) {
GWObjects::DefaultConfiguration Config;
Convert(i, Config);
for (const auto &j : Config.Models) {
if (j == "*" || j == Model) {
DefConfig = Config;
for (const auto &DefConfig : DefConfigs) {
GWObjects::DefaultConfiguration C;
Convert(DefConfig, C);
for (const auto &Model : C.models) {
if ((Model == "*" || Model == DeviceModel) && (Config.platform == Platform)){
Config = C;
return true;
}
}
}
Logger().information(
fmt::format("AUTO-PROVISIONING: no default configuration for model:{}", Model));
return false;
fmt::format("AUTO-PROVISIONING: no default configuration for model:{}", DeviceModel));
} catch (const Poco::Exception &E) {
poco_warning(Logger(), fmt::format("{}: Failed with: {}", std::string(__func__),
E.displayText()));

View File

@@ -172,13 +172,26 @@ namespace OpenWifi {
R.set<30>(D.connectReason);
}
bool Storage::GetDeviceCount(uint64_t &Count) {
bool Storage::GetDeviceCount(uint64_t &Count, const std::string &platform, bool includeProvisioned) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
std::string st{"SELECT COUNT(*) FROM Devices"};
std::string st;
std::string whereClause = "";
if(!platform.empty()) {
if (includeProvisioned == false) {
whereClause = fmt::format("WHERE entity='' and venue='' and DeviceType='" + platform + "'");
} else {
whereClause = fmt::format("WHERE DeviceType='" + platform + "'");
}
} else {
if (includeProvisioned == false) {
whereClause = fmt::format("WHERE entity='' and venue=''");
}
}
st = fmt::format("SELECT COUNT(*) FROM Devices {}", whereClause);
Select << st, Poco::Data::Keywords::into(Count);
Select.execute();
return true;
@@ -190,16 +203,37 @@ namespace OpenWifi {
bool Storage::GetDeviceSerialNumbers(uint64_t From, uint64_t HowMany,
std::vector<std::string> &SerialNumbers,
const std::string &orderBy) {
const std::string &orderBy,
const std::string &platform, bool includeProvisioned) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
std::string st;
std::string whereClause = "";
if(!platform.empty()) {
if (includeProvisioned == false) {
whereClause = fmt::format("WHERE entity='' and venue='' and DeviceType='" + platform + "'");
} else {
whereClause = fmt::format("WHERE DeviceType='" + platform + "'");
}
//st = "SELECT SerialNumber From Devices WHERE DeviceType='" + platform + "' ";
} else {
if (includeProvisioned == false) {
whereClause = fmt::format("WHERE entity='' and venue=''");
}
//st = "SELECT SerialNumber From Devices ";
}
st = fmt::format("SELECT SerialNumber From Devices {}", whereClause);
if (orderBy.empty())
st = "SELECT SerialNumber From Devices ORDER BY SerialNumber ASC ";
st += " ORDER BY SerialNumber ASC ";
else
st = "SELECT SerialNumber From Devices " + orderBy;
st += orderBy;
Select << st + ComputeRange(From, HowMany), Poco::Data::Keywords::into(SerialNumbers);
Select.execute();
@@ -210,7 +244,7 @@ namespace OpenWifi {
return false;
}
bool Storage::UpdateDeviceConfiguration(std::string &SerialNumber, std::string &Configuration,
/* bool Storage::UpdateDeviceConfiguration(std::string &SerialNumber, std::string &Configuration,
uint64_t &NewUUID) {
try {
@@ -255,7 +289,7 @@ namespace OpenWifi {
}
return false;
}
*/
bool Storage::RollbackDeviceConfigurationChange(std::string & SerialNumber) {
try {
GWObjects::Device D;
@@ -265,9 +299,10 @@ namespace OpenWifi {
D.pendingUUID = 0;
D.LastConfigurationChange = Utils::Now();
ConfigurationCache().Add(Utils::SerialNumberToInt(SerialNumber), D.UUID);
SetCurrentConfigurationID(Utils::SerialNumberToInt(SerialNumber), D.UUID);
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Update(Sess);
DeviceRecordTuple R;
@@ -277,6 +312,7 @@ namespace OpenWifi {
Update << ConvertParams(St2), Poco::Data::Keywords::use(R),
Poco::Data::Keywords::use(SerialNumber);
Update.execute();
Sess.commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -286,22 +322,43 @@ namespace OpenWifi {
bool Storage::CompleteDeviceConfigurationChange(std::string & SerialNumber) {
try {
auto Session = Pool_->get();
return CompleteDeviceConfigurationChange(Session, SerialNumber);
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::CompleteDeviceConfigurationChange(Poco::Data::Session & Session, std::string & SerialNumber) {
try {
GWObjects::Device D;
if (!GetDevice(SerialNumber, D))
return false;
if(D.pendingConfiguration.empty())
return true;
D.Configuration = D.pendingConfiguration;
D.pendingConfiguration.clear();
D.UUID = D.pendingUUID;
D.pendingUUID = 0;
if(!D.pendingConfiguration.empty()) {
D.Configuration = D.pendingConfiguration;
D.pendingConfiguration.clear();
}
if(D.pendingUUID!=0) {
D.UUID = D.pendingUUID;
D.pendingUUID = 0;
}
// if this is a broken device, fix it...
if(D.UUID==0) {
Config::Config Cfg(D.Configuration);
if(Cfg.Valid()) {
D.UUID = Cfg.UUID();
}
}
D.LastConfigurationChange = Utils::Now();
SetCurrentConfigurationID(Utils::SerialNumberToInt(SerialNumber), D.UUID);
ConfigurationCache().Add(Utils::SerialNumberToInt(SerialNumber), D.UUID);
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Update(Sess);
Session.begin();
Poco::Data::Statement Update(Session);
DeviceRecordTuple R;
ConvertDeviceRecord(D, R);
@@ -310,6 +367,7 @@ namespace OpenWifi {
Update << ConvertParams(St2), Poco::Data::Keywords::use(R),
Poco::Data::Keywords::use(SerialNumber);
Update.execute();
Session.commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -328,13 +386,12 @@ namespace OpenWifi {
return false;
}
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
GWObjects::Device D;
if (!GetDevice(SerialNumber, D))
return false;
uint64_t Now = time(nullptr);
if(NewUUID==0) {
D.pendingUUID = NewUUID = (D.LastConfigurationChange == Now ? Now + 1 : Now);
@@ -343,6 +400,8 @@ namespace OpenWifi {
}
if (Cfg.SetUUID(NewUUID)) {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Update(Sess);
D.pendingConfiguration = Cfg.get();
@@ -353,6 +412,7 @@ namespace OpenWifi {
Update << ConvertParams(St2), Poco::Data::Keywords::use(R),
Poco::Data::Keywords::use(SerialNumber);
Update.execute();
Sess.commit();
poco_information(Logger(),
fmt::format("DEVICE-PENDING-CONFIGURATION-UPDATED({}): New UUID is {}",
SerialNumber, NewUUID));
@@ -366,68 +426,74 @@ namespace OpenWifi {
return false;
}
bool Storage::SetDeviceLastRecordedContact(std::string &SerialNumber, std::uint64_t lastRecordedContact) {
bool Storage::SetDeviceLastRecordedContact(LockedDbSession &Session, std::string &SerialNumber, std::uint64_t lastRecordedContact) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Update(Sess);
std::string St{"UPDATE Devices SET lastRecordedContact=? WHERE SerialNumber=?"};
Update << ConvertParams(St), Poco::Data::Keywords::use(lastRecordedContact),
Poco::Data::Keywords::use(SerialNumber);
Update.execute();
return true;
std::lock_guard Lock(Session.Mutex());
return SetDeviceLastRecordedContact(Session.Session(), SerialNumber, lastRecordedContact);
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::CreateDevice(GWObjects::Device &DeviceDetails) {
bool Storage::SetDeviceLastRecordedContact(Poco::Data::Session &Session, std::string &SerialNumber, std::uint64_t lastRecordedContact) {
try {
Session.begin();
Poco::Data::Statement Update(Session);
std::string St{"UPDATE Devices SET lastRecordedContact=? WHERE SerialNumber=?"};
Update << ConvertParams(St), Poco::Data::Keywords::use(lastRecordedContact),
Poco::Data::Keywords::use(SerialNumber);
Update.execute();
Session.commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::SetDeviceLastRecordedContact(std::string &SerialNumber, std::uint64_t lastRecordedContact) {
try {
auto Session = Pool_->get();
return SetDeviceLastRecordedContact(Session, SerialNumber, lastRecordedContact);
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::CreateDevice(Poco::Data::Session &Sess, GWObjects::Device &DeviceDetails) {
std::string SerialNumber;
try {
Config::Config Cfg(DeviceDetails.Configuration);
uint64_t Now = Utils::Now();
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
DeviceDetails.modified = Utils::Now();
DeviceDetails.CreationTimestamp = DeviceDetails.LastConfigurationDownload =
DeviceDetails.UUID = DeviceDetails.LastConfigurationChange = Now;
std::string St{"SELECT SerialNumber FROM Devices WHERE SerialNumber=?"};
if (Cfg.Valid() && Cfg.SetUUID(DeviceDetails.UUID)) {
// Select << ConvertParams(St), Poco::Data::Keywords::into(SerialNumber),
// Poco::Data::Keywords::use(DeviceDetails.SerialNumber);
// Select.execute();
DeviceDetails.Configuration = Cfg.get();
Sess.begin();
Poco::Data::Statement Insert(Sess);
// if (Select.rowsExtracted() == 0) {
Config::Config Cfg(DeviceDetails.Configuration);
uint64_t Now = Utils::Now();
std::string St2{"INSERT INTO Devices ( " + DB_DeviceSelectFields + " ) " +
DB_DeviceInsertValues + " ON CONFLICT (SerialNumber) DO NOTHING"};
DeviceDetails.modified = Utils::Now();
DeviceDetails.CreationTimestamp = DeviceDetails.LastConfigurationDownload =
DeviceDetails.UUID = DeviceDetails.LastConfigurationChange = Now;
if (Cfg.Valid() && Cfg.SetUUID(DeviceDetails.UUID)) {
DeviceDetails.Configuration = Cfg.get();
Poco::Data::Statement Insert(Sess);
std::string St2{"INSERT INTO Devices ( " + DB_DeviceSelectFields + " ) " +
DB_DeviceInsertValues + " ON CONFLICT (SerialNumber) DO NOTHING"};
SetCurrentConfigurationID(DeviceDetails.SerialNumber, DeviceDetails.UUID);
DeviceRecordTuple R;
ConvertDeviceRecord(DeviceDetails, R);
Insert << ConvertParams(St2), Poco::Data::Keywords::use(R);
Insert.execute();
SetCurrentConfigurationID(DeviceDetails.SerialNumber, DeviceDetails.UUID);
SerialNumberCache()->AddSerialNumber(DeviceDetails.SerialNumber);
return true;
} else {
poco_warning(Logger(), "Cannot create device: invalid configuration.");
return false;
}
// } else {
// poco_warning(Logger(), fmt::format("Device {} already exists.", SerialNumber));
// return false;
// }
SetCurrentConfigurationID(DeviceDetails.SerialNumber, DeviceDetails.UUID);
DeviceRecordTuple R;
ConvertDeviceRecord(DeviceDetails, R);
Insert << ConvertParams(St2), Poco::Data::Keywords::use(R);
Insert.execute();
Sess.commit();
SetCurrentConfigurationID(DeviceDetails.SerialNumber, DeviceDetails.UUID);
SerialNumberCache()->AddSerialNumber(DeviceDetails.SerialNumber);
} else {
poco_warning(Logger(), "Cannot create device: invalid configuration.");
return false;
}
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -435,6 +501,26 @@ namespace OpenWifi {
return false;
}
bool Storage::CreateDevice(LockedDbSession &Session, GWObjects::Device &DeviceDetails) {
try {
std::lock_guard Lock(Session.Mutex());
return CreateDevice(Session.Session(), DeviceDetails);
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::CreateDevice(GWObjects::Device &DeviceDetails) {
try {
auto Session = Pool_->get();
return CreateDevice(Session, DeviceDetails);
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
static std::string InsertRadiosCountyRegulation(std::string &Config,
const Poco::Net::IPAddress &IPAddress) {
std::string FoundCountry;
@@ -484,19 +570,18 @@ namespace OpenWifi {
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return true;
return false;
}
#define __DBGLOG__ std::cout << __LINE__ << std::endl;
bool Storage::CreateDefaultDevice(std::string &SerialNumber, const Config::Capabilities &Caps,
bool Storage::CreateDefaultDevice(Poco::Data::Session &Session, std::string &SerialNumber, const Config::Capabilities &Caps,
std::string &Firmware,
const Poco::Net::IPAddress &IPAddress,
bool simulated) {
GWObjects::Device D;
poco_information(Logger(), fmt::format("AUTO-CREATION({})", SerialNumber));
uint64_t Now = time(nullptr);
// poco_information(Logger(), fmt::format("AUTO-CREATION({}): Start.", SerialNumber));
uint64_t Now = Utils::Now();
GWObjects::DefaultConfiguration DefConfig;
if (!Caps.Platform().empty() && !Caps.Compatible().empty()) {
@@ -517,21 +602,29 @@ namespace OpenWifi {
}
if (!Found && AP_WS_Server()->UseDefaults() &&
FindDefaultConfigurationForModel(Caps.Compatible(), DefConfig)) {
Config::Config NewConfig(DefConfig.Configuration);
FindDefaultConfigurationForModel(Caps.Compatible(), Caps.Platform(), DefConfig)) {
Config::Config NewConfig(DefConfig.configuration);
NewConfig.SetUUID(Now);
D.Configuration = NewConfig.get();
} else if (!Found) {
Config::Config NewConfig;
NewConfig.SetUUID(Now);
D.Configuration = NewConfig.get();
if(Caps.Platform()==Platforms::AP) {
Config::Config NewConfig;
NewConfig.SetUUID(Now);
D.Configuration = NewConfig.get();
} else {
Poco::JSON::Object Obj;
Obj.set("uuid", Now);
std::ostringstream os;
Obj.stringify(os);
D.Configuration = os.str();
}
}
// We need to insert the country code according to the IP in the radios section...
D.locale = InsertRadiosCountyRegulation(D.Configuration, IPAddress);
D.SerialNumber = Poco::toLower(SerialNumber);
D.Compatible = Caps.Compatible();
D.DeviceType = Daemon()->IdentifyDevice(D.Compatible);
D.DeviceType = Caps.Platform();
D.MACAddress = Utils::SerialToMAC(SerialNumber);
D.Manufacturer = Caps.Model();
D.Firmware = Firmware;
@@ -539,12 +632,13 @@ namespace OpenWifi {
D.Notes = SecurityObjects::NoteInfoVec{
SecurityObjects::NoteInfo{(uint64_t)Utils::Now(), "", "Auto-provisioned."}};
CreateDeviceCapabilities(SerialNumber, Caps);
return CreateDevice(D);
CreateDeviceCapabilities(Session, SerialNumber, Caps);
auto Result = CreateDevice(Session, D);
poco_information(Logger(), fmt::format("AUTO-CREATION({}): Done, Result={}", SerialNumber, Result));
return Result;
}
bool Storage::GetDeviceFWUpdatePolicy(std::string &SerialNumber, std::string &Policy) {
/* bool Storage::GetDeviceFWUpdatePolicy(std::string &SerialNumber, std::string &Policy) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
@@ -559,46 +653,19 @@ namespace OpenWifi {
}
return false;
}
bool Storage::SetDevicePassword(std::string &SerialNumber, std::string &Password) {
*/
bool Storage::SetDevicePassword(LockedDbSession &Sess, std::string &SerialNumber, std::string &Password) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Update(Sess);
std::lock_guard Lock(Sess.Mutex());
Sess.Session().begin();
Poco::Data::Statement Update(Sess.Session());
std::string St{"UPDATE Devices SET DevicePassword=? WHERE SerialNumber=?"};
Update << ConvertParams(St), Poco::Data::Keywords::use(Password),
Poco::Data::Keywords::use(SerialNumber);
Update.execute();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::SetConnectInfo(std::string &SerialNumber, std::string &Firmware) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
// Get the old version and if they do not match, set the last date
std::string St{"SELECT Firmware FROM Devices WHERE SerialNumber=?"};
std::string TmpFirmware;
Select << ConvertParams(St), Poco::Data::Keywords::into(TmpFirmware),
Poco::Data::Keywords::use(SerialNumber);
Select.execute();
if (TmpFirmware != Firmware) {
Poco::Data::Statement Update(Sess);
std::string St2{
"UPDATE Devices SET Firmware=?, LastFWUpdate=? WHERE SerialNumber=?"};
uint64_t Now = Utils::Now();
Update << ConvertParams(St2), Poco::Data::Keywords::use(Firmware),
Poco::Data::Keywords::use(Now), Poco::Data::Keywords::use(SerialNumber);
Update.execute();
return true;
}
Sess.Session().commit();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -614,12 +681,14 @@ namespace OpenWifi {
for (const auto &tableName : TableNames) {
Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Delete(Sess);
std::string St = fmt::format("DELETE FROM {} WHERE SerialNumber='{}'", tableName, SerialNumber);
try {
Delete << St;
Delete.execute();
Sess.commit();
} catch (...) {
}
}
@@ -692,19 +761,14 @@ namespace OpenWifi {
return false;
}
bool Storage::GetDevice(std::string &SerialNumber, GWObjects::Device &DeviceDetails) {
bool Storage::GetDevice(Poco::Data::Session &Session, const std::string &SerialNumber, GWObjects::Device &DeviceDetails) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
std::string St{"SELECT " + DB_DeviceSelectFields +
" FROM Devices WHERE SerialNumber=?"};
Poco::Data::Statement Select(Session);
std::string St = fmt::format("SELECT {} FROM Devices WHERE SerialNumber='{}'", DB_DeviceSelectFields, SerialNumber);
DeviceRecordTuple R;
Select << ConvertParams(St), Poco::Data::Keywords::into(R),
Poco::Data::Keywords::use(SerialNumber);
Select << St, Poco::Data::Keywords::into(R);
Select.execute();
if (Select.rowsExtracted() == 0)
return false;
ConvertDeviceRecord(R, DeviceDetails);
@@ -715,6 +779,26 @@ namespace OpenWifi {
return false;
}
bool Storage::GetDevice(const std::string &SerialNumber, GWObjects::Device &DeviceDetails) {
try {
auto Sess = Pool_->get();
return GetDevice(Sess, SerialNumber, DeviceDetails);
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::GetDevice(LockedDbSession &Session, const std::string &SerialNumber, GWObjects::Device &DeviceDetails) {
try {
std::lock_guard Lock(Session.Mutex());
return GetDevice(Session.Session(), SerialNumber, DeviceDetails);
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::DeviceExists(std::string &SerialNumber) {
try {
Poco::Data::Session Sess = Pool_->get();
@@ -741,6 +825,26 @@ namespace OpenWifi {
bool Storage::UpdateDevice(GWObjects::Device &NewDeviceDetails) {
try {
Poco::Data::Session Sess = Pool_->get();
return UpdateDevice(Sess, NewDeviceDetails);
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::UpdateDevice(LockedDbSession &Session, GWObjects::Device &NewDeviceDetails) {
try {
std::lock_guard Lock(Session.Mutex());
return UpdateDevice(Session.Session(), NewDeviceDetails);
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::UpdateDevice(Poco::Data::Session &Sess, GWObjects::Device &NewDeviceDetails) {
try {
Sess.begin();
Poco::Data::Statement Update(Sess);
DeviceRecordTuple R;
@@ -753,6 +857,7 @@ namespace OpenWifi {
Update << ConvertParams(St2), Poco::Data::Keywords::use(R),
Poco::Data::Keywords::use(NewDeviceDetails.SerialNumber);
Update.execute();
Sess.commit();
// GetDevice(NewDeviceDetails.SerialNumber,NewDeviceDetails);
return true;
} catch (const Poco::Exception &E) {
@@ -762,18 +867,38 @@ namespace OpenWifi {
}
bool Storage::GetDevices(uint64_t From, uint64_t HowMany,
std::vector<GWObjects::Device> &Devices, const std::string &orderBy) {
std::vector<GWObjects::Device> &Devices, const std::string &orderBy, const std::string &platform,
bool includeProvisioned) {
DeviceRecordList Records;
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
// 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));
std::string st;
std::string whereClause = "";
if(platform.empty()) {
if (includeProvisioned == false) {
whereClause = fmt::format("WHERE entity='' and venue=''");
}
} else {
if (includeProvisioned == false) {
whereClause = fmt::format("WHERE DeviceType='{}' and entity='' and venue=''",platform);
} else {
whereClause = fmt::format("WHERE DeviceType='{}'", platform);
}
}
st =
fmt::format("SELECT {} FROM Devices {} {} {}", DB_DeviceSelectFields, whereClause,
orderBy.empty() ? " ORDER BY SerialNumber ASC " : orderBy,
ComputeRange(From, HowMany));
//Logger().information(fmt::format(" GetDevices st is {} ", st));
Select << ConvertParams(st), Poco::Data::Keywords::into(Records);
Select.execute();
@@ -1001,9 +1126,9 @@ namespace OpenWifi {
}
}
uint64_t Associations_2G, Associations_5G, Associations_6G;
uint64_t Associations_2G, Associations_5G, Associations_6G, uptime;
StateUtils::ComputeAssociations(RawObject, Associations_2G, Associations_5G,
Associations_6G);
Associations_6G, uptime);
UpdateCountedMap(Dashboard.associations, "2G", Associations_2G);
UpdateCountedMap(Dashboard.associations, "5G", Associations_5G);
UpdateCountedMap(Dashboard.associations, "6G", Associations_6G);
@@ -1027,4 +1152,25 @@ namespace OpenWifi {
FieldList.push_back(field);
}
void Storage::FixDeviceTypeBug() {
try {
std::vector<std::string> ScriptLines{
"update devices set devicetype='ap' where devicetype='AP';",
"update devices set devicetype='switch' where devicetype='SWITCH';",
"update devices set devicetype='ap' where devicetype!='ap' and devicetype!='switch';"
};
for (const auto &ScriptLine : ScriptLines) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement SqlStatement(Sess);
SqlStatement << ScriptLine, Poco::Data::Keywords::now;
} catch (...) {
}
}
} catch (const Poco::Exception &E) {
Logger().log(E);
}
}
} // namespace OpenWifi

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