Compare commits

..

132 Commits

Author SHA1 Message Date
TIP Automation User
d03dbcf96c Update OpenAPI docs for GitHub pages 2025-08-22 13:16:53 +00:00
TIP Automation User
aaded5fdd1 Update OpenAPI docs for GitHub pages 2025-08-14 20:33:59 +00:00
TIP Automation User
9121892a03 Update OpenAPI docs for GitHub pages 2024-09-25 19:10:55 +00:00
TIP Automation User
7a40cd26e7 Update OpenAPI docs for GitHub pages 2024-03-27 05:06:49 +00:00
TIP Automation User
f32fc95d0b Update OpenAPI docs for GitHub pages 2024-03-15 15:49:35 +00:00
TIP Automation User
9b0c06dc12 Update OpenAPI docs for GitHub pages 2024-03-15 15:07:15 +00:00
TIP Automation User
240b24f7b5 Update OpenAPI docs for GitHub pages 2024-03-15 15:01:09 +00:00
TIP Automation User
afc2c30621 Update OpenAPI docs for GitHub pages 2024-03-13 21:20:04 +00:00
TIP Automation User
46a5d59f99 Update OpenAPI docs for GitHub pages 2024-02-20 21:27:48 +00:00
TIP Automation User
41eb4eca2c Update OpenAPI docs for GitHub pages 2024-01-11 23:19:12 +00:00
TIP Automation User
ccc36c69ad Update OpenAPI docs for GitHub pages 2024-01-05 20:21:55 +00:00
TIP Automation User
94e40fab26 Update OpenAPI docs for GitHub pages 2024-01-04 16:10:27 +00:00
TIP Automation User
80a346e389 Update OpenAPI docs for GitHub pages 2023-11-21 05:13:49 +00:00
TIP Automation User
e0a688f67d Update OpenAPI docs for GitHub pages 2023-11-15 19:16:47 +00:00
TIP Automation User
d35d6b0597 Update OpenAPI docs for GitHub pages 2023-10-31 14:15:29 +00:00
TIP Automation User
98677ab128 Update OpenAPI docs for GitHub pages 2023-10-19 23:24:27 +00:00
TIP Automation User
6f5f51fcc6 Update OpenAPI docs for GitHub pages 2023-10-19 18:09:19 +00:00
TIP Automation User
f3ee562810 Update OpenAPI docs for GitHub pages 2023-10-06 15:34:55 +00:00
TIP Automation User
907e2fc7f1 Update OpenAPI docs for GitHub pages 2023-09-26 04:58:09 +00:00
TIP Automation User
9f67078884 Update OpenAPI docs for GitHub pages 2023-09-15 19:08:30 +00:00
TIP Automation User
86cbf39533 Update OpenAPI docs for GitHub pages 2023-08-31 17:43:21 +00:00
TIP Automation User
d79ab1069f Update OpenAPI docs for GitHub pages 2023-08-03 17:35:08 +00:00
TIP Automation User
f35d141d2c Update OpenAPI docs for GitHub pages 2023-08-03 17:13:23 +00:00
TIP Automation User
d758269f1f Update OpenAPI docs for GitHub pages 2023-07-12 16:07:53 +00:00
TIP Automation User
e301775fcd Update OpenAPI docs for GitHub pages 2023-07-12 15:45:57 +00:00
TIP Automation User
962867f5c9 Update OpenAPI docs for GitHub pages 2023-07-12 15:31:36 +00:00
TIP Automation User
f6c9b98a4b Update OpenAPI docs for GitHub pages 2023-07-12 06:15:29 +00:00
TIP Automation User
2645dd0800 Update OpenAPI docs for GitHub pages 2023-05-22 21:32:55 +00:00
TIP Automation User
374f56425e Update OpenAPI docs for GitHub pages 2023-05-22 19:12:34 +00:00
TIP Automation User
3015bba32d Update OpenAPI docs for GitHub pages 2023-05-22 15:52:05 +00:00
TIP Automation User
5502ea12e1 Update OpenAPI docs for GitHub pages 2023-05-16 16:42:23 +00:00
TIP Automation User
a211c62091 Update OpenAPI docs for GitHub pages 2023-05-16 16:31:26 +00:00
TIP Automation User
efd61ed51a Update OpenAPI docs for GitHub pages 2023-04-18 23:24:19 +00:00
TIP Automation User
5b0c775499 Update OpenAPI docs for GitHub pages 2023-04-18 22:09:49 +00:00
TIP Automation User
1c23a8584e Update OpenAPI docs for GitHub pages 2023-04-17 14:57:39 +00:00
TIP Automation User
c80c3be99e Update OpenAPI docs for GitHub pages 2023-04-06 15:59:49 +00:00
TIP Automation User
eadfa6bfc4 Update OpenAPI docs for GitHub pages 2023-04-04 16:04:59 +00:00
TIP Automation User
e594475f6c Update OpenAPI docs for GitHub pages 2023-04-04 03:45:05 +00:00
TIP Automation User
c4576a6858 Update OpenAPI docs for GitHub pages 2023-04-03 18:46:16 +00:00
TIP Automation User
90671250c1 Update OpenAPI docs for GitHub pages 2023-04-03 06:53:18 +00:00
TIP Automation User
f1d4a81946 Update OpenAPI docs for GitHub pages 2023-03-17 22:58:31 +00:00
TIP Automation User
1504b76dc7 Update OpenAPI docs for GitHub pages 2023-03-07 15:35:42 +00:00
TIP Automation User
9742304822 Update OpenAPI docs for GitHub pages 2023-02-28 06:26:09 +00:00
TIP Automation User
b19fcab532 Update OpenAPI docs for GitHub pages 2022-12-12 21:21:53 +00:00
TIP Automation User
6557e6e297 Update OpenAPI docs for GitHub pages 2022-12-01 10:17:45 +00:00
TIP Automation User
06b656d9e5 Update OpenAPI docs for GitHub pages 2022-11-27 21:57:21 +00:00
TIP Automation User
e215618c2c Update OpenAPI docs for GitHub pages 2022-11-25 19:01:09 +00:00
Dmitry Dunaev
a0ee1a40d4 [WIFI-11729] Fix: branch set for pages pushing
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-11-25 22:00:37 +03:00
Dmitry Dunaev
5c5aa3551b [WIFI-11729] Fix: pages generation
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-11-25 21:59:10 +03:00
Dmitry Dunaev
bd7daf4072 Merge pull request #272 from Telecominfraproject/feature/wifi-11729--openapi-gh-pages
[WIFI-11729] Add: workflow to generate OpenAPI docs
2022-11-25 21:48:14 +03:00
Dmitry Dunaev
dad844795f [WIFI-11729] Add: workflow to generate OpenAPI docs
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-11-25 21:47:59 +03:00
Johann Hoffmann
41107af0d0 Merge pull request #271 from Telecominfraproject/WIFI-11419-patch-workflows
[WIFI-11419] Patch workflows with regard to deprecated Github actions commands
2022-11-25 15:26:35 +01:00
Johann Hoffmann
468a2553f8 Update checkout action version and replace set-output commands
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-11-22 11:54:46 +01:00
stephb9959
37053a40b7 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-21 09:16:06 -08:00
stephb9959
7eff8c9699 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-21 07:38:30 -08:00
stephb9959
49d9030bf4 https://telecominfraproject.atlassian.net/browse/WIFI-11691
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-20 13:12:37 -08:00
stephb9959
9e741c0348 https://telecominfraproject.atlassian.net/browse/WIFI-11691
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-19 22:25:24 -08:00
stephb9959
95dc3c1a6c https://telecominfraproject.atlassian.net/browse/WIFI-11691
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-19 22:19:20 -08:00
stephb9959
2fa7081f3f https://telecominfraproject.atlassian.net/browse/WIFI-11691
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-19 21:32:24 -08:00
stephb9959
288773a727 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-18 19:52:37 -08:00
stephb9959
06079115e6 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-18 07:45:39 -08:00
stephb9959
5db21677dc https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-17 21:23:18 -08:00
stephb9959
5c7db88f10 https://telecominfraproject.atlassian.net/browse/WIFI-11691
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-17 21:02:45 -08:00
stephb9959
0060e81fae https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-17 11:35:33 -08:00
stephb9959
1a6bf2d71b https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-16 22:49:46 -08:00
stephb9959
59a6de92d0 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-16 10:31:30 -08:00
stephb9959
b7b013f669 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-16 10:18:07 -08:00
stephb9959
d8be1eca90 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-16 10:14:18 -08:00
stephb9959
d04f8965c3 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-16 10:03:57 -08:00
stephb9959
ffdbe6f4da https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-16 10:01:28 -08:00
stephb9959
fafa915613 https://telecominfraproject.atlassian.net/browse/WIFI-11620
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-15 10:24:06 -08:00
stephb9959
f5f0af0dcd https://telecominfraproject.atlassian.net/browse/WIFI-11251
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-14 23:55:27 -08:00
stephb9959
23eb4d6b0b https://telecominfraproject.atlassian.net/browse/WIFI-11251
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-14 23:52:30 -08:00
stephb9959
f9d6020c4f https://telecominfraproject.atlassian.net/browse/WIFI-11251
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-14 23:28:22 -08:00
stephb9959
b9dfbdd5e8 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-14 13:53:47 -08:00
stephb9959
8f9d708285 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-14 10:09:18 -08:00
stephb9959
05b06d3eac https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-13 22:01:12 -08:00
stephb9959
8b68ab8ac7 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-10 23:39:44 -08:00
stephb9959
80021d520f https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-10 23:32:52 -08:00
stephb9959
363cfa1998 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-10 23:13:58 -08:00
stephb9959
9ea1a5cde6 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-10 23:04:45 -08:00
stephb9959
faeb6bf6b8 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-09 22:49:55 -08:00
stephb9959
1917b1346b https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-09 22:48:14 -08:00
stephb9959
3feaf9221d https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-08 23:07:31 -08:00
stephb9959
943b735150 Merge remote-tracking branch 'origin/master' 2022-11-08 23:07:20 -08:00
stephb9959
02ce04261d https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-08 23:07:10 -08:00
Dmitry Dunaev
eae5f4f5f9 Merge pull request #270 from Telecominfraproject/fix/wifi-11490--git-hash
[WIFI-11490] Fix: Get Git hash command in CMakeLists
2022-11-08 13:42:16 +03:00
Dmitry Dunaev
8ec8a02924 [WIFI-11490] Fix: Get Git hash command in CMakeLists
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-11-08 13:07:22 +03:00
stephb9959
12c34ef63d https://telecominfraproject.atlassian.net/browse/WIFI-10918
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 15:31:34 -08:00
stephb9959
a54848b636 https://telecominfraproject.atlassian.net/browse/WIFI-10918
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 14:58:49 -08:00
stephb9959
35c09940b4 https://telecominfraproject.atlassian.net/browse/WIFI-10918
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 14:34:18 -08:00
stephb9959
cb4fdaab28 https://telecominfraproject.atlassian.net/browse/WIFI-10918
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 14:25:12 -08:00
stephb9959
3501de22ed https://telecominfraproject.atlassian.net/browse/WIFI-10918
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 14:08:00 -08:00
stephb9959
1f59fccc97 https://telecominfraproject.atlassian.net/browse/WIFI-10918
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 14:01:48 -08:00
stephb9959
4307d23b00 https://telecominfraproject.atlassian.net/browse/WIFI-11542
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 10:59:13 -08:00
stephb9959
b83345c91a https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-04 11:42:31 -07:00
stephb9959
76feb208bc https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-03 12:19:23 -07:00
stephb9959
efa49593da https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-03 10:44:27 -07:00
stephb9959
361d6fa22f https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-03 09:53:04 -07:00
stephb9959
f7d1b8f972 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-03 09:16:36 -07:00
stephb9959
a9afc2dc2b https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-03 08:56:44 -07:00
stephb9959
8d949b97ea https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 22:54:47 -07:00
stephb9959
0d5a07ffe1 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 22:30:11 -07:00
stephb9959
11972c2511 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 21:37:32 -07:00
stephb9959
3081efebd8 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 16:07:09 -07:00
stephb9959
b27039dcc8 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 16:05:08 -07:00
stephb9959
847f107ac2 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 16:03:14 -07:00
stephb9959
ec9766a544 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 16:01:47 -07:00
stephb9959
7bdc148063 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 16:00:00 -07:00
stephb9959
7284e9f100 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 15:53:55 -07:00
stephb9959
03ecfbea25 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 15:49:44 -07:00
stephb9959
eb1716e078 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 15:46:50 -07:00
stephb9959
b11b8a2f22 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 15:43:30 -07:00
stephb9959
845bb37c8c https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 15:29:49 -07:00
stephb9959
6f9f6495a0 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 15:21:57 -07:00
stephb9959
04ef327a86 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 15:20:50 -07:00
stephb9959
913b595587 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 15:16:39 -07:00
stephb9959
7628af35ba https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 15:14:14 -07:00
stephb9959
cad8b7752b https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 15:10:54 -07:00
stephb9959
7175546f54 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 14:50:38 -07:00
stephb9959
6186f46ec2 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 14:48:35 -07:00
stephb9959
2413867bf3 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 14:46:21 -07:00
stephb9959
545c539a08 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 12:30:49 -07:00
stephb9959
b0cfed809f https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 12:23:10 -07:00
stephb9959
d5502e1527 https://telecominfraproject.atlassian.net/browse/WIFI-11434
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 09:36:16 -07:00
stephb9959
714d02060c Merge remote-tracking branch 'origin/master' 2022-11-01 09:03:02 -07:00
stephb9959
c8d0739692 https://telecominfraproject.atlassian.net/browse/WIFI-11434
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-01 09:02:53 -07:00
stephb9959
d4b9d61e2b https://telecominfraproject.atlassian.net/browse/WIFI-11434
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-01 09:02:37 -07:00
stephb9959
1f7f2f64ad https://telecominfraproject.atlassian.net/browse/WIFI-11433
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-31 14:53:00 -07:00
stephb9959
f26ca31dbc https://telecominfraproject.atlassian.net/browse/WIFI-11433
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-31 14:42:15 -07:00
stephb9959
92b6edc9a4 https://telecominfraproject.atlassian.net/browse/WIFI-11432
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-31 14:34:47 -07:00
stephb9959
e1a2b46333 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-31 10:45:41 -07:00
96 changed files with 42876 additions and 922 deletions

View File

@@ -4,4 +4,4 @@ TabWidth: 4
IndentWidth: 4
UseTab: Always
ColumnLimit: 100
Language: Cpp
Language: Cpp

View File

@@ -27,7 +27,7 @@ jobs:
DOCKER_REGISTRY_USERNAME: ucentral
steps:
- name: Checkout actions repo
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
repository: Telecominfraproject/.github
path: github
@@ -58,10 +58,10 @@ jobs:
- name: Get base branch name and set as output
id: get_base_branch
run: |
echo ::set-output name=branch::$(echo ${GITHUB_BASE_REF##*/} | sed 's/master/main/g')
echo "branch=$(echo ${GITHUB_BASE_REF##*/} | sed 's/master/main/g')" >> $GITHUB_OUTPUT
- name: Checkout actions repo
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
repository: Telecominfraproject/.github
path: github
@@ -85,7 +85,7 @@ jobs:
- docker
steps:
- name: Checkout actions repo
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
repository: Telecominfraproject/.github
path: github

View File

@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout actions repo
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
repository: Telecominfraproject/.github
path: github

40
.github/workflows/openapi-pages.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
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
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

@@ -17,7 +17,7 @@ jobs:
HELM_REPO_USERNAME: ucentral
steps:
- name: Checkout uCentral assembly chart repo
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
path: wlan-cloud-ucentralgw

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.13)
project(owgw VERSION 2.7.1)
project(owgw VERSION 2.8.0)
set(CMAKE_CXX_STANDARD 17)
@@ -39,12 +39,12 @@ endif()
find_package(Git QUIET)
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
execute_process(COMMAND ${GIT_EXECUTABLE} describe --always --tags
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE GIT_RESULT
OUTPUT_VARIABLE GIT_HASH)
if(NOT GIT_RESULT EQUAL "0")
message(FATAL_ERROR "git describe --always --tags failed with ${GIT_RESULT}")
message(FATAL_ERROR "git rev-parse --short HEAD failed with ${GIT_RESULT}")
endif()
string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}")
endif()
@@ -79,7 +79,6 @@ add_executable( owgw
src/framework/KafkaTopics.h
src/framework/MicroService.h
src/framework/OpenWifiTypes.h
src/framework/MicroServiceErrorHandler.h
src/framework/orm.h
src/framework/StorageClass.h
src/framework/MicroServiceErrorHandler.h
@@ -116,6 +115,7 @@ add_executable( owgw
src/framework/RESTAPI_IntServer.h
src/framework/RESTAPI_SystemCommand.h
src/framework/RESTAPI_WebSocketServer.h
src/framework/RESTAPI_SystemConfiguration.h
src/framework/EventBusManager.cpp
src/framework/EventBusManager.h
src/framework/RESTAPI_PartHandler.h
@@ -199,7 +199,7 @@ add_executable( owgw
src/AP_WS_Process_telemetry.cpp
src/AP_WS_Process_venuebroadcast.cpp
src/RADSEC_server.h
src/UI_GW_WebSocketNotifications.cpp src/UI_GW_WebSocketNotifications.h)
src/UI_GW_WebSocketNotifications.cpp src/UI_GW_WebSocketNotifications.h src/framework/RESTAPI_SystemConfiguration.h src/AP_restrictions.h)
if(NOT SMALL_BUILD)
@@ -223,4 +223,4 @@ if(NOT SMALL_BUILD)
if(UNIX AND NOT APPLE)
target_link_libraries(owgw PUBLIC PocoJSON)
endif()
endif()
endif()

View File

@@ -101,7 +101,7 @@ RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentr
COPY --from=owgw-build /owgw/cmake-build/owgw /openwifi/owgw
COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib /usr/local/lib/
COPY --from=poco-build /poco/cmake-build/lib /usr/local/lib
COPY --from=poco-build /poco/cmake-build/lib /usr/local/lib/
RUN ldconfig

View File

@@ -5,6 +5,11 @@ This document will describe how the API is built and how to use it.
This uses OpenAPI definition 3.0 and can be found [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/openapi/ucentral/owgw.yaml).
All endpoints begin with `/api/v1`.
## OpenAPI docs
You may get static page with OpenAPI docs generated from the definition on [GitHub Page](https://telecominfraproject.github.io/wlan-cloud-ucentralgw).
Also you may use [Swagger UI](https://petstore.swagger.io/#/) with OpenAPI definition file raw link (i.e. [latest version file](https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentralgw/master/openapi/owgw.yaml)) to get interactive docs page.
## The flow
In order to use any of the API calls, you must obtain a token (I know - shocking). You do so by calling the end-point
`/oauth2`. Once you obtain that `access-token`, you will need to pass it in the headers under `Authorization: Bearer <place your token here>`.

View File

@@ -298,7 +298,8 @@ Controller sends this command when it believes the device should upgrade its fir
"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>
"uri" : <URI to download the firmware>,
"FWsignature" : <string representation of the signature for the FW> (optional)
},
"id" : <some number>
}
@@ -318,6 +319,13 @@ The device should answer:
"id" : <same number>
}
```
Here are the error values
```text
0: No error
1: Bad firmware
2: Missing signature
```
#### Controller wants the device to perform a factory reset
Controller sends this command when it believes the device should upgrade its firmware.
@@ -673,9 +681,11 @@ Controller sends this command to run a predefined script. Extreme care must be t
"method" : "script" ,
"params" : {
"serial" : <serial number>,
"type" : <one of "shell", "ucode">,
"script" : <text blob containing the script>,
"timeout" : <max timeout in seconds, default is 30>,
"type" : <one of "shell", "ucode", "bundle">,
"script" : <text blob containing the script, This must be vase64 encoded>,
"timeout" : <max timeout in seconds, default is 30, unused if URI is supplied>,
"uri": "<upload script results using this URI>",
"signature" : "<signature for script>: must be supplied to restricted devices",
"when" : <time when this will be performed as UTC seconds>
},
"id" : <some number>

View File

View File

View File

View File

@@ -0,0 +1,36 @@
scripts:
- name: List Antennas
description: A script to list all antennas on a device
type: shell
runtype:
timeout: 30
filename: listantennas.sh
readme: listantennas.md
help: https://authors.com/scripts/index.html
- name: List AP Noise
description: A script to list all noise values on all APs
type: shell
runtype:
deferred: true
filename: listnoise.sh
readme: listnoise.md
help: https://authors.com/scripts/index.html
- name: Reset AP Statistics
description: A script to reset the statistics on a given AP
type: shell
runtype:
timeout: 30
filename: resetstats.sh
readme: resetstats.md
help: https://authors.com/scripts/index.html
- name: Gather kernel stats
description: A script to all the kernel stats for an AP
type: bundle
runtype:
deferred: true
filename: kstats.uci
readme: kstats.md
help: https://authors.com/scripts/index.html

View File

View File

View File

View File

@@ -0,0 +1 @@
#!/bin/sh

View File

View File

@@ -0,0 +1,2 @@
#!/bin/sh

View File

View File

@@ -0,0 +1,2 @@
#!/bin/sh

1
ap_scripts/README.md Normal file
View File

@@ -0,0 +1 @@
# Repo for scripts

2
build
View File

@@ -1 +1 @@
42
44

40844
docs/index.html Normal file

File diff suppressed because one or more lines are too long

View File

@@ -9,7 +9,7 @@ fullnameOverride: ""
images:
owgw:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owgw
tag: v2.7.2
tag: master
pullPolicy: Always
# regcred:
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io

View File

@@ -107,6 +107,12 @@ components:
type: string
minLength: 2
maxLength: 2
FCC:
type: boolean
default: false
certificateExpiryDate:
type: integer
format: int64
DeviceWithStatus:
type: object
@@ -202,6 +208,12 @@ components:
totalConnectionTime:
type: integer
format: int64
restrictedDevice:
type: boolean
default: false
certificateDate:
type: integer
format: int64
DeviceList:
type: object
@@ -500,18 +512,20 @@ components:
type:
type: string
enum:
- uci
- ucode
- shell
- bundle
script:
type: string
scriptId:
type: string
format: uuid
when:
type: integer
format: int64
default: 0
signature:
type: string
deferred:
type: boolean
uri:
type: string
FactoryRequest:
type: object
@@ -921,9 +935,26 @@ components:
items:
$ref: '#/components/schemas/TagValuePair'
ExtraSystemConfiguration:
type: array
items:
type: object
properties:
parameterName:
type: string
parameterType:
type: string
enum:
- string
- integer
- boolean
- path
parameterValue:
{}
#########################################################################################
##
## End of uCentral system wide values
## End of uCentral system-wide values
##
#########################################################################################
BlackDeviceInfo:
@@ -1890,6 +1921,12 @@ paths:
schema:
type: boolean
required: false
- in: query
description: Return the number of matching records.
name: countOnly
schema:
type: boolean
required: false
responses:
200:
@@ -1899,6 +1936,8 @@ paths:
schema:
oneOf:
- $ref: '#/components/schemas/StatisticsRecords'
- $ref: '#/components/schemas/DeviceCount'
403:
$ref: '#/components/responses/Unauthorized'
404:
@@ -2076,6 +2115,11 @@ paths:
schema:
type: string
required: true
- in: query
name: FWsignature
schema:
type: string
required: false
requestBody:
description: Command details
content:
@@ -2731,4 +2775,51 @@ paths:
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
$ref: '#/components/responses/NotFound'
/systemConfiguration:
get:
tags:
- SystemConfiguration
summary: Retrieve system configuration items
operationId: getSystemConfiguration
responses:
200:
$ref: '#/components/schemas/ExtraSystemConfiguration'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
put:
tags:
- SystemConfiguration
summary: Set some or all system configuration
operationId: setSystemConfiguration
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ExtraSystemConfiguration'
responses:
200:
$ref: '#/components/schemas/ExtraSystemConfiguration'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
delete:
tags:
- SystemConfiguration
summary: Delete all additional system configuration
operationId: deleteSystemConfiguration
responses:
200:
$ref: '#/components/responses/Success'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'

View File

@@ -71,27 +71,6 @@ namespace OpenWifi {
Valid_ = true;
}
class ThreadedCounter {
public:
ThreadedCounter(bool T, std::atomic_uint64_t &C) :
C_(C),
Threaded_(T) {
if(Threaded_) {
C_++;
}
}
~ThreadedCounter() {
if(Threaded_ && C_>0) {
C_--;
}
}
private:
std::atomic_uint64_t &C_;
bool Threaded_;
};
bool AP_WS_Connection::ValidatedDevice() {
if(DeviceValidated_)
return true;
@@ -99,6 +78,7 @@ namespace OpenWifi {
if(!Valid_)
return false;
std::lock_guard Lock(ConnectionMutex_);
try {
auto SockImpl = dynamic_cast<Poco::Net::WebSocketImpl *>(WS_->impl());
auto SS = dynamic_cast<Poco::Net::SecureStreamSocketImpl*>(SockImpl->streamSocketImpl());
@@ -155,6 +135,7 @@ namespace OpenWifi {
return false;
}
State_.certificateExpiryDate = PeerCert.expiresOn().timestamp().epochTime();
SerialNumber_ = CN_;
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
@@ -245,9 +226,9 @@ namespace OpenWifi {
auto SessionDeleted = AP_WS_Server()->EndSession(State_.sessionId, SerialNumberInt_);
if (SessionDeleted) {
WebNotificationSingleDevice_t N;
GWWebSocketNotifications::SingleDevice_t N;
N.content.serialNumber = SerialNumber_;
WebSocketClientNotificationDeviceDisconnected(N);
GWWebSocketNotifications::DeviceDisconnected(N);
}
}
}
@@ -309,13 +290,13 @@ namespace OpenWifi {
bool Sent;
StorageService()->AddCommand(SerialNumber_, Cmd, Storage::CommandExecutionType::COMMAND_EXECUTED);
CommandManager()->PostCommand(CommandManager()->NextRPCId(),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
CommandManager()->PostCommand(CommandManager()->Next_RPC_ID(),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
WebNotificationSingleDeviceConfigurationChange_t Notification;
GWWebSocketNotifications::SingleDeviceConfigurationChange_t Notification;
Notification.content.serialNumber = D.SerialNumber;
Notification.content.oldUUID = UUID;
Notification.content.newUUID = UpgradedUUID;
WebSocketClientNotificationDeviceConfigurationChange(Notification);
GWWebSocketNotifications::DeviceConfigurationChange(Notification);
return true;
}
@@ -324,7 +305,7 @@ namespace OpenWifi {
void AP_WS_Connection::ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc) {
poco_debug(Logger_,fmt::format("RECEIVED-RPC({}): {}.", CId_, Doc->get(uCentralProtocol::ID).toString()));
CommandManager()->PostCommandResult(SerialNumber_, *Doc);
CommandManager()->PostCommandResult(SerialNumber_, Doc);
}
void AP_WS_Connection::ProcessJSONRPCEvent(Poco::JSON::Object::Ptr &Doc) {
@@ -607,7 +588,6 @@ namespace OpenWifi {
WS_->sendFrame("", 0,
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
State_.MessageCount++;
if (KafkaManager()->Enabled()) {
Poco::JSON::Object PingObject;

View File

@@ -15,7 +15,7 @@
#include "Poco/Net/WebSocket.h"
#include "RESTObjects/RESTAPI_GWobjects.h"
#include "AP_restrictions.h"
namespace OpenWifi {
@@ -44,7 +44,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(const uint64_t UUID, uint64_t & UpgradedUUID);
bool LookForUpgrade(uint64_t UUID, uint64_t & UpgradedUUID);
static bool ExtractBase64CompressedData(const std::string & CompressedData, std::string & UnCompressedData, uint64_t compress_sz);
void LogException(const Poco::Exception &E);
inline Poco::Logger & Logger() { return Logger_; }
@@ -53,6 +53,36 @@ namespace OpenWifi {
bool StopWebSocketTelemetry(uint64_t RPCID);
bool StopKafkaTelemetry(uint64_t RPCID);
inline void GetLastStats(std::string &LastStats) const {
std::shared_lock G(ConnectionMutex_);
LastStats = RawLastStats_;
}
inline void SetLastStats(const std::string &LastStats) {
std::unique_lock G(ConnectionMutex_);
RawLastStats_ = LastStats;
}
inline void SetLastHealthCheck(const GWObjects::HealthCheck &H) {
std::unique_lock G(ConnectionMutex_);
RawLastHealthcheck_ = H;
}
inline void GetLastHealthCheck(GWObjects::HealthCheck &H) {
std::shared_lock G(ConnectionMutex_);
H = RawLastHealthcheck_;
}
inline void GetState(GWObjects::ConnectionState &State) const {
std::shared_lock G(ConnectionMutex_);
State = State_;
}
inline void GetRestrictions(AP_Restrictions & R) const {
std::shared_lock G(ConnectionMutex_);
R = 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);
@@ -83,11 +113,15 @@ namespace OpenWifi {
return true;
}
friend class DeviceRegistry;
friend class AP_WS_Server;
inline AP_Restrictions Restrictions() const {
std::shared_lock G(ConnectionMutex_);
return Restrictions_;
}
private:
// std::recursive_mutex LocalMutex_;
mutable std::shared_mutex ConnectionMutex_;
std::shared_mutex TelemetryMutex_;
Poco::Logger &Logger_;
Poco::Net::SocketReactor &Reactor_;
@@ -101,22 +135,22 @@ 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;
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;
GWObjects::ConnectionState State_;
std::string LastStats_;
GWObjects::HealthCheck LastHealthcheck_;
std::string 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};
bool Threaded_=false;
std::atomic_flag Dead_=false;
std::atomic_bool DeviceValidated_=false;
std::atomic_bool Valid_=false;
AP_Restrictions Restrictions_;
static inline std::atomic_uint64_t ConcurrentStartingDevices_=0;

View File

@@ -24,10 +24,7 @@ namespace OpenWifi {
ParamsObj->has(uCentralProtocol::CAPABILITIES)) {
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
auto Firmware = ParamsObj->get(uCentralProtocol::FIRMWARE).toString();
auto CapabilitiesString = ParamsObj->get(uCentralProtocol::CAPABILITIES).toString();
Config::Capabilities Caps(CapabilitiesString);
Compatible_ = Caps.Compatible();
auto Capabilities = ParamsObj->getObject(uCentralProtocol::CAPABILITIES);
SerialNumber_ = Serial;
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
@@ -35,6 +32,12 @@ namespace OpenWifi {
CommandManager()->ClearQueue(SerialNumberInt_);
AP_WS_Server()->SetSessionDetails(State_.sessionId,SerialNumberInt_);
std::lock_guard Lock(ConnectionMutex_);
Config::Capabilities Caps(Capabilities);
Compatible_ = Caps.Compatible();
State_.UUID = UUID;
State_.Firmware = Firmware;
State_.PendingUUID = 0;
@@ -46,40 +49,52 @@ namespace OpenWifi {
IP = IP.substr(7);
}
bool RestrictedDevice = false;
if(ParamsObj->has("restricted") && ParamsObj->get("restricted").isBoolean()) {
RestrictedDevice = true;
if(Capabilities->has("restrictions")) {
auto RestrictionObject = Capabilities->getObject("restrictions");
Restrictions_.initialize(Logger_, SerialNumber_, RestrictionObject);
}
}
State_.locale = FindCountryFromIP()->Get(IP);
GWObjects::Device DeviceInfo;
auto DeviceExists = StorageService()->GetDevice(SerialNumber_,DeviceInfo);
if (Daemon()->AutoProvisioning() && !DeviceExists) {
StorageService()->CreateDefaultDevice(SerialNumber_, CapabilitiesString, Firmware,
Compatible_, PeerAddress_);
StorageService()->CreateDefaultDevice(SerialNumber_, Caps, Firmware, PeerAddress_);
} else if (DeviceExists) {
StorageService()->UpdateDeviceCapabilities(SerialNumber_, CapabilitiesString,
Compatible_);
bool Updated = false;
StorageService()->UpdateDeviceCapabilities(SerialNumber_, Caps );
int Updated{0};
if(!Firmware.empty()) {
if(Firmware!=DeviceInfo.Firmware) {
DeviceInfo.Firmware = Firmware;
DeviceInfo.LastFWUpdate = Utils::Now();
Updated = true;
++Updated;
WebNotificationSingleDeviceFirmwareChange_t Notification;
GWWebSocketNotifications::SingleDeviceFirmwareChange_t Notification;
Notification.content.serialNumber = SerialNumber_;
Notification.content.newFirmware = Firmware;
WebSocketClientNotificationDeviceFirmwareUpdated(Notification);
GWWebSocketNotifications::DeviceFirmwareUpdated(Notification);
} else if(DeviceInfo.LastFWUpdate==0) {
DeviceInfo.LastFWUpdate = Utils::Now();
Updated = true;
++Updated;
}
}
if(DeviceInfo.locale != State_.locale) {
DeviceInfo.locale = State_.locale;
Updated = true;
++Updated;
}
if(Compatible_ != DeviceInfo.DeviceType) {
DeviceInfo.DeviceType = Compatible_;
Updated = true;
++Updated;
}
if(RestrictedDevice != DeviceInfo.restrictedDevice) {
DeviceInfo.restrictedDevice = RestrictedDevice;
++Updated;
}
if(Updated) {
@@ -120,9 +135,9 @@ namespace OpenWifi {
}
}
WebNotificationSingleDevice_t Notification;
GWWebSocketNotifications::SingleDevice_t Notification;
Notification.content.serialNumber = SerialNumber_;
WebSocketClientNotificationDeviceConnected(Notification);
GWWebSocketNotifications::DeviceConnected(Notification);
// std::cout << "Serial: " << SerialNumber_ << "Session: " << State_.sessionId << std::endl;

View File

@@ -11,65 +11,64 @@
namespace OpenWifi {
void AP_WS_Connection::Process_healthcheck(Poco::JSON::Object::Ptr ParamsObj) {
if (!State_.Connected) {
poco_warning(Logger_, fmt::format(
"INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
Errors_++;
return;
}
if (ParamsObj->has(uCentralProtocol::UUID) && ParamsObj->has(uCentralProtocol::SANITY) &&
ParamsObj->has(uCentralProtocol::DATA)) {
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
auto Sanity = ParamsObj->get(uCentralProtocol::SANITY);
auto CheckData = ParamsObj->get(uCentralProtocol::DATA).toString();
if (CheckData.empty())
CheckData = uCentralProtocol::EMPTY_JSON_DOC;
void AP_WS_Connection::Process_healthcheck(Poco::JSON::Object::Ptr ParamsObj) {
if (!State_.Connected) {
poco_warning(Logger_, fmt::format(
"INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
Errors_++;
return;
}
if (ParamsObj->has(uCentralProtocol::UUID) && ParamsObj->has(uCentralProtocol::SANITY) &&
ParamsObj->has(uCentralProtocol::DATA)) {
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
auto Sanity = ParamsObj->get(uCentralProtocol::SANITY);
auto CheckData = ParamsObj->get(uCentralProtocol::DATA).toString();
if (CheckData.empty())
CheckData = uCentralProtocol::EMPTY_JSON_DOC;
std::string request_uuid;
if (ParamsObj->has(uCentralProtocol::REQUEST_UUID))
request_uuid = ParamsObj->get(uCentralProtocol::REQUEST_UUID).toString();
std::string request_uuid;
if (ParamsObj->has(uCentralProtocol::REQUEST_UUID))
request_uuid = ParamsObj->get(uCentralProtocol::REQUEST_UUID).toString();
if (request_uuid.empty()) {
poco_trace(Logger_,
fmt::format("HEALTHCHECK({}): UUID={} Updating.", CId_, UUID));
if (request_uuid.empty()) {
poco_trace(Logger_,
fmt::format("HEALTHCHECK({}): UUID={} Updating.", CId_, UUID));
} else {
poco_trace(Logger_,
fmt::format("HEALTHCHECK({}): UUID={} Updating for CMD={}.", CId_,
UUID, request_uuid));
}
uint64_t UpgradedUUID;
LookForUpgrade(UUID,UpgradedUUID);
State_.UUID = UpgradedUUID;
GWObjects::HealthCheck Check;
Check.SerialNumber = SerialNumber_;
Check.Recorded = Utils::Now();
Check.UUID = UUID;
Check.Data = CheckData;
Check.Sanity = Sanity;
StorageService()->AddHealthCheckData(Check);
if (!request_uuid.empty()) {
StorageService()->SetCommandResult(request_uuid, CheckData);
}
SetLastHealthCheck(Check);
if (KafkaManager()->Enabled()) {
Poco::JSON::Stringifier Stringify;
std::ostringstream OS;
ParamsObj->set("timestamp", Utils::Now());
Stringify.condense(ParamsObj, OS);
KafkaManager()->PostMessage(KafkaTopics::HEALTHCHECK, SerialNumber_, OS.str());
}
} else {
poco_trace(Logger_,
fmt::format("HEALTHCHECK({}): UUID={} Updating for CMD={}.", CId_,
UUID, request_uuid));
poco_warning(Logger_, fmt::format("HEALTHCHECK({}): Missing parameter", CId_));
return;
}
uint64_t UpgradedUUID;
LookForUpgrade(UUID,UpgradedUUID);
State_.UUID = UpgradedUUID;
GWObjects::HealthCheck Check;
Check.SerialNumber = SerialNumber_;
Check.Recorded = Utils::Now();
Check.UUID = UUID;
Check.Data = CheckData;
Check.Sanity = Sanity;
StorageService()->AddHealthCheckData(Check);
if (!request_uuid.empty()) {
StorageService()->SetCommandResult(request_uuid, CheckData);
}
LastHealthcheck_ = Check;
if (KafkaManager()->Enabled()) {
Poco::JSON::Stringifier Stringify;
std::ostringstream OS;
ParamsObj->set("timestamp", Utils::Now());
Stringify.condense(ParamsObj, OS);
KafkaManager()->PostMessage(KafkaTopics::HEALTHCHECK, SerialNumber_, OS.str());
}
} else {
poco_warning(Logger_, fmt::format("HEALTHCHECK({}): Missing parameter", CId_));
return;
}
}
}

View File

@@ -51,7 +51,7 @@ namespace OpenWifi {
Poco::JSON::Stringifier::stringify(Params, O);
Cmd.Details = O.str();
bool Sent;
CommandManager()->PostCommand(CommandManager()->NextRPCId(),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
CommandManager()->PostCommand(CommandManager()->Next_RPC_ID(),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
StorageService()->AddCommand(SerialNumber_, Cmd, Storage::CommandExecutionType::COMMAND_EXECUTED);
poco_information(Logger_, fmt::format("RECOVERY({}): Recovery mode received, need for a reboot.", CId_));
} else {

View File

@@ -41,7 +41,7 @@ namespace OpenWifi {
uint64_t UpgradedUUID;
LookForUpgrade(UUID,UpgradedUUID);
State_.UUID = UpgradedUUID;
LastStats_ = StateStr;
SetLastStats(StateStr);
GWObjects::Statistics Stats{
.SerialNumber = SerialNumber_, .UUID = UUID, .Data = StateStr};
@@ -52,7 +52,9 @@ namespace OpenWifi {
}
StateUtils::ComputeAssociations(StateObj, State_.Associations_2G,
State_.Associations_5G);
State_.Associations_5G,
State_.Associations_6G
);
if (KafkaManager()->Enabled()) {
Poco::JSON::Stringifier Stringify;
@@ -61,9 +63,9 @@ namespace OpenWifi {
KafkaManager()->PostMessage(KafkaTopics::STATE, SerialNumber_, OS.str());
}
WebNotificationSingleDevice_t N;
GWWebSocketNotifications::SingleDevice_t N;
N.content.serialNumber = SerialNumber_;
WebSocketClientNotificationDeviceStatistics(N);
GWWebSocketNotifications::DeviceStatistics(N);
} else {
poco_warning(Logger_, fmt::format("STATE({}): Invalid request. Missing serial, uuid, or state", CId_));

View File

@@ -33,7 +33,7 @@ namespace OpenWifi {
State_.websocketPackets = TelemetryWebSocketPackets_;
TelemetryStream()->NotifyEndPoint(SerialNumberInt_, SS.str());
} else {
StopWebSocketTelemetry(CommandManager()->NextRPCId());
StopWebSocketTelemetry(CommandManager()->Next_RPC_ID());
}
}
if (TelemetryKafkaRefCount_) {
@@ -44,7 +44,7 @@ namespace OpenWifi {
KafkaManager()->PostMessage(KafkaTopics::DEVICE_TELEMETRY, SerialNumber_,
SS.str());
} else {
StopKafkaTelemetry(CommandManager()->NextRPCId());
StopKafkaTelemetry(CommandManager()->Next_RPC_ID());
}
}
} else {
@@ -53,7 +53,7 @@ namespace OpenWifi {
} else {
// if we are ignoring telemetry, then close it down on the device.
poco_debug(Logger_,fmt::format("TELEMETRY({}): Stopping runaway telemetry.",SerialNumber_));
StopTelemetry(CommandManager()->NextRPCId());
StopTelemetry(CommandManager()->Next_RPC_ID());
}
}
}

View File

@@ -159,9 +159,8 @@ namespace OpenWifi {
}
void AP_WS_Server::onGarbageCollecting([[maybe_unused]] Poco::Timer &timer) {
std::lock_guard Lock(LocalMutex_);
if(Garbage_.size()>0) {
std::cout << "Removing " << Garbage_.size() << " old connections." << std::endl;
std::lock_guard Lock(WSServerMutex_);
if(!Garbage_.empty()) {
Garbage_.clear();
}
@@ -173,20 +172,15 @@ namespace OpenWifi {
uint64_t total_connected_time=0;
auto now = Utils::Now();
for (auto connection=SerialNumbers_.begin(); connection!=SerialNumbers_.end();) {
if(connection->second.second== nullptr) {
connection++;
for (const auto & connection:SerialNumbers_) {
if(connection.second.second == nullptr) {
continue;
}
if (connection->second.second->State_.Connected) {
if (connection.second.second->State_.Connected) {
NumberOfConnectedDevices_++;
total_connected_time += (now - connection->second.second->State_.started);
connection++;
total_connected_time += (now - connection.second.second->State_.started);
} else {
NumberOfConnectingDevices_++;
connection++;
}
}
@@ -198,11 +192,11 @@ namespace OpenWifi {
NumberOfConnectedDevices_, NumberOfConnectingDevices_, AverageDeviceConnectionTime_));
}
WebSocketClientNotificationNumberOfConnection_t Notification;
GWWebSocketNotifications::NumberOfConnection_t Notification;
Notification.content.numberOfConnectingDevices = NumberOfConnectingDevices_;
Notification.content.numberOfDevices = NumberOfConnectedDevices_;
Notification.content.averageConnectedTime = AverageDeviceConnectionTime_;
WebSocketClientNotificationNumberOfConnections(Notification);
GWWebSocketNotifications::NumberOfConnections(Notification);
}
void AP_WS_Server::Stop() {
@@ -221,36 +215,49 @@ namespace OpenWifi {
}
bool AP_WS_Server::GetStatistics(uint64_t SerialNumber, std::string &Statistics) const {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
return false;
Statistics = Device->second.second->LastStats_;
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
DevicePtr->GetLastStats(Statistics);
return true;
}
bool AP_WS_Server::GetState(uint64_t SerialNumber, GWObjects::ConnectionState & State) const {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
return false;
State = Device->second.second->State_;
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
DevicePtr->GetState(State);
return true;
}
bool AP_WS_Server::GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
return false;
CheckData = Device->second.second->LastHealthcheck_;
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
DevicePtr->GetLastHealthCheck(CheckData);
return true;
}
void AP_WS_Server::SetSessionDetails(uint64_t connection_id, uint64_t SerialNumber) {
std::lock_guard Lock(LocalMutex_);
std::lock_guard Lock(WSServerMutex_);
auto Conn = Sessions_.find(connection_id);
if(Conn == end(Sessions_))
@@ -259,19 +266,19 @@ namespace OpenWifi {
auto CurrentSerialNumber = SerialNumbers_.find(SerialNumber);
if( (CurrentSerialNumber==SerialNumbers_.end()) ||
(CurrentSerialNumber->second.first<connection_id)) {
SerialNumbers_[SerialNumber] = std::make_pair(connection_id, Conn->second.first);
SerialNumbers_[SerialNumber] = std::make_pair(connection_id, Conn->second);
return;
}
}
bool AP_WS_Server::EndSession(uint64_t session_id, uint64_t serial_number) {
std::unique_lock G(LocalMutex_);
std::lock_guard G(WSServerMutex_);
auto Session = Sessions_.find(session_id);
if(Session==end(Sessions_))
return false;
Garbage_.push_back(Session->second.first);
Garbage_.push_back(Session->second);
auto Device = SerialNumbers_.find(serial_number);
if (Device == end(SerialNumbers_)) {
@@ -289,24 +296,45 @@ namespace OpenWifi {
return false;
}
bool AP_WS_Server::Connected(uint64_t SerialNumber) const {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
return false;
bool AP_WS_Server::Connected(uint64_t SerialNumber, AP_Restrictions & Restrictions) const {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
DevicePtr->GetRestrictions(Restrictions);
return DevicePtr->State_.Connected;
}
return Device->second.second->State_.Connected;
bool AP_WS_Server::Connected(uint64_t SerialNumber) const {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
return DevicePtr->State_.Connected;
}
bool AP_WS_Server::SendFrame(uint64_t SerialNumber, const std::string & Payload) const {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
return false;
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
try {
// std::cout << "Device connection pointer: " << (uint64_t) Device->second.second << std::endl;
return Device->second.second->Send(Payload);
return DevicePtr->Send(Payload);
} catch (...) {
poco_debug(Logger(),fmt::format(": SendFrame: Could not send data to device '{}'", Utils::IntToSerialNumber(SerialNumber)));
}
@@ -314,39 +342,56 @@ namespace OpenWifi {
}
void AP_WS_Server::StopWebSocketTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
std::lock_guard Lock(LocalMutex_);
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_) || Device->second.second==nullptr)
return;
Device->second.second->StopWebSocketTelemetry(RPCID);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
return;
}
DevicePtr = Device->second.second;
}
DevicePtr->StopWebSocketTelemetry(RPCID);
}
void AP_WS_Server::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_) || Device->second.second==nullptr)
return;
Device->second.second->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime);
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
return;
}
DevicePtr = Device->second.second;
}
DevicePtr->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime);
}
void AP_WS_Server::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
return;
Device->second.second->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime);
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
return;
}
DevicePtr = Device->second.second;
}
DevicePtr->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime);
}
void AP_WS_Server::StopKafkaTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
return;
Device->second.second->StopKafkaTelemetry(RPCID);
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
return;
}
DevicePtr = Device->second.second;
}
DevicePtr->StopKafkaTelemetry(RPCID);
}
void AP_WS_Server::GetTelemetryParameters(uint64_t SerialNumber , bool & TelemetryRunning,
@@ -357,29 +402,34 @@ namespace OpenWifi {
uint64_t & TelemetryKafkaCount,
uint64_t & TelemetryWebSocketPackets,
uint64_t & TelemetryKafkaPackets) {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_)|| Device->second.second== nullptr)
return;
Device->second.second->GetTelemetryParameters(TelemetryRunning,
TelemetryInterval,
TelemetryWebSocketTimer,
TelemetryKafkaTimer,
TelemetryWebSocketCount,
TelemetryKafkaCount,
TelemetryWebSocketPackets,
TelemetryKafkaPackets);
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
return;
}
DevicePtr = Device->second.second;
}
DevicePtr->GetTelemetryParameters(
TelemetryRunning, TelemetryInterval, TelemetryWebSocketTimer, TelemetryKafkaTimer,
TelemetryWebSocketCount, TelemetryKafkaCount, TelemetryWebSocketPackets,
TelemetryKafkaPackets);
}
bool AP_WS_Server::SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
return false;
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
try {
return Device->second.second->SendRadiusAccountingData(buffer,size);
return DevicePtr->SendRadiusAccountingData(buffer,size);
} catch (...) {
poco_debug(Logger(),fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'", SerialNumber));
}
@@ -387,13 +437,18 @@ namespace OpenWifi {
}
bool AP_WS_Server::SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
return false;
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
try {
return Device->second.second->SendRadiusAuthenticationData(buffer,size);
return DevicePtr->SendRadiusAuthenticationData(buffer,size);
} catch (...) {
poco_debug(Logger(),fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'", SerialNumber));
}
@@ -401,13 +456,18 @@ namespace OpenWifi {
}
bool AP_WS_Server::SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
return false;
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
try {
return Device->second.second->SendRadiusCoAData(buffer,size);
return DevicePtr->SendRadiusCoAData(buffer,size);
} catch (...) {
poco_debug(Logger(),fmt::format(": SendRadiusCoAData: Could not send data to device '{}'", SerialNumber));
}

View File

@@ -106,16 +106,16 @@ namespace OpenWifi {
[[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(LocalMutex_);
Sessions_[session_id] = std::make_pair(std::move(Connection),false);
std::lock_guard Lock(WSServerMutex_);
Sessions_[session_id] = std::move(Connection);
}
inline std::shared_ptr<AP_WS_Connection> FindConnection(uint64_t session_id) const {
std::lock_guard Lock(LocalMutex_);
std::lock_guard Lock(WSServerMutex_);
auto Connection = Sessions_.find(session_id);
if(Connection!=end(Sessions_))
return Connection->second.first;
return Connection->second;
return nullptr;
}
@@ -134,6 +134,7 @@ namespace OpenWifi {
}
bool GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const ;
bool Connected(uint64_t SerialNumber, AP_Restrictions & Restrictions) const ;
bool Connected(uint64_t SerialNumber) const ;
inline bool SendFrame(const std::string & SerialNumber, const std::string & Payload) const {
@@ -171,7 +172,7 @@ namespace OpenWifi {
}
private:
mutable std::recursive_mutex LocalMutex_;
mutable std::recursive_mutex WSServerMutex_;
std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_;
std::list<std::unique_ptr<Poco::Net::HTTPServer>> WebServers_;
Poco::Net::SocketReactor Reactor_;
@@ -183,7 +184,8 @@ namespace OpenWifi {
bool SimulatorEnabled_=false;
std::unique_ptr<AP_WS_ReactorThreadPool> Reactor_pool_;
std::atomic_bool Running_=false;
std::map<uint64_t, std::pair<std::shared_ptr<AP_WS_Connection>,bool>> Sessions_;
// std::map<uint64_t, std::pair<std::shared_ptr<AP_WS_Connection>,bool>> Sessions_;
std::map<std::uint64_t, std::shared_ptr<AP_WS_Connection>> Sessions_;
std::map<uint64_t, std::pair<uint64_t,std::shared_ptr<AP_WS_Connection>>> SerialNumbers_;
std::atomic_bool AllowSerialNumberMismatch_=true;
std::atomic_uint64_t MismatchDepth_=2;

77
src/AP_restrictions.h Normal file
View File

@@ -0,0 +1,77 @@
//
// Created by stephane bourque on 2022-11-14.
//
#pragma once
#include <string>
#include <set>
#include "Poco/JSON/Object.h"
#include "Poco/Logger.h"
#include "fmt/format.h"
/*
{
“country”: [
“US”, “CA”
],
“dfs”: true,
“ssh”: true,
“rtty”: true,
“tty”: true,
“developer”: true,
“sysupgrade”: true,
“commands”: true
}
*/
namespace OpenWifi {
class AP_Restrictions {
public:
inline bool initialize(Poco::Logger & Logger, const std::string & serialNumber, const Poco::JSON::Object::Ptr &O) {
try {
dfs_ = O->optValue("dfs",false);
ssh_ = O->optValue("ssh",false);
rtty_ = O->optValue("rtty",false);
tty_ = O->optValue("tty",false);
developer_ = O->optValue("developer",false);
sysupgrade_ = O->optValue("sysupgrade",false);
commands_ = O->optValue("commands",false);
if(O->has("country") && O->isArray("country")) {
auto Countries = O->getArray("country");
for(const auto &country:*Countries) {
countries_.insert(Poco::toLower(country.toString()));
}
}
return true;
} catch (...) {
poco_error(Logger,fmt::format("Cannot parse restrictions for device {}", serialNumber));
}
return false;
}
[[nodiscard]] inline auto dfs_not_allowed() const { return dfs_; }
[[nodiscard]] inline auto ssh_not_allowed() const { return ssh_; }
[[nodiscard]] inline auto rtty_not_allowed() const { return rtty_; }
[[nodiscard]] inline auto tty_not_allowed() const { return tty_; }
[[nodiscard]] inline auto developer_not_allowed() const { return developer_; }
[[nodiscard]] inline auto sysupgrade_not_allowed() const { return sysupgrade_; }
[[nodiscard]] inline auto commands_not_allowed() const { return commands_; }
[[nodiscard]] inline bool valid_country(const std::string &c) const {
if(countries_.empty())
return true;
return countries_.find(Poco::toLower(c))!=countries_.end();
}
private:
std::set<std::string> countries_;
bool dfs_ = false;
bool ssh_ = false;
bool rtty_ = false;
bool tty_ = false;
bool developer_ = false;
bool sysupgrade_ = false;
bool commands_ = false;
};
}

View File

@@ -12,6 +12,7 @@
#include "framework/MicroServiceFuncs.h"
#include "nlohmann/json.hpp"
#include "CentralConfig.h"
namespace OpenWifi {
const std::string PlatformCacheFileName{"/plat_cache.json"};
@@ -27,17 +28,17 @@ namespace OpenWifi {
return instance;
}
inline void Add(const std::string & DeviceType, const std::string & Platform, const std::string & FullCapabilities) {
if(DeviceType.empty() || Platform.empty())
inline void Add(const Config::Capabilities &Caps) {
if(Caps.Compatible().empty() || Caps.Platform().empty())
return;
std::lock_guard G(Mutex_);
if(!PlatformsLoaded_)
LoadPlatforms();
auto P = Poco::toUpper(Platform);
auto Hint = Platforms_.find(DeviceType);
auto P = Poco::toUpper(Caps.Platform());
auto Hint = Platforms_.find(Caps.Compatible());
if(Hint==Platforms_.end()) {
Platforms_.insert(std::make_pair(DeviceType,P));
Platforms_.insert(std::make_pair(Caps.Compatible(),P));
SavePlatforms();
} else if(Hint->second != P) {
Hint->second = P;
@@ -47,12 +48,14 @@ namespace OpenWifi {
if(!CapabilitiesLoaded_)
LoadCapabilities();
auto CapHint = Capabilities_.find(DeviceType);
auto CapHint = Capabilities_.find(Caps.Compatible());
if(CapHint==Capabilities_.end()) {
Capabilities_[DeviceType] = nlohmann::json::parse(FullCapabilities);
auto C = nlohmann::json::parse(Caps.AsString());
C.erase("restrictions");
Capabilities_[Caps.Compatible()] = nlohmann::json::parse(Caps.AsString());
SaveCapabilities();
} else {
CapHint->second = nlohmann::json::parse(FullCapabilities);
CapHint->second = nlohmann::json::parse(Caps.AsString());
SaveCapabilities();
}
}
@@ -150,4 +153,7 @@ namespace OpenWifi {
}
}
};
inline auto CapabilitiesCache() { return CapabilitiesCache::instance(); };
}

View File

@@ -228,7 +228,7 @@ R"lit(
return DefaultConfiguration_;
}
std::string Capabilities::Default() {
/* std::string Capabilities::Default() {
return std::string(R"lit({"model":{"id":"linksys,ea8300","name":"Linksys EA8300 (Dallas)"},
"network":{"lan":{"ifname":"eth0","protocol":"static"},"wan":{"ifname":"eth1","protocol":"dhcp"}},
"switch":{"switch0":{"enable":true,"reset":true,"ports":[{"num":0,"device":"eth0","need_tag":false,
@@ -242,27 +242,23 @@ R"lit(
"platform/soc/a800000.wifi":{"band":["5l"],"ht_capa":6639,"vht_capa":865687986,"htmode":["HT20","HT40","VHT20","VHT40","VHT80"],
"tx_ant":3,"rx_ant":3,"channels":[36,40,44,48,52,56,60,64]}}})lit");
}
*/
void Capabilities::Parse() {
if(Capabilities_.empty())
Capabilities_=Default();
Capabilities::Capabilities(const Poco::JSON::Object::Ptr &Caps) {
try {
Poco::JSON::Parser parser;
auto Result = parser.parse(Capabilities_);
auto Objects = Result.extract<Poco::JSON::Object::Ptr>();
if(Caps->has("compatible"))
Compatible_ = Caps->get("compatible").toString();
if(Objects->has("compatible"))
Compatible_ = Objects->get("compatible").toString();
if(Caps->has("model"))
Model_ = Caps->get("model").toString();
if(Objects->has("model"))
Model_ = Objects->get("model").toString();
if(Caps->has("platform"))
Platform_ = Caps->get("platform").toString();
if(Objects->has("platform"))
Platform_ = Objects->get("platform").toString();
Parsed_ = true ;
std::ostringstream OS;
Caps->stringify(OS);
AsString_ = OS.str();
}
catch ( const Poco::Exception & E )
{
@@ -270,22 +266,20 @@ R"lit(
}
}
const std::string & Capabilities::Compatible() {
if(!Parsed_)
Parse();
const std::string & Capabilities::Compatible() const {
return Compatible_;
}
const std::string & Capabilities::Model() {
if(!Parsed_)
Parse();
const std::string & Capabilities::Model() const {
return Model_;
}
const std::string & Capabilities::Platform() {
if(!Parsed_)
Parse();
const std::string & Capabilities::Platform() const {
return Platform_;
}
const std::string & Capabilities::AsString() const {
return AsString_;
}
} // namespace

View File

@@ -35,29 +35,28 @@ namespace OpenWifi::Config {
class Capabilities {
public:
explicit Capabilities(std::string Caps)
: Capabilities_(std::move(Caps))
{
explicit Capabilities(const Poco::JSON::Object::Ptr &Caps);
}
Capabilities()
/* Capabilities()
{
Capabilities_ = Default();
}
static std::string Default();
[[nodiscard]] const std::string & Get() const { return Capabilities_; };
[[nodiscard]] const std::string & Compatible();
[[nodiscard]] const std::string & Model();
[[nodiscard]] const std::string & Platform();
*/
[[nodiscard]] const std::string & Compatible() const;
[[nodiscard]] const std::string & Model() const;
[[nodiscard]] const std::string & Platform() const;
[[nodiscard]] const std::string & AsString() const;
private:
std::string Capabilities_;
bool Parsed_=false;
std::string Compatible_;
std::string Model_;
std::string Platform_;
std::string AsString_;
void Parse();
};

View File

@@ -31,25 +31,24 @@ namespace OpenWifi {
try {
if (Resp != nullptr) {
const Poco::JSON::Object &Payload = Resp->Payload_;
const std::string &SerialNumber = Resp->SerialNumber_;
Poco::JSON::Object::Ptr Payload = Resp->Payload_;
std::string SerialNumberStr = Utils::IntToSerialNumber(Resp->SerialNumber_);
std::ostringstream SS;
Payload.stringify(SS);
Payload->stringify(SS);
if (!Payload.has(uCentralProtocol::ID)) {
poco_error(Logger(), fmt::format("({}): Invalid RPC response.", SerialNumber));
if (!Payload->has(uCentralProtocol::ID)) {
poco_error(Logger(), fmt::format("({}): Invalid RPC response.", SerialNumberStr));
} else {
uint64_t ID = Payload.get(uCentralProtocol::ID);
poco_debug(Logger(),fmt::format("({}): Processing {} response.", SerialNumber, ID));
uint64_t ID = Payload->get(uCentralProtocol::ID);
poco_debug(Logger(),fmt::format("({}): Processing {} response.", SerialNumberStr, ID));
if (ID > 1) {
std::lock_guard Lock(LocalMutex_);
auto RPC = OutStandingRequests_.find(ID);
if (RPC == OutStandingRequests_.end() ||
RPC->second.SerialNumber !=
Utils::SerialNumberToInt(Resp->SerialNumber_)) {
RPC->second.SerialNumber != Resp->SerialNumber_) {
poco_debug(Logger(),
fmt::format("({}): RPC {} completed.", SerialNumber, ID));
fmt::format("({}): RPC {} completed.", SerialNumberStr, ID));
} else {
std::chrono::duration<double, std::milli> rpc_execution_time =
std::chrono::high_resolution_clock::now() -
@@ -61,7 +60,7 @@ namespace OpenWifi {
}
poco_debug(Logger(),
fmt::format("({}): Received RPC answer {}. Command={}",
SerialNumber, ID, RPC->second.Command));
SerialNumberStr, ID, RPC->second.Command));
OutStandingRequests_.erase(ID);
}
}
@@ -206,7 +205,7 @@ namespace OpenWifi {
poco_information(MyLogger, fmt::format("{}: Serial={} Command={} Preparing execution.",
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
auto Params = P.parse(Cmd.Details).extract<Poco::JSON::Object::Ptr>();
auto Result = PostCommandDisk(NextRPCId(), Cmd.SerialNumber, Cmd.Command,
auto Result = PostCommandDisk(Next_RPC_ID(), Cmd.SerialNumber, Cmd.Command,
*Params, Cmd.UUID, Sent);
if (Sent) {
StorageService()->SetCommandExecuted(Cmd.UUID);

View File

@@ -31,22 +31,22 @@ namespace OpenWifi {
class RPCResponseNotification: public Poco::Notification {
public:
RPCResponseNotification(const std::string &ser,
const Poco::JSON::Object &pl) :
RPCResponseNotification(std::uint64_t ser,
Poco::JSON::Object::Ptr pl) :
SerialNumber_(ser),
Payload_(pl)
Payload_(std::move(pl))
{
}
std::string SerialNumber_;
Poco::JSON::Object Payload_;
std::uint64_t SerialNumber_;
Poco::JSON::Object::Ptr Payload_;
};
class CommandManager : public SubSystemServer, Poco::Runnable {
public:
typedef Poco::JSON::Object objtype_t;
typedef std::promise<objtype_t> promise_type_t;
using objtype_t = Poco::JSON::Object::Ptr;
using promise_type_t = std::promise<objtype_t>;
struct CommandInfo {
std::uint64_t Id=0;
@@ -58,31 +58,30 @@ namespace OpenWifi {
};
struct RPCResponse {
std::string serialNumber;
Poco::JSON::Object payload;
std::uint64_t serialNumber;
Poco::JSON::Object::Ptr payload;
explicit RPCResponse(const std::string &ser, const Poco::JSON::Object &pl)
explicit RPCResponse(std::uint64_t ser, Poco::JSON::Object::Ptr pl)
:
serialNumber(ser),
payload(pl) {
payload(std::move(pl)) {
}
};
int Start() override;
void Stop() override;
void WakeUp();
inline void PostCommandResult(const std::string &SerialNumber, const Poco::JSON::Object &Obj) {
// RPCResponseQueue_->Write(RPCResponse{.serialNumber=SerialNumber, .payload = Obj});
ResponseQueue_.enqueueNotification(new RPCResponseNotification(SerialNumber,Obj));
inline void PostCommandResult(const std::string &SerialNumber, Poco::JSON::Object::Ptr Obj) {
ResponseQueue_.enqueueNotification(new RPCResponseNotification(Utils::SerialNumberToInt(SerialNumber),std::move(Obj)));
}
std::shared_ptr<promise_type_t> PostCommandOneWayDisk(uint64_t RPCID,
std::shared_ptr<promise_type_t> PostCommandOneWayDisk(uint64_t RPC_ID,
const std::string &SerialNumber,
const std::string &Method,
const Poco::JSON::Object &Params,
const std::string &UUID,
bool & Sent) {
return PostCommand(RPCID, SerialNumber,
return PostCommand(RPC_ID, SerialNumber,
Method,
Params,
UUID,
@@ -90,13 +89,13 @@ namespace OpenWifi {
}
std::shared_ptr<promise_type_t> PostCommandDisk(
uint64_t RPCID,
uint64_t RPC_ID,
const std::string &SerialNumber,
const std::string &Method,
const Poco::JSON::Object &Params,
const std::string &UUID,
bool & Sent) {
return PostCommand(RPCID,
return PostCommand(RPC_ID,
SerialNumber,
Method,
Params,
@@ -105,13 +104,13 @@ namespace OpenWifi {
}
std::shared_ptr<promise_type_t> PostCommand(
uint64_t RPCID,
uint64_t RPC_ID,
const std::string &SerialNumber,
const std::string &Method,
const Poco::JSON::Object &Params,
const std::string &UUID,
bool & Sent) {
return PostCommand(RPCID, SerialNumber,
return PostCommand(RPC_ID, SerialNumber,
Method,
Params,
UUID,
@@ -120,13 +119,13 @@ namespace OpenWifi {
}
std::shared_ptr<promise_type_t> PostCommandOneWay(
uint64_t RPCID,
uint64_t RPC_ID,
const std::string &SerialNumber,
const std::string &Method,
const Poco::JSON::Object &Params,
const std::string &UUID,
bool & Sent) {
return PostCommand(RPCID,
return PostCommand(RPC_ID,
SerialNumber,
Method,
Params,
@@ -147,8 +146,7 @@ namespace OpenWifi {
inline bool Running() const { return Running_; }
void onJanitorTimer(Poco::Timer & timer);
void onCommandRunnerTimer(Poco::Timer & timer);
void onRPCAnswer(bool& b);
inline uint64_t NextRPCId() { return ++Id_; }
inline uint64_t Next_RPC_ID() { return ++Id_; }
void RemovePendingCommand(std::uint64_t Id) {
std::unique_lock Lock(LocalMutex_);

View File

@@ -27,6 +27,7 @@
#include "framework/ConfigurationValidator.h"
#include "rttys/RTTYS_server.h"
#include "framework/UI_WebSocketClientServer.h"
#include "UI_GW_WebSocketNotifications.h"
namespace OpenWifi {
class Daemon *Daemon::instance() {
@@ -105,6 +106,7 @@ namespace OpenWifi {
void DaemonPostInitialization(Poco::Util::Application &self) {
Daemon()->PostInitialization(self);
GWWebSocketNotifications::Register();
}
}

View File

@@ -126,34 +126,32 @@ namespace OpenWifi {
}
// if you pass in an empty UUID, it will just clean the list and not add it.
bool FileUploader::AddUUID( const std::string & UUID) {
bool FileUploader::AddUUID( const std::string & UUID, std::chrono::seconds WaitTimeInSeconds, const std::string &Type) {
std::lock_guard Guard(Mutex_);
uint64_t now = Utils::Now();
// remove old stuff...
for(auto i=OutStandingUploads_.begin();i!=OutStandingUploads_.end();) {
if ((now-i->second) > (60 * 30))
i = OutStandingUploads_.erase(i);
else
++i;
}
if(!UUID.empty())
OutStandingUploads_[UUID] = now;
auto Func=[now](const UploadId &I) -> bool {
return (now > I.Expires);
};
OutStandingUploads_.erase(std::remove_if(OutStandingUploads_.begin(),OutStandingUploads_.end(),Func),OutStandingUploads_.end());
OutStandingUploads_.emplace_back(UploadId{UUID, now + WaitTimeInSeconds.count(), Type});
return true;
}
bool FileUploader::ValidRequest(const std::string &UUID) {
std::lock_guard Guard(Mutex_);
return OutStandingUploads_.find(UUID)!=OutStandingUploads_.end();
auto Func = [UUID](const UploadId &P) -> bool {
return (P.UUID==UUID);
};
return std::find_if(OutStandingUploads_.begin(), OutStandingUploads_.end(), Func) != end(OutStandingUploads_);
}
void FileUploader::RemoveRequest(const std::string &UUID) {
std::lock_guard Guard(Mutex_);
OutStandingUploads_.erase(UUID);
auto Func = [UUID](const UploadId &P) -> bool {
return (P.UUID==UUID);
};
OutStandingUploads_.erase(std::remove_if(OutStandingUploads_.begin(),OutStandingUploads_.end(),Func),OutStandingUploads_.end());
}
class FileUploaderPartHandler2 : public Poco::Net::PartHandler {
@@ -193,9 +191,10 @@ namespace OpenWifi {
class FormRequestHandler: public Poco::Net::HTTPRequestHandler
{
public:
explicit FormRequestHandler(std::string UUID, Poco::Logger & L):
explicit FormRequestHandler(std::string UUID, Poco::Logger & L, const std::string &Type):
UUID_(std::move(UUID)),
Logger_(L)
Logger_(L),
Type_(Type)
{
}
@@ -230,8 +229,8 @@ namespace OpenWifi {
Poco::StreamCopier::copyStream(Reader.stream(), FileContent);
Answer.set("filename", UUID_);
Answer.set("error", 0);
poco_debug(Logger(),fmt::format("{}: Trace file uploaded.", UUID_));
StorageService()->AttachFileDataToCommand(UUID_, FileContent);
poco_debug(Logger(),fmt::format("{}: File uploaded.", UUID_));
StorageService()->AttachFileDataToCommand(UUID_, FileContent, Type_);
std::ostream &ResponseStream = Response.send();
Poco::JSON::Stringifier::stringify(Answer, ResponseStream);
return;
@@ -267,6 +266,7 @@ namespace OpenWifi {
private:
std::string UUID_;
Poco::Logger & Logger_;
std::string Type_;
};
Poco::Net::HTTPRequestHandler *FileUpLoaderRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest & Request) {
@@ -285,11 +285,12 @@ namespace OpenWifi {
if( UUIDLocation != std::string::npos )
{
auto UUID = Request.getURI().substr(UUIDLocation+URI_BASE.size());
if(FileUploader()->ValidRequest(UUID))
FileUploader::UploadId E;
if(FileUploader()->Find(UUID,E))
{
// make sure we do not allow anyone else to overwrite our file
FileUploader()->RemoveRequest(UUID);
return new FormRequestHandler(UUID,Logger());
return new FormRequestHandler(UUID,Logger(),E.Type);
}
else
{
@@ -299,6 +300,17 @@ namespace OpenWifi {
return nullptr;
}
bool FileUploader::Find(const std::string &UUID, UploadId &V) {
std::lock_guard G(Mutex_);
for(const auto &E:OutStandingUploads_) {
if (E.UUID == UUID) {
V = E;
return true;
}
}
return false;
}
void FileUploader::Stop() {
poco_notice(Logger(),"Stopping...");
for( const auto & svr : Servers_ )

View File

@@ -19,11 +19,18 @@ namespace OpenWifi {
class FileUploader : public SubSystemServer {
public:
struct UploadId {
std::string UUID;
std::uint64_t Expires;
std::string Type;
};
int Start() override;
void Stop() override;
void reinitialize(Poco::Util::Application &self) override;
const std::string & FullName();
bool AddUUID( const std::string & UUID);
bool AddUUID( const std::string & UUID, std::chrono::seconds WaitTimeInSecond, const std::string &Type);
bool ValidRequest(const std::string & UUID);
void RemoveRequest(const std::string &UUID);
const std::string & Path() { return Path_; };
@@ -35,12 +42,13 @@ namespace OpenWifi {
[[nodiscard]] inline uint64_t MaxSize() const { return MaxSize_; }
bool Find(const std::string &UUID, UploadId &V);
private:
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> Servers_;
std::string FullName_;
std::map<std::string,uint64_t> OutStandingUploads_;
std::string Path_;
uint64_t MaxSize_=10000000;
std::string FullName_;
std::list<UploadId> OutStandingUploads_;
std::string Path_;
uint64_t MaxSize_=10000000;
explicit FileUploader() noexcept:
SubSystemServer("FileUploader", "FILE-UPLOAD", "openwifi.fileuploader")
@@ -51,10 +59,13 @@ namespace OpenWifi {
class FileUpLoaderRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
explicit FileUpLoaderRequestHandlerFactory(Poco::Logger &L) :
Logger_(L){}
Logger_(L) {
}
Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &request) override;
inline Poco::Logger & Logger() { return Logger_; }
inline Poco::Logger & Logger() {
return Logger_;
}
private:
Poco::Logger & Logger_;
};

View File

@@ -82,13 +82,13 @@ namespace OpenWifi::RESTAPI_RPC {
if (rpc_result == std::future_status::ready) {
std::chrono::duration<double, std::milli> rpc_execution_time = std::chrono::high_resolution_clock::now() - rpc_submitted;
auto rpc_answer = rpc_future.get();
if (!rpc_answer.has(uCentralProtocol::RESULT) || !rpc_answer.isObject(uCentralProtocol::RESULT)) {
if (!rpc_answer->has(uCentralProtocol::RESULT) || !rpc_answer->isObject(uCentralProtocol::RESULT)) {
SetCommandStatus(Cmd, Request, Response, Handler, Storage::CommandExecutionType::COMMAND_FAILED, Logger);
Logger.information(fmt::format("{},{}: Invalid response. Missing result.", Cmd.UUID, RPCID));
return;
}
auto ResultFields = rpc_answer.get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
auto ResultFields = rpc_answer->get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
if (!ResultFields->has(uCentralProtocol::STATUS) || !ResultFields->isObject(uCentralProtocol::STATUS)) {
Cmd.executionTime = rpc_execution_time.count();
if(Cmd.Command=="ping") {
@@ -107,20 +107,20 @@ namespace OpenWifi::RESTAPI_RPC {
if (StatusInnerObj->has(uCentralProtocol::TEXT))
Cmd.ErrorText = StatusInnerObj->get(uCentralProtocol::TEXT).toString();
std::stringstream ResultText;
if(rpc_answer.has(uCentralProtocol::RESULT)) {
if(rpc_answer->has(uCentralProtocol::RESULT)) {
if(Cmd.Command==uCentralProtocol::WIFISCAN) {
auto ScanObj = rpc_answer.get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
auto ScanObj = rpc_answer->get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
ParseWifiScan(ScanObj, ResultText, Logger);
} else {
Poco::JSON::Stringifier::stringify(
rpc_answer.get(uCentralProtocol::RESULT), ResultText);
rpc_answer->get(uCentralProtocol::RESULT), ResultText);
}
} if (rpc_answer.has(uCentralProtocol::RESULT_64)) {
} if (rpc_answer->has(uCentralProtocol::RESULT_64)) {
uint64_t sz=0;
if(rpc_answer.has(uCentralProtocol::RESULT_SZ))
sz=rpc_answer.get(uCentralProtocol::RESULT_SZ);
if(rpc_answer->has(uCentralProtocol::RESULT_SZ))
sz=rpc_answer->get(uCentralProtocol::RESULT_SZ);
std::string UnCompressedData;
Utils::ExtractBase64CompressedData(rpc_answer.get(uCentralProtocol::RESULT_64).toString(),
Utils::ExtractBase64CompressedData(rpc_answer->get(uCentralProtocol::RESULT_64).toString(),
UnCompressedData,sz);
Poco::JSON::Stringifier::stringify(UnCompressedData, ResultText);
}
@@ -129,7 +129,7 @@ namespace OpenWifi::RESTAPI_RPC {
Cmd.Completed = Utils::Now();
Cmd.executionTime = rpc_execution_time.count();
if (Cmd.ErrorCode && Cmd.Command == uCentralProtocol::TRACE) {
if (Cmd.ErrorCode && (Cmd.Command == uCentralProtocol::TRACE || Cmd.Command == uCentralProtocol::SCRIPT)) {
Cmd.WaitingForFile = 0;
Cmd.AttachDate = Cmd.AttachSize = 0;
Cmd.AttachType = "";

View File

@@ -8,7 +8,7 @@
namespace OpenWifi {
void RESTAPI_capabilities_handler::DoGet() {
CapabilitiesCache_t Caps = CapabilitiesCache().AllCapabilities();
CapabilitiesCache_t Caps = CapabilitiesCache()->AllCapabilities();
Poco::JSON::Array ObjArr;
for(const auto &[deviceType,capabilities]:Caps) {

View File

@@ -33,7 +33,7 @@
namespace OpenWifi {
void RESTAPI_device_commandHandler::CallCanceled(const char * Cmd, const OpenWifi::RESTAPI::Errors::msg &Err, const std::string & Details) {
Logger_.warning(fmt::format("{},{}: TID={} Canceled. Error:{} Reason:{} Details={}", Cmd, SerialNumber_, TransactionId_, Err.err_num, Err.err_txt, Details));
poco_warning(Logger_,fmt::format("{},{}: TID={} Canceled. Error:{} Reason:{} Details={}", Cmd, SerialNumber_, TransactionId_, Err.err_num, Err.err_txt, Details));
}
void RESTAPI_device_commandHandler::DoGet() {
@@ -64,16 +64,17 @@ namespace OpenWifi {
} else if (Command_ == RESTAPI::Protocol::STATUS) {
return GetStatus();
} else if (Command_ == RESTAPI::Protocol::RTTY) {
if(!AP_WS_Server()->Connected(SerialNumberInt_)) {
AP_Restrictions Restrictions;
if(!AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) {
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected);
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
}
auto UUID = MicroServiceCreateUUID();
auto RPC = CommandManager()->NextRPCId();
auto RPC = CommandManager()->Next_RPC_ID();
poco_debug(Logger_,fmt::format("Command rtty TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
TransactionId_, UUID, RPC,
Poco::Thread::current()->id()));
return Rtty(UUID,RPC,60000ms);
return Rtty(UUID,RPC,60000ms, Restrictions);
} else {
return BadRequest(RESTAPI::Errors::InvalidCommand);
}
@@ -113,28 +114,25 @@ namespace OpenWifi {
const char * Command;
bool AllowParallel=false;
bool RequireConnection = true;
void (RESTAPI_device_commandHandler::*funPtr)(const std::string &, std::uint64_t, std::chrono::milliseconds );
void (RESTAPI_device_commandHandler::*funPtr)(const std::string &, std::uint64_t, std::chrono::milliseconds, const AP_Restrictions &R );
std::chrono::milliseconds Timeout=120ms;
};
/*
const static std::vector<PostDeviceCommand> PostCommands
const std::vector<PostDeviceCommand> PostCommands =
{
{ RESTAPI::Protocol::PERFORM, false, true, &RESTAPI_device_commandHandler::ExecuteCommand },
{ RESTAPI::Protocol::CONFIGURE, false, false, &RESTAPI_device_commandHandler::Configure },
{ RESTAPI::Protocol::UPGRADE, false, false, &RESTAPI_device_commandHandler::Upgrade },
{ RESTAPI::Protocol::REBOOT, false, true, &RESTAPI_device_commandHandler::Reboot },
{ RESTAPI::Protocol::FACTORY, false, false, &RESTAPI_device_commandHandler::Factory },
{ RESTAPI::Protocol::LEDS, false, true, &RESTAPI_device_commandHandler::LEDs },
{ RESTAPI::Protocol::TRACE, false, true, &RESTAPI_device_commandHandler::Trace },
{ RESTAPI::Protocol::REQUEST, false, true, &RESTAPI_device_commandHandler::MakeRequest },
{ RESTAPI::Protocol::WIFISCAN, false, true, &RESTAPI_device_commandHandler::WifiScan },
{ RESTAPI::Protocol::EVENTQUEUE, false, true, &RESTAPI_device_commandHandler::EventQueue },
{ RESTAPI::Protocol::TELEMETRY, false, true, &RESTAPI_device_commandHandler::Telemetry },
{ RESTAPI::Protocol::PING, false, true, &RESTAPI_device_commandHandler::Ping },
{ RESTAPI::Protocol::SCRIPT, false, true, &RESTAPI_device_commandHandler::Script }
};
*/
{ RESTAPI::Protocol::CONFIGURE, false, false, &RESTAPI_device_commandHandler::Configure, 120000ms },
{ RESTAPI::Protocol::UPGRADE, false, false, &RESTAPI_device_commandHandler::Upgrade, 30000ms },
{ RESTAPI::Protocol::REBOOT, false, true, &RESTAPI_device_commandHandler::Reboot, 30000ms },
{ RESTAPI::Protocol::FACTORY, false, false, &RESTAPI_device_commandHandler::Factory, 30000ms },
{ RESTAPI::Protocol::LEDS, false, true, &RESTAPI_device_commandHandler::LEDs, 120000ms },
{ RESTAPI::Protocol::TRACE, false, true, &RESTAPI_device_commandHandler::Trace, 300000ms },
{ RESTAPI::Protocol::REQUEST, false, true, &RESTAPI_device_commandHandler::MakeRequest, 120000ms },
{ RESTAPI::Protocol::WIFISCAN, false, true, &RESTAPI_device_commandHandler::WifiScan, 120000ms },
{ RESTAPI::Protocol::EVENTQUEUE, false, true, &RESTAPI_device_commandHandler::EventQueue, 30000ms },
{ RESTAPI::Protocol::TELEMETRY, false, true, &RESTAPI_device_commandHandler::Telemetry, 30000ms },
{ RESTAPI::Protocol::PING, false, true, &RESTAPI_device_commandHandler::Ping, 60000ms },
{ RESTAPI::Protocol::SCRIPT, false, true, &RESTAPI_device_commandHandler::Script, 300000ms }
};
void RESTAPI_device_commandHandler::DoPost() {
if(!ValidateParameters()) {
@@ -149,27 +147,11 @@ namespace OpenWifi {
return NotFound();
}
const std::vector<PostDeviceCommand> PostCommands =
{
{ RESTAPI::Protocol::PERFORM, false, true, &RESTAPI_device_commandHandler::ExecuteCommand, 120000ms },
{ RESTAPI::Protocol::CONFIGURE, false, false, &RESTAPI_device_commandHandler::Configure, 120000ms },
{ RESTAPI::Protocol::UPGRADE, false, false, &RESTAPI_device_commandHandler::Upgrade, 30000ms },
{ RESTAPI::Protocol::REBOOT, false, true, &RESTAPI_device_commandHandler::Reboot, 30000ms },
{ RESTAPI::Protocol::FACTORY, false, false, &RESTAPI_device_commandHandler::Factory, 30000ms },
{ RESTAPI::Protocol::LEDS, false, true, &RESTAPI_device_commandHandler::LEDs, 120000ms },
{ RESTAPI::Protocol::TRACE, false, true, &RESTAPI_device_commandHandler::Trace, 300000ms },
{ RESTAPI::Protocol::REQUEST, false, true, &RESTAPI_device_commandHandler::MakeRequest, 120000ms },
{ RESTAPI::Protocol::WIFISCAN, false, true, &RESTAPI_device_commandHandler::WifiScan, 120000ms },
{ RESTAPI::Protocol::EVENTQUEUE, false, true, &RESTAPI_device_commandHandler::EventQueue, 30000ms },
{ RESTAPI::Protocol::TELEMETRY, false, true, &RESTAPI_device_commandHandler::Telemetry, 30000ms },
{ RESTAPI::Protocol::PING, false, true, &RESTAPI_device_commandHandler::Ping, 60000ms },
{ RESTAPI::Protocol::SCRIPT, false, true, &RESTAPI_device_commandHandler::Script, 300000ms }
};
for(const auto &Command:PostCommands) {
if(Command_==Command.Command) {
Poco::Thread::current()->setName(fmt::format("{}:{}:{}",Command.Command, TransactionId_,SerialNumber_));
if(Command.RequireConnection && !AP_WS_Server()->Connected(SerialNumberInt_)) {
AP_Restrictions Restrictions;
if(Command.RequireConnection && !AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) {
CallCanceled(Command.Command, RESTAPI::Errors::DeviceNotConnected);
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
}
@@ -180,18 +162,18 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::DeviceIsAlreadyBusy, Extra);
}
auto UUID = MicroServiceCreateUUID();
auto RPC = CommandManager()->NextRPCId();
auto RPC = CommandManager()->Next_RPC_ID();
poco_debug(Logger_,fmt::format("Command {} TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
Command.Command, TransactionId_, UUID, RPC,
Poco::Thread::current()->id()));
return (*this.*Command.funPtr)(UUID,RPC,Command.Timeout);
return (*this.*Command.funPtr)(UUID,RPC,Command.Timeout, Restrictions);
}
}
return BadRequest(RESTAPI::Errors::InvalidCommand);
}
void RESTAPI_device_commandHandler::GetCapabilities() {
Logger_.information(fmt::format("GET-CAPABILITIES: TID={} user={} serial={}. thr_id={}",
poco_information(Logger_,fmt::format("GET-CAPABILITIES: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
GWObjects::Capabilities Caps;
@@ -205,7 +187,7 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::DeleteCapabilities() {
Logger_.information(fmt::format("DELETE-CAPABILITIES: TID={} user={} serial={}. thr_id={}",
poco_information(Logger_,fmt::format("DELETE-CAPABILITIES: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
if (StorageService()->DeleteDeviceCapabilities(SerialNumber_)) {
@@ -215,17 +197,15 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::GetStatistics() {
Logger_.information(fmt::format("GET-STATISTICS: TID={} user={} serial={}. thr_id={}",
std::string StatsType = QB_.LastOnly ? "LastOnly" : ( QB_.Newest ? "Newest" :
( QB_.CountOnly ? "CountOnly" : "Timed"));
poco_information(Logger_,fmt::format("GET-STATISTICS: TID={} user={} serial={}. thr_id={}, TYPE={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
Poco::Thread::current()->id(),StatsType));
if (QB_.LastOnly) {
std::string Stats;
if (AP_WS_Server()->GetStatistics(SerialNumber_, Stats) && !Stats.empty()) {
Poco::JSON::Parser P;
if (Stats.empty())
Stats = uCentralProtocol::EMPTY_JSON_DOC;
auto Obj = P.parse(Stats).extract<Poco::JSON::Object::Ptr>();
return ReturnObject(*Obj);
return ReturnRawJSON(Stats);
}
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
}
@@ -234,6 +214,14 @@ namespace OpenWifi {
if (QB_.Newest) {
StorageService()->GetNewestStatisticsData(SerialNumber_, QB_.Limit, Stats);
} else {
if(QB_.CountOnly) {
std::uint64_t Count = 0 ;
StorageService()->GetNumberOfStatisticsDataRecords(SerialNumber_, QB_.StartDate, QB_.EndDate,Count);
return ReturnCountOnly(Count);
}
if(QB_.Limit>100)
QB_.Limit=100;
StorageService()->GetStatisticsData(SerialNumber_, QB_.StartDate, QB_.EndDate,
QB_.Offset, QB_.Limit, Stats);
}
@@ -252,7 +240,7 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::DeleteStatistics() {
Logger_.information(fmt::format("DELETE-STATISTICS: TID={} user={} serial={}. thr_id={}",
poco_information(Logger_,fmt::format("DELETE-STATISTICS: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
if (StorageService()->DeleteStatisticsData(SerialNumber_, QB_.StartDate, QB_.EndDate)) {
@@ -262,7 +250,7 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::GetStatus() {
Logger_.information(fmt::format("GET-STATUS: TID={} user={} serial={}. thr_id={}",
poco_information(Logger_,fmt::format("GET-STATUS: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
GWObjects::ConnectionState State;
@@ -280,7 +268,7 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::GetLogs() {
Logger_.information(fmt::format("GET-LOGS: TID={} user={} serial={}. thr_id={}",
poco_information(Logger_,fmt::format("GET-LOGS: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
std::vector<GWObjects::DeviceLog> Logs;
@@ -304,7 +292,7 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::DeleteLogs() {
Logger_.information(fmt::format("DELETE-LOGS: TID={} user={} serial={}. thr_id={}",
poco_information(Logger_,fmt::format("DELETE-LOGS: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
if (StorageService()->DeleteLogData(SerialNumber_, QB_.StartDate, QB_.EndDate,
@@ -315,12 +303,10 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::GetChecks() {
Logger_.information(fmt::format("GET-HEALTHCHECKS: TID={} user={} serial={}. thr_id={}",
poco_information(Logger_,fmt::format("GET-HEALTHCHECKS: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
std::vector<GWObjects::HealthCheck> Checks;
if (QB_.LastOnly) {
GWObjects::HealthCheck HC;
if (AP_WS_Server()->GetHealthcheck(SerialNumber_, HC)) {
@@ -331,6 +317,7 @@ namespace OpenWifi {
return NotFound();
}
} else {
std::vector<GWObjects::HealthCheck> Checks;
if (QB_.Newest) {
StorageService()->GetNewestHealthCheckData(SerialNumber_, QB_.Limit, Checks);
} else {
@@ -353,7 +340,7 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::DeleteChecks() {
Logger_.information(fmt::format("DELETE-HEALTHCHECKS: TID={} user={} serial={}. thr_id={}",
poco_information(Logger_,fmt::format("DELETE-HEALTHCHECKS: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
if (StorageService()->DeleteHealthCheckData(SerialNumber_, QB_.StartDate, QB_.EndDate)) {
@@ -362,8 +349,8 @@ namespace OpenWifi {
BadRequest(RESTAPI::Errors::NoRecordsDeleted);
}
void RESTAPI_device_commandHandler::Ping(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("PING({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Ping(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
poco_information(Logger_,fmt::format("PING({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
@@ -415,11 +402,15 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::CallCanceled(const char * Cmd, const std::string &UUID, uint64_t RPC, const OpenWifi::RESTAPI::Errors::msg &Err) {
Logger_.warning(fmt::format("{}({},{}): Canceled. Error:{} Reason:{}", Cmd, UUID, RPC, Err.err_num, Err.err_txt));
poco_warning(Logger_,fmt::format("{}({},{}): Canceled. Error:{} Reason:{}", Cmd, UUID, RPC, Err.err_num, Err.err_txt));
}
void RESTAPI_device_commandHandler::Script(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("SCRIPT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
static bool ValidateScriptType(const std::string &t) {
return t=="shell" || t=="bundle";
}
void RESTAPI_device_commandHandler::Script(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
poco_information(Logger_,fmt::format("SCRIPT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
if(!Internal_ && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
@@ -434,9 +425,7 @@ namespace OpenWifi {
if (SCR.serialNumber.empty() ||
SCR.script.empty() ||
SCR.type.empty() ||
SCR.scriptId.empty() ||
(SCR.type!="shell" && SCR.type!="ucode")) {
!ValidateScriptType(SCR.type)) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::MissingOrInvalidParameters);
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
@@ -446,6 +435,15 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
}
GWObjects::Device D;
if(!StorageService()->GetDevice(SerialNumber_,D)) {
return NotFound();
}
if(D.restrictedDevice && SCR.signature.empty()) {
return BadRequest(RESTAPI::Errors::DeviceRequiresSignature);
}
uint64_t ap_timeout = SCR.timeout==0 ? 30 : SCR.timeout;
GWObjects::CommandDetails Cmd;
@@ -454,10 +452,23 @@ namespace OpenWifi {
Cmd.SubmittedBy = Requester();
Cmd.Command = uCentralProtocol::SCRIPT;
Cmd.RunAt = 0;
Cmd.WaitingForFile = SCR.deferred ? 1 : 0;
Poco::JSON::Object Params;
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
Params.set(uCentralProtocol::TIMEOUT, ap_timeout);
if(SCR.deferred && SCR.uri.empty()) {
SCR.uri = FileUploader()->FullName() + CMD_UUID ;
}
if(SCR.deferred) {
Params.set(uCentralProtocol::URI, SCR.uri);
} else {
Params.set(uCentralProtocol::TIMEOUT, ap_timeout);
}
if(!SCR.signature.empty()) {
Params.set(uCentralProtocol::SIGNATURE, SCR.signature);
}
Params.set(uCentralProtocol::TYPE, SCR.type);
Params.set(uCentralProtocol::SCRIPT, SCR.script);
Params.set(uCentralProtocol::WHEN, SCR.when);
@@ -465,12 +476,13 @@ namespace OpenWifi {
std::stringstream ParamStream;
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
FileUploader()->AddUUID(CMD_UUID, 15min, "script_result");
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
void RESTAPI_device_commandHandler::Configure(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("CONFIGURE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Configure(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
poco_information(Logger_,fmt::format("CONFIGURE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
@@ -521,8 +533,8 @@ namespace OpenWifi {
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::Upgrade(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("UPGRADE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Upgrade(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
poco_information(Logger_,fmt::format("UPGRADE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -535,6 +547,17 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
}
GWObjects::Device DeviceInfo;
if(!StorageService()->GetDevice(SerialNumber_,DeviceInfo)) {
return NotFound();
}
std::string FWSignature = GetParameter("FWsignature","");
if(FWSignature.empty() && R.sysupgrade_not_allowed()) {
return BadRequest(RESTAPI::Errors::DeviceRequiresSignature);
}
auto URI = GetS(RESTAPI::Protocol::URI, Obj);
auto When = GetWhen(Obj);
@@ -553,6 +576,9 @@ namespace OpenWifi {
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
Params.set(uCentralProtocol::URI, URI);
Params.set(uCentralProtocol::KEEP_REDIRECTOR, KeepRedirector ? 1 : 0);
if(!FWSignature.empty()) {
Params.set(uCentralProtocol::FWSIGNATURE, FWSignature);
}
Params.set(uCentralProtocol::WHEN, When);
std::stringstream ParamStream;
@@ -564,57 +590,8 @@ namespace OpenWifi {
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::ExecuteCommand(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("EXECUTE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
if (Obj->has(RESTAPI::Protocol::COMMAND) &&
Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
Obj->has(RESTAPI::Protocol::PAYLOAD)) {
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
if (SerialNumber_ != SNum) {
CallCanceled("EXECUTE", CMD_UUID, CMD_RPC,RESTAPI::Errors::SerialNumberMismatch);
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
}
auto Command = GetS(RESTAPI::Protocol::COMMAND, Obj);
auto Payload = GetS(RESTAPI::Protocol::PAYLOAD, Obj);
auto When = GetWhen(Obj);
GWObjects::CommandDetails Cmd;
Cmd.SerialNumber = SerialNumber_;
Cmd.UUID = CMD_UUID;
Cmd.SubmittedBy = Requester();
Cmd.Command = Command;
Cmd.Custom = 1;
Cmd.RunAt = When;
Poco::JSON::Parser parser2;
Poco::Dynamic::Var result = parser2.parse(Payload);
const auto &PayloadObject = result.extract<Poco::JSON::Object::Ptr>();
Poco::JSON::Object Params;
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
Params.set(uCentralProtocol::COMMAND, Command);
Params.set(uCentralProtocol::WHEN, When);
Params.set(uCentralProtocol::PAYLOAD, PayloadObject);
std::stringstream ParamStream;
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::Reboot(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("REBOOT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Reboot(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
poco_information(Logger_,fmt::format("REBOOT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -647,8 +624,8 @@ namespace OpenWifi {
BadRequest(RESTAPI::Errors::MissingSerialNumber);
}
void RESTAPI_device_commandHandler::Factory(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("FACTORY-RESET({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Factory(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
poco_information(Logger_,fmt::format("FACTORY-RESET({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
if (Obj->has(RESTAPI::Protocol::KEEPREDIRECTOR) &&
@@ -687,8 +664,8 @@ namespace OpenWifi {
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::LEDs(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("LEDS({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::LEDs(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
poco_information(Logger_,fmt::format("LEDS({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -735,8 +712,8 @@ namespace OpenWifi {
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::Trace(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("TRACE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Trace(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
poco_information(Logger_,fmt::format("TRACE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -782,14 +759,14 @@ namespace OpenWifi {
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
FileUploader()->AddUUID(CMD_UUID);
FileUploader()->AddUUID(CMD_UUID, 10min, "trace");
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::WifiScan(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("WIFISCAN({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::WifiScan(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
poco_information(Logger_,fmt::format("WIFISCAN({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
@@ -817,6 +794,11 @@ namespace OpenWifi {
Poco::JSON::Object Params;
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
if(R.dfs_not_allowed() && OverrideDFS) {
return BadRequest(RESTAPI::Errors::DeviceIsRestricted);
}
Params.set(uCentralProtocol::OVERRIDEDFS, OverrideDFS);
Params.set(uCentralProtocol::ACTIVE, ActiveScan);
if(ies)
@@ -833,8 +815,8 @@ namespace OpenWifi {
}
}
void RESTAPI_device_commandHandler::EventQueue(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("EVENT-QUEUE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::EventQueue(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
poco_information(Logger_,fmt::format("EVENT-QUEUE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
@@ -872,8 +854,8 @@ namespace OpenWifi {
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::MakeRequest(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("FORCE-REQUEST({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::MakeRequest(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
poco_information(Logger_,fmt::format("FORCE-REQUEST({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
@@ -914,17 +896,18 @@ namespace OpenWifi {
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::Rtty(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("RTTY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Rtty(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
poco_information(Logger_,fmt::format("RTTY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
if(R.rtty_not_allowed()) {
return BadRequest(RESTAPI::Errors::DeviceIsRestricted);
}
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
if (MicroServiceConfigGetBool("rtty.enabled", false)) {
GWObjects::Device Device;
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
if (StorageService()->GetDevice(SerialNumber_, Device)) {
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
GWObjects::RttySessionDetails Rtty{
.SerialNumber = SerialNumber_,
.Server = MicroServiceConfigGetString("rtty.server", "localhost"),
@@ -937,19 +920,13 @@ namespace OpenWifi {
.ViewPort = MicroServiceConfigGetInt("rtty.viewport", 5913),
.DevicePassword = ""
};
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
if(RTTYS_server()->UseInternal()) {
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
Rtty.Token = Utils::ComputeHash(UserInfo_.webtoken.refresh_token_,Utils::Now()).substr(0,RTTY_DEVICE_TOKEN_LENGTH);
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
if(!RTTYS_server()->CreateEndPoint(Rtty.ConnectionId, Rtty.Token, Requester(), SerialNumber_)) {
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
return BadRequest(RESTAPI::Errors::MaximumRTTYSessionsReached);
}
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
}
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
Poco::JSON::Object ReturnedObject;
Rtty.to_json(ReturnedObject);
@@ -961,7 +938,6 @@ namespace OpenWifi {
Cmd.UUID = CMD_UUID;
Cmd.Command = uCentralProtocol::RTTY;
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
Poco::JSON::Object Params;
Params.set(uCentralProtocol::METHOD, uCentralProtocol::RTTY);
@@ -974,27 +950,22 @@ namespace OpenWifi {
Params.set(uCentralProtocol::TIMEOUT, Rtty.TimeOut);
Params.set(uCentralProtocol::PASSWORD, Device.DevicePassword);
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
std::stringstream ParamStream;
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
Params.stringify(ParamStream);
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
Cmd.Details = ParamStream.str();
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
Logger_.information(fmt::format("RTTY: user={} serial={} rttyid={} token={} cmd={}.", Requester(), SerialNumber_, Rtty.ConnectionId, Rtty.Token, CMD_UUID));
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
poco_information(Logger_,fmt::format("RTTY: user={} serial={} rttyid={} token={} cmd={}.", Requester(), SerialNumber_, Rtty.ConnectionId, Rtty.Token, CMD_UUID));
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, &ReturnedObject, this, Logger_);
}
return NotFound();
}
Logger_.information(fmt::format("RTTY: user={} serial={}. Internal error.", Requester(), SerialNumber_));
poco_information(Logger_,fmt::format("RTTY: user={} serial={}. Internal error.", Requester(), SerialNumber_));
return ReturnStatus(Poco::Net::HTTPResponse::HTTP_SERVICE_UNAVAILABLE);
}
// #define DBG { std::cout << __LINE__ << std::endl; }
void RESTAPI_device_commandHandler::Telemetry(const std::string &CMD_UUID, uint64_t CMD_RPC, [[maybe_unused]] std::chrono::milliseconds timeout){
Logger_.information(fmt::format("TELEMETRY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Telemetry(const std::string &CMD_UUID, uint64_t CMD_RPC, [[maybe_unused]] std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R){
poco_information(Logger_,fmt::format("TELEMETRY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;

View File

@@ -9,6 +9,7 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "AP_restrictions.h"
namespace OpenWifi {
class RESTAPI_device_commandHandler : public RESTAPIHandler {
@@ -32,20 +33,20 @@ namespace OpenWifi {
void GetStatus();
void GetChecks();
void DeleteChecks();
void ExecuteCommand(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Configure(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Upgrade(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Reboot(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Factory(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void LEDs(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Trace(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void MakeRequest(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void WifiScan(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void EventQueue(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Rtty(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Telemetry(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Ping(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Script(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Configure(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Upgrade(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Reboot(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Factory(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void LEDs(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Trace(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void MakeRequest(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void WifiScan(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void EventQueue(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Rtty(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Telemetry(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Ping(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Script(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
static auto PathName() { return std::list<std::string>{"/api/v1/device/{serialNumber}/{command}"}; };
void DoGet() final;

View File

@@ -107,11 +107,6 @@ namespace OpenWifi {
return ReturnObject(Answer);
}
if (!Utils::ValidSerialNumber(SerialNumber)) {
Logger_.warning(fmt::format("CREATE-DEVICE({}): Illegal serial number.", SerialNumber));
return BadRequest( RESTAPI::Errors::InvalidSerialNumber);
}
GWObjects::Device Device;
if (!Device.from_json(Obj)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);

View File

@@ -26,7 +26,7 @@ namespace OpenWifi {
std::string ItemList;
Types::StringVec Fields;
StorageService()->GetDeviceDbFieldList(Fields);
Storage::GetDeviceDbFieldList(Fields);
std::set<std::string> FieldNames;
for(const auto &field:Fields)
@@ -68,7 +68,7 @@ namespace OpenWifi {
if(GetBoolParameter("orderSpec")) {
Types::StringVec Fields;
StorageService()->GetDeviceDbFieldList(Fields);
Storage::GetDeviceDbFieldList(Fields);
std::sort(Fields.begin(),Fields.end());
Poco::JSON::Object Answer;
RESTAPI_utils::field_to_json(Answer,"list",Fields);

View File

@@ -18,8 +18,10 @@
#include "RESTAPI/RESTAPI_telemetryWebSocket.h"
#include "RESTAPI/RESTAPI_iptocountry_handler.h"
#include "RESTAPI/RESTAPI_radiusProxyConfig_handler.h"
#include "framework/RESTAPI_SystemCommand.h"
#include "framework/RESTAPI_WebSocketServer.h"
#include "framework/RESTAPI_SystemConfiguration.h"
namespace OpenWifi {
@@ -37,6 +39,7 @@ namespace OpenWifi {
RESTAPI_ouis,
RESTAPI_file,
RESTAPI_system_command,
RESTAPI_system_configuration,
RESTAPI_deviceDashboardHandler,
RESTAPI_webSocketServer,
RESTAPI_blacklist,

View File

@@ -50,6 +50,8 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"entity", entity);
field_to_json(Obj,"modified", modified);
field_to_json(Obj,"locale", locale);
field_to_json(Obj,"restrictedDevice", restrictedDevice);
}
void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
@@ -70,6 +72,7 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE");
field_to_json(Obj,"associations_2G", (uint64_t) 0);
field_to_json(Obj,"associations_5G", (uint64_t) 0);
field_to_json(Obj,"associations_6G", (uint64_t) 0);
}
#endif
}
@@ -89,6 +92,7 @@ namespace OpenWifi::GWObjects {
field_from_json(Obj,"subscriber", subscriber);
field_from_json(Obj,"entity", entity);
field_from_json(Obj,"locale", locale);
field_from_json(Obj,"restrictedDevice", restrictedDevice);
return true;
} catch (const Poco::Exception &E) {
}
@@ -199,6 +203,7 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"lastContact", LastContact);
field_to_json(Obj,"associations_2G", Associations_2G);
field_to_json(Obj,"associations_5G", Associations_5G);
field_to_json(Obj,"associations_6G", Associations_6G);
field_to_json(Obj,"webSocketClients", webSocketClients);
field_to_json(Obj,"websocketPackets", websocketPackets);
field_to_json(Obj,"kafkaClients", kafkaClients);
@@ -208,6 +213,7 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"sessionId", sessionId);
field_to_json(Obj,"connectionCompletionTime", connectionCompletionTime);
field_to_json(Obj,"totalConnectionTime", Utils::Now() - started);
field_to_json(Obj,"certificateExpiryDate", certificateExpiryDate);
switch(VerifiedCertificate) {
case NO_CERTIFICATE:
@@ -299,8 +305,10 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"timeout",timeout);
field_to_json(Obj,"type",type);
field_to_json(Obj,"script",script);
field_to_json(Obj,"scriptId",scriptId);
field_to_json(Obj,"when",when);
field_to_json(Obj,"signature", signature);
field_to_json(Obj,"deferred", deferred);
field_to_json(Obj,"uri", uri);
}
bool ScriptRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -309,8 +317,10 @@ namespace OpenWifi::GWObjects {
field_from_json(Obj,"timeout",timeout);
field_from_json(Obj,"type",type);
field_from_json(Obj,"script",script);
field_from_json(Obj,"scriptId",scriptId);
field_from_json(Obj,"when",when);
field_from_json(Obj,"signature", signature);
field_from_json(Obj,"deferred", deferred);
field_from_json(Obj,"uri", uri);
return true;
} catch (const Poco::Exception &E) {
}

View File

@@ -28,19 +28,21 @@ namespace OpenWifi::GWObjects {
uint64_t TX = 0, RX = 0;
uint64_t Associations_2G=0;
uint64_t Associations_5G=0;
uint64_t Associations_6G=0;
bool Connected = false;
uint64_t LastContact=0;
std::string Firmware;
CertificateValidation VerifiedCertificate = NO_CERTIFICATE;
std::string Compatible;
uint64_t kafkaClients=0;
uint64_t webSocketClients=0;
uint64_t kafkaPackets=0;
uint64_t websocketPackets=0;
std::string locale;
uint64_t started=0;
uint64_t sessionId=0;
double connectionCompletionTime=0.0;
std::string Compatible;
uint64_t kafkaClients=0;
uint64_t webSocketClients=0;
uint64_t kafkaPackets=0;
uint64_t websocketPackets=0;
std::string locale;
uint64_t started=0;
uint64_t sessionId=0;
double connectionCompletionTime=0.0;
std::uint64_t certificateExpiryDate=0;
void to_json(Poco::JSON::Object &Obj) const;
};
@@ -68,6 +70,7 @@ namespace OpenWifi::GWObjects {
std::string entity;
uint64_t modified=0;
std::string locale;
bool restrictedDevice=false;
void to_json(Poco::JSON::Object &Obj) const;
void to_json_with_status(Poco::JSON::Object &Obj) const;
@@ -214,12 +217,15 @@ namespace OpenWifi::GWObjects {
};
struct ScriptRequest {
uint64_t timeout=30;
std::string serialNumber;
uint64_t timeout=30;
std::string type;
std::string script;
std::string scriptId;
uint64_t when=0;
std::uint64_t when;
std::string signature;
bool deferred;
std::string uri;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};

View File

@@ -602,6 +602,7 @@ namespace OpenWifi::ProvObjects {
field_to_json( Obj, "devClass",devClass);
field_to_json( Obj, "locale",locale);
field_to_json( Obj, "realMacAddress",realMacAddress);
field_to_json( Obj, "doNotAllowOverrides",doNotAllowOverrides);
}
bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -623,6 +624,7 @@ namespace OpenWifi::ProvObjects {
field_from_json( Obj,"devClass",devClass);
field_from_json( Obj,"locale",locale);
field_from_json( Obj,"realMacAddress",realMacAddress);
field_from_json( Obj, "doNotAllowOverrides",doNotAllowOverrides);
return true;
} catch(...) {
@@ -1195,6 +1197,48 @@ namespace OpenWifi::ProvObjects {
return false;
}
void ConfigurationOverride::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"source",source);
field_to_json(Obj,"reason",reason);
field_to_json(Obj,"parameterName",parameterName);
field_to_json(Obj,"parameterType",parameterType);
field_to_json(Obj,"parameterValue",parameterValue);
field_to_json(Obj,"modified",modified);
}
bool ConfigurationOverride::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"source",source);
field_from_json(Obj,"reason",reason);
field_from_json(Obj,"parameterName",parameterName);
field_from_json(Obj,"parameterType",parameterType);
field_from_json(Obj,"parameterValue",parameterValue);
field_from_json(Obj,"modified",modified);
return true;
} catch(...) {
}
return false;
}
void ConfigurationOverrideList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"serialNumber",serialNumber);
field_to_json(Obj,"managementPolicy",managementPolicy);
field_to_json(Obj,"overrides",overrides);
}
bool ConfigurationOverrideList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"serialNumber",serialNumber);
field_from_json(Obj,"managementPolicy",managementPolicy);
field_from_json(Obj,"overrides",overrides);
return true;
} catch(...) {
}
return false;
}
}

View File

@@ -428,6 +428,7 @@ namespace OpenWifi::ProvObjects {
std::string devClass;
std::string locale;
std::string realMacAddress;
bool doNotAllowOverrides=false;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -693,6 +694,27 @@ namespace OpenWifi::ProvObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ConfigurationOverride {
std::string source;
std::string reason;
std::string parameterName;
std::string parameterType;
std::string parameterValue;
std::uint64_t modified;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ConfigurationOverrideList {
std::string serialNumber;
Types::UUID_t managementPolicy;
std::vector<ConfigurationOverride> overrides;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I);
bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I);
bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I);

View File

@@ -619,5 +619,80 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"login",login);
field_to_json(Obj,"logout",logout);
}
void ApiKeyAccessRight::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "service", service);
field_to_json(Obj, "access", access);
}
bool ApiKeyAccessRight::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "service", service);
field_from_json(Obj, "access", access);
return true;
} catch(...) {
std::cout << "Cannot parse: Token" << std::endl;
}
return false;
}
void ApiKeyAccessRightList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "acls", acls);
}
bool ApiKeyAccessRightList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "acls", acls);
return true;
} catch(...) {
std::cout << "Cannot parse: Token" << std::endl;
}
return false;
}
void ApiKeyEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "id", id);
field_to_json(Obj, "userUuid", userUuid);
field_to_json(Obj, "name", name);
field_to_json(Obj, "apiKey", apiKey);
field_to_json(Obj, "salt", salt);
field_to_json(Obj, "description", description);
field_to_json(Obj, "expiresOn", expiresOn);
field_to_json(Obj, "rights", rights);
field_to_json(Obj, "lastUse", lastUse);
}
bool ApiKeyEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "id", id);
field_from_json(Obj, "userUuid", userUuid);
field_from_json(Obj, "name", name);
field_from_json(Obj, "apiKey", apiKey);
field_from_json(Obj, "salt", salt);
field_from_json(Obj, "description", description);
field_from_json(Obj, "expiresOn", expiresOn);
field_from_json(Obj, "rights", rights);
field_from_json(Obj, "lastUse", lastUse);
return true;
} catch(...) {
std::cout << "Cannot parse: Token" << std::endl;
}
return false;
}
void ApiKeyEntryList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "apiKeys", apiKeys);
}
bool ApiKeyEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "apiKeys", apiKeys);
return true;
} catch(...) {
std::cout << "Cannot parse: Token" << std::endl;
}
return false;
}
}

View File

@@ -325,5 +325,44 @@ namespace OpenWifi {
void to_json(Poco::JSON::Object &Obj) const;
};
struct ApiKeyAccessRight {
std::string service;
std::string access;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ApiKeyAccessRightList {
std::vector<ApiKeyAccessRight> acls;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ApiKeyEntry {
Types::UUID_t id;
Types::UUID_t userUuid;
std::string name;
std::string description;
std::string apiKey;
std::string salt;
std::uint64_t created;
std::uint64_t expiresOn=0;
ApiKeyAccessRightList rights;
std::uint64_t lastUse=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ApiKeyEntryList {
std::vector<ApiKeyEntry> apiKeys;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
}
}

View File

@@ -12,10 +12,13 @@ namespace OpenWifi::StateUtils {
return 5;
}
bool ComputeAssociations(const Poco::JSON::Object::Ptr RawObject, uint64_t &Radios_2G,
uint64_t &Radios_5G) {
bool ComputeAssociations(const Poco::JSON::Object::Ptr & RawObject,
uint64_t &Radios_2G,
uint64_t &Radios_5G, uint64_t &Radios_6G) {
Radios_2G = 0 ;
Radios_5G = 0;
Radios_6G = 0;
if(RawObject->isArray("radios") && RawObject->isArray("interfaces")) {
auto RA = RawObject->getArray("radios");
// map of phy to 2g/5g

View File

@@ -7,6 +7,6 @@
#include "Poco/JSON/Object.h"
namespace OpenWifi::StateUtils {
bool ComputeAssociations(const Poco::JSON::Object::Ptr RawObject, uint64_t &Radios_2G,
uint64_t &Radios_5G);
bool ComputeAssociations(const Poco::JSON::Object::Ptr & RawObject, uint64_t &Radios_2G,
uint64_t &Radios_5G, uint64_t &Radio_6G);
}

View File

@@ -11,6 +11,7 @@
#include "framework/StorageClass.h"
#include "RESTObjects//RESTAPI_GWobjects.h"
#include "Poco/Net/IPAddress.h"
#include "CentralConfig.h"
namespace OpenWifi {
@@ -84,6 +85,7 @@ namespace OpenWifi {
bool AddStatisticsData(const GWObjects::Statistics & Stats);
bool GetStatisticsData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, uint64_t Offset, uint64_t HowMany,
std::vector<GWObjects::Statistics> &Stats);
bool GetNumberOfStatisticsDataRecords(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, std::uint64_t &Count);
bool DeleteStatisticsData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate );
bool GetNewestStatisticsData(std::string &SerialNumber, uint64_t HowMany, std::vector<GWObjects::Statistics> &Stats);
@@ -97,7 +99,7 @@ namespace OpenWifi {
bool UpdateDeviceConfiguration(std::string &SerialNumber, std::string &Configuration, uint64_t & NewUUID );
bool CreateDevice(GWObjects::Device &);
bool CreateDefaultDevice(std::string & SerialNumber, std::string & Capabilities, std::string & Firmware, std::string &Compatible,const Poco::Net::IPAddress & IPAddress);
bool CreateDefaultDevice(std::string &SerialNumber, const Config::Capabilities &Caps, std::string & Firmware, const Poco::Net::IPAddress & IPAddress);
bool GetDevice(std::string &SerialNumber, GWObjects::Device &);
bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices, const std::string & orderBy="");
@@ -111,14 +113,14 @@ namespace OpenWifi {
bool GetDeviceFWUpdatePolicy(std::string & SerialNumber, std::string & Policy);
bool SetDevicePassword(std::string & SerialNumber, std::string & Password);
bool UpdateSerialNumberCache();
void GetDeviceDbFieldList( Types::StringVec & Fields);
static void GetDeviceDbFieldList( Types::StringVec & Fields);
bool ExistingConfiguration(std::string &SerialNumber, uint64_t CurrentConfig, std::string &NewConfig, uint64_t &);
bool UpdateDeviceCapabilities(std::string &SerialNumber, std::string &State, std::string & Compatible);
bool UpdateDeviceCapabilities(std::string &SerialNumber, const Config::Capabilities & Capabilities);
bool GetDeviceCapabilities(std::string &SerialNumber, GWObjects::Capabilities &);
bool DeleteDeviceCapabilities(std::string & SerialNumber);
bool CreateDeviceCapabilities(std::string & SerialNumber, std::string & Capabilities);
bool CreateDeviceCapabilities(std::string & SerialNumber, const Config::Capabilities & Capabilities);
bool InitCapabilitiesCache();
bool GetLogData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, uint64_t Offset, uint64_t HowMany,
@@ -144,9 +146,9 @@ namespace OpenWifi {
bool DeleteCommand( std::string &UUID );
bool GetReadyToExecuteCommands( uint64_t Offset, uint64_t HowMany, std::vector<GWObjects::CommandDetails> & Commands );
bool CommandExecuted(std::string & UUID);
bool CommandCompleted(std::string & UUID, const Poco::JSON::Object & ReturnVars, const std::chrono::duration<double, std::milli> & execution_time, bool FullCommand);
bool CommandCompleted(std::string & UUID, Poco::JSON::Object::Ptr ReturnVars, const std::chrono::duration<double, std::milli> & execution_time, bool FullCommand);
// bool AttachFileToCommand(std::string & UUID);
bool AttachFileDataToCommand(std::string & UUID, const std::stringstream &s);
bool AttachFileDataToCommand(std::string & UUID, const std::stringstream &s, const std::string &Type);
bool CancelWaitFile( std::string & UUID, std::string & ErrorText );
// bool GetAttachedFile(std::string & UUID, const std::string & SerialNumber, const std::string & FileName, std::string &Type);
bool GetAttachedFileContent(std::string & UUID, const std::string & SerialNumber, std::string & FileContent, std::string &Type);

View File

@@ -80,7 +80,7 @@ namespace OpenWifi {
void TelemetryClient::SendTelemetryShutdown() {
poco_information(Logger(),fmt::format("TELEMETRY-SHUTDOWN({}): Closing.",CId_));
DeRegister();
AP_WS_Server()->StopWebSocketTelemetry(CommandManager()->NextRPCId(), SerialNumber_);
AP_WS_Server()->StopWebSocketTelemetry(CommandManager()->Next_RPC_ID(), SerialNumber_);
TelemetryStream()->DeRegisterClient(UUID_);
}

View File

@@ -4,12 +4,13 @@
#include "UI_GW_WebSocketNotifications.h"
namespace OpenWifi {
inline void WebNotificationSingleDevice::to_json(Poco::JSON::Object &Obj) const {
namespace OpenWifi::GWWebSocketNotifications {
inline void SingleDevice::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber);
}
inline bool WebNotificationSingleDevice::from_json(const Poco::JSON::Object::Ptr &Obj) {
inline bool SingleDevice::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber);
return true;
@@ -19,13 +20,13 @@ namespace OpenWifi {
return false;
}
inline void WebNotificationSingleDeviceConfigurationChange::to_json(Poco::JSON::Object &Obj) const {
inline void SingleDeviceConfigurationChange::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber);
RESTAPI_utils::field_to_json(Obj,"oldUUID", oldUUID);
RESTAPI_utils::field_to_json(Obj,"newUUID", newUUID);
}
inline bool WebNotificationSingleDeviceConfigurationChange::from_json(const Poco::JSON::Object::Ptr &Obj) {
inline bool SingleDeviceConfigurationChange::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber);
RESTAPI_utils::field_from_json(Obj,"oldUUID", oldUUID);
@@ -37,12 +38,12 @@ namespace OpenWifi {
return false;
}
inline void WebNotificationSingleDeviceFirmwareChange::to_json(Poco::JSON::Object &Obj) const {
inline void SingleDeviceFirmwareChange::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber);
RESTAPI_utils::field_to_json(Obj,"newFirmware", newFirmware);
}
inline bool WebNotificationSingleDeviceFirmwareChange::from_json(const Poco::JSON::Object::Ptr &Obj) {
inline bool SingleDeviceFirmwareChange::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber);
RESTAPI_utils::field_from_json(Obj,"newFirmware", newFirmware);
@@ -53,13 +54,13 @@ namespace OpenWifi {
return false;
}
inline void WebSocketClientNotificationNumberOfConnection::to_json(Poco::JSON::Object &Obj) const {
inline void NumberOfConnection::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"numberOfDevices", numberOfDevices);
RESTAPI_utils::field_to_json(Obj,"averageConnectedTime", averageConnectedTime);
RESTAPI_utils::field_to_json(Obj,"numberOfConnectingDevices", numberOfConnectingDevices);
}
inline bool WebSocketClientNotificationNumberOfConnection::from_json(const Poco::JSON::Object::Ptr &Obj) {
inline bool NumberOfConnection::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"numberOfDevices", numberOfDevices);
RESTAPI_utils::field_from_json(Obj,"averageConnectedTime", averageConnectedTime);
@@ -71,64 +72,89 @@ namespace OpenWifi {
return false;
}
void WebSocketClientNotificationNumberOfConnections(WebSocketClientNotificationNumberOfConnection_t &N) {
N.type = "device_connections_statistics";
UI_WebSocketClientServer()->SendNotification(N);
}
void WebSocketClientNotificationNumberOfConnections(const std::string & User, WebSocketClientNotificationNumberOfConnection_t &N) {
N.type = "device_connections_statistics";
UI_WebSocketClientServer()->SendUserNotification(User,N);
}
void WebSocketClientNotificationDeviceConfigurationChange(WebNotificationSingleDeviceConfigurationChange_t &N) {
N.type = "device_configuration_upgrade";
void NumberOfConnections(NumberOfConnection_t &N) {
// N.type = "device_connections_statistics";
N.type_id = 1000 ;
UI_WebSocketClientServer()->SendNotification(N);
}
void WebSocketClientNotificationDeviceConfigurationChange(const std::string & User, WebNotificationSingleDeviceConfigurationChange_t &N) {
N.type = "device_configuration_upgrade";
void NumberOfConnections(const std::string & User, NumberOfConnection_t &N) {
// N.type = "device_connections_statistics";
N.type_id = 1000 ;
UI_WebSocketClientServer()->SendUserNotification(User,N);
}
void WebSocketClientNotificationDeviceFirmwareUpdated(WebNotificationSingleDeviceFirmwareChange_t &N) {
N.type = "device_firmware_upgrade";
void DeviceConfigurationChange(SingleDeviceConfigurationChange_t &N) {
// N.type = "device_configuration_upgrade";
N.type_id = 2000 ;
UI_WebSocketClientServer()->SendNotification(N);
}
void WebSocketClientNotificationDeviceFirmwareUpdated(const std::string & User, WebNotificationSingleDeviceFirmwareChange_t &N){
N.type = "device_firmware_upgrade";
void DeviceConfigurationChange(const std::string & User, SingleDeviceConfigurationChange_t &N) {
// N.type = "device_configuration_upgrade";
N.type_id = 2000 ;
UI_WebSocketClientServer()->SendUserNotification(User,N);
}
void WebSocketClientNotificationDeviceConnected(WebNotificationSingleDevice_t &N){
N.type = "device_connection";
void DeviceFirmwareUpdated(SingleDeviceFirmwareChange_t &N) {
// N.type = "device_firmware_upgrade";
N.type_id = 3000 ;
UI_WebSocketClientServer()->SendNotification(N);
}
void WebSocketClientNotificationDeviceConnected(const std::string & User, WebNotificationSingleDevice_t &N){
N.type = "device_connection";
void DeviceFirmwareUpdated(const std::string & User, SingleDeviceFirmwareChange_t &N){
// N.type = "device_firmware_upgrade";
N.type_id = 3000 ;
UI_WebSocketClientServer()->SendUserNotification(User,N);
}
void WebSocketClientNotificationDeviceDisconnected(const std::string & User, WebNotificationSingleDevice_t &N){
N.type = "device_disconnection";
UI_WebSocketClientServer()->SendUserNotification(User,N);
}
void WebSocketClientNotificationDeviceDisconnected(WebNotificationSingleDevice_t &N){
N.type = "device_disconnection";
void DeviceConnected(SingleDevice_t &N){
// N.type = "device_connection";
N.type_id = 4000 ;
UI_WebSocketClientServer()->SendNotification(N);
}
void WebSocketClientNotificationDeviceStatistics(const std::string & User, WebNotificationSingleDevice_t &N){
N.type = "device_statistics";
void DeviceConnected(const std::string & User, SingleDevice_t &N){
// N.type = "device_connection";
N.type_id = 4000 ;
UI_WebSocketClientServer()->SendUserNotification(User,N);
}
void WebSocketClientNotificationDeviceStatistics(WebNotificationSingleDevice_t &N){
N.type = "device_statistics";
void DeviceDisconnected(const std::string & User, SingleDevice_t &N){
// N.type = "device_disconnection";
N.type_id = 5000 ;
UI_WebSocketClientServer()->SendUserNotification(User,N);
}
void DeviceDisconnected(SingleDevice_t &N){
// N.type = "device_disconnection";
N.type_id = 5000 ;
UI_WebSocketClientServer()->SendNotification(N);
}
void DeviceStatistics(const std::string & User, SingleDevice_t &N){
// N.type = "device_statistics";
N.type_id = 6000 ;
UI_WebSocketClientServer()->SendUserNotification(User,N);
}
void DeviceStatistics(SingleDevice_t &N){
// N.type = "device_statistics";
N.type_id = 6000 ;
UI_WebSocketClientServer()->SendNotification(N);
}
void Register() {
static const UI_WebSocketClientServer::NotificationTypeIdVec Notifications = {
{ 1000, "device_connections_statistics" },
{ 2000, "device_configuration_upgrade" },
{ 3000, "device_firmware_upgrade" },
{ 4000, "device_connection" },
{ 5000, "device_disconnection" },
{ 6000, "device_statistics" }
};
UI_WebSocketClientServer()->RegisterNotifications(Notifications);
}
}

View File

@@ -7,14 +7,15 @@
#include "framework/UI_WebSocketClientNotifications.h"
#include "framework/UI_WebSocketClientServer.h"
namespace OpenWifi {
struct WebNotificationSingleDevice {
namespace OpenWifi::GWWebSocketNotifications {
struct SingleDevice {
std::string serialNumber;
inline void to_json(Poco::JSON::Object &Obj) const ;
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct WebNotificationSingleDeviceConfigurationChange {
struct SingleDeviceConfigurationChange {
std::string serialNumber;
uint64_t oldUUID;
uint64_t newUUID;
@@ -23,14 +24,14 @@ namespace OpenWifi {
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct WebNotificationSingleDeviceFirmwareChange {
struct SingleDeviceFirmwareChange {
std::string serialNumber;
std::string newFirmware;
inline void to_json(Poco::JSON::Object &Obj) const ;
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct WebSocketClientNotificationNumberOfConnection {
struct NumberOfConnection {
std::uint64_t numberOfDevices=0;
std::uint64_t averageConnectedTime=0;
std::uint64_t numberOfConnectingDevices=0;
@@ -39,23 +40,25 @@ namespace OpenWifi {
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef WebSocketNotification<WebNotificationSingleDevice> WebNotificationSingleDevice_t;
typedef WebSocketNotification<WebNotificationSingleDeviceConfigurationChange> WebNotificationSingleDeviceConfigurationChange_t;
typedef WebSocketNotification<WebNotificationSingleDeviceFirmwareChange> WebNotificationSingleDeviceFirmwareChange_t;
typedef WebSocketNotification<WebSocketClientNotificationNumberOfConnection> WebSocketClientNotificationNumberOfConnection_t;
void Register();
void WebSocketClientNotificationNumberOfConnections(WebSocketClientNotificationNumberOfConnection_t &N);
void WebSocketClientNotificationDeviceConfigurationChange(WebNotificationSingleDeviceConfigurationChange_t &N);
void WebSocketClientNotificationDeviceFirmwareUpdated(WebNotificationSingleDeviceFirmwareChange_t &);
void WebSocketClientNotificationDeviceConnected(WebNotificationSingleDevice_t &N);
void WebSocketClientNotificationDeviceDisconnected(WebNotificationSingleDevice_t &N);
void WebSocketClientNotificationDeviceStatistics(WebNotificationSingleDevice_t &N);
typedef WebSocketNotification<SingleDevice> SingleDevice_t;
typedef WebSocketNotification<SingleDeviceConfigurationChange> SingleDeviceConfigurationChange_t;
typedef WebSocketNotification<SingleDeviceFirmwareChange> SingleDeviceFirmwareChange_t;
typedef WebSocketNotification<NumberOfConnection> NumberOfConnection_t;
void WebSocketClientNotificationNumberOfConnections(const std::string & User, WebSocketClientNotificationNumberOfConnection_t &N);
void WebSocketClientNotificationDeviceConfigurationChange(const std::string & User, WebNotificationSingleDeviceConfigurationChange_t &N);
void WebSocketClientNotificationDeviceFirmwareUpdated(const std::string & User, WebNotificationSingleDeviceFirmwareChange_t &);
void WebSocketClientNotificationDeviceConnected(const std::string & User, WebNotificationSingleDevice_t &N);
void WebSocketClientNotificationDeviceDisconnected(const std::string & User, WebNotificationSingleDevice_t &N);
void WebSocketClientNotificationDeviceStatistics(const std::string & User, WebNotificationSingleDevice_t &N);
void NumberOfConnections(NumberOfConnection_t &N);
void DeviceConfigurationChange(SingleDeviceConfigurationChange_t &N);
void DeviceFirmwareUpdated(SingleDeviceFirmwareChange_t &);
void DeviceConnected(SingleDevice_t &N);
void DeviceDisconnected(SingleDevice_t &N);
void DeviceStatistics(SingleDevice_t &N);
void NumberOfConnections(const std::string & User, NumberOfConnection_t &N);
void DeviceConfigurationChange(const std::string & User, SingleDeviceConfigurationChange_t &N);
void DeviceFirmwareUpdated(const std::string & User, SingleDeviceFirmwareChange_t &);
void DeviceConnected(const std::string & User, SingleDevice_t &N);
void DeviceDisconnected(const std::string & User, SingleDevice_t &N);
void DeviceStatistics(const std::string & User, SingleDevice_t &N);
};

View File

@@ -7,6 +7,7 @@
#include "framework/AuthClient.h"
#include "framework/MicroServiceNames.h"
#include "framework/OpenAPIRequests.h"
#include "framework/utils.h"
#include "fmt/format.h"
namespace OpenWifi {
@@ -18,10 +19,13 @@ namespace OpenWifi {
try {
Types::StringPairVec QueryData;
QueryData.push_back(std::make_pair("token",SessionToken));
std::string AlternateURIForLogging = fmt::format("{}?token={}", Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken", Utils::SanitizeToken(SessionToken));
OpenAPIRequestGet Req( uSERVICE_SECURITY,
Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken",
QueryData,
10000);
10000,
AlternateURIForLogging
);
Poco::JSON::Object::Ptr Response;
auto StatusCode = Req.Do(Response);
@@ -46,7 +50,7 @@ namespace OpenWifi {
}
}
} catch (...) {
poco_error(Logger(),fmt::format("Failed to retrieve token={} for TID={}", SessionToken, TID));
poco_error(Logger(),fmt::format("Failed to retrieve token={} for TID={}", Utils::SanitizeToken(SessionToken), TID));
}
Expired = false;
return false;
@@ -59,6 +63,7 @@ namespace OpenWifi {
if(!User.isNull()) {
if(IsTokenExpired(User->webtoken)) {
Expired = true;
Cache_.remove(SessionToken);
return false;
}
Expired = false;
@@ -68,4 +73,57 @@ namespace OpenWifi {
return RetrieveTokenInformation(SessionToken, UInfo, TID, Expired, Contacted, Sub);
}
bool AuthClient::RetrieveApiKeyInformation(const std::string & SessionToken,
SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted) {
try {
Types::StringPairVec QueryData;
QueryData.push_back(std::make_pair("apikey",SessionToken));
std::string AlternateURIForLogging = fmt::format("/api/v1/validateApiKey?apiKey={}", Utils::SanitizeToken(SessionToken));
OpenAPIRequestGet Req( uSERVICE_SECURITY,
"/api/v1/validateApiKey" ,
QueryData,
10000,
AlternateURIForLogging);
Poco::JSON::Object::Ptr Response;
auto StatusCode = Req.Do(Response);
if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT) {
Contacted = false;
return false;
}
Contacted = true;
if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_OK) {
if(Response->has("tokenInfo") && Response->has("userInfo") && Response->has("expiresOn")) {
UInfo.from_json(Response);
Expired = false;
ApiKeyCache_.update(SessionToken, ApiKeyCacheEntry{ .UserInfo = UInfo, .ExpiresOn = Response->get("expiresOn")});
return true;
} else {
return false;
}
}
} catch (...) {
poco_error(Logger(),fmt::format("Failed to retrieve api key={} for TID={}", Utils::SanitizeToken(SessionToken), TID));
}
Expired = false;
return false;
}
bool AuthClient::IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy &UInfo,
std::uint64_t TID, bool &Expired, bool &Contacted) {
auto User = ApiKeyCache_.get(SessionToken);
if (!User.isNull()) {
if(User->ExpiresOn < Utils::Now()) {
Expired = false;
UInfo = User->UserInfo;
return true;
}
ApiKeyCache_.remove(SessionToken);
}
return RetrieveApiKeyInformation(SessionToken, UInfo, TID, Expired, Contacted);
}
} // namespace OpenWifi

View File

@@ -12,6 +12,7 @@
namespace OpenWifi {
class AuthClient : public SubSystemServer {
public:
explicit AuthClient() noexcept:
SubSystemServer("Authentication", "AUTH-CLNT", "authentication")
@@ -23,7 +24,12 @@ namespace OpenWifi {
return instance_;
}
inline int Start() override {
struct ApiKeyCacheEntry {
OpenWifi::SecurityObjects::UserInfoAndPolicy UserInfo;
std::uint64_t ExpiresOn;
};
inline int Start() override {
return 0;
}
@@ -36,6 +42,7 @@ namespace OpenWifi {
inline void RemovedCachedToken(const std::string &Token) {
Cache_.remove(Token);
ApiKeyCache_.remove(Token);
}
inline static bool IsTokenExpired(const SecurityObjects::WebToken &T) {
@@ -46,12 +53,24 @@ namespace OpenWifi {
SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool Sub=false);
bool RetrieveApiKeyInformation(const std::string & SessionToken,
SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted);
bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool Sub = false);
bool IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted);
private:
Poco::ExpireLRUCache<std::string,OpenWifi::SecurityObjects::UserInfoAndPolicy> Cache_{512,1200000 };
Poco::ExpireLRUCache<std::string,ApiKeyCacheEntry> ApiKeyCache_{512,1200000 };
};
inline auto AuthClient() { return AuthClient::instance(); }

View File

@@ -2632,7 +2632,7 @@ static json DefaultUCentralSchema = R"(
std::string GitSchema;
if(MicroServiceConfigGetBool("ucentral.datamodel.internal",true)) {
RootSchema_ = DefaultUCentralSchema;
Logger().information("Using uCentral validation from built-in default.");
poco_information(Logger(),"Using uCentral validation from built-in default.");
Initialized_ = Working_ = true;
return;
}
@@ -2641,7 +2641,7 @@ static json DefaultUCentralSchema = R"(
auto GitURI = MicroServiceConfigGetString("ucentral.datamodel.uri",GitUCentralJSONSchemaFile);
if(Utils::wgets(GitURI, GitSchema)) {
RootSchema_ = json::parse(GitSchema);
Logger().information("Using uCentral validation schema from GIT.");
poco_information(Logger(),"Using uCentral validation schema from GIT.");
} else {
std::string FileName{ MicroServiceDataDirectory() + "/ucentral.schema.json" };
std::ifstream input(FileName);
@@ -2649,11 +2649,11 @@ static json DefaultUCentralSchema = R"(
schema_file << input.rdbuf();
input.close();
RootSchema_ = json::parse(schema_file.str());
Logger().information("Using uCentral validation schema from local file.");
poco_information(Logger(),"Using uCentral validation schema from local file.");
}
} catch (const Poco::Exception &E) {
RootSchema_ = DefaultUCentralSchema;
Logger().information("Using uCentral validation from built-in default.");
poco_information(Logger(),"Using uCentral validation from built-in default.");
}
Initialized_ = Working_ = true;
}
@@ -2812,7 +2812,7 @@ static json DefaultUCentralSchema = R"(
}
void ConfigurationValidator::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
Logger().information("Reinitializing.");
poco_information(Logger(),"Reinitializing.");
Working_ = Initialized_ = false;
Init();
}

View File

@@ -8,6 +8,7 @@
#include "Poco/FormattingChannel.h"
#include "Poco/AsyncChannel.h"
#include "Poco/NullChannel.h"
#include "Poco/SplitterChannel.h"
#include "Poco/Net/HTTPStreamFactory.h"
#include "Poco/Net/HTTPSStreamFactory.h"
#include "Poco/Net/FTPSStreamFactory.h"
@@ -26,7 +27,7 @@
#include "framework/RESTAPI_ExtServer.h"
#include "framework/RESTAPI_IntServer.h"
#include "framework/utils.h"
#include "framework/WebSocketLogger.h"
namespace OpenWifi {
@@ -77,7 +78,7 @@ namespace OpenWifi {
else
SvcList += ", " + Svc.second.Type;
}
logger().information(fmt::format("Current list of microservices: {}", SvcList));
poco_information(logger(),fmt::format("Current list of microservices: {}", SvcList));
}
} else {
poco_error(logger(),fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",Event));
@@ -180,8 +181,6 @@ namespace OpenWifi {
MyHash_ = Utils::ComputeHash(MyPublicEndPoint_);
}
void MicroServicePostInitialization();
void MicroService::InitializeLoggingSystem() {
static auto initialized = false;
@@ -192,75 +191,143 @@ namespace OpenWifi {
auto LoggingDestination = MicroService::instance().ConfigGetString("logging.type", "file");
auto LoggingFormat = MicroService::instance().ConfigGetString("logging.format",
"%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t");
auto UseAsyncLogs_ = MicroService::instance().ConfigGetBool("logging.asynch",false);
auto UseAsyncLogs_ = MicroService::instance().ConfigGetBool("logging.asynch", true);
auto DisableWebSocketLogging = MicroService::instance().ConfigGetBool("logging.websocket",false);
if (LoggingDestination == "null") {
Poco::AutoPtr<Poco::NullChannel> DevNull(new Poco::NullChannel);
Poco::Logger::root().setChannel(DevNull);
} else if (LoggingDestination == "console") {
Poco::AutoPtr<Poco::ConsoleChannel> Console(new Poco::ConsoleChannel);
if(UseAsyncLogs_) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Console));
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", LoggingFormat);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
new Poco::FormattingChannel(Formatter, Async));
Poco::Logger::root().setChannel(FormattingChannel);
} else {
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", LoggingFormat);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
new Poco::FormattingChannel(Formatter, Console));
Poco::Logger::root().setChannel(FormattingChannel);
}
SetConsoleLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
} else if (LoggingDestination == "colorconsole") {
Poco::AutoPtr<Poco::ColorConsoleChannel> ColorConsole(new Poco::ColorConsoleChannel);
if(UseAsyncLogs_) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(ColorConsole));
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", LoggingFormat);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
new Poco::FormattingChannel(Formatter, Async));
Poco::Logger::root().setChannel(FormattingChannel);
} else {
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", LoggingFormat);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
new Poco::FormattingChannel(Formatter, ColorConsole));
Poco::Logger::root().setChannel(FormattingChannel);
}
SetColorConsoleLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
} else if (LoggingDestination == "sql") {
//"CREATE TABLE T_POCO_LOG (Source VARCHAR, Name VARCHAR, ProcessId INTEGER, Thread VARCHAR, ThreadId INTEGER, Priority INTEGER, Text VARCHAR, DateTime DATE)"
SetSQLLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
} else if (LoggingDestination == "syslog") {
SetSyslogLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
} else {
auto LoggingLocation =
MicroService::instance().ConfigPath("logging.path", "$OWCERT_ROOT/logs") + "/log";
SetFileLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat, DAEMON_ROOT_ENV_VAR);
}
Poco::AutoPtr<Poco::FileChannel> FileChannel(new Poco::FileChannel);
FileChannel->setProperty("rotation", "10 M");
FileChannel->setProperty("archive", "timestamp");
FileChannel->setProperty("path", LoggingLocation);
if(UseAsyncLogs_) {
Poco::AutoPtr<Poco::AsyncChannel> Async_File(
new Poco::AsyncChannel(FileChannel));
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", LoggingFormat);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
new Poco::FormattingChannel(Formatter, Async_File));
Poco::Logger::root().setChannel(FormattingChannel);
} else {
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", LoggingFormat);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
new Poco::FormattingChannel(Formatter, FileChannel));
Poco::Logger::root().setChannel(FormattingChannel);
}
}
auto Level = Poco::Logger::parseLevel(MicroService::instance().ConfigGetString("logging.level", "debug"));
Poco::Logger::root().setLevel(Level);
if(!DisableWebSocketLogging) {
static const UI_WebSocketClientServer::NotificationTypeIdVec Notifications = {
{1, "log"}};
UI_WebSocketClientServer()->RegisterNotifications(Notifications);
}
}
}
}
void MicroService::SetConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) {
Poco::AutoPtr<Poco::ConsoleChannel> Console(new Poco::ConsoleChannel);
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", FormatterPattern);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, Console));
if(DisableWebSocketLogging) {
if(UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(FormattingChannel));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(FormattingChannel);
}
} else {
Poco::AutoPtr<WebSocketLogger> WSLogger(new WebSocketLogger);
Poco::AutoPtr<Poco::SplitterChannel> Splitter(new Poco::SplitterChannel);
Splitter->addChannel(WSLogger);
Splitter->addChannel(FormattingChannel);
if(UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Splitter));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(Splitter);
}
}
}
void MicroService::SetColorConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) {
Poco::AutoPtr<Poco::ColorConsoleChannel> Console(new Poco::ColorConsoleChannel);
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", FormatterPattern);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, Console));
if(DisableWebSocketLogging) {
if(UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(FormattingChannel));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(FormattingChannel);
}
} else {
Poco::AutoPtr<WebSocketLogger> WSLogger(new WebSocketLogger);
Poco::AutoPtr<Poco::SplitterChannel> Splitter(new Poco::SplitterChannel);
Splitter->addChannel(WSLogger);
Splitter->addChannel(FormattingChannel);
if(UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Splitter));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(Splitter);
}
}
}
void MicroService::SetSQLLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]] bool DisableWebSocketLogging,[[maybe_unused]] const std::string & FormatterPattern) {
//"CREATE TABLE T_POCO_LOG (Source VARCHAR, Name VARCHAR, ProcessId INTEGER, Thread VARCHAR, ThreadId INTEGER, Priority INTEGER, Text VARCHAR, DateTime DATE)"
}
void MicroService::SetSyslogLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]] bool DisableWebSocketLogging,[[maybe_unused]] const std::string & FormatterPattern) {
}
void MicroService::SetFileLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern, const std::string & root_env_var) {
std::string DefaultLogPath = fmt::format("${}/logs",root_env_var);
auto LoggingLocationDir = MicroService::instance().ConfigPath("logging.path", DefaultLogPath);
Poco::File LD(LoggingLocationDir);
try {
if(!LD.exists()) {
LD.createDirectory();
}
} catch(const Poco::Exception &E) {
std::cout << "Cannot create " << LD.path() << " Error: " << E.message() << std::endl;
}
auto LoggingLocationDirFilePattern = LoggingLocationDir + "/log";
Poco::AutoPtr<Poco::FileChannel> FileChannel(new Poco::FileChannel);
FileChannel->setProperty("rotation", "10 M");
FileChannel->setProperty("archive", "timestamp");
FileChannel->setProperty("purgeCount", "10");
FileChannel->setProperty("path", LoggingLocationDirFilePattern);
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", FormatterPattern);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, FileChannel));
if(DisableWebSocketLogging) {
if(UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(FormattingChannel));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(FormattingChannel);
}
} else {
Poco::AutoPtr<WebSocketLogger> WSLogger(new WebSocketLogger);
Poco::AutoPtr<Poco::SplitterChannel> Splitter(new Poco::SplitterChannel);
Splitter->addChannel(WSLogger);
Splitter->addChannel(FormattingChannel);
if(UseAsync) {
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Splitter));
Poco::Logger::root().setChannel(Async);
} else {
Poco::Logger::root().setChannel(Splitter);
}
}
}
void DaemonPostInitialization(Poco::Util::Application &self);
@@ -590,15 +657,15 @@ namespace OpenWifi {
logger.notice(fmt::format("Starting {} version {}.",DAEMON_APP_NAME, Version()));
if(Poco::Net::Socket::supportsIPv6())
logger.information("System supports IPv6.");
poco_information(logger,"System supports IPv6.");
else
logger.information("System does NOT support IPv6.");
poco_information(logger,"System does NOT support IPv6.");
if (config().getBool("application.runAsDaemon", false)) {
logger.information("Starting as a daemon.");
poco_information(logger,"Starting as a daemon.");
}
logger.information(fmt::format("System ID set to {}",ID_));
poco_information(logger,fmt::format("System ID set to {}",ID_));
StartSubSystemServers();
waitForTerminationRequest();
StopSubSystemServers();
@@ -630,4 +697,15 @@ namespace OpenWifi {
}
}
void MicroService::DeleteOverrideConfiguration() {
Poco::File F(DataDir_ + ExtraConfigurationFilename);
try {
if(F.exists())
F.remove();
} catch (...) {
}
}
}

View File

@@ -55,7 +55,6 @@ namespace OpenWifi {
#include "nlohmann/json.hpp"
#include "ow_version.h"
#include "fmt/core.h"
#include "framework/MicroServiceErrorHandler.h"
#define _OWDEBUG_ std::cout<< __FILE__ <<":" << __LINE__ << std::endl;
// #define _OWDEBUG_ Logger().debug(Poco::format("%s: %lu",__FILE__,__LINE__));
@@ -82,6 +81,8 @@ namespace OpenWifi {
// Logger_ = Poco::Logger::root().get("BASE-SVC");
}
inline static const char * ExtraConfigurationFilename = "/configuration_override.json";
inline void SaveConfig() { PropConfigurationFile_->save(ConfigFileName_); }
inline auto UpdateConfig() { return PropConfigurationFile_; }
inline bool NoAPISecurity() const { return NoAPISecurity_; }
@@ -152,9 +153,17 @@ namespace OpenWifi {
int main(const ArgVec &args) override;
void InitializeLoggingSystem();
void DeleteOverrideConfiguration();
[[nodiscard]] std::string Sign(Poco::JWT::Token &T, const std::string &Algo);
void AddActivity(const std::string &Activity);
static void SetConsoleLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetColorConsoleLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetSQLLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetSyslogLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetFileLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern, const std::string & root_env_var);
private:
static MicroService * instance_;
bool HelpRequested_ = false;

View File

@@ -167,4 +167,4 @@ namespace OpenWifi {
int t_id=0;
};
}
}

View File

@@ -114,4 +114,8 @@ namespace OpenWifi {
std::string MicroServiceGetPublicAPIEndPoint() {
return MicroService::instance().GetPublicAPIEndPoint();
}
void MicroServiceDeleteOverrideConfiguration() {
return MicroService::instance().DeleteOverrideConfiguration();
}
}

View File

@@ -52,4 +52,5 @@ namespace OpenWifi {
std::uint64_t MicroServiceRandom(std::uint64_t Range);
std::string MicroServiceSign(Poco::JWT::Token &T, const std::string &Algo);
std::string MicroServiceGetPublicAPIEndPoint();
void MicroServiceDeleteOverrideConfiguration();
}

View File

@@ -33,7 +33,7 @@ namespace OpenWifi {
Path,
Poco::Net::HTTPMessage::HTTP_1_1);
poco_debug(Poco::Logger::get("REST-CALLER-GET"),fmt::format(" {}", URI.toString()));
poco_debug(Poco::Logger::get("REST-CALLER-GET"), fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
if(BearerToken.empty()) {
Request.add("X-API-KEY", Svc.AccessKey);
@@ -91,7 +91,7 @@ namespace OpenWifi {
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
poco_debug(Poco::Logger::get("REST-CALLER-PUT"),fmt::format("{}", URI.toString()));
poco_debug(Poco::Logger::get("REST-CALLER-PUT"), fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
std::string Path(URI.getPathAndQuery());
@@ -170,7 +170,7 @@ namespace OpenWifi {
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
poco_debug(Poco::Logger::get("REST-CALLER-POST"),fmt::format(" {}", URI.toString()));
poco_debug(Poco::Logger::get("REST-CALLER-POST"),fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
std::string Path(URI.getPathAndQuery());
@@ -246,7 +246,7 @@ namespace OpenWifi {
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
poco_debug(Poco::Logger::get("REST-CALLER-DELETE"),fmt::format(" {}", URI.toString()));
poco_debug(Poco::Logger::get("REST-CALLER-DELETE"),fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
std::string Path(URI.getPathAndQuery());

View File

@@ -18,17 +18,20 @@ namespace OpenWifi {
explicit OpenAPIRequestGet( const std::string & Type,
const std::string & EndPoint,
const Types::StringPairVec & QueryData,
uint64_t msTimeout):
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout) {};
msTimeout_(msTimeout),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
private:
std::string Type_;
std::string EndPoint_;
Types::StringPairVec QueryData_;
uint64_t msTimeout_;
std::string LoggingStr_;
};
class OpenAPIRequestPut {
@@ -37,12 +40,14 @@ namespace OpenWifi {
const std::string & EndPoint,
const Types::StringPairVec & QueryData,
const Poco::JSON::Object & Body,
uint64_t msTimeout):
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout),
Body_(Body){};
Body_(Body),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
@@ -52,6 +57,7 @@ namespace OpenWifi {
Types::StringPairVec QueryData_;
uint64_t msTimeout_;
Poco::JSON::Object Body_;
std::string LoggingStr_;
};
class OpenAPIRequestPost {
@@ -60,12 +66,14 @@ namespace OpenWifi {
const std::string & EndPoint,
const Types::StringPairVec & QueryData,
const Poco::JSON::Object & Body,
uint64_t msTimeout):
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout),
Body_(Body){};
Body_(Body),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
private:
std::string Type_;
@@ -73,18 +81,21 @@ namespace OpenWifi {
Types::StringPairVec QueryData_;
uint64_t msTimeout_;
Poco::JSON::Object Body_;
std::string LoggingStr_;
};
class OpenAPIRequestDelete {
public:
explicit OpenAPIRequestDelete( const std::string & Type,
const std::string & EndPoint,
const Types::StringPairVec & QueryData,
uint64_t msTimeout):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout){};
explicit OpenAPIRequestDelete( const std::string & Type,
const std::string & EndPoint,
const Types::StringPairVec & QueryData,
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(const std::string & BearerToken = "");
private:
@@ -93,6 +104,7 @@ namespace OpenWifi {
Types::StringPairVec QueryData_;
uint64_t msTimeout_;
Poco::JSON::Object Body_;
std::string LoggingStr_;
};
} // namespace OpenWifi

View File

@@ -30,15 +30,15 @@ namespace OpenWifi {
}
inline int Start() override {
Logger().information("Starting.");
poco_information(Logger(),"Starting.");
Server_.InitLogging();
for(const auto & Svr: ConfigServersList_) {
if(MicroServiceNoAPISecurity()) {
Logger().information(fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
poco_information(Logger(),fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
} else {
Logger().information(fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
poco_information(Logger(),fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
Svr.KeyFile(),Svr.CertFile()));
Svr.LogCert(Logger());
if (!Svr.RootCA().empty())
@@ -64,18 +64,18 @@ namespace OpenWifi {
}
inline void Stop() override {
Logger().information("Stopping...");
poco_information(Logger(),"Stopping...");
for( const auto & svr : RESTServers_ )
svr->stopAll(true);
Pool_.stopAll();
Pool_.joinAll();
RESTServers_.clear();
Logger().information("Stopped...");
poco_information(Logger(),"Stopped...");
}
inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
MicroServiceLoadConfigurationFile();
Logger().information("Reinitializing.");
poco_information(Logger(),"Reinitializing.");
Stop();
Start();
}

View File

@@ -26,6 +26,10 @@
#include "framework/AuthClient.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#if defined(TIP_SECURITY_SERVICE)
#include "AuthService.h"
#endif
using namespace std::chrono_literals;
namespace OpenWifi {
@@ -388,7 +392,7 @@ namespace OpenWifi {
std::ostream &Answer = Response->send();
Poco::JSON::Stringifier::stringify(ErrorObject, Answer);
poco_debug(Logger_,fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}",
UserInfo_.userinfo.email,
Requester(),
Utils::FormatIPv6(Request->clientAddress().toString()),
Request->getMethod(),
Request->getURI()));
@@ -546,6 +550,27 @@ namespace OpenWifi {
Poco::JSON::Stringifier::stringify(Object, Answer);
}
inline void ReturnRawJSON(const std::string &json_doc) {
PrepareResponse();
if(Request!= nullptr) {
// can we compress ???
auto AcceptedEncoding = Request->find("Accept-Encoding");
if(AcceptedEncoding!=Request->end()) {
if( AcceptedEncoding->second.find("gzip")!=std::string::npos ||
AcceptedEncoding->second.find("compress")!=std::string::npos) {
Response->set("Content-Encoding", "gzip");
std::ostream &Answer = Response->send();
Poco::DeflatingOutputStream deflater(Answer, Poco::DeflatingStreamBuf::STREAM_GZIP);
deflater << json_doc;
deflater.close();
return;
}
}
}
std::ostream &Answer = Response->send();
Answer << json_doc;
}
inline void ReturnCountOnly(uint64_t Count) {
Poco::JSON::Object Answer;
Answer.set("count", Count);
@@ -640,7 +665,8 @@ namespace OpenWifi {
};
#ifdef TIP_SECURITY_SERVICE
[[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired , bool Sub );
[[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired , bool Sub );
#endif
inline bool RESTAPIHandler::IsAuthorized( bool & Expired , [[maybe_unused]] bool & Contacted , bool Sub ) {
if(Internal_ && Request->has("X-INTERNAL-NAME")) {
@@ -665,7 +691,36 @@ namespace OpenWifi {
}
}
return Allowed;
} else {
} else if(!Internal_ && Request->has("X-API-KEY")) {
SessionToken_ = Request->get("X-API-KEY", "");
#ifdef TIP_SECURITY_SERVICE
std::uint64_t expiresOn;
if (AuthService()->IsValidApiKey(SessionToken_, UserInfo_.webtoken, UserInfo_.userinfo, Expired, expiresOn)) {
#else
if (AuthClient()->IsValidApiKey( SessionToken_, UserInfo_, TransactionId_, Expired, Contacted)) {
#endif
REST_Requester_ = UserInfo_.userinfo.email;
if(Server_.LogIt(Request->getMethod(),true)) {
poco_debug(Logger_,fmt::format("X-REQ-ALLOWED({}): APIKEY-ACCESS TID={} User='{}@{}' Method={} Path={}",
UserInfo_.userinfo.email,
TransactionId_,
Utils::FormatIPv6(Request->clientAddress().toString()),
Request->clientAddress().toString(),
Request->getMethod(),
Request->getURI()));
}
return true;
} else {
if(Server_.LogBadTokens(true)) {
poco_debug(Logger_,fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}",
Utils::FormatIPv6(Request->clientAddress().toString()),
TransactionId_,
Request->getMethod(),
Request->getURI()));
}
}
return false;
} else {
if (SessionToken_.empty()) {
try {
Poco::Net::OAuth20Credentials Auth(*Request);

View File

@@ -30,15 +30,15 @@ namespace OpenWifi {
}
inline int Start() override {
Logger().information("Starting.");
poco_information(Logger(),"Starting.");
Server_.InitLogging();
for(const auto & Svr: ConfigServersList_) {
if(MicroServiceNoAPISecurity()) {
Logger().information(fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
poco_information(Logger(),fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
} else {
Logger().information(fmt::format("Starting: {}:{}. Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
poco_information(Logger(),fmt::format("Starting: {}:{}. Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
Svr.KeyFile(),Svr.CertFile()));
Svr.LogCert(Logger());
if (!Svr.RootCA().empty())
@@ -65,17 +65,17 @@ namespace OpenWifi {
}
inline void Stop() override {
Logger().information("Stopping...");
poco_information(Logger(),"Stopping...");
for( const auto & svr : RESTServers_ )
svr->stopAll(true);
Pool_.stopAll();
Pool_.joinAll();
Logger().information("Stopped...");
poco_information(Logger(),"Stopped...");
}
inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
MicroServiceLoadConfigurationFile();
Logger().information("Reinitializing.");
poco_information(Logger(),"Reinitializing.");
Stop();
Start();
}

View File

@@ -88,7 +88,7 @@ namespace OpenWifi {
auto Name = GetS(RESTAPI::Protocol::TAG, InnerObj);
auto Value = GetS(RESTAPI::Protocol::VALUE, InnerObj);
MicroServiceSetSubsystemLogLevel(Name, Value);
Logger_.information(
poco_information(Logger_,
fmt::format("Setting log level for {} at {}", Name, Value));
}
}

View File

@@ -0,0 +1,52 @@
//
// Created by stephane bourque on 2022-10-31.
//
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "framework/MicroServiceFuncs.h"
using namespace std::chrono_literals;
namespace OpenWifi {
class RESTAPI_system_configuration : public RESTAPIHandler {
public:
RESTAPI_system_configuration(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/systemConfiguration"}; }
inline void DoPost() final {}
inline void DoGet() final {
return OK();
}
inline void DoPut() final{
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
return OK();
};
inline void DoDelete() final{
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
MicroServiceDeleteOverrideConfiguration();
return OK();
};
};
}

View File

@@ -16,7 +16,7 @@ namespace OpenWifi {
inline RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{ Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal,false) {}
static auto PathName() { return std::list<std::string>{"/api/v1/ws"};}
void DoGet() final {
@@ -27,7 +27,7 @@ namespace OpenWifi {
{
Poco::Net::WebSocket WS(*Request, *Response);
auto Id = MicroServiceCreateUUID();
UI_WebSocketClientServer()->NewClient(WS,Id,UserInfo_.userinfo.email);
UI_WebSocketClientServer()->NewClient(WS,Id,UserInfo_.userinfo.email, TransactionId_);
}
catch (...) {
std::cout << "Cannot create websocket client..." << std::endl;

View File

@@ -23,7 +23,7 @@ namespace OpenWifi {
}
void onPrivateKeyRequested([[maybe_unused]] const void * pSender,std::string & privateKey) {
Logger_.information("Returning key passphrase.");
poco_information(Logger_,"Returning key passphrase.");
privateKey = Password_;
};
inline Poco::Logger & Logger() { return Logger_; }
@@ -83,7 +83,7 @@ namespace OpenWifi {
inline void uninitialize() override {
}
inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
Logger_->L_.information("Reloading of this subsystem is not supported.");
poco_information(Logger_->L_,"Reloading of this subsystem is not supported.");
}
inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override {
}

View File

@@ -10,11 +10,12 @@
namespace OpenWifi {
template<typename ContentStruct>
struct WebSocketNotification {
inline static uint64_t xid = 1;
uint64_t notification_id = ++xid;
std::string type;
ContentStruct content;
uint64_t notification_id = ++xid;
std::uint64_t type_id=0;
ContentStruct content;
void to_json(Poco::JSON::Object &Obj) const;
@@ -24,7 +25,7 @@ namespace OpenWifi {
template<typename ContentStruct>
void WebSocketNotification<ContentStruct>::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj, "notification_id", notification_id);
RESTAPI_utils::field_to_json(Obj, "type", type);
RESTAPI_utils::field_to_json(Obj, "type_id", type_id);
RESTAPI_utils::field_to_json(Obj, "content", content);
}
@@ -32,8 +33,8 @@ namespace OpenWifi {
bool WebSocketNotification<ContentStruct>::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj, "notification_id", notification_id);
RESTAPI_utils::field_from_json(Obj, "content", content);
RESTAPI_utils::field_from_json(Obj, "type", type);
RESTAPI_utils::field_from_json(Obj, "type_id", type_id);
RESTAPI_utils::field_from_json(Obj, "content", content);
return true;
} catch (...) {

View File

@@ -15,16 +15,20 @@
#include "fmt/format.h"
#if defined(TIP_SECURITY_SERVICE)
#include "AuthService.h"
#endif
#define DBG { std::cout << __LINE__ << std::endl; }
namespace OpenWifi {
void UI_WebSocketClientServer::NewClient(Poco::Net::WebSocket & WS, const std::string &Id, const std::string &UserName ) {
void UI_WebSocketClientServer::NewClient(Poco::Net::WebSocket & WS, const std::string &Id, const std::string &UserName, std::uint64_t TID ) {
std::lock_guard G(Mutex_);
std::lock_guard G(LocalMutex_);
auto Client = std::make_unique<UI_WebSocketClientInfo>(WS,Id, UserName);
auto ClientSocket = Client->WS_->impl()->sockfd();
TID_ = TID;
Client->WS_->setNoDelay(true);
Client->WS_->setKeepAlive(true);
Client->WS_->setBlocking(false);
@@ -39,6 +43,7 @@ namespace OpenWifi {
*this, &UI_WebSocketClientServer::OnSocketError));
Client->SocketRegistered_ = true;
Clients_[ClientSocket] = std::move(Client);
UsersConnected_ = Clients_.size();
}
void UI_WebSocketClientServer::SetProcessor( UI_WebSocketClientProcessor * F) {
@@ -50,10 +55,28 @@ namespace OpenWifi {
{
}
void UI_WebSocketClientServer::EndConnection([[maybe_unused]] std::lock_guard<std::recursive_mutex> &G, ClientList::iterator &Client) {
void UI_WebSocketClientServer::run() {
Running_ = true;
while(Running_) {
Poco::Thread::trySleep(2000);
if(!Running_)
break;
std::lock_guard G(LocalMutex_);
for(const auto i:ToBeRemoved_) {
// std::cout << "Erasing old WS UI connection..." << std::endl;
Clients_.erase(i);
}
ToBeRemoved_.clear();
UsersConnected_ = Clients_.size();
}
}
void UI_WebSocketClientServer::EndConnection(ClientList::iterator Client) {
if(Client->second->SocketRegistered_) {
Client->second->SocketRegistered_ = false;
(*Client->second->WS_).shutdown();
Reactor_.removeEventHandler(*Client->second->WS_,
Poco::NObserver<UI_WebSocketClientServer,
Poco::Net::ReadableNotification>(*this,&UI_WebSocketClientServer::OnSocketReadable));
@@ -64,27 +87,17 @@ namespace OpenWifi {
Poco::NObserver<UI_WebSocketClientServer,
Poco::Net::ErrorNotification>(*this,&UI_WebSocketClientServer::OnSocketError));
}
Clients_.erase(Client);
std::cout << "How many clients: " << Clients_.size() << std::endl;
ToBeRemoved_.push_back(Client);
}
void UI_WebSocketClientServer::run() {
Running_ = true ;
Utils::SetThreadName("ws:uiclnt-svr");
while(Running_) {
Poco::Thread::trySleep(2000);
if(!Running_)
break;
}
};
int UI_WebSocketClientServer::Start() {
poco_information(Logger(),"Starting...");
GoogleApiKey_ = MicroServiceConfigGetString("google.apikey","");
GeoCodeEnabled_ = !GoogleApiKey_.empty();
ReactorThread_.start(Reactor_);
Thr_.start(*this);
ReactorThread_.setName("ws:ui-reactor");
CleanerThread_.start(*this);
CleanerThread_.setName("ws:ui-cleaner");
return 0;
};
@@ -95,45 +108,43 @@ namespace OpenWifi {
Reactor_.stop();
ReactorThread_.join();
Running_ = false;
Thr_.wakeUp();
Thr_.join();
CleanerThread_.wakeUp();
CleanerThread_.join();
poco_information(Logger(),"Stopped...");
}
};
bool UI_WebSocketClientServer::SendToId(const std::string &Id, const std::string &Payload) {
std::lock_guard G(Mutex_);
for(const auto &Client:Clients_) {
if(Client.second->Id_==Id)
return Client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size());
}
return false;
bool UI_WebSocketClientServer::IsFiltered(std::uint64_t id, const OpenWifi::UI_WebSocketClientInfo &Client) {
return std::find(Client.Filter_.begin(), Client.Filter_.end(),id)!=end(Client.Filter_);
}
bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, const std::string &Payload) {
bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, std::uint64_t id, const std::string &Payload) {
std::lock_guard G(Mutex_);
uint64_t Sent=0;
for(const auto &client:Clients_) {
if(client.second->UserName_ == UserName) {
for(const auto &Client:Clients_) {
if(Client.second->UserName_ == UserName) {
try {
if (client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size()))
Sent++;
if(!IsFiltered(id,*Client.second) && Client.second->Authenticated_) {
return Client.second->WS_->sendFrame(
Payload.c_str(), (int)Payload.size()) == (int)Payload.size();
} else {
return false;
}
} catch (...) {
return false;
}
}
}
return Sent>0;
return false;
}
void UI_WebSocketClientServer::SendToAll(const std::string &Payload) {
void UI_WebSocketClientServer::SendToAll(std::uint64_t id, const std::string &Payload) {
std::lock_guard G(Mutex_);
for(const auto &client:Clients_) {
for(const auto &Client:Clients_) {
try {
client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size());
if(!IsFiltered(id,*Client.second) && Client.second->Authenticated_)
Client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size());
} catch (...) {
}
@@ -144,12 +155,35 @@ namespace OpenWifi {
return Clients_.find(ClientSocket);
}
void UI_WebSocketClientServer::SortNotifications() {
struct {
bool operator()(const NotificationEntry &A, const NotificationEntry & B) const {
return A.id < B.id; };
} CompareNotifications;
std::sort(NotificationTypes_.begin(), NotificationTypes_.end(), CompareNotifications);
NotificationTypesJSON_.clear();
Poco::JSON::Array AllNotifications;
for(const auto &notification:NotificationTypes_) {
Poco::JSON::Object Notification;
Notification.set("id", notification.id);
Notification.set("helper", notification.helper);
AllNotifications.add(Notification);
}
NotificationTypesJSON_.set("notificationTypes", AllNotifications);
}
void UI_WebSocketClientServer::RegisterNotifications(const OpenWifi::UI_WebSocketClientServer::NotificationTypeIdVec &Notifications) {
std::copy(Notifications.begin(), Notifications.end(), std::back_inserter(NotificationTypes_));
SortNotifications();
}
void UI_WebSocketClientServer::OnSocketError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
std::lock_guard G(LocalMutex_);
auto Client = FindWSClient(G,pNf->socket().impl()->sockfd());
auto Client = Clients_.find(pNf->socket().impl()->sockfd());
if(Client==end(Clients_))
return;
EndConnection(G,Client);
EndConnection(Client);
}
void UI_WebSocketClientServer::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
@@ -160,7 +194,7 @@ namespace OpenWifi {
try {
Client = FindWSClient(G,pNf->socket().impl()->sockfd());
Client = Clients_.find(pNf->socket().impl()->sockfd());
if( Client == end(Clients_))
return;
@@ -172,7 +206,7 @@ namespace OpenWifi {
if (n == 0) {
poco_debug(Logger(),fmt::format("CLOSE({}): {} UI Client is closing WS connection.", Client->second->Id_, Client->second->UserName_));
return EndConnection(G, Client);
return EndConnection(Client);
}
switch (Op) {
@@ -185,32 +219,56 @@ namespace OpenWifi {
} break;
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
poco_debug(Logger(),fmt::format("CLOSE({}): {} UI Client is closing WS connection.", Client->second->Id_, Client->second->UserName_));
return EndConnection(G, Client);
return EndConnection(Client);
} break;
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
constexpr const char *DropMessagesCommand = "drop-notifications";
IncomingFrame.append(0);
if (!Client->second->Authenticated_) {
std::string Frame{IncomingFrame.begin()};
auto Tokens = Utils::Split(Frame, ':');
bool Expired = false, Contacted = false;
bool Expired = false;
#if not defined(TIP_SECURITY_SERVICE)
bool Contacted = false;
#endif
if (Tokens.size() == 2 &&
AuthClient()->IsAuthorized(Tokens[1], Client->second->UserInfo_, 0, Expired, Contacted)) {
#if defined(TIP_SECURITY_SERVICE)
AuthService()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_, Expired)) {
#else
AuthClient()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_, Expired, Contacted)) {
#endif
Client->second->Authenticated_ = true;
Client->second->UserName_ = Client->second->UserInfo_.userinfo.email;
poco_debug(Logger(),fmt::format("START({}): {} UI Client is starting WS connection.", Client->second->Id_, Client->second->UserName_));
std::string S{"Welcome! Bienvenue! Bienvenidos!"};
Client->second->WS_->sendFrame(S.c_str(), S.size());
auto WelcomeMessage = NotificationTypesJSON_;
WelcomeMessage.set("success", "Welcome! Bienvenue! Bienvenidos!");
std::ostringstream OS;
WelcomeMessage.stringify(OS);
Client->second->WS_->sendFrame(OS.str().c_str(), (int) OS.str().size());
Client->second->UserName_ = Client->second->UserInfo_.userinfo.email;
} else {
std::string S{"Invalid token. Closing connection."};
Client->second->WS_->sendFrame(S.c_str(), S.size());
return EndConnection(G, Client);
Poco::JSON::Object WelcomeMessage;
WelcomeMessage.set("error", "Invalid token. Closing connection.");
std::ostringstream OS;
WelcomeMessage.stringify(OS);
Client->second->WS_->sendFrame(OS.str().c_str(), (int) OS.str().size());
return EndConnection(Client);
}
} else {
Poco::JSON::Parser P;
auto Obj =
P.parse(IncomingFrame.begin()).extract<Poco::JSON::Object::Ptr>();
if(Obj->has(DropMessagesCommand) && Obj->isArray(DropMessagesCommand)) {
auto Filters = Obj->getArray(DropMessagesCommand);
Client->second->Filter_.clear();
for(const auto &Filter:*Filters) {
Client->second->Filter_.emplace_back( (std::uint64_t) Filter);
}
std::sort(begin(Client->second->Filter_),end(Client->second->Filter_));
return;
}
std::string Answer;
bool CloseConnection=false;
if (Processor_ != nullptr) {
@@ -223,7 +281,7 @@ namespace OpenWifi {
}
if(CloseConnection) {
return EndConnection(G, Client);
return EndConnection(Client);
}
}
} break;
@@ -231,18 +289,16 @@ namespace OpenWifi {
}
}
} catch (...) {
return EndConnection(G, Client);
return EndConnection(Client);
}
}
void UI_WebSocketClientServer::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
ClientList::iterator Client;
std::lock_guard G(LocalMutex_);
try {
Client = FindWSClient(G, pNf->socket().impl()->sockfd());
auto Client = Clients_.find(pNf->socket().impl()->sockfd());
if (Client == end(Clients_))
return;
EndConnection(G, Client);
EndConnection(Client);
} catch (...) {
}

View File

@@ -19,8 +19,6 @@
namespace OpenWifi {
class UI_WebSocketClient;
class UI_WebSocketClientProcessor {
public:
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done ) = 0;
@@ -33,6 +31,7 @@ namespace OpenWifi {
std::string UserName_;
bool Authenticated_ = false;
bool SocketRegistered_=false;
std::vector<std::uint64_t> Filter_;
SecurityObjects::UserInfoAndPolicy UserInfo_;
UI_WebSocketClientInfo(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &username) {
@@ -50,11 +49,15 @@ namespace OpenWifi {
return instance_;
}
bool IsAnyoneConnected() {
return UsersConnected_;
}
int Start() override;
void Stop() override;
void run() override;
Poco::Net::SocketReactor & Reactor() { return Reactor_; }
void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName);
void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName, std::uint64_t TID);
void SetProcessor(UI_WebSocketClientProcessor *F);
[[nodiscard]] inline bool GeoCodeEnabled() const { return GeoCodeEnabled_; }
[[nodiscard]] inline std::string GoogleApiKey() const { return GoogleApiKey_; }
@@ -69,7 +72,7 @@ namespace OpenWifi {
std::ostringstream OO;
Msg.stringify(OO);
return SendToUser(userName,OO.str());
return SendToUser(userName, Notification.type_id, OO.str());
}
template <typename T> void SendNotification(const WebSocketNotification<T> &Notification) {
@@ -79,26 +82,41 @@ namespace OpenWifi {
Msg.set("notification",Payload);
std::ostringstream OO;
Msg.stringify(OO);
SendToAll(OO.str());
SendToAll(Notification.type_id, OO.str());
}
[[nodiscard]] bool SendToId(const std::string &Id, const std::string &Payload);
[[nodiscard]] bool SendToUser(const std::string &userName, const std::string &Payload);
void SendToAll(const std::string &Payload);
[[nodiscard]] bool SendToUser(const std::string &userName, std::uint64_t id, const std::string &Payload);
void SendToAll(std::uint64_t id, const std::string &Payload);
struct NotificationEntry {
std::uint64_t id=0;
std::string helper;
};
using ClientList = std::map<int,std::unique_ptr<UI_WebSocketClientInfo>>;
using NotificationTypeIdVec = std::vector<NotificationEntry>;
void RegisterNotifications(const NotificationTypeIdVec & Notifications);
bool IsFiltered(std::uint64_t id, const UI_WebSocketClientInfo &Client);
private:
mutable std::atomic_bool Running_ = false;
Poco::Thread Thr_;
volatile bool Running_ = false;
std::atomic_uint64_t UsersConnected_=0;
Poco::Net::SocketReactor Reactor_;
Poco::Thread ReactorThread_;
Poco::Thread CleanerThread_;
std::recursive_mutex LocalMutex_;
bool GeoCodeEnabled_ = false;
std::string GoogleApiKey_;
ClientList Clients_;
bool GeoCodeEnabled_ = false;
std::string GoogleApiKey_;
ClientList Clients_;
UI_WebSocketClientProcessor *Processor_ = nullptr;
NotificationTypeIdVec NotificationTypes_;
Poco::JSON::Object NotificationTypesJSON_;
std::vector<ClientList::iterator> ToBeRemoved_;
std::uint64_t TID_=0;
UI_WebSocketClientServer() noexcept;
void EndConnection(std::lock_guard<std::recursive_mutex> &G, ClientList::iterator & Client);
void EndConnection(ClientList::iterator Client);
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf);
@@ -106,7 +124,7 @@ namespace OpenWifi {
ClientList::iterator FindWSClient( std::lock_guard<std::recursive_mutex> &G, int ClientSocket);
void SortNotifications();
};
inline auto UI_WebSocketClientServer() { return UI_WebSocketClientServer::instance(); }

View File

@@ -5,29 +5,39 @@
#pragma once
#include "framework/SubSystemServer.h"
#include "framework/UI_WebSocketClientServer.h"
#include "framework/UI_WebSocketClientNotifications.h"
namespace OpenWifi {
class WebSocketLogger : public Poco::Channel {
public:
inline std::string getProperty( [[maybe_unused]] const std::string &p ) const final {
WebSocketLogger() {
}
~WebSocketLogger() {
}
std::string getProperty( [[maybe_unused]] const std::string &p ) const {
std::cout << "WS getProperty" << std::endl;
return "";
}
inline void close() final {
void close() final {
}
inline void open() final {
void open() final {
}
inline static std::string to_string(Poco::Message::Priority p) {
static std::string to_string(Poco::Message::Priority p) {
switch(p) {
case Poco::Message::PRIO_INFORMATION: return "information";
case Poco::Message::PRIO_CRITICAL: return "critical";
case Poco::Message::PRIO_DEBUG: return "debug";
case Poco::Message::PRIO_ERROR: return "error";
case Poco::Message::PRIO_FATAL: return "level";
case Poco::Message::PRIO_FATAL: return "fatal";
case Poco::Message::PRIO_NOTICE: return "notice";
case Poco::Message::PRIO_TRACE: return "trace";
case Poco::Message::PRIO_WARNING: return "warning";
@@ -35,55 +45,63 @@ namespace OpenWifi {
}
}
inline void log(const Poco::Message &m) final {
if(Enabled_) {
/*
nlohmann::json log_msg;
log_msg["msg"] = m.getText();
log_msg["level"] = to_string(m.getPriority());
log_msg["timestamp"] = Poco::DateTimeFormatter::format(m.getTime(), Poco::DateTimeFormat::ISO8601_FORMAT);
log_msg["source"] = m.getSource();
log_msg["thread_name"] = m.getThread();
log_msg["thread_id"] = m.getTid();
struct NotificationLogMessage {
std::string msg;
std::string level;
std::uint64_t timestamp;
std::string source;
std::string thread_name;
std::uint64_t thread_id=0;
inline void to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"msg", msg);
RESTAPI_utils::field_to_json(Obj,"level", level);
RESTAPI_utils::field_to_json(Obj,"timestamp", timestamp);
RESTAPI_utils::field_to_json(Obj,"source", source);
RESTAPI_utils::field_to_json(Obj,"thread_name", thread_name);
RESTAPI_utils::field_to_json(Obj,"thread_id", thread_id);
}
inline bool from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj, "msg", msg);
RESTAPI_utils::field_from_json(Obj, "level", level);
RESTAPI_utils::field_from_json(Obj, "timestamp", timestamp);
RESTAPI_utils::field_from_json(Obj, "source", source);
RESTAPI_utils::field_from_json(Obj, "thread_name", thread_name);
RESTAPI_utils::field_from_json(Obj, "thread_id", thread_id);
return true;
} catch(...) {
std::cout << log_msg << std::endl;
*/
std::lock_guard G(Mutex_);
std::vector<uint64_t> Remove;
for(const auto &[Id,CallBack]:CallBacks_) {
try {
CallBack(m);
} catch (...) {
Remove.push_back(Id);
}
}
for(const auto &i:Remove)
CallBacks_.erase(i);
return false;
}
};
typedef WebSocketNotification<NotificationLogMessage> WebSocketClientNotificationLogMessage_t;
void log(const Poco::Message &m) final {
if(UI_WebSocketClientServer()->IsAnyoneConnected()) {
WebSocketClientNotificationLogMessage_t Msg;
Msg.content.msg = m.getText();
Msg.content.level = WebSocketLogger::to_string(m.getPriority());
Msg.content.timestamp = m.getTime().epochTime();
Msg.content.source = m.getSource();
Msg.content.thread_name = m.getThread();
Msg.content.thread_id = m.getTid();
Msg.type_id = 1;
UI_WebSocketClientServer()->SendNotification(Msg);
}
}
inline void setProperty([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) final {
void setProperty([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) {
std::cout << "WS setProperty" << std::endl;
}
inline static auto instance() {
static auto instance_ = new WebSocketLogger;
return instance_;
}
inline void Enable(bool enable) { Enabled_ = enable; }
typedef std::function<void(const Poco::Message &M)> logmuxer_callback_func_t;
inline void RegisterCallback(const logmuxer_callback_func_t & R, uint64_t &Id) {
std::lock_guard G(Mutex_);
Id = CallBackId_++;
CallBacks_[Id] = R;
}
private:
std::recursive_mutex Mutex_;
std::map<uint64_t,logmuxer_callback_func_t> CallBacks_;
inline static uint64_t CallBackId_=1;
bool Enabled_ = false;
};
inline auto WebSocketLogger() { return WebSocketLogger::instance(); }
// inline auto WebSocketLogger() { return WebSocketLogger::instance(); }
}

View File

@@ -219,6 +219,16 @@ namespace OpenWifi::RESTAPI::Errors {
static const struct msg MaximumRTTYSessionsReached{1144,"Too many RTTY sessions currently active"};
static const struct msg DeviceIsAlreadyBusy{1145,"Device is already executing a command. Please try later."};
static const struct msg DeviceRequiresSignature{1146,"Device requires device signature to be provided."};
static const struct msg ApiKeyNameAlreadyExists{1147,"API Key name must be unique."};
static const struct msg TooManyApiKeys{1148,"Too many API Keys have already been created."};
static const struct msg UserMustExist{1149,"User must exist."};
static const struct msg ApiKeyNameDoesNotExist{1150,"API Key name does not exist."};
static const struct msg ApiKeyDoesNotExist{1150,"API Key does not exist."};
static const struct msg DeviceIsRestricted{1151,"Device is protected by regulation. This function is not allowed."};
}
@@ -433,6 +443,8 @@ namespace OpenWifi::uCentralProtocol {
static const char *CHANNELS = "channels";
static const char *PASSWORD = "password";
static const char *DEVICEUPDATE = "deviceupdate";
static const char *FWSIGNATURE = "FWsignature";
static const char *SIGNATURE = "signature";
static const char *SERIALNUMBER = "serialNumber";
static const char *COMPATIBLE = "compatible";

View File

@@ -520,4 +520,15 @@ bool ExtractBase64CompressedData(const std::string &CompressedData,
return false;
}
bool IsAlphaNumeric(const std::string &s) {
return std::all_of(s.begin(),s.end(),[](char c) -> bool { return isalnum(c); });
}
std::string SanitizeToken(const std::string &Token) {
if(Token.size()>8) {
return Token.substr(0,4) + "****" + Token.substr(Token.size()-4,4);
}
return "*******";
}
}

View File

@@ -115,6 +115,8 @@ namespace OpenWifi::Utils {
[[nodiscard]] std::string BinaryFileToHexString(const Poco::File &F);
[[nodiscard]] std::string SecondsToNiceText(uint64_t Seconds);
[[nodiscard]] bool wgets(const std::string &URL, std::string &Response);
[[nodiscard]] bool IsAlphaNumeric(const std::string &s);
[[nodiscard]] std::string SanitizeToken(const std::string &Token);
template< typename T >
std::string int_to_hex( T i )

View File

@@ -17,20 +17,21 @@
namespace OpenWifi {
bool Storage::CreateDeviceCapabilities(std::string &SerialNumber, std::string &Capabilities) {
bool Storage::CreateDeviceCapabilities(std::string & SerialNumber, const Config::Capabilities & Capabilities) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement UpSert(Sess);
std::string TCaps{Capabilities.AsString()};
uint64_t Now = Utils::Now();
std::string St{ "insert into Capabilities (SerialNumber, Capabilities, FirstUpdate, LastUpdate) values(?,?,?,?) on conflict (SerialNumber) do "
" update set Capabilities=?, LastUpdate=?"};
UpSert << ConvertParams(St),
Poco::Data::Keywords::use(SerialNumber),
Poco::Data::Keywords::use(Capabilities),
Poco::Data::Keywords::use(TCaps),
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Capabilities),
Poco::Data::Keywords::use(TCaps),
Poco::Data::Keywords::use(Now);
UpSert.execute();
return true;
@@ -41,25 +42,25 @@ bool Storage::CreateDeviceCapabilities(std::string &SerialNumber, std::string &C
return false;
}
bool Storage::UpdateDeviceCapabilities(std::string &SerialNumber, std::string & Capabilities, std::string & Compat) {
bool Storage::UpdateDeviceCapabilities(std::string &SerialNumber, const Config::Capabilities & Caps) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement UpSert(Sess);
uint64_t Now = Utils::Now();
OpenWifi::Config::Capabilities Caps(Capabilities);
Compat = Caps.Compatible();
if(!Caps.Compatible().empty() && !Caps.Platform().empty())
CapabilitiesCache::instance()->Add(Caps.Compatible(), Caps.Platform(), Capabilities);
CapabilitiesCache()->Add(Caps);
std::string TCaps{Caps.AsString()};
std::string St{"insert into Capabilities (SerialNumber, Capabilities, FirstUpdate, LastUpdate) values(?,?,?,?) on conflict (SerialNumber) do "
" update set Capabilities=?, LastUpdate=?"};
UpSert << ConvertParams(St),
Poco::Data::Keywords::use(SerialNumber),
Poco::Data::Keywords::use(Capabilities),
Poco::Data::Keywords::use(TCaps),
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Capabilities),
Poco::Data::Keywords::use(TCaps),
Poco::Data::Keywords::use(Now);
UpSert.execute();
return true;

View File

@@ -508,7 +508,7 @@ typedef Poco::Tuple<
return false;
}
bool Storage::CommandCompleted(std::string &UUID, const Poco::JSON::Object & ReturnVars,
bool Storage::CommandCompleted(std::string &UUID, Poco::JSON::Object::Ptr ReturnVars,
const std::chrono::duration<double, std::milli> & execution_time,
bool FullCommand) {
try {
@@ -519,8 +519,8 @@ typedef Poco::Tuple<
uint64_t ErrorCode = 0;
std::string ErrorText, ResultStr;
if (ReturnVars.has("result")) {
auto ResultObj = ReturnVars.get("result");
if (ReturnVars->has("result")) {
auto ResultObj = ReturnVars->get("result");
auto ResultFields = ResultObj.extract<Poco::JSON::Object::Ptr>();
if (ResultFields->has("status")) {
auto StatusObj = ResultFields->get("status");
@@ -584,7 +584,7 @@ typedef Poco::Tuple<
return false;
}
bool Storage::AttachFileDataToCommand(std::string & UUID, const std::stringstream & FileContent) {
bool Storage::AttachFileDataToCommand(std::string & UUID, const std::stringstream & FileContent, const std::string &Type) {
try {
Poco::Data::Session Sess = Pool_->get();
auto Now = Utils::Now();
@@ -611,7 +611,7 @@ typedef Poco::Tuple<
TheBlob.appendRaw((const unsigned char *)FileContent.str().c_str(),FileContent.str().size());
Poco::Data::Statement Insert(Sess);
std::string FileType{"trace"};
std::string FileType{Type};
std::string St2{
"INSERT INTO FileUploads (UUID,Type,Created,FileContent) VALUES(?,?,?,?)"};

View File

@@ -11,7 +11,6 @@
#include "CentralConfig.h"
#include "ConfigurationCache.h"
#include "Daemon.h"
#include "AP_WS_Server.h"
#include "FindCountry.h"
#include "OUIServer.h"
#include "Poco/Data/RecordSet.h"
@@ -48,7 +47,8 @@ namespace OpenWifi {
"subscriber, "
"entity, "
"modified, "
"locale"
"locale,"
"restrictedDevice"
};
const static std::string DB_DeviceUpdateFields{
@@ -73,10 +73,11 @@ namespace OpenWifi {
"subscriber=?, "
"entity=?, "
"modified=?, "
"locale=? "
"locale=?, "
"restrictedDevice=?"
};
const static std::string DB_DeviceInsertValues{" VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "};
const static std::string DB_DeviceInsertValues{" VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "};
typedef Poco::Tuple<
std::string,
@@ -100,7 +101,8 @@ namespace OpenWifi {
std::string,
std::string,
uint64_t,
std::string
std::string,
bool
> DeviceRecordTuple;
typedef std::vector<DeviceRecordTuple> DeviceRecordList;
@@ -127,6 +129,7 @@ namespace OpenWifi {
D.entity = R.get<19>();
D.modified = R.get<20>();
D.locale = R.get<21>();
D.restrictedDevice = R.get<22>();
}
void ConvertDeviceRecord(const GWObjects::Device &D, DeviceRecordTuple & R) {
@@ -152,6 +155,7 @@ namespace OpenWifi {
R.set<19>(D.entity);
R.set<20>(D.modified);
R.set<21>(D.locale);
R.set<22>(D.restrictedDevice);
}
bool Storage::GetDeviceCount(uint64_t &Count) {
@@ -314,16 +318,15 @@ namespace OpenWifi {
#define __DBGLOG__ std::cout << __LINE__ << std::endl;
bool Storage::CreateDefaultDevice(std::string &SerialNumber, std::string &Capabilities, std::string & Firmware, std::string &Compat, const Poco::Net::IPAddress & IPAddress) {
bool Storage::CreateDefaultDevice(std::string &SerialNumber, const Config::Capabilities &Caps, std::string & Firmware, const Poco::Net::IPAddress & IPAddress) {
GWObjects::Device D;
poco_information(Logger(),fmt::format("AUTO-CREATION({})", SerialNumber));
uint64_t Now = time(nullptr);
Config::Capabilities Caps(Capabilities);
GWObjects::DefaultConfiguration DefConfig;
if(!Caps.Platform().empty() && !Caps.Compatible().empty()) {
CapabilitiesCache::instance()->Add(Caps.Compatible(), Caps.Platform(), Capabilities);
CapabilitiesCache()->Add(Caps);
}
bool Found = false;
@@ -339,7 +342,7 @@ namespace OpenWifi {
}
}
if (!Found && AP_WS_Server()->UseDefaults() && FindDefaultConfigurationForModel(Compat, DefConfig)) {
if (!Found && AP_WS_Server()->UseDefaults() && FindDefaultConfigurationForModel(Caps.Compatible(), DefConfig)) {
Config::Config NewConfig(DefConfig.Configuration);
NewConfig.SetUUID(Now);
D.Configuration = NewConfig.get();
@@ -352,14 +355,14 @@ namespace OpenWifi {
// 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);
Compat = D.Compatible = Caps.Compatible();
D.Compatible = Caps.Compatible();
D.DeviceType = Daemon()->IdentifyDevice(D.Compatible);
D.MACAddress = Utils::SerialToMAC(SerialNumber);
D.Manufacturer = Caps.Model();
D.Firmware = Firmware;
D.Notes = SecurityObjects::NoteInfoVec { SecurityObjects::NoteInfo{ (uint64_t)Utils::Now(), "", "Auto-provisioned."}};
CreateDeviceCapabilities(SerialNumber, Capabilities);
CreateDeviceCapabilities(SerialNumber, Caps);
return CreateDevice(D);
}
@@ -555,7 +558,6 @@ namespace OpenWifi {
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,
@@ -704,11 +706,6 @@ namespace OpenWifi {
return ">75%";
}
int ChannelToBand(uint64_t C) {
if(C>=1 && C<=16) return 2;
return 5;
}
bool Storage::AnalyzeDevices(GWObjects::Dashboard &Dashboard) {
try {
Poco::Data::Session Sess = Pool_->get();
@@ -766,10 +763,11 @@ namespace OpenWifi {
}
}
uint64_t Associations_2G, Associations_5G;
StateUtils::ComputeAssociations(RawObject, Associations_2G, Associations_5G);
uint64_t Associations_2G, Associations_5G, Associations_6G;
StateUtils::ComputeAssociations(RawObject, Associations_2G, Associations_5G, Associations_6G);
UpdateCountedMap(Dashboard.associations, "2G", Associations_2G);
UpdateCountedMap(Dashboard.associations, "5G", Associations_5G);
UpdateCountedMap(Dashboard.associations, "6G", Associations_6G);
}
} else {
UpdateCountedMap(Dashboard.status, "not connected");

View File

@@ -39,7 +39,7 @@ namespace OpenWifi {
bool Storage::AddStatisticsData(const GWObjects::Statistics & Stats) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Session Sess(Pool_->get());
Poco::Data::Statement Insert(Sess);
poco_trace(Logger(),fmt::format("{}: Adding stats. Size={}",Stats.SerialNumber,std::to_string(Stats.Data.size())));
@@ -60,11 +60,46 @@ namespace OpenWifi {
return false;
}
bool Storage::GetNumberOfStatisticsDataRecords(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, std::uint64_t &Count) {
try {
Poco::Data::Session Sess(Pool_->get());
Poco::Data::Statement Select(Sess);
StatsRecordList Records;
bool DatesIncluded = (FromDate != 0 || ToDate != 0);
std::string Prefix{"SELECT count(*) FROM Statistics "};
std::string StatementStr = SerialNumber.empty()
? Prefix + std::string(DatesIncluded ? "WHERE " : "")
: Prefix + "WHERE SerialNumber='" + SerialNumber + "'" +
std::string(DatesIncluded ? " AND " : "");
std::string DateSelector;
if (FromDate && ToDate) {
DateSelector = " Recorded>=" + std::to_string(FromDate) + " AND Recorded<=" + std::to_string(ToDate);
} else if (FromDate) {
DateSelector = " Recorded>=" + std::to_string(FromDate);
} else if (ToDate) {
DateSelector = " Recorded<=" + std::to_string(ToDate);
}
Select << StatementStr + DateSelector ,
Poco::Data::Keywords::into(Count);
Select.execute();
return true;
}
catch (const Poco::Exception &E) {
poco_warning(Logger(),fmt::format("{}: Failed with: {}", std::string(__func__), E.displayText()));
}
return false;
}
bool Storage::GetStatisticsData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, uint64_t Offset,
uint64_t HowMany,
std::vector<GWObjects::Statistics> &Stats) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Session Sess(Pool_->get());
Poco::Data::Statement Select(Sess);
StatsRecordList Records;
@@ -93,7 +128,7 @@ namespace OpenWifi {
for (const auto &i: Records) {
GWObjects::Statistics R;
ConvertStatsRecord(i,R);
Stats.push_back(R);
Stats.emplace_back(R);
}
return true;
}
@@ -106,7 +141,7 @@ namespace OpenWifi {
bool Storage::GetNewestStatisticsData(std::string &SerialNumber, uint64_t HowMany, std::vector<GWObjects::Statistics> &Stats) {
try {
StatsRecordList Records;
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Session Sess(Pool_->get());
Poco::Data::Statement Select(Sess);
std::string St{"SELECT " +
@@ -120,7 +155,7 @@ namespace OpenWifi {
for (const auto &i: Records) {
GWObjects::Statistics R;
ConvertStatsRecord(i,R);
Stats.push_back(R);
Stats.emplace_back(R);
}
return true;
}
@@ -165,7 +200,7 @@ bool Storage::DeleteStatisticsData(std::string &SerialNumber, uint64_t FromDate,
bool Storage::RemoveStatisticsRecordsOlderThan(uint64_t Date) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Session Sess(Pool_->get());
Poco::Data::Statement Delete(Sess);
std::string St1{"delete from Statistics where recorded<?"};

View File

@@ -107,7 +107,8 @@ namespace OpenWifi {
"subscriber VARCHAR(64) , "
"entity VARCHAR(64) , "
"modified BIGINT,"
"locale varchar(32) "
"locale varchar(32), "
"restrictedDevice BOOLEAN "
")", Poco::Data::Keywords::now;
Sess << "CREATE INDEX IF NOT EXISTS DeviceOwner ON Devices (Owner ASC)", Poco::Data::Keywords::now;
Sess << "CREATE INDEX IF NOT EXISTS DeviceLocation ON Devices (Location ASC)", Poco::Data::Keywords::now;
@@ -118,7 +119,8 @@ namespace OpenWifi {
"alter table devices add column subscriber varchar(64)",
"alter table devices add column entity varchar(64)",
"alter table devices add column modified bigint",
"alter table devices add column locale varchar(32)"
"alter table devices add column locale varchar(32)",
"alter table devices add column restrictedDevice boolean",
};
for(const auto &i:Script) {

View File

@@ -0,0 +1,16 @@
bundle.wifi();
let paths = [
[ 'network.wireless', 'status' ],
[ 'network.device', 'status' ],
[ 'network.interface', 'dump' ],
[ 'log', 'read', { stream: false } ],
];
for (let path in paths)
bundle.ubus(path[0], path[1], path[2]);
for (let config in [ 'network', 'wireless', 'dhcp', 'firewall', 'system' ])
bundle.uci(config);
for (let cmd in [ "route", "ifconfig", "logread" ])
bundle.shell(cmd);

View File

@@ -46,7 +46,7 @@ browser=""
login() {
payload="{ \"userId\" : \"$username\" , \"password\" : \"$password\" }"
token=$(curl ${FLAGS} -X POST -H "Content-Type: application/json" -d "$payload" "https://${OWSEC}/api/v1/oauth2" | jq -r '.access_token')
# curl -v -X POST -H "Content-Type: application/json" -d "$payload" "https://${OWSEC}/api/v1/oauth2" | jq -r '.access_token'
if [[ "${token}" == "" ]]
then
echo "Could not login. Please verify the host and username/password."
@@ -175,11 +175,11 @@ listdevices() {
jq < ${result_file}
}
listdevices() {
listdevicesk() {
curl ${FLAGS} -X GET "https://${OWGW}/api/v1/devices" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${token}" > ${result_file}
-H "X-API-KEY: $1" > ${result_file}
jq < ${result_file}
}
@@ -651,6 +651,26 @@ telemetry() {
fi
}
notifications() {
if [[ -z "$1" ]]
then
timeout=30
else
timeout=$1
fi
socket="wss://${OWGW}/api/v1/ws"
echo ${socket}
if [[ "$(which wscat)" == "" ]]
then
echo "wscat command not found. Cannot start a websocket session."
else
wscat \
--connect "${socket}" "token:${token}" \
--wait $timeout \
--execute "token:${token}"
fi
}
telemetry_to_kafka() {
payload="$(printf '{ "serialNumber": "%s", "interval": 2, "kafka": true, "lifetime": %d, "types": [ "dhcp-snooping", "state", "wifi-frames" ] }' "$1" "$2")"
curl ${FLAGS} -X POST "https://${OWGW}/api/v1/device/$1/telemetry" \
@@ -662,7 +682,8 @@ telemetry_to_kafka() {
}
runscript() {
payload="$(printf '{ "serialNumber": "%s", "type": "%s" , "kafka": true, "timeout": 30, "scriptId": "cli-manual", "script" : "%s" }' "$1" "$2" "$3" )"
scriptcontent=$(base64 -i $3)
payload="$(printf '{ "serialNumber": "%s", "type": "%s" , "timeout": 30, "script" : "%s" , "when" : 0 }' "$1" "$2" "$scriptcontent" )"
curl ${FLAGS} -X POST "https://${OWGW}/api/v1/device/$1/script" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
@@ -730,6 +751,49 @@ connectionstatistics() {
jq < ${result_file}
}
testtoken() {
login
systeminfo
logout
systeminfo
}
# retreive the stats for a snigle device for the last 7 days
stats7() {
now=$(date +%s)
len=$((7 * 24 * 60 * 60))
start=$((now - len))
offset=0
records=100
while [ ${records} == 100 ]
do
curl ${FLAGS} -X GET "https://${OWGW}/api/v1/device/$1/statistics?startDate=${start}&endDate=${now}&offset=${offset}&limit=100" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${token}" > ${result_file}
# jq < ${result_file}
records=$(jq '.data | length' ${result_file})
offset=$((offset + ${records}))
echo "Downloaded ${records} records. New offset is ${offset}"
if [[ ${records} != 100 ]]
then
break
fi
done
}
stats7count() {
now=$(date +%s)
len=$((7 * 24 * 60 * 60))
start=$((now - len))
curl ${FLAGS} -X GET "https://${OWGW}/api/v1/device/$1/statistics?startDate=${start}&endDate=${now}&countOnly=true" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${token}" > ${result_file}
jq < ${result_file}
}
check_response() {
if [ -s "$1" ]; then
@@ -931,7 +995,8 @@ case "$1" in
"getcapabilities") login; getcapabilities "$2" ; logout ;;
"deletecapabilities") login; deletecapabilities "$2" ; logout ;;
"listdevices") login; listdevices ; logout ;;
"deletedevice") login; deletedevice "$2" ; logout ;;
"listdevicesk") login; listdevicesk "$2" ; logout ;;
"deletedevice") login; deletedevice "$2" ; logout ;;
"deleteoui") login; deleteoui "$2" ; logout ;;
"createdevice") login; createdevice "$2" "$3" "$4" ; logout ;;
"reboot") login; reboot "$2" ; logout ;;
@@ -997,6 +1062,10 @@ case "$1" in
"deleteradiusconfig") login; deleteradiusconfig ; logout;;
"deviceping") login; deviceping $2; logout;;
"connectionstatistics") login; connectionstatistics $2; logout;;
"notifications") login; notifications "$2"; logout;;
"stats7") login; stats7 "$2"; logout;;
"stats7count") login; stats7count "$2"; logout;;
"testtoken") testtoken;;
*) help ;;
esac

View File

@@ -0,0 +1,4 @@
#!/bin/bash
ls -l /etc/ucentral

File diff suppressed because one or more lines are too long