Compare commits

...

150 Commits

Author SHA1 Message Date
Ivan Chvets
26b9a96506 fix: updated internal switch schema
https://telecominfraproject.atlassian.net/browse/OLS-433

Summary of changes:
- Updated internal switch schema.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-12-10 08:53:01 -05:00
i-chvets
5ce8dae9ec Merge pull request #393 from Telecominfraproject/OLS-433-fix-switch-schema-sync
OLS-433: fix: updated internal switch schema
2024-12-04 15:49:07 -05:00
i-chvets
7da135c1e5 Merge pull request #394 from Telecominfraproject/OLS-380-fix-file-upload
OSL-380: fix: modified code for file upload transactions
2024-12-04 15:48:47 -05:00
Carsten Schafer
50ee4ba5cb Merge pull request #395 from Telecominfraproject/version_update
fix: release 3.2.1 version update
2024-12-04 12:17:39 -05:00
Ivan Chvets
3a8109d7ad fix: release 3.2.1 version update
https://telecominfraproject.atlassian.net/browse/WIFI-14165

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-12-04 12:10:44 -05:00
Ivan Chvets
56232966ec fix: modified code for file upload transactions
https://telecominfraproject.atlassian.net/browse/OLS-380

Summary of changes:
- Modified code to have two distinct transaction in storage file upload.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-11-29 13:09:34 -05:00
Ivan Chvets
1ecf98d712 fix: updated internal switch schema
https://telecominfraproject.atlassian.net/browse/OLS-433

Summary of changes:
- Updated internal switch schema.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-11-29 11:56:05 -05:00
Gopi Raga
f5b60ced61 Merge pull request #392 from Telecominfraproject/WIFI-14292-fix-json-parse-error
WIFI-14292: fix: json parsing error
2024-11-17 11:20:00 +05:30
Ivan Chvets
e4d141bb8e fix: json parsing error
https://telecominfraproject.atlassian.net/browse/WIFI-14292

Summary of changes:
- Removed code that was incorrectly added to JSON string.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-11-15 13:17:12 -05:00
i-chvets
25b4288050 Merge pull request #391 from Telecominfraproject/WIFI-14254-doc-update
WIFI-14254: doc: update protocol.md
2024-10-31 10:39:24 -04:00
Ivan Chvets
82430c2d5d doc: update protocol.md
https://telecominfraproject.atlassian.net/browse/WIFI-14254

Summary of changes:
- Updated PROTOCOL.md with compressed configuration message
  specification.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-10-31 10:14:21 -04:00
i-chvets
7b68ec0536 Merge pull request #390 from Telecominfraproject/WIFI-14227-feat-compressed-config
WIFI-14229: feat: compressed config
2024-10-30 12:08:45 -04:00
Ivan Chvets
839f4fec44 feat: compressed config
https://telecominfraproject.atlassian.net/browse/WIFI-14229

Summary of changes:
- Modified code to compress configuration data, if capabilities object
  has compress command indicator enabled.
- Added encode and compress function to utilities.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-10-30 11:44:02 -04:00
i-chvets
c4178209bb Merge pull request #388 from Telecominfraproject/version_update
WIFI-14165: Release 3.2 version update
2024-09-30 10:12:32 -04:00
Ivan Chvets
79ab67db50 fix: release 3.2 version update
https://telecominfraproject.atlassian.net/browse/WIFI-14165

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-09-30 09:39:44 -04:00
i-chvets
00bc77feea Merge pull request #385 from Telecominfraproject/WIFI-14134-fix_code_style_change
WIFI-14134: fix: file upload status - code style change
2024-09-27 10:59:14 -04:00
Ivan Chvets
4f00d77d2b fix: file upload status - code style change
https://telecominfraproject.atlassian.net/browse/WIFI-14134

Summary of changes:
- Code style change.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-09-27 10:34:45 -04:00
i-chvets
c679d4ac40 Merge pull request #383 from Telecominfraproject/WIFI-14134-fix_file_upload_status
WIP: WIFI-14134: fix: file upload status
2024-09-26 21:33:56 -04:00
Ivan Chvets
4a150a9fcb fix: file upload status
https://telecominfraproject.atlassian.net/browse/WIFI-14134

Summary of changes:
- Return 202 in case of file pening upload.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-09-26 16:07:19 -04:00
i-chvets
83eb603f0a Merge pull request #382 from Telecominfraproject/openapi-fix
WIFI-14165: Fix wrong port in openapi.yaml
2024-09-25 15:10:28 -04:00
Adam Capparelli
38bc0f0d69 Fix wrong port in openapi.yaml
Signed-off-by: Adam Capparelli <adam.capparelli@alumni.utoronto.ca>
2024-09-25 11:08:11 -04:00
i-chvets
e7362c2020 Merge pull request #381 from Telecominfraproject/ols-246-feat-cable-diag
OLS-246: feat: add cable diagnostics command
2024-09-25 10:42:52 -04:00
Ivan Chvets
9c9987e190 feat: add cable diagnostics command
https://telecominfraproject.atlassian.net/browse/OLS-246

Summary of changes:
- Modified code to match spec, ie. command is `cable-diagnostics`.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-09-25 10:17:52 -04:00
i-chvets
4ac7b6ba0b Merge pull request #379 from Telecominfraproject/WIFI-14140-fix-update-schema-multi-psk
WIFI-14140: fix: sync-ed up ucentral schema with code - added missing code
2024-09-25 09:54:12 -04:00
Ivan Chvets
f9ee19af91 fix: sync-ed up ucentral schema with code - added missing code
https://telecominfraproject.atlassian.net/browse/WIFI-14140

Summary of changes:
- Synchronized built-in schema in configuration validation code with
ucentral schema. Added missing code.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-09-25 08:30:58 -04:00
i-chvets
cd2ab8660f Merge pull request #376 from Telecominfraproject/WIFI-14140-fix-update-schema-multi-psk
WIFI-14140 fix: sync-ed up ucentral schema with code
2024-09-24 10:05:56 -04:00
Ivan Chvets
b9f00f6603 fix: sync-ed up ucentral schema with code
https://telecominfraproject.atlassian.net/browse/WIFI-14140

Summary of changes:
- Synchronized built-in schema in configuration validation code with
  ucentral schema.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-09-19 10:26:51 -04:00
i-chvets
596cfd49e1 Merge pull request #375 from Telecominfraproject/ols-246-feat-cable-diag
OLS-246: feat: add cable diagnostics command
2024-09-18 11:45:14 -04:00
Ivan Chvets
b3deba5606 feat: add cable diagnostics command
https://telecominfraproject.atlassian.net/browse/OLS-246

Summary of changes:
- Added `cablediagnostics` command.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-09-18 11:04:57 -04:00
i-chvets
a97d49a06b Merge pull request #373 from Telecominfraproject/WIFI-13126-feat-fixed-config-doc-update
WIFI-13126: feat: fixedconfig doc update
2024-09-16 10:05:55 -04:00
Ivan Chvets
b1be0604d6 feat: fixedconfig doc update
https://telecominfraproject.atlassian.net/browse/WIFI-13126

Summary of changes:
- Updated documentation.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-09-13 11:30:40 -04:00
i-chvets
b29f7f7dc4 Merge pull request #372 from Telecominfraproject/WIFI-13126-feat-fixed-config
WIFI-13126: feat: add fixedconfig command
2024-09-11 16:59:16 -04:00
Ivan Chvets
132b31b06b feat: add fixedconfig command
https://telecominfraproject.atlassian.net/browse/WIFI-13126

Summary of changes:
- Added `fixedconfig` command.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-09-11 16:20:02 -04:00
i-chvets
3114ff8a32 Merge pull request #371 from Telecominfraproject/WIFI-14038-fix-exception-handling-for-zero-queue
WIFI-14038: fix: update code to improve exception handling
2024-09-10 13:45:48 -04:00
Ivan Chvets
9c5aeda5dd fix: update code to improve exception handling
https://telecominfraproject.atlassian.net/browse/WIFI-14038

Summary of changes:
- Modified code to cover zero sized queues under exception handling.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-08-29 17:57:05 -04:00
i-chvets
783ec99930 Merge pull request #370 from Telecominfraproject/WIFI-13875-fix-use-dns
WIFI-13875: fix: updated valijson version
2024-08-08 10:05:40 -04:00
Ivan Chvets
0c661b8b93 fix: updated valijson version
https://telecominfraproject.atlassian.net/browse/WIFI-13875

Summary of changes:
- Updated valijson version in Docker file to bring in fix for https://github.com/tristanpenman/valijson/issues/181

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-08-08 09:23:30 -04:00
i-chvets
9d7f4da504 Merge pull request #369 from Telecominfraproject/WIFI-14027-fix-ping-crash
fix: fix crash for non-configure commands
2024-08-01 19:03:54 -04:00
Ivan Chvets
a3b6e7c315 fix: fix crash for non-configure commands
https://telecominfraproject.atlassian.net/browse/WIFI-14027

Summary of changes:
- Modified code to relay errors only in case of configure command and
  strict mode.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-08-01 17:09:09 -04:00
i-chvets
451680cd5a Merge pull request #368 from Telecominfraproject/WIFI-14019-fix-report-errors-in-strict-only
WIFI-14019: fix: relay errors from ap nos configuration only when strict mode is enabled
2024-07-30 12:50:25 -04:00
Ivan Chvets
7be48c3cfc fix: relay errors from ap nos configuration only when strict mode is
enabled
https://telecominfraproject.atlassian.net/browse/WIFI-14019

Summary of changes:
- Modified code to only relay errors from AP NOS configuration update
  only when strict mode is enabled.

NOTE: AP NOS is capable of modifying config thus fixing invalid configs
(in some cases) and applying resulting configuration. Warning messages
are produced, but error code is being sent back as error/failed.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-07-30 12:21:19 -04:00
i-chvets
b59d1cb4da Merge pull request #366 from Telecominfraproject/WIFI-13985-fix-return-400-on-error
WIFI-13985: commands API will return 400 if command fails on device.
2024-07-26 13:26:27 -04:00
Adam Capparelli
c3a709c2b9 commands API will return 400 if command fails on device.
Signed-off-by: Adam Capparelli <adam.capparelli@mail.utoronto.ca>
2024-07-22 14:28:03 -04:00
i-chvets
5d89107827 Merge pull request #362 from Telecominfraproject/WIFI-13597-fix-kafka-producer-using-poll
WIFI-13857: fix: modified code to use flush() when internal queue is not loaded
2024-06-19 16:52:01 -04:00
Ivan Chvets
3c15c6dc4f fix: modified code to use flush() when internal queue is not loaded
https://telecominfraproject.atlassian.net/browse/WIFI-13597

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-06-19 16:29:24 -04:00
i-chvets
7b33a692b2 Merge pull request #361 from Telecominfraproject/WIFI-13597-fix-kafka-producer-using-poll
fix: added flush() for proper shutdown
2024-06-18 12:04:02 -04:00
Ivan Chvets
b118dcbcec fix: added flush() for proper shutdown
https://telecominfraproject.atlassian.net/browse/WIFI-13597

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-06-14 16:30:23 -04:00
Stephane Bourque
02a0eef44a Merge pull request #360 from Telecominfraproject/WIFI-13597-fix-kafka-producer-using-poll
WIFI-13597: fix: modified kafka manager to use poll in producer
2024-06-12 12:17:08 -07:00
Ivan Chvets
c7ed7fb264 fix: modified kafka manager to use poll in producer
https://telecominfraproject.atlassian.net/browse/WIFI-13597

Summary of changes:
- Modified code in KafkaManager to use poll instead of flush for every
  messages sent. flush is used only on empty internal notification queue
in idle times.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-06-11 11:15:42 -04:00
Gopi Raga
1d88bb50d9 Merge pull request #359 from Telecominfraproject/WIFI-431-fix-update-internal-schema-validation
fix: modified code to use final as default for fingerprint mode
2024-06-06 11:10:46 +05:30
Ivan Chvets
3b613ea159 fix: modified code to use final as default for fingerprint mode
https://telecominfraproject.atlassian.net/browse/WIFI-431

Summary of changes:
- Modified code to use `final` as default value for fingerprint mode.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-06-05 11:49:49 -04:00
Stephane Bourque
d00d409fca Merge pull request #358 from Telecominfraproject/OLS-84
https://telecominfraproject.atlassian.net/browse/OLS-84
2024-06-04 20:49:16 -07:00
stephb9959
8382818e2d https://telecominfraproject.atlassian.net/browse/OLS-84
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-06-04 20:48:14 -07:00
Stephane Bourque
ed4670d239 Merge pull request #357 from Telecominfraproject/OLS-84
https://telecominfraproject.atlassian.net/browse/OLS-84
2024-06-04 13:32:32 -07:00
stephb9959
cca3619e91 https://telecominfraproject.atlassian.net/browse/OLS-84
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-06-04 12:55:54 -07:00
Stephane Bourque
9a834c29a2 Merge pull request #355 from Telecominfraproject/WIFI-431-fix-update-internal-schema-validation
fix: modified code to use proper fingerprint defintion
2024-06-04 09:41:34 -07:00
Ivan Chvets
2b06a0bcf6 fix: modified code to use proper fingerprint defintion
https://telecominfraproject.atlassian.net/browse/WIFI-431

Summary of changes:
- Modified code to use proper definition of fingerprint service.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-06-04 12:16:19 -04:00
Stephane Bourque
03dabed878 Merge pull request #352 from Telecominfraproject/WIFI-13535
https://telecominfraproject.atlassian.net/browse/WIFI-13535
2024-06-03 13:25:46 -07:00
i-chvets
e133a9c3ab Merge pull request #354 from Telecominfraproject/OLS-56-cherry-pick-fix-ols-switch-schema-parsing
OLS-56: fix: replaced incorrect case conversion for device type
2024-05-31 11:37:43 -04:00
Ivan Chvets
23b33fab20 fix: replaced incorrect case conversion for device type
https://telecominfraproject.atlassian.net/browse/OLS-56

Summary of changes:
- Replaced incorrect case conversion for device type.

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-05-30 09:09:48 -04:00
stephb9959
909b4c889e https://telecominfraproject.atlassian.net/browse/WIFI-13535
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-05-29 09:12:58 -07:00
Stephane Bourque
a04c5336d2 Merge pull request #350 from Telecominfraproject/WIFI-12748-feat-schema-update-afc-support
ucentral schema update: added afc support
2024-05-27 13:38:27 -07:00
Ivan Chvets
4df1bf985d ucentral schema update: added afc support
https://telecominfraproject.atlassian.net/browse/WIFI-12748

Update to internal schema in the gateway code is required to ensure code is in-sync with schema version on Github.

- Added section to enabled AFC configuration
- Additional updates listed below.

The following updates to schema are also included in this PR:

fix bss color handling
da090931f0

drop ports.duplex support
35da0a1cd0

add support for device fingerprinting
cb1c18db70

Signed-off-by: Ivan Chvets <ivan.chvets@kinarasystems.com>
2024-05-27 15:01:17 -04:00
Stephane Bourque
26a89f3eb5 Merge pull request #347 from kinarasystems/wifi_13539_feat_devices_api
WIFI-13539 Feat: devices api update to include preprovisioned
2024-03-26 22:06:26 -07:00
Bhavesh Patel
b055711993 adding includeProvisioned parameter to GET devices REST call to get non provisioned APs easily
Signed-off-by: Bhavesh Patel <bhavesh.patel@kinarasystems.com>
2024-03-21 14:42:08 -04:00
Bhavesh Patel
fcdb7423ef adding nonProvisioned parameter to GET devices API call
Signed-off-by: Bhavesh Patel <bhavesh.patel@kinarasystems.com>
2024-03-21 14:18:34 -04:00
Stephane Bourque
f286d5fb48 Merge pull request #344 from Telecominfraproject/WIFI-12939
WIFI-12939: change to TIP repos for libraries
2024-03-19 13:03:35 -07:00
Stephane Bourque
0d70601c64 Merge pull request #346 from Telecominfraproject/WIFI-13522
https://telecominfraproject.atlassian.net/browse/WIFI-13522
2024-03-19 13:01:41 -07:00
stephb9959
a493defc99 https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 12:55:54 -07:00
stephb9959
fb3e1288ae https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 12:53:36 -07:00
stephb9959
ce52e05104 https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 12:28:01 -07:00
stephb9959
920b922121 https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 11:57:36 -07:00
stephb9959
3732cfd07e https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 10:55:41 -07:00
stephb9959
9e772b8c91 https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 10:46:28 -07:00
stephb9959
92252d09dc https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 10:45:18 -07:00
stephb9959
28636c3e1e https://telecominfraproject.atlassian.net/browse/WIFI-13522
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-19 10:16:00 -07:00
Stephane Bourque
8e44f1e85c Merge pull request #345 from Telecominfraproject/WIFI-13507
https://telecominfraproject.atlassian.net/browse/WIFI-13507
2024-03-15 23:26:27 -07:00
stephb9959
b77d40fbf8 https://telecominfraproject.atlassian.net/browse/WIFI-13507
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-15 23:23:13 -07:00
Stephane Bourque
574172b8bf Merge pull request #343 from Telecominfraproject/WIFI-13507
https://telecominfraproject.atlassian.net/browse/WIFI-13507
2024-03-15 09:06:19 -07:00
stephb9959
794b31591d https://telecominfraproject.atlassian.net/browse/WIFI-13507
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-15 09:05:21 -07:00
Stephane Bourque
66aee07105 Merge pull request #342 from Telecominfraproject/WIFI-13507
https://telecominfraproject.atlassian.net/browse/WIFI-13507
2024-03-15 08:49:08 -07:00
stephb9959
86685f17d6 https://telecominfraproject.atlassian.net/browse/WIFI-13507
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-15 08:48:13 -07:00
Stephane Bourque
08f683c15a Merge pull request #341 from Telecominfraproject/WIFI-13507
https://telecominfraproject.atlassian.net/browse/WIFI-13507
2024-03-15 08:06:50 -07:00
stephb9959
7fea477f55 https://telecominfraproject.atlassian.net/browse/WIFI-13507
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-15 08:05:20 -07:00
Stephane Bourque
f22b3e3995 Merge pull request #340 from Telecominfraproject/WIFI-13507
https://telecominfraproject.atlassian.net/browse/WIFI-13507
2024-03-15 08:00:48 -07:00
stephb9959
3a1011a662 https://telecominfraproject.atlassian.net/browse/WIFI-13507
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-14 22:54:59 -07:00
stephb9959
6595b37ae4 https://telecominfraproject.atlassian.net/browse/WIFI-13507
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-14 22:38:52 -07:00
stephb9959
05b6a9474b https://telecominfraproject.atlassian.net/browse/WIFI-13507
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-14 22:26:31 -07:00
Carsten Schafer
1de94be447 WIFI-12939: change to TIP repos for libraries
Signed-off-by: Carsten Schafer <Carsten.Schafer@kinarasystems.com>
2024-03-14 15:11:23 -04:00
Stephane Bourque
aa8486c71b Merge pull request #339 from Telecominfraproject/WIFI-13447
https://telecominfraproject.atlassian.net/browse/WIFI-13447
2024-03-13 14:19:32 -07:00
stephb9959
e75d3cfdbb https://telecominfraproject.atlassian.net/browse/WIFI-13447
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-13 14:07:10 -07:00
Stephane Bourque
1a0a6d4a70 Merge pull request #338 from Telecominfraproject/WIFI-13450
https://telecominfraproject.atlassian.net/browse/WIFI-13450
2024-03-05 21:47:06 -08:00
stephb9959
071922c555 https://telecominfraproject.atlassian.net/browse/WIFI-13450
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-03-04 22:41:51 -08:00
stephb9959
4e4b69e672 https://telecominfraproject.atlassian.net/browse/WIFI-13450
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-29 17:35:11 -08:00
stephb9959
3d8f7c1162 https://telecominfraproject.atlassian.net/browse/WIFI-13450
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-29 14:19:12 -08:00
stephb9959
2bf60dbb3f https://telecominfraproject.atlassian.net/browse/WIFI-13450
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-29 11:03:14 -08:00
stephb9959
44bc27e9d4 https://telecominfraproject.atlassian.net/browse/WIFI-13450
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-29 10:58:57 -08:00
stephb9959
f328a72b85 https://telecominfraproject.atlassian.net/browse/WIFI-13450
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-29 10:58:13 -08:00
stephb9959
4cbceb9366 https://telecominfraproject.atlassian.net/browse/WIFI-13447
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-28 23:06:48 -08:00
stephb9959
921267c00a https://telecominfraproject.atlassian.net/browse/WIFI-13434
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-21 08:39:11 -08:00
stephb9959
d63cbce602 https://telecominfraproject.atlassian.net/browse/WIFI-13434
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-20 17:19:26 -08:00
stephb9959
094bba4747 https://telecominfraproject.atlassian.net/browse/WIFI-13434
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-02-20 13:27:17 -08:00
stephb9959
5bee5b1372 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-31 12:11:00 -08:00
stephb9959
45357ad567 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-25 20:35:21 -08:00
stephb9959
8e984a8f0e https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-25 12:50:46 -08:00
stephb9959
4e7babc25f https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-23 22:04:59 -08:00
stephb9959
1acabd4986 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-23 09:57:07 -08:00
stephb9959
d839646dd8 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-22 20:28:34 -08:00
stephb9959
31b52f9bd2 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 10:38:09 -08:00
stephb9959
97bc19b949 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 10:30:40 -08:00
stephb9959
c252e6c5c7 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 10:22:10 -08:00
stephb9959
cef012c333 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 10:16:53 -08:00
stephb9959
6513980525 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 10:14:35 -08:00
stephb9959
adc055f3e8 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 10:08:27 -08:00
stephb9959
6d991e5a48 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 10:02:48 -08:00
stephb9959
ec5031ca83 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 09:39:11 -08:00
stephb9959
19e4e92d92 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-17 07:07:36 -08:00
stephb9959
37feb6a44c https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-11 15:54:24 -08:00
stephb9959
2aaab1207b https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-11 15:42:01 -08:00
Stephane Bourque
7896b071da Merge pull request #337 from Telecominfraproject/WIFI-13280
https://telecominfraproject.atlassian.net/browse/WIFI-13280
2024-01-11 15:18:46 -08:00
stephb9959
e073576692 https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-11 11:45:19 -08:00
stephb9959
65ad9ff96e https://telecominfraproject.atlassian.net/browse/WIFI-13280
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-11 09:21:14 -08:00
stephb9959
08e7900889 https://telecominfraproject.atlassian.net/browse/WIFI-13273
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-10 23:01:43 -08:00
stephb9959
8554481186 https://telecominfraproject.atlassian.net/browse/WIFI-13273
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-08 10:58:32 -08:00
stephb9959
2b246fe1ee https://telecominfraproject.atlassian.net/browse/WIFI-13273
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-05 13:03:57 -08:00
stephb9959
bd37534223 https://telecominfraproject.atlassian.net/browse/WIFI-13273
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-05 12:59:39 -08:00
stephb9959
aa862d3fcf https://telecominfraproject.atlassian.net/browse/WIFI-13273
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-05 12:54:53 -08:00
stephb9959
c6c6eaa4a5 https://telecominfraproject.atlassian.net/browse/WIFI-13273
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-05 12:21:26 -08:00
stephb9959
ffe86a3994 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 22:37:35 -08:00
stephb9959
52123f7dcc https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 22:29:39 -08:00
stephb9959
e430c522ba https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 22:13:49 -08:00
stephb9959
93c236aa79 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 14:25:15 -08:00
stephb9959
c802e35c12 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 14:16:02 -08:00
stephb9959
a59d49e096 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 14:04:08 -08:00
stephb9959
5756d59519 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 14:00:25 -08:00
stephb9959
35aa6fb99d https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 13:39:23 -08:00
stephb9959
fa6d0aa714 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 13:27:10 -08:00
stephb9959
91147f3fbb https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 13:17:03 -08:00
stephb9959
15f3eaa02e https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 13:04:25 -08:00
stephb9959
6305e92399 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 12:48:58 -08:00
stephb9959
3714fd5f05 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 12:00:01 -08:00
stephb9959
19497b88ce https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 11:53:13 -08:00
stephb9959
6a35dc93bf https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 11:46:02 -08:00
stephb9959
8004aa6676 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 11:43:42 -08:00
stephb9959
2c654d3471 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 11:37:25 -08:00
stephb9959
df67141a98 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 11:21:47 -08:00
stephb9959
071330d7f8 https://telecominfraproject.atlassian.net/browse/WIFI-13268
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 11:15:09 -08:00
stephb9959
90f23dca73 https://telecominfraproject.atlassian.net/browse/WIFI-13256
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2024-01-04 08:10:01 -08:00
stephb9959
500688edb7 https://telecominfraproject.atlassian.net/browse/WIFI-13147
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-15 13:29:00 -08:00
Stephane Bourque
222b98d019 Merge pull request #334 from Telecominfraproject/sqlopt1
https://telecominfraproject.atlassian.net/browse/WIFI-13240
2023-12-15 11:49:00 -08:00
67 changed files with 6575 additions and 858 deletions

4
.gitignore vendored
View File

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

2
.idea/.gitignore generated vendored
View File

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

3
.idea/misc.xml generated
View File

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

View File

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

View File

@@ -1,7 +1,8 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
project(owgw VERSION 3.0.0) project(owgw VERSION 3.2.1)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
if(UNIX AND APPLE) if(UNIX AND APPLE)
set(OPENSSL_ROOT_DIR /usr/local/opt/openssl) set(OPENSSL_ROOT_DIR /usr/local/opt/openssl)
@@ -148,6 +149,7 @@ add_executable( owgw
src/RESTAPI/RESTAPI_script_handler.cpp src/RESTAPI/RESTAPI_script_handler.h src/RESTAPI/RESTAPI_script_handler.cpp src/RESTAPI/RESTAPI_script_handler.h
src/RESTAPI/RESTAPI_regulatory.cpp src/RESTAPI/RESTAPI_regulatory.h src/RESTAPI/RESTAPI_regulatory.cpp src/RESTAPI/RESTAPI_regulatory.h
src/RESTAPI/RESTAPI_radiussessions_handler.cpp src/RESTAPI/RESTAPI_radiussessions_handler.h src/RESTAPI/RESTAPI_radiussessions_handler.cpp src/RESTAPI/RESTAPI_radiussessions_handler.h
src/storage/storage_blacklist.cpp src/storage/storage_tables.cpp src/storage/storage_logs.cpp src/storage/storage_blacklist.cpp src/storage/storage_tables.cpp src/storage/storage_logs.cpp
src/storage/storage_command.cpp src/storage/storage_healthcheck.cpp src/storage/storage_statistics.cpp src/storage/storage_command.cpp src/storage/storage_healthcheck.cpp src/storage/storage_statistics.cpp
src/storage/storage_device.cpp src/storage/storage_capabilities.cpp src/storage/storage_defconfig.cpp src/storage/storage_device.cpp src/storage/storage_capabilities.cpp src/storage/storage_defconfig.cpp

View File

@@ -1,7 +1,7 @@
ARG DEBIAN_VERSION=11.5-slim ARG DEBIAN_VERSION=11.5-slim
ARG POCO_VERSION=poco-tip-v2 ARG POCO_VERSION=poco-tip-v2
ARG CPPKAFKA_VERSION=tip-v1 ARG CPPKAFKA_VERSION=tip-v1
ARG VALIJASON_VERSION=tip-v1 ARG VALIJASON_VERSION=tip-v1.0.2
ARG APP_NAME=owgw ARG APP_NAME=owgw
ARG APP_HOME_DIR=/openwifi ARG APP_HOME_DIR=/openwifi
@@ -17,8 +17,8 @@ FROM build-base AS poco-build
ARG POCO_VERSION ARG POCO_VERSION
ADD https://api.github.com/repos/AriliaWireless/poco/git/refs/tags/${POCO_VERSION} version.json ADD https://api.github.com/repos/Telecominfraproject/wlan-cloud-lib-poco/git/refs/tags/${POCO_VERSION} version.json
RUN git clone https://github.com/AriliaWireless/poco --branch ${POCO_VERSION} /poco RUN git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch ${POCO_VERSION} /poco
WORKDIR /poco WORKDIR /poco
RUN mkdir cmake-build RUN mkdir cmake-build
@@ -31,8 +31,8 @@ FROM build-base AS cppkafka-build
ARG CPPKAFKA_VERSION ARG CPPKAFKA_VERSION
ADD https://api.github.com/repos/AriliaWireless/cppkafka/git/refs/tags/${CPPKAFKA_VERSION} version.json ADD https://api.github.com/repos/Telecominfraproject/wlan-cloud-lib-cppkafka/git/refs/tags/${CPPKAFKA_VERSION} version.json
RUN git clone https://github.com/AriliaWireless/cppkafka --branch ${CPPKAFKA_VERSION} /cppkafka RUN git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch ${CPPKAFKA_VERSION} /cppkafka
WORKDIR /cppkafka WORKDIR /cppkafka
RUN mkdir cmake-build RUN mkdir cmake-build
@@ -45,8 +45,8 @@ FROM build-base AS valijson-build
ARG VALIJASON_VERSION ARG VALIJASON_VERSION
ADD https://api.github.com/repos/AriliaWireless/valijson/git/refs/tags/${VALIJASON_VERSION} version.json ADD https://api.github.com/repos/Telecominfraproject/wlan-cloud-lib-valijson/git/refs/tags/${VALIJASON_VERSION} version.json
RUN git clone https://github.com/AriliaWireless/valijson --branch ${VALIJASON_VERSION} /valijson RUN git clone https://github.com/Telecominfraproject/wlan-cloud-lib-valijson --branch ${VALIJASON_VERSION} /valijson
WORKDIR /valijson WORKDIR /valijson
RUN mkdir cmake-build RUN mkdir cmake-build

View File

@@ -306,8 +306,54 @@ The device should answer:
}, },
"id" : <same number> "id" : <same number>
} }
```
#### Controller wants the device to apply a given fixed configuration
Controller sends this command when it requires the device to apply fixed configuration, eg. country code. The device
should respond with message indicating failure or success.
```json
{ "jsonrpc" : "2.0",
"method" : "fixedconfig",
"params" : {
"serial" : <serial number>,
"when" : Optional - <UTC time when to apply this config, 0 means immediate, this is a suggestion>
"country" : "<country-code>"
},
}
```
If AP supports compressed configuration feature by inidcating `compress_cmd=true` in its capabilities, controller
will send a compressed configuration message where configuration payload (i.e. contents of `params`) is compressed
and encoded in base64 format:
```json
{ "jsonrpc" : "2.0",
"method" : "configure",
"params" : {
"compress_64" : "<b64 encoded zlib compressed payload>",
"compress_sz" : "<size of uncompressed data in bytes>"
},
"id" : <some number>
}
```
The device should answer:
```json
{ "jsonrpc" : "2.0",
"result" : {
"serial": <serial number>,
"status": {
"error": 0 or an error number,
"text": <description of the error or success, eg. "Applied fixed config, rebooting">
},
"uuid": <UUID>
}
}
``` ```
##### The Answer ##### The Answer
The device can answer and tell the controller it has rejected certain parts of the config and potentially replaced them with The device can answer and tell the controller it has rejected certain parts of the config and potentially replaced them with
appropriate values. This could be used to allow a device to replace frequencies for the regions it is located in. The device appropriate values. This could be used to allow a device to replace frequencies for the regions it is located in. The device
@@ -355,6 +401,39 @@ The device should answer:
- 1 : the device is busy but will reboot soon. `text` may indicate why. - 1 : the device is busy but will reboot soon. `text` may indicate why.
- 2 : the device will not reboot. `text` contains information as to why. - 2 : the device will not reboot. `text` contains information as to why.
#### Controller wants to power-cycle PoE port(s)
Controller sends this command to power-cycle 1 or more PoE ports
```json
{ "jsonrpc" : "2.0" ,
"method" : "powercycle" ,
"params" : {
"serial" : <serial number> ,
"ports" : [ { "name" : "Ethernet1", "cycle" : 5000}, { "name" : "Ethernet8", "cycle" : 10000 } ],
"when" : Optional - <UTC time when to reboot, 0 mean immediately, this is a suggestion>
},
"id" : <some number>
}
```
The device should answer:
```json
{ "jsonrpc" : "2.0" ,
"result" : {
"serial" : <serial number> ,
"status" : {
"error" : 0 or an error number,
"text" : [ "Error 1" , "Error 2" ],
"when" : <time when this will be performed as UTC seconds>,
},
"id" : <same id from request>
}
```
###### Error codes
- 0 : is rebooting at `when` seconds.
- 1 : the device is busy but will reboot soon. `text` may indicate why.
- 2 : the device will not reboot. `text` contains information as to why.
#### Controller wants the device to upgrade its firmware #### Controller wants the device to upgrade its firmware
Controller sends this command when it believes the device should upgrade its firmware. Controller sends this command when it believes the device should upgrade its firmware.
```json ```json

2
build
View File

@@ -1 +1 @@
63 3

85
ols_samples/sample1.json Normal file
View File

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

View File

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

View File

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

View File

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

View File

@@ -2,37 +2,32 @@
// Created by stephane bourque on 2022-02-03. // Created by stephane bourque on 2022-02-03.
// //
#include "AP_WS_Connection.h"
#include "Poco/Base64Decoder.h" #include <Poco/Base64Decoder.h>
#include "Poco/Net/Context.h" #include <Poco/Net/Context.h>
#include "Poco/Net/HTTPServerRequestImpl.h" #include <Poco/Net/HTTPServerRequestImpl.h>
#include "Poco/Net/HTTPServerResponseImpl.h" #include <Poco/Net/HTTPServerResponseImpl.h>
#include "Poco/Net/NetException.h" #include <Poco/Net/NetException.h>
#include "Poco/Net/SSLException.h" #include <Poco/Net/SSLException.h>
#include "Poco/Net/SecureStreamSocketImpl.h" #include <Poco/Net/SecureStreamSocketImpl.h>
#include "Poco/Net/WebSocketImpl.h" #include <Poco/Net/WebSocketImpl.h>
#include "Poco/zlib.h"
#include "AP_WS_Server.h" #include <framework/KafkaManager.h>
#include "CentralConfig.h" #include <framework/MicroServiceFuncs.h>
#include "CommandManager.h" #include <framework/utils.h>
#include "ConfigurationCache.h" #include <framework/ow_constants.h>
#include "StorageService.h"
#include "TelemetryStream.h"
#include "GWKafkaEvents.h" #include <fmt/format.h>
#include "UI_GW_WebSocketNotifications.h"
#include "framework/KafkaManager.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.h"
#include "fmt/format.h" #include <AP_WS_Connection.h>
#include <AP_WS_Server.h>
#include "framework/ow_constants.h" #include <CentralConfig.h>
#include <CommandManager.h>
#include "RADIUSSessionTracker.h" #include <StorageService.h>
#include "RADIUS_proxy_server.h" #include <RADIUSSessionTracker.h>
#include <RADIUS_proxy_server.h>
#include <GWKafkaEvents.h>
#include <UI_GW_WebSocketNotifications.h>
namespace OpenWifi { namespace OpenWifi {
@@ -60,6 +55,8 @@ namespace OpenWifi {
WS_->setKeepAlive(true); WS_->setKeepAlive(true);
WS_->setBlocking(false); WS_->setBlocking(false);
uuid_ = MicroServiceRandom(std::numeric_limits<std::uint64_t>::max()-1); uuid_ = MicroServiceRandom(std::numeric_limits<std::uint64_t>::max()-1);
AP_WS_Server()->IncrementConnectionCount();
} }
void AP_WS_Connection::Start() { void AP_WS_Connection::Start() {
@@ -79,14 +76,11 @@ namespace OpenWifi {
} }
AP_WS_Connection::~AP_WS_Connection() { AP_WS_Connection::~AP_WS_Connection() {
// poco_information(Logger_, fmt::format("DESTRUCTOR({}): 0 - Session={} Connection closed.", SerialNumber_,
// State_.sessionId));
std::lock_guard G(ConnectionMutex_); std::lock_guard G(ConnectionMutex_);
// poco_information(Logger_, fmt::format("DESTRUCTOR({}): 1 - Session={} Connection closed.", SerialNumber_, AP_WS_Server()->DecrementConnectionCount();
// State_.sessionId)); EndConnection();
EndConnection(false);
poco_debug(Logger_, fmt::format("TERMINATION({}): Session={}, Connection removed.", SerialNumber_, poco_debug(Logger_, fmt::format("TERMINATION({}): Session={}, Connection removed.", SerialNumber_,
State_.sessionId)); State_.sessionId));
} }
static void NotifyKafkaDisconnect(const std::string &SerialNumber, std::uint64_t uuid) { static void NotifyKafkaDisconnect(const std::string &SerialNumber, std::uint64_t uuid) {
@@ -102,7 +96,7 @@ namespace OpenWifi {
} }
} }
void AP_WS_Connection::EndConnection(bool Clean) { void AP_WS_Connection::EndConnection() {
bool expectedValue=false; bool expectedValue=false;
if (Dead_.compare_exchange_strong(expectedValue,true,std::memory_order_release,std::memory_order_relaxed)) { if (Dead_.compare_exchange_strong(expectedValue,true,std::memory_order_release,std::memory_order_relaxed)) {
@@ -128,9 +122,7 @@ namespace OpenWifi {
if(!SerialNumber_.empty()) { if(!SerialNumber_.empty()) {
DeviceDisconnectionCleanup(SerialNumber_, uuid_); DeviceDisconnectionCleanup(SerialNumber_, uuid_);
} }
AP_WS_Server()->AddCleanupSession(State_.sessionId, SerialNumberInt_);
if(Clean)
AP_WS_Server()->EndSession(State_.sessionId, SerialNumberInt_);
} }
} }
@@ -569,14 +561,14 @@ namespace OpenWifi {
void AP_WS_Connection::OnSocketShutdown( void AP_WS_Connection::OnSocketShutdown(
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) { [[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
poco_trace(Logger_, fmt::format("SOCKET-SHUTDOWN({}): Closing.", CId_)); poco_trace(Logger_, fmt::format("SOCKET-SHUTDOWN({}): Closing.", CId_));
std::lock_guard G(ConnectionMutex_); // std::lock_guard G(ConnectionMutex_);
return EndConnection(); return EndConnection();
} }
void AP_WS_Connection::OnSocketError( void AP_WS_Connection::OnSocketError(
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) { [[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
poco_trace(Logger_, fmt::format("SOCKET-ERROR({}): Closing.", CId_)); poco_trace(Logger_, fmt::format("SOCKET-ERROR({}): Closing.", CId_));
std::lock_guard G(ConnectionMutex_); // std::lock_guard G(ConnectionMutex_);
return EndConnection(); return EndConnection();
} }
@@ -586,7 +578,7 @@ namespace OpenWifi {
if (Dead_) // we are dead, so we do not process anything. if (Dead_) // we are dead, so we do not process anything.
return; return;
std::lock_guard DeviceLock(ConnectionMutex_); std::lock_guard G(ConnectionMutex_);
State_.LastContact = LastContact_ = Utils::Now(); State_.LastContact = LastContact_ = Utils::Now();
if (AP_WS_Server()->Running() && (DeviceValidated_ || ValidatedDevice())) { if (AP_WS_Server()->Running() && (DeviceValidated_ || ValidatedDevice())) {
@@ -902,25 +894,25 @@ namespace OpenWifi {
try { try {
Poco::JSON::Parser P; Poco::JSON::Parser P;
auto Stats = P.parse(LastStats).extract<Poco::JSON::Object::Ptr>(); auto Stats = P.parse(LastStats).extract<Poco::JSON::Object::Ptr>();
hasGPS_ = Stats->isObject("gps"); State_.hasGPS = Stats->isObject("gps");
auto Unit = Stats->getObject("unit"); auto Unit = Stats->getObject("unit");
auto Memory = Unit->getObject("memory"); auto Memory = Unit->getObject("memory");
std::uint64_t TotalMemory = Memory->get("total"); std::uint64_t TotalMemory = Memory->get("total");
std::uint64_t FreeMemory = Memory->get("free"); std::uint64_t FreeMemory = Memory->get("free");
if (TotalMemory > 0) { if (TotalMemory > 0) {
memory_used_ = State_.memoryUsed =
(100.0 * ((double)TotalMemory - (double)FreeMemory)) / (double)TotalMemory; (100.0 * ((double)TotalMemory - (double)FreeMemory)) / (double)TotalMemory;
} }
if (Unit->isArray("load")) { if (Unit->isArray("load")) {
Poco::JSON::Array::Ptr Load = Unit->getArray("load"); Poco::JSON::Array::Ptr Load = Unit->getArray("load");
if (Load->size() > 1) { if (Load->size() > 1) {
cpu_load_ = Load->get(1); State_.load = Load->get(1);
} }
} }
if (Unit->isArray("temperature")) { if (Unit->isArray("temperature")) {
Poco::JSON::Array::Ptr Temperature = Unit->getArray("temperature"); Poco::JSON::Array::Ptr Temperature = Unit->getArray("temperature");
if (Temperature->size() > 1) { if (Temperature->size() > 1) {
temperature_ = Temperature->get(0); State_.temperature = Temperature->get(0);
} }
} }
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {

View File

@@ -30,7 +30,7 @@ namespace OpenWifi {
Poco::Logger &L, std::pair<std::shared_ptr<Poco::Net::SocketReactor>, std::shared_ptr<LockedDbSession>> R); Poco::Logger &L, std::pair<std::shared_ptr<Poco::Net::SocketReactor>, std::shared_ptr<LockedDbSession>> R);
~AP_WS_Connection(); ~AP_WS_Connection();
void EndConnection(bool Clean = true); void EndConnection();
void ProcessJSONRPCEvent(Poco::JSON::Object::Ptr &Doc); void ProcessJSONRPCEvent(Poco::JSON::Object::Ptr &Doc);
void ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc); void ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc);
void ProcessIncomingFrame(); void ProcessIncomingFrame();
@@ -79,14 +79,14 @@ namespace OpenWifi {
} }
} }
inline GWObjects::DeviceRestrictions GetRestrictions() {
std::lock_guard G(ConnectionMutex_);
return Restrictions_;
}
[[nodiscard]] inline bool HasGPS() const { return hasGPS_; } [[nodiscard]] inline bool HasGPS() const { return hasGPS_; }
[[nodiscard]] bool ValidatedDevice(); [[nodiscard]] bool ValidatedDevice();
inline void GetRestrictions(GWObjects::DeviceRestrictions &R) {
std::lock_guard G(ConnectionMutex_);
R = Restrictions_;
}
inline bool GetTelemetryParameters(bool &Reporting, uint64_t &Interval, inline bool GetTelemetryParameters(bool &Reporting, uint64_t &Interval,
uint64_t &WebSocketTimer, uint64_t &KafkaTimer, uint64_t &WebSocketTimer, uint64_t &KafkaTimer,
uint64_t &WebSocketCount, uint64_t &KafkaCount, uint64_t &WebSocketCount, uint64_t &KafkaCount,
@@ -105,14 +105,10 @@ namespace OpenWifi {
friend class AP_WS_Server; friend class AP_WS_Server;
inline GWObjects::DeviceRestrictions Restrictions() {
std::lock_guard G(ConnectionMutex_);
return Restrictions_;
}
void Start(); void Start();
private: private:
std::recursive_mutex ConnectionMutex_; mutable std::recursive_mutex ConnectionMutex_;
std::mutex TelemetryMutex_; std::mutex TelemetryMutex_;
Poco::Logger &Logger_; Poco::Logger &Logger_;
std::shared_ptr<Poco::Net::SocketReactor> Reactor_; std::shared_ptr<Poco::Net::SocketReactor> Reactor_;
@@ -148,7 +144,7 @@ namespace OpenWifi {
std::double_t memory_used_=0.0, cpu_load_ = 0.0, temperature_ = 0.0; std::double_t memory_used_=0.0, cpu_load_ = 0.0, temperature_ = 0.0;
std::uint64_t uuid_=0; std::uint64_t uuid_=0;
bool Simulated_=false; bool Simulated_=false;
std::uint64_t LastContact_=0; std::atomic_uint64_t LastContact_=0;
static inline std::atomic_uint64_t ConcurrentStartingDevices_ = 0; static inline std::atomic_uint64_t ConcurrentStartingDevices_ = 0;

View File

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

View File

@@ -83,6 +83,8 @@ namespace OpenWifi {
State_.Address = Utils::FormatIPv6(WS_->peerAddress().toString()); State_.Address = Utils::FormatIPv6(WS_->peerAddress().toString());
CId_ = SerialNumber_ + "@" + CId_; CId_ = SerialNumber_ + "@" + CId_;
auto Platform = Poco::toLower(Caps.Platform());
if(ParamsObj->has("reason")) { if(ParamsObj->has("reason")) {
State_.connectReason = ParamsObj->get("reason").toString(); State_.connectReason = ParamsObj->get("reason").toString();
} }
@@ -204,8 +206,13 @@ namespace OpenWifi {
++Updated; ++Updated;
} }
if (Compatible_ != DeviceInfo.DeviceType) { if (Compatible_ != DeviceInfo.Compatible) {
DeviceInfo.DeviceType = Compatible_; DeviceInfo.Compatible = Compatible_;
++Updated;
}
if (Platform != DeviceInfo.DeviceType) {
DeviceInfo.DeviceType = Platform;
++Updated; ++Updated;
} }
@@ -227,10 +234,11 @@ namespace OpenWifi {
if (Updated) { if (Updated) {
StorageService()->UpdateDevice(DbSession_->Session(), DeviceInfo); StorageService()->UpdateDevice(DbSession_->Session(), DeviceInfo);
} }
}
if(!Simulated_) { if(!Simulated_) {
uint64_t UpgradedUUID = 0; uint64_t UpgradedUUID = 0;
LookForUpgrade(DbSession_->Session(), UUID, UpgradedUUID); if (LookForUpgrade(DbSession_->Session(), UUID, UpgradedUUID)) {
State_.UUID = UpgradedUUID; State_.UUID = UpgradedUUID;
} }
} }

View File

@@ -26,6 +26,7 @@ namespace OpenWifi {
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID); uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
auto Sanity = ParamsObj->get(uCentralProtocol::SANITY); auto Sanity = ParamsObj->get(uCentralProtocol::SANITY);
State_.sanity = Sanity;
auto CheckData = ParamsObj->get(uCentralProtocol::DATA).toString(); auto CheckData = ParamsObj->get(uCentralProtocol::DATA).toString();
if (CheckData.empty()) if (CheckData.empty())
CheckData = uCentralProtocol::EMPTY_JSON_DOC; CheckData = uCentralProtocol::EMPTY_JSON_DOC;

View File

@@ -58,7 +58,7 @@ namespace OpenWifi {
} }
StateUtils::ComputeAssociations(StateObj, State_.Associations_2G, StateUtils::ComputeAssociations(StateObj, State_.Associations_2G,
State_.Associations_5G, State_.Associations_6G); State_.Associations_5G, State_.Associations_6G, State_.uptime);
if (KafkaManager()->Enabled() && !AP_WS_Server()->KafkaDisableState()) { if (KafkaManager()->Enabled() && !AP_WS_Server()->KafkaDisableState()) {
KafkaManager()->PostMessage(KafkaTopics::STATE, SerialNumber_, *ParamsObj); KafkaManager()->PostMessage(KafkaTopics::STATE, SerialNumber_, *ParamsObj);

View File

@@ -7,10 +7,12 @@
#include <mutex> #include <mutex>
#include <string> #include <string>
#include "Poco/Environment.h" #include <framework/utils.h>
#include "Poco/Net/SocketAcceptor.h"
#include <Poco/Environment.h>
#include <Poco/Net/SocketAcceptor.h>
#include <Poco/Data/SessionPool.h> #include <Poco/Data/SessionPool.h>
#include "framework/utils.h"
#include <StorageService.h> #include <StorageService.h>
namespace OpenWifi { namespace OpenWifi {
@@ -55,7 +57,7 @@ namespace OpenWifi {
DbSessions_.clear(); DbSessions_.clear();
} }
std::pair<std::shared_ptr<Poco::Net::SocketReactor>, std::shared_ptr<LockedDbSession> > NextReactor() { auto NextReactor() {
std::lock_guard Lock(Mutex_); std::lock_guard Lock(Mutex_);
NextReactor_++; NextReactor_++;
NextReactor_ %= NumberOfThreads_; NextReactor_ %= NumberOfThreads_;

View File

@@ -6,21 +6,23 @@
// Arilia Wireless Inc. // Arilia Wireless Inc.
// //
#include "Poco/Net/Context.h" #include <Poco/Net/Context.h>
#include "Poco/Net/HTTPHeaderStream.h" #include <Poco/Net/HTTPHeaderStream.h>
#include "Poco/Net/HTTPServerRequest.h" #include <Poco/Net/HTTPServerRequest.h>
#include "AP_WS_Connection.h" #include <AP_WS_Connection.h>
#include "AP_WS_Server.h" #include <AP_WS_Server.h>
#include "ConfigurationCache.h" #include <ConfigurationCache.h>
#include "TelemetryStream.h" #include <TelemetryStream.h>
#include "UI_GW_WebSocketNotifications.h" #include <fmt/format.h>
#include "fmt/format.h"
#include "framework/MicroServiceFuncs.h" #include <framework/MicroServiceFuncs.h>
#include "framework/utils.h" #include <framework/utils.h>
#include <framework/KafkaManager.h> #include <framework/KafkaManager.h>
#include <UI_GW_WebSocketNotifications.h>
namespace OpenWifi { namespace OpenWifi {
class AP_WS_RequestHandler : public Poco::Net::HTTPRequestHandler { class AP_WS_RequestHandler : public Poco::Net::HTTPRequestHandler {
@@ -198,9 +200,53 @@ namespace OpenWifi {
Running_ = true; Running_ = true;
GarbageCollector_.setName("ws:garbage"); GarbageCollector_.setName("ws:garbage");
GarbageCollector_.start(*this); GarbageCollector_.start(*this);
std::thread CleanupThread([this](){ CleanupSessions(); });
CleanupThread.detach();
return 0; return 0;
} }
bool AP_WS_Server::Disconnect(uint64_t SerialNumber) {
std::shared_ptr<AP_WS_Connection> Connection;
{
auto hashIndex = MACHash::Hash(SerialNumber);
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == SerialNumbers_[hashIndex].end() || DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
SerialNumbers_[hashIndex].erase(DeviceHint);
}
{
auto H = SessionHash::Hash(Connection->State_.sessionId);
std::lock_guard SessionLock(SessionMutex_[H]);
Sessions_[H].erase(Connection->State_.sessionId);
}
return true;
}
void AP_WS_Server::CleanupSessions() {
while(Running_) {
std::this_thread::sleep_for(std::chrono::seconds(10));
while(Running_ && !CleanupSessions_.empty()) {
std::pair<uint64_t, uint64_t> Session;
{
std::lock_guard G(CleanupMutex_);
Session = CleanupSessions_.front();
CleanupSessions_.pop_front();
}
poco_trace(this->Logger(),fmt::format("Cleaning up session: {} for device: {}", Session.first, Utils::IntToSerialNumber(Session.second)));
EndSession(Session.first, Session.second);
}
}
}
void AP_WS_Server::run() { void AP_WS_Server::run() {
uint64_t last_log = Utils::Now(), uint64_t last_log = Utils::Now(),
last_zombie_run = 0, last_zombie_run = 0,
@@ -223,7 +269,6 @@ namespace OpenWifi {
try { try {
poco_information(LocalLogger, poco_information(LocalLogger,
fmt::format("Garbage collecting zombies... (step 1)")); fmt::format("Garbage collecting zombies... (step 1)"));
NumberOfConnectedDevices_ = 0;
NumberOfConnectingDevices_ = 0; NumberOfConnectingDevices_ = 0;
AverageDeviceConnectionTime_ = 0; AverageDeviceConnectionTime_ = 0;
int waits = 0; int waits = 0;
@@ -235,55 +280,49 @@ namespace OpenWifi {
waits = 0; waits = 0;
auto hint = SerialNumbers_[hashIndex].begin(); auto hint = SerialNumbers_[hashIndex].begin();
while (hint != end(SerialNumbers_[hashIndex])) { while (hint != end(SerialNumbers_[hashIndex])) {
if (hint->second == nullptr) { if (hint->second == nullptr) {
poco_information( poco_information(
LocalLogger, LocalLogger,
fmt::format("Dead device found in hash index {}", hashIndex)); fmt::format("Dead device found in hash index {}", hashIndex));
// hint = SerialNumbers_[hashIndex].erase(hint); hint = SerialNumbers_[hashIndex].erase(hint);
hint++; } else {
continue; auto Device = hint->second;
}
auto Device = hint->second;
if(Device->ConnectionMutex_.try_lock()) {
auto RightNow = Utils::Now(); auto RightNow = Utils::Now();
if (RightNow > Device->LastContact_ && if (Device->Dead_) {
(RightNow - Device->LastContact_) > SessionTimeOut_) { AddCleanupSession(Device->State_.sessionId, Device->SerialNumberInt_);
++hint;
// hint = SerialNumbers_[hashIndex].erase(hint);
} else if (RightNow > Device->LastContact_ &&
(RightNow - Device->LastContact_) > SessionTimeOut_) {
poco_information( poco_information(
LocalLogger, LocalLogger,
fmt::format("{}: Session seems idle. Controller disconnecting device.", fmt::format(
Device->SerialNumber_)); "{}: Session seems idle. Controller disconnecting device.",
hint = SerialNumbers_[hashIndex].erase(hint); Device->SerialNumber_));
} else if (Device->State_.Connected) { // hint = SerialNumbers_[hashIndex].erase(hint);
NumberOfConnectedDevices_++; AddCleanupSession(Device->State_.sessionId, Device->SerialNumberInt_);
total_connected_time +=
(RightNow - Device->State_.started);
++hint; ++hint;
} else { } else {
if (Device->State_.Connected) {
total_connected_time +=
(RightNow - Device->State_.started);
}
++hint; ++hint;
} }
Device->ConnectionMutex_.unlock();
continue;
} else {
poco_warning(LocalLogger, fmt::format("Could not lock device mutex for {}",
Device->SerialNumber_));
} }
++NumberOfConnectingDevices_;
++hint;
} }
SerialNumbersMutex_[hashIndex].unlock(); SerialNumbersMutex_[hashIndex].unlock();
break; break;
} else if (waits < 5) { } else if (waits < 5) {
waits++; waits++;
std::this_thread::sleep_for(std::chrono::milliseconds(10)); Poco::Thread::trySleep(10);
} else { } else {
break; break;
} }
} }
} }
poco_information(LocalLogger, poco_information(LocalLogger, fmt::format("Garbage collecting zombies... (step 2)"));
fmt::format("Garbage collecting zombies... (step 2)"));
LeftOverSessions_ = 0; LeftOverSessions_ = 0;
for (int i = 0; i < SessionHash::HashMax(); i++) { for (int i = 0; i < SessionHash::HashMax(); i++) {
waits = 0; waits = 0;
@@ -295,6 +334,10 @@ namespace OpenWifi {
while (hint != end(Sessions_[i])) { while (hint != end(Sessions_[i])) {
if (hint->second == nullptr) { if (hint->second == nullptr) {
hint = Sessions_[i].erase(hint); hint = Sessions_[i].erase(hint);
} else if (hint->second->Dead_) {
// hint = Sessions_[i].erase(hint);
AddCleanupSession(hint->second->State_.sessionId, hint->second->SerialNumberInt_);
++hint;
} else if (RightNow > hint->second->LastContact_ && } else if (RightNow > hint->second->LastContact_ &&
(RightNow - hint->second->LastContact_) > (RightNow - hint->second->LastContact_) >
SessionTimeOut_) { SessionTimeOut_) {
@@ -302,7 +345,9 @@ namespace OpenWifi {
LocalLogger, LocalLogger,
fmt::format("{}: Session seems idle. Controller disconnecting device.", fmt::format("{}: Session seems idle. Controller disconnecting device.",
hint->second->SerialNumber_)); hint->second->SerialNumber_));
hint = Sessions_[i].erase(hint); AddCleanupSession(hint->second->State_.sessionId, hint->second->SerialNumberInt_);
++hint;
// hint = Sessions_[i].erase(hint);
} else { } else {
++LeftOverSessions_; ++LeftOverSessions_;
++hint; ++hint;
@@ -311,7 +356,7 @@ namespace OpenWifi {
SessionMutex_[i].unlock(); SessionMutex_[i].unlock();
break; break;
} else if (waits < 5) { } else if (waits < 5) {
std::this_thread::sleep_for(std::chrono::milliseconds(10)); Poco::Thread::trySleep(10);
waits++; waits++;
} else { } else {
break; break;
@@ -319,10 +364,9 @@ namespace OpenWifi {
} }
} }
AverageDeviceConnectionTime_ = AverageDeviceConnectionTime_ = NumberOfConnectedDevices_ > 0
NumberOfConnectedDevices_ > 0 ? total_connected_time / NumberOfConnectedDevices_
? total_connected_time / NumberOfConnectedDevices_ : 0;
: 0;
poco_information(LocalLogger, fmt::format("Garbage collecting zombies done...")); poco_information(LocalLogger, fmt::format("Garbage collecting zombies done..."));
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
poco_error(LocalLogger, fmt::format("Poco::Exception: Garbage collecting zombies failed: {}", E.displayText())); poco_error(LocalLogger, fmt::format("Poco::Exception: Garbage collecting zombies failed: {}", E.displayText()));
@@ -332,47 +376,49 @@ namespace OpenWifi {
poco_error(LocalLogger, fmt::format("exception:Garbage collecting zombies failed: {}", "unknown")); poco_error(LocalLogger, fmt::format("exception:Garbage collecting zombies failed: {}", "unknown"));
} }
} else { }
NumberOfConnectedDevices_=0;
for(int i=0;i<MACHash::HashMax();i++) { if(NumberOfConnectedDevices_) {
std::lock_guard Lock(SerialNumbersMutex_[i]); if (last_garbage_run > 0) {
NumberOfConnectedDevices_ += SerialNumbers_[i].size(); AverageDeviceConnectionTime_ += (now - last_garbage_run);
}
if(NumberOfConnectedDevices_) {
if (last_garbage_run > 0) {
AverageDeviceConnectionTime_ += (now - last_garbage_run);
}
} else {
AverageDeviceConnectionTime_ = 0;
} }
} }
if ((now - last_log) > 60) { try {
last_log = now; if ((now - last_log) > 60) {
poco_information(LocalLogger, last_log = now;
fmt::format("Active AP connections: {} Connecting: {} Average connection time: {} seconds. Left Over Sessions: {}", poco_information(
NumberOfConnectedDevices_, NumberOfConnectingDevices_, LocalLogger,
AverageDeviceConnectionTime_, LeftOverSessions_)); fmt::format("Active AP connections: {} Connecting: {} Average connection time: {} seconds. Left Over Sessions: {}",
NumberOfConnectedDevices_, NumberOfConnectingDevices_,
AverageDeviceConnectionTime_, LeftOverSessions_));
}
GWWebSocketNotifications::NumberOfConnection_t Notification;
Notification.content.numberOfConnectingDevices = NumberOfConnectingDevices_;
Notification.content.numberOfDevices = NumberOfConnectedDevices_;
Notification.content.averageConnectedTime = AverageDeviceConnectionTime_;
GetTotalDataStatistics(Notification.content.tx, Notification.content.rx);
GWWebSocketNotifications::NumberOfConnections(Notification);
Poco::JSON::Object KafkaNotification;
Notification.to_json(KafkaNotification);
Poco::JSON::Object FullEvent;
FullEvent.set("type", "load-update");
FullEvent.set("timestamp", now);
FullEvent.set("payload", KafkaNotification);
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, "system", FullEvent);
LocalLogger.information(fmt::format("Garbage collection finished run."));
last_garbage_run = now;
} catch (const Poco::Exception &E) {
LocalLogger.error(fmt::format("Poco::Exception: Garbage collecting failed: {}", E.displayText()));
} catch (const std::exception &E) {
LocalLogger.error(fmt::format("std::exception: Garbage collecting failed: {}", E.what()));
} catch (...) {
LocalLogger.error(fmt::format("exception:Garbage collecting failed: {}", "unknown"));
} }
GWWebSocketNotifications::NumberOfConnection_t Notification;
Notification.content.numberOfConnectingDevices = NumberOfConnectingDevices_;
Notification.content.numberOfDevices = NumberOfConnectedDevices_;
Notification.content.averageConnectedTime = AverageDeviceConnectionTime_;
GetTotalDataStatistics(Notification.content.tx,Notification.content.rx);
GWWebSocketNotifications::NumberOfConnections(Notification);
Poco::JSON::Object KafkaNotification;
Notification.to_json(KafkaNotification);
Poco::JSON::Object FullEvent;
FullEvent.set("type", "load-update");
FullEvent.set("timestamp", now);
FullEvent.set("payload", KafkaNotification);
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, "system", FullEvent);
LocalLogger.information(fmt::format("Garbage collection finished run." ));
last_garbage_run = now;
} }
LocalLogger.information(fmt::format("Garbage collector done for the day." )); LocalLogger.information(fmt::format("Garbage collector done for the day." ));
} }
@@ -409,15 +455,17 @@ namespace OpenWifi {
} }
bool AP_WS_Server::GetStatistics(uint64_t SerialNumber, std::string &Statistics) const { bool AP_WS_Server::GetStatistics(uint64_t SerialNumber, std::string &Statistics) const {
std::shared_ptr<AP_WS_Connection> Connection;
auto hashIndex = MACHash::Hash(SerialNumber); {
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]); auto hashIndex = MACHash::Hash(SerialNumber);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber); std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
if (Device == SerialNumbers_[hashIndex].end() || Device->second == nullptr) { auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
return false; if (DeviceHint == SerialNumbers_[hashIndex].end() || DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
} }
Device->second->GetLastStats(Statistics); Connection->GetLastStats(Statistics);
return true; return true;
} }
@@ -439,49 +487,63 @@ namespace OpenWifi {
bool AP_WS_Server::GetHealthcheck(uint64_t SerialNumber, bool AP_WS_Server::GetHealthcheck(uint64_t SerialNumber,
GWObjects::HealthCheck &CheckData) const { GWObjects::HealthCheck &CheckData) const {
std::shared_ptr<AP_WS_Connection> Connection;
auto hashIndex = MACHash::Hash(SerialNumber); {
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]); auto hashIndex = MACHash::Hash(SerialNumber);
auto Device = SerialNumbers_[hashIndex].find(SerialNumber); std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
if (Device == SerialNumbers_[hashIndex].end() || Device->second == nullptr) { auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
return false; if (Device == SerialNumbers_[hashIndex].end() || Device->second == nullptr) {
return false;
}
Connection = Device->second;
} }
Device->second->GetLastHealthCheck(CheckData); Connection->GetLastHealthCheck(CheckData);
return true; return true;
} }
void AP_WS_Server::StartSession(uint64_t session_id, uint64_t SerialNumber) { void AP_WS_Server::StartSession(uint64_t session_id, uint64_t SerialNumber) {
auto deviceHash = MACHash::Hash(SerialNumber);
auto sessionHash = SessionHash::Hash(session_id); auto sessionHash = SessionHash::Hash(session_id);
std::lock_guard SessionLock(SessionMutex_[sessionHash]); std::shared_ptr<AP_WS_Connection> Connection;
auto SessionHint = Sessions_[sessionHash].find(session_id); {
if (SessionHint != end(Sessions_[sessionHash])) { std::lock_guard SessionLock(SessionMutex_[sessionHash]);
std::lock_guard Lock(SerialNumbersMutex_[deviceHash]); auto SessionHint = Sessions_[sessionHash].find(session_id);
SerialNumbers_[deviceHash][SerialNumber] = SessionHint->second; if (SessionHint == end(Sessions_[sessionHash])) {
return;
}
Connection = SessionHint->second;
Sessions_[sessionHash].erase(SessionHint); Sessions_[sessionHash].erase(SessionHint);
} else {
poco_error(Logger(), fmt::format("StartSession: Could not find session '{}'", session_id));
} }
auto deviceHash = MACHash::Hash(SerialNumber);
std::lock_guard DeviceLock(SerialNumbersMutex_[deviceHash]);
SerialNumbers_[deviceHash][SerialNumber] = Connection;
} }
bool AP_WS_Server::EndSession(uint64_t session_id, uint64_t SerialNumber) { bool AP_WS_Server::EndSession(uint64_t session_id, uint64_t SerialNumber) {
{ {
poco_trace(Logger(), fmt::format("Ending session 1: {} for device: {}", session_id, Utils::IntToSerialNumber(SerialNumber)));
auto sessionHash = SessionHash::Hash(session_id); auto sessionHash = SessionHash::Hash(session_id);
std::lock_guard SessionLock(SessionMutex_[sessionHash]); std::lock_guard SessionLock(SessionMutex_[sessionHash]);
Sessions_[sessionHash].erase(session_id); Sessions_[sessionHash].erase(session_id);
poco_trace(Logger(), fmt::format("Ended session 1: {} for device: {}", session_id, Utils::IntToSerialNumber(SerialNumber)));
} }
{ {
auto hashIndex = MACHash::Hash(SerialNumber); auto hashIndex = MACHash::Hash(SerialNumber);
poco_trace(Logger(), fmt::format("Ending session 2.0: {} for device: {} hi:{}", session_id, Utils::IntToSerialNumber(SerialNumber), hashIndex));
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]); std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
poco_trace(Logger(), fmt::format("Ending session 2.1: {} for device: {} hi:{}", session_id, Utils::IntToSerialNumber(SerialNumber), hashIndex));
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber); auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
poco_trace(Logger(), fmt::format("Ending session 2.2: {} for device: {} hi:{}", session_id, Utils::IntToSerialNumber(SerialNumber), hashIndex));
if (DeviceHint == SerialNumbers_[hashIndex].end() if (DeviceHint == SerialNumbers_[hashIndex].end()
|| DeviceHint->second == nullptr || DeviceHint->second == nullptr
|| DeviceHint->second->State_.sessionId != session_id) { || DeviceHint->second->State_.sessionId != session_id) {
poco_trace(Logger(), fmt::format("Did not end session 2: {} for device: {}", session_id, Utils::IntToSerialNumber(SerialNumber)));
return false; return false;
} }
SerialNumbers_[hashIndex].erase(DeviceHint); SerialNumbers_[hashIndex].erase(DeviceHint);
poco_trace(Logger(), fmt::format("Ended session 2: {} for device: {}", session_id, Utils::IntToSerialNumber(SerialNumber)));
} }
return true; return true;
} }
@@ -489,47 +551,62 @@ namespace OpenWifi {
bool AP_WS_Server::Connected(uint64_t SerialNumber, bool AP_WS_Server::Connected(uint64_t SerialNumber,
GWObjects::DeviceRestrictions &Restrictions) const { GWObjects::DeviceRestrictions &Restrictions) const {
auto hashIndex = MACHash::Hash(SerialNumber); std::shared_ptr<AP_WS_Connection> Connection;
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]); {
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber); auto hashIndex = MACHash::Hash(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) { std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
}
if(Connection->Dead_) {
return false; return false;
} }
if(!DeviceHint->second->Dead_) { Restrictions = Connection->GetRestrictions();
DeviceHint->second->GetRestrictions(Restrictions); return Connection->State_.Connected;
return DeviceHint->second->State_.Connected;
}
return false;
} }
bool AP_WS_Server::Connected(uint64_t SerialNumber) const { bool AP_WS_Server::Connected(uint64_t SerialNumber) const {
auto hashIndex = MACHash::Hash(SerialNumber); std::shared_ptr<AP_WS_Connection> Connection;
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]); {
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber); auto hashIndex = MACHash::Hash(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) { std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
}
if(Connection->Dead_) {
return false; return false;
} }
if(!DeviceHint->second->Dead_) { return Connection->State_.Connected;
return DeviceHint->second->State_.Connected;
}
return false;
} }
bool AP_WS_Server::SendFrame(uint64_t SerialNumber, const std::string &Payload) const { bool AP_WS_Server::SendFrame(uint64_t SerialNumber, const std::string &Payload) const {
auto hashIndex = MACHash::Hash(SerialNumber); auto hashIndex = MACHash::Hash(SerialNumber);
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber); std::shared_ptr<AP_WS_Connection> Connection;
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) { {
return false; std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
} }
if(DeviceHint->second->Dead_) { if(Connection->Dead_) {
return false; return false;
} }
try { try {
return DeviceHint->second->Send(Payload); return Connection->Send(Payload);
} catch (...) { } catch (...) {
poco_debug(Logger(), fmt::format(": SendFrame: Could not send data to device '{}'", poco_debug(Logger(), fmt::format(": SendFrame: Could not send data to device '{}'",
Utils::IntToSerialNumber(SerialNumber))); Utils::IntToSerialNumber(SerialNumber)));
@@ -538,48 +615,64 @@ namespace OpenWifi {
} }
void AP_WS_Server::StopWebSocketTelemetry(uint64_t RPCID, uint64_t SerialNumber) { void AP_WS_Server::StopWebSocketTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
auto hashIndex = MACHash::Hash(SerialNumber); std::shared_ptr<AP_WS_Connection> Connection;
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]); {
auto Device = SerialNumbers_[hashIndex].find(SerialNumber); auto hashIndex = MACHash::Hash(SerialNumber);
if (Device == end(SerialNumbers_[hashIndex]) || Device->second == nullptr) { std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
return; auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
if (Device == end(SerialNumbers_[hashIndex]) || Device->second == nullptr) {
return;
}
Connection = Device->second;
} }
Device->second->StopWebSocketTelemetry(RPCID); Connection->StopWebSocketTelemetry(RPCID);
} }
void void
AP_WS_Server::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, AP_WS_Server::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber,
uint64_t Interval, uint64_t Lifetime, uint64_t Interval, uint64_t Lifetime,
const std::vector<std::string> &TelemetryTypes) { const std::vector<std::string> &TelemetryTypes) {
auto hashIndex = MACHash::Hash(SerialNumber); std::shared_ptr<AP_WS_Connection> Connection;
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]); {
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber); auto hashIndex = MACHash::Hash(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) { std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
return; auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return;
}
Connection = DeviceHint->second;
} }
DeviceHint->second->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime, TelemetryTypes); Connection->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime, TelemetryTypes);
} }
void AP_WS_Server::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, void AP_WS_Server::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber,
uint64_t Interval, uint64_t Lifetime, uint64_t Interval, uint64_t Lifetime,
const std::vector<std::string> &TelemetryTypes) { const std::vector<std::string> &TelemetryTypes) {
auto hashIndex = MACHash::Hash(SerialNumber); std::shared_ptr<AP_WS_Connection> Connection;
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]); {
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber); auto hashIndex = MACHash::Hash(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) { std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
return; auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return;
}
Connection = DeviceHint->second;
} }
DeviceHint->second->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime, TelemetryTypes); Connection->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime, TelemetryTypes);
} }
void AP_WS_Server::StopKafkaTelemetry(uint64_t RPCID, uint64_t SerialNumber) { void AP_WS_Server::StopKafkaTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
auto hashIndex = MACHash::Hash(SerialNumber); std::shared_ptr<AP_WS_Connection> Connection;
std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]); {
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber); auto hashIndex = MACHash::Hash(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) { std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]);
return; auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return;
}
Connection = DeviceHint->second;
} }
DeviceHint->second->StopKafkaTelemetry(RPCID); Connection->StopKafkaTelemetry(RPCID);
} }
void AP_WS_Server::GetTelemetryParameters( void AP_WS_Server::GetTelemetryParameters(
@@ -588,14 +681,18 @@ namespace OpenWifi {
uint64_t &TelemetryWebSocketCount, uint64_t &TelemetryKafkaCount, uint64_t &TelemetryWebSocketCount, uint64_t &TelemetryKafkaCount,
uint64_t &TelemetryWebSocketPackets, uint64_t &TelemetryKafkaPackets) { uint64_t &TelemetryWebSocketPackets, uint64_t &TelemetryKafkaPackets) {
auto hashIndex = MACHash::Hash(SerialNumber); std::shared_ptr<AP_WS_Connection> Connection;
std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]); {
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber); auto hashIndex = MACHash::Hash(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) { std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]);
return; auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return;
}
Connection = DeviceHint->second;
} }
DeviceHint->second->GetTelemetryParameters(TelemetryRunning, TelemetryInterval, Connection->GetTelemetryParameters(TelemetryRunning, TelemetryInterval,
TelemetryWebSocketTimer, TelemetryKafkaTimer, TelemetryWebSocketTimer, TelemetryKafkaTimer,
TelemetryWebSocketCount, TelemetryKafkaCount, TelemetryWebSocketCount, TelemetryKafkaCount,
TelemetryWebSocketPackets, TelemetryKafkaPackets); TelemetryWebSocketPackets, TelemetryKafkaPackets);
@@ -604,20 +701,24 @@ namespace OpenWifi {
bool AP_WS_Server::SendRadiusAccountingData(const std::string &SerialNumber, bool AP_WS_Server::SendRadiusAccountingData(const std::string &SerialNumber,
const unsigned char *buffer, std::size_t size) { const unsigned char *buffer, std::size_t size) {
auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber); std::shared_ptr<AP_WS_Connection> Connection;
auto hashIndex = MACHash::Hash(IntSerialNumber); {
std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]); auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber);
auto DeviceHint = SerialNumbers_[hashIndex].find(IntSerialNumber); auto hashIndex = MACHash::Hash(IntSerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) { std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]);
return false; auto DeviceHint = SerialNumbers_[hashIndex].find(IntSerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
} }
if(DeviceHint->second->Dead_) { if(Connection->Dead_) {
return false; return false;
} }
try { try {
return DeviceHint->second->SendRadiusAccountingData(buffer, size); return Connection->SendRadiusAccountingData(buffer, size);
} catch (...) { } catch (...) {
poco_debug( poco_debug(
Logger(), Logger(),
@@ -629,20 +730,24 @@ namespace OpenWifi {
bool AP_WS_Server::SendRadiusAuthenticationData(const std::string &SerialNumber, bool AP_WS_Server::SendRadiusAuthenticationData(const std::string &SerialNumber,
const unsigned char *buffer, std::size_t size) { const unsigned char *buffer, std::size_t size) {
auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber); std::shared_ptr<AP_WS_Connection> Connection;
auto hashIndex = MACHash::Hash(IntSerialNumber); {
std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]); auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber);
auto DeviceHint = SerialNumbers_[hashIndex].find(IntSerialNumber); auto hashIndex = MACHash::Hash(IntSerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) { std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]);
return false; auto DeviceHint = SerialNumbers_[hashIndex].find(IntSerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
} }
if(DeviceHint->second->Dead_) { if(Connection->Dead_) {
return false; return false;
} }
try { try {
return DeviceHint->second->SendRadiusAuthenticationData(buffer, size); return Connection->SendRadiusAuthenticationData(buffer, size);
} catch (...) { } catch (...) {
poco_debug( poco_debug(
Logger(), Logger(),
@@ -654,19 +759,23 @@ namespace OpenWifi {
bool AP_WS_Server::SendRadiusCoAData(const std::string &SerialNumber, bool AP_WS_Server::SendRadiusCoAData(const std::string &SerialNumber,
const unsigned char *buffer, std::size_t size) { const unsigned char *buffer, std::size_t size) {
auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber); std::shared_ptr<AP_WS_Connection> Connection;
auto hashIndex = MACHash::Hash(IntSerialNumber); {
std::lock_guard DevicesGuard(SerialNumbersMutex_[hashIndex]); auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber);
auto DeviceHint = SerialNumbers_[hashIndex].find(IntSerialNumber); auto hashIndex = MACHash::Hash(IntSerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) { std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
return false; auto DeviceHint = SerialNumbers_[hashIndex].find(IntSerialNumber);
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
return false;
}
Connection = DeviceHint->second;
} }
if(DeviceHint->second->Dead_) { if(Connection->Dead_) {
return false; return false;
} }
try { try {
return DeviceHint->second->SendRadiusCoAData(buffer, size); return Connection->SendRadiusCoAData(buffer, size);
} catch (...) { } catch (...) {
poco_debug(Logger(), poco_debug(Logger(),
fmt::format(": SendRadiusCoAData: Could not send data to device '{}'", fmt::format(": SendRadiusCoAData: Could not send data to device '{}'",
@@ -675,32 +784,4 @@ namespace OpenWifi {
return false; return false;
} }
bool AP_WS_Server::ExtendedAttributes(const std::string &serialNumber,
bool & hasGPS,
std::uint64_t &Sanity,
std::double_t &MemoryUsed,
std::double_t &Load,
std::double_t &Temperature
) {
auto serialNumberInt = Utils::SerialNumberToInt(serialNumber);
auto hashIndex = MACHash::Hash(serialNumberInt);
std::lock_guard DevicesGuard(SerialNumbersMutex_[hashIndex]);
auto DeviceHint = SerialNumbers_[hashIndex].find(Utils::SerialNumberToInt(serialNumber));
if(DeviceHint==end(SerialNumbers_[hashIndex])) {
return false;
}
if(DeviceHint->second->Dead_) {
return false;
}
std::lock_guard DeviceGuard(DeviceHint->second->ConnectionMutex_);
hasGPS = DeviceHint->second->hasGPS_;
Sanity = DeviceHint->second->RawLastHealthcheck_.Sanity;
MemoryUsed = DeviceHint->second->memory_used_;
Load = DeviceHint->second->cpu_load_;
Temperature = DeviceHint->second->temperature_;
return true;
}
} // namespace OpenWifi } // namespace OpenWifi

View File

@@ -103,20 +103,23 @@ namespace OpenWifi {
inline void AddConnection(std::shared_ptr<AP_WS_Connection> Connection) { inline void AddConnection(std::shared_ptr<AP_WS_Connection> Connection) {
std::uint64_t sessionHash = SessionHash::Hash(Connection->State_.sessionId); std::uint64_t sessionHash = SessionHash::Hash(Connection->State_.sessionId);
std::lock_guard Lock(SessionMutex_[sessionHash]); std::lock_guard SessionLock(SessionMutex_[sessionHash]);
if(Sessions_[sessionHash].find(Connection->State_.sessionId)==end(Sessions_[sessionHash])) { if(Sessions_[sessionHash].find(Connection->State_.sessionId)==end(Sessions_[sessionHash])) {
Sessions_[sessionHash][Connection->State_.sessionId] = std::move(Connection); Sessions_[sessionHash][Connection->State_.sessionId] = std::move(Connection);
} }
} }
[[nodiscard]] inline bool DeviceRequiresSecureRTTY(uint64_t serialNumber) const { [[nodiscard]] inline bool DeviceRequiresSecureRTTY(uint64_t serialNumber) const {
auto hashIndex = MACHash::Hash(serialNumber); std::shared_ptr<AP_WS_Connection> Connection;
std::lock_guard G(SerialNumbersMutex_[hashIndex]); {
auto hashIndex = MACHash::Hash(serialNumber);
auto Connection = SerialNumbers_[hashIndex].find(serialNumber); std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
if (Connection==end(SerialNumbers_[hashIndex]) || Connection->second==nullptr) auto DeviceHint = SerialNumbers_[hashIndex].find(serialNumber);
return false; if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr)
return Connection->second->RTTYMustBeSecure_; return false;
Connection = DeviceHint->second;
}
return Connection->RTTYMustBeSecure_;
} }
inline bool GetStatistics(const std::string &SerialNumber, std::string &Statistics) const { inline bool GetStatistics(const std::string &SerialNumber, std::string &Statistics) const {
@@ -138,6 +141,7 @@ namespace OpenWifi {
bool Connected(uint64_t SerialNumber, GWObjects::DeviceRestrictions &Restrictions) const; bool Connected(uint64_t SerialNumber, GWObjects::DeviceRestrictions &Restrictions) const;
bool Connected(uint64_t SerialNumber) const; bool Connected(uint64_t SerialNumber) const;
bool Disconnect(uint64_t SerialNumber);
bool SendFrame(uint64_t SerialNumber, const std::string &Payload) const; bool SendFrame(uint64_t SerialNumber, const std::string &Payload) const;
bool SendRadiusAuthenticationData(const std::string &SerialNumber, bool SendRadiusAuthenticationData(const std::string &SerialNumber,
const unsigned char *buffer, std::size_t size); const unsigned char *buffer, std::size_t size);
@@ -165,8 +169,8 @@ namespace OpenWifi {
uint64_t &TelemetryKafkaPackets); uint64_t &TelemetryKafkaPackets);
bool GetHealthDevices(std::uint64_t lowLimit, std::uint64_t highLimit, std::vector<std::string> & SerialNumbers); bool GetHealthDevices(std::uint64_t lowLimit, std::uint64_t highLimit, std::vector<std::string> & SerialNumbers);
bool ExtendedAttributes(const std::string &serialNumber, bool & hasGPS, std::uint64_t &Sanity, // bool ExtendedAttributes(const std::string &serialNumber, bool & hasGPS, std::uint64_t &Sanity,
std::double_t &MemoryUsed, std::double_t &Load, std::double_t &Temperature); // std::double_t &MemoryUsed, std::double_t &Load, std::double_t &Temperature);
inline void AverageDeviceStatistics(uint64_t &Connections, uint64_t &AverageConnectionTime, inline void AverageDeviceStatistics(uint64_t &Connections, uint64_t &AverageConnectionTime,
uint64_t &NumberOfConnectingDevices) const { uint64_t &NumberOfConnectingDevices) const {
@@ -195,13 +199,28 @@ namespace OpenWifi {
bool KafkaDisableState() const { return KafkaDisableState_; } bool KafkaDisableState() const { return KafkaDisableState_; }
bool KafkaDisableHealthChecks() const { return KafkaDisableHealthChecks_; } bool KafkaDisableHealthChecks() const { return KafkaDisableHealthChecks_; }
inline void IncrementConnectionCount() {
++NumberOfConnectedDevices_;
}
inline void DecrementConnectionCount() {
--NumberOfConnectedDevices_;
}
inline void AddCleanupSession(uint64_t session_id, uint64_t SerialNumber) {
std::lock_guard G(CleanupMutex_);
CleanupSessions_.emplace_back(session_id, SerialNumber);
}
void CleanupSessions();
private: private:
std::array<std::mutex,SessionHashMax> SessionMutex_; std::array<std::mutex,SessionHashMax> SessionMutex_;
std::array<std::map<std::uint64_t, std::shared_ptr<AP_WS_Connection>>,SessionHashMax> Sessions_; std::array<std::map<std::uint64_t, std::shared_ptr<AP_WS_Connection>>,SessionHashMax> Sessions_;
using SerialNumberMap = std::map<uint64_t /* serial number */, using SerialNumberMap = std::map<uint64_t /* serial number */,
std::shared_ptr<AP_WS_Connection>>; std::shared_ptr<AP_WS_Connection>>;
std::array<SerialNumberMap,MACHashMax> SerialNumbers_; std::array<SerialNumberMap,MACHashMax> SerialNumbers_;
mutable std::array<std::recursive_mutex,MACHashMax> SerialNumbersMutex_; mutable std::array<std::mutex,MACHashMax> SerialNumbersMutex_;
std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_; std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_;
std::list<std::unique_ptr<Poco::Net::HTTPServer>> WebServers_; std::list<std::unique_ptr<Poco::Net::HTTPServer>> WebServers_;
@@ -214,12 +233,17 @@ namespace OpenWifi {
bool SimulatorEnabled_ = false; bool SimulatorEnabled_ = false;
bool AllowSerialNumberMismatch_ = true; bool AllowSerialNumberMismatch_ = true;
Poco::Thread CleanupThread_;
std::mutex CleanupMutex_;
std::deque<std::pair<uint64_t, uint64_t>> CleanupSessions_;
std::unique_ptr<AP_WS_ReactorThreadPool> Reactor_pool_; std::unique_ptr<AP_WS_ReactorThreadPool> Reactor_pool_;
std::atomic_bool Running_ = false; std::atomic_bool Running_ = false;
std::uint64_t MismatchDepth_ = 2; std::uint64_t MismatchDepth_ = 2;
std::uint64_t NumberOfConnectedDevices_ = 0;
std::uint64_t AverageDeviceConnectionTime_ = 0; std::atomic_uint64_t NumberOfConnectedDevices_ = 0;
std::atomic_uint64_t AverageDeviceConnectionTime_ = 0;
std::uint64_t NumberOfConnectingDevices_ = 0; std::uint64_t NumberOfConnectingDevices_ = 0;
std::uint64_t SessionTimeOut_ = 10*60; std::uint64_t SessionTimeOut_ = 10*60;
std::uint64_t LeftOverSessions_ = 0; std::uint64_t LeftOverSessions_ = 0;

View File

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

View File

@@ -204,6 +204,17 @@ namespace OpenWifi::Config {
return false; return false;
} }
std::uint64_t Config::UUID() {
try {
Poco::JSON::Parser Parser;
auto object = Parser.parse(Config_).extract<Poco::JSON::Object::Ptr>();
if (object->has("uuid"))
return object->get("uuid");
} catch (...) {
}
return 0;
}
bool Config::Valid() { bool Config::Valid() {
try { try {
Poco::JSON::Parser Parser; Poco::JSON::Parser Parser;
@@ -254,7 +265,11 @@ namespace OpenWifi::Config {
Model_ = Caps->get("model").toString(); Model_ = Caps->get("model").toString();
if (Caps->has("platform")) if (Caps->has("platform"))
Platform_ = Caps->get("platform").toString(); Platform_ = Poco::toLower(Caps->get("platform").toString());
if(Compatible_.empty()) {
Compatible_ = Model_;
}
std::ostringstream OS; std::ostringstream OS;
Caps->stringify(OS); Caps->stringify(OS);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -25,9 +25,23 @@ namespace OpenWifi::RESTAPI_RPC {
if (StorageService()->AddCommand(Cmd.SerialNumber, Cmd, Status)) { if (StorageService()->AddCommand(Cmd.SerialNumber, Cmd, Status)) {
Poco::JSON::Object RetObj; Poco::JSON::Object RetObj;
Cmd.to_json(RetObj); Cmd.to_json(RetObj);
if (Handler != nullptr) if (Handler == nullptr) {
return Handler->ReturnObject(RetObj); // nothing to process/return
return; return;
}
Poco::Net::HTTPResponse::HTTPStatus cmd_status = Poco::Net::HTTPResponse::HTTP_OK;
if (Cmd.ErrorCode > 0) {
// command returned error
cmd_status = Poco::Net::HTTPResponse::HTTP_BAD_REQUEST;
if (Cmd.Command == uCentralProtocol::CONFIGURE) {
// special handling for configure command
if (!Handler->GetBoolParameter("strict", false)) {
// in non-strict mode return success for failed configure command
cmd_status = Poco::Net::HTTPResponse::HTTP_OK;
}
}
}
return Handler->ReturnObject(RetObj, cmd_status);
} }
if (Handler != nullptr) if (Handler != nullptr)
return Handler->ReturnStatus(Poco::Net::HTTPResponse::HTTP_INTERNAL_SERVER_ERROR); return Handler->ReturnStatus(Poco::Net::HTTPResponse::HTTP_INTERNAL_SERVER_ERROR);
@@ -40,8 +54,8 @@ namespace OpenWifi::RESTAPI_RPC {
std::chrono::milliseconds WaitTimeInMs, Poco::JSON::Object *ObjectToReturn, std::chrono::milliseconds WaitTimeInMs, Poco::JSON::Object *ObjectToReturn,
RESTAPIHandler *Handler, Poco::Logger &Logger, bool Deferred) { RESTAPIHandler *Handler, Poco::Logger &Logger, bool Deferred) {
Logger.information(fmt::format("{},{}: New {} command. User={} Serial={}. ", Cmd.UUID, Logger.information(fmt::format("{},{}: New {} command. User={} Serial={} Details={}. ", Cmd.UUID,
RPCID, Cmd.Command, Cmd.SubmittedBy, Cmd.SerialNumber)); RPCID, Cmd.Command, Cmd.SubmittedBy, Cmd.SerialNumber, Cmd.Details));
Cmd.Submitted = Utils::Now(); Cmd.Submitted = Utils::Now();
Cmd.Executed = 0; Cmd.Executed = 0;
@@ -167,6 +181,20 @@ namespace OpenWifi::RESTAPI_RPC {
Cmd.AttachType = ""; Cmd.AttachType = "";
} }
// If the command fails on the device we should show it as failed and not return 200 OK
// exception is configure command which only reported failed in strict validation mode
if (Cmd.ErrorCode &&
(Cmd.Command != uCentralProtocol::CONFIGURE ||
(Cmd.Command == uCentralProtocol::CONFIGURE && Handler->GetBoolParameter("strict", false))
))
{
Logger.information(fmt::format(
"Command failed with error on device: {} Reason: {}.",
Cmd.ErrorCode, Cmd.ErrorText));
return SetCommandStatus(Cmd, Request, Response, Handler,
Storage::CommandExecutionType::COMMAND_FAILED, Logger);
}
if (Cmd.ErrorCode == 0 && Cmd.Command == uCentralProtocol::CONFIGURE) { if (Cmd.ErrorCode == 0 && Cmd.Command == uCentralProtocol::CONFIGURE) {
// we need to post a kafka event for this. // we need to post a kafka event for this.
if (Params.has(uCentralProtocol::CONFIG) && Params.isObject(uCentralProtocol::CONFIG)) { if (Params.has(uCentralProtocol::CONFIG) && Params.isObject(uCentralProtocol::CONFIG)) {
@@ -175,6 +203,7 @@ namespace OpenWifi::RESTAPI_RPC {
DeviceConfigurationChangeKafkaEvent KEvent( DeviceConfigurationChangeKafkaEvent KEvent(
Utils::SerialNumberToInt(Cmd.SerialNumber), Utils::Now(), Utils::SerialNumberToInt(Cmd.SerialNumber), Utils::Now(),
Config); Config);
} }
} }

View File

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

View File

@@ -166,7 +166,11 @@ namespace OpenWifi {
{APCommands::Commands::rrm, false, true, &RESTAPI_device_commandHandler::RRM, 60000ms}, {APCommands::Commands::rrm, false, true, &RESTAPI_device_commandHandler::RRM, 60000ms},
{APCommands::Commands::certupdate, false, true, &RESTAPI_device_commandHandler::CertUpdate, 60000ms}, {APCommands::Commands::certupdate, false, true, &RESTAPI_device_commandHandler::CertUpdate, 60000ms},
{APCommands::Commands::transfer, false, true, &RESTAPI_device_commandHandler::Transfer, 60000ms}, {APCommands::Commands::transfer, false, true, &RESTAPI_device_commandHandler::Transfer, 60000ms},
{APCommands::Commands::script, false, true, &RESTAPI_device_commandHandler::Script, 60000ms} {APCommands::Commands::script, false, true, &RESTAPI_device_commandHandler::Script, 60000ms},
{APCommands::Commands::powercycle, false, true, &RESTAPI_device_commandHandler::PowerCycle, 60000ms},
{APCommands::Commands::fixedconfig, false, true, &RESTAPI_device_commandHandler::FixedConfig, 120000ms},
{APCommands::Commands::cablediagnostics, false, true, &RESTAPI_device_commandHandler::CableDiagnostics, 120000ms},
}; };
void RESTAPI_device_commandHandler::DoPost() { void RESTAPI_device_commandHandler::DoPost() {
@@ -653,13 +657,18 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::SerialNumberMismatch); return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
} }
GWObjects::Device DeviceInfo;
if (!StorageService()->GetDevice(SerialNumber_, DeviceInfo)) {
return NotFound();
}
auto Configuration = auto Configuration =
GetS(RESTAPI::Protocol::CONFIGURATION, Obj, uCentralProtocol::EMPTY_JSON_DOC); GetS(RESTAPI::Protocol::CONFIGURATION, Obj, uCentralProtocol::EMPTY_JSON_DOC);
std::vector<std::string> Error; std::string Error;
if (!ValidateUCentralConfiguration(Configuration, Error, if (!ValidateUCentralConfiguration(ConfigurationValidator::GetType(DeviceInfo.DeviceType),
Configuration, Error,
GetBoolParameter("strict", false))) { GetBoolParameter("strict", false))) {
CallCanceled("CONFIGURE", CMD_UUID, CMD_RPC, RESTAPI::Errors::ConfigBlockInvalid); CallCanceled("CONFIGURE", CMD_UUID, CMD_RPC, RESTAPI::Errors::ConfigBlockInvalid);
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid); return BadRequest(RESTAPI::Errors::ConfigBlockInvalid, Error);
} }
auto When = GetWhen(Obj); auto When = GetWhen(Obj);
@@ -685,9 +694,31 @@ namespace OpenWifi {
Params.stringify(ParamStream); Params.stringify(ParamStream);
Cmd.Details = ParamStream.str(); Cmd.Details = ParamStream.str();
// retrieve capabilities and encode/compress parameters, if required
Poco::JSON::Object ConfigParams = Params;
GWObjects::Capabilities Caps;
if (StorageService()->GetDeviceCapabilities(SerialNumber_, Caps)) {
Poco::JSON::Object CapsJson;
Caps.to_json(CapsJson);
auto DeviceCaps = CapsJson.getObject(uCentralProtocol::CAPABILITIES);
if (DeviceCaps->has("compress_cmd") && DeviceCaps->get("compress_cmd")) {
// compressed command capability present and it is set, compress parameters
Poco::JSON::Object CompressedParams;
std::string CompressedBase64Data;
std::uint64_t UncompressedDataLen = ParamStream.str().length();
if (Utils::CompressAndEncodeBase64(ParamStream.str(), CompressedBase64Data)) {
// set compressed, base 64 encoded data and length of uncompressed data
CompressedParams.set(uCentralProtocol::COMPRESS_64, CompressedBase64Data);
CompressedParams.set(uCentralProtocol::COMPRESS_SZ, UncompressedDataLen);
ConfigParams = CompressedParams;
}
}
}
// AP_WS_Server()->SetPendingUUID(SerialNumber_, NewUUID); // AP_WS_Server()->SetPendingUUID(SerialNumber_, NewUUID);
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::configure, true, RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::configure, true,
Cmd, Params, *Request, *Response, timeout, Cmd, ConfigParams, *Request, *Response, timeout,
nullptr, this, Logger_); nullptr, this, Logger_);
if(!Cmd.Executed) { if(!Cmd.Executed) {
@@ -1401,9 +1432,9 @@ namespace OpenWifi {
Cmd.WaitingForFile = 0; Cmd.WaitingForFile = 0;
Cmd.Status= "completed"; Cmd.Status= "completed";
if(CommandManager()->FireAndForget(SerialNumber_, uCentralProtocol::RRM, Params)) { if(CommandManager()->FireAndForget(SerialNumber_, uCentralProtocol::RRM, Params)) {
Cmd.Status= "completed";
StorageService()->AddCommand(SerialNumber_, Cmd, StorageService()->AddCommand(SerialNumber_, Cmd,
Storage::CommandExecutionType::COMMAND_COMPLETED); Storage::CommandExecutionType::COMMAND_COMPLETED);
Cmd.Status= "completed";
return OK(); return OK();
} }
Cmd.Status= "failed"; // should never happen Cmd.Status= "failed"; // should never happen
@@ -1501,4 +1532,123 @@ namespace OpenWifi {
} }
void RESTAPI_device_commandHandler::PowerCycle(
const std::string &CMD_UUID, uint64_t CMD_RPC,
[[maybe_unused]] std::chrono::milliseconds timeout,
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
if(UserInfo_.userinfo.userRole != SecurityObjects::ROOT &&
UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) {
CallCanceled("RRM", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
poco_debug(Logger_, fmt::format("POWERCYCLE({},{}): TID={} user={} serial={}", CMD_UUID,
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
if(IsDeviceSimulated(SerialNumber_)) {
CallCanceled("RRM", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported);
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
}
GWObjects::PowerCycleRequest PR;
if(!PR.from_json(ParsedBody_)) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
GWObjects::CommandDetails Cmd;
Cmd.SerialNumber = SerialNumber_;
Cmd.SubmittedBy = Requester();
Cmd.UUID = CMD_UUID;
Cmd.Command = uCentralProtocol::POWERCYCLE;
std::ostringstream os;
ParsedBody_->stringify(os);
Cmd.Details = os.str();
Cmd.RunAt = PR.when;
Cmd.ErrorCode = 0;
Cmd.WaitingForFile = 0;
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::powercycle, false, Cmd,
*ParsedBody_, *Request, *Response, timeout, nullptr, this,
Logger_);
}
// `fixedconfig` command is used set country propery on AP
// This handler uses `fixedconfig` command definitions
void RESTAPI_device_commandHandler::FixedConfig(
const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout,
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
poco_debug(Logger_, fmt::format("FIXEDCONFIG({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC,
TransactionId_, Requester(), SerialNumber_));
// do not allow `fixedconfig` command for simulated devices
if(IsDeviceSimulated(SerialNumber_)) {
CallCanceled("FIXEDCONFIG", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported);
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
}
// setup and validate fixedconfig object
GWObjects::FixedConfig fixed_config;
if(!fixed_config.from_json(ParsedBody_)) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
// setup command message
GWObjects::CommandDetails Cmd;
Cmd.SerialNumber = SerialNumber_;
Cmd.SubmittedBy = Requester();
Cmd.UUID = CMD_UUID;
Cmd.Command = uCentralProtocol::FIXEDCONFIG;
std::ostringstream os;
ParsedBody_->stringify(os);
Cmd.Details = os.str();
Cmd.RunAt = 0;
Cmd.ErrorCode = 0;
Cmd.WaitingForFile = 0;
// send fixedconfig command to device and return status
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::fixedconfig, false, Cmd,
*ParsedBody_, *Request, *Response, timeout, nullptr, this,
Logger_);
}
void RESTAPI_device_commandHandler::CableDiagnostics(
const std::string &CMD_UUID, uint64_t CMD_RPC,
[[maybe_unused]] std::chrono::milliseconds timeout,
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
if(UserInfo_.userinfo.userRole != SecurityObjects::ROOT &&
UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) {
CallCanceled("CABLEDIAGNOSTICS", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
poco_debug(Logger_, fmt::format("CABLEDIAGNOSTICS({},{}): TID={} user={} serial={}", CMD_UUID,
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
if(IsDeviceSimulated(SerialNumber_)) {
CallCanceled("CABLEDIAGNOSTICS", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported);
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
}
GWObjects::CableDiagnostics PR;
if(!PR.from_json(ParsedBody_)) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
GWObjects::CommandDetails Cmd;
Cmd.SerialNumber = SerialNumber_;
Cmd.SubmittedBy = Requester();
Cmd.UUID = CMD_UUID;
Cmd.Command = uCentralProtocol::CABLEDIAGNOSTICS;
std::ostringstream os;
ParsedBody_->stringify(os);
Cmd.Details = os.str();
Cmd.RunAt = PR.when;
Cmd.ErrorCode = 0;
Cmd.WaitingForFile = 0;
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::cablediagnostics, false, Cmd,
*ParsedBody_, *Request, *Response, timeout, nullptr, this,
Logger_);
}
} // namespace OpenWifi } // namespace OpenWifi

View File

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

View File

@@ -17,6 +17,8 @@
#include "RESTAPI_device_helper.h" #include "RESTAPI_device_helper.h"
#include "AP_WS_Server.h"
namespace OpenWifi { namespace OpenWifi {
void RESTAPI_device_handler::DoGet() { void RESTAPI_device_handler::DoGet() {
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, ""); std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
@@ -80,6 +82,9 @@ namespace OpenWifi {
return OK(); return OK();
} else if (StorageService()->DeleteDevice(SerialNumber)) { } else if (StorageService()->DeleteDevice(SerialNumber)) {
if(AP_WS_Server()->Connected(Utils::SerialNumberToInt(SerialNumber))) {
AP_WS_Server()->Disconnect(Utils::SerialNumberToInt(SerialNumber));
}
return OK(); return OK();
} }
@@ -101,9 +106,10 @@ namespace OpenWifi {
} }
auto Config = Obj->get("configuration").toString(); auto Config = Obj->get("configuration").toString();
Poco::JSON::Object Answer; Poco::JSON::Object Answer;
std::vector<std::string> Error; std::string Error;
auto DeviceType = Poco::toLower(GetParameter("deviceType", Platforms::AP));
auto Res = auto Res =
ValidateUCentralConfiguration(Config, Error, GetBoolParameter("strict", false)); ValidateUCentralConfiguration(ConfigurationValidator::GetType(DeviceType),Config, Error, GetBoolParameter("strict", false));
Answer.set("valid", Res); Answer.set("valid", Res);
if (!Error.empty()) if (!Error.empty())
Answer.set("error", Error); Answer.set("error", Error);
@@ -123,12 +129,13 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::SerialNumberMismatch); return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
} }
std::vector<std::string> Error; std::string Error;
if (Device.Configuration.empty() || if (Device.Configuration.empty() ||
(!Device.Configuration.empty() && (!Device.Configuration.empty() &&
!ValidateUCentralConfiguration(Device.Configuration, Error, !ValidateUCentralConfiguration(ConfigurationValidator::GetType(Device.DeviceType),
Device.Configuration, Error,
GetBoolParameter("strict", false)))) { GetBoolParameter("strict", false)))) {
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid); return BadRequest(RESTAPI::Errors::ConfigBlockInvalid, Error);
} }
for (auto &i : Device.Notes) { for (auto &i : Device.Notes) {
@@ -169,10 +176,11 @@ namespace OpenWifi {
} }
if (!NewDevice.Configuration.empty()) { if (!NewDevice.Configuration.empty()) {
std::vector<std::string> Error; std::string Error;
if (!ValidateUCentralConfiguration(NewDevice.Configuration, Error, if (!ValidateUCentralConfiguration(ConfigurationValidator::GetType(Existing.DeviceType),
NewDevice.Configuration, Error,
GetBoolParameter("strict", false))) { GetBoolParameter("strict", false))) {
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid); return BadRequest(RESTAPI::Errors::ConfigBlockInvalid, Error);
} }
Config::Config NewConfig(NewDevice.Configuration); Config::Config NewConfig(NewDevice.Configuration);
uint64_t NewConfigUUID = Utils::Now(); uint64_t NewConfigUUID = Utils::Now();

View File

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

View File

@@ -22,9 +22,15 @@ namespace OpenWifi {
std::string FileType; std::string FileType;
std::string FileContent; std::string FileContent;
if (!StorageService()->GetAttachedFileContent(UUID, SerialNumber, FileContent, FileType) || FileContent.empty()) { int WaitingForFile = 0;
if (!StorageService()->GetAttachedFileContent(UUID, SerialNumber, FileContent, FileType, WaitingForFile) && !WaitingForFile) {
return NotFound(); return NotFound();
} }
else if (WaitingForFile) {
// waiting for file to be uploaded, return Accepted
return Accepted();
}
if (FileType == "pcap") { if (FileType == "pcap") {
SendFileContent(FileContent, "application/vnd.tcpdump.pcap", UUID + ".pcap"); SendFileContent(FileContent, "application/vnd.tcpdump.pcap", UUID + ".pcap");
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -143,26 +143,31 @@ namespace OpenWifi {
bool simulated); bool simulated);
bool CreateDevice(Poco::Data::Session &Sess, GWObjects::Device &DeviceDetails); bool CreateDevice(Poco::Data::Session &Sess, GWObjects::Device &DeviceDetails);
bool GetDevice(LockedDbSession &Session, std::string &SerialNumber, GWObjects::Device &); bool GetDevice(LockedDbSession &Session, const std::string &SerialNumber, GWObjects::Device &);
bool GetDevice(Poco::Data::Session &Session, std::string &SerialNumber, GWObjects::Device &DeviceDetails); bool GetDevice(Poco::Data::Session &Session, const std::string &SerialNumber, GWObjects::Device &DeviceDetails);
bool GetDevice(std::string &SerialNumber, GWObjects::Device &); bool GetDevice(const std::string &SerialNumber, GWObjects::Device &);
bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices, bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices,
const std::string &orderBy = ""); const std::string &orderBy = "",
const std::string &platform = "",
bool includeProvisioned = true);
// bool GetDevices(uint64_t From, uint64_t HowMany, const std::string & Select, // bool GetDevices(uint64_t From, uint64_t HowMany, const std::string & Select,
// std::vector<GWObjects::Device> &Devices, const std::string & orderBy=""); // std::vector<GWObjects::Device> &Devices, const std::string & orderBy="");
bool DeleteDevice(std::string &SerialNumber); bool DeleteDevice(std::string &SerialNumber);
bool DeleteDevices(std::string &SerialPattern, bool SimulatedOnly); bool DeleteDevices(std::string &SerialPattern, bool SimulatedOnly);
bool DeleteDevices(std::uint64_t OlderContact, bool SimulatedOnly); bool DeleteDevices(std::uint64_t OlderContact, bool SimulatedOnly);
std::string GetPlatform(const std::string &SerialNumber);
bool UpdateDevice(GWObjects::Device &); bool UpdateDevice(GWObjects::Device &);
bool UpdateDevice(LockedDbSession &Session, GWObjects::Device &); bool UpdateDevice(LockedDbSession &Session, GWObjects::Device &);
bool UpdateDevice(Poco::Data::Session &Sess, GWObjects::Device &NewDeviceDetails); bool UpdateDevice(Poco::Data::Session &Sess, GWObjects::Device &NewDeviceDetails);
bool DeviceExists(std::string &SerialNumber); bool DeviceExists(std::string &SerialNumber);
bool SetConnectInfo(std::string &SerialNumber, std::string &Firmware); bool SetConnectInfo(std::string &SerialNumber, std::string &Firmware);
bool GetDeviceCount(uint64_t &Count); bool GetDeviceCount(uint64_t &Count, const std::string &platform = "");
bool GetDeviceSerialNumbers(uint64_t From, uint64_t HowMany, bool GetDeviceSerialNumbers(uint64_t From, uint64_t HowMany,
std::vector<std::string> &SerialNumbers, std::vector<std::string> &SerialNumbers,
const std::string &orderBy = ""); const std::string &orderBy = "",
const std::string &platform = "",
bool includeProvisioned = true);
bool GetDeviceFWUpdatePolicy(std::string &SerialNumber, std::string &Policy); bool GetDeviceFWUpdatePolicy(std::string &SerialNumber, std::string &Policy);
bool SetDevicePassword(LockedDbSession &Session, std::string &SerialNumber, std::string &Password); bool SetDevicePassword(LockedDbSession &Session, std::string &SerialNumber, std::string &Password);
bool UpdateSerialNumberCache(); bool UpdateSerialNumberCache();
@@ -198,6 +203,7 @@ namespace OpenWifi {
bool GetDefaultConfigurations(uint64_t From, uint64_t HowMany, bool GetDefaultConfigurations(uint64_t From, uint64_t HowMany,
std::vector<GWObjects::DefaultConfiguration> &Devices); std::vector<GWObjects::DefaultConfiguration> &Devices);
bool FindDefaultConfigurationForModel(const std::string &Model, bool FindDefaultConfigurationForModel(const std::string &Model,
const std::string &Platform,
GWObjects::DefaultConfiguration &DefConfig); GWObjects::DefaultConfiguration &DefConfig);
uint64_t GetDefaultConfigurationsCount(); uint64_t GetDefaultConfigurationsCount();
bool DefaultConfigurationAlreadyExists(std::string &Name); bool DefaultConfigurationAlreadyExists(std::string &Name);
@@ -237,7 +243,7 @@ namespace OpenWifi {
const std::string &Type); const std::string &Type);
bool CancelWaitFile(std::string &UUID, std::string &ErrorText); bool CancelWaitFile(std::string &UUID, std::string &ErrorText);
bool GetAttachedFileContent(std::string &UUID, const std::string &SerialNumber, bool GetAttachedFileContent(std::string &UUID, const std::string &SerialNumber,
std::string &FileContent, std::string &Type); std::string &FileContent, std::string &Type, int& WaitingForFile);
bool RemoveAttachedFile(std::string &UUID); bool RemoveAttachedFile(std::string &UUID);
bool SetCommandResult(std::string &UUID, std::string &Result); bool SetCommandResult(std::string &UUID, std::string &Result);
bool GetNewestCommands(std::string &SerialNumber, uint64_t HowMany, bool GetNewestCommands(std::string &SerialNumber, uint64_t HowMany,
@@ -291,6 +297,8 @@ namespace OpenWifi {
bool AnalyzeCommands(Types::CountedMap &R); bool AnalyzeCommands(Types::CountedMap &R);
bool AnalyzeDevices(GWObjects::Dashboard &D); bool AnalyzeDevices(GWObjects::Dashboard &D);
void FixDeviceTypeBug();
int Start() override; int Start() override;
void Stop() override; void Stop() override;

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

@@ -22,7 +22,6 @@ namespace OpenWifi {
return instance_; return instance_;
} }
explicit EventBusManager(Poco::Logger &L);
void run() final; void run() final;
void Start(); void Start();
void Stop(); void Stop();

View File

@@ -79,8 +79,10 @@ namespace OpenWifi {
Utils::SetThreadName("Kafka:Prod"); Utils::SetThreadName("Kafka:Prod");
cppkafka::Configuration Config( cppkafka::Configuration Config(
{{"client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "")}, {{"client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "")},
{"metadata.broker.list", {"metadata.broker.list",MicroServiceConfigGetString("openwifi.kafka.brokerlist", "")} // ,
MicroServiceConfigGetString("openwifi.kafka.brokerlist", "")}}); // {"send.buffer.bytes", KafkaManager()->KafkaManagerMaximumPayloadSize() }
}
);
AddKafkaSecurity(Config); AddKafkaSecurity(Config);
@@ -105,6 +107,19 @@ namespace OpenWifi {
NewMessage.partition(0); NewMessage.partition(0);
NewMessage.payload(Msg->Payload()); NewMessage.payload(Msg->Payload());
Producer.produce(NewMessage); Producer.produce(NewMessage);
if (Queue_.size() < 100) {
// use flush when internal queue is lightly loaded, i.e. flush after each
// message
Producer.flush();
}
else {
// use poll when internal queue is loaded to allow messages to be sent in
// batches
Producer.poll((std::chrono::milliseconds) 0);
}
}
if (Queue_.size() == 0) {
// message queue is empty, flush all previously sent messages
Producer.flush(); Producer.flush();
} }
} catch (const cppkafka::HandleException &E) { } catch (const cppkafka::HandleException &E) {
@@ -117,6 +132,7 @@ namespace OpenWifi {
} }
Note = Queue_.waitDequeueNotification(); Note = Queue_.waitDequeueNotification();
} }
Producer.flush();
poco_information(Logger_, "Stopped..."); poco_information(Logger_, "Stopped...");
} }
@@ -275,6 +291,7 @@ namespace OpenWifi {
int KafkaManager::Start() { int KafkaManager::Start() {
if (!KafkaEnabled_) if (!KafkaEnabled_)
return 0; return 0;
MaxPayloadSize_ = MicroServiceConfigGetInt("openwifi.kafka.max.payload", 250000);
ConsumerThr_.Start(); ConsumerThr_.Start();
ProducerThr_.Start(); ProducerThr_.Start();
return 0; return 0;

View File

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

View File

@@ -1,4 +1,5 @@
// //
//
// Created by stephane bourque on 2022-10-26. // Created by stephane bourque on 2022-10-26.
// //
@@ -29,11 +30,13 @@
#include "framework/WebSocketLogger.h" #include "framework/WebSocketLogger.h"
#include "framework/utils.h" #include "framework/utils.h"
#ifdef USE_MEDUSA_CLIENT
#include <medusa/MedusaClient.h>
#endif
namespace OpenWifi { namespace OpenWifi {
void MicroService::Exit(int Reason) { std::exit(Reason); } static std::string MakeServiceListString(const Types::MicroServiceMetaMap &Services) {
static std::string MakeServiceListString(const Types::MicroServiceMetaMap &Services) {
std::string SvcList; std::string SvcList;
for (const auto &Svc : Services) { for (const auto &Svc : Services) {
if (SvcList.empty()) if (SvcList.empty())
@@ -204,25 +207,29 @@ namespace OpenWifi {
Res.push_back(ServiceRec); Res.push_back(ServiceRec);
} }
return Res; return Res;
} }
void MicroService::LoadConfigurationFile() { void MicroService::LoadConfigurationFile() {
std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR, "."); if(ConfigContent_.empty()) {
ConfigFileName_ = std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR, ".");
ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_; ConfigFileName_ =
Poco::Path ConfigFile(ConfigFileName_); ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_;
Poco::Path ConfigFile(ConfigFileName_);
if (!ConfigFile.isFile()) { if (!ConfigFile.isFile()) {
std::cerr << DAEMON_APP_NAME << ": Configuration " << ConfigFile.toString() std::cerr << DAEMON_APP_NAME << ": Configuration " << ConfigFile.toString()
<< " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR + << " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR +
" env variable the path of the " + DAEMON_PROPERTIES_FILENAME + " env variable the path of the " + DAEMON_PROPERTIES_FILENAME +
" file." " file."
<< std::endl; << std::endl;
std::exit(Poco::Util::Application::EXIT_CONFIG); std::exit(Poco::Util::Application::EXIT_CONFIG);
} }
PropConfigurationFile_ = new Poco::Util::PropertyFileConfiguration(ConfigFile.toString());
// loadConfiguration(ConfigFile.toString()); } else {
PropConfigurationFile_ = new Poco::Util::PropertyFileConfiguration(ConfigFile.toString()); std::istringstream is(ConfigContent_);
PropConfigurationFile_ = new Poco::Util::PropertyFileConfiguration(is);
}
configPtr()->addWriteable(PropConfigurationFile_, PRIO_DEFAULT); configPtr()->addWriteable(PropConfigurationFile_, PRIO_DEFAULT);
} }
@@ -425,49 +432,69 @@ namespace OpenWifi {
void DaemonPostInitialization(Poco::Util::Application &self); void DaemonPostInitialization(Poco::Util::Application &self);
void MicroService::initialize(Poco::Util::Application &self) { void MicroService::StartEverything(Poco::Util::Application &self) {
// add the default services LoadConfigurationFile();
LoadConfigurationFile(); InitializeLoggingSystem();
InitializeLoggingSystem();
SubSystems_.push_back(KafkaManager()); static bool InitializedBaseService=false;
SubSystems_.push_back(ALBHealthCheckServer()); if(!InitializedBaseService) {
SubSystems_.push_back(RESTAPI_ExtServer()); InitializedBaseService = true;
SubSystems_.push_back(RESTAPI_IntServer()); SubSystems_.push_back(KafkaManager());
SubSystems_.push_back(ALBHealthCheckServer());
SubSystems_.push_back(RESTAPI_ExtServer());
SubSystems_.push_back(RESTAPI_IntServer());
#ifndef TIP_SECURITY_SERVICE #ifndef TIP_SECURITY_SERVICE
SubSystems_.push_back(AuthClient()); SubSystems_.push_back(AuthClient());
#endif #endif
Poco::Net::initializeSSL();
Poco::Net::HTTPStreamFactory::registerFactory();
Poco::Net::HTTPSStreamFactory::registerFactory();
Poco::Net::FTPStreamFactory::registerFactory();
Poco::Net::FTPSStreamFactory::registerFactory();
Poco::File DataDir(ConfigPath("openwifi.system.data")); Poco::Net::initializeSSL();
DataDir_ = DataDir.path(); Poco::Net::HTTPStreamFactory::registerFactory();
if (!DataDir.exists()) { Poco::Net::HTTPSStreamFactory::registerFactory();
try { Poco::Net::FTPStreamFactory::registerFactory();
DataDir.createDirectory(); Poco::Net::FTPSStreamFactory::registerFactory();
} catch (const Poco::Exception &E) { }
Logger_.log(E);
}
}
WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets", "");
if (WWWAssetsDir_.empty())
WWWAssetsDir_ = DataDir_;
LoadMyConfig(); Poco::File DataDir(ConfigPath("openwifi.system.data"));
DataDir_ = DataDir.path();
if (!DataDir.exists()) {
try {
DataDir.createDirectory();
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
}
WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets", "");
if (WWWAssetsDir_.empty())
WWWAssetsDir_ = DataDir_;
AllowExternalMicroServices_ = ConfigGetBool("allowexternalmicroservices", true); LoadMyConfig();
InitializeSubSystemServers(); AllowExternalMicroServices_ = ConfigGetBool("allowexternalmicroservices", true);
ServerApplication::initialize(self);
DaemonPostInitialization(self);
Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) { InitializeSubSystemServers();
this->BusMessageReceived(Key, Payload); ServerApplication::initialize(self);
}; DaemonPostInitialization(self);
KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) {
this->BusMessageReceived(Key, Payload);
};
KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
}
void MicroService::StopEverything([[maybe_unused]] Poco::Util::Application &self) {
LoadConfigurationFile();
InitializeLoggingSystem();
Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) {
this->BusMessageReceived(Key, Payload);
};
KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
}
void MicroService::initialize([[maybe_unused]] Poco::Util::Application &self) {
#ifndef USE_MEDUSA_CLIENT
StartEverything(self);
#endif
} }
void MicroService::uninitialize() { void MicroService::uninitialize() {
@@ -753,6 +780,8 @@ namespace OpenWifi {
MicroServiceErrorHandler ErrorHandler(*this); MicroServiceErrorHandler ErrorHandler(*this);
Poco::ErrorHandler::set(&ErrorHandler); Poco::ErrorHandler::set(&ErrorHandler);
Args_ = args;
if (!HelpRequested_) { if (!HelpRequested_) {
SavePID(); SavePID();
@@ -768,11 +797,18 @@ namespace OpenWifi {
poco_information(logger, "Starting as a daemon."); poco_information(logger, "Starting as a daemon.");
} }
#ifdef USE_MEDUSA_CLIENT
MedusaClient::instance()->SetSubSystems(SubSystems_);
MedusaClient::instance()->Start();
waitForTerminationRequest();
MedusaClient::instance()->Stop();
#else
poco_information(logger, fmt::format("System ID set to {}", ID_)); poco_information(logger, fmt::format("System ID set to {}", ID_));
StartSubSystemServers(); StartSubSystemServers();
waitForTerminationRequest(); waitForTerminationRequest();
StopSubSystemServers(); StopSubSystemServers();
logger.notice(fmt::format("Stopped {}...", DAEMON_APP_NAME)); logger.notice(fmt::format("Stopped {}...", DAEMON_APP_NAME));
#endif
} }
return Application::EXIT_OK; return Application::EXIT_OK;

View File

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

View File

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

View File

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

View File

@@ -431,6 +431,11 @@ namespace OpenWifi {
} }
} }
inline void Accepted() {
PrepareResponse(Poco::Net::HTTPResponse::HTTP_ACCEPTED);
Response->send();
}
inline void SendCompressedTarFile(const std::string &FileName, const std::string &Content) { inline void SendCompressedTarFile(const std::string &FileName, const std::string &Content) {
Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK); Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK);
SetCommonHeaders(); SetCommonHeaders();
@@ -552,8 +557,8 @@ namespace OpenWifi {
inline bool IsAuthorized(bool &Expired, bool &Contacted, bool SubOnly = false); inline bool IsAuthorized(bool &Expired, bool &Contacted, bool SubOnly = false);
inline void ReturnObject(Poco::JSON::Object &Object) { inline void ReturnObject(Poco::JSON::Object &Object, Poco::Net::HTTPResponse::HTTPStatus Status = Poco::Net::HTTPResponse::HTTP_OK) {
PrepareResponse(); PrepareResponse(Status);
if (Request != nullptr) { if (Request != nullptr) {
// can we compress ??? // can we compress ???
auto AcceptedEncoding = Request->find("Accept-Encoding"); auto AcceptedEncoding = Request->find("Accept-Encoding");

View File

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

View File

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

View File

@@ -565,6 +565,7 @@ namespace OpenWifi::RESTAPI::Protocol {
static const char *TRANSFER = "transfer"; static const char *TRANSFER = "transfer";
static const char *CERTUPDATE = "certupdate"; static const char *CERTUPDATE = "certupdate";
static const char *POWERCYCLE = "powercycle";
static const char *RRM = "rrm"; static const char *RRM = "rrm";
static const char *REQUIREMENTS = "requirements"; static const char *REQUIREMENTS = "requirements";
@@ -579,6 +580,9 @@ namespace OpenWifi::RESTAPI::Protocol {
static const char *INTERVAL = "interval"; static const char *INTERVAL = "interval";
static const char *UI = "UI"; static const char *UI = "UI";
static const char *BANDWIDTH = "bandwidth"; static const char *BANDWIDTH = "bandwidth";
static const char *FIXEDCONFIG = "fixedconfig";
static const char *CABLEDIAGNOSTICS = "cable-diagnostics";
} // namespace OpenWifi::RESTAPI::Protocol } // namespace OpenWifi::RESTAPI::Protocol
namespace OpenWifi::uCentralProtocol { namespace OpenWifi::uCentralProtocol {
@@ -607,6 +611,7 @@ namespace OpenWifi::uCentralProtocol {
static const char *CFGPENDING = "cfgpending"; static const char *CFGPENDING = "cfgpending";
static const char *RECOVERY = "recovery"; static const char *RECOVERY = "recovery";
static const char *COMPRESS_64 = "compress_64"; static const char *COMPRESS_64 = "compress_64";
static const char *COMPRESS_SZ = "compress_sz";
static const char *CAPABILITIES = "capabilities"; static const char *CAPABILITIES = "capabilities";
static const char *REQUEST_UUID = "request_uuid"; static const char *REQUEST_UUID = "request_uuid";
static const char *SANITY = "sanity"; static const char *SANITY = "sanity";
@@ -687,9 +692,13 @@ namespace OpenWifi::uCentralProtocol {
static const char *TRANSFER = "transfer"; static const char *TRANSFER = "transfer";
static const char *CERTUPDATE = "certupdate"; static const char *CERTUPDATE = "certupdate";
static const char *POWERCYCLE = "powercycle";
static const char *RRM = "rrm"; static const char *RRM = "rrm";
static const char *ACTIONS = "actions"; static const char *ACTIONS = "actions";
static const char *FIXEDCONFIG = "fixedconfig";
static const char *CABLEDIAGNOSTICS = "cable-diagnostics";
} // namespace OpenWifi::uCentralProtocol } // namespace OpenWifi::uCentralProtocol
namespace OpenWifi::uCentralProtocol::Events { namespace OpenWifi::uCentralProtocol::Events {
@@ -785,6 +794,9 @@ namespace OpenWifi::APCommands {
rrm, rrm,
certupdate, certupdate,
transfer, transfer,
powercycle,
fixedconfig,
cablediagnostics,
unknown unknown
}; };
@@ -799,7 +811,8 @@ namespace OpenWifi::APCommands {
RESTAPI::Protocol::EVENTQUEUE, RESTAPI::Protocol::TELEMETRY, RESTAPI::Protocol::EVENTQUEUE, RESTAPI::Protocol::TELEMETRY,
RESTAPI::Protocol::PING, RESTAPI::Protocol::SCRIPT, RESTAPI::Protocol::PING, RESTAPI::Protocol::SCRIPT,
RESTAPI::Protocol::RRM, RESTAPI::Protocol::CERTUPDATE, RESTAPI::Protocol::RRM, RESTAPI::Protocol::CERTUPDATE,
RESTAPI::Protocol::TRANSFER RESTAPI::Protocol::TRANSFER, RESTAPI::Protocol::POWERCYCLE,
RESTAPI::Protocol::FIXEDCONFIG, RESTAPI::Protocol::CABLEDIAGNOSTICS
}; };
inline const char *to_string(Commands Cmd) { return uCentralAPCommands[(uint8_t)Cmd]; } inline const char *to_string(Commands Cmd) { return uCentralAPCommands[(uint8_t)Cmd]; }
@@ -828,6 +841,11 @@ namespace OpenWifi::Provisioning::DeviceClass {
} // namespace OpenWifi::Provisioning::DeviceClass } // namespace OpenWifi::Provisioning::DeviceClass
namespace OpenWifi::Platforms {
static const std::string AP = "ap";
static const std::string SWITCH = "switch";
}
#if defined(__GNUC__) #if defined(__GNUC__)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif

View File

@@ -590,6 +590,26 @@ namespace OpenWifi::Utils {
return false; return false;
} }
//
// Compress given data using utility function and encode it in base64 format.
//
bool CompressAndEncodeBase64(const std::string& UnCompressedData, std::string& CompressedBase64Data) {
unsigned long CompressedDataSize = UnCompressedData.size();
std::vector<Bytef> CompressedData(CompressedDataSize);
auto status = compress(&CompressedData[0], &CompressedDataSize,
(Bytef*) UnCompressedData.c_str(), UnCompressedData.size());
if (status == Z_OK) {
CompressedBase64Data = OpenWifi::Utils::base64encode(&CompressedData[0], CompressedDataSize);
}
else {
// failed to compress data
return false;
}
return true;
}
bool IsAlphaNumeric(const std::string &s) { bool IsAlphaNumeric(const std::string &s) {
return std::all_of(s.begin(), s.end(), [](char c) -> bool { return isalnum(c); }); return std::all_of(s.begin(), s.end(), [](char c) -> bool { return isalnum(c); });
} }

View File

@@ -151,6 +151,8 @@ namespace OpenWifi::Utils {
bool ExtractBase64CompressedData(const std::string &CompressedData, bool ExtractBase64CompressedData(const std::string &CompressedData,
std::string &UnCompressedData, uint64_t compress_sz); std::string &UnCompressedData, uint64_t compress_sz);
bool CompressAndEncodeBase64(const std::string& UnCompressedData, std::string& CompressedData);
inline bool match(const char* first, const char* second) inline bool match(const char* first, const char* second)
{ {
// If we reach at the end of both strings, we are done // If we reach at the end of both strings, we are done

View File

@@ -644,21 +644,7 @@ namespace OpenWifi {
uint64_t Size = FileContent.str().size(); uint64_t Size = FileContent.str().size();
Poco::Data::Session Sess = Pool_->get(); Poco::Data::Session Sess = Pool_->get();
Sess.begin();
Poco::Data::Statement Statement(Sess);
std::string StatementStr;
// Get the existing command
StatementStr =
"UPDATE CommandList SET WaitingForFile=?, AttachDate=?, AttachSize=? WHERE UUID=?";
Statement << ConvertParams(StatementStr), Poco::Data::Keywords::use(WaitForFile),
Poco::Data::Keywords::use(Now), Poco::Data::Keywords::use(Size),
Poco::Data::Keywords::use(UUID);
Statement.execute();
Sess.commit();
if (Size < FileUploader()->MaxSize()) { if (Size < FileUploader()->MaxSize()) {
Poco::Data::BLOB TheBlob; Poco::Data::BLOB TheBlob;
@@ -680,7 +666,20 @@ namespace OpenWifi {
} else { } else {
poco_warning(Logger(), fmt::format("File {} is too large.", UUID)); poco_warning(Logger(), fmt::format("File {} is too large.", UUID));
} }
// update CommandList here to ensure that file us uploaded
Sess.begin();
Poco::Data::Statement Statement(Sess);
std::string StatementStr;
StatementStr =
"UPDATE CommandList SET WaitingForFile=?, AttachDate=?, AttachSize=? WHERE UUID=?";
Statement << ConvertParams(StatementStr), Poco::Data::Keywords::use(WaitForFile),
Poco::Data::Keywords::use(Now), Poco::Data::Keywords::use(Size),
Poco::Data::Keywords::use(UUID);
Statement.execute();
Sess.commit(); Sess.commit();
return true; return true;
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
Logger().log(E); Logger().log(E);
@@ -689,7 +688,7 @@ namespace OpenWifi {
} }
bool Storage::GetAttachedFileContent(std::string &UUID, const std::string &SerialNumber, bool Storage::GetAttachedFileContent(std::string &UUID, const std::string &SerialNumber,
std::string &FileContent, std::string &Type) { std::string &FileContent, std::string &Type, int &WaitingForFile) {
try { try {
Poco::Data::BLOB L; Poco::Data::BLOB L;
/* /*
@@ -702,10 +701,10 @@ namespace OpenWifi {
Poco::Data::Statement Select1(Sess); Poco::Data::Statement Select1(Sess);
std::string TmpSerialNumber; std::string TmpSerialNumber;
std::string st1{"SELECT SerialNumber, Command FROM CommandList WHERE UUID=?"}; std::string st1{"SELECT SerialNumber, Command , WaitingForFile FROM CommandList WHERE UUID=?"};
std::string Command; std::string Command;
Select1 << ConvertParams(st1), Poco::Data::Keywords::into(TmpSerialNumber), Select1 << ConvertParams(st1), Poco::Data::Keywords::into(TmpSerialNumber),
Poco::Data::Keywords::into(Command), Poco::Data::Keywords::use(UUID); Poco::Data::Keywords::into(Command), Poco::Data::Keywords::into(WaitingForFile), Poco::Data::Keywords::use(UUID);
Select1.execute(); Select1.execute();
if (TmpSerialNumber != SerialNumber) { if (TmpSerialNumber != SerialNumber) {

View File

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

View File

@@ -172,14 +172,18 @@ namespace OpenWifi {
R.set<30>(D.connectReason); R.set<30>(D.connectReason);
} }
bool Storage::GetDeviceCount(uint64_t &Count) { bool Storage::GetDeviceCount(uint64_t &Count, const std::string &platform) {
try { try {
Poco::Data::Session Sess = Pool_->get(); Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess); Poco::Data::Statement Select(Sess);
std::string st{"SELECT COUNT(*) FROM Devices"}; if(!platform.empty()) {
std::string st{"SELECT COUNT(*) FROM Devices WHERE DeviceType='" + platform + "'"};
Select << st, Poco::Data::Keywords::into(Count); Select << st, Poco::Data::Keywords::into(Count);
} else {
std::string st{"SELECT COUNT(*) FROM Devices"};
Select << st, Poco::Data::Keywords::into(Count);
}
Select.execute(); Select.execute();
return true; return true;
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
@@ -190,16 +194,37 @@ namespace OpenWifi {
bool Storage::GetDeviceSerialNumbers(uint64_t From, uint64_t HowMany, bool Storage::GetDeviceSerialNumbers(uint64_t From, uint64_t HowMany,
std::vector<std::string> &SerialNumbers, std::vector<std::string> &SerialNumbers,
const std::string &orderBy) { const std::string &orderBy,
const std::string &platform, bool includeProvisioned) {
try { try {
Poco::Data::Session Sess = Pool_->get(); Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess); Poco::Data::Statement Select(Sess);
std::string st; std::string st;
std::string whereClause = "";
if(!platform.empty()) {
if (includeProvisioned == false) {
whereClause = fmt::format("WHERE entity='' and venue='' and DeviceType='" + platform + "'");
} else {
whereClause = fmt::format("WHERE DeviceType='" + platform + "'");
}
//st = "SELECT SerialNumber From Devices WHERE DeviceType='" + platform + "' ";
} else {
if (includeProvisioned == false) {
whereClause = fmt::format("WHERE entity='' and venue=''");
}
//st = "SELECT SerialNumber From Devices ";
}
st = fmt::format("SELECT SerialNumber From Devices {}", whereClause);
if (orderBy.empty()) if (orderBy.empty())
st = "SELECT SerialNumber From Devices ORDER BY SerialNumber ASC "; st += " ORDER BY SerialNumber ASC ";
else else
st = "SELECT SerialNumber From Devices " + orderBy; st += orderBy;
Select << st + ComputeRange(From, HowMany), Poco::Data::Keywords::into(SerialNumbers); Select << st + ComputeRange(From, HowMany), Poco::Data::Keywords::into(SerialNumbers);
Select.execute(); Select.execute();
@@ -265,7 +290,7 @@ namespace OpenWifi {
D.pendingUUID = 0; D.pendingUUID = 0;
D.LastConfigurationChange = Utils::Now(); D.LastConfigurationChange = Utils::Now();
ConfigurationCache().Add(Utils::SerialNumberToInt(SerialNumber), D.UUID); SetCurrentConfigurationID(Utils::SerialNumberToInt(SerialNumber), D.UUID);
Poco::Data::Session Sess = Pool_->get(); Poco::Data::Session Sess = Pool_->get();
Sess.begin(); Sess.begin();
@@ -298,19 +323,30 @@ namespace OpenWifi {
bool Storage::CompleteDeviceConfigurationChange(Poco::Data::Session & Session, std::string & SerialNumber) { bool Storage::CompleteDeviceConfigurationChange(Poco::Data::Session & Session, std::string & SerialNumber) {
try { try {
GWObjects::Device D; GWObjects::Device D;
if (!GetDevice(SerialNumber, D)) if (!GetDevice(SerialNumber, D))
return false; return false;
if(D.pendingConfiguration.empty()) if(!D.pendingConfiguration.empty()) {
return true; D.Configuration = D.pendingConfiguration;
D.Configuration = D.pendingConfiguration; D.pendingConfiguration.clear();
D.pendingConfiguration.clear(); }
D.UUID = D.pendingUUID; if(D.pendingUUID!=0) {
D.pendingUUID = 0; D.UUID = D.pendingUUID;
D.LastConfigurationChange = Utils::Now(); D.pendingUUID = 0;
}
ConfigurationCache().Add(Utils::SerialNumberToInt(SerialNumber), D.UUID); // if this is a broken device, fix it...
if(D.UUID==0) {
Config::Config Cfg(D.Configuration);
if(Cfg.Valid()) {
D.UUID = Cfg.UUID();
}
}
D.LastConfigurationChange = Utils::Now();
SetCurrentConfigurationID(Utils::SerialNumberToInt(SerialNumber), D.UUID);
Session.begin(); Session.begin();
Poco::Data::Statement Update(Session); Poco::Data::Statement Update(Session);
@@ -525,7 +561,7 @@ namespace OpenWifi {
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
Logger().log(E); Logger().log(E);
} }
return true; return false;
} }
bool Storage::CreateDefaultDevice(Poco::Data::Session &Session, std::string &SerialNumber, const Config::Capabilities &Caps, bool Storage::CreateDefaultDevice(Poco::Data::Session &Session, std::string &SerialNumber, const Config::Capabilities &Caps,
@@ -557,21 +593,31 @@ namespace OpenWifi {
} }
if (!Found && AP_WS_Server()->UseDefaults() && if (!Found && AP_WS_Server()->UseDefaults() &&
FindDefaultConfigurationForModel(Caps.Compatible(), DefConfig)) { FindDefaultConfigurationForModel(Caps.Compatible(), Caps.Platform(), DefConfig)) {
Config::Config NewConfig(DefConfig.Configuration); Config::Config NewConfig(DefConfig.configuration);
NewConfig.SetUUID(Now); NewConfig.SetUUID(Now);
D.Configuration = NewConfig.get(); D.Configuration = NewConfig.get();
} else if (!Found) { } else if (!Found) {
Config::Config NewConfig; if(Caps.Platform()==Platforms::AP) {
NewConfig.SetUUID(Now); Config::Config NewConfig;
D.Configuration = NewConfig.get(); NewConfig.SetUUID(Now);
D.Configuration = NewConfig.get();
} else {
Poco::JSON::Object Obj;
Obj.set("uuid", Now);
std::ostringstream os;
Obj.stringify(os);
D.Configuration = os.str();
}
} }
// We need to insert the country code according to the IP in the radios section... // We need to insert the country code according to the IP in the radios section...
D.locale = InsertRadiosCountyRegulation(D.Configuration, IPAddress); D.locale = InsertRadiosCountyRegulation(D.Configuration, IPAddress);
D.SerialNumber = Poco::toLower(SerialNumber); D.SerialNumber = Poco::toLower(SerialNumber);
D.Compatible = Caps.Compatible(); D.Compatible = Caps.Compatible();
D.DeviceType = Daemon()->IdentifyDevice(D.Compatible); if(D.Compatible.empty())
D.Compatible = Caps.Model();
D.DeviceType = Poco::toLower(Caps.Platform());
D.MACAddress = Utils::SerialToMAC(SerialNumber); D.MACAddress = Utils::SerialToMAC(SerialNumber);
D.Manufacturer = Caps.Model(); D.Manufacturer = Caps.Model();
D.Firmware = Firmware; D.Firmware = Firmware;
@@ -620,6 +666,22 @@ namespace OpenWifi {
return false; return false;
} }
std::string Storage::GetPlatform(const std::string &SerialNumber) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess);
std::string St = fmt::format("SELECT DeviceType FROM Devices WHERE SerialNumber='{}'", SerialNumber);
std::string Platform;
Select << ConvertParams(St), Poco::Data::Keywords::into(Platform);
Select.execute();
return Platform;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return "";
}
bool Storage::DeleteDevice(std::string &SerialNumber) { bool Storage::DeleteDevice(std::string &SerialNumber) {
try { try {
std::vector<std::string> TableNames{"Devices", "Statistics", "CommandList", std::vector<std::string> TableNames{"Devices", "Statistics", "CommandList",
@@ -708,17 +770,14 @@ namespace OpenWifi {
return false; return false;
} }
bool Storage::GetDevice(Poco::Data::Session &Session, std::string &SerialNumber, GWObjects::Device &DeviceDetails) { bool Storage::GetDevice(Poco::Data::Session &Session, const std::string &SerialNumber, GWObjects::Device &DeviceDetails) {
try { try {
Poco::Data::Statement Select(Session); Poco::Data::Statement Select(Session);
std::string St{"SELECT " + DB_DeviceSelectFields + std::string St = fmt::format("SELECT {} FROM Devices WHERE SerialNumber='{}'", DB_DeviceSelectFields, SerialNumber);
" FROM Devices WHERE SerialNumber=?"};
DeviceRecordTuple R; DeviceRecordTuple R;
Select << ConvertParams(St), Poco::Data::Keywords::into(R), Select << St, Poco::Data::Keywords::into(R);
Poco::Data::Keywords::use(SerialNumber);
Select.execute(); Select.execute();
if (Select.rowsExtracted() == 0) if (Select.rowsExtracted() == 0)
return false; return false;
ConvertDeviceRecord(R, DeviceDetails); ConvertDeviceRecord(R, DeviceDetails);
@@ -729,7 +788,7 @@ namespace OpenWifi {
return false; return false;
} }
bool Storage::GetDevice(std::string &SerialNumber, GWObjects::Device &DeviceDetails) { bool Storage::GetDevice(const std::string &SerialNumber, GWObjects::Device &DeviceDetails) {
try { try {
auto Sess = Pool_->get(); auto Sess = Pool_->get();
return GetDevice(Sess, SerialNumber, DeviceDetails); return GetDevice(Sess, SerialNumber, DeviceDetails);
@@ -739,7 +798,7 @@ namespace OpenWifi {
return false; return false;
} }
bool Storage::GetDevice(LockedDbSession &Session, std::string &SerialNumber, GWObjects::Device &DeviceDetails) { bool Storage::GetDevice(LockedDbSession &Session, const std::string &SerialNumber, GWObjects::Device &DeviceDetails) {
try { try {
std::lock_guard Lock(Session.Mutex()); std::lock_guard Lock(Session.Mutex());
return GetDevice(Session.Session(), SerialNumber, DeviceDetails); return GetDevice(Session.Session(), SerialNumber, DeviceDetails);
@@ -817,17 +876,37 @@ namespace OpenWifi {
} }
bool Storage::GetDevices(uint64_t From, uint64_t HowMany, bool Storage::GetDevices(uint64_t From, uint64_t HowMany,
std::vector<GWObjects::Device> &Devices, const std::string &orderBy) { std::vector<GWObjects::Device> &Devices, const std::string &orderBy, const std::string &platform,
bool includeProvisioned) {
DeviceRecordList Records; DeviceRecordList Records;
try { try {
Poco::Data::Session Sess = Pool_->get(); Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Select(Sess); Poco::Data::Statement Select(Sess);
// std::string st{"SELECT " + DB_DeviceSelectFields + " FROM Devices " + orderBy.empty() std::string st;
// ? " ORDER BY SerialNumber ASC " + ComputeRange(From, HowMany)}; std::string whereClause = "";
std::string st = fmt::format("SELECT {} FROM Devices {} {}", DB_DeviceSelectFields, if(platform.empty()) {
orderBy.empty() ? " ORDER BY SerialNumber ASC " : orderBy,
ComputeRange(From, HowMany)); if (includeProvisioned == false) {
whereClause = fmt::format("WHERE entity='' and venue=''");
}
} else {
if (includeProvisioned == false) {
whereClause = fmt::format("WHERE DeviceType='{}' and entity='' and venue=''",platform);
} else {
whereClause = fmt::format("WHERE DeviceType='{}'", platform);
}
}
st =
fmt::format("SELECT {} FROM Devices {} {} {}", DB_DeviceSelectFields, whereClause,
orderBy.empty() ? " ORDER BY SerialNumber ASC " : orderBy,
ComputeRange(From, HowMany));
//Logger().information(fmt::format(" GetDevices st is {} ", st));
Select << ConvertParams(st), Poco::Data::Keywords::into(Records); Select << ConvertParams(st), Poco::Data::Keywords::into(Records);
Select.execute(); Select.execute();
@@ -1056,9 +1135,9 @@ namespace OpenWifi {
} }
} }
uint64_t Associations_2G, Associations_5G, Associations_6G; uint64_t Associations_2G, Associations_5G, Associations_6G, uptime;
StateUtils::ComputeAssociations(RawObject, Associations_2G, Associations_5G, StateUtils::ComputeAssociations(RawObject, Associations_2G, Associations_5G,
Associations_6G); Associations_6G, uptime);
UpdateCountedMap(Dashboard.associations, "2G", Associations_2G); UpdateCountedMap(Dashboard.associations, "2G", Associations_2G);
UpdateCountedMap(Dashboard.associations, "5G", Associations_5G); UpdateCountedMap(Dashboard.associations, "5G", Associations_5G);
UpdateCountedMap(Dashboard.associations, "6G", Associations_6G); UpdateCountedMap(Dashboard.associations, "6G", Associations_6G);
@@ -1082,4 +1161,25 @@ namespace OpenWifi {
FieldList.push_back(field); FieldList.push_back(field);
} }
void Storage::FixDeviceTypeBug() {
try {
std::vector<std::string> ScriptLines{
"update devices set devicetype='ap' where devicetype='AP';",
"update devices set devicetype='switch' where devicetype='SWITCH';",
"update devices set devicetype='ap' where devicetype!='ap' and devicetype!='switch';"
};
for (const auto &ScriptLine : ScriptLines) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement SqlStatement(Sess);
SqlStatement << ScriptLine, Poco::Data::Keywords::now;
} catch (...) {
}
}
} catch (const Poco::Exception &E) {
Logger().log(E);
}
}
} // namespace OpenWifi } // namespace OpenWifi

View File

@@ -275,9 +275,21 @@ namespace OpenWifi {
"Models TEXT, " "Models TEXT, "
"Description TEXT, " "Description TEXT, "
"Created BIGINT , " "Created BIGINT , "
"LastModified BIGINT)", "LastModified BIGINT, Platform TEXT)",
Poco::Data::Keywords::now; Poco::Data::Keywords::now;
} }
std::vector<std::string> Script{
"alter table DefaultConfigs add column Platform text"
};
for (const auto &i : Script) {
try {
Sess << i, Poco::Data::Keywords::now;
} catch (...) {
}
}
return 0; return 0;
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
Logger().log(E); Logger().log(E);