Compare commits

..

21 Commits

Author SHA1 Message Date
TIP Automation User
6ce7436992 Chg: update image tag in helm values to v2.7.1 2022-10-19 23:07:27 +00:00
TIP Automation User
cf2ad4fa5a Chg: update image tag in helm values to v2.7.1-RC2 2022-10-14 19:14:55 +00:00
Stephane Bourque
d8257265da Merge pull request #266 from Telecominfraproject/master
https://telecominfraproject.atlassian.net/browse/WIFI-11226
2022-10-14 11:53:10 -07:00
TIP Automation User
66825a1103 Chg: update image tag in helm values to v2.7.1-RC1 2022-10-11 17:32:44 +00:00
Stephane Bourque
7e6a566996 Merge pull request #263 from Telecominfraproject/master
Creating 2.7.1 release
2022-10-11 10:26:41 -07:00
TIP Automation User
a373a24ee1 Chg: update image tag in helm values to v2.7.0 2022-10-05 11:32:46 +00:00
TIP Automation User
3d6e5e00bb Chg: update image tag in helm values to v2.7.0-RC6 2022-10-05 02:45:44 +00:00
jaspreetsachdev
e7d3b4b151 Merge pull request #260 from Telecominfraproject/master
WIFI-10942
2022-10-04 22:38:13 -04:00
TIP Automation User
c3a51487c0 Chg: update image tag in helm values to v2.7.0-RC5 2022-10-03 11:14:15 +00:00
Dmitry Dunaev
dd44d0504d Merge pull request #253 from Telecominfraproject/master
[WIFI-10581] Add: postgresql-client in Dockerfile
2022-10-03 14:03:55 +03:00
Stephane Bourque
a6ff0ab197 Merge pull request #251 from Telecominfraproject/master
https://telecominfraproject.atlassian.net/browse/WIFI-10942
2022-10-02 10:30:26 -07:00
TIP Automation User
9202893b77 Chg: update image tag in helm values to v2.7.0-RC4 2022-09-30 19:48:53 +00:00
Stephane Bourque
7b1920b7b2 Merge pull request #249 from Telecominfraproject/WIFI-10942
https://telecominfraproject.atlassian.net/browse/WIFI-10942
2022-09-30 11:40:29 -07:00
stephb9959
cafd757593 https://telecominfraproject.atlassian.net/browse/WIFI-10942
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-30 11:35:12 -07:00
stephb9959
ff7a806f67 https://telecominfraproject.atlassian.net/browse/WIFI-10942
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-30 11:33:30 -07:00
TIP Automation User
f264a2e556 Chg: update image tag in helm values to v2.7.0-RC3 2022-09-30 16:31:25 +00:00
Stephane Bourque
f11751ac89 Merge pull request #248 from Telecominfraproject/WIFI-10942
https://telecominfraproject.atlassian.net/browse/WIFI-10942
2022-09-30 08:55:04 -07:00
stephb9959
fa9d59852a https://telecominfraproject.atlassian.net/browse/WIFI-10942
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-30 08:18:47 -07:00
TIP Automation User
51d1df8150 Chg: update image tag in helm values to v2.7.0-RC2 2022-09-29 23:27:31 +00:00
jaspreetsachdev
37e910e1c2 Merge pull request #247 from Telecominfraproject/master
Fixes for WIFI-10846
2022-09-29 19:01:04 -04:00
TIP Automation User
6c038e1d64 Chg: update image tag in helm values to v2.7.0-RC1 2022-09-16 19:54:47 +00:00
217 changed files with 11367 additions and 14928 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.13)
project(owgw VERSION 2.8.0)
project(owgw VERSION 2.7.1)
set(CMAKE_CXX_STANDARD 17)
@@ -39,12 +39,12 @@ endif()
find_package(Git QUIET)
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
execute_process(COMMAND ${GIT_EXECUTABLE} describe --always --tags
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE GIT_RESULT
OUTPUT_VARIABLE GIT_HASH)
if(NOT GIT_RESULT EQUAL "0")
message(FATAL_ERROR "git rev-parse --short HEAD failed with ${GIT_RESULT}")
message(FATAL_ERROR "git describe --always --tags failed with ${GIT_RESULT}")
endif()
string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}")
endif()
@@ -79,56 +79,14 @@ add_executable( owgw
src/framework/KafkaTopics.h
src/framework/MicroService.h
src/framework/OpenWifiTypes.h
src/framework/MicroServiceErrorHandler.h
src/framework/orm.h
src/framework/StorageClass.h
src/framework/MicroServiceErrorHandler.h
src/framework/UI_WebSocketClientServer.cpp
src/framework/UI_WebSocketClientServer.h
src/framework/UI_WebSocketClientNotifications.cpp
src/framework/UI_WebSocketClientNotifications.h
src/framework/utils.h
src/framework/utils.cpp
src/framework/AppServiceRegistry.h
src/framework/SubSystemServer.cpp
src/framework/SubSystemServer.h
src/framework/RESTAPI_utils.h
src/framework/AuthClient.cpp
src/framework/AuthClient.h
src/framework/MicroServiceNames.h
src/framework/MicroServiceFuncs.h
src/framework/OpenAPIRequests.cpp
src/framework/OpenAPIRequests.h
src/framework/MicroServiceFuncs.cpp
src/framework/ALBserver.cpp
src/framework/ALBserver.h
src/framework/KafkaManager.cpp
src/framework/KafkaManager.h
src/framework/RESTAPI_RateLimiter.h
src/framework/WebSocketLogger.h
src/framework/RESTAPI_GenericServerAccounting.h
src/framework/CIDR.h
src/framework/RESTAPI_Handler.cpp
src/framework/RESTAPI_Handler.h
src/framework/RESTAPI_ExtServer.h
src/framework/RESTAPI_ExtServer.cpp
src/framework/RESTAPI_IntServer.cpp
src/framework/RESTAPI_IntServer.h
src/framework/RESTAPI_SystemCommand.h
src/framework/RESTAPI_WebSocketServer.h
src/framework/RESTAPI_SystemConfiguration.h
src/framework/EventBusManager.cpp
src/framework/EventBusManager.h
src/framework/RESTAPI_PartHandler.h
src/framework/MicroService.cpp
src/framework/MicroServiceExtra.h
src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp
src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h
src/RESTObjects/RESTAPI_GWobjects.h src/RESTObjects/RESTAPI_GWobjects.cpp
src/RESTObjects/RESTAPI_FMSObjects.h src/RESTObjects/RESTAPI_FMSObjects.cpp
src/RESTObjects/RESTAPI_CertObjects.cpp src/RESTObjects/RESTAPI_CertObjects.h
src/RESTObjects/RESTAPI_OWLSobjects.cpp src/RESTObjects/RESTAPI_OWLSobjects.h
src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h
src/RESTObjects/RESTAPI_AnalyticsObjects.cpp src/RESTObjects/RESTAPI_AnalyticsObjects.h
src/RESTObjects/RESTAPI_SubObjects.cpp src/RESTObjects/RESTAPI_SubObjects.h
src/RESTAPI/RESTAPI_devices_handler.cpp src/RESTAPI/RESTAPI_devices_handler.h
src/RESTAPI/RESTAPI_device_handler.cpp src/RESTAPI/RESTAPI_device_handler.h
src/RESTAPI/RESTAPI_device_commandHandler.cpp src/RESTAPI/RESTAPI_device_commandHandler.h
@@ -152,6 +110,7 @@ add_executable( owgw
src/Daemon.cpp src/Daemon.h
src/AP_WS_Server.cpp src/AP_WS_Server.h
src/StorageService.cpp src/StorageService.h
# src/DeviceRegistry.cpp src/DeviceRegistry.h
src/CommandManager.cpp src/CommandManager.h
src/CentralConfig.cpp src/CentralConfig.h
src/FileUploader.cpp src/FileUploader.h
@@ -165,37 +124,17 @@ add_executable( owgw
src/CapabilitiesCache.h src/FindCountry.h
src/rttys/RTTYS_server.cpp
src/rttys/RTTYS_server.h
src/rttys/RTTYS_device.cpp
src/rttys/RTTYS_device.h
src/rttys/RTTYS_ClientConnection.cpp
src/rttys/RTTYS_ClientConnection.h
src/rttys/RTTYS_WebServer.cpp
src/rttys/RTTYS_WebServer.h src/RESTAPI/RESTAPI_device_helper.h
src/SDKcalls.cpp
src/SDKcalls.h
src/StateUtils.cpp src/StateUtils.h
src/AP_WS_ReactorPool.h
src/AP_WS_Connection.h
src/AP_WS_Connection.cpp
src/TelemetryClient.h src/TelemetryClient.cpp
src/RESTAPI/RESTAPI_iptocountry_handler.cpp src/RESTAPI/RESTAPI_iptocountry_handler.h
src/framework/ow_constants.h
src/GwWebSocketClient.cpp src/GwWebSocketClient.h
src/RADIUS_proxy_server.cpp src/RADIUS_proxy_server.h
src/RESTAPI/RESTAPI_radiusProxyConfig_handler.cpp src/RESTAPI/RESTAPI_radiusProxyConfig_handler.h
src/ParseWifiScan.h
src/RADIUS_helpers.h
src/VenueBroadcaster.h
src/sdks/sdk_prov.h
src/rttys/RTTYS_WebServer.h src/RESTAPI/RESTAPI_device_helper.h src/SDKcalls.cpp src/SDKcalls.h src/StateUtils.cpp src/StateUtils.h src/AP_WS_ReactorPool.h src/AP_WS_Connection.h src/AP_WS_Connection.cpp src/TelemetryClient.h src/TelemetryClient.cpp src/RESTAPI/RESTAPI_iptocountry_handler.cpp src/RESTAPI/RESTAPI_iptocountry_handler.h src/framework/ow_constants.h src/GwWebSocketClient.cpp src/GwWebSocketClient.h src/framework/WebSocketClientNotifications.h src/RADIUS_proxy_server.cpp src/RADIUS_proxy_server.h src/RESTAPI/RESTAPI_radiusProxyConfig_handler.cpp src/RESTAPI/RESTAPI_radiusProxyConfig_handler.h src/ParseWifiScan.h src/RADIUS_helpers.h src/VenueBroadcaster.h src/sdks/sdk_prov.h
src/AP_WS_Process_connect.cpp
src/AP_WS_Process_state.cpp
src/AP_WS_Process_healthcheck.cpp
src/AP_WS_Process_log.cpp
src/AP_WS_Process_crashlog.cpp
src/AP_WS_Process_ping.cpp
src/AP_WS_Process_cfgpending.cpp
src/AP_WS_Process_recovery.cpp
src/AP_WS_Process_deviceupdate.cpp
src/AP_WS_Process_telemetry.cpp
src/AP_WS_Process_venuebroadcast.cpp
src/RADSEC_server.h
src/UI_GW_WebSocketNotifications.cpp src/UI_GW_WebSocketNotifications.h src/framework/RESTAPI_SystemConfiguration.h src/ScriptManager.cpp src/ScriptManager.h src/RESTAPI/RESTAPI_scripts_handler.cpp src/RESTAPI/RESTAPI_scripts_handler.h src/RESTAPI/RESTAPI_script_handler.cpp src/RESTAPI/RESTAPI_script_handler.h src/storage/storage_scripts.cpp src/storage/storage_scripts.h src/SignatureMgr.cpp src/SignatureMgr.h)
src/AP_WS_Process_crashlog.cpp src/AP_WS_Process_ping.cpp src/AP_WS_Process_cfgpending.cpp src/AP_WS_Process_recovery.cpp src/AP_WS_Process_deviceupdate.cpp src/AP_WS_Process_telemetry.cpp src/AP_WS_Process_venuebroadcast.cpp src/RADSECserver.h)
if(NOT SMALL_BUILD)
@@ -219,4 +158,4 @@ if(NOT SMALL_BUILD)
if(UNIX AND NOT APPLE)
target_link_libraries(owgw PUBLIC PocoJSON)
endif()
endif()
endif()

View File

@@ -1,5 +1,6 @@
ARG DEBIAN_VERSION=11.5-slim
ARG POCO_VERSION=poco-tip-v2
ARG POCO_VERSION=poco-tip-v1
ARG FMTLIB_VERSION=9.0.0
ARG CPPKAFKA_VERSION=tip-v1
ARG JSON_VALIDATOR_VERSION=2.1.0
@@ -9,7 +10,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
make cmake g++ git \
libpq-dev libmariadb-dev libmariadbclient-dev-compat \
librdkafka-dev libboost-all-dev libssl-dev \
zlib1g-dev nlohmann-json3-dev ca-certificates libfmt-dev
zlib1g-dev nlohmann-json3-dev ca-certificates
FROM build-base AS poco-build
@@ -25,6 +26,20 @@ RUN cmake ..
RUN cmake --build . --config Release -j8
RUN cmake --build . --target install
FROM build-base AS fmtlib-build
ARG FMTLIB_VERSION
ADD https://api.github.com/repos/fmtlib/fmt/git/refs/tags/${FMTLIB_VERSION} version.json
RUN git clone https://github.com/fmtlib/fmt --branch ${FMTLIB_VERSION} /fmtlib
WORKDIR /fmtlib
RUN mkdir cmake-build
WORKDIR cmake-build
RUN cmake ..
RUN make
RUN make install
FROM build-base AS cppkafka-build
ARG CPPKAFKA_VERSION
@@ -66,6 +81,8 @@ COPY --from=cppkafka-build /usr/local/include /usr/local/include
COPY --from=cppkafka-build /usr/local/lib /usr/local/lib
COPY --from=json-schema-validator-build /usr/local/include /usr/local/include
COPY --from=json-schema-validator-build /usr/local/lib /usr/local/lib
COPY --from=fmtlib-build /usr/local/include /usr/local/include
COPY --from=fmtlib-build /usr/local/lib /usr/local/lib
WORKDIR /owgw
RUN mkdir cmake-build
@@ -87,7 +104,7 @@ RUN mkdir -p "$OWGW_ROOT" "$OWGW_CONFIG" && \
RUN apt-get update && apt-get install --no-install-recommends -y \
librdkafka++1 gosu gettext ca-certificates bash jq curl wget \
libmariadb-dev-compat libpq5 unixodbc postgresql-client libfmt7 sqlite3
libmariadb-dev-compat libpq5 unixodbc postgresql-client
COPY readiness_check /readiness_check
COPY test_scripts/curl/cli /cli
@@ -101,7 +118,7 @@ RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentr
COPY --from=owgw-build /owgw/cmake-build/owgw /openwifi/owgw
COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib /usr/local/lib/
COPY --from=poco-build /poco/cmake-build/lib /usr/local/lib/
COPY --from=poco-build /poco/cmake-build/lib /usr/local/lib
RUN ldconfig

View File

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

View File

@@ -298,8 +298,7 @@ Controller sends this command when it believes the device should upgrade its fir
"params" : {
"serial" : <serial number> ,
"when" : Optional - <UTC time when to upgrade the firmware, 0 mean immediate, this is a suggestion>,
"uri" : <URI to download the firmware>,
"FWsignature" : <string representation of the signature for the FW> (optional)
"uri" : <URI to download the firmware>
},
"id" : <some number>
}
@@ -319,13 +318,6 @@ The device should answer:
"id" : <same number>
}
```
Here are the error values
```text
0: No error
1: Bad firmware
2: Missing signature
```
#### Controller wants the device to perform a factory reset
Controller sends this command when it believes the device should upgrade its firmware.
@@ -431,6 +423,44 @@ The device should answer:
- 1 : device cannot flash LEDs because it does not have any.
- 2 : device rejects the request. `text` should include information as to why.
#### Controller sends a device specific command
Controller sends this command specific to this device. The command is proprietary and must be agreed upon by the device
and the controller.
```json
{ "jsonrpc" : "2.0" ,
"method" : "perform" ,
"params" : {
"serial" : <serial number> ,
"when" : Optional - <UTC time when to perform this command, 0 mean immediate, this is a suggestion>,
"command" : <this is device specific and is TEXT only>,
"payload" : <JSON Document: containing additional information about the command>
},
"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>,
"when" : <in UTC time in seconds>,
"resultCode" : <0 or an appropriate error code>,
"resultText" : <any text resulting from the command. This is propietary to each command>
}
},
"id" : <same number>
}
```
##### The device answer
The device should answer with teh above message. The `error` value should be interpreted the following way:
- 0 : the command was performed as requested and the reults of the command is available in the `resultCode` and `resultText` parameters.
- 1 : the command will be performed in the future and `when` shows that time. The `resultCode` and `resultText` dod not contain anything relevant.
- 2 : the command cannot be performed as indicated. `resultCode` and `resultText` may contain some indication as to why.
#### Controller wants the device to perform a trace
Controller sends this command when it needs the device to perform a trace (i.e. tcpdump).
```json
@@ -681,11 +711,9 @@ Controller sends this command to run a predefined script. Extreme care must be t
"method" : "script" ,
"params" : {
"serial" : <serial number>,
"type" : <one of "shell", "ucode", "bundle">,
"script" : <text blob containing the script, This must be vase64 encoded>,
"timeout" : <max timeout in seconds, default is 30, unused if URI is supplied>,
"uri": "<upload script results using this URI>",
"signature" : "<signature for script>: must be supplied to restricted devices",
"type" : <one of "shell", "ucode">,
"script" : <text blob containing the script>,
"timeout" : <max timeout in seconds, default is 30>,
"when" : <time when this will be performed as UTC seconds>
},
"id" : <some number>

View File

@@ -1,82 +0,0 @@
# Restricted devices
## What is a restricted device?
A restricted device is one that because of regulations or a desire for utmost security, requires signatures to access restricted or blocked
features. The restriction process is burnt in the device at manufacturing or later by running a specific command on the device. Once a device
is restricted, it cannot be unlocked.
## Current restrictions
Restrictions are stored on the AP in a protected partition. They are contained in a file called `restrictions.json`. Here is a sample:
```json
{
"country": [
"US", "CA"
],
"dfs": true,
"rtty": true,
"tty": true,
"developer": true,
"sysupgrade": true,
"commands": true,
"key_info": {
"vendor": "dummy",
"algo": "static"
}
}
```
- country
- List of countries where this device may be used
- dfs
- Disallow DFS Override during wifi-scan. If set to `true`, device will not allow to override DFS channels
- rtty
- Disallow the use of the RTTY command for this device
- tty
- Do not allow the AP to accept `tty` connection
- developer
- Internal use only.
- sysupgrade
- If set to `true`, only signed firmware upgrade command will be allowed.
- commands
- If set to `true`, do not allow commands.
- key_info
- This structure defines how signatures should be generated and verified in a secure system
- vendor
- An identified that must match the vendor name provided in the controller
- algo
- The signature algorithm. Here are the supported algorithms
- `static`
- A test algorithm that always returns and uses a value of `aaaaaaaaaa`. This should never be used in the field.
- `dgst-sha256`
- The default OpenSSL RSA signature generation and verification. The controller will use the following command to generate the signature
```sh
openssl dgst -sha256 -sign private-key.pem -out signature.txt myfile
```
- The AP will be using the following to verify the signature
```sh
openssl dgst -sha256 -verify public-key.pem -signature signature.txt myfile
```
## Creating signatures on the controller
When a device is restricted and a signature is required, the controller can generate the signature
for the specified `vendor`. However, on the controlelr side, you must configure the vendors. In
order to do so we suggest the following.
- Create a directory called `signatures` under your `certs` directory
- Copy the public and private keys for each `vendor` name. We suggest naming them accordingly
- `vendor`-private-key.pem
- `vendor`-public-key.pem
- In the `owgw.properties` file, you need to declare these signatures the following way
```properties
signature.manager.0.key.public = $OWGW_ROOT/certs/signatures/test1-public-key.pem
signature.manager.0.key.private = $OWGW_ROOT/certs/signatures/test1-private-key.pem
signature.manager.0.vendor = test1
signature.manager.1.key.public = $OWGW_ROOT/certs/signatures/test2-public-key.pem
signature.manager.1.key.private = $OWGW_ROOT/certs/signatures/test2-private-key.pem
signature.manager.1.vendor = test2
```
## How do you use the signatures?
There is nothing to do really. Now the controller will use the proper key to create the signatures
when it sends commands to the AP. It will use the algorithm that the device understands too. This is transparent
to the user. The `vendor` name used in the controller configuration must match the `vendor` name provided in the
`restrictions.json` file.

View File

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

View File

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

View File

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

View File

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

View File

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

2
build
View File

@@ -1 +1 @@
94
6

View File

@@ -73,7 +73,6 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"owgw"} \
STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"owgw"} \
STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \
CERTIFICATES_ALLOWMISMATCH=${CERTIFICATES_ALLOWMISMATCH:-"false"} \
envsubst < /owgw.properties.tmpl > $OWGW_CONFIG/owgw.properties
fi

View File

@@ -9,7 +9,7 @@ fullnameOverride: ""
images:
owgw:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owgw
tag: v2.8.0
tag: v2.7.1
pullPolicy: Always
# regcred:
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
@@ -230,7 +230,6 @@ configProperties:
openwifi.devicetypes.0: AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
openwifi.devicetypes.1: SWITCH:edgecore_ecs4100-12ph
openwifi.devicetypes.2: IOT:esp32
openwifi.certificates.allowmismatch: "false"
oui.download.uri: https://standards-oui.ieee.org/oui/oui.txt
firmware.autoupdate.policy.default: auto
iptocountry.provider: ipinfo

View File

@@ -49,38 +49,6 @@ components:
- IOT
- MESH
DeviceRestrictionsKeyInfo:
type: object
properties:
vendor:
type: string
algo:
type: string
DeviceRestrictions:
type: object
properties:
dfs:
type: boolean
ssh:
type: boolean
rtty:
type: boolean
tty:
type: boolean
developer:
type: boolean
upgrade:
type: boolean
commands:
type: boolean
country:
type: array
items:
type: string
key_info:
$ref: '#/components/schemas/DeviceRestrictionsKeyInfo'
Device:
type: object
description: Definition of uCentral device
@@ -139,19 +107,6 @@ components:
type: string
minLength: 2
maxLength: 2
restrictedDevice:
type: boolean
default: false
certificateExpiryDate:
type: integer
format: int64
pendingConfiguration:
type: string
pendingConfigurationCmd:
type: string
format: uuid
restrictionDetails:
$ref: '#/components/schemas/DeviceRestrictions'
DeviceWithStatus:
type: object
@@ -247,19 +202,6 @@ components:
totalConnectionTime:
type: integer
format: int64
restrictedDevice:
type: boolean
default: false
certificateDate:
type: integer
format: int64
pendingConfiguration:
type: string
pendingConfigurationCmd:
type: string
format: uuid
restrictionDetails:
$ref: '#/components/schemas/DeviceRestrictions'
DeviceList:
type: object
@@ -558,69 +500,18 @@ components:
type:
type: string
enum:
- uci
- ucode
- shell
- bundle
- diagnostic
script:
type: string
scriptId:
type: string
format: uuid
when:
type: integer
format: int64
default: 0
signature:
type: string
deferred:
type: boolean
uri:
type: string
ScriptEntry:
type: object
properties:
id:
type: string
name:
type: string
description:
type: string
uri:
type: string
content:
type: string
version:
type: string
type:
enum:
- shell
- bundle
created:
type: integer
modified:
type: integer
author:
type: string
restricted:
type: array
items:
type: string
deferred:
type: boolean
default: false
timeout:
type: integer
default: 30
defaultUploadURI:
type: string
ScriptEntryList:
type: object
properties:
scripts:
type: array
items:
$ref: '#/components/schemas/ScriptEntry'
FactoryRequest:
type: object
@@ -1030,26 +921,9 @@ components:
items:
$ref: '#/components/schemas/TagValuePair'
ExtraSystemConfiguration:
type: array
items:
type: object
properties:
parameterName:
type: string
parameterType:
type: string
enum:
- string
- integer
- boolean
- path
parameterValue:
{}
#########################################################################################
##
## End of uCentral system-wide values
## End of uCentral system wide values
##
#########################################################################################
BlackDeviceInfo:
@@ -2016,12 +1890,6 @@ paths:
schema:
type: boolean
required: false
- in: query
description: Return the number of matching records.
name: countOnly
schema:
type: boolean
required: false
responses:
200:
@@ -2031,8 +1899,6 @@ paths:
schema:
oneOf:
- $ref: '#/components/schemas/StatisticsRecords'
- $ref: '#/components/schemas/DeviceCount'
403:
$ref: '#/components/responses/Unauthorized'
404:
@@ -2210,11 +2076,6 @@ paths:
schema:
type: string
required: true
- in: query
name: FWsignature
schema:
type: string
required: false
requestBody:
description: Command details
content:
@@ -2569,148 +2430,6 @@ paths:
404:
$ref: '#/components/responses/NotFound'
/scripts:
get:
tags:
- Scripting
summary: Returns a list scripts.
description: Get a list of scripts.
operationId: getScripts
parameters:
- in: query
description: Pagination start (starts at 0. If not specified, 0 is assumed)
name: offset
schema:
type: integer
required: false
- in: query
description: Maximum number of entries to return (if absent, no limit is assumed)
name: limit
schema:
type: integer
required: false
- in: query
description: Filter the results
name: filter
schema:
type: string
required: false
responses:
200:
description: List all scripts
content:
application/json:
schema:
$ref: '#/components/schemas/ScriptEntryList'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/script/{uuid}:
get:
tags:
- Scripting
summary: Returns a script entry.
description: Get a specific script entry.
operationId: getScript
parameters:
- in: path
description: The UUID of the script
name: uuid
schema:
type: string
format: uuid
required: true
responses:
200:
description: A script entry
content:
application/json:
schema:
$ref: '#/components/schemas/ScriptEntry'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
post:
tags:
- Scripting
summary: Create a new script.
operationId: createScript
parameters:
- in: path
description: The UUID of the script. Must be set to 0 for creation
name: uuid
schema:
type: string
format: uuid
required: true
requestBody:
description: Complet script entry
content:
application/json:
schema:
$ref: '#/components/schemas/ScriptEntry'
responses:
200:
$ref: '#/components/schemas/ScriptEntry'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
put:
tags:
- Scripting
summary: Modify a script.
operationId: modifyScript
parameters:
- in: path
description: The UUID of the script.
name: uuid
schema:
type: string
format: uuid
required: true
requestBody:
description: Complete script entry. You may only modify the name, description, version, uri, and content
content:
application/json:
schema:
$ref: '#/components/schemas/ScriptEntry'
responses:
200:
$ref: '#/components/schemas/ScriptEntry'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
delete:
tags:
- Scripting
summary: Delete a script.
operationId: deleteScript
parameters:
- in: path
name: uuid
schema:
type: string
format: uuid
required: true
responses:
204:
$ref: '#/components/responses/Success'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/blacklist:
get:
tags:
@@ -3012,51 +2731,4 @@ paths:
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/systemConfiguration:
get:
tags:
- SystemConfiguration
summary: Retrieve system configuration items
operationId: getSystemConfiguration
responses:
200:
$ref: '#/components/schemas/ExtraSystemConfiguration'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
put:
tags:
- SystemConfiguration
summary: Set some or all system configuration
operationId: setSystemConfiguration
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/ExtraSystemConfiguration'
responses:
200:
$ref: '#/components/schemas/ExtraSystemConfiguration'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
delete:
tags:
- SystemConfiguration
summary: Delete all additional system configuration
operationId: deleteSystemConfiguration
responses:
200:
$ref: '#/components/responses/Success'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
$ref: '#/components/responses/NotFound'

View File

@@ -75,7 +75,6 @@ openwifi.autoprovisioning = true
openwifi.devicetypes.0 = AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
openwifi.devicetypes.1 = SWITCH:edgecore_ecs4100-12ph
openwifi.devicetypes.2 = IOT:esp32
openwifi.certificates.allowmismatch = ${CERTIFICATES_ALLOWMISMATCH}
oui.download.uri = https://standards-oui.ieee.org/oui/oui.txt
simulatorid = ${SIMULATORID}
iptocountry.default = US

View File

@@ -16,7 +16,6 @@
"weight" : 10,
"radsec" : true,
"radsecPort" : 2083,
"allowSelfSigned" : false,
"radsecSecret" : "radsec",
"radsecKey" : "LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUR6RnpXeTZlYXg0QVoxTySG9VUURRZ0FFS3BnWVBHMktPTVd2S0w1Z3NMRXpUc09rREg1M3NHaEQyS3RsRXBDTXVnNDNIZlFnTFVpUgpTR1R2S1l0bDFmbmJaU1lnY0RJdncxdjNYRy9hVDhOY2JBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=",
"radsecCert" : "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNRVENDQWVpZ0F3SUJBZ0lVY3BKS3pVM0Ba0dBMVVFQmhNQ1ZWTXhFekFSQmdOVkJBb1RDa0oxZEhSdmJuZHZiMlF4SFRBYkJnTlZCQU1URkVKMQpkSFJ2Ym5kdmIyUWdVbUZrYzJWaklFTkJNQjRYRFRJeU1EY3dNekExTWpVeE5Gb1hEVEkzTURVeE9UQTFNalV4Ck5Gb3dkVEVMTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFvVENrSjFkSFJ2Ym5kdmIyUXhOakEwQmdOVkJBTVQKTFdGeWFXeHBZUzVqWWpFd2FtTnVjemgxYlhCbk9HWnBjRFowTUM1dmNtbHZiaTVoY21WaE1USXdMbU52YlRFWgpNQmNHQ2dtU0pvbVQ4aXhrQVFFVENVZHZiMmRzWlRwVlV6QlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VICkEwSUFCQ3FZR0R4dGlqakZyeWkrWUxDeE0wN0RwQXgrZDdCb1E5aXJaUktRakxvT054MzBJQzFJa1Voazd5bUwKWmRYNTIyVW1JSEF5TDhOYjkxeHYyay9EWEd5amdZa3dnWVl3RGdZRFZSMFBBUUgvQkFRREFnZUFNQk1HQTFVZApKUVFNTUFvR0NDc0dBUVVGQndNQ01Bd0dBMVVkRXdFQi93UUNNQUF3T0FZRFZSMFJCREV3TDRJdFlYSnBiR2xoCkxtTmlNVEJxWTI1ek9IVnRjR2M0Wm1sd05uUXdMbTl5YVc5dUxtRnlaV0V4TWpBdVkyOXRNQmNHQTFVZElBUVEKTUE0d0RBWUtLd1lCQkFIdUtnRUJCVEFLQmdncWhrak9QUVFEQWdOSEFEQkVBaUFwTmM1dUNBSkp6KzVyakdqdwpCWGtOdHE3UU83bWU5dUg5bkNsTDZnSVE5Z0lnUHM2VkVKVW5CcEZ0RktXbFF4eWJ1YlBxYnpJNjBPSERHQ0ExCmhXUk1PS1U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K",

View File

@@ -11,7 +11,7 @@
#include "Poco/Net/SSLException.h"
#include "Poco/Net/Context.h"
#include "Poco/Base64Decoder.h"
#include "Poco/Net/WebSocketImpl.h"
#include "Poco/zlib.h"
#include "AP_WS_Server.h"
@@ -20,16 +20,8 @@
#include "ConfigurationCache.h"
#include "StorageService.h"
#include "TelemetryStream.h"
#include "framework/KafkaManager.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.h"
#include "UI_GW_WebSocketNotifications.h"
#include "fmt/format.h"
#include "framework/ow_constants.h"
#include "framework/WebSocketClientNotifications.h"
#include "Poco/Net/WebSocketImpl.h"
#include "RADIUS_proxy_server.h"
@@ -43,7 +35,7 @@ namespace OpenWifi {
AP_WS_Connection::AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response,
uint64_t connection_id,
std::uint64_t connection_id,
Poco::Logger &L,
Poco::Net::SocketReactor &R)
: Logger_(L) ,
@@ -73,6 +65,27 @@ namespace OpenWifi {
Valid_ = true;
}
class ThreadedCounter {
public:
ThreadedCounter(bool T, std::atomic_uint64_t &C) :
C_(C),
Threaded_(T) {
if(Threaded_) {
C_++;
}
}
~ThreadedCounter() {
if(Threaded_ && C_>0) {
C_--;
}
}
private:
std::atomic_uint64_t &C_;
bool Threaded_;
};
bool AP_WS_Connection::ValidatedDevice() {
if(DeviceValidated_)
return true;
@@ -80,7 +93,6 @@ namespace OpenWifi {
if(!Valid_)
return false;
std::lock_guard Lock(ConnectionMutex_);
try {
auto SockImpl = dynamic_cast<Poco::Net::WebSocketImpl *>(WS_->impl());
auto SS = dynamic_cast<Poco::Net::SecureStreamSocketImpl*>(SockImpl->streamSocketImpl());
@@ -88,7 +100,7 @@ namespace OpenWifi {
PeerAddress_ = SS->peerAddress().host();
CId_ = Utils::FormatIPv6(SS->peerAddress().toString());
State_.started = Utils::Now();
State_.started = OpenWifi::Now();
if (!SS->secure()) {
poco_warning(Logger_,fmt::format("TLS-CONNECTION({}): Session={} Connection is NOT secure. Device is not allowed.", CId_, State_.sessionId ));
@@ -128,7 +140,7 @@ namespace OpenWifi {
return false;
}
if (!CN_.empty() && StorageService()->IsBlackListed(CN_)) {
if (!CN_.empty() && StorageService()->IsBlackListed(SerialNumber_)) {
poco_warning(
Logger_,
fmt::format("TLS-CONNECTION({}): Session={} Device {} is black listed. Disconnecting.",
@@ -137,7 +149,6 @@ namespace OpenWifi {
return false;
}
State_.certificateExpiryDate = PeerCert.expiresOn().timestamp().epochTime();
SerialNumber_ = CN_;
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
@@ -187,7 +198,7 @@ namespace OpenWifi {
Poco::JSON::Object Disconnect;
Poco::JSON::Object Details;
Details.set(uCentralProtocol::SERIALNUMBER, SerialNumber);
Details.set(uCentralProtocol::TIMESTAMP, Utils::Now());
Details.set(uCentralProtocol::TIMESTAMP, OpenWifi::Now());
Disconnect.set(uCentralProtocol::DISCONNECTION, Details);
Poco::JSON::Stringifier Stringify;
std::ostringstream OS;
@@ -227,11 +238,8 @@ namespace OpenWifi {
}
auto SessionDeleted = AP_WS_Server()->EndSession(State_.sessionId, SerialNumberInt_);
if (SessionDeleted) {
GWWebSocketNotifications::SingleDevice_t N;
N.content.serialNumber = SerialNumber_;
GWWebSocketNotifications::DeviceDisconnected(N);
}
if (SessionDeleted)
WebSocketClientNotificationDeviceDisconnected(SerialNumber_);
}
}
@@ -272,7 +280,7 @@ namespace OpenWifi {
State_.PendingUUID = D.UUID;
GWObjects::CommandDetails Cmd;
Cmd.SerialNumber = SerialNumber_;
Cmd.UUID = MicroServiceCreateUUID();
Cmd.UUID = MicroService::CreateUUID();
Cmd.SubmittedBy = uCentralProtocol::SUBMITTED_BY_SYSTEM;
Cmd.Status = uCentralProtocol::PENDING;
Cmd.Command = uCentralProtocol::CONFIGURE;
@@ -292,13 +300,9 @@ namespace OpenWifi {
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);
CommandManager()->PostCommand(CommandManager()->NextRPCId(),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
GWWebSocketNotifications::SingleDeviceConfigurationChange_t Notification;
Notification.content.serialNumber = D.SerialNumber;
Notification.content.oldUUID = UUID;
Notification.content.newUUID = UpgradedUUID;
GWWebSocketNotifications::DeviceConfigurationChange(Notification);
WebSocketClientNotificationDeviceConfigurationChange(D.SerialNumber, UUID, UpgradedUUID);
return true;
}
@@ -307,7 +311,7 @@ namespace OpenWifi {
void AP_WS_Connection::ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc) {
poco_debug(Logger_,fmt::format("RECEIVED-RPC({}): {}.", CId_, Doc->get(uCentralProtocol::ID).toString()));
CommandManager()->PostCommandResult(SerialNumber_, Doc);
CommandManager()->PostCommandResult(SerialNumber_, *Doc);
}
void AP_WS_Connection::ProcessJSONRPCEvent(Poco::JSON::Object::Ptr &Doc) {
@@ -432,14 +436,14 @@ namespace OpenWifi {
}
}
bool AP_WS_Connection::StartTelemetry(uint64_t RPCID) {
bool AP_WS_Connection::StartTelemetry(std::uint64_t RPCID) {
poco_information(Logger_, fmt::format("TELEMETRY({}): Starting.", CId_));
Poco::JSON::Object StartMessage;
StartMessage.set("jsonrpc", "2.0");
StartMessage.set("method", "telemetry");
Poco::JSON::Object Params;
Params.set("serial", SerialNumber_);
Params.set("interval", (uint64_t)TelemetryInterval_);
Params.set("interval", TelemetryInterval_);
Poco::JSON::Array Types;
Types.add("wifi-frames");
Types.add("dhcp-snooping");
@@ -453,7 +457,7 @@ namespace OpenWifi {
return Send(OS.str());
}
bool AP_WS_Connection::StopTelemetry(uint64_t RPCID) {
bool AP_WS_Connection::StopTelemetry(std::uint64_t RPCID) {
poco_information(Logger_, fmt::format("TELEMETRY({}): Stopping.", CId_));
Poco::JSON::Object StopMessage;
StopMessage.set("jsonrpc", "2.0");
@@ -476,13 +480,13 @@ namespace OpenWifi {
State_.webSocketClients = TelemetryWebSocketRefCount_;
}
bool AP_WS_Connection::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t Interval,
uint64_t LifeTime) {
bool AP_WS_Connection::SetWebSocketTelemetryReporting(std::uint64_t RPCID, uint64_t Interval,
uint64_t LifeTime) {
std::unique_lock Lock(TelemetryMutex_);
TelemetryWebSocketRefCount_++;
TelemetryInterval_ = TelemetryInterval_ ? ( Interval< TelemetryInterval_ ? Interval : TelemetryInterval_) : Interval;
auto TelemetryWebSocketTimer = LifeTime + Utils::Now();
TelemetryWebSocketTimer_ = TelemetryWebSocketTimer > TelemetryWebSocketTimer_ ? TelemetryWebSocketTimer : TelemetryWebSocketTimer_;
TelemetryInterval_ = TelemetryInterval_ ? std::min(Interval, TelemetryInterval_) : Interval;
auto TelemetryWebSocketTimer = LifeTime + OpenWifi::Now();
TelemetryWebSocketTimer_ = std::max(TelemetryWebSocketTimer, TelemetryWebSocketTimer_);
UpdateCounts();
if (!TelemetryReporting_) {
TelemetryReporting_ = true;
@@ -491,12 +495,12 @@ namespace OpenWifi {
return true;
}
bool AP_WS_Connection::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t Interval, uint64_t LifeTime) {
bool AP_WS_Connection::SetKafkaTelemetryReporting(std::uint64_t RPCID, uint64_t Interval, uint64_t LifeTime) {
std::unique_lock Lock(TelemetryMutex_);
TelemetryKafkaRefCount_++;
TelemetryInterval_ = TelemetryInterval_ ? ( Interval<TelemetryInterval_ ? Interval : TelemetryInterval_) : Interval;
auto TelemetryKafkaTimer = LifeTime + Utils::Now();
TelemetryKafkaTimer_ = TelemetryKafkaTimer > TelemetryKafkaTimer_ ? TelemetryKafkaTimer : TelemetryKafkaTimer_;
TelemetryInterval_ = TelemetryInterval_ ? std::min(Interval, TelemetryInterval_) : Interval;
auto TelemetryKafkaTimer = LifeTime + OpenWifi::Now();
TelemetryKafkaTimer_ = std::max(TelemetryKafkaTimer, TelemetryKafkaTimer_);
UpdateCounts();
if (!TelemetryReporting_) {
TelemetryReporting_ = true;
@@ -505,7 +509,7 @@ namespace OpenWifi {
return true;
}
bool AP_WS_Connection::StopWebSocketTelemetry(uint64_t RPCID) {
bool AP_WS_Connection::StopWebSocketTelemetry(std::uint64_t RPCID) {
std::unique_lock Lock(TelemetryMutex_);
if (TelemetryWebSocketRefCount_)
TelemetryWebSocketRefCount_--;
@@ -517,7 +521,7 @@ namespace OpenWifi {
return true;
}
bool AP_WS_Connection::StopKafkaTelemetry(uint64_t RPCID) {
bool AP_WS_Connection::StopKafkaTelemetry(std::uint64_t RPCID) {
std::unique_lock Lock(TelemetryMutex_);
if (TelemetryKafkaRefCount_)
TelemetryKafkaRefCount_--;
@@ -582,7 +586,7 @@ namespace OpenWifi {
State_.RX += IncomingSize;
State_.MessageCount++;
State_.LastContact = Utils::Now();
State_.LastContact = OpenWifi::Now();
switch (Op) {
case Poco::Net::WebSocket::FRAME_OP_PING: {
@@ -590,6 +594,7 @@ namespace OpenWifi {
WS_->sendFrame("", 0,
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
State_.MessageCount++;
if (KafkaManager()->Enabled()) {
Poco::JSON::Object PingObject;
@@ -598,7 +603,7 @@ namespace OpenWifi {
PingDetails.set(uCentralProtocol::SERIALNUMBER, SerialNumber_);
PingDetails.set(uCentralProtocol::COMPATIBLE, Compatible_);
PingDetails.set(uCentralProtocol::CONNECTIONIP, CId_);
PingDetails.set(uCentralProtocol::TIMESTAMP, Utils::Now());
PingDetails.set(uCentralProtocol::TIMESTAMP, OpenWifi::Now());
PingDetails.set("locale", State_.locale );
PingObject.set(uCentralProtocol::PING, PingDetails);
Poco::JSON::Stringifier Stringify;

View File

@@ -16,6 +16,7 @@
#include "RESTObjects/RESTAPI_GWobjects.h"
namespace OpenWifi {
class AP_WS_Connection {
@@ -23,7 +24,7 @@ namespace OpenWifi {
public:
explicit AP_WS_Connection( Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response,
uint64_t connection_id,
std::uint64_t connection_id,
Poco::Logger &L,
Poco::Net::SocketReactor &R);
~AP_WS_Connection();
@@ -43,44 +44,14 @@ namespace OpenWifi {
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf);
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf);
bool LookForUpgrade(uint64_t UUID, uint64_t & UpgradedUUID);
bool LookForUpgrade(const uint64_t UUID, uint64_t & UpgradedUUID);
static bool ExtractBase64CompressedData(const std::string & CompressedData, std::string & UnCompressedData, uint64_t compress_sz);
void LogException(const Poco::Exception &E);
inline Poco::Logger & Logger() { return Logger_; }
bool SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t interval, uint64_t TelemetryWebSocketTimer);
bool SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t interval, uint64_t TelemetryKafkaTimer);
bool StopWebSocketTelemetry(uint64_t RPCID);
bool StopKafkaTelemetry(uint64_t RPCID);
inline void GetLastStats(std::string &LastStats) const {
std::shared_lock G(ConnectionMutex_);
LastStats = RawLastStats_;
}
inline void SetLastStats(const std::string &LastStats) {
std::unique_lock G(ConnectionMutex_);
RawLastStats_ = LastStats;
}
inline void SetLastHealthCheck(const GWObjects::HealthCheck &H) {
std::unique_lock G(ConnectionMutex_);
RawLastHealthcheck_ = H;
}
inline void GetLastHealthCheck(GWObjects::HealthCheck &H) {
std::shared_lock G(ConnectionMutex_);
H = RawLastHealthcheck_;
}
inline void GetState(GWObjects::ConnectionState &State) const {
std::shared_lock G(ConnectionMutex_);
State = State_;
}
inline void GetRestrictions(GWObjects::DeviceRestrictions & R) const {
std::shared_lock G(ConnectionMutex_);
R = Restrictions_;
}
bool SetWebSocketTelemetryReporting(std::uint64_t RPCID, uint64_t interval, uint64_t TelemetryWebSocketTimer);
bool SetKafkaTelemetryReporting(std::uint64_t RPCID, uint64_t interval, uint64_t TelemetryKafkaTimer);
bool StopWebSocketTelemetry(std::uint64_t RPCID);
bool StopKafkaTelemetry(std::uint64_t RPCID);
void Process_connect(Poco::JSON::Object::Ptr ParamsObj, const std::string &Serial);
void Process_state(Poco::JSON::Object::Ptr ParamsObj);
@@ -112,15 +83,11 @@ namespace OpenWifi {
return true;
}
friend class DeviceRegistry;
friend class AP_WS_Server;
inline GWObjects::DeviceRestrictions Restrictions() const {
std::shared_lock G(ConnectionMutex_);
return Restrictions_;
}
private:
mutable std::shared_mutex ConnectionMutex_;
// std::recursive_mutex LocalMutex_;
std::shared_mutex TelemetryMutex_;
Poco::Logger &Logger_;
Poco::Net::SocketReactor &Reactor_;
@@ -133,28 +100,28 @@ namespace OpenWifi {
std::string CN_;
uint64_t Errors_=0;
Poco::Net::IPAddress PeerAddress_;
volatile bool TelemetryReporting_ = false;
volatile uint64_t TelemetryWebSocketRefCount_ = 0;
volatile uint64_t TelemetryKafkaRefCount_ = 0;
volatile uint64_t TelemetryWebSocketTimer_ = 0;
volatile uint64_t TelemetryKafkaTimer_ = 0 ;
volatile uint64_t TelemetryInterval_ = 0;
volatile uint64_t TelemetryWebSocketPackets_=0;
volatile uint64_t TelemetryKafkaPackets_=0;
std::atomic_bool TelemetryReporting_ = false;
std::atomic_uint64_t TelemetryWebSocketRefCount_ = 0;
std::atomic_uint64_t TelemetryKafkaRefCount_ = 0;
uint64_t TelemetryWebSocketTimer_ = 0;
uint64_t TelemetryKafkaTimer_ = 0 ;
uint64_t TelemetryInterval_ = 0;
std::atomic_uint64_t TelemetryWebSocketPackets_=0;
std::atomic_uint64_t TelemetryKafkaPackets_=0;
GWObjects::ConnectionState State_;
std::string RawLastStats_;
GWObjects::HealthCheck RawLastHealthcheck_;
std::string LastStats_;
GWObjects::HealthCheck LastHealthcheck_;
std::chrono::time_point<std::chrono::high_resolution_clock> ConnectionStart_ = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> ConnectionCompletionTime_{0.0};
bool Threaded_=false;
std::atomic_flag Dead_=false;
std::atomic_bool DeviceValidated_=false;
std::atomic_bool Valid_=false;
OpenWifi::GWObjects::DeviceRestrictions Restrictions_;
static inline std::atomic_uint64_t ConcurrentStartingDevices_=0;
bool StartTelemetry(uint64_t RPCID);
bool StopTelemetry(uint64_t RPCID);
bool StartTelemetry(std::uint64_t RPCID);
bool StopTelemetry(std::uint64_t RPCID);
void UpdateCounts();
};

View File

@@ -6,157 +6,130 @@
#include "AP_WS_Server.h"
#include "StorageService.h"
#include "FindCountry.h"
#include "framework/WebSocketClientNotifications.h"
#include "Daemon.h"
#include "CentralConfig.h"
#include "CommandManager.h"
#include "framework/KafkaManager.h"
#include "framework/utils.h"
#include "UI_GW_WebSocketNotifications.h"
namespace OpenWifi {
void AP_WS_Connection::Process_connect(Poco::JSON::Object::Ptr ParamsObj, const std::string &Serial) {
if (ParamsObj->has(uCentralProtocol::UUID) &&
ParamsObj->has(uCentralProtocol::FIRMWARE) &&
ParamsObj->has(uCentralProtocol::CAPABILITIES)) {
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
auto Firmware = ParamsObj->get(uCentralProtocol::FIRMWARE).toString();
auto Capabilities = ParamsObj->getObject(uCentralProtocol::CAPABILITIES);
void AP_WS_Connection::Process_connect(Poco::JSON::Object::Ptr ParamsObj, const std::string &Serial) {
if (ParamsObj->has(uCentralProtocol::UUID) &&
ParamsObj->has(uCentralProtocol::FIRMWARE) &&
ParamsObj->has(uCentralProtocol::CAPABILITIES)) {
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
auto Firmware = ParamsObj->get(uCentralProtocol::FIRMWARE).toString();
auto CapabilitiesString = ParamsObj->get(uCentralProtocol::CAPABILITIES).toString();
SerialNumber_ = Serial;
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
Config::Capabilities Caps(CapabilitiesString);
Compatible_ = Caps.Compatible();
CommandManager()->ClearQueue(SerialNumberInt_);
SerialNumber_ = Serial;
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
AP_WS_Server()->SetSessionDetails(State_.sessionId,SerialNumberInt_);
CommandManager()->ClearQueue(SerialNumberInt_);
std::lock_guard Lock(ConnectionMutex_);
Config::Capabilities Caps(Capabilities);
AP_WS_Server()->SetSessionDetails(State_.sessionId,SerialNumberInt_);
State_.UUID = UUID;
State_.Firmware = Firmware;
State_.PendingUUID = 0;
State_.Address = Utils::FormatIPv6(WS_->peerAddress().toString());
CId_ = SerialNumber_ + "@" + CId_;
Compatible_ = Caps.Compatible();
State_.UUID = UUID;
State_.Firmware = Firmware;
State_.PendingUUID = 0;
State_.Address = Utils::FormatIPv6(WS_->peerAddress().toString());
CId_ = SerialNumber_ + "@" + CId_;
auto IP = PeerAddress_.toString();
if(IP.substr(0,7)=="::ffff:") {
IP = IP.substr(7);
}
bool RestrictedDevice = false;
if(Capabilities->has("restrictions")){
RestrictedDevice = true;
Poco::JSON::Object::Ptr RestrictionObject = Capabilities->getObject("restrictions");
Restrictions_.from_json(RestrictionObject);
}
State_.locale = FindCountryFromIP()->Get(IP);
GWObjects::Device DeviceInfo;
auto DeviceExists = StorageService()->GetDevice(SerialNumber_,DeviceInfo);
if (Daemon()->AutoProvisioning() && !DeviceExists) {
StorageService()->CreateDefaultDevice(SerialNumber_, Caps, Firmware, PeerAddress_);
} else if (DeviceExists) {
StorageService()->UpdateDeviceCapabilities(SerialNumber_, Caps );
int Updated{0};
if(!Firmware.empty()) {
if(Firmware!=DeviceInfo.Firmware) {
DeviceInfo.Firmware = Firmware;
DeviceInfo.LastFWUpdate = Utils::Now();
++Updated;
GWWebSocketNotifications::SingleDeviceFirmwareChange_t Notification;
Notification.content.serialNumber = SerialNumber_;
Notification.content.newFirmware = Firmware;
GWWebSocketNotifications::DeviceFirmwareUpdated(Notification);
} else if(DeviceInfo.LastFWUpdate==0) {
DeviceInfo.LastFWUpdate = Utils::Now();
++Updated;
}
}
if(DeviceInfo.locale != State_.locale) {
DeviceInfo.locale = State_.locale;
++Updated;
}
if(Compatible_ != DeviceInfo.DeviceType) {
DeviceInfo.DeviceType = Compatible_;
++Updated;
}
if(RestrictedDevice != DeviceInfo.restrictedDevice) {
DeviceInfo.restrictedDevice = RestrictedDevice;
++Updated;
}
if(Restrictions_ != DeviceInfo.restrictionDetails) {
DeviceInfo.restrictionDetails = Restrictions_;
++Updated;
}
if(Updated) {
StorageService()->UpdateDevice(DeviceInfo);
}
uint64_t UpgradedUUID=0;
LookForUpgrade(UUID,UpgradedUUID);
State_.UUID = UpgradedUUID;
}
State_.Compatible = Compatible_;
State_.Connected = true;
ConnectionCompletionTime_ = std::chrono::high_resolution_clock::now() - ConnectionStart_;
State_.connectionCompletionTime = ConnectionCompletionTime_.count();
if(State_.VerifiedCertificate == GWObjects::VALID_CERTIFICATE) {
if (( Utils::SerialNumberMatch(CN_, SerialNumber_, (int)AP_WS_Server()->MismatchDepth())) ||
AP_WS_Server()->IsSimSerialNumber(CN_)) {
State_.VerifiedCertificate = GWObjects::VERIFIED;
poco_information(Logger_, fmt::format("CONNECT({}): Fully validated and authenticated device. Session={} ConnectionCompletion Time={}",
CId_,
State_.sessionId,
State_.connectionCompletionTime ));
} else {
State_.VerifiedCertificate = GWObjects::MISMATCH_SERIAL;
if(AP_WS_Server()->AllowSerialNumberMismatch()) {
poco_information(
Logger_, fmt::format("CONNECT({}): Serial number mismatch allowed. CN={} Serial={} Session={} ConnectionCompletion Time={}",
CId_, CN_, SerialNumber_, State_.sessionId,
State_.connectionCompletionTime));
} else {
poco_information(
Logger_, fmt::format("CONNECT({}): Serial number mismatch disallowed. Device rejected. CN={} Serial={} Session={}",
CId_, CN_, SerialNumber_, State_.sessionId));
return EndConnection();
}
}
}
GWWebSocketNotifications::SingleDevice_t Notification;
Notification.content.serialNumber = SerialNumber_;
GWWebSocketNotifications::DeviceConnected(Notification);
// std::cout << "Serial: " << SerialNumber_ << "Session: " << State_.sessionId << std::endl;
if (KafkaManager()->Enabled()) {
Poco::JSON::Stringifier Stringify;
ParamsObj->set(uCentralProtocol::CONNECTIONIP, CId_);
ParamsObj->set("locale", State_.locale );
ParamsObj->set(uCentralProtocol::TIMESTAMP, Utils::Now());
std::ostringstream OS;
Stringify.condense(ParamsObj, OS);
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_, OS.str());
}
} else {
poco_warning(Logger_,fmt::format("INVALID-PROTOCOL({}): Missing one of uuid, firmware, or capabilities", CId_));
Errors_++;
auto IP = PeerAddress_.toString();
if(IP.substr(0,7)=="::ffff:") {
IP = IP.substr(7);
}
State_.locale = FindCountryFromIP()->Get(IP);
GWObjects::Device DeviceInfo;
auto DeviceExists = StorageService()->GetDevice(SerialNumber_,DeviceInfo);
if (Daemon()->AutoProvisioning() && !DeviceExists) {
StorageService()->CreateDefaultDevice(SerialNumber_, CapabilitiesString, Firmware,
Compatible_, PeerAddress_);
} else if (DeviceExists) {
StorageService()->UpdateDeviceCapabilities(SerialNumber_, CapabilitiesString,
Compatible_);
bool Updated = false;
if(!Firmware.empty()) {
if(Firmware!=DeviceInfo.Firmware) {
DeviceInfo.Firmware = Firmware;
DeviceInfo.LastFWUpdate = OpenWifi::Now();
Updated = true;
WebSocketClientNotificationDeviceFirmwareUpdated(SerialNumber_, Firmware);
} else if(DeviceInfo.LastFWUpdate==0) {
DeviceInfo.LastFWUpdate = OpenWifi::Now();
Updated = true;
}
}
if(DeviceInfo.locale != State_.locale) {
DeviceInfo.locale = State_.locale;
Updated = true;
}
if(Compatible_ != DeviceInfo.DeviceType) {
DeviceInfo.DeviceType = Compatible_;
Updated = true;
}
if(Updated) {
StorageService()->UpdateDevice(DeviceInfo);
}
uint64_t UpgradedUUID=0;
LookForUpgrade(UUID,UpgradedUUID);
State_.UUID = UpgradedUUID;
}
State_.Compatible = Compatible_;
State_.Connected = true;
ConnectionCompletionTime_ = std::chrono::high_resolution_clock::now() - ConnectionStart_;
State_.connectionCompletionTime = ConnectionCompletionTime_.count();
if(State_.VerifiedCertificate == GWObjects::VALID_CERTIFICATE) {
if (( Utils::SerialNumberMatch(CN_, SerialNumber_, AP_WS_Server()->MismatchDepth())) ||
AP_WS_Server()->IsSimSerialNumber(CN_)) {
State_.VerifiedCertificate = GWObjects::VERIFIED;
poco_information(Logger_, fmt::format("CONNECT({}): Fully validated and authenticated device. Session={} ConnectionCompletion Time={}",
CId_,
State_.sessionId,
State_.connectionCompletionTime ));
} else {
State_.VerifiedCertificate = GWObjects::MISMATCH_SERIAL;
if(AP_WS_Server()->AllowSerialNumberMismatch()) {
poco_information(
Logger_, fmt::format("CONNECT({}): Serial number mismatch allowed. CN={} Serial={} Session={} ConnectionCompletion Time={}",
CId_, CN_, SerialNumber_, State_.sessionId,
State_.connectionCompletionTime));
} else {
poco_information(
Logger_, fmt::format("CONNECT({}): Serial number mismatch disallowed. Device rejected. CN={} Serial={} Session={} ConnectionCompletion Time={}",
CId_, CN_, SerialNumber_, State_.sessionId,
State_.connectionCompletionTime));
return EndConnection();
}
}
}
WebSocketClientNotificationDeviceConnected(SerialNumber_);
// std::cout << "Serial: " << SerialNumber_ << "Session: " << State_.sessionId << std::endl;
if (KafkaManager()->Enabled()) {
Poco::JSON::Stringifier Stringify;
ParamsObj->set(uCentralProtocol::CONNECTIONIP, CId_);
ParamsObj->set("locale", State_.locale );
ParamsObj->set(uCentralProtocol::TIMESTAMP, OpenWifi::Now());
std::ostringstream OS;
Stringify.condense(ParamsObj, OS);
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_, OS.str());
}
} else {
poco_warning(Logger_,fmt::format("INVALID-PROTOCOL({}): Missing one of uuid, firmware, or capabilities", CId_));
Errors_++;
}
}
}

View File

@@ -5,10 +5,6 @@
#include "AP_WS_Connection.h"
#include "StorageService.h"
#include "framework/utils.h"
#include "framework/ow_constants.h"
#include "fmt/format.h"
namespace OpenWifi {
void AP_WS_Connection::Process_crashlog(Poco::JSON::Object::Ptr ParamsObj) {
if (ParamsObj->has(uCentralProtocol::UUID) && ParamsObj->has(uCentralProtocol::LOGLINES)) {

View File

@@ -5,8 +5,6 @@
#include "AP_WS_Connection.h"
#include "StorageService.h"
#include "fmt/format.h"
namespace OpenWifi {
void AP_WS_Connection::Process_deviceupdate(Poco::JSON::Object::Ptr ParamsObj, std::string &Serial) {

View File

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

View File

@@ -5,9 +5,6 @@
#include "AP_WS_Connection.h"
#include "StorageService.h"
#include "framework/ow_constants.h"
#include "fmt/format.h"
namespace OpenWifi {
void AP_WS_Connection::Process_log(Poco::JSON::Object::Ptr ParamsObj) {
if (!State_.Connected) {

View File

@@ -6,11 +6,6 @@
#include "StorageService.h"
#include "CommandManager.h"
#include "framework/ow_constants.h"
#include "framework/MicroServiceFuncs.h"
#include "fmt/format.h"
#include "framework/ow_constants.h"
namespace OpenWifi {
void AP_WS_Connection::Process_recovery(Poco::JSON::Object::Ptr ParamsObj) {
if (ParamsObj->has(uCentralProtocol::SERIAL) &&
@@ -41,7 +36,7 @@ namespace OpenWifi {
if (ParamsObj->get(uCentralProtocol::REBOOT).toString() == "true") {
GWObjects::CommandDetails Cmd;
Cmd.SerialNumber = SerialNumber_;
Cmd.UUID = MicroServiceCreateUUID();
Cmd.UUID = MicroService::CreateUUID();
Cmd.SubmittedBy = uCentralProtocol::SUBMITTED_BY_SYSTEM;
Cmd.Status = uCentralProtocol::PENDING;
Cmd.Command = uCentralProtocol::REBOOT;
@@ -52,7 +47,7 @@ namespace OpenWifi {
Poco::JSON::Stringifier::stringify(Params, O);
Cmd.Details = O.str();
bool Sent;
CommandManager()->PostCommand(CommandManager()->Next_RPC_ID(), APCommands::Commands::reboot, SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
CommandManager()->PostCommand(CommandManager()->NextRPCId(),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
StorageService()->AddCommand(SerialNumber_, Cmd, Storage::CommandExecutionType::COMMAND_EXECUTED);
poco_information(Logger_, fmt::format("RECOVERY({}): Recovery mode received, need for a reboot.", CId_));
} else {

View File

@@ -4,15 +4,9 @@
#include "AP_WS_Connection.h"
#include "StorageService.h"
#include "framework/WebSocketClientNotifications.h"
#include "StateUtils.h"
#include "UI_GW_WebSocketNotifications.h"
#include "framework/KafkaManager.h"
#include "framework/utils.h"
#include "fmt/format.h"
namespace OpenWifi {
void AP_WS_Connection::Process_state(Poco::JSON::Object::Ptr ParamsObj) {
if (!State_.Connected) {
@@ -41,20 +35,18 @@ namespace OpenWifi {
uint64_t UpgradedUUID;
LookForUpgrade(UUID,UpgradedUUID);
State_.UUID = UpgradedUUID;
SetLastStats(StateStr);
LastStats_ = StateStr;
GWObjects::Statistics Stats{
.SerialNumber = SerialNumber_, .UUID = UUID, .Data = StateStr};
Stats.Recorded = Utils::Now();
Stats.Recorded = OpenWifi::Now();
StorageService()->AddStatisticsData(Stats);
if (!request_uuid.empty()) {
StorageService()->SetCommandResult(request_uuid, StateStr);
}
StateUtils::ComputeAssociations(StateObj, State_.Associations_2G,
State_.Associations_5G,
State_.Associations_6G
);
State_.Associations_5G);
if (KafkaManager()->Enabled()) {
Poco::JSON::Stringifier Stringify;
@@ -63,9 +55,10 @@ namespace OpenWifi {
KafkaManager()->PostMessage(KafkaTopics::STATE, SerialNumber_, OS.str());
}
GWWebSocketNotifications::SingleDevice_t N;
WebSocketNotification<WebNotificationSingleDevice> N;
N.content.serialNumber = SerialNumber_;
GWWebSocketNotifications::DeviceStatistics(N);
N.type = "device_statistics";
WebSocketClientServer()->SendNotification(N);
} else {
poco_warning(Logger_, fmt::format("STATE({}): Invalid request. Missing serial, uuid, or state", CId_));

View File

@@ -6,10 +6,6 @@
#include "TelemetryStream.h"
#include "CommandManager.h"
#include "framework/KafkaManager.h"
#include "framework/utils.h"
#include "fmt/format.h"
namespace OpenWifi {
void AP_WS_Connection::Process_telemetry(Poco::JSON::Object::Ptr ParamsObj) {
if (!State_.Connected) {
@@ -18,22 +14,21 @@ namespace OpenWifi {
Errors_++;
return;
}
poco_trace(Logger_,fmt::format("Telemetry data received for {}", SerialNumber_));
if (TelemetryReporting_) {
if (ParamsObj->has("data")) {
auto Payload = ParamsObj->get("data").extract<Poco::JSON::Object::Ptr>();
Payload->set("timestamp", Utils::Now());
Payload->set("timestamp", OpenWifi::Now());
std::ostringstream SS;
Payload->stringify(SS);
auto now=Utils::Now();
auto now=OpenWifi::Now();
if (TelemetryWebSocketRefCount_) {
if(now<TelemetryWebSocketTimer_) {
// std::cout << SerialNumber_ << ": Updating WebSocket telemetry" << std::endl;
TelemetryWebSocketPackets_++;
State_.websocketPackets = TelemetryWebSocketPackets_;
TelemetryStream()->NotifyEndPoint(SerialNumberInt_, SS.str());
TelemetryStream()->UpdateEndPoint(SerialNumberInt_, SS.str());
} else {
StopWebSocketTelemetry(CommandManager()->Next_RPC_ID());
StopWebSocketTelemetry(CommandManager()->NextRPCId());
}
}
if (TelemetryKafkaRefCount_) {
@@ -44,7 +39,7 @@ namespace OpenWifi {
KafkaManager()->PostMessage(KafkaTopics::DEVICE_TELEMETRY, SerialNumber_,
SS.str());
} else {
StopKafkaTelemetry(CommandManager()->Next_RPC_ID());
StopKafkaTelemetry(CommandManager()->NextRPCId());
}
}
} else {
@@ -53,7 +48,7 @@ namespace OpenWifi {
} else {
// if we are ignoring telemetry, then close it down on the device.
poco_debug(Logger_,fmt::format("TELEMETRY({}): Stopping runaway telemetry.",SerialNumber_));
StopTelemetry(CommandManager()->Next_RPC_ID());
StopTelemetry(CommandManager()->NextRPCId());
}
}
}

View File

@@ -10,8 +10,6 @@
#include "Poco/Net/SocketAcceptor.h"
#include "Poco/Environment.h"
#include "framework/utils.h"
namespace OpenWifi {
class AP_WS_ReactorThreadPool {
public:

View File

@@ -7,18 +7,14 @@
//
#include "Poco/Net/HTTPHeaderStream.h"
#include "Poco/JSON/Array.h"
#include "Poco/Net/Context.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "AP_WS_Server.h"
#include "AP_WS_Connection.h"
#include "ConfigurationCache.h"
#include "TelemetryStream.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.h"
#include "UI_GW_WebSocketNotifications.h"
#include "fmt/format.h"
#include "framework/WebSocketClientNotifications.h"
namespace OpenWifi {
@@ -44,8 +40,8 @@ namespace OpenWifi {
int AP_WS_Server::Start() {
AllowSerialNumberMismatch_ = MicroServiceConfigGetBool("openwifi.certificates.allowmismatch",true);
MismatchDepth_ = MicroServiceConfigGetInt("openwifi.certificates.mismatchdepth",2);
AllowSerialNumberMismatch_ = MicroService::instance().ConfigGetBool("openwifi.certificates.allowmismatch",true);
MismatchDepth_ = MicroService::instance().ConfigGetInt("openwifi.certificates.mismatchdepth",2);
Reactor_pool_ = std::make_unique<AP_WS_ReactorThreadPool>();
Reactor_pool_->Start();
@@ -76,11 +72,11 @@ namespace OpenWifi {
auto Context = Poco::AutoPtr<Poco::Net::Context>(new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
/* if(!Svr.KeyFilePassword().empty()) {
if(!Svr.KeyFilePassword().empty()) {
auto PassphraseHandler = Poco::SharedPtr<MyPrivateKeyPassphraseHandler>( new MyPrivateKeyPassphraseHandler(Svr.KeyFilePassword(),Logger()));
Poco::Net::SSLManager::instance().initializeServer(PassphraseHandler, nullptr,Context);
}
*/
Poco::Crypto::X509Certificate Cert(Svr.CertFile());
Poco::Crypto::X509Certificate Root(Svr.RootCA());
@@ -132,7 +128,7 @@ namespace OpenWifi {
ReactorThread_.start(Reactor_);
auto ProvString = MicroServiceConfigGetString("autoprovisioning.process","default");
auto ProvString = MicroService::instance().ConfigGetString("autoprovisioning.process","default");
if(ProvString!="default") {
auto Tokens = Poco::StringTokenizer(ProvString, ",");
for (const auto &i : Tokens) {
@@ -145,42 +141,48 @@ namespace OpenWifi {
UseDefaultConfig_ = true;
}
SimulatorId_ = MicroServiceConfigGetString("simulatorid","");
SimulatorId_ = MicroService::instance().ConfigGetString("simulatorid","");
SimulatorEnabled_ = !SimulatorId_.empty();
Utils::SetThreadName(ReactorThread_,"dev:react:head");
GarbageCollectorCallback_ = std::make_unique<Poco::TimerCallback<AP_WS_Server>>(*this,&AP_WS_Server::onGarbageCollecting);
Timer_.setStartInterval(10 * 1000);
Timer_.setPeriodicInterval(5 * 1000); // every minute
Timer_.start(*GarbageCollectorCallback_, MicroServiceTimerPool());
Timer_.start(*GarbageCollectorCallback_, MicroService::instance().TimerPool());
Running_ = true;
return 0;
}
void AP_WS_Server::onGarbageCollecting([[maybe_unused]] Poco::Timer &timer) {
std::lock_guard Lock(WSServerMutex_);
if(!Garbage_.empty()) {
std::lock_guard Lock(LocalMutex_);
if(Garbage_.size()>0) {
std::cout << "Removing " << Garbage_.size() << " old connections." << std::endl;
Garbage_.clear();
}
static uint64_t last_log = Utils::Now();
static std::uint64_t last_log = OpenWifi::Now();
NumberOfConnectedDevices_ = 0;
NumberOfConnectingDevices_ = 0;
AverageDeviceConnectionTime_ = 0;
uint64_t total_connected_time=0;
std::uint64_t total_connected_time=0;
auto now = Utils::Now();
for (const auto & connection:SerialNumbers_) {
if(connection.second.second == nullptr) {
auto now = OpenWifi::Now();
for (auto connection=SerialNumbers_.begin(); connection!=SerialNumbers_.end();) {
if(connection->second.second== nullptr) {
connection++;
continue;
}
if (connection.second.second->State_.Connected) {
if (connection->second.second->State_.Connected) {
NumberOfConnectedDevices_++;
total_connected_time += (now - connection.second.second->State_.started);
total_connected_time += (now - connection->second.second->State_.started);
connection++;
} else {
NumberOfConnectingDevices_++;
connection++;
}
}
@@ -191,12 +193,9 @@ namespace OpenWifi {
fmt::format("Active AP connections: {} Connecting: {} Average connection time: {} seconds",
NumberOfConnectedDevices_, NumberOfConnectingDevices_, AverageDeviceConnectionTime_));
}
GWWebSocketNotifications::NumberOfConnection_t Notification;
Notification.content.numberOfConnectingDevices = NumberOfConnectingDevices_;
Notification.content.numberOfDevices = NumberOfConnectedDevices_;
Notification.content.averageConnectedTime = AverageDeviceConnectionTime_;
GWWebSocketNotifications::NumberOfConnections(Notification);
WebSocketClientNotificationNumberOfConnections(NumberOfConnectedDevices_,
AverageDeviceConnectionTime_,
NumberOfConnectingDevices_);
}
void AP_WS_Server::Stop() {
@@ -214,50 +213,37 @@ namespace OpenWifi {
poco_information(Logger(),"Stopped...");
}
bool AP_WS_Server::GetStatistics(uint64_t SerialNumber, std::string &Statistics) const {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
DevicePtr->GetLastStats(Statistics);
bool AP_WS_Server::GetStatistics(std::uint64_t SerialNumber, std::string &Statistics) const {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
return false;
Statistics = Device->second.second->LastStats_;
return true;
}
bool AP_WS_Server::GetState(uint64_t SerialNumber, GWObjects::ConnectionState & State) const {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
DevicePtr->GetState(State);
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
return false;
State = Device->second.second->State_;
return true;
}
bool AP_WS_Server::GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
DevicePtr->GetLastHealthCheck(CheckData);
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
return false;
CheckData = Device->second.second->LastHealthcheck_;
return true;
}
void AP_WS_Server::SetSessionDetails(uint64_t connection_id, uint64_t SerialNumber) {
std::lock_guard Lock(WSServerMutex_);
void AP_WS_Server::SetSessionDetails(std::uint64_t connection_id, uint64_t SerialNumber) {
std::lock_guard Lock(LocalMutex_);
auto Conn = Sessions_.find(connection_id);
if(Conn == end(Sessions_))
@@ -266,19 +252,19 @@ namespace OpenWifi {
auto CurrentSerialNumber = SerialNumbers_.find(SerialNumber);
if( (CurrentSerialNumber==SerialNumbers_.end()) ||
(CurrentSerialNumber->second.first<connection_id)) {
SerialNumbers_[SerialNumber] = std::make_pair(connection_id, Conn->second);
SerialNumbers_[SerialNumber] = std::make_pair(connection_id, Conn->second.first);
return;
}
}
bool AP_WS_Server::EndSession(uint64_t session_id, uint64_t serial_number) {
std::lock_guard G(WSServerMutex_);
bool AP_WS_Server::EndSession(std::uint64_t session_id, std::uint64_t serial_number) {
std::unique_lock G(LocalMutex_);
auto Session = Sessions_.find(session_id);
if(Session==end(Sessions_))
return false;
Garbage_.push_back(Session->second);
Garbage_.push_back(Session->second.first);
auto Device = SerialNumbers_.find(serial_number);
if (Device == end(SerialNumbers_)) {
@@ -296,102 +282,64 @@ namespace OpenWifi {
return false;
}
bool AP_WS_Server::Connected(uint64_t SerialNumber, GWObjects::DeviceRestrictions & Restrictions) const {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
DevicePtr->GetRestrictions(Restrictions);
return DevicePtr->State_.Connected;
}
bool AP_WS_Server::Connected(uint64_t SerialNumber) const {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
return DevicePtr->State_.Connected;
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
return false;
return Device->second.second->State_.Connected;
}
bool AP_WS_Server::SendFrame(uint64_t SerialNumber, const std::string & Payload) const {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
return false;
try {
return DevicePtr->Send(Payload);
// std::cout << "Device connection pointer: " << (std::uint64_t) Device->second.second << std::endl;
return Device->second.second->Send(Payload);
} catch (...) {
poco_debug(Logger(),fmt::format(": SendFrame: Could not send data to device '{}'", Utils::IntToSerialNumber(SerialNumber)));
}
return false;
}
void AP_WS_Server::StopWebSocketTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
void AP_WS_Server::StopWebSocketTelemetry(std::uint64_t RPCID, uint64_t SerialNumber) {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
return;
}
DevicePtr = Device->second.second;
}
DevicePtr->StopWebSocketTelemetry(RPCID);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_) || Device->second.second==nullptr)
return;
Device->second.second->StopWebSocketTelemetry(RPCID);
}
void AP_WS_Server::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
return;
}
DevicePtr = Device->second.second;
}
DevicePtr->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime);
void AP_WS_Server::SetWebSocketTelemetryReporting(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_) || Device->second.second==nullptr)
return;
Device->second.second->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime);
}
void AP_WS_Server::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
return;
}
DevicePtr = Device->second.second;
}
DevicePtr->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime);
void AP_WS_Server::SetKafkaTelemetryReporting(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
return;
Device->second.second->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime);
}
void AP_WS_Server::StopKafkaTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
return;
}
DevicePtr = Device->second.second;
}
DevicePtr->StopKafkaTelemetry(RPCID);
void AP_WS_Server::StopKafkaTelemetry(std::uint64_t RPCID, uint64_t SerialNumber) {
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
return;
Device->second.second->StopKafkaTelemetry(RPCID);
}
void AP_WS_Server::GetTelemetryParameters(uint64_t SerialNumber , bool & TelemetryRunning,
@@ -402,34 +350,29 @@ namespace OpenWifi {
uint64_t & TelemetryKafkaCount,
uint64_t & TelemetryWebSocketPackets,
uint64_t & TelemetryKafkaPackets) {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
return;
}
DevicePtr = Device->second.second;
}
DevicePtr->GetTelemetryParameters(
TelemetryRunning, TelemetryInterval, TelemetryWebSocketTimer, TelemetryKafkaTimer,
TelemetryWebSocketCount, TelemetryKafkaCount, TelemetryWebSocketPackets,
TelemetryKafkaPackets);
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_)|| Device->second.second== nullptr)
return;
Device->second.second->GetTelemetryParameters(TelemetryRunning,
TelemetryInterval,
TelemetryWebSocketTimer,
TelemetryKafkaTimer,
TelemetryWebSocketCount,
TelemetryKafkaCount,
TelemetryWebSocketPackets,
TelemetryKafkaPackets);
}
bool AP_WS_Server::SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
return false;
try {
return DevicePtr->SendRadiusAccountingData(buffer,size);
return Device->second.second->SendRadiusAccountingData(buffer,size);
} catch (...) {
poco_debug(Logger(),fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'", SerialNumber));
}
@@ -437,18 +380,13 @@ namespace OpenWifi {
}
bool AP_WS_Server::SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
return false;
try {
return DevicePtr->SendRadiusAuthenticationData(buffer,size);
return Device->second.second->SendRadiusAuthenticationData(buffer,size);
} catch (...) {
poco_debug(Logger(),fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'", SerialNumber));
}
@@ -456,18 +394,13 @@ namespace OpenWifi {
}
bool AP_WS_Server::SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
return false;
}
DevicePtr = Device->second.second;
}
std::lock_guard Lock(LocalMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
return false;
try {
return DevicePtr->SendRadiusCoAData(buffer,size);
return Device->second.second->SendRadiusCoAData(buffer,size);
} catch (...) {
poco_debug(Logger(),fmt::format(": SendRadiusCoAData: Could not send data to device '{}'", SerialNumber));
}

View File

@@ -13,27 +13,22 @@
#include <array>
#include <ctime>
#include "framework/MicroService.h"
#include "Poco/AutoPtr.h"
#include "Poco/Net/SocketReactor.h"
#include "Poco/Net/ParallelSocketAcceptor.h"
#include "Poco/Net/SocketAcceptor.h"
#include "Poco/Timer.h"
#include "Poco/Net/HTTPRequestHandler.h"
#include "Poco/Net/HTTPRequestHandlerFactory.h"
#include "Poco/Net/HTTPServer.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "AP_WS_Connection.h"
#include "AP_WS_ReactorPool.h"
#include "framework/utils.h"
#include "framework/SubSystemServer.h"
namespace OpenWifi {
class AP_WS_RequestHandler : public Poco::Net::HTTPRequestHandler {
public:
explicit AP_WS_RequestHandler(Poco::Logger &L, uint64_t id)
explicit AP_WS_RequestHandler(Poco::Logger &L, std::uint64_t id)
: Logger_(L),
id_(id){
};
@@ -42,7 +37,7 @@ namespace OpenWifi {
Poco::Net::HTTPServerResponse &response) override;
private:
Poco::Logger &Logger_;
uint64_t id_=0;
std::uint64_t id_=0;
};
class AP_WS_RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
@@ -63,7 +58,7 @@ namespace OpenWifi {
}
private:
Poco::Logger &Logger_;
inline static uint64_t id_=1;
inline static std::uint64_t id_=1;
};
class AP_WS_Server : public SubSystemServer {
@@ -95,7 +90,7 @@ namespace OpenWifi {
return AllowSerialNumberMismatch_;
}
inline uint64_t MismatchDepth() const {
inline std::uint64_t MismatchDepth() const {
return MismatchDepth_;
}
@@ -105,55 +100,54 @@ namespace OpenWifi {
[[nodiscard]] inline Poco::Net::SocketReactor & NextReactor() { return Reactor_pool_->NextReactor(); }
[[nodiscard]] inline bool Running() const { return Running_; }
inline void AddConnection(uint64_t session_id, std::shared_ptr<AP_WS_Connection> Connection ) {
std::lock_guard Lock(WSServerMutex_);
Sessions_[session_id] = std::move(Connection);
inline void AddConnection(std::uint64_t session_id, std::shared_ptr<AP_WS_Connection> Connection ) {
std::lock_guard Lock(LocalMutex_);
Sessions_[session_id] = std::make_pair(std::move(Connection),false);
}
inline std::shared_ptr<AP_WS_Connection> FindConnection(uint64_t session_id) const {
std::lock_guard Lock(WSServerMutex_);
inline std::shared_ptr<AP_WS_Connection> FindConnection(std::uint64_t session_id) const {
std::lock_guard Lock(LocalMutex_);
auto Connection = Sessions_.find(session_id);
if(Connection!=end(Sessions_))
return Connection->second;
return Connection->second.first;
return nullptr;
}
inline bool GetStatistics(const std::string &SerialNumber, std::string & Statistics) const {
return GetStatistics(Utils::SerialNumberToInt(SerialNumber),Statistics);
}
bool GetStatistics(uint64_t SerialNumber, std::string & Statistics) const ;
bool GetStatistics(std::uint64_t SerialNumber, std::string & Statistics) const ;
inline bool GetState(const std::string & SerialNumber, GWObjects::ConnectionState & State) const {
return GetState(Utils::SerialNumberToInt(SerialNumber), State);
}
bool GetState(uint64_t SerialNumber, GWObjects::ConnectionState & State) const;
bool GetState(std::uint64_t SerialNumber, GWObjects::ConnectionState & State) const;
inline bool GetHealthcheck(const std::string &SerialNumber, GWObjects::HealthCheck & CheckData) const {
return GetHealthcheck(Utils::SerialNumberToInt(SerialNumber), CheckData);
}
bool GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const ;
bool GetHealthcheck(std::uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const ;
bool Connected(uint64_t SerialNumber, GWObjects::DeviceRestrictions & Restrictions) const ;
bool Connected(uint64_t SerialNumber) const ;
inline bool SendFrame(const std::string & SerialNumber, const std::string & Payload) const {
return SendFrame(Utils::SerialNumberToInt(SerialNumber), Payload);
}
bool SendFrame(uint64_t SerialNumber, const std::string & Payload) const ;
bool SendFrame(std::uint64_t SerialNumber, const std::string & Payload) const ;
bool SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
bool SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
bool SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
void SetSessionDetails(uint64_t connection_id, uint64_t SerialNumber);
bool EndSession(uint64_t connection_id, uint64_t serial_number);
void SetSessionDetails(std::uint64_t connection_id, uint64_t SerialNumber);
bool EndSession(std::uint64_t connection_id, std::uint64_t serial_number);
void SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime);
void StopWebSocketTelemetry(uint64_t RPCID, uint64_t SerialNumber);
void SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime);
void StopKafkaTelemetry(uint64_t RPCID, uint64_t SerialNumber);
void SetWebSocketTelemetryReporting(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime);
void StopWebSocketTelemetry(std::uint64_t RPCID, uint64_t SerialNumber);
void SetKafkaTelemetryReporting(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime);
void StopKafkaTelemetry(std::uint64_t RPCID, uint64_t SerialNumber);
void GetTelemetryParameters(uint64_t SerialNumber , bool & TelemetryRunning,
uint64_t & TelemetryInterval,
uint64_t & TelemetryWebSocketTimer,
@@ -165,14 +159,14 @@ namespace OpenWifi {
void onGarbageCollecting(Poco::Timer & timer);
inline void AverageDeviceStatistics( uint64_t & Connections, uint64_t & AverageConnectionTime, uint64_t & NumberOfConnectingDevices) const {
inline void AverageDeviceStatistics( std::uint64_t & Connections, std::uint64_t & AverageConnectionTime, std::uint64_t & NumberOfConnectingDevices) const {
Connections = NumberOfConnectedDevices_;
AverageConnectionTime = AverageDeviceConnectionTime_;
NumberOfConnectingDevices = NumberOfConnectingDevices_;
}
private:
mutable std::recursive_mutex WSServerMutex_;
mutable std::recursive_mutex LocalMutex_;
std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_;
std::list<std::unique_ptr<Poco::Net::HTTPServer>> WebServers_;
Poco::Net::SocketReactor Reactor_;
@@ -184,9 +178,8 @@ namespace OpenWifi {
bool SimulatorEnabled_=false;
std::unique_ptr<AP_WS_ReactorThreadPool> Reactor_pool_;
std::atomic_bool Running_=false;
// std::map<uint64_t, std::pair<std::shared_ptr<AP_WS_Connection>,bool>> Sessions_;
std::map<std::uint64_t, std::shared_ptr<AP_WS_Connection>> Sessions_;
std::map<uint64_t, std::pair<uint64_t,std::shared_ptr<AP_WS_Connection>>> SerialNumbers_;
std::map<std::uint64_t, std::pair<std::shared_ptr<AP_WS_Connection>,bool>> Sessions_;
std::map<std::uint64_t, std::pair<std::uint64_t,std::shared_ptr<AP_WS_Connection>>> SerialNumbers_;
std::atomic_bool AllowSerialNumberMismatch_=true;
std::atomic_uint64_t MismatchDepth_=2;

View File

@@ -4,15 +4,9 @@
#pragma once
#include <string>
#include <map>
#include <mutex>
#include <fstream>
#include "framework/MicroServiceFuncs.h"
#include "framework/MicroService.h"
#include "nlohmann/json.hpp"
#include "CentralConfig.h"
namespace OpenWifi {
const std::string PlatformCacheFileName{"/plat_cache.json"};
@@ -28,17 +22,17 @@ namespace OpenWifi {
return instance;
}
inline void Add(const Config::Capabilities &Caps) {
if(Caps.Compatible().empty() || Caps.Platform().empty())
inline void Add(const std::string & DeviceType, const std::string & Platform, const std::string & FullCapabilities) {
if(DeviceType.empty() || Platform.empty())
return;
std::lock_guard G(Mutex_);
if(!PlatformsLoaded_)
LoadPlatforms();
auto P = Poco::toUpper(Caps.Platform());
auto Hint = Platforms_.find(Caps.Compatible());
auto P = Poco::toUpper(Platform);
auto Hint = Platforms_.find(DeviceType);
if(Hint==Platforms_.end()) {
Platforms_.insert(std::make_pair(Caps.Compatible(),P));
Platforms_.insert(std::make_pair(DeviceType,P));
SavePlatforms();
} else if(Hint->second != P) {
Hint->second = P;
@@ -48,14 +42,12 @@ namespace OpenWifi {
if(!CapabilitiesLoaded_)
LoadCapabilities();
auto CapHint = Capabilities_.find(Caps.Compatible());
auto CapHint = Capabilities_.find(DeviceType);
if(CapHint==Capabilities_.end()) {
auto C = nlohmann::json::parse(Caps.AsString());
C.erase("restrictions");
Capabilities_[Caps.Compatible()] = nlohmann::json::parse(Caps.AsString());
Capabilities_[DeviceType] = nlohmann::json::parse(FullCapabilities);
SaveCapabilities();
} else {
CapHint->second = nlohmann::json::parse(Caps.AsString());
CapHint->second = nlohmann::json::parse(FullCapabilities);
SaveCapabilities();
}
}
@@ -100,8 +92,8 @@ namespace OpenWifi {
std::atomic_bool CapabilitiesLoaded_=false;
std::map<std::string,std::string> Platforms_;
CapabilitiesCache_t Capabilities_;
std::string PlatformCacheFileName_{ MicroServiceDataDirectory()+PlatformCacheFileName };
std::string CapabilitiesCacheFileName_{ MicroServiceDataDirectory()+CapabilitiesCacheFileName };
std::string PlatformCacheFileName_{ MicroService::instance().DataDir()+PlatformCacheFileName };
std::string CapabilitiesCacheFileName_{ MicroService::instance().DataDir()+CapabilitiesCacheFileName };
inline void LoadPlatforms() {
try {
@@ -153,7 +145,4 @@ namespace OpenWifi {
}
}
};
inline auto CapabilitiesCache() { return CapabilitiesCache::instance(); };
}

View File

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

View File

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

View File

@@ -8,16 +8,14 @@
#include <algorithm>
#include "framework/MicroService.h"
#include "Poco/JSON/Parser.h"
#include "CommandManager.h"
#include "AP_WS_Server.h"
#include "StorageService.h"
#include "framework/ow_constants.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.h"
using namespace std::chrono_literals;
namespace OpenWifi {
@@ -31,87 +29,39 @@ namespace OpenWifi {
try {
if (Resp != nullptr) {
Poco::JSON::Object::Ptr Payload = Resp->Payload_;
std::string SerialNumberStr = Utils::IntToSerialNumber(Resp->SerialNumber_);
const Poco::JSON::Object &Payload = Resp->Payload_;
const std::string &SerialNumber = Resp->SerialNumber_;
bool NoReply = false;
std::ostringstream SS;
Payload.stringify(SS);
if (!Payload->has(uCentralProtocol::ID)) {
poco_error(Logger(), fmt::format("({}): Invalid RPC response.", SerialNumberStr));
if (!Payload.has(uCentralProtocol::ID)) {
poco_error(Logger(), fmt::format("({}): Invalid RPC response.", SerialNumber));
} else {
uint64_t ID = Payload->get(uCentralProtocol::ID);
std::shared_ptr<promise_type_t> TmpRpcEntry;
poco_debug(Logger(),fmt::format("({}): Processing {} response.", SerialNumberStr, ID));
uint64_t ID = Payload.get(uCentralProtocol::ID);
poco_debug(Logger(),fmt::format("({}): Processing {} response.", SerialNumber, ID));
if (ID > 1) {
std::lock_guard Lock(LocalMutex_);
auto RPC = OutStandingRequests_.find(ID);
if (RPC == OutStandingRequests_.end() ||
RPC->second.SerialNumber != Resp->SerialNumber_) {
RPC->second.SerialNumber !=
Utils::SerialNumberToInt(Resp->SerialNumber_)) {
poco_debug(Logger(),
fmt::format("({}): RPC {} completed.", SerialNumberStr, ID));
fmt::format("({}): RPC {} completed.", SerialNumber, ID));
} else {
std::chrono::duration<double, std::milli> rpc_execution_time =
std::chrono::high_resolution_clock::now() -
RPC->second.submitted;
StorageService()->CommandCompleted(RPC->second.UUID, Payload,
rpc_execution_time, true);
if (RPC->second.rpc_entry) {
RPC->second.rpc_entry->set_value(Payload);
}
poco_debug(Logger(),
fmt::format("({}): Received RPC answer {}. Command={}",
SerialNumberStr, ID, APCommands::to_string(RPC->second.Command)));
if(RPC->second.Command==APCommands::Commands::script) {
if(RPC->second.State==2) {
// look at the payload to see if we should continue or not...
if (RPC->second.rpc_entry) {
TmpRpcEntry = RPC->second.rpc_entry;
}
// Payload->stringify(std::cout);
if (Payload->has("result")) {
auto Result = Payload->getObject("result");
if (Result->has("status")) {
auto Status = Result->getObject("status");
// Status->stringify(std::cout);
std::uint64_t Error = Status->get("error");
if(Error==0) {
StorageService()->CommandCompleted(RPC->second.UUID, Payload,
rpc_execution_time, true);
RPC->second.State = 1 ;
} else {
StorageService()->CommandCompleted(RPC->second.UUID, Payload,
rpc_execution_time, true);
std::string ErrorTxt = Status->get("result");
StorageService()->CancelWaitFile(RPC->second.UUID, ErrorTxt);
RPC->second.State = 0 ;
}
}
} else {
// std::cout << "Bad payload on command result" << std::endl;
RPC->second.State=0;
}
} else {
// std::cout << "Completing script 2 phase commit." << std::endl;
StorageService()->CommandCompleted(RPC->second.UUID, Payload,
rpc_execution_time, true);
NoReply = true;
RPC->second.State=0;
}
} else {
if(RPC->second.Command!=APCommands::Commands::telemetry) {
StorageService()->CommandCompleted(
RPC->second.UUID, Payload, rpc_execution_time, true);
}
if (RPC->second.rpc_entry) {
TmpRpcEntry = RPC->second.rpc_entry;
}
RPC->second.State = 0 ;
}
if(RPC->second.State==0) {
OutStandingRequests_.erase(ID);
}
SerialNumber, ID, RPC->second.Command));
OutStandingRequests_.erase(ID);
}
if(!NoReply && TmpRpcEntry != nullptr)
TmpRpcEntry->set_value(Payload);
}
}
}
@@ -133,12 +83,12 @@ namespace OpenWifi {
JanitorCallback_ = std::make_unique<Poco::TimerCallback<CommandManager>>(*this,&CommandManager::onJanitorTimer);
JanitorTimer_.setStartInterval( 10000 );
JanitorTimer_.setPeriodicInterval(10 * 60 * 1000); // 1 hours
JanitorTimer_.start(*JanitorCallback_, MicroServiceTimerPool());
JanitorTimer_.start(*JanitorCallback_, MicroService::instance().TimerPool());
CommandRunnerCallback_ = std::make_unique<Poco::TimerCallback<CommandManager>>(*this,&CommandManager::onCommandRunnerTimer);
CommandRunnerTimer_.setStartInterval( 10000 );
CommandRunnerTimer_.setPeriodicInterval(30 * 1000); // 1 hours
CommandRunnerTimer_.start(*CommandRunnerCallback_, MicroServiceTimerPool());
CommandRunnerTimer_.start(*CommandRunnerCallback_, MicroService::instance().TimerPool());
return 0;
}
@@ -169,7 +119,7 @@ namespace OpenWifi {
if(delta > 10min) {
MyLogger.debug(fmt::format("{}: Command={} for {} Timed out.",
request->second.UUID,
APCommands::to_string(request->second.Command),
request->second.Command,
Utils::IntToSerialNumber(request->second.SerialNumber)));
request = OutStandingRequests_.erase(request);
} else {
@@ -218,7 +168,7 @@ namespace OpenWifi {
if(IsCommandRunning(Cmd.UUID))
continue;
auto now = Utils::Now();
auto now = OpenWifi::Now();
// 2 hour timeout for commands
if ((now - Cmd.Submitted) > (1 * 60 * 60)) {
poco_information(
@@ -238,15 +188,14 @@ namespace OpenWifi {
continue;
}
std::string ExecutingUUID;
APCommands::Commands ExecutingCommand=APCommands::Commands::unknown;
std::string ExecutingCommand, ExecutingUUID;
if (CommandRunningForDevice(Utils::SerialNumberToInt(Cmd.SerialNumber),
ExecutingUUID, ExecutingCommand)) {
poco_trace(
MyLogger,
fmt::format(
"{}: Serial={} Command={} Device is already busy with command {} (Command={})."
, Cmd.UUID, Cmd.SerialNumber, Cmd.Command, ExecutingUUID, APCommands::to_string(ExecutingCommand)));
, Cmd.UUID, Cmd.SerialNumber, Cmd.Command,ExecutingUUID, ExecutingCommand));
continue;
}
@@ -255,7 +204,7 @@ namespace OpenWifi {
poco_information(MyLogger, fmt::format("{}: Serial={} Command={} Preparing execution.",
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
auto Params = P.parse(Cmd.Details).extract<Poco::JSON::Object::Ptr>();
auto Result = PostCommandDisk(Next_RPC_ID(), APCommands::to_apcommand(Cmd.Command.c_str()), Cmd.SerialNumber, Cmd.Command,
auto Result = PostCommandDisk(NextRPCId(), Cmd.SerialNumber, Cmd.Command,
*Params, Cmd.UUID, Sent);
if (Sent) {
StorageService()->SetCommandExecuted(Cmd.UUID);
@@ -290,10 +239,9 @@ namespace OpenWifi {
}
std::shared_ptr<CommandManager::promise_type_t> CommandManager::PostCommand(
uint64_t RPC_ID,
APCommands::Commands Command,
uint64_t RPCID,
const std::string &SerialNumber,
const std::string &CommandStr,
const std::string &Command,
const Poco::JSON::Object &Params,
const std::string &UUID,
bool oneway_rpc,
@@ -306,33 +254,31 @@ namespace OpenWifi {
std::stringstream ToSend;
CommandInfo Idx;
Idx.Id = oneway_rpc ? 1 : RPC_ID;
Idx.Id = oneway_rpc ? 1 : RPCID;
Idx.SerialNumber = SerialNumberInt;
Idx.Command = Command;
if(Command == APCommands::Commands::script)
Idx.State=2;
Idx.UUID = UUID;
Poco::JSON::Object CompleteRPC;
CompleteRPC.set(uCentralProtocol::JSONRPC, uCentralProtocol::JSONRPC_VERSION);
CompleteRPC.set(uCentralProtocol::ID, RPC_ID);
CompleteRPC.set(uCentralProtocol::METHOD, CommandStr);
CompleteRPC.set(uCentralProtocol::ID, RPCID);
CompleteRPC.set(uCentralProtocol::METHOD, Command);
CompleteRPC.set(uCentralProtocol::PARAMS, Params);
Poco::JSON::Stringifier::stringify(CompleteRPC, ToSend);
Idx.rpc_entry = disk_only ? nullptr : std::make_shared<CommandManager::promise_type_t>();
poco_debug(Logger(), fmt::format("{}: Sending command {} to {}. ID: {}", UUID, CommandStr, SerialNumber, RPC_ID));
poco_debug(Logger(), fmt::format("{}: Sending command. ID: {}", UUID, RPCID));
if(AP_WS_Server()->SendFrame(SerialNumber, ToSend.str())) {
if(!oneway_rpc) {
std::lock_guard M(Mutex_);
OutStandingRequests_[RPC_ID] = Idx;
OutStandingRequests_[RPCID] = Idx;
}
poco_debug(Logger(), fmt::format("{}: Sent command. ID: {}", UUID, RPC_ID));
poco_debug(Logger(), fmt::format("{}: Sent command. ID: {}", UUID, RPCID));
Sent=true;
return Idx.rpc_entry;
}
poco_warning(Logger(), fmt::format("{}: Failed to send command. ID: {}", UUID, RPC_ID));
poco_warning(Logger(), fmt::format("{}: Failed to send command. ID: {}", UUID, RPCID));
return nullptr;
}
} // namespace

View File

@@ -15,15 +15,12 @@
#include <functional>
#include <shared_mutex>
#include "framework/MicroService.h"
#include "Poco/JSON/Object.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "Poco/Timer.h"
#include "Poco/Notification.h"
#include "Poco/NotificationQueue.h"
#include "framework/SubSystemServer.h"
#include "fmt/format.h"
#include "RESTObjects/RESTAPI_GWobjects.h"
@@ -31,61 +28,58 @@ namespace OpenWifi {
class RPCResponseNotification: public Poco::Notification {
public:
RPCResponseNotification(std::uint64_t ser,
Poco::JSON::Object::Ptr pl) :
RPCResponseNotification(const std::string &ser,
const Poco::JSON::Object &pl) :
SerialNumber_(ser),
Payload_(std::move(pl))
Payload_(pl)
{
}
std::uint64_t SerialNumber_;
Poco::JSON::Object::Ptr Payload_;
std::string SerialNumber_;
Poco::JSON::Object Payload_;
};
class CommandManager : public SubSystemServer, Poco::Runnable {
public:
using objtype_t = Poco::JSON::Object::Ptr;
using promise_type_t = std::promise<objtype_t>;
typedef Poco::JSON::Object objtype_t;
typedef std::promise<objtype_t> promise_type_t;
struct CommandInfo {
std::uint64_t Id=0;
std::uint64_t SerialNumber=0;
APCommands::Commands Command;
std::string UUID;
std::uint64_t State=1;
std::uint64_t Id=0;
std::uint64_t SerialNumber=0;
std::string Command;
std::string UUID;
std::chrono::time_point<std::chrono::high_resolution_clock> submitted = std::chrono::high_resolution_clock::now();
std::shared_ptr<promise_type_t> rpc_entry;
};
struct RPCResponse {
std::uint64_t serialNumber;
Poco::JSON::Object::Ptr payload;
std::string serialNumber;
Poco::JSON::Object payload;
explicit RPCResponse(std::uint64_t ser, Poco::JSON::Object::Ptr pl)
explicit RPCResponse(const std::string &ser, const Poco::JSON::Object &pl)
:
serialNumber(ser),
payload(std::move(pl)) {
payload(pl) {
}
};
int Start() override;
void Stop() override;
void WakeUp();
inline void PostCommandResult(const std::string &SerialNumber, Poco::JSON::Object::Ptr Obj) {
ResponseQueue_.enqueueNotification(new RPCResponseNotification(Utils::SerialNumberToInt(SerialNumber),std::move(Obj)));
inline void PostCommandResult(const std::string &SerialNumber, const Poco::JSON::Object &Obj) {
// RPCResponseQueue_->Write(RPCResponse{.serialNumber=SerialNumber, .payload = Obj});
ResponseQueue_.enqueueNotification(new RPCResponseNotification(SerialNumber,Obj));
}
std::shared_ptr<promise_type_t> PostCommandOneWayDisk(uint64_t RPC_ID,
APCommands::Commands Command,
std::shared_ptr<promise_type_t> PostCommandOneWayDisk(uint64_t RPCID,
const std::string &SerialNumber,
const std::string &Method,
const Poco::JSON::Object &Params,
const std::string &UUID,
bool & Sent) {
return PostCommand(RPC_ID,
Command,
SerialNumber,
return PostCommand(RPCID, SerialNumber,
Method,
Params,
UUID,
@@ -93,15 +87,13 @@ namespace OpenWifi {
}
std::shared_ptr<promise_type_t> PostCommandDisk(
uint64_t RPC_ID,
APCommands::Commands Command,
uint64_t RPCID,
const std::string &SerialNumber,
const std::string &Method,
const Poco::JSON::Object &Params,
const std::string &UUID,
bool & Sent) {
return PostCommand(RPC_ID,
Command,
return PostCommand(RPCID,
SerialNumber,
Method,
Params,
@@ -110,16 +102,13 @@ namespace OpenWifi {
}
std::shared_ptr<promise_type_t> PostCommand(
uint64_t RPC_ID,
APCommands::Commands Command,
uint64_t RPCID,
const std::string &SerialNumber,
const std::string &Method,
const Poco::JSON::Object &Params,
const std::string &UUID,
bool & Sent) {
return PostCommand(RPC_ID,
Command,
SerialNumber,
return PostCommand(RPCID, SerialNumber,
Method,
Params,
UUID,
@@ -128,15 +117,13 @@ namespace OpenWifi {
}
std::shared_ptr<promise_type_t> PostCommandOneWay(
uint64_t RPC_ID,
APCommands::Commands Command,
uint64_t RPCID,
const std::string &SerialNumber,
const std::string &Method,
const Poco::JSON::Object &Params,
const std::string &UUID,
bool & Sent) {
return PostCommand(RPC_ID,
Command,
return PostCommand(RPCID,
SerialNumber,
Method,
Params,
@@ -157,14 +144,15 @@ namespace OpenWifi {
inline bool Running() const { return Running_; }
void onJanitorTimer(Poco::Timer & timer);
void onCommandRunnerTimer(Poco::Timer & timer);
inline uint64_t Next_RPC_ID() { return ++Id_; }
void onRPCAnswer(bool& b);
inline uint64_t NextRPCId() { return ++Id_; }
void RemovePendingCommand(std::uint64_t Id) {
std::unique_lock Lock(LocalMutex_);
OutStandingRequests_.erase(Id);
}
inline bool CommandRunningForDevice(std::uint64_t SerialNumber, std::string & uuid, APCommands::Commands &command) {
inline bool CommandRunningForDevice(std::uint64_t SerialNumber, std::string & uuid, std::string &command) {
std::lock_guard Lock(LocalMutex_);
for(const auto &[Request,Command]:OutStandingRequests_) {
@@ -201,7 +189,6 @@ namespace OpenWifi {
std::shared_ptr<promise_type_t> PostCommand(
uint64_t RPCID,
APCommands::Commands Command,
const std::string &SerialNumber,
const std::string &Method,
const Poco::JSON::Object &Params,

View File

@@ -7,6 +7,7 @@
#include <map>
#include <string>
#include <mutex>
#include "framework/MicroService.h"
namespace OpenWifi {
class ConfigurationCache {

View File

@@ -6,6 +6,8 @@
// Arilia Wireless Inc.
//
#include "framework/MicroService.h"
#include "Poco/Util/Application.h"
#include "Poco/Util/Option.h"
#include "Poco/Environment.h"
@@ -26,10 +28,6 @@
#include "VenueBroadcaster.h"
#include "framework/ConfigurationValidator.h"
#include "rttys/RTTYS_server.h"
#include "framework/UI_WebSocketClientServer.h"
#include "UI_GW_WebSocketNotifications.h"
#include "ScriptManager.h"
#include "SignatureMgr.h"
namespace OpenWifi {
class Daemon *Daemon::instance() {
@@ -42,9 +40,10 @@ namespace OpenWifi {
StorageService(),
SerialNumberCache(),
ConfigurationValidator(),
UI_WebSocketClientServer(),
WebSocketClientServer(),
OUIServer(),
FindCountryFromIP(),
// DeviceRegistry(),
CommandManager(),
FileUploader(),
StorageArchiver(),
@@ -52,8 +51,6 @@ namespace OpenWifi {
RTTYS_server(),
RADIUS_proxy_server(),
VenueBroadcaster(),
ScriptManager(),
SignatureManager(),
AP_WS_Server()
});
return &instance;
@@ -107,11 +104,6 @@ namespace OpenWifi {
}
return "AP";
}
void DaemonPostInitialization(Poco::Util::Application &self) {
Daemon()->PostInitialization(self);
GWWebSocketNotifications::Register();
}
}
int main(int argc, char **argv) {

View File

@@ -14,9 +14,18 @@
#include <vector>
#include <set>
#include "framework/MicroServiceNames.h"
#include "framework/MicroService.h"
#include "Poco/Util/Application.h"
#include "Poco/Util/ServerApplication.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/UUIDGenerator.h"
#include "Poco/ErrorHandler.h"
#include "Poco/Crypto/RSAKey.h"
#include "Poco/Crypto/CipherFactory.h"
#include "Poco/Crypto/Cipher.h"
#include "Dashboard.h"
#include "framework/OpenWifiTypes.h"
#include "GwWebSocketClient.h"
@@ -53,6 +62,8 @@ namespace OpenWifi {
};
inline Daemon * Daemon() { return Daemon::instance(); }
void DaemonPostInitialization(Poco::Util::Application &self);
inline void DaemonPostInitialization(Poco::Util::Application &self) {
Daemon()->PostInitialization(self);
}
}

View File

@@ -4,48 +4,16 @@
#include "Dashboard.h"
#include "StorageService.h"
#include "framework/utils.h"
namespace OpenWifi {
void DeviceDashboard::Create() {
uint64_t Now = OpenWifi::Now();
bool DeviceDashboard::Get(GWObjects::Dashboard &D, Poco::Logger & Logger) {
uint64_t Now = Utils::Now();
if(!ValidDashboard_ || LastRun_==0 || (Now-LastRun_)>120) {
Generate(D, Logger);
} else {
std::lock_guard G(DataMutex_);
D = DB_;
}
return ValidDashboard_;
};
void DeviceDashboard::Generate(GWObjects::Dashboard &D, Poco::Logger & Logger ) {
if (GeneratingDashboard_.load()) {
// std::cout << "Trying to generate dashboard but already being generated" << std::endl;
while(GeneratingDashboard_.load()) {
Poco::Thread::trySleep(100);
}
std::lock_guard G(DataMutex_);
D = DB_;
} else {
GeneratingDashboard_ = true;
ValidDashboard_ = false;
try {
// std::cout << "Generating dashboard." << std::endl;
poco_information(Logger, "DASHBOARD: Generating a new dashboard.");
GWObjects::Dashboard NewData;
StorageService()->AnalyzeCommands(NewData.commands);
StorageService()->AnalyzeDevices(NewData);
LastRun_ = Utils::Now();
NewData.snapshot = LastRun_;
D = NewData;
std::lock_guard G(DataMutex_);
DB_ = NewData;
ValidDashboard_=true;
} catch(...) {
}
GeneratingDashboard_ = false;
if(LastRun_==0 || (Now-LastRun_)>120) {
DB_.reset();
StorageService()->AnalyzeCommands(DB_.commands);
StorageService()->AnalyzeDevices(DB_);
LastRun_ = Now;
}
}
}

View File

@@ -4,24 +4,19 @@
#pragma once
#include <mutex>
#include "RESTObjects//RESTAPI_GWobjects.h"
#include "framework/OpenWifiTypes.h"
#include "Poco/Logger.h"
namespace OpenWifi {
class DeviceDashboard {
public:
bool Get(GWObjects::Dashboard &D, Poco::Logger & Logger);
DeviceDashboard() { DB_.reset(); }
void Create();
[[nodiscard]] const GWObjects::Dashboard & Report() const { return DB_;}
private:
std::mutex DataMutex_;
volatile std::atomic_bool GeneratingDashboard_=false;
volatile bool ValidDashboard_=false;
GWObjects::Dashboard DB_;
uint64_t LastRun_=0;
void Generate(GWObjects::Dashboard &D, Poco::Logger & Logger);
GWObjects::Dashboard DB_;
uint64_t LastRun_=0;
inline void Reset() { DB_.reset(); }
};
}

264
src/DeviceRegistry.cpp Normal file
View File

@@ -0,0 +1,264 @@
//
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#include "Poco/JSON/Object.h"
#include "AP_WS_Server.h"
#include "DeviceRegistry.h"
#include "CommandManager.h"
#include "framework/WebSocketClientNotifications.h"
namespace OpenWifi {
int DeviceRegistry::Start() {
std::lock_guard Guard(Mutex_);
poco_notice(Logger(),"Starting");
ArchiverCallback_ = std::make_unique<Poco::TimerCallback<DeviceRegistry>>(*this,&DeviceRegistry::onConnectionJanitor);
Timer_.setStartInterval(60 * 1000);
Timer_.setPeriodicInterval(20 * 1000); // every minute
Timer_.start(*ArchiverCallback_, MicroService::instance().TimerPool());
return 0;
}
void DeviceRegistry::Stop() {
poco_notice(Logger(),"Stopping...");
std::lock_guard Guard(Mutex_);
Timer_.stop();
poco_notice(Logger(),"Stopped...");
}
void DeviceRegistry::onConnectionJanitor([[maybe_unused]] Poco::Timer &timer) {
static std::uint64_t last_log = OpenWifi::Now();
std::shared_lock Guard(LocalMutex_);
NumberOfConnectedDevices_ = 0;
NumberOfConnectingDevices_ = 0;
AverageDeviceConnectionTime_ = 0;
std::uint64_t total_connected_time=0;
auto now = OpenWifi::Now();
for (auto connection=SerialNumbers_.begin(); connection!=SerialNumbers_.end();) {
if(connection->second.second== nullptr) {
connection++;
continue;
}
if (connection->second.second->State_.Connected) {
NumberOfConnectedDevices_++;
total_connected_time += (now - connection->second.second->State_.started);
connection++;
} else {
NumberOfConnectingDevices_++;
connection++;
}
}
AverageDeviceConnectionTime_ = (NumberOfConnectedDevices_!=0) ? total_connected_time/NumberOfConnectedDevices_ : 0;
if((now-last_log)>120) {
last_log = now;
poco_information(Logger(),
fmt::format("Active AP connections: {} Connecting: {} Average connection time: {} seconds",
NumberOfConnectedDevices_, NumberOfConnectingDevices_, AverageDeviceConnectionTime_));
}
WebSocketClientNotificationNumberOfConnections(NumberOfConnectedDevices_,
AverageDeviceConnectionTime_,
NumberOfConnectingDevices_);
}
bool DeviceRegistry::GetStatistics(uint64_t SerialNumber, std::string & Statistics) const {
std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
return false;
Statistics = Device->second.second->LastStats_;
return true;
}
bool DeviceRegistry::GetState(uint64_t SerialNumber, GWObjects::ConnectionState & State) const {
std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
return false;
State = Device->second.second->State_;
return true;
}
bool DeviceRegistry::GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const {
std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
return false;
CheckData = Device->second.second->LastHealthcheck_;
return true;
}
bool DeviceRegistry::EndSession(std::uint64_t connection_id, std::uint64_t serial_number) {
std::unique_lock G(LocalMutex_);
auto Connection = SerialNumbers_.find(serial_number);
if (Connection == end(SerialNumbers_)) {
return false;
}
if (Connection->second.first != connection_id) {
return false;
}
SerialNumbers_.erase(Connection);
return true;
}
void DeviceRegistry::SetSessionDetails(std::uint64_t connection_id, uint64_t SerialNumber) {
auto Connection = AP_WS_Server()->FindConnection(connection_id);
if(Connection== nullptr)
return;
std::unique_lock G(LocalMutex_);
auto CurrentSerialNumber = SerialNumbers_.find(SerialNumber);
if( (CurrentSerialNumber==SerialNumbers_.end()) ||
(CurrentSerialNumber->second.first<connection_id)) {
SerialNumbers_[SerialNumber] = std::make_pair(connection_id, Connection);
return;
}
}
bool DeviceRegistry::Connected(uint64_t SerialNumber) const {
std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
return false;
return Device->second.second->State_.Connected;
}
bool DeviceRegistry::SendFrame(uint64_t SerialNumber, const std::string & Payload) const {
std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
return false;
try {
// std::cout << "Device connection pointer: " << (std::uint64_t) Device->second.second << std::endl;
return Device->second.second->Send(Payload);
} catch (...) {
poco_debug(Logger(),fmt::format(": SendFrame: Could not send data to device '{}'", Utils::IntToSerialNumber(SerialNumber)));
}
return false;
}
void DeviceRegistry::StopWebSocketTelemetry(std::uint64_t RPCID, uint64_t SerialNumber) {
std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_) || Device->second.second==nullptr)
return;
Device->second.second->StopWebSocketTelemetry(RPCID);
}
void DeviceRegistry::SetWebSocketTelemetryReporting(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_) || Device->second.second==nullptr)
return;
Device->second.second->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime);
}
void DeviceRegistry::SetKafkaTelemetryReporting(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
return;
Device->second.second->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime);
}
void DeviceRegistry::StopKafkaTelemetry(std::uint64_t RPCID, uint64_t SerialNumber) {
std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
return;
Device->second.second->StopKafkaTelemetry(RPCID);
}
void DeviceRegistry::GetTelemetryParameters(uint64_t SerialNumber , bool & TelemetryRunning,
uint64_t & TelemetryInterval,
uint64_t & TelemetryWebSocketTimer,
uint64_t & TelemetryKafkaTimer,
uint64_t & TelemetryWebSocketCount,
uint64_t & TelemetryKafkaCount,
uint64_t & TelemetryWebSocketPackets,
uint64_t & TelemetryKafkaPackets) {
std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_)|| Device->second.second== nullptr)
return;
Device->second.second->GetTelemetryParameters(TelemetryRunning,
TelemetryInterval,
TelemetryWebSocketTimer,
TelemetryKafkaTimer,
TelemetryWebSocketCount,
TelemetryKafkaCount,
TelemetryWebSocketPackets,
TelemetryKafkaPackets);
}
bool DeviceRegistry::SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
return false;
try {
return Device->second.second->SendRadiusAccountingData(buffer,size);
} catch (...) {
poco_debug(Logger(),fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'", SerialNumber));
}
return false;
}
bool DeviceRegistry::SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
return false;
try {
return Device->second.second->SendRadiusAuthenticationData(buffer,size);
} catch (...) {
poco_debug(Logger(),fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'", SerialNumber));
}
return false;
}
bool DeviceRegistry::SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
return false;
try {
return Device->second.second->SendRadiusCoAData(buffer,size);
} catch (...) {
poco_debug(Logger(),fmt::format(": SendRadiusCoAData: Could not send data to device '{}'", SerialNumber));
}
return false;
}
} // namespace

104
src/DeviceRegistry.h Normal file
View File

@@ -0,0 +1,104 @@
//
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#pragma once
#include <shared_mutex>
#include "framework/MicroService.h"
#include "Poco/JSON/Object.h"
#include "Poco/Timer.h"
#include "RESTObjects//RESTAPI_GWobjects.h"
namespace OpenWifi {
class AP_WS_Connection;
class DeviceRegistry : public SubSystemServer {
public:
DeviceRegistry() noexcept:
SubSystemServer("DeviceRegistry", "DevStatus", "devicestatus") {
}
static auto instance() {
static auto instance_ = new DeviceRegistry;
return instance_;
}
int Start() override;
void Stop() override;
inline bool GetStatistics(const std::string &SerialNumber, std::string & Statistics) const {
return GetStatistics(Utils::SerialNumberToInt(SerialNumber),Statistics);
}
bool GetStatistics(std::uint64_t SerialNumber, std::string & Statistics) const;
inline bool GetState(const std::string & SerialNumber, GWObjects::ConnectionState & State) const {
return GetState(Utils::SerialNumberToInt(SerialNumber), State);
}
bool GetState(std::uint64_t SerialNumber, GWObjects::ConnectionState & State) const;
inline bool GetHealthcheck(const std::string &SerialNumber, GWObjects::HealthCheck & CheckData) const {
return GetHealthcheck(Utils::SerialNumberToInt(SerialNumber), CheckData);
}
bool GetHealthcheck(std::uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const ;
bool Connected(uint64_t SerialNumber) const ;
inline bool SendFrame(const std::string & SerialNumber, const std::string & Payload) const {
return SendFrame(Utils::SerialNumberToInt(SerialNumber), Payload);
}
bool SendFrame(std::uint64_t SerialNumber, const std::string & Payload) const ;
bool SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
bool SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
bool SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
void SetSessionDetails(std::uint64_t connection_id, uint64_t SerialNumber);
bool EndSession(std::uint64_t connection_id, std::uint64_t serial_number);
void SetWebSocketTelemetryReporting(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime);
void StopWebSocketTelemetry(std::uint64_t RPCID, uint64_t SerialNumber);
void SetKafkaTelemetryReporting(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime);
void StopKafkaTelemetry(std::uint64_t RPCID, uint64_t SerialNumber);
void GetTelemetryParameters(uint64_t SerialNumber , bool & TelemetryRunning,
uint64_t & TelemetryInterval,
uint64_t & TelemetryWebSocketTimer,
uint64_t & TelemetryKafkaTimer,
uint64_t & TelemetryWebSocketCount,
uint64_t & TelemetryKafkaCount,
uint64_t & TelemetryWebSocketPackets,
uint64_t & TelemetryKafkaPackets);
void onConnectionJanitor(Poco::Timer & timer);
inline void AverageDeviceStatistics( std::uint64_t & Connections, std::uint64_t & AverageConnectionTime, std::uint64_t & NumberOfConnectingDevices) const {
Connections = NumberOfConnectedDevices_;
AverageConnectionTime = AverageDeviceConnectionTime_;
NumberOfConnectingDevices = NumberOfConnectingDevices_;
}
private:
mutable std::shared_mutex LocalMutex_;
std::map<std::uint64_t, std::pair<std::uint64_t,std::shared_ptr<AP_WS_Connection>>> SerialNumbers_;
std::unique_ptr<Poco::TimerCallback<DeviceRegistry>> ArchiverCallback_;
Poco::Timer Timer_;
Poco::Thread ConnectionJanitor_;
std::atomic_uint64_t NumberOfConnectedDevices_=0;
std::atomic_uint64_t AverageDeviceConnectionTime_=0;
std::atomic_uint64_t NumberOfConnectingDevices_=0;
};
inline auto DeviceRegistry() { return DeviceRegistry::instance(); }
} // namespace

View File

@@ -8,6 +8,8 @@
#include <iostream>
#include "framework/MicroService.h"
#include "Poco/Net/HTTPServerParams.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "Poco/DynamicAny.h"
@@ -17,16 +19,9 @@
#include "Poco/CountingStream.h"
#include "Poco/StreamCopier.h"
#include "Poco/Exception.h"
#include "Poco/File.h"
#include "Poco/StringTokenizer.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/ow_constants.h"
#include "framework/utils.h"
#include "FileUploader.h"
#include "StorageService.h"
#include "fmt/format.h"
namespace OpenWifi {
@@ -35,7 +30,7 @@ namespace OpenWifi {
int FileUploader::Start() {
poco_notice(Logger(),"Starting.");
Poco::File UploadsDir(MicroServiceConfigPath("openwifi.fileuploader.path","/tmp"));
Poco::File UploadsDir(MicroService::instance().ConfigPath("openwifi.fileuploader.path","/tmp"));
Path_ = UploadsDir.path();
if(!UploadsDir.exists()) {
try {
@@ -47,7 +42,7 @@ namespace OpenWifi {
}
for(const auto & Svr: ConfigServersList_) {
if(MicroServiceNoAPISecurity()) {
if(MicroService::instance().NoAPISecurity()) {
poco_notice(Logger(), fmt::format("Starting: {}:{}",Svr.Address(),Svr.Port()));
auto Sock{Svr.CreateSocket(Logger())};
@@ -59,7 +54,7 @@ namespace OpenWifi {
if (FullName_.empty()) {
std::string TmpName =
MicroServiceConfigGetString("openwifi.fileuploader.uri", "");
MicroService::instance().ConfigGetString("openwifi.fileuploader.uri", "");
if (TmpName.empty()) {
FullName_ =
"https://" + Svr.Name() + ":" + std::to_string(Svr.Port()) + URI_BASE;
@@ -92,7 +87,7 @@ namespace OpenWifi {
if (FullName_.empty()) {
std::string TmpName =
MicroServiceConfigGetString("openwifi.fileuploader.uri", "");
MicroService::instance().ConfigGetString("openwifi.fileuploader.uri", "");
if (TmpName.empty()) {
FullName_ =
"https://" + Svr.Name() + ":" + std::to_string(Svr.Port()) + URI_BASE;
@@ -109,13 +104,13 @@ namespace OpenWifi {
}
}
MaxSize_ = 1000 * MicroServiceConfigGetInt("openwifi.fileuploader.maxsize", 10000);
MaxSize_ = 1000 * MicroService::instance().ConfigGetInt("openwifi.fileuploader.maxsize", 10000);
return 0;
}
void FileUploader::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
MicroServiceLoadConfigurationFile();
MicroService::instance().LoadConfigurationFile();
poco_information(Logger(),"Reinitializing.");
Stop();
Start();
@@ -126,32 +121,34 @@ namespace OpenWifi {
}
// if you pass in an empty UUID, it will just clean the list and not add it.
bool FileUploader::AddUUID( const std::string & UUID, std::chrono::seconds WaitTimeInSeconds, const std::string &Type) {
bool FileUploader::AddUUID( const std::string & UUID) {
std::lock_guard Guard(Mutex_);
uint64_t now = Utils::Now();
auto Func=[now](const UploadId &I) -> bool {
return (now > I.Expires);
};
OutStandingUploads_.erase(std::remove_if(OutStandingUploads_.begin(),OutStandingUploads_.end(),Func),OutStandingUploads_.end());
OutStandingUploads_.emplace_back(UploadId{UUID, now + WaitTimeInSeconds.count(), Type});
uint64_t now = OpenWifi::Now();
// remove old stuff...
for(auto i=OutStandingUploads_.begin();i!=OutStandingUploads_.end();) {
if ((now-i->second) > (60 * 30))
i = OutStandingUploads_.erase(i);
else
++i;
}
if(!UUID.empty())
OutStandingUploads_[UUID] = now;
return true;
}
bool FileUploader::ValidRequest(const std::string &UUID) {
std::lock_guard Guard(Mutex_);
auto Func = [UUID](const UploadId &P) -> bool {
return (P.UUID==UUID);
};
return std::find_if(OutStandingUploads_.begin(), OutStandingUploads_.end(), Func) != end(OutStandingUploads_);
return OutStandingUploads_.find(UUID)!=OutStandingUploads_.end();
}
void FileUploader::RemoveRequest(const std::string &UUID) {
std::lock_guard Guard(Mutex_);
auto Func = [UUID](const UploadId &P) -> bool {
return (P.UUID==UUID);
};
OutStandingUploads_.erase(std::remove_if(OutStandingUploads_.begin(),OutStandingUploads_.end(),Func),OutStandingUploads_.end());
OutStandingUploads_.erase(UUID);
}
class FileUploaderPartHandler2 : public Poco::Net::PartHandler {
@@ -191,10 +188,9 @@ namespace OpenWifi {
class FormRequestHandler: public Poco::Net::HTTPRequestHandler
{
public:
explicit FormRequestHandler(std::string UUID, Poco::Logger & L, const std::string &Type):
explicit FormRequestHandler(std::string UUID, Poco::Logger & L):
UUID_(std::move(UUID)),
Logger_(L),
Type_(Type)
Logger_(L)
{
}
@@ -229,8 +225,8 @@ namespace OpenWifi {
Poco::StreamCopier::copyStream(Reader.stream(), FileContent);
Answer.set("filename", UUID_);
Answer.set("error", 0);
poco_debug(Logger(),fmt::format("{}: File uploaded.", UUID_));
StorageService()->AttachFileDataToCommand(UUID_, FileContent, Type_);
poco_debug(Logger(),fmt::format("{}: Trace file uploaded.", UUID_));
StorageService()->AttachFileDataToCommand(UUID_, FileContent);
std::ostream &ResponseStream = Response.send();
Poco::JSON::Stringifier::stringify(Answer, ResponseStream);
return;
@@ -266,7 +262,6 @@ namespace OpenWifi {
private:
std::string UUID_;
Poco::Logger & Logger_;
std::string Type_;
};
Poco::Net::HTTPRequestHandler *FileUpLoaderRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest & Request) {
@@ -285,12 +280,11 @@ namespace OpenWifi {
if( UUIDLocation != std::string::npos )
{
auto UUID = Request.getURI().substr(UUIDLocation+URI_BASE.size());
FileUploader::UploadId E;
if(FileUploader()->Find(UUID,E))
if(FileUploader()->ValidRequest(UUID))
{
// make sure we do not allow anyone else to overwrite our file
FileUploader()->RemoveRequest(UUID);
return new FormRequestHandler(UUID,Logger(),E.Type);
return new FormRequestHandler(UUID,Logger());
}
else
{
@@ -300,17 +294,6 @@ namespace OpenWifi {
return nullptr;
}
bool FileUploader::Find(const std::string &UUID, UploadId &V) {
std::lock_guard G(Mutex_);
for(const auto &E:OutStandingUploads_) {
if (E.UUID == UUID) {
V = E;
return true;
}
}
return false;
}
void FileUploader::Stop() {
poco_notice(Logger(),"Stopping...");
for( const auto & svr : Servers_ )

View File

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

View File

@@ -4,11 +4,9 @@
#pragma once
#include "framework/MicroService.h"
#include "Poco/Net/IPAddress.h"
#include "framework/SubSystemServer.h"
#include "framework/MicroServiceFuncs.h"
#include "nlohmann/json.hpp"
namespace OpenWifi {
@@ -26,7 +24,7 @@ namespace OpenWifi {
public:
static std::string Name() { return "ipinfo"; }
inline bool Init() override {
Key_ = MicroServiceConfigGetString("iptocountry.ipinfo.token", "");
Key_ = MicroService::instance().ConfigGetString("iptocountry.ipinfo.token", "");
return !Key_.empty();
}
@@ -58,7 +56,7 @@ namespace OpenWifi {
public:
static std::string Name() { return "ipdata"; }
inline bool Init() override {
Key_ = MicroServiceConfigGetString("iptocountry.ipdata.apikey", "");
Key_ = MicroService::instance().ConfigGetString("iptocountry.ipdata.apikey", "");
return !Key_.empty();
}
@@ -88,7 +86,7 @@ namespace OpenWifi {
public:
static std::string Name() { return "ip2location"; }
inline bool Init() override {
Key_ = MicroServiceConfigGetString("iptocountry.ip2location.apikey", "");
Key_ = MicroService::instance().ConfigGetString("iptocountry.ip2location.apikey", "");
return !Key_.empty();
}
@@ -137,14 +135,14 @@ namespace OpenWifi {
inline int Start() final {
poco_notice(Logger(),"Starting...");
ProviderName_ = MicroServiceConfigGetString("iptocountry.provider","");
ProviderName_ = MicroService::instance().ConfigGetString("iptocountry.provider","");
if(!ProviderName_.empty()) {
Provider_ = IPLocationProvider<IPToCountryProvider, IPInfo, IPData, IP2Location>(ProviderName_);
if(Provider_!= nullptr) {
Enabled_ = Provider_->Init();
}
}
Default_ = MicroServiceConfigGetString("iptocountry.default", "US");
Default_ = MicroService::instance().ConfigGetString("iptocountry.default", "US");
return 0;
}

View File

@@ -9,11 +9,11 @@ namespace OpenWifi {
GwWebSocketClient::GwWebSocketClient(Poco::Logger &Logger):
Logger_(Logger){
UI_WebSocketClientServer()->SetProcessor(this);
WebSocketClientServer()->SetProcessor(this);
}
GwWebSocketClient::~GwWebSocketClient() {
UI_WebSocketClientServer()->SetProcessor(nullptr);
WebSocketClientServer()->SetProcessor(nullptr);
}
void GwWebSocketClient::Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done ) {
@@ -60,4 +60,7 @@ namespace OpenWifi {
Done = false;
Answer = std::string{R"lit({ "error" : "invalid command" })lit"};
}
}

View File

@@ -4,10 +4,10 @@
#pragma once
#include "framework/UI_WebSocketClientServer.h"
#include "framework/MicroService.h"
namespace OpenWifi {
class GwWebSocketClient : public UI_WebSocketClientProcessor {
class GwWebSocketClient : public WebSocketClientProcessor {
public:
explicit GwWebSocketClient(Poco::Logger &Logger);
virtual ~GwWebSocketClient();

View File

@@ -11,19 +11,15 @@
#include "Poco/StreamCopier.h"
#include "Poco/File.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.h"
#include "fmt/format.h"
#include "OUIServer.h"
#include "framework/MicroService.h"
namespace OpenWifi {
int OUIServer::Start() {
Running_ = true;
LatestOUIFileName_ = MicroServiceDataDirectory() + "/newOUIFile.txt";
CurrentOUIFileName_ = MicroServiceDataDirectory() + "/current_oui.txt";
LatestOUIFileName_ = MicroService::instance().DataDir() + "/newOUIFile.txt";
CurrentOUIFileName_ = MicroService::instance().DataDir() + "/current_oui.txt";
bool Recovered = false;
Poco::File OuiFile(CurrentOUIFileName_);
@@ -46,7 +42,7 @@ namespace OpenWifi {
Timer_.setStartInterval(30 * 1000); // first run in 5 minutes
}
Timer_.setPeriodicInterval(7 * 24 * 60 * 60 * 1000);
Timer_.start(*UpdaterCallBack_, MicroServiceTimerPool());
Timer_.start(*UpdaterCallBack_, MicroService::instance().TimerPool());
return 0;
}
@@ -58,7 +54,7 @@ namespace OpenWifi {
}
void OUIServer::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
MicroServiceLoadConfigurationFile();
MicroService::instance().LoadConfigurationFile();
poco_information(Logger(),"Reinitializing.");
Stop();
Start();
@@ -66,15 +62,15 @@ namespace OpenWifi {
bool OUIServer::GetFile(const std::string &FileName) {
try {
LastUpdate_ = Utils::Now();
poco_information(Logger(), fmt::format("Start: Retrieving OUI file: {}",MicroServiceConfigGetString("oui.download.uri","")));
LastUpdate_ = OpenWifi::Now();
poco_information(Logger(), fmt::format("Start: Retrieving OUI file: {}",MicroService::instance().ConfigGetString("oui.download.uri")));
std::unique_ptr<std::istream> pStr(
Poco::URIStreamOpener::defaultOpener().open(MicroServiceConfigGetString("oui.download.uri","")));
Poco::URIStreamOpener::defaultOpener().open(MicroService::instance().ConfigGetString("oui.download.uri")));
std::ofstream OS;
OS.open(FileName);
Poco::StreamCopier::copyStream(*pStr, OS);
OS.close();
poco_information(Logger(), fmt::format("Done: Retrieving OUI file: {}",MicroServiceConfigGetString("oui.download.uri","")));
poco_information(Logger(), fmt::format("Done: Retrieving OUI file: {}",MicroService::instance().ConfigGetString("oui.download.uri")));
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -129,7 +125,7 @@ namespace OpenWifi {
// fetch data from server, if not available, just use the file we already have.
Poco::File Current(CurrentOUIFileName_);
if(Current.exists()) {
if((Utils::Now()-Current.getLastModified().epochTime()) < (7*24*60*60)) {
if((OpenWifi::Now()-Current.getLastModified().epochTime()) < (7*24*60*60)) {
if(!Initialized_) {
if(ProcessFile(CurrentOUIFileName_, OUIs_)) {
Initialized_ = true;
@@ -148,7 +144,7 @@ namespace OpenWifi {
if(GetFile(LatestOUIFileName_) && ProcessFile(LatestOUIFileName_, TmpOUIs)) {
std::unique_lock G(LocalMutex_);
OUIs_ = std::move(TmpOUIs);
LastUpdate_ = Utils::Now();
LastUpdate_ = OpenWifi::Now();
Poco::File F1(CurrentOUIFileName_);
if(F1.exists())
F1.remove();
@@ -157,7 +153,7 @@ namespace OpenWifi {
poco_information(Logger(), fmt::format("New OUI file {} downloaded.",LatestOUIFileName_));
} else if(OUIs_.empty()) {
if(ProcessFile(CurrentOUIFileName_, TmpOUIs)) {
LastUpdate_ = Utils::Now();
LastUpdate_ = OpenWifi::Now();
std::unique_lock G(LocalMutex_);
OUIs_ = std::move(TmpOUIs);
}

View File

@@ -6,8 +6,7 @@
#include <shared_mutex>
#include "framework/SubSystemServer.h"
#include "framework/MicroService.h"
#include "Poco/Timer.h"
namespace OpenWifi {

View File

@@ -4,12 +4,7 @@
#pragma once
#include <string>
#include <vector>
#include <map>
#include <utility>
#include "nlohmann/json.hpp"
#include "framework/MicroService.h"
namespace OpenWifi {

View File

@@ -11,7 +11,6 @@
#include "Poco/HMACEngine.h"
#include "Poco/MD5Engine.h"
#include "Poco/StringTokenizer.h"
namespace OpenWifi::RADIUS {
@@ -291,8 +290,6 @@ static const struct tok radius_attribute_names[] = {
constexpr unsigned char CoA_ACK = 44;
constexpr unsigned char CoA_NAK = 45;
constexpr unsigned char ATTR_MessageAuthenticator = 80;
inline bool IsAuthentication(unsigned char t) {
return (t == RADIUS::Access_Request ||
t == RADIUS::Access_Accept ||
@@ -332,11 +329,6 @@ static const struct tok radius_attribute_names[] = {
return "Unknown";
}
inline void MakeRadiusAuthenticator(unsigned char *authenticator) {
for(int i=0;i<16;i++)
authenticator[i]=std::rand() & 0xff;
}
//
// From: https://github.com/Telecominfraproject/wlan-dictionary/blob/main/dictionary.tip
//
@@ -673,44 +665,6 @@ static const struct tok radius_attribute_names[] = {
bool Valid_=false;
};
class RadiusOutputPacket {
public:
explicit RadiusOutputPacket(const std::string &Secret)
: Secret_(Secret) {
}
inline void MakeStatusMessage() {
P_.code = RADCMD_STATUS_SER;
P_.identifier = std::rand() & 0x00ff;
MakeRadiusAuthenticator(P_.authenticator);
unsigned char MessageAuthenticator[16]{0};
AddAttribute(ATTR_MessageAuthenticator,sizeof(MessageAuthenticator),MessageAuthenticator);
P_.rawlen = 1 + 1 + 2 + 16 + 1 + 1 + 16;
Poco::HMACEngine<Poco::MD5Engine> H(Secret_);
H.update((const unsigned char *)&P_, P_.rawlen);
auto digest = H.digest();
int p = 0;
for (const auto &i : digest)
P_.attributes[1 + 1 + p++] = i;
}
inline void AddAttribute(unsigned char attr, uint8_t len, const unsigned char * data) {
P_.attributes[AttributesLen_++] = attr;
P_.attributes[AttributesLen_++] = len;
memcpy(&P_.attributes[AttributesLen_],data,len);
AttributesLen_+=len;
}
[[nodiscard]] inline const unsigned char * Data() const { return (const unsigned char *) &P_;}
[[nodiscard]] inline std::uint16_t Len() const { return P_.rawlen; }
private:
RawRadiusPacket P_;
uint16_t AttributesLen_=0;
std::string Secret_;
};
inline std::ostream &operator<<(std::ostream &os, RadiusPacket const &P) {
os << P.Attrs_ ;
return os;

View File

@@ -2,14 +2,9 @@
// Created by stephane bourque on 2022-05-18.
//
#include "Poco/JSON/Parser.h"
#include "RADIUS_proxy_server.h"
#include "RADIUS_helpers.h"
#include "AP_WS_Server.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
const int SMALLEST_RADIUS_PACKET = 20+19+4;
@@ -19,133 +14,118 @@ namespace OpenWifi {
int RADIUS_proxy_server::Start() {
ConfigFilename_ = MicroServiceDataDirectory()+"/radius_pool_config.json";
ConfigFilename_ = MicroService::instance().DataDir()+"/radius_pool_config.json";
Poco::File Config(ConfigFilename_);
Enabled_ = MicroServiceConfigGetBool("radius.proxy.enable",false);
if(!Enabled_ && !Config.exists()) {
StopRADSECServers();
enabled_ = MicroService::instance().ConfigGetBool("radius.proxy.enable",false);
if(!enabled_ && !Config.exists())
return 0;
}
poco_notice(Logger(),"Starting...");
Enabled_ = true;
enabled_ = true;
Poco::Net::SocketAddress AuthSockAddrV4(Poco::Net::AddressFamily::IPv4,
MicroServiceConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
AuthenticationSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV4,true,true);
MicroService::instance().ConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
AuthenticationSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV4,true);
Poco::Net::SocketAddress AuthSockAddrV6(Poco::Net::AddressFamily::IPv6,
MicroServiceConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
AuthenticationSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV6,true,true);
MicroService::instance().ConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
AuthenticationSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV6,true);
Poco::Net::SocketAddress AcctSockAddrV4(Poco::Net::AddressFamily::IPv4,
MicroServiceConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
AccountingSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV4,true,true);
MicroService::instance().ConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
AccountingSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV4,true);
Poco::Net::SocketAddress AcctSockAddrV6(Poco::Net::AddressFamily::IPv6,
MicroServiceConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
AccountingSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV6,true,true);
MicroService::instance().ConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
AccountingSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV6,true);
Poco::Net::SocketAddress CoASockAddrV4(Poco::Net::AddressFamily::IPv4,
MicroServiceConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
CoASocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV4,true,true);
MicroService::instance().ConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
CoASocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV4,true);
Poco::Net::SocketAddress CoASockAddrV6(Poco::Net::AddressFamily::IPv6,
MicroServiceConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
CoASocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV6,true,true);
MicroService::instance().ConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
CoASocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV6,true);
RadiusReactor_.reset();
RadiusReactor_ = std::make_unique<Poco::Net::SocketReactor>();
RadiusReactor_->addEventHandler(*AuthenticationSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
RadiusReactor_.addEventHandler(*AuthenticationSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
RadiusReactor_->addEventHandler(*AuthenticationSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
RadiusReactor_.addEventHandler(*AuthenticationSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
RadiusReactor_->addEventHandler(*AccountingSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
RadiusReactor_.addEventHandler(*AccountingSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
RadiusReactor_->addEventHandler(*AccountingSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
RadiusReactor_.addEventHandler(*AccountingSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
RadiusReactor_->addEventHandler(*CoASocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
RadiusReactor_.addEventHandler(*CoASocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnCoASocketReadable));
RadiusReactor_->addEventHandler(*CoASocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
RadiusReactor_.addEventHandler(*CoASocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnCoASocketReadable));
ParseConfig();
// start RADSEC servers...
StartRADSECServers();
RadiusReactorThread_.start(*RadiusReactor_);
RadiusReactorThread_.start(RadiusReactor_);
Utils::SetThreadName(RadiusReactorThread_,"rad:reactor");
Running_ = true;
running_ = true;
return 0;
}
void RADIUS_proxy_server::Stop() {
if(Enabled_ && Running_) {
poco_information(Logger(),"Stopping...");
RadiusReactor_->removeEventHandler(
poco_information(Logger(),"Stopping...");
if(enabled_ && running_) {
RadiusReactor_.removeEventHandler(
*AuthenticationSocketV4_,
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
RadiusReactor_->removeEventHandler(
RadiusReactor_.removeEventHandler(
*AuthenticationSocketV6_,
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
RadiusReactor_->removeEventHandler(
RadiusReactor_.removeEventHandler(
*AccountingSocketV4_,
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
RadiusReactor_->removeEventHandler(
RadiusReactor_.removeEventHandler(
*AccountingSocketV6_,
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
RadiusReactor_->removeEventHandler(
RadiusReactor_.removeEventHandler(
*CoASocketV4_,
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnCoASocketReadable));
RadiusReactor_->removeEventHandler(
RadiusReactor_.removeEventHandler(
*CoASocketV6_,
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnCoASocketReadable));
AuthenticationSocketV4_->close();
AuthenticationSocketV6_->close();
AccountingSocketV4_->close();
AccountingSocketV6_->close();
CoASocketV4_->close();
CoASocketV6_->close();
for(auto &[_,radsec_server]:RADSECservers_)
radsec_server->Stop();
AuthenticationSocketV4_.reset();
AuthenticationSocketV6_.reset();
AccountingSocketV4_.reset();
AccountingSocketV6_.reset();
CoASocketV4_.reset();
CoASocketV6_.reset();
StopRADSECServers();
RadiusReactor_->stop();
RadiusReactor_.stop();
RadiusReactorThread_.join();
Running_=false;
poco_information(Logger(),"Stopped...");
enabled_=false;
running_=false;
}
poco_information(Logger(),"Stopped...");
}
void RADIUS_proxy_server::StartRADSECServers() {
std::lock_guard G(Mutex_);
for(const auto &pool:PoolList_.pools) {
for(const auto &entry:pool.authConfig.servers) {
if(entry.radsec) {
RADSECservers_[ Poco::Net::SocketAddress(entry.ip,0) ] = std::make_unique<RADSEC_server>(*RadiusReactor_,entry);
StartRADSECServer(entry);
}
}
}
}
void RADIUS_proxy_server::StopRADSECServers() {
std::lock_guard G(Mutex_);
RADSECservers_.clear();
void RADIUS_proxy_server::StartRADSECServer(const GWObjects::RadiusProxyServerEntry &E) {
RADSECservers_[ Poco::Net::SocketAddress(E.ip,0) ] = std::make_unique<RADSECserver>(RadiusReactor_,E);
}
void RADIUS_proxy_server::OnAccountingSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
@@ -216,7 +196,7 @@ namespace OpenWifi {
void RADIUS_proxy_server::SendAccountingData(const std::string &serialNumber, const char *buffer, std::size_t size) {
if(!Continue())
if(Pools_.empty() || !enabled_)
return;
try {
@@ -274,7 +254,7 @@ namespace OpenWifi {
void RADIUS_proxy_server::SendAuthenticationData(const std::string &serialNumber, const char *buffer, std::size_t size) {
if(!Continue())
if(Pools_.empty() || !enabled_)
return;
try {
@@ -327,7 +307,7 @@ namespace OpenWifi {
void RADIUS_proxy_server::SendCoAData(const std::string &serialNumber, const char *buffer, std::size_t size) {
if(!Continue())
if(Pools_.empty() || !enabled_)
return;
try {
@@ -397,7 +377,7 @@ namespace OpenWifi {
};
if(setAsDefault && D.useRADSEC)
DefaultIsRADSEC_ = true;
defaultIsRADSEC_ = true;
if(S.family()==Poco::Net::IPAddress::IPv4) {
TotalV4 += server.weight;
@@ -491,26 +471,26 @@ namespace OpenWifi {
}
}
if(DefaultIsRADSEC_) {
if(defaultIsRADSEC_) {
UseRADSEC = true;
return (IsV4 ? Pools_[DefaultPoolIndex_].AuthV4[0].Addr : Pools_[DefaultPoolIndex_].AuthV6[0].Addr );
return (IsV4 ? Pools_[defaultPoolIndex_].AuthV4[0].Addr : Pools_[defaultPoolIndex_].AuthV6[0].Addr );
}
switch(rtype) {
case radius_type::auth: {
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].AuthV4
: Pools_[DefaultPoolIndex_].AuthV6,
return ChooseAddress(IsV4 ? Pools_[defaultPoolIndex_].AuthV4
: Pools_[defaultPoolIndex_].AuthV6,
RequestedAddress);
}
case radius_type::acct:
default: {
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].AcctV4
: Pools_[DefaultPoolIndex_].AcctV6,
return ChooseAddress(IsV4 ? Pools_[defaultPoolIndex_].AcctV4
: Pools_[defaultPoolIndex_].AcctV6,
RequestedAddress);
}
case radius_type::coa: {
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].CoaV4
: Pools_[DefaultPoolIndex_].CoaV6,
return ChooseAddress(IsV4 ? Pools_[defaultPoolIndex_].CoaV4
: Pools_[defaultPoolIndex_].CoaV6,
RequestedAddress);
}
}
@@ -629,6 +609,7 @@ namespace OpenWifi {
void RADIUS_proxy_server::SetConfig(const GWObjects::RadiusProxyPoolList &C) {
std::lock_guard G(Mutex_);
PoolList_ = C;
Poco::JSON::Object Disk;
C.to_json(Disk);
@@ -637,17 +618,17 @@ namespace OpenWifi {
Disk.stringify(ofs);
ofs.close();
Stop();
ResetConfig();
PoolList_ = C;
Start();
if(!running_) {
Start();
}
ParseConfig();
}
void RADIUS_proxy_server::ResetConfig() {
PoolList_.pools.clear();
Pools_.clear();
DefaultPoolIndex_=0;
DefaultIsRADSEC_=false;
defaultPoolIndex_=0;
}
void RADIUS_proxy_server::DeleteConfig() {
@@ -660,8 +641,8 @@ namespace OpenWifi {
} catch (...) {
}
Stop();
ResetConfig();
Stop();
}
void RADIUS_proxy_server::GetConfig(GWObjects::RadiusProxyPoolList &C) {

View File

@@ -4,14 +4,13 @@
#pragma once
#include "framework/MicroService.h"
#include "RESTObjects/RESTAPI_GWobjects.h"
#include "Poco/Net/DatagramSocket.h"
#include "Poco/Net/SocketReactor.h"
#include "framework/SubSystemServer.h"
#include "RADSEC_server.h"
#include "RADSECserver.h"
namespace OpenWifi {
@@ -29,7 +28,7 @@ namespace OpenWifi {
int Start() final;
void Stop() final;
inline bool Enabled() const { return Enabled_; }
inline bool Enabled() const { return enabled_; }
void OnAccountingSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
void OnAuthenticationSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
@@ -44,7 +43,7 @@ namespace OpenWifi {
void GetConfig(GWObjects::RadiusProxyPoolList &C);
void StartRADSECServers();
void StopRADSECServers();
void StartRADSECServer(const GWObjects::RadiusProxyServerEntry &E);
struct Destination {
Poco::Net::SocketAddress Addr;
@@ -61,10 +60,6 @@ namespace OpenWifi {
std::vector<std::string> realms;
};
inline bool Continue() const {
return Running_ && Enabled_ && !Pools_.empty();
}
private:
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV4_;
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV6_;
@@ -72,13 +67,13 @@ namespace OpenWifi {
std::unique_ptr<Poco::Net::DatagramSocket> AuthenticationSocketV6_;
std::unique_ptr<Poco::Net::DatagramSocket> CoASocketV4_;
std::unique_ptr<Poco::Net::DatagramSocket> CoASocketV6_;
std::unique_ptr<Poco::Net::SocketReactor> RadiusReactor_;
Poco::Thread RadiusReactorThread_;
Poco::Net::SocketReactor RadiusReactor_;
Poco::Thread RadiusReactorThread_;
GWObjects::RadiusProxyPoolList PoolList_;
std::string ConfigFilename_;
std::map<Poco::Net::SocketAddress, std::unique_ptr<RADSEC_server>> RADSECservers_;
std::map<Poco::Net::SocketAddress, std::unique_ptr<RADSECserver>> RADSECservers_;
struct RadiusPool {
std::vector<Destination> AuthV4;
@@ -90,10 +85,10 @@ namespace OpenWifi {
};
std::vector<RadiusPool> Pools_;
uint DefaultPoolIndex_=0;
bool Enabled_=false;
bool DefaultIsRADSEC_=false;
std::atomic_bool Running_=false;
uint defaultPoolIndex_=0;
bool enabled_=false;
bool defaultIsRADSEC_=false;
std::atomic_bool running_=false;
RADIUS_proxy_server() noexcept:
SubSystemServer("RADIUS-PROXY", "RADIUS-PROXY", "radius.proxy")

View File

@@ -7,6 +7,8 @@
#include <iostream>
#include <fstream>
#include "framework/MicroService.h"
#include "RESTObjects/RESTAPI_GWobjects.h"
#include "Poco/Net/SocketReactor.h"
@@ -16,60 +18,31 @@
#include "Poco/Net/NetException.h"
#include "Poco/TemporaryFile.h"
#include "framework/MicroServiceFuncs.h"
#include "fmt/format.h"
#include "RADIUS_helpers.h"
#include "AP_WS_Server.h"
namespace OpenWifi {
class RADSEC_server : public Poco::Runnable {
class RADSECserver : public Poco::Runnable {
public:
RADSEC_server(Poco::Net::SocketReactor & R, GWObjects::RadiusProxyServerEntry E) :
RADSECserver(Poco::Net::SocketReactor & R, GWObjects::RadiusProxyServerEntry E) :
Reactor_(R),
Server_(std::move(E)),
Logger_(Poco::Logger::get(fmt::format("RADSEC: {}@{}:{}",
Server_.name ,
Server_.ip,
Server_.port))) {
Start();
}
~RADSEC_server() {
Stop();
}
inline int Start() {
ReconnectThread_.start(*this);
return 0;
}
inline void Stop() {
TryAgain_ = false;
Disconnect();
ReconnectThread_.wakeUp();
ReconnectThread_.join();
Server_.port)))
{
ReconnectorThr_.start(*this);
}
inline void run() final {
Poco::Thread::trySleep(3000);
std::uint64_t LastStatus=0 ;
auto RadSecKeepAlive = MicroServiceConfigGetInt("radsec.keepalive",120);
while(TryAgain_) {
if(!Connected_) {
std::lock_guard G(LocalMutex_);
LastStatus = Utils::Now() ;
std::unique_lock G(Mutex_);
Connect();
} else if( (Utils::Now() - LastStatus) > RadSecKeepAlive) {
RADIUS::RadiusOutputPacket P(Server_.radsecSecret);
P.MakeStatusMessage();
poco_information(Logger_,"Keep-Alive message.");
Socket_->sendBytes(P.Data(), P.Len());
LastStatus = Utils::Now();
}
Poco::Thread::trySleep(!Connected_ ? 3000 : 10000);
Poco::Thread::trySleep(1000);
}
}
@@ -77,23 +50,22 @@ namespace OpenWifi {
try {
if (Connected_) {
RADIUS::RadiusPacket P(buffer, length);
// std::cout << serial_number << " Sending " << P.PacketType() << " " << length << " bytes" << std::endl;
int sent_bytes;
if (P.VerifyMessageAuthenticator(Server_.radsecSecret)) {
poco_debug(Logger_, fmt::format("{}: {} Sending {} bytes", serial_number,
P.PacketType(), length));
poco_debug(Logger_,fmt::format("{}: {} Sending {} bytes", serial_number,
P.PacketType(), length));
sent_bytes = Socket_->sendBytes(buffer, length);
} else {
poco_debug(Logger_, fmt::format("{}: {} Sending {} bytes", serial_number,
P.PacketType(), length));
poco_debug(Logger_,fmt::format("{}: {} Sending {} bytes", serial_number,
P.PacketType(), length));
P.ComputeMessageAuthenticator(Server_.radsecSecret);
sent_bytes = Socket_->sendBytes(P.Buffer(), length);
}
return (sent_bytes == length);
}
} catch (const Poco::Exception &E) {
Logger_.log(E);
} catch (...) {
poco_warning(Logger_,"Exception occurred: while sending data.");
}
return false;
}
@@ -103,7 +75,7 @@ namespace OpenWifi {
try {
auto NumberOfReceivedBytes = Socket_->receiveBytes(Buffer,sizeof(Buffer));
if(NumberOfReceivedBytes>=20) {
if(NumberOfReceivedBytes>40) {
RADIUS::RadiusPacket P(Buffer,NumberOfReceivedBytes);
if (P.IsAuthentication()) {
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
@@ -114,7 +86,9 @@ namespace OpenWifi {
AP_WS_Server()->SendRadiusAuthenticationData(SerialNumber, Buffer,
NumberOfReceivedBytes);
} else {
poco_debug(Logger_, "AUTH packet dropped.");
poco_debug(Logger_,
fmt::format("Invalid AUTH packet received in proxy dropped. No serial number Source={}",
Socket_->address().toString()));
}
} else if (P.IsAccounting()) {
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
@@ -125,72 +99,53 @@ namespace OpenWifi {
AP_WS_Server()->SendRadiusAccountingData(SerialNumber, Buffer,
NumberOfReceivedBytes);
} else {
poco_debug(Logger_, "ACCT packet dropped.");
poco_debug(Logger_,
fmt::format("Invalid ACCT packet received in proxy dropped. No serial number Source={}",
Socket_->address().toString()));
}
} else if (P.IsAuthority()) {
auto SerialNumber = P.ExtractSerialNumberTIP();
if(!SerialNumber.empty()) {
poco_debug(Logger_,
fmt::format("{}: {} Received {} bytes.", SerialNumber,
P.PacketType(), NumberOfReceivedBytes));
AP_WS_Server()->SendRadiusCoAData(SerialNumber, Buffer,
NumberOfReceivedBytes);
} else {
poco_debug(Logger_, "CoA/DM packet dropped.");
}
} else {
poco_warning(Logger_,fmt::format("Unknown packet: Type: {} (type={}) Length={}", P.PacketType(), P.PacketTypeInt(), P.BufferLen()));
}
} else {
poco_warning(Logger_,"Invalid packet received. Resetting the connection.");
Disconnect();
}
} catch (const Poco::Exception &E) {
Logger_.log(E);
Disconnect();
} catch (...) {
Disconnect();
poco_warning(Logger_,"Exception occurred. Resetting the connection.");
}
}
inline void onError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf) {
poco_warning(Logger_,"Socker error. Terminating connection.");
std::cout << "onError" << std::endl;
Disconnect();
}
inline void onShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf) {
poco_warning(Logger_,"Socker socket shutdown. Terminating connection.");
std::cout << "onShutdown" << std::endl;
Disconnect();
}
inline bool Connect() {
if(TryAgain_) {
std::lock_guard G(LocalMutex_);
Poco::TemporaryFile CertFile_(MicroServiceDataDirectory());
Poco::TemporaryFile KeyFile_(MicroServiceDataDirectory());
std::vector<std::unique_ptr<Poco::TemporaryFile>> CaCertFiles_;
Poco::TemporaryFile CertFile_(MicroService::instance().DataDir());
Poco::TemporaryFile KeyFile_(MicroService::instance().DataDir());
std::vector<Poco::TemporaryFile> CaCertFiles_;
DecodeFile(CertFile_.path(), Server_.radsecCert);
DecodeFile(KeyFile_.path(), Server_.radsecKey);
for(auto &cert:Server_.radsecCacerts) {
CaCertFiles_.emplace_back(std::make_unique<Poco::TemporaryFile>(MicroServiceDataDirectory()));
DecodeFile(CaCertFiles_[CaCertFiles_.size()-1]->path(), cert);
CaCertFiles_.emplace_back(Poco::TemporaryFile(MicroService::instance().DataDir()));
DecodeFile(CaCertFiles_[CaCertFiles_.size()-1].path(), cert);
}
Poco::Net::Context::Ptr SecureContext = Poco::AutoPtr<Poco::Net::Context>(
new Poco::Net::Context(Poco::Net::Context::TLS_CLIENT_USE,
KeyFile_.path(),
CertFile_.path(),""));
if(Server_.allowSelfSigned) {
SecureContext->setSecurityLevel(Poco::Net::Context::SECURITY_LEVEL_NONE);
SecureContext->enableExtendedCertificateVerification(false);
}
for(const auto &ca:CaCertFiles_) {
Poco::Crypto::X509Certificate cert(ca->path());
Poco::Crypto::X509Certificate cert(ca.path());
SecureContext->addCertificateAuthority(cert);
}
@@ -202,10 +157,7 @@ namespace OpenWifi {
poco_information(Logger_, "Attempting to connect");
Socket_->connect(Destination, Poco::Timespan(100, 0));
Socket_->completeHandshake();
if(!Server_.allowSelfSigned) {
Socket_->verifyPeerCertificate();
}
Socket_->verifyPeerCertificate();
if(Socket_->havePeerCertificate()) {
Peer_Cert_ = std::make_unique<Poco::Crypto::X509Certificate>(Socket_->peerCertificate());
@@ -214,19 +166,21 @@ namespace OpenWifi {
Socket_->setBlocking(false);
Socket_->setNoDelay(true);
Socket_->setKeepAlive(true);
Socket_->setReceiveTimeout(Poco::Timespan(1 * 60 * 60,0));
Reactor_.addEventHandler(
*Socket_,
Poco::NObserver<RADSEC_server, Poco::Net::ReadableNotification>(
*this, &RADSEC_server::onData));
Poco::NObserver<RADSECserver, Poco::Net::ReadableNotification>(
*this, &RADSECserver::onData));
Reactor_.addEventHandler(
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ErrorNotification>(
*this, &RADSEC_server::onError));
*Socket_, Poco::NObserver<RADSECserver, Poco::Net::ErrorNotification>(
*this, &RADSECserver::onError));
Reactor_.addEventHandler(
*Socket_,
Poco::NObserver<RADSEC_server, Poco::Net::ShutdownNotification>(
*this, &RADSEC_server::onShutdown));
Poco::NObserver<RADSECserver, Poco::Net::ShutdownNotification>(
*this, &RADSECserver::onShutdown));
Socket_->setBlocking(false);
Socket_->setNoDelay(true);
Socket_->setKeepAlive(true);
Connected_ = true;
poco_information(Logger_,fmt::format("Connected. CN={}",CommonName()));
@@ -246,23 +200,29 @@ namespace OpenWifi {
inline void Disconnect() {
if(Connected_) {
std::lock_guard G(LocalMutex_);
std::unique_lock G(Mutex_);
Reactor_.removeEventHandler(
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ReadableNotification>(
*this, &RADSEC_server::onData));
*Socket_, Poco::NObserver<RADSECserver, Poco::Net::ReadableNotification>(
*this, &RADSECserver::onData));
Reactor_.removeEventHandler(
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ErrorNotification>(
*this, &RADSEC_server::onError));
*Socket_, Poco::NObserver<RADSECserver, Poco::Net::ErrorNotification>(
*this, &RADSECserver::onError));
Reactor_.removeEventHandler(
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ShutdownNotification>(
*this, &RADSEC_server::onShutdown));
Socket_->close();
*Socket_, Poco::NObserver<RADSECserver, Poco::Net::ShutdownNotification>(
*this, &RADSECserver::onShutdown));
Connected_ = false;
}
poco_information(Logger_,"Disconnecting.");
}
inline void Stop() {
TryAgain_ = false;
Disconnect();
ReconnectorThr_.wakeUp();
ReconnectorThr_.join();
}
static void DecodeFile(const std::string &filename, const std::string &s) {
std::ofstream sec_file(filename,std::ios_base::out|std::ios_base::trunc|std::ios_base::binary);
std::stringstream is(s);
@@ -290,14 +250,14 @@ namespace OpenWifi {
}
private:
std::recursive_mutex LocalMutex_;
std::shared_mutex Mutex_;
Poco::Net::SocketReactor &Reactor_;
GWObjects::RadiusProxyServerEntry Server_;
Poco::Logger &Logger_;
std::atomic_bool Connected_=false;
std::atomic_bool TryAgain_=true;
std::unique_ptr<Poco::Net::SecureStreamSocket> Socket_;
Poco::Thread ReconnectThread_;
Poco::Thread ReconnectorThr_;
std::unique_ptr<Poco::Crypto::X509Certificate> Peer_Cert_;
volatile bool Connected_=false;
volatile bool TryAgain_=true;
};
}

View File

@@ -11,9 +11,7 @@
#include "AP_WS_Server.h"
#include "StorageService.h"
#include "framework/ow_constants.h"
#include "framework/RESTAPI_Handler.h"
#include "ParseWifiScan.h"
#include "framework/utils.h"
namespace OpenWifi::RESTAPI_RPC {
void SetCommandStatus(GWObjects::CommandDetails &Cmd,
@@ -34,7 +32,6 @@ namespace OpenWifi::RESTAPI_RPC {
}
void WaitForCommand(uint64_t RPCID,
APCommands::Commands Command,
bool RetryLater,
GWObjects::CommandDetails &Cmd,
Poco::JSON::Object & Params,
@@ -60,12 +57,12 @@ namespace OpenWifi::RESTAPI_RPC {
return SetCommandStatus(Cmd, Request, Response, Handler, Storage::CommandExecutionType::COMMAND_FAILED, Logger);
}
Cmd.Executed = Utils::Now();
Cmd.Executed = OpenWifi::Now();
bool Sent;
std::chrono::time_point<std::chrono::high_resolution_clock> rpc_submitted = std::chrono::high_resolution_clock::now();
std::shared_ptr<CommandManager::promise_type_t> rpc_endpoint =
CommandManager()->PostCommand(RPCID, Command, Cmd.SerialNumber, Cmd.Command, Params, Cmd.UUID, Sent);
CommandManager()->PostCommand(RPCID, Cmd.SerialNumber, Cmd.Command, Params, Cmd.UUID, Sent);
if(RetryLater && (!Sent || rpc_endpoint== nullptr)) {
Logger.information(fmt::format("{},{}: Pending completion. Device is not connected.", Cmd.UUID, RPCID));
@@ -83,13 +80,13 @@ namespace OpenWifi::RESTAPI_RPC {
if (rpc_result == std::future_status::ready) {
std::chrono::duration<double, std::milli> rpc_execution_time = std::chrono::high_resolution_clock::now() - rpc_submitted;
auto rpc_answer = rpc_future.get();
if (!rpc_answer->has(uCentralProtocol::RESULT) || !rpc_answer->isObject(uCentralProtocol::RESULT)) {
if (!rpc_answer.has(uCentralProtocol::RESULT) || !rpc_answer.isObject(uCentralProtocol::RESULT)) {
SetCommandStatus(Cmd, Request, Response, Handler, Storage::CommandExecutionType::COMMAND_FAILED, Logger);
Logger.information(fmt::format("{},{}: Invalid response. Missing result.", Cmd.UUID, RPCID));
return;
}
auto ResultFields = rpc_answer->get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
auto ResultFields = rpc_answer.get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
if (!ResultFields->has(uCentralProtocol::STATUS) || !ResultFields->isObject(uCentralProtocol::STATUS)) {
Cmd.executionTime = rpc_execution_time.count();
if(Cmd.Command=="ping") {
@@ -108,29 +105,29 @@ namespace OpenWifi::RESTAPI_RPC {
if (StatusInnerObj->has(uCentralProtocol::TEXT))
Cmd.ErrorText = StatusInnerObj->get(uCentralProtocol::TEXT).toString();
std::stringstream ResultText;
if(rpc_answer->has(uCentralProtocol::RESULT)) {
if(rpc_answer.has(uCentralProtocol::RESULT)) {
if(Cmd.Command==uCentralProtocol::WIFISCAN) {
auto ScanObj = rpc_answer->get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
auto ScanObj = rpc_answer.get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
ParseWifiScan(ScanObj, ResultText, Logger);
} else {
Poco::JSON::Stringifier::stringify(
rpc_answer->get(uCentralProtocol::RESULT), ResultText);
rpc_answer.get(uCentralProtocol::RESULT), ResultText);
}
} if (rpc_answer->has(uCentralProtocol::RESULT_64)) {
} if (rpc_answer.has(uCentralProtocol::RESULT_64)) {
uint64_t sz=0;
if(rpc_answer->has(uCentralProtocol::RESULT_SZ))
sz=rpc_answer->get(uCentralProtocol::RESULT_SZ);
if(rpc_answer.has(uCentralProtocol::RESULT_SZ))
sz=rpc_answer.get(uCentralProtocol::RESULT_SZ);
std::string UnCompressedData;
Utils::ExtractBase64CompressedData(rpc_answer->get(uCentralProtocol::RESULT_64).toString(),
Utils::ExtractBase64CompressedData(rpc_answer.get(uCentralProtocol::RESULT_64).toString(),
UnCompressedData,sz);
Poco::JSON::Stringifier::stringify(UnCompressedData, ResultText);
}
Cmd.Results = ResultText.str();
Cmd.Status = "completed";
Cmd.Completed = Utils::Now();
Cmd.Completed = OpenWifi::Now();
Cmd.executionTime = rpc_execution_time.count();
if (Cmd.ErrorCode && (Cmd.Command == uCentralProtocol::TRACE || Cmd.Command == uCentralProtocol::SCRIPT)) {
if (Cmd.ErrorCode && Cmd.Command == uCentralProtocol::TRACE) {
Cmd.WaitingForFile = 0;
Cmd.AttachDate = Cmd.AttachSize = 0;
Cmd.AttachType = "";

View File

@@ -16,15 +16,12 @@
#include "RESTObjects/RESTAPI_GWobjects.h"
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
#include "framework/ow_constants.h"
#include "framework/MicroService.h"
namespace OpenWifi::RESTAPI_RPC {
void WaitForCommand(
uint64_t RPCID,
APCommands::Commands Command,
bool RetryLater,
GWObjects::CommandDetails &Cmd,
Poco::JSON::Object & Params,

View File

@@ -6,11 +6,13 @@
// Arilia Wireless Inc.
//
#include <ctime>
#include "Poco/JSON/Parser.h"
#include "Poco/JSON/Stringifier.h"
#include "RESTAPI_blacklist.h"
#include "StorageService.h"
#include "framework/ow_constants.h"
#include "framework/utils.h"
namespace OpenWifi {
void RESTAPI_blacklist::DoDelete() {
@@ -20,8 +22,6 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
}
poco_debug(Logger(),fmt::format("BLACKLIST-DELETE: {}", SerialNumber));
GWObjects::BlackListedDevice D;
if(!StorageService()->GetBlackListDevice(SerialNumber, D)) {
return NotFound();
@@ -40,12 +40,14 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
}
poco_debug(Logger(),fmt::format("BLACKLIST-GET: {}", SerialNumber));
GWObjects::BlackListedDevice D;
if(!StorageService()->GetBlackListDevice(SerialNumber, D)) {
return NotFound();
}
return Object(D);
Poco::JSON::Object Answer;
D.to_json(Answer);
return ReturnObject(Answer);
}
void RESTAPI_blacklist::DoPost() {
@@ -60,20 +62,22 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
}
poco_debug(Logger(),fmt::format("BLACKLIST-POST: {}", D.serialNumber));
Poco::toLowerInPlace(D.serialNumber);
if(StorageService()->IsBlackListed(D.serialNumber)) {
return BadRequest(RESTAPI::Errors::SerialNumberExists);
}
D.author = UserInfo_.userinfo.email;
D.created = Utils::Now();
D.created = OpenWifi::Now();
if(StorageService()->AddBlackListDevice(D)) {
GWObjects::BlackListedDevice CreatedDevice;
StorageService()->GetBlackListDevice(D.serialNumber,CreatedDevice);
return Object(CreatedDevice);
Poco::JSON::Object Answer;
CreatedDevice.to_json(Answer);
return ReturnObject(Answer);
}
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
@@ -90,8 +94,6 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
poco_debug(Logger(),fmt::format("BLACKLIST-PUT: {}", SerialNumber));
GWObjects::BlackListedDevice NewDevice;
if(!NewDevice.from_json(Obj)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
@@ -104,7 +106,10 @@ namespace OpenWifi {
GWObjects::BlackListedDevice CreatedDevice;
StorageService()->GetBlackListDevice(SerialNumber,CreatedDevice);
return Object(CreatedDevice);
Poco::JSON::Object Answer;
CreatedDevice.to_json(Answer);
return ReturnObject(Answer);
}
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}

View File

@@ -8,12 +8,12 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_blacklist : public RESTAPIHandler {
public:
RESTAPI_blacklist(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server , uint64_t TransactionId , bool Internal)
RESTAPI_blacklist(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server , uint64_t TransactionId , bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_POST,

View File

@@ -10,16 +10,22 @@
namespace OpenWifi {
void RESTAPI_blacklist_list::DoGet() {
poco_debug(Logger(),fmt::format("BLACKLIST-GET: Device serial number list"));
std::vector<GWObjects::BlackListedDevice> Devices;
Poco::JSON::Array Arr;
Poco::JSON::Object Answer;
if(QB_.CountOnly) {
auto Count = StorageService()->GetBlackListDeviceCount();
return ReturnCountOnly(Count);
} else if(StorageService()->GetBlackListDevices(QB_.Offset, QB_.Limit, Devices)) {
return Object("devices",Devices);
for(const auto &i:Devices) {
Poco::JSON::Object O;
i.to_json(O);
Arr.add(O);
}
}
NotFound();
Answer.set("devices", Arr);
return ReturnObject(Answer);
}
}

View File

@@ -4,12 +4,12 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_blacklist_list : public RESTAPIHandler {
public:
RESTAPI_blacklist_list(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
RESTAPI_blacklist_list(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},

View File

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

View File

@@ -4,12 +4,12 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_capabilities_handler : public RESTAPIHandler {
public:
RESTAPI_capabilities_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
RESTAPI_capabilities_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},

View File

@@ -20,7 +20,9 @@ namespace OpenWifi {
GWObjects::CommandDetails Command;
if (StorageService()->GetCommand(CommandUUID, Command)) {
return Object(Command);
Poco::JSON::Object RetObj;
Command.to_json(RetObj);
return ReturnObject(RetObj);
}
return NotFound();
}

View File

@@ -8,12 +8,12 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_command : public RESTAPIHandler {
public:
RESTAPI_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
RESTAPI_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_DELETE,

View File

@@ -24,7 +24,15 @@ namespace OpenWifi {
StorageService()->GetCommands(SerialNumber, QB_.StartDate, QB_.EndDate, QB_.Offset, QB_.Limit,
Commands);
}
return Object(RESTAPI::Protocol::COMMANDS, Commands);
Poco::JSON::Array ArrayObj;
for (const auto &i : Commands) {
Poco::JSON::Object Obj;
i.to_json(Obj);
ArrayObj.add(Obj);
}
Poco::JSON::Object RetObj;
RetObj.set(RESTAPI::Protocol::COMMANDS, ArrayObj);
ReturnObject(RetObj);
}
void RESTAPI_commands::DoDelete() {

View File

@@ -8,12 +8,12 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_commands : public RESTAPIHandler {
public:
RESTAPI_commands(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
RESTAPI_commands(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_DELETE,

View File

@@ -15,14 +15,15 @@
#include "framework/ow_constants.h"
#include "framework/ConfigurationValidator.h"
#include "framework/orm.h"
#include "framework/utils.h"
namespace OpenWifi {
void RESTAPI_default_configuration::DoGet() {
std::string Name = ORM::Escape(GetBinding(RESTAPI::Protocol::NAME, ""));
GWObjects::DefaultConfiguration DefConfig;
if (StorageService()->GetDefaultConfiguration(Name, DefConfig)) {
return Object(DefConfig);
Poco::JSON::Object Obj;
DefConfig.to_json(Obj);
return ReturnObject(Obj);
}
NotFound();
}
@@ -65,7 +66,7 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
}
DefConfig.Created = DefConfig.LastModified = Utils::Now();
DefConfig.Created = DefConfig.LastModified = OpenWifi::Now();
if (StorageService()->CreateDefaultConfiguration(Name, DefConfig)) {
return OK();
}
@@ -95,7 +96,7 @@ namespace OpenWifi {
Existing.Configuration = NewConfig.Configuration;
}
Existing.LastModified = Utils::Now();
Existing.LastModified = OpenWifi::Now();
AssignIfPresent(Obj,"description",Existing.Description);
if(Obj->has("modelIds"))
Existing.Models = NewConfig.Models;
@@ -104,9 +105,12 @@ namespace OpenWifi {
GWObjects::DefaultConfiguration ModifiedConfig;
StorageService()->GetDefaultConfiguration(Name,ModifiedConfig);
return Object(ModifiedConfig);
Poco::JSON::Object Answer;
ModifiedConfig.to_json(Answer);
return ReturnObject(Answer);
}
BadRequest(RESTAPI::Errors::RecordNotUpdated);
}
}

View File

@@ -8,12 +8,12 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_default_configuration : public RESTAPIHandler {
public:
RESTAPI_default_configuration(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
RESTAPI_default_configuration(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,

View File

@@ -23,6 +23,16 @@ namespace OpenWifi {
std::vector<GWObjects::DefaultConfiguration> DefConfigs;
StorageService()->GetDefaultConfigurations(QB_.Offset, QB_.Limit, DefConfigs);
return Object(RESTAPI::Protocol::CONFIGURATIONS, DefConfigs);
Poco::JSON::Array Objects;
for (const auto &i : DefConfigs) {
Poco::JSON::Object Obj;
i.to_json(Obj);
Objects.add(Obj);
}
Poco::JSON::Object RetObj;
RetObj.set(RESTAPI::Protocol::CONFIGURATIONS, Objects);
ReturnObject(RetObj);
}
}

View File

@@ -8,12 +8,12 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_default_configurations : public RESTAPIHandler {
public:
RESTAPI_default_configurations(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
RESTAPI_default_configurations(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},

View File

@@ -8,11 +8,9 @@
namespace OpenWifi {
void RESTAPI_deviceDashboardHandler::DoGet() {
poco_information(Logger(),fmt::format("GET-DASHBOARD: {}", Requester()));
GWObjects::Dashboard Data;
if(Daemon()->GetDashboard().Get(Data, Logger())) {
return Object(Data);
}
return BadRequest(RESTAPI::Errors::InternalError);
Daemon()->GetDashboard().Create();
Poco::JSON::Object Answer;
Daemon()->GetDashboard().Report().to_json(Answer);
ReturnObject(Answer);
}
}

View File

@@ -4,12 +4,12 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_deviceDashboardHandler : public RESTAPIHandler {
public:
RESTAPI_deviceDashboardHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
RESTAPI_deviceDashboardHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,

View File

@@ -20,22 +20,15 @@
#include "StorageService.h"
#include "TelemetryStream.h"
#include "CommandManager.h"
#include "SignatureMgr.h"
#include "framework/ConfigurationValidator.h"
#include "framework/KafkaTopics.h"
#include "framework/ow_constants.h"
#include "framework/KafkaManager.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.h"
#include "rttys/RTTYS_server.h"
namespace OpenWifi {
void RESTAPI_device_commandHandler::CallCanceled(const char * Cmd, const OpenWifi::RESTAPI::Errors::msg &Err, const std::string & Details) {
poco_warning(Logger_,fmt::format("{},{}: TID={} Canceled. Error:{} Reason:{} Details={}", Cmd, SerialNumber_, TransactionId_, Err.err_num, Err.err_txt, Details));
Logger_.warning(fmt::format("{},{}: TID={} Canceled. Error:{} Reason:{} Details={}", Cmd, SerialNumber_, TransactionId_, Err.err_num, Err.err_txt, Details));
}
void RESTAPI_device_commandHandler::DoGet() {
@@ -52,40 +45,32 @@ namespace OpenWifi {
return NotFound();
}
auto Command = APCommands::to_apcommand(Command_.c_str());
if(Command==APCommands::Commands::unknown) {
return BadRequest(RESTAPI::Errors::InvalidCommand);
}
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
Poco::Thread::current()->setName(fmt::format("{}:{}:{}", Command_, TransactionId_, SerialNumber_));
switch(Command) {
case APCommands::Commands::capabilities:
return GetCapabilities();
case APCommands::Commands::logs:
return GetLogs();
case APCommands::Commands::healthchecks:
return GetChecks();
case APCommands::Commands::statistics:
return GetStatistics();
case APCommands::Commands::status:
return GetStatus();
case APCommands::Commands::rtty: {
GWObjects::DeviceRestrictions Restrictions;
if(!AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) {
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected);
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
}
auto UUID = MicroServiceCreateUUID();
auto RPC = CommandManager()->Next_RPC_ID();
poco_debug(Logger_,fmt::format("Command rtty TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
TransactionId_, UUID, RPC,
Poco::Thread::current()->id()));
return Rtty(UUID,RPC,60000ms, Restrictions);
};
default:
return BadRequest(RESTAPI::Errors::InvalidCommand);
if (Command_ == RESTAPI::Protocol::CAPABILITIES){
return GetCapabilities();
} else if (Command_ == RESTAPI::Protocol::LOGS) {
return GetLogs();
} else if (Command_ == RESTAPI::Protocol::HEALTHCHECKS) {
return GetChecks();
} else if (Command_ == RESTAPI::Protocol::STATISTICS) {
return GetStatistics();
} else if (Command_ == RESTAPI::Protocol::STATUS) {
return GetStatus();
} else if (Command_ == RESTAPI::Protocol::RTTY) {
if(!AP_WS_Server()->Connected(SerialNumberInt_)) {
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected);
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
}
auto UUID = MicroService::CreateUUID();
auto RPC = CommandManager()->NextRPCId();
poco_debug(Logger_,fmt::format("Command rtty TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
TransactionId_, UUID, RPC,
Poco::Thread::current()->id()));
return Rtty(UUID,RPC,60000ms);
} else {
return BadRequest(RESTAPI::Errors::InvalidCommand);
}
}
@@ -103,51 +88,48 @@ namespace OpenWifi {
return NotFound();
}
auto Command = APCommands::to_apcommand(Command_.c_str());
if(Command==APCommands::Commands::unknown) {
return BadRequest(RESTAPI::Errors::InvalidCommand);
}
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
Poco::Thread::current()->setName(fmt::format("{}:{}:{}",Command_, TransactionId_,SerialNumber_));
switch(Command) {
case APCommands::Commands::capabilities:
if (Command_ == RESTAPI::Protocol::CAPABILITIES) {
return DeleteCapabilities();
case APCommands::Commands::logs:
} else if (Command_ == RESTAPI::Protocol::LOGS){
return DeleteLogs();
case APCommands::Commands::healthchecks:
} else if (Command_ == RESTAPI::Protocol::HEALTHCHECKS){
return DeleteChecks();
case APCommands::Commands::statistics:
} else if (Command_ == RESTAPI::Protocol::STATISTICS) {
return DeleteStatistics();
default:
} else {
return BadRequest(RESTAPI::Errors::InvalidCommand);
}
}
struct PostDeviceCommand {
APCommands::Commands Command=APCommands::Commands::unknown;
bool AllowParallel=false;
bool RequireConnection = true;
void (RESTAPI_device_commandHandler::*funPtr)(const std::string &, std::uint64_t, std::chrono::milliseconds, const GWObjects::DeviceRestrictions &R );
const char * Command;
bool AllowParallel=false;
bool RequireConnection = true;
void (RESTAPI_device_commandHandler::*funPtr)(const std::string &, std::uint64_t, std::chrono::milliseconds );
std::chrono::milliseconds Timeout=120ms;
};
static const std::vector<PostDeviceCommand> PostCommands =
/*
const static std::vector<PostDeviceCommand> PostCommands
{
{ APCommands::Commands::configure, false, false, &RESTAPI_device_commandHandler::Configure, 120000ms },
{ APCommands::Commands::upgrade, false, false, &RESTAPI_device_commandHandler::Upgrade, 30000ms },
{ APCommands::Commands::reboot, false, true, &RESTAPI_device_commandHandler::Reboot, 30000ms },
{ APCommands::Commands::factory, false, false, &RESTAPI_device_commandHandler::Factory, 30000ms },
{ APCommands::Commands::leds, false, true, &RESTAPI_device_commandHandler::LEDs, 120000ms },
{ APCommands::Commands::trace, false, true, &RESTAPI_device_commandHandler::Trace, 300000ms },
{ APCommands::Commands::request, false, true, &RESTAPI_device_commandHandler::MakeRequest, 120000ms },
{ APCommands::Commands::wifiscan, false, true, &RESTAPI_device_commandHandler::WifiScan, 120000ms },
{ APCommands::Commands::eventqueue, false, true, &RESTAPI_device_commandHandler::EventQueue, 30000ms },
{ APCommands::Commands::telemetry, false, true, &RESTAPI_device_commandHandler::Telemetry, 30000ms },
{ APCommands::Commands::ping, false, true, &RESTAPI_device_commandHandler::Ping, 60000ms },
{ APCommands::Commands::script, false, true, &RESTAPI_device_commandHandler::Script, 300000ms }
};
{ RESTAPI::Protocol::PERFORM, false, true, &RESTAPI_device_commandHandler::ExecuteCommand },
{ RESTAPI::Protocol::CONFIGURE, false, false, &RESTAPI_device_commandHandler::Configure },
{ RESTAPI::Protocol::UPGRADE, false, false, &RESTAPI_device_commandHandler::Upgrade },
{ RESTAPI::Protocol::REBOOT, false, true, &RESTAPI_device_commandHandler::Reboot },
{ RESTAPI::Protocol::FACTORY, false, false, &RESTAPI_device_commandHandler::Factory },
{ RESTAPI::Protocol::LEDS, false, true, &RESTAPI_device_commandHandler::LEDs },
{ RESTAPI::Protocol::TRACE, false, true, &RESTAPI_device_commandHandler::Trace },
{ RESTAPI::Protocol::REQUEST, false, true, &RESTAPI_device_commandHandler::MakeRequest },
{ RESTAPI::Protocol::WIFISCAN, false, true, &RESTAPI_device_commandHandler::WifiScan },
{ RESTAPI::Protocol::EVENTQUEUE, false, true, &RESTAPI_device_commandHandler::EventQueue },
{ RESTAPI::Protocol::TELEMETRY, false, true, &RESTAPI_device_commandHandler::Telemetry },
{ RESTAPI::Protocol::PING, false, true, &RESTAPI_device_commandHandler::Ping },
{ RESTAPI::Protocol::SCRIPT, false, true, &RESTAPI_device_commandHandler::Script }
};
*/
void RESTAPI_device_commandHandler::DoPost() {
if(!ValidateParameters()) {
@@ -156,46 +138,55 @@ namespace OpenWifi {
if(!Utils::NormalizeMac(SerialNumber_)) {
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
}
auto Command = APCommands::to_apcommand(Command_.c_str());
if(Command==APCommands::Commands::unknown) {
return BadRequest(RESTAPI::Errors::InvalidCommand);
}
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
GWObjects::Device TheDevice;
if(!StorageService()->GetDevice(SerialNumber_,TheDevice)) {
return NotFound();
}
for(const auto &PostCommand:PostCommands) {
if(Command==PostCommand.Command) {
Poco::Thread::current()->setName(fmt::format("{}:{}:{}",Command_, TransactionId_,SerialNumber_));
GWObjects::DeviceRestrictions Restrictions;
if(PostCommand.RequireConnection && !AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) {
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected);
const std::vector<PostDeviceCommand> PostCommands =
{
{ RESTAPI::Protocol::PERFORM, false, true, &RESTAPI_device_commandHandler::ExecuteCommand, 120000ms },
{ RESTAPI::Protocol::CONFIGURE, false, false, &RESTAPI_device_commandHandler::Configure, 120000ms },
{ RESTAPI::Protocol::UPGRADE, false, false, &RESTAPI_device_commandHandler::Upgrade, 30000ms },
{ RESTAPI::Protocol::REBOOT, false, true, &RESTAPI_device_commandHandler::Reboot, 30000ms },
{ RESTAPI::Protocol::FACTORY, false, false, &RESTAPI_device_commandHandler::Factory, 30000ms },
{ RESTAPI::Protocol::LEDS, false, true, &RESTAPI_device_commandHandler::LEDs, 120000ms },
{ RESTAPI::Protocol::TRACE, false, true, &RESTAPI_device_commandHandler::Trace, 300000ms },
{ RESTAPI::Protocol::REQUEST, false, true, &RESTAPI_device_commandHandler::MakeRequest, 120000ms },
{ RESTAPI::Protocol::WIFISCAN, false, true, &RESTAPI_device_commandHandler::WifiScan, 120000ms },
{ RESTAPI::Protocol::EVENTQUEUE, false, true, &RESTAPI_device_commandHandler::EventQueue, 30000ms },
{ RESTAPI::Protocol::TELEMETRY, false, true, &RESTAPI_device_commandHandler::Telemetry, 30000ms },
{ RESTAPI::Protocol::PING, false, true, &RESTAPI_device_commandHandler::Ping, 60000ms },
{ RESTAPI::Protocol::SCRIPT, false, true, &RESTAPI_device_commandHandler::Script, 300000ms }
};
for(const auto &Command:PostCommands) {
if(Command_==Command.Command) {
Poco::Thread::current()->setName(fmt::format("{}:{}:{}",Command.Command, TransactionId_,SerialNumber_));
if(Command.RequireConnection && !AP_WS_Server()->Connected(SerialNumberInt_)) {
CallCanceled(Command.Command, RESTAPI::Errors::DeviceNotConnected);
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
}
std::string Command_UUID;
APCommands::Commands CommandName;
if(!PostCommand.AllowParallel && CommandManager()->CommandRunningForDevice(SerialNumberInt_,Command_UUID,CommandName)) {
auto Extra = fmt::format("UUID={} Command={}", Command_UUID, APCommands::to_string(CommandName));
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceIsAlreadyBusy, Extra);
std::string Command_UUID, CommandName;
if(!Command.AllowParallel && CommandManager()->CommandRunningForDevice(SerialNumberInt_,Command_UUID,CommandName)) {
auto Extra = fmt::format("UUID={} Command={}", Command_UUID, CommandName);
CallCanceled(Command.Command, RESTAPI::Errors::DeviceIsAlreadyBusy, Extra);
return BadRequest(RESTAPI::Errors::DeviceIsAlreadyBusy, Extra);
}
auto UUID = MicroServiceCreateUUID();
auto RPC = CommandManager()->Next_RPC_ID();
auto UUID = MicroService::CreateUUID();
auto RPC = CommandManager()->NextRPCId();
poco_debug(Logger_,fmt::format("Command {} TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
Command_, TransactionId_, UUID, RPC,
Command.Command, TransactionId_, UUID, RPC,
Poco::Thread::current()->id()));
return (*this.*PostCommand.funPtr)(UUID,RPC,PostCommand.Timeout, Restrictions);
return (*this.*Command.funPtr)(UUID,RPC,Command.Timeout);
}
}
return BadRequest(RESTAPI::Errors::InvalidCommand);
}
void RESTAPI_device_commandHandler::GetCapabilities() {
poco_information(Logger_,fmt::format("GET-CAPABILITIES: TID={} user={} serial={}. thr_id={}",
Logger_.information(fmt::format("GET-CAPABILITIES: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
GWObjects::Capabilities Caps;
@@ -209,7 +200,7 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::DeleteCapabilities() {
poco_information(Logger_,fmt::format("DELETE-CAPABILITIES: TID={} user={} serial={}. thr_id={}",
Logger_.information(fmt::format("DELETE-CAPABILITIES: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
if (StorageService()->DeleteDeviceCapabilities(SerialNumber_)) {
@@ -219,45 +210,35 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::GetStatistics() {
std::string StatsType = QB_.LastOnly ? "LastOnly" : ( QB_.Newest ? "Newest" :
( QB_.CountOnly ? "CountOnly" : "Timed"));
poco_information(Logger_,fmt::format("GET-STATISTICS: TID={} user={} serial={}. thr_id={}, TYPE={}",
Logger_.information(fmt::format("GET-STATISTICS: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id(),StatsType));
Poco::Thread::current()->id()));
if (QB_.LastOnly) {
std::string Stats;
if (AP_WS_Server()->GetStatistics(SerialNumber_, Stats) && !Stats.empty()) {
return ReturnRawJSON(Stats);
if (AP_WS_Server()->GetStatistics(SerialNumber_, Stats)) {
Poco::JSON::Parser P;
if (Stats.empty())
Stats = uCentralProtocol::EMPTY_JSON_DOC;
auto Obj = P.parse(Stats).extract<Poco::JSON::Object::Ptr>();
return ReturnObject(*Obj);
}
if(AP_WS_Server()->Connected(SerialNumberInt_)) {
return BadRequest(RESTAPI::Errors::NoDeviceStatisticsYet);
}
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
return NotFound();
}
std::vector<GWObjects::Statistics> Stats;
if (QB_.Newest) {
StorageService()->GetNewestStatisticsData(SerialNumber_, QB_.Limit, Stats);
} else {
if(QB_.CountOnly) {
std::uint64_t Count = 0 ;
StorageService()->GetNumberOfStatisticsDataRecords(SerialNumber_, QB_.StartDate, QB_.EndDate,Count);
return ReturnCountOnly(Count);
}
if(QB_.Limit>100)
QB_.Limit=100;
StorageService()->GetStatisticsData(SerialNumber_, QB_.StartDate, QB_.EndDate,
QB_.Offset, QB_.Limit, Stats);
}
Poco::JSON::Array::Ptr ArrayObj = Poco::SharedPtr<Poco::JSON::Array>(new Poco::JSON::Array);
Poco::JSON::Array ArrayObj;
for (const auto &i : Stats) {
Poco::JSON::Object::Ptr Obj = Poco::SharedPtr<Poco::JSON::Object>(new Poco::JSON::Object);
i.to_json(*Obj);
ArrayObj->add(Obj);
Poco::JSON::Object Obj;
i.to_json(Obj);
ArrayObj.add(Obj);
}
Poco::JSON::Object RetObj;
RetObj.set(RESTAPI::Protocol::DATA, ArrayObj);
RetObj.set(RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
@@ -266,7 +247,7 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::DeleteStatistics() {
poco_information(Logger_,fmt::format("DELETE-STATISTICS: TID={} user={} serial={}. thr_id={}",
Logger_.information(fmt::format("DELETE-STATISTICS: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
if (StorageService()->DeleteStatisticsData(SerialNumber_, QB_.StartDate, QB_.EndDate)) {
@@ -276,7 +257,7 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::GetStatus() {
poco_information(Logger_,fmt::format("GET-STATUS: TID={} user={} serial={}. thr_id={}",
Logger_.information(fmt::format("GET-STATUS: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
GWObjects::ConnectionState State;
@@ -294,7 +275,7 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::GetLogs() {
poco_information(Logger_,fmt::format("GET-LOGS: TID={} user={} serial={}. thr_id={}",
Logger_.information(fmt::format("GET-LOGS: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
std::vector<GWObjects::DeviceLog> Logs;
@@ -318,7 +299,7 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::DeleteLogs() {
poco_information(Logger_,fmt::format("DELETE-LOGS: TID={} user={} serial={}. thr_id={}",
Logger_.information(fmt::format("DELETE-LOGS: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
if (StorageService()->DeleteLogData(SerialNumber_, QB_.StartDate, QB_.EndDate,
@@ -329,10 +310,12 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::GetChecks() {
poco_information(Logger_,fmt::format("GET-HEALTHCHECKS: TID={} user={} serial={}. thr_id={}",
Logger_.information(fmt::format("GET-HEALTHCHECKS: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
std::vector<GWObjects::HealthCheck> Checks;
if (QB_.LastOnly) {
GWObjects::HealthCheck HC;
if (AP_WS_Server()->GetHealthcheck(SerialNumber_, HC)) {
@@ -343,7 +326,6 @@ namespace OpenWifi {
return NotFound();
}
} else {
std::vector<GWObjects::HealthCheck> Checks;
if (QB_.Newest) {
StorageService()->GetNewestHealthCheckData(SerialNumber_, QB_.Limit, Checks);
} else {
@@ -366,7 +348,7 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::DeleteChecks() {
poco_information(Logger_,fmt::format("DELETE-HEALTHCHECKS: TID={} user={} serial={}. thr_id={}",
Logger_.information(fmt::format("DELETE-HEALTHCHECKS: TID={} user={} serial={}. thr_id={}",
TransactionId_, Requester(), SerialNumber_,
Poco::Thread::current()->id()));
if (StorageService()->DeleteHealthCheckData(SerialNumber_, QB_.StartDate, QB_.EndDate)) {
@@ -375,8 +357,8 @@ namespace OpenWifi {
BadRequest(RESTAPI::Errors::NoRecordsDeleted);
}
void RESTAPI_device_commandHandler::Ping(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("PING({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Ping(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("PING({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
@@ -399,7 +381,7 @@ namespace OpenWifi {
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::ping,false,Cmd, Params, *Request, *Response, timeout, nullptr, nullptr, Logger_);
RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, nullptr, Logger_);
GWObjects::CommandDetails Cmd2;
if(StorageService()->GetCommand(CMD_UUID,Cmd2)) {
@@ -428,15 +410,15 @@ namespace OpenWifi {
}
void RESTAPI_device_commandHandler::CallCanceled(const char * Cmd, const std::string &UUID, uint64_t RPC, const OpenWifi::RESTAPI::Errors::msg &Err) {
poco_warning(Logger_,fmt::format("{}({},{}): Canceled. Error:{} Reason:{}", Cmd, UUID, RPC, Err.err_num, Err.err_txt));
Logger_.warning(fmt::format("{}({},{}): Canceled. Error:{} Reason:{}", Cmd, UUID, RPC, Err.err_num, Err.err_txt));
}
static bool ValidateScriptType(const std::string &t) {
return t=="shell" || t=="bundle";
}
void RESTAPI_device_commandHandler::Script(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("SCRIPT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Script(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("SCRIPT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
if(!Internal_ && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
const auto &Obj = ParsedBody_;
GWObjects::ScriptRequest SCR;
@@ -445,25 +427,13 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
bool DiagnosticScript = (SCR.type=="diagnostic");
if(!SCR.script.empty() && !SCR.scriptId.empty()) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::InvalidScriptSelection);
return UnAuthorized(RESTAPI::Errors::InvalidScriptSelection);
}
if(!Internal_ && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && SCR.scriptId.empty()) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if (SCR.script.empty() && SCR.scriptId.empty() && !DiagnosticScript) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::InvalidScriptSelection);
return BadRequest(RESTAPI::Errors::InvalidScriptSelection);
}
if(DiagnosticScript && (!SCR.scriptId.empty() || !SCR.script.empty())){
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::InvalidScriptSelection);
return BadRequest(RESTAPI::Errors::InvalidScriptSelection);
if (SCR.serialNumber.empty() ||
SCR.script.empty() ||
SCR.type.empty() ||
SCR.scriptId.empty() ||
(SCR.type!="shell" && SCR.type!="ucode")) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::MissingOrInvalidParameters);
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if (SerialNumber_ != SCR.serialNumber) {
@@ -471,50 +441,6 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
}
if(!SCR.uri.empty() && !Utils::ValidateURI(SCR.uri)) {
return BadRequest(RESTAPI::Errors::InvalidURI);
}
GWObjects::Device D;
if(!StorageService()->GetDevice(SerialNumber_,D)) {
return NotFound();
}
if(!SCR.scriptId.empty()) {
GWObjects::ScriptEntry Existing;
if(!StorageService()->ScriptDB().GetRecord("id",SCR.scriptId,Existing)) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::MissingOrInvalidParameters);
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
// verify the role...
if(Existing.restricted.empty() && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
if (std::find(Existing.restricted.begin(), Existing.restricted.end(),
SecurityObjects::UserTypeToString(UserInfo_.userinfo.userRole)) ==
end(Existing.restricted)) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
}
poco_information(Logger_,fmt::format("SCRIPT({},{}): TID={} Name={}", CMD_UUID, CMD_RPC, TransactionId_, Existing.name));
SCR.script = Existing.content;
SCR.type = Existing.type;
if(!ParsedBody_->has("deferred"))
SCR.deferred = Existing.deferred;
if(!ParsedBody_->has("timeout"))
SCR.timeout = Existing.timeout;
} else {
if(!DiagnosticScript && !ValidateScriptType(SCR.type)) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::MissingOrInvalidParameters);
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
}
uint64_t ap_timeout = SCR.timeout==0 ? 30 : SCR.timeout;
GWObjects::CommandDetails Cmd;
@@ -523,50 +449,23 @@ namespace OpenWifi {
Cmd.SubmittedBy = Requester();
Cmd.Command = uCentralProtocol::SCRIPT;
Cmd.RunAt = 0;
Cmd.WaitingForFile = SCR.deferred ? 1 : 0;
Poco::JSON::Object Params;
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
if(SCR.deferred && SCR.uri.empty()) {
SCR.uri = FileUploader()->FullName() + CMD_UUID ;
}
if(SCR.deferred) {
Params.set(uCentralProtocol::URI, SCR.uri);
} else {
Params.set(uCentralProtocol::TIMEOUT, ap_timeout);
}
if(!SCR.signature.empty()) {
Params.set(uCentralProtocol::SIGNATURE, SCR.signature);
}
if(D.restrictedDevice && SCR.signature.empty()) {
SCR.signature = SignatureManager()->Sign(R, SCR.script);
}
if(D.restrictedDevice && SCR.signature.empty()) {
return BadRequest(RESTAPI::Errors::DeviceRequiresSignature);
}
// convert script to base64 ...
auto EncodedScript = Utils::base64encode((const unsigned char *)SCR.script.c_str(),SCR.script.size());
Params.set(uCentralProtocol::TIMEOUT, ap_timeout);
Params.set(uCentralProtocol::TYPE, SCR.type);
if(!DiagnosticScript) {
Params.set(uCentralProtocol::SCRIPT, EncodedScript);
}
Params.set(uCentralProtocol::SCRIPT, SCR.script);
Params.set(uCentralProtocol::WHEN, SCR.when);
std::stringstream ParamStream;
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
FileUploader()->AddUUID(CMD_UUID, 15min, "script_result");
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::script,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
void RESTAPI_device_commandHandler::Configure(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("CONFIGURE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Configure(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("CONFIGURE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
@@ -610,15 +509,15 @@ namespace OpenWifi {
Cmd.Details = ParamStream.str();
// AP_WS_Server()->SetPendingUUID(SerialNumber_, NewUUID);
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::configure,true,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
return RESTAPI_RPC::WaitForCommand(CMD_RPC,true,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
return BadRequest(RESTAPI::Errors::RecordNotUpdated);
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::Upgrade(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("UPGRADE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Upgrade(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("UPGRADE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -631,12 +530,6 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
}
GWObjects::Device DeviceInfo;
if(!StorageService()->GetDevice(SerialNumber_,DeviceInfo)) {
return NotFound();
}
std::string FWSignature = GetParameter("FWsignature","");
auto URI = GetS(RESTAPI::Protocol::URI, Obj);
auto When = GetWhen(Obj);
@@ -655,33 +548,68 @@ namespace OpenWifi {
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
Params.set(uCentralProtocol::URI, URI);
Params.set(uCentralProtocol::KEEP_REDIRECTOR, KeepRedirector ? 1 : 0);
if(DeviceInfo.restrictionDetails.upgrade && FWSignature.empty()) {
Poco::URI uri(URI);
FWSignature = SignatureManager()->Sign(DeviceInfo.restrictionDetails,uri);
}
if(FWSignature.empty() && DeviceInfo.restrictionDetails.upgrade) {
return BadRequest(RESTAPI::Errors::DeviceRequiresSignature);
}
if(!FWSignature.empty()) {
Params.set(uCentralProtocol::SIGNATURE, FWSignature);
}
Params.set(uCentralProtocol::WHEN, When);
std::stringstream ParamStream;
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::upgrade,true,Cmd,Params, *Request, *Response, timeout, nullptr, this, Logger_);
return RESTAPI_RPC::WaitForCommand(CMD_RPC,true,Cmd,Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::Reboot(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("REBOOT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::ExecuteCommand(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("EXECUTE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
if (Obj->has(RESTAPI::Protocol::COMMAND) &&
Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
Obj->has(RESTAPI::Protocol::PAYLOAD)) {
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
if (SerialNumber_ != SNum) {
CallCanceled("EXECUTE", CMD_UUID, CMD_RPC,RESTAPI::Errors::SerialNumberMismatch);
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
}
auto Command = GetS(RESTAPI::Protocol::COMMAND, Obj);
auto Payload = GetS(RESTAPI::Protocol::PAYLOAD, Obj);
auto When = GetWhen(Obj);
GWObjects::CommandDetails Cmd;
Cmd.SerialNumber = SerialNumber_;
Cmd.UUID = CMD_UUID;
Cmd.SubmittedBy = Requester();
Cmd.Command = Command;
Cmd.Custom = 1;
Cmd.RunAt = When;
Poco::JSON::Parser parser2;
Poco::Dynamic::Var result = parser2.parse(Payload);
const auto &PayloadObject = result.extract<Poco::JSON::Object::Ptr>();
Poco::JSON::Object Params;
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
Params.set(uCentralProtocol::COMMAND, Command);
Params.set(uCentralProtocol::WHEN, When);
Params.set(uCentralProtocol::PAYLOAD, PayloadObject);
std::stringstream ParamStream;
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::Reboot(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("REBOOT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -709,13 +637,13 @@ namespace OpenWifi {
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::reboot, false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
BadRequest(RESTAPI::Errors::MissingSerialNumber);
}
void RESTAPI_device_commandHandler::Factory(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("FACTORY-RESET({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Factory(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("FACTORY-RESET({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
if (Obj->has(RESTAPI::Protocol::KEEPREDIRECTOR) &&
@@ -749,13 +677,13 @@ namespace OpenWifi {
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::factory,true,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
return RESTAPI_RPC::WaitForCommand(CMD_RPC,true,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::LEDs(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("LEDS({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::LEDs(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("LEDS({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -797,13 +725,13 @@ namespace OpenWifi {
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::leds,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::Trace(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("TRACE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Trace(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("TRACE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -849,14 +777,14 @@ namespace OpenWifi {
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
FileUploader()->AddUUID(CMD_UUID, 10min, "trace");
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::trace,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
FileUploader()->AddUUID(CMD_UUID);
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::WifiScan(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("WIFISCAN({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::WifiScan(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("WIFISCAN({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
@@ -884,11 +812,6 @@ namespace OpenWifi {
Poco::JSON::Object Params;
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
if(R.dfs && OverrideDFS) {
return BadRequest(RESTAPI::Errors::DeviceIsRestricted);
}
Params.set(uCentralProtocol::OVERRIDEDFS, OverrideDFS);
Params.set(uCentralProtocol::ACTIVE, ActiveScan);
if(ies)
@@ -899,14 +822,14 @@ namespace OpenWifi {
std::stringstream ParamStream;
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::wifiscan,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
if (Cmd.ErrorCode == 0) {
KafkaManager()->PostMessage(KafkaTopics::WIFISCAN, SerialNumber_, Cmd.Results);
}
}
void RESTAPI_device_commandHandler::EventQueue(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("EVENT-QUEUE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::EventQueue(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("EVENT-QUEUE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
@@ -934,7 +857,7 @@ namespace OpenWifi {
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::eventqueue,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
if(Cmd.ErrorCode==0) {
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, SerialNumber_,
Cmd.Results);
@@ -944,8 +867,8 @@ namespace OpenWifi {
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::MakeRequest(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("FORCE-REQUEST({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::MakeRequest(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("FORCE-REQUEST({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
@@ -981,45 +904,47 @@ namespace OpenWifi {
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::request,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_ );
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_ );
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
#define DBGLINE { std::cout << __LINE__ << std::endl; }
void RESTAPI_device_commandHandler::Rtty(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
Logger_.information(fmt::format("RTTY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Rtty(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("RTTY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
if(R.rtty) {
return BadRequest(RESTAPI::Errors::DeviceIsRestricted);
}
if (MicroServiceConfigGetBool("rtty.enabled", false)) {
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
if (MicroService::instance().ConfigGetBool("rtty.enabled", false)) {
GWObjects::Device Device;
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
if (StorageService()->GetDevice(SerialNumber_, Device)) {
static std::uint64_t rtty_sid = 0;
rtty_sid += std::rand();
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
GWObjects::RttySessionDetails Rtty{
.SerialNumber = SerialNumber_,
.Server = MicroServiceConfigGetString("rtty.server", "localhost"),
.Port = MicroServiceConfigGetInt("rtty.port", 5912),
.Token = MicroServiceConfigGetString("rtty.token", "nothing"),
.TimeOut = MicroServiceConfigGetInt("rtty.timeout", 60),
.ConnectionId = Utils::ComputeHash(SerialNumber_,Utils::Now(),rtty_sid).substr(0,RTTY_DEVICE_TOKEN_LENGTH),
.Started = Utils::Now(),
.Server = MicroService::instance().ConfigGetString("rtty.server", "localhost"),
.Port = MicroService::instance().ConfigGetInt("rtty.port", 5912),
.Token = MicroService::instance().ConfigGetString("rtty.token", "nothing"),
.TimeOut = MicroService::instance().ConfigGetInt("rtty.timeout", 60),
.ConnectionId = Utils::ComputeHash(SerialNumber_,OpenWifi::Now()).substr(0,32),
.Started = OpenWifi::Now(),
.CommandUUID = CMD_UUID,
.ViewPort = MicroServiceConfigGetInt("rtty.viewport", 5913),
.ViewPort = MicroService::instance().ConfigGetInt("rtty.viewport", 5913),
.DevicePassword = ""
};
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
if(RTTYS_server()->UseInternal()) {
Rtty.Token = Utils::ComputeHash(UserInfo_.webtoken.refresh_token_,Utils::Now()).substr(0,RTTY_DEVICE_TOKEN_LENGTH);
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
Rtty.Token = Utils::ComputeHash(UserInfo_.webtoken.refresh_token_,OpenWifi::Now()).substr(0,32);
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
if(!RTTYS_server()->CreateEndPoint(Rtty.ConnectionId, Rtty.Token, Requester(), SerialNumber_)) {
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
return BadRequest(RESTAPI::Errors::MaximumRTTYSessionsReached);
}
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
}
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
Poco::JSON::Object ReturnedObject;
Rtty.to_json(ReturnedObject);
@@ -1031,6 +956,7 @@ namespace OpenWifi {
Cmd.UUID = CMD_UUID;
Cmd.Command = uCentralProtocol::RTTY;
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
Poco::JSON::Object Params;
Params.set(uCentralProtocol::METHOD, uCentralProtocol::RTTY);
@@ -1043,23 +969,27 @@ namespace OpenWifi {
Params.set(uCentralProtocol::TIMEOUT, Rtty.TimeOut);
Params.set(uCentralProtocol::PASSWORD, Device.DevicePassword);
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
std::stringstream ParamStream;
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
Params.stringify(ParamStream);
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
Cmd.Details = ParamStream.str();
poco_information(Logger_,fmt::format("RTTY: user={} serial={} rttyid={} token={} cmd={}.", Requester(), SerialNumber_, Rtty.ConnectionId, Rtty.Token, CMD_UUID));
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::rtty,false,Cmd, Params, *Request, *Response, timeout, &ReturnedObject, this, Logger_);
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
Logger_.information(fmt::format("RTTY: user={} serial={} rttyid={} token={} cmd={}.", Requester(), SerialNumber_, Rtty.ConnectionId, Rtty.Token, CMD_UUID));
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, &ReturnedObject, this, Logger_);
}
return NotFound();
}
poco_information(Logger_,fmt::format("RTTY: user={} serial={}. Internal error.", Requester(), SerialNumber_));
Logger_.information(fmt::format("RTTY: user={} serial={}. Internal error.", Requester(), SerialNumber_));
return ReturnStatus(Poco::Net::HTTPResponse::HTTP_SERVICE_UNAVAILABLE);
}
void RESTAPI_device_commandHandler::Telemetry(const std::string &CMD_UUID, uint64_t CMD_RPC, [[maybe_unused]] std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R){
poco_information(Logger_,fmt::format("TELEMETRY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
void RESTAPI_device_commandHandler::Telemetry(const std::string &CMD_UUID, uint64_t CMD_RPC, [[maybe_unused]] std::chrono::milliseconds timeout){
Logger_.information(fmt::format("TELEMETRY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
Obj->has(RESTAPI::Protocol::INTERVAL) &&
Obj->has(RESTAPI::Protocol::TYPES)) {
@@ -1072,9 +1002,10 @@ namespace OpenWifi {
std::stringstream oooss;
Obj->stringify(oooss);
// std::cout << "Payload:" << oooss.str() << std::endl;
std::uint64_t Lifetime = 60 * 60 ; // 1 hour
std::uint64_t Interval = 5;
uint64_t Lifetime = 60 * 60 ; // 1 hour
uint64_t Interval = 5;
bool KafkaOnly = false;
if(Obj->has("kafka")) {
@@ -1102,7 +1033,7 @@ namespace OpenWifi {
}
} else {
if (Interval) {
AP_WS_Server()->SetWebSocketTelemetryReporting(CMD_RPC, IntSerialNumber, Interval,
AP_WS_Server()->SetWebSocketTelemetryReporting(CMD_RPC,IntSerialNumber, Interval,
Lifetime);
std::string EndPoint;
if (TelemetryStream()->CreateEndpoint(Utils::SerialNumberToInt(SerialNumber_), EndPoint, CMD_UUID)) {
@@ -1123,7 +1054,7 @@ namespace OpenWifi {
}
bool TelemetryRunning;
std::uint64_t TelemetryWebSocketCount, TelemetryKafkaCount, TelemetryInterval,
uint64_t TelemetryWebSocketCount, TelemetryKafkaCount, TelemetryInterval,
TelemetryWebSocketTimer, TelemetryKafkaTimer, TelemetryWebSocketPackets,
TelemetryKafkaPackets;
AP_WS_Server()->GetTelemetryParameters(IntSerialNumber,TelemetryRunning,

View File

@@ -8,13 +8,13 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "RESTObjects/RESTAPI_GWobjects.h"
#include "framework/MicroService.h"
#include "framework/ow_constants.h"
namespace OpenWifi {
class RESTAPI_device_commandHandler : public RESTAPIHandler {
public:
RESTAPI_device_commandHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
RESTAPI_device_commandHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
@@ -33,20 +33,20 @@ namespace OpenWifi {
void GetStatus();
void GetChecks();
void DeleteChecks();
void Configure(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Upgrade(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Reboot(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Factory(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void LEDs(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Trace(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void MakeRequest(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void WifiScan(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void EventQueue(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Rtty(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Telemetry(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Ping(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Script(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void ExecuteCommand(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Configure(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Upgrade(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Reboot(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Factory(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void LEDs(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Trace(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void MakeRequest(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void WifiScan(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void EventQueue(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Rtty(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Telemetry(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Ping(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
void Script(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
static auto PathName() { return std::list<std::string>{"/api/v1/device/{serialNumber}/{command}"}; };
void DoGet() final;

View File

@@ -9,12 +9,11 @@
#include "RESTAPI_device_handler.h"
#include "CentralConfig.h"
#include "ConfigurationCache.h"
#include "Poco/JSON/Parser.h"
#include "StorageService.h"
#include "framework/ConfigurationValidator.h"
#include "framework/MicroService.h"
#include "framework/ow_constants.h"
#include "framework/utils.h"
#include "RESTAPI_device_helper.h"
namespace OpenWifi {
@@ -32,7 +31,9 @@ namespace OpenWifi {
CompleteDeviceInfo(Device, Answer);
return ReturnObject(Answer);
} else {
return Object(Device);
Poco::JSON::Object Obj;
Device.to_json(Obj);
return ReturnObject(Obj);
}
}
NotFound();
@@ -105,6 +106,11 @@ namespace OpenWifi {
return ReturnObject(Answer);
}
if (!Utils::ValidSerialNumber(SerialNumber)) {
Logger_.warning(fmt::format("CREATE-DEVICE({}): Illegal serial number.", SerialNumber));
return BadRequest( RESTAPI::Errors::InvalidSerialNumber);
}
GWObjects::Device Device;
if (!Device.from_json(Obj)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
@@ -125,11 +131,11 @@ namespace OpenWifi {
for(auto &i:Device.Notes) {
i.createdBy = UserInfo_.userinfo.email;
i.created = Utils::Now();
i.created = OpenWifi::Now();
}
Config::Config NewConfig(Device.Configuration);
Device.UUID = Utils::Now();
Device.UUID = OpenWifi::Now();
NewConfig.SetUUID(Device.UUID);
Device.Configuration = NewConfig.get();
@@ -137,7 +143,9 @@ namespace OpenWifi {
if (StorageService()->CreateDevice(Device)) {
SetCurrentConfigurationID(SerialNumber, Device.UUID);
return Object(Device);
Poco::JSON::Object DevObj;
Device.to_json(DevObj);
return ReturnObject(DevObj);
}
InternalError(RESTAPI::Errors::RecordNotCreated);
}
@@ -166,7 +174,7 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
}
Config::Config NewConfig(NewDevice.Configuration);
uint64_t NewConfigUUID = Utils::Now();
uint64_t NewConfigUUID = OpenWifi::Now();
NewConfig.SetUUID(NewConfigUUID);
Existing.Configuration = NewConfig.get();
Existing.UUID = NewConfigUUID;
@@ -180,16 +188,16 @@ namespace OpenWifi {
for(auto &i:NewDevice.Notes) {
i.createdBy = UserInfo_.userinfo.email;
i.created = Utils::Now();
i.created = OpenWifi::Now();
Existing.Notes.push_back(i);
}
Existing.LastConfigurationChange = Utils::Now();
Existing.LastConfigurationChange = OpenWifi::Now();
if (StorageService()->UpdateDevice(Existing)) {
SetCurrentConfigurationID(SerialNumber, Existing.UUID);
GWObjects::Device UpdatedDevice;
StorageService()->GetDevice(SerialNumber, UpdatedDevice);
return Object(UpdatedDevice);
Poco::JSON::Object DevObj;
NewDevice.to_json(DevObj);
return ReturnObject(DevObj);
}
InternalError(RESTAPI::Errors::RecordNotUpdated);
}

View File

@@ -8,12 +8,14 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_device_handler : public RESTAPIHandler {
public:
RESTAPI_device_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
RESTAPI_device_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,

View File

@@ -12,6 +12,7 @@
#include "RESTAPI_devices_handler.h"
#include "StorageService.h"
#include "framework/ow_constants.h"
#include "framework/MicroService.h"
#include "RESTAPI/RESTAPI_device_helper.h"
#include "Poco/StringTokenizer.h"
#include "framework/orm.h"
@@ -26,7 +27,7 @@ namespace OpenWifi {
std::string ItemList;
Types::StringVec Fields;
Storage::GetDeviceDbFieldList(Fields);
StorageService()->GetDeviceDbFieldList(Fields);
std::set<std::string> FieldNames;
for(const auto &field:Fields)
@@ -68,7 +69,7 @@ namespace OpenWifi {
if(GetBoolParameter("orderSpec")) {
Types::StringVec Fields;
Storage::GetDeviceDbFieldList(Fields);
StorageService()->GetDeviceDbFieldList(Fields);
std::sort(Fields.begin(),Fields.end());
Poco::JSON::Object Answer;
RESTAPI_utils::field_to_json(Answer,"list",Fields);

View File

@@ -8,12 +8,12 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_devices_handler : public RESTAPIHandler {
public:
RESTAPI_devices_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
RESTAPI_devices_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},

View File

@@ -25,12 +25,7 @@ namespace OpenWifi {
if (!StorageService()->GetAttachedFileContent(UUID, SerialNumber, FileContent, FileType)) {
return NotFound();
}
if(FileType=="pcap")
SendFileContent(FileContent,"application/vnd.tcpdump.pcap",UUID+".pcap");
else if(FileType=="gzip")
SendFileContent(FileContent,"application/gzip",UUID+".tar.gz");
else
SendFileContent(FileContent,"application/txt",UUID+".txt");
SendFileContent(FileContent,"pcap",UUID+".pcap");
}
void RESTAPI_file::DoDelete() {

View File

@@ -8,12 +8,12 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_file : public RESTAPIHandler {
public:
RESTAPI_file(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
RESTAPI_file(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_DELETE,

View File

@@ -4,12 +4,12 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_iptocountry_handler : public RESTAPIHandler {
public:
RESTAPI_iptocountry_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
RESTAPI_iptocountry_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},

View File

@@ -4,12 +4,12 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_ouis : public RESTAPIHandler {
public:
RESTAPI_ouis(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal)
RESTAPI_ouis(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,

View File

@@ -9,18 +9,14 @@
namespace OpenWifi {
void RESTAPI_radiusProxyConfig_handler::DoGet() {
Logger_.information(fmt::format("GET-RADIUS-PROXY-CONFIG: TID={} user={} thr_id={}",
TransactionId_, Requester(),
Poco::Thread::current()->id()));
GWObjects::RadiusProxyPoolList C;
RADIUS_proxy_server()->GetConfig(C);
return Object(C);
Poco::JSON::Object Answer;
C.to_json(Answer);
return ReturnObject(Answer);
}
void RESTAPI_radiusProxyConfig_handler::DoDelete() {
Logger_.information(fmt::format("DELETE-RADIUS-PROXY-CONFIG: TID={} user={} thr_id={}",
TransactionId_, Requester(),
Poco::Thread::current()->id()));
if(!Internal_ && (UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN)) {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
@@ -29,9 +25,7 @@ namespace OpenWifi {
}
void RESTAPI_radiusProxyConfig_handler::DoPut() {
Logger_.information(fmt::format("MODIFY-RADIUS-PROXY-CONFIG: TID={} user={} thr_id={}",
TransactionId_, Requester(),
Poco::Thread::current()->id()));
if(!Internal_ && (UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN)) {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
@@ -71,11 +65,8 @@ namespace OpenWifi {
}
}
Logger_.information(fmt::format("MODIFY-RADIUS-PROXY-CONFIG: TID={} user={} thr_id={}. Applying new RADIUS Proxy config.",
TransactionId_, Requester(),
Poco::Thread::current()->id()));
RADIUS_proxy_server()->SetConfig(C);
return Object(C);
return ReturnObject(*ParsedBody_);
}
}

View File

@@ -4,13 +4,13 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_radiusProxyConfig_handler : public RESTAPIHandler {
public:
RESTAPI_radiusProxyConfig_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
RESTAPI_GenericServer &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,

View File

@@ -2,6 +2,8 @@
// Created by stephane bourque on 2021-10-23.
//
#include "framework/MicroService.h"
#include "RESTAPI/RESTAPI_blacklist.h"
#include "RESTAPI/RESTAPI_blacklist_list.h"
#include "RESTAPI/RESTAPI_command.h"
@@ -18,17 +20,11 @@
#include "RESTAPI/RESTAPI_telemetryWebSocket.h"
#include "RESTAPI/RESTAPI_iptocountry_handler.h"
#include "RESTAPI/RESTAPI_radiusProxyConfig_handler.h"
#include "RESTAPI/RESTAPI_script_handler.h"
#include "RESTAPI/RESTAPI_scripts_handler.h"
#include "framework/RESTAPI_SystemCommand.h"
#include "framework/RESTAPI_WebSocketServer.h"
#include "framework/RESTAPI_SystemConfiguration.h"
namespace OpenWifi {
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t TransactionId) {
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
return RESTAPI_Router<
RESTAPI_devices_handler,
@@ -41,20 +37,17 @@ namespace OpenWifi {
RESTAPI_ouis,
RESTAPI_file,
RESTAPI_system_command,
RESTAPI_system_configuration,
RESTAPI_deviceDashboardHandler,
RESTAPI_webSocketServer,
RESTAPI_blacklist,
RESTAPI_blacklist_list,
RESTAPI_iptocountry_handler,
RESTAPI_radiusProxyConfig_handler,
RESTAPI_scripts_handler,
RESTAPI_script_handler,
RESTAPI_capabilities_handler, RESTAPI_telemetryWebSocket>(Path,Bindings,L, S, TransactionId);
}
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t TransactionId) {
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
return RESTAPI_Router_I<
RESTAPI_devices_handler,
@@ -69,8 +62,6 @@ namespace OpenWifi {
RESTAPI_blacklist,
RESTAPI_iptocountry_handler,
RESTAPI_radiusProxyConfig_handler,
RESTAPI_scripts_handler,
RESTAPI_script_handler,
RESTAPI_blacklist_list>(Path,Bindings,L, S, TransactionId);
}
}

View File

@@ -1,160 +0,0 @@
//
// Created by stephane bourque on 2022-11-21.
//
#include "RESTAPI_script_handler.h"
namespace OpenWifi {
void RESTAPI_script_handler::DoGet() {
std::string UUID = GetBinding("uuid","");
if(UUID.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
GWObjects::ScriptEntry SE;
if(DB_.GetRecord("id",UUID, SE)) {
return Object(SE);
}
return NotFound();
}
void RESTAPI_script_handler::DoDelete() {
std::string UUID = GetBinding("uuid","");
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
return BadRequest(RESTAPI::Errors::ACCESS_DENIED);
}
if(UUID.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(DB_.DeleteRecord("id",UUID)) {
return OK();
}
return NotFound();
}
void RESTAPI_script_handler::DoPost() {
std::string UUID = GetBinding("uuid","");
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
return BadRequest(RESTAPI::Errors::ACCESS_DENIED);
}
if(UUID.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
GWObjects::ScriptEntry SE;
if(!SE.from_json(ParsedBody_)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if( SE.name.empty() ||
SE.author.empty() ||
(SE.type!="bundle" && SE.type!="shell") ||
SE.content.empty() ||
SE.version.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(!SE.restricted.empty()) {
for(const auto &role:SE.restricted) {
if(SecurityObjects::UserTypeFromString(role)==SecurityObjects::UNKNOWN) {
return BadRequest(RESTAPI::Errors::InvalidUserRole);
}
}
std::sort(SE.restricted.begin(),SE.restricted.end());
}
if(!SE.uri.empty() && !Utils::ValidateURI(SE.uri)) {
return BadRequest(RESTAPI::Errors::InvalidURI);
}
if(!SE.defaultUploadURI.empty() && !Utils::ValidateURI(SE.defaultUploadURI)) {
return BadRequest(RESTAPI::Errors::InvalidURI);
}
SE.id = MicroServiceCreateUUID();
SE.created = SE.modified = Utils::Now();
if(DB_.CreateRecord(SE)) {
return Object(SE);
}
return BadRequest(RESTAPI::Errors::RecordNotCreated);
}
void RESTAPI_script_handler::DoPut() {
std::string UUID = GetBinding("uuid","");
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
return BadRequest(RESTAPI::Errors::ACCESS_DENIED);
}
if(UUID.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
GWObjects::ScriptEntry SE;
if(!SE.from_json(ParsedBody_)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(!SE.restricted.empty()) {
for(const auto &role:SE.restricted) {
if(SecurityObjects::UserTypeFromString(role)==SecurityObjects::UNKNOWN) {
return BadRequest(RESTAPI::Errors::InvalidUserRole);
}
}
std::sort(SE.restricted.begin(),SE.restricted.end());
}
GWObjects::ScriptEntry Existing;
if(!DB_.GetRecord("id", UUID, Existing)) {
return NotFound();
}
if(ParsedBody_->has("name") && SE.name.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(ParsedBody_->has("content") && SE.content.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(ParsedBody_->has("version") && SE.version.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(!SE.uri.empty() && !Utils::ValidateURI(SE.uri)) {
return BadRequest(RESTAPI::Errors::InvalidURI);
}
if(!SE.defaultUploadURI.empty() && !Utils::ValidateURI(SE.defaultUploadURI)) {
return BadRequest(RESTAPI::Errors::InvalidURI);
}
if(ParsedBody_->has("restricted")) {
Existing.restricted = SE.restricted;
}
AssignIfPresent(ParsedBody_, "name", Existing.name);
AssignIfPresent(ParsedBody_, "description", Existing.description);
AssignIfPresent(ParsedBody_, "uri", Existing.uri);
AssignIfPresent(ParsedBody_, "content", Existing.content);
AssignIfPresent(ParsedBody_, "version", Existing.version);
AssignIfPresent(ParsedBody_, "deferred", Existing.deferred);
AssignIfPresent(ParsedBody_, "timeout", Existing.timeout);
AssignIfPresent(ParsedBody_, "defaultUploadURI", Existing.defaultUploadURI);
Existing.modified = Utils::Now();
if(DB_.UpdateRecord("id", UUID, Existing)) {
return Object(Existing);
}
return BadRequest(RESTAPI::Errors::RecordNotUpdated);
}
} // namespace OpenWifi

View File

@@ -1,31 +0,0 @@
//
// Created by stephane bourque on 2022-11-21.
//
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_script_handler : public RESTAPIHandler {
public:
RESTAPI_script_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal){};
static auto PathName() { return std::list<std::string>{"/api/v1/script/{uuid}"}; };
private:
ScriptDB & DB_{ StorageService()->ScriptDB() };
void DoGet() final;
void DoDelete() final;
void DoPost() final;
void DoPut() final;
};
}

View File

@@ -1,20 +0,0 @@
//
// Created by stephane bourque on 2022-11-21.
//
#include "RESTAPI_scripts_handler.h"
#include "RESTObjects/RESTAPI_GWobjects.h"
#include "StorageService.h"
namespace OpenWifi {
void RESTAPI_scripts_handler::DoGet() {
GWObjects::ScriptEntryList L;
StorageService()->ScriptDB().GetRecords(QB_.Offset,QB_.Limit,L.scripts);
Poco::JSON::Object Answer;
L.to_json(Answer);
return ReturnObject(Answer);
}
} // namespace OpenWifi

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