mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2025-12-24 22:37:04 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17fe350d8c | ||
|
|
73e4f0df94 | ||
|
|
702d863e6b |
@@ -4,4 +4,4 @@ TabWidth: 4
|
||||
IndentWidth: 4
|
||||
UseTab: Always
|
||||
ColumnLimit: 100
|
||||
Language: Cpp
|
||||
Language: Cpp
|
||||
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@@ -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
|
||||
|
||||
2
.github/workflows/enforce-jira-issue-key.yml
vendored
2
.github/workflows/enforce-jira-issue-key.yml
vendored
@@ -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
|
||||
|
||||
41
.github/workflows/openapi-pages.yml
vendored
41
.github/workflows/openapi-pages.yml
vendored
@@ -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
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
@@ -81,54 +81,10 @@ add_executable( owgw
|
||||
src/framework/OpenWifiTypes.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 +108,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 +122,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 src/framework/MicroServiceErrorHandler.h)
|
||||
|
||||
if(NOT SMALL_BUILD)
|
||||
|
||||
@@ -219,4 +156,4 @@ if(NOT SMALL_BUILD)
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(owgw PUBLIC PocoJSON)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
47
Dockerfile
47
Dockerfile
@@ -1,15 +1,16 @@
|
||||
ARG DEBIAN_VERSION=11.5-slim
|
||||
ARG POCO_VERSION=poco-tip-v2
|
||||
ARG ALPINE_VERSION=3.16.2
|
||||
ARG POCO_VERSION=poco-tip-v1
|
||||
ARG FMTLIB_VERSION=9.0.0
|
||||
ARG CPPKAFKA_VERSION=tip-v1
|
||||
ARG JSON_VALIDATOR_VERSION=2.1.0
|
||||
|
||||
FROM debian:$DEBIAN_VERSION AS build-base
|
||||
FROM alpine:$ALPINE_VERSION AS build-base
|
||||
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||
RUN apk add --update --no-cache \
|
||||
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
|
||||
unixodbc-dev postgresql-dev mariadb-dev \
|
||||
librdkafka-dev boost-dev openssl-dev \
|
||||
zlib-dev nlohmann-json 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
|
||||
@@ -73,21 +90,21 @@ WORKDIR /owgw/cmake-build
|
||||
RUN cmake ..
|
||||
RUN cmake --build . --config Release -j8
|
||||
|
||||
FROM debian:$DEBIAN_VERSION
|
||||
FROM alpine:$ALPINE_VERSION
|
||||
|
||||
ENV OWGW_USER=owgw \
|
||||
OWGW_ROOT=/owgw-data \
|
||||
OWGW_CONFIG=/owgw-data
|
||||
|
||||
RUN useradd "$OWGW_USER"
|
||||
RUN addgroup -S "$OWGW_USER" && \
|
||||
adduser -S -G "$OWGW_USER" "$OWGW_USER"
|
||||
|
||||
RUN mkdir /openwifi
|
||||
RUN mkdir -p "$OWGW_ROOT" "$OWGW_CONFIG" && \
|
||||
chown "$OWGW_USER": "$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
|
||||
RUN apk add --update --no-cache librdkafka su-exec gettext ca-certificates bash jq curl \
|
||||
mariadb-connector-c libpq unixodbc postgresql-client
|
||||
|
||||
COPY readiness_check /readiness_check
|
||||
COPY test_scripts/curl/cli /cli
|
||||
@@ -97,13 +114,11 @@ COPY docker-entrypoint.sh /
|
||||
COPY wait-for-postgres.sh /
|
||||
COPY rtty_ui /dist/rtty_ui
|
||||
RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \
|
||||
-O /usr/local/share/ca-certificates/restapi-ca-selfsigned.crt
|
||||
-O /usr/local/share/ca-certificates/restapi-ca-selfsigned.pem
|
||||
|
||||
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/
|
||||
|
||||
RUN ldconfig
|
||||
COPY --from=poco-build /poco/cmake-build/lib /usr/local/lib
|
||||
|
||||
EXPOSE 15002 16002 16003 17002 16102
|
||||
|
||||
|
||||
@@ -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>`.
|
||||
|
||||
56
PROTOCOL.md
56
PROTOCOL.md
@@ -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>
|
||||
|
||||
69
README.md
69
README.md
@@ -119,61 +119,54 @@ cmake ..
|
||||
make
|
||||
|
||||
```
|
||||
|
||||
### macOS Build
|
||||
The following instructions have proven to work on macOS Big Sur. You need to install [Homebrew](https://brew.sh/). You must also have installed [XCode for OS X](https://www.freecodecamp.org/news/how-to-download-and-install-xcode/).
|
||||
|
||||
### OSX Build
|
||||
The following instructions have proven to work on OSX Big Sur. You need to install [Homebrew](https://brew.sh/). You must also have installed [XCode for OS X](https://www.freecodecamp.org/news/how-to-download-and-install-xcode/).
|
||||
```
|
||||
brew install openssl \
|
||||
cmake \
|
||||
libpq \
|
||||
mysql-client \
|
||||
apr \
|
||||
apr-util \
|
||||
boost \
|
||||
yaml-cpp \
|
||||
postgresql \
|
||||
librdkafka \
|
||||
nlohmann-json \
|
||||
fmt
|
||||
brew install openssl
|
||||
brew install cmake
|
||||
brew install libpq
|
||||
brew install mysql-client
|
||||
brew install apr
|
||||
brew install apr-util
|
||||
brew install boost
|
||||
brew install yaml-cpp
|
||||
brew install postgresql
|
||||
brew install librdkafka
|
||||
brew install nlohmann-json
|
||||
|
||||
git clone https://github.com/AriliaWireless/poco --branch poco-tip-v1
|
||||
pushd poco
|
||||
cd poco
|
||||
mkdir cmake-build
|
||||
push cmake-build
|
||||
cmake -DOPENSSL_ROOT_DIR=</path/to/openssl> -DENABLE_NETSSL=1 -DENABLE_JWT=1 -DENABLE_CRYPTO=1 ..
|
||||
cmake --build . --config Release
|
||||
sudo cmake --build . --target install
|
||||
popd
|
||||
popd
|
||||
|
||||
git clone https://github.com/AriliaWireless/cppkafka --branch tip-v1
|
||||
pushd cppkafka
|
||||
mkdir cmake-build
|
||||
pushd cmake-build
|
||||
cd cmake-build
|
||||
cmake ..
|
||||
cmake --build . --config Release
|
||||
sudo cmake --build . --target install
|
||||
popd
|
||||
popd
|
||||
|
||||
git clone https://github.com/pboettch/json-schema-validator.git --branch 2.1.0
|
||||
pushd json-schema-validator
|
||||
git clone https://github.com/AriliaWireless/cppkafka --branch tip-v1
|
||||
cd cppkafka
|
||||
mkdir cmake-build
|
||||
pushd cmake-build
|
||||
cd cmake-build
|
||||
cmake ..
|
||||
cmake --build . --config Release
|
||||
sudo cmake --build . --target install
|
||||
|
||||
cd ~
|
||||
git clone https://github.com/pboettch/json-schema-validator.git --branch 2.1.0
|
||||
cd json-schema-validator
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
cmake ..
|
||||
make -j
|
||||
sudo make install
|
||||
popd
|
||||
popd
|
||||
|
||||
cd ~
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralgw
|
||||
pushd wlan-cloud-ucentralgw
|
||||
cd wlan-cloud-ucentralgw
|
||||
mkdir cmake-build
|
||||
pushd cmake-build
|
||||
cd cmake-build
|
||||
cmake ..
|
||||
make -j
|
||||
popd
|
||||
popd
|
||||
```
|
||||
|
||||
### Raspberry
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#!/bin/sh
|
||||
@@ -1,2 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
# Repo for scripts
|
||||
File diff suppressed because it is too large
Load Diff
4
cmake-build-debug/rdkafka_version_test.cpp
Normal file
4
cmake-build-debug/rdkafka_version_test.cpp
Normal file
@@ -0,0 +1,4 @@
|
||||
#include <librdkafka/rdkafka.h>
|
||||
#if RD_KAFKA_VERSION >= 0x00090400
|
||||
int main() { }
|
||||
#endif
|
||||
26
config.yaml
Normal file
26
config.yaml
Normal file
@@ -0,0 +1,26 @@
|
||||
tip:
|
||||
port: 6051
|
||||
server: ssc.wlan.local
|
||||
username: support@example.com
|
||||
password: support
|
||||
|
||||
certificates:
|
||||
keyfile: keyfile.pem
|
||||
certfile: certfile.pem
|
||||
password: mypassword
|
||||
|
||||
ucentral:
|
||||
port: 1991
|
||||
listeners: 100
|
||||
|
||||
logger:
|
||||
size: 10
|
||||
days: 31
|
||||
|
||||
ui:
|
||||
port: 9771
|
||||
username: support@example.com
|
||||
password: support
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [ "$SELFSIGNED_CERTS" = 'true' ]; then
|
||||
@@ -38,12 +38,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
||||
SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17002"} \
|
||||
SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16002"} \
|
||||
SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
|
||||
SECURITY_RESTAPI_DISABLE=${SECURITY_RESTAPI_DISABLE:-"false"} \
|
||||
SIMULATORID=${SIMULATORID:-""} \
|
||||
IPTOCOUNTRY_PROVIDER=${IPTOCOUNTRY_PROVIDER:-"ipinfo"} \
|
||||
IPTOCOUNTRY_IPINFO_TOKEN=${IPTOCOUNTRY_IPINFO_TOKEN:-""} \
|
||||
IPTOCOUNTRY_IPDATA_APIKEY=${IPTOCOUNTRY_IPDATA_APIKEY:-""} \
|
||||
AUTOPROVISIONING_PROCESS=${AUTOPROVISIONING_PROCESS:-"prov,default"} \
|
||||
RTTY_INTERNAL=${RTTY_INTERNAL:-"true"} \
|
||||
RTTY_ENABLED=${RTTY_ENABLED:-"true"} \
|
||||
RTTY_SERVER=${RTTY_SERVER:-"localhost"} \
|
||||
@@ -52,10 +47,6 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
||||
RTTY_TIMEOUT=${RTTY_TIMEOUT:-"60"} \
|
||||
RTTY_VIEWPORT=${RTTY_VIEWPORT:-"5913"} \
|
||||
RTTY_ASSETS=${RTTY_ASSETS:-"\$OWGW_ROOT/rtty_ui"} \
|
||||
RADIUS_PROXY_ENABLE=${RADIUS_PROXY_ENABLE:-"false"} \
|
||||
RADIUS_PROXY_ACCOUNTING_PORT=${RADIUS_PROXY_ACCOUNTING_PORT:-"1813"} \
|
||||
RADIUS_PROXY_AUTHENTICATION_PORT=${RADIUS_PROXY_AUTHENTICATION_PORT:-"1812"} \
|
||||
RADIUS_PROXY_COA_PORT=${RADIUS_PROXY_COA_PORT:-"3799"} \
|
||||
KAFKA_ENABLE=${KAFKA_ENABLE:-"true"} \
|
||||
KAFKA_BROKERLIST=${KAFKA_BROKERLIST:-"localhost:9092"} \
|
||||
KAFKA_SSL_CA_LOCATION=${KAFKA_SSL_CA_LOCATION:-""} \
|
||||
@@ -73,7 +64,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
|
||||
|
||||
@@ -96,7 +86,7 @@ if [ "$1" = '/openwifi/owgw' -a "$(id -u)" = '0' ]; then
|
||||
if [ "$RUN_CHOWN" = 'true' ]; then
|
||||
chown -R "$OWGW_USER": "$OWGW_ROOT" "$OWGW_CONFIG"
|
||||
fi
|
||||
exec gosu "$OWGW_USER" "$@"
|
||||
exec su-exec "$OWGW_USER" "$@"
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
|
||||
14
docker_build.sh
Executable file
14
docker_build.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
USERNAME=arilia
|
||||
HUBNAME=tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||
IMAGE_NAME=ucentralgw
|
||||
|
||||
echo "Removing docker images before build..."
|
||||
docker rmi -f $(docker images -a -q)
|
||||
echo "Building $IMAGE_NAME image..."
|
||||
docker build --no-cache --tag $IMAGE_NAME .
|
||||
IMAGE_ID=`docker images -q $IMAGE_NAME`
|
||||
docker login --username=$USERNAME $HUBNAME
|
||||
docker tag $IMAGE_ID $HUBNAME/$IMAGE_NAME:latest
|
||||
echo "Updating $HUBNAME with the latest $IMAGE_NAME image..."
|
||||
docker push $HUBNAME/$IMAGE_NAME
|
||||
docker logout $HUBNAME
|
||||
5
docker_clean.sh
Normal file
5
docker_clean.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Removes all local images. This is dangerous but good when debugging
|
||||
docker rmi -f $(docker images -a -q)
|
||||
|
||||
43
docker_run.sh
Normal file
43
docker_run.sh
Normal file
@@ -0,0 +1,43 @@
|
||||
#!/bin/sh
|
||||
|
||||
HUBNAME=tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||
IMAGE_NAME=ucentralgw
|
||||
DOCKER_NAME=$HUBNAME/$IMAGE_NAME:master
|
||||
|
||||
CONTAINER_NAME=ucentralgw
|
||||
|
||||
#stop previously running images
|
||||
docker container stop $CONTAINER_NAME
|
||||
docker container rm $CONTAINER_NAME --force
|
||||
|
||||
if [[ ! -d logs ]]
|
||||
then
|
||||
mkdir logs
|
||||
fi
|
||||
|
||||
if [[ ! -d uploads ]]
|
||||
then
|
||||
mkdir uploads
|
||||
fi
|
||||
|
||||
if [[ ! -d certs ]]
|
||||
then
|
||||
echo "certs directory does not exist. Please create and add the proper certificates."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f owgw.properties ]]
|
||||
then
|
||||
echo "Configuration file ucentral.properties is missing in the current directory"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
docker run -d -p 15002:15002 \
|
||||
-p 16001:16001 \
|
||||
-p 16003:16003 \
|
||||
--init \
|
||||
--volume="$PWD:/ucentral-data" \
|
||||
-e UCENTRALGW_ROOT="/ucentral-data" \
|
||||
-e UCENTRALGW_CONFIG="/ucentral-data" \
|
||||
--name="ucentralgw" $DOCKER_NAME
|
||||
|
||||
@@ -79,8 +79,7 @@ The following table lists the configurable parameters of the chart and their def
|
||||
| persistence.size | string | Defines PV size | `'10Gi'` |
|
||||
| public_env_variables | hash | Defines list of environment variables to be passed to the Gateway | |
|
||||
| configProperties | hash | Configuration properties that should be passed to the application in `owgw.properties`. May be passed by key in set (i.e. `configProperties."rtty\.token"`) | |
|
||||
| existingCertsSecret | string | Existing Kubernetes secret containing all required certificates and private keys for microservice operation. If set, certificates from `certs` key are ignored | `""` |
|
||||
| certs | hash | Defines files (keys and certificates) that should be passed to the Gateway (PEM format is adviced to be used) (see `volumes.owgw` on where it is mounted). If `existingCertsSecret` is set, certificates passed this way will not be used. | |
|
||||
| certs | hash | Defines files (keys and certificates) that should be passed to the Gateway (PEM format is adviced to be used) (see `volumes.owgw` on where it is mounted) | |
|
||||
| certsCAs | hash | Defines files with CAs that should be passed to the Gateway (see `volumes.owgw` on where it is mounted) | |
|
||||
|
||||
|
||||
|
||||
@@ -109,11 +109,6 @@ spec:
|
||||
containerPort: {{ $portValue.targetPort }}
|
||||
protocol: {{ $portValue.protocol }}
|
||||
{{- end }}
|
||||
{{- range $port, $portValue := .Values.services.radius.ports }}
|
||||
- name: {{ $port }}
|
||||
containerPort: {{ $portValue.targetPort }}
|
||||
protocol: {{ $portValue.protocol }}
|
||||
{{- end }}
|
||||
|
||||
volumeMounts:
|
||||
{{- range .Values.volumes.owgw }}
|
||||
|
||||
198
helm/values.yaml
198
helm/values.yaml
@@ -9,7 +9,7 @@ fullnameOverride: ""
|
||||
images:
|
||||
owgw:
|
||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owgw
|
||||
tag: v2.8.0
|
||||
tag: master
|
||||
pullPolicy: Always
|
||||
# regcred:
|
||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||
@@ -46,21 +46,6 @@ services:
|
||||
rttys-view:
|
||||
servicePort: 5913
|
||||
targetPort: 5913
|
||||
radius:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
acc:
|
||||
servicePort: 1813
|
||||
targetPort: 1813
|
||||
protocol: UDP
|
||||
auth:
|
||||
servicePort: 1812
|
||||
targetPort: 1812
|
||||
protocol: UDP
|
||||
coa:
|
||||
servicePort: 3799
|
||||
targetPort: 3799
|
||||
protocol: UDP
|
||||
|
||||
checks:
|
||||
owgw:
|
||||
@@ -112,7 +97,7 @@ volumes:
|
||||
mountPath: /owgw-data/certs
|
||||
volumeDefinition: |
|
||||
secret:
|
||||
secretName: {{ if .Values.existingCertsSecret }}{{ .Values.existingCertsSecret }}{{ else }}{{ include "owgw.fullname" . }}-certs{{ end }}
|
||||
secretName: {{ include "owgw.fullname" . }}-certs
|
||||
- name: certs-cas
|
||||
mountPath: /owgw-data/certs/cas
|
||||
volumeDefinition: |
|
||||
@@ -138,7 +123,7 @@ resources: {}
|
||||
# memory: 128Mi
|
||||
|
||||
securityContext:
|
||||
fsGroup: 1000
|
||||
fsGroup: 101
|
||||
# Usage of unsafe sysctls requires multiple things:
|
||||
# - allow these unsafe sysctls on kubelet level (by adding --allowed-unsafe-sysctls flag)
|
||||
# - enabling addition of PodSecurityContext setting podSecurityPolicy.enabled to "true" below
|
||||
@@ -230,7 +215,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
|
||||
@@ -247,11 +231,6 @@ configProperties:
|
||||
rtty.timeout: 60
|
||||
rtty.viewport: 5913
|
||||
rtty.assets: $OWGW_ROOT/rtty_ui
|
||||
# RADIUS proxy
|
||||
radius.proxy.enable: "true"
|
||||
radius.proxy.accounting.port: 1813
|
||||
radius.proxy.authentication.port: 1812
|
||||
radius.proxy.coa.port: 3799
|
||||
# ALB
|
||||
alb.enable: "true"
|
||||
alb.port: 16102
|
||||
@@ -292,7 +271,6 @@ configProperties:
|
||||
openwifi.system.debug: "true"
|
||||
openwifi.system.uri.private: https://localhost:17002
|
||||
openwifi.system.uri.public: https://localhost:16002
|
||||
openwifi.system.uri.ui: https://localhost
|
||||
openwifi.system.commandchannel: /tmp/app_owgw
|
||||
# Logging
|
||||
logging.type: console
|
||||
@@ -332,22 +310,166 @@ configProperties:
|
||||
storage.type.mysql.username: stephb
|
||||
storage.type.mysql.password: snoopy99
|
||||
|
||||
# NOTE: List of required certificates may be found in "certs" key. Alternative way to pass required certificates is to create external secret with all required certificates and set secret name in "existingCertsSecret" key. Details may be found in https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/main/chart#tldr
|
||||
existingCertsSecret: ""
|
||||
|
||||
certs:
|
||||
clientcas.pem: ""
|
||||
issuer.pem: ""
|
||||
restapi-ca.pem: ""
|
||||
restapi-cert.pem: ""
|
||||
restapi-key.pem: ""
|
||||
root.pem: ""
|
||||
websocket-cert.pem: ""
|
||||
websocket-key.pem: ""
|
||||
clientcas.pem: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEnDCCA4SgAwIBAgIUVpyCUx1MUeUwxg+7I1BvGFTz7HkwDQYJKoZIhvcNAQEL
|
||||
BQAwaTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG1RlbGVjb20gSW5mcmEgUHJvamVj
|
||||
dCwgSW5jLjEMMAoGA1UECxMDVElQMSYwJAYDVQQDEx1UZWxlY29tIEluZnJhIFBy
|
||||
b2plY3QgUm9vdCBDQTAeFw0yMTA0MTMyMjUxMjZaFw0yNjA0MTMyMjM4NDZaMGwx
|
||||
CzAJBgNVBAYTAlVTMSQwIgYDVQQKExtUZWxlY29tIEluZnJhIFByb2plY3QsIElu
|
||||
Yy4xDDAKBgNVBAsTA1RJUDEpMCcGA1UEAxMgVGVsZWNvbSBJbmZyYSBQcm9qZWN0
|
||||
IElzc3VpbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtKBrq
|
||||
qd2aKVSk25KfL5xHu8X7/8rJrz3IvyPuVKWhk/N1zabot3suBcGaYNKjnRHxg78R
|
||||
yKwKzajKYWtiQFqztu24g16LQeAnoUxZnF6a0z3JkkRPsz14A2y8TUhdEe1tx+UU
|
||||
4VGsk3n+FMmOQHL+79FO57zQC1LwylgfLSltrI6mF3jowVUQvnwzKhUzT87AJ6EO
|
||||
ndK/q0T/Bgi+aI39zfVOjJjsTJwghvrmYW3iarP1THSKxeib2s02bZKrvvHa5HL4
|
||||
UI8+LvREpVZl4mzt1z6Nl344Y6f+UeJlYa/Ci0jJqaXJmyVnUbAz+c0i5JfwAVn3
|
||||
YQzfC4eLnZCmdF8zAgMBAAGjggE3MIIBMzAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
|
||||
DgQWBBSzG1S44EerPfM4gOQ85f0AYW3R6DAfBgNVHSMEGDAWgBQCRpZgebFT9qny
|
||||
98WfIUDk6ZEB+jAOBgNVHQ8BAf8EBAMCAYYwgYMGCCsGAQUFBwEBBHcwdTAoBggr
|
||||
BgEFBQcwAYYcaHR0cDovL29jc3Aub25lLmRpZ2ljZXJ0LmNvbTBJBggrBgEFBQcw
|
||||
AoY9aHR0cDovL2NhY2VydHMub25lLmRpZ2ljZXJ0LmNvbS9UZWxlY29tSW5mcmFQ
|
||||
cm9qZWN0Um9vdENBLmNydDBKBgNVHR8EQzBBMD+gPaA7hjlodHRwOi8vY3JsLm9u
|
||||
ZS5kaWdpY2VydC5jb20vVGVsZWNvbUluZnJhUHJvamVjdFJvb3RDQS5jcmwwDQYJ
|
||||
KoZIhvcNAQELBQADggEBAFbz+K94bHIkBMJqps0dApniUmOn0pO6Q6cGh47UP/kX
|
||||
IiPIsnYgG+hqYD/qtsiqJhaWi0hixRWn38UmvZxMRk27aSTGE/TWx0JTC3qDGsSe
|
||||
XkUagumbSfmS0ZyiTwMPeGAjXwyzGorqZWeA95eKfImntMiOf3E7//GK0K7HpCx8
|
||||
IPCnLZsZD2q/mLyBsduImFIRQJbLAhwIxpcd1qYJk+BlGFL+HtBpEbq6JxW2Xy+v
|
||||
DpNWc2WIsUTle0rTc9JNJrLX4ChUJmKqf8obKHap3Xh3//qw/jDB9pOAinA33FLJ
|
||||
EmCnwBvQr9mfNmPBGMYZVU8cPruDQJ57GjmmvdisbJY=
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDojCCAoqgAwIBAgIUPVYBpqNbcLYygF6Mx+qxSWwQyFowDQYJKoZIhvcNAQEL
|
||||
BQAwaTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG1RlbGVjb20gSW5mcmEgUHJvamVj
|
||||
dCwgSW5jLjEMMAoGA1UECxMDVElQMSYwJAYDVQQDEx1UZWxlY29tIEluZnJhIFBy
|
||||
b2plY3QgUm9vdCBDQTAeFw0yMTA0MTMyMjQyNDRaFw0zMTA0MTMyMjM4NDZaMGkx
|
||||
CzAJBgNVBAYTAlVTMSQwIgYDVQQKExtUZWxlY29tIEluZnJhIFByb2plY3QsIElu
|
||||
Yy4xDDAKBgNVBAsTA1RJUDEmMCQGA1UEAxMdVGVsZWNvbSBJbmZyYSBQcm9qZWN0
|
||||
IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIGCibwf5u
|
||||
AAwZ+1H8U0e3u2V+0d2gSctucoK86XwUmfe1V2a/qlCYZd29r80IuN1IIeB0naIm
|
||||
KnK/MzXW87clF6tFd1+HzEvmlY/W4KyIXalVCTEzirFSvBEG2oZpM0yC3AefytAO
|
||||
aOpA00LaM3xTfTqMKIRhJBuLy0I4ANUVG6ixVebbGuc78IodleqiLoWy2Q9QHyEO
|
||||
t/7hZndJhiVogh0PveRhho45EbsACu7ymDY+JhlIleevqwlE3iQoq0YcmYADHno6
|
||||
Eq8vcwLpZFxihupUafkd1T3WJYQAJf9coCjBu2qIhNgrcrGD8R9fGswwNRzMRMpX
|
||||
720+GjcDW3bJAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFAJG
|
||||
lmB5sVP2qfL3xZ8hQOTpkQH6MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF
|
||||
AAOCAQEAVjl9dm4epG9NUYnagT9sg7scVQEPfz3Lt6w1NXJXgD8mAUlK0jXmEyvM
|
||||
dCPD4514n+8+lM7US8fh+nxc7jO//LwK17Wm9FblgjNFR7+anv0Q99T9fP19DLlF
|
||||
PSNHL2emogy1bl1lLTAoj8nxg2wVKPDSHBGviQ5LR9fsWUIJDv9Bs5k0qWugWYSj
|
||||
19S6qnHeskRDB8MqRLhKMG82oDVLerSnhD0P6HjySBHgTTU7/tYS/OZr1jI6MPbG
|
||||
L+/DtiR5fDVMNdBSGU89UNTi0wHY9+RFuNlIuvZC+x/swF0V9R5mN+ywquTPtDLA
|
||||
5IOM7ItsRmen6u3qu+JXros54e4juQ==
|
||||
-----END CERTIFICATE-----
|
||||
issuer.pem: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEnDCCA4SgAwIBAgIUVpyCUx1MUeUwxg+7I1BvGFTz7HkwDQYJKoZIhvcNAQEL
|
||||
BQAwaTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG1RlbGVjb20gSW5mcmEgUHJvamVj
|
||||
dCwgSW5jLjEMMAoGA1UECxMDVElQMSYwJAYDVQQDEx1UZWxlY29tIEluZnJhIFBy
|
||||
b2plY3QgUm9vdCBDQTAeFw0yMTA0MTMyMjUxMjZaFw0yNjA0MTMyMjM4NDZaMGwx
|
||||
CzAJBgNVBAYTAlVTMSQwIgYDVQQKExtUZWxlY29tIEluZnJhIFByb2plY3QsIElu
|
||||
Yy4xDDAKBgNVBAsTA1RJUDEpMCcGA1UEAxMgVGVsZWNvbSBJbmZyYSBQcm9qZWN0
|
||||
IElzc3VpbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtKBrq
|
||||
qd2aKVSk25KfL5xHu8X7/8rJrz3IvyPuVKWhk/N1zabot3suBcGaYNKjnRHxg78R
|
||||
yKwKzajKYWtiQFqztu24g16LQeAnoUxZnF6a0z3JkkRPsz14A2y8TUhdEe1tx+UU
|
||||
4VGsk3n+FMmOQHL+79FO57zQC1LwylgfLSltrI6mF3jowVUQvnwzKhUzT87AJ6EO
|
||||
ndK/q0T/Bgi+aI39zfVOjJjsTJwghvrmYW3iarP1THSKxeib2s02bZKrvvHa5HL4
|
||||
UI8+LvREpVZl4mzt1z6Nl344Y6f+UeJlYa/Ci0jJqaXJmyVnUbAz+c0i5JfwAVn3
|
||||
YQzfC4eLnZCmdF8zAgMBAAGjggE3MIIBMzAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
|
||||
DgQWBBSzG1S44EerPfM4gOQ85f0AYW3R6DAfBgNVHSMEGDAWgBQCRpZgebFT9qny
|
||||
98WfIUDk6ZEB+jAOBgNVHQ8BAf8EBAMCAYYwgYMGCCsGAQUFBwEBBHcwdTAoBggr
|
||||
BgEFBQcwAYYcaHR0cDovL29jc3Aub25lLmRpZ2ljZXJ0LmNvbTBJBggrBgEFBQcw
|
||||
AoY9aHR0cDovL2NhY2VydHMub25lLmRpZ2ljZXJ0LmNvbS9UZWxlY29tSW5mcmFQ
|
||||
cm9qZWN0Um9vdENBLmNydDBKBgNVHR8EQzBBMD+gPaA7hjlodHRwOi8vY3JsLm9u
|
||||
ZS5kaWdpY2VydC5jb20vVGVsZWNvbUluZnJhUHJvamVjdFJvb3RDQS5jcmwwDQYJ
|
||||
KoZIhvcNAQELBQADggEBAFbz+K94bHIkBMJqps0dApniUmOn0pO6Q6cGh47UP/kX
|
||||
IiPIsnYgG+hqYD/qtsiqJhaWi0hixRWn38UmvZxMRk27aSTGE/TWx0JTC3qDGsSe
|
||||
XkUagumbSfmS0ZyiTwMPeGAjXwyzGorqZWeA95eKfImntMiOf3E7//GK0K7HpCx8
|
||||
IPCnLZsZD2q/mLyBsduImFIRQJbLAhwIxpcd1qYJk+BlGFL+HtBpEbq6JxW2Xy+v
|
||||
DpNWc2WIsUTle0rTc9JNJrLX4ChUJmKqf8obKHap3Xh3//qw/jDB9pOAinA33FLJ
|
||||
EmCnwBvQr9mfNmPBGMYZVU8cPruDQJ57GjmmvdisbJY=
|
||||
-----END CERTIFICATE-----
|
||||
# restapi-ca.pem: ""
|
||||
# restapi-cert.pem: ""
|
||||
# restapi-key.pem: ""
|
||||
root.pem: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDojCCAoqgAwIBAgIUPVYBpqNbcLYygF6Mx+qxSWwQyFowDQYJKoZIhvcNAQEL
|
||||
BQAwaTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG1RlbGVjb20gSW5mcmEgUHJvamVj
|
||||
dCwgSW5jLjEMMAoGA1UECxMDVElQMSYwJAYDVQQDEx1UZWxlY29tIEluZnJhIFBy
|
||||
b2plY3QgUm9vdCBDQTAeFw0yMTA0MTMyMjQyNDRaFw0zMTA0MTMyMjM4NDZaMGkx
|
||||
CzAJBgNVBAYTAlVTMSQwIgYDVQQKExtUZWxlY29tIEluZnJhIFByb2plY3QsIElu
|
||||
Yy4xDDAKBgNVBAsTA1RJUDEmMCQGA1UEAxMdVGVsZWNvbSBJbmZyYSBQcm9qZWN0
|
||||
IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIGCibwf5u
|
||||
AAwZ+1H8U0e3u2V+0d2gSctucoK86XwUmfe1V2a/qlCYZd29r80IuN1IIeB0naIm
|
||||
KnK/MzXW87clF6tFd1+HzEvmlY/W4KyIXalVCTEzirFSvBEG2oZpM0yC3AefytAO
|
||||
aOpA00LaM3xTfTqMKIRhJBuLy0I4ANUVG6ixVebbGuc78IodleqiLoWy2Q9QHyEO
|
||||
t/7hZndJhiVogh0PveRhho45EbsACu7ymDY+JhlIleevqwlE3iQoq0YcmYADHno6
|
||||
Eq8vcwLpZFxihupUafkd1T3WJYQAJf9coCjBu2qIhNgrcrGD8R9fGswwNRzMRMpX
|
||||
720+GjcDW3bJAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFAJG
|
||||
lmB5sVP2qfL3xZ8hQOTpkQH6MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF
|
||||
AAOCAQEAVjl9dm4epG9NUYnagT9sg7scVQEPfz3Lt6w1NXJXgD8mAUlK0jXmEyvM
|
||||
dCPD4514n+8+lM7US8fh+nxc7jO//LwK17Wm9FblgjNFR7+anv0Q99T9fP19DLlF
|
||||
PSNHL2emogy1bl1lLTAoj8nxg2wVKPDSHBGviQ5LR9fsWUIJDv9Bs5k0qWugWYSj
|
||||
19S6qnHeskRDB8MqRLhKMG82oDVLerSnhD0P6HjySBHgTTU7/tYS/OZr1jI6MPbG
|
||||
L+/DtiR5fDVMNdBSGU89UNTi0wHY9+RFuNlIuvZC+x/swF0V9R5mN+ywquTPtDLA
|
||||
5IOM7ItsRmen6u3qu+JXros54e4juQ==
|
||||
-----END CERTIFICATE-----
|
||||
# websocket-cert.pem: ""
|
||||
# websocket-key.pem: ""
|
||||
|
||||
certsCAs:
|
||||
issuer.pem: ""
|
||||
root.pem: ""
|
||||
issuer.pem: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEnDCCA4SgAwIBAgIUVpyCUx1MUeUwxg+7I1BvGFTz7HkwDQYJKoZIhvcNAQEL
|
||||
BQAwaTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG1RlbGVjb20gSW5mcmEgUHJvamVj
|
||||
dCwgSW5jLjEMMAoGA1UECxMDVElQMSYwJAYDVQQDEx1UZWxlY29tIEluZnJhIFBy
|
||||
b2plY3QgUm9vdCBDQTAeFw0yMTA0MTMyMjUxMjZaFw0yNjA0MTMyMjM4NDZaMGwx
|
||||
CzAJBgNVBAYTAlVTMSQwIgYDVQQKExtUZWxlY29tIEluZnJhIFByb2plY3QsIElu
|
||||
Yy4xDDAKBgNVBAsTA1RJUDEpMCcGA1UEAxMgVGVsZWNvbSBJbmZyYSBQcm9qZWN0
|
||||
IElzc3VpbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDtKBrq
|
||||
qd2aKVSk25KfL5xHu8X7/8rJrz3IvyPuVKWhk/N1zabot3suBcGaYNKjnRHxg78R
|
||||
yKwKzajKYWtiQFqztu24g16LQeAnoUxZnF6a0z3JkkRPsz14A2y8TUhdEe1tx+UU
|
||||
4VGsk3n+FMmOQHL+79FO57zQC1LwylgfLSltrI6mF3jowVUQvnwzKhUzT87AJ6EO
|
||||
ndK/q0T/Bgi+aI39zfVOjJjsTJwghvrmYW3iarP1THSKxeib2s02bZKrvvHa5HL4
|
||||
UI8+LvREpVZl4mzt1z6Nl344Y6f+UeJlYa/Ci0jJqaXJmyVnUbAz+c0i5JfwAVn3
|
||||
YQzfC4eLnZCmdF8zAgMBAAGjggE3MIIBMzAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
|
||||
DgQWBBSzG1S44EerPfM4gOQ85f0AYW3R6DAfBgNVHSMEGDAWgBQCRpZgebFT9qny
|
||||
98WfIUDk6ZEB+jAOBgNVHQ8BAf8EBAMCAYYwgYMGCCsGAQUFBwEBBHcwdTAoBggr
|
||||
BgEFBQcwAYYcaHR0cDovL29jc3Aub25lLmRpZ2ljZXJ0LmNvbTBJBggrBgEFBQcw
|
||||
AoY9aHR0cDovL2NhY2VydHMub25lLmRpZ2ljZXJ0LmNvbS9UZWxlY29tSW5mcmFQ
|
||||
cm9qZWN0Um9vdENBLmNydDBKBgNVHR8EQzBBMD+gPaA7hjlodHRwOi8vY3JsLm9u
|
||||
ZS5kaWdpY2VydC5jb20vVGVsZWNvbUluZnJhUHJvamVjdFJvb3RDQS5jcmwwDQYJ
|
||||
KoZIhvcNAQELBQADggEBAFbz+K94bHIkBMJqps0dApniUmOn0pO6Q6cGh47UP/kX
|
||||
IiPIsnYgG+hqYD/qtsiqJhaWi0hixRWn38UmvZxMRk27aSTGE/TWx0JTC3qDGsSe
|
||||
XkUagumbSfmS0ZyiTwMPeGAjXwyzGorqZWeA95eKfImntMiOf3E7//GK0K7HpCx8
|
||||
IPCnLZsZD2q/mLyBsduImFIRQJbLAhwIxpcd1qYJk+BlGFL+HtBpEbq6JxW2Xy+v
|
||||
DpNWc2WIsUTle0rTc9JNJrLX4ChUJmKqf8obKHap3Xh3//qw/jDB9pOAinA33FLJ
|
||||
EmCnwBvQr9mfNmPBGMYZVU8cPruDQJ57GjmmvdisbJY=
|
||||
-----END CERTIFICATE-----
|
||||
root.pem: |
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDojCCAoqgAwIBAgIUPVYBpqNbcLYygF6Mx+qxSWwQyFowDQYJKoZIhvcNAQEL
|
||||
BQAwaTELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG1RlbGVjb20gSW5mcmEgUHJvamVj
|
||||
dCwgSW5jLjEMMAoGA1UECxMDVElQMSYwJAYDVQQDEx1UZWxlY29tIEluZnJhIFBy
|
||||
b2plY3QgUm9vdCBDQTAeFw0yMTA0MTMyMjQyNDRaFw0zMTA0MTMyMjM4NDZaMGkx
|
||||
CzAJBgNVBAYTAlVTMSQwIgYDVQQKExtUZWxlY29tIEluZnJhIFByb2plY3QsIElu
|
||||
Yy4xDDAKBgNVBAsTA1RJUDEmMCQGA1UEAxMdVGVsZWNvbSBJbmZyYSBQcm9qZWN0
|
||||
IFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIGCibwf5u
|
||||
AAwZ+1H8U0e3u2V+0d2gSctucoK86XwUmfe1V2a/qlCYZd29r80IuN1IIeB0naIm
|
||||
KnK/MzXW87clF6tFd1+HzEvmlY/W4KyIXalVCTEzirFSvBEG2oZpM0yC3AefytAO
|
||||
aOpA00LaM3xTfTqMKIRhJBuLy0I4ANUVG6ixVebbGuc78IodleqiLoWy2Q9QHyEO
|
||||
t/7hZndJhiVogh0PveRhho45EbsACu7ymDY+JhlIleevqwlE3iQoq0YcmYADHno6
|
||||
Eq8vcwLpZFxihupUafkd1T3WJYQAJf9coCjBu2qIhNgrcrGD8R9fGswwNRzMRMpX
|
||||
720+GjcDW3bJAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFAJG
|
||||
lmB5sVP2qfL3xZ8hQOTpkQH6MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF
|
||||
AAOCAQEAVjl9dm4epG9NUYnagT9sg7scVQEPfz3Lt6w1NXJXgD8mAUlK0jXmEyvM
|
||||
dCPD4514n+8+lM7US8fh+nxc7jO//LwK17Wm9FblgjNFR7+anv0Q99T9fP19DLlF
|
||||
PSNHL2emogy1bl1lLTAoj8nxg2wVKPDSHBGviQ5LR9fsWUIJDv9Bs5k0qWugWYSj
|
||||
19S6qnHeskRDB8MqRLhKMG82oDVLerSnhD0P6HjySBHgTTU7/tYS/OZr1jI6MPbG
|
||||
L+/DtiR5fDVMNdBSGU89UNTi0wHY9+RFuNlIuvZC+x/swF0V9R5mN+ywquTPtDLA
|
||||
5IOM7ItsRmen6u3qu+JXros54e4juQ==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# PostgreSQL (https://github.com/bitnami/charts/tree/master/bitnami/postgresql)
|
||||
postgresql:
|
||||
|
||||
@@ -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'
|
||||
@@ -65,7 +65,6 @@ openwifi.system.debug = true
|
||||
openwifi.system.uri.private = https://localhost:17002
|
||||
openwifi.system.uri.public = https://ucentral.dpaas.arilia.com:16002
|
||||
openwifi.system.uri.ui = https://ucentral-ui.arilia.com
|
||||
openwifi.security.restapi.disable = false
|
||||
openwifi.system.commandchannel = /tmp/app.ucentralgw
|
||||
|
||||
#
|
||||
@@ -178,4 +177,4 @@ archiver.db.3.keep = 7
|
||||
########################################################################
|
||||
logging.type = file
|
||||
logging.path = $OWGW_ROOT/logs
|
||||
logging.level = information
|
||||
logging.level = debug
|
||||
@@ -52,8 +52,8 @@ openwifi.fileuploader.host.0.cert = ${FILEUPLOADER_HOST_CERT}
|
||||
openwifi.fileuploader.host.0.key = ${FILEUPLOADER_HOST_KEY}
|
||||
openwifi.fileuploader.host.0.key.password = ${FILEUPLOADER_HOST_KEY_PASSWORD}
|
||||
openwifi.fileuploader.path = ${FILEUPLOADER_PATH}
|
||||
openwifi.fileuploader.maxsize = 10000
|
||||
openwifi.fileuploader.uri = ${FILEUPLOADER_URI}
|
||||
openwifi.fileuploader.maxsize = 10000
|
||||
|
||||
#
|
||||
# Generic section that all microservices must have
|
||||
@@ -65,7 +65,6 @@ openwifi.system.debug = true
|
||||
openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE}
|
||||
openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
|
||||
openwifi.system.uri.ui = ${SYSTEM_URI_UI}
|
||||
openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE}
|
||||
openwifi.system.commandchannel = /tmp/app.ucentralgw
|
||||
|
||||
#
|
||||
@@ -75,15 +74,9 @@ 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
|
||||
firmware.autoupdate.policy.default = auto
|
||||
simulatorid = ${SIMULATORID}
|
||||
iptocountry.default = US
|
||||
iptocountry.provider = ${IPTOCOUNTRY_PROVIDER}
|
||||
iptocountry.ipinfo.token = ${IPTOCOUNTRY_IPINFO_TOKEN}
|
||||
iptocountry.ipdata.apikey = ${IPTOCOUNTRY_IPDATA_APIKEY}
|
||||
|
||||
autoprovisioning.process = ${AUTOPROVISIONING_PROCESS}
|
||||
|
||||
#
|
||||
# rtty
|
||||
@@ -97,12 +90,6 @@ rtty.timeout = ${RTTY_TIMEOUT}
|
||||
rtty.viewport = ${RTTY_VIEWPORT}
|
||||
rtty.assets = ${RTTY_ASSETS}
|
||||
|
||||
### RADIUS proxy config
|
||||
radius.proxy.enable = ${RADIUS_PROXY_ENABLE}
|
||||
radius.proxy.accounting.port = ${RADIUS_PROXY_ACCOUNTING_PORT}
|
||||
radius.proxy.authentication.port = ${RADIUS_PROXY_AUTHENTICATION_PORT}
|
||||
radius.proxy.coa.port = ${RADIUS_PROXY_COA_PORT}
|
||||
|
||||
#############################
|
||||
# Generic information for all micro services
|
||||
#############################
|
||||
@@ -121,7 +108,6 @@ openwifi.kafka.enable = ${KAFKA_ENABLE}
|
||||
openwifi.kafka.brokerlist = ${KAFKA_BROKERLIST}
|
||||
openwifi.kafka.auto.commit = false
|
||||
openwifi.kafka.queue.buffering.max.ms = 50
|
||||
|
||||
openwifi.kafka.ssl.ca.location = ${KAFKA_SSL_CA_LOCATION}
|
||||
openwifi.kafka.ssl.certificate.location = ${KAFKA_SSL_CERTIFICATE_LOCATION}
|
||||
openwifi.kafka.ssl.key.location = ${KAFKA_SSL_KEY_LOCATION}
|
||||
@@ -175,4 +161,4 @@ archiver.db.3.keep = 7
|
||||
########################################################################
|
||||
logging.type = console
|
||||
logging.path = $OWGW_ROOT/logs
|
||||
logging.level = information
|
||||
logging.level = debug
|
||||
|
||||
41
pcap/radius
Normal file
41
pcap/radius
Normal file
@@ -0,0 +1,41 @@
|
||||
/* Frame (255 bytes) */
|
||||
static const unsigned char pkt41[255] = {
|
||||
0x14, 0x98, 0x77, 0x71, 0xc6, 0xe7, 0x34, 0xef, /* ..wq..4. */
|
||||
0xb6, 0xaf, 0x4a, 0x5c, 0x08, 0x00, 0x45, 0x00, /* ..J\..E. */
|
||||
0x00, 0xf1, 0x87, 0x50, 0x00, 0x00, 0x40, 0x11, /* ...P..@. */
|
||||
0x0c, 0xdf, 0xc0, 0xa8, 0xb2, 0x1b, 0xc0, 0xa8, /* ........ */
|
||||
0xb2, 0x60, 0xc3, 0xfe, 0x07, 0x14, 0x00, 0xdd, /* .`...... */
|
||||
0x26, 0x63, 0x01, 0x04, 0x00, 0xd5, 0xcc, 0x29, /* &c.....) */
|
||||
0x82, 0x36, 0xd6, 0x57, 0x3d, 0xa7, 0xd5, 0x62, /* .6.W=..b */
|
||||
0x70, 0x12, 0x00, 0xc0, 0xf2, 0x19, 0x01, 0x03, /* p....... */
|
||||
0x61, 0x1e, 0x1c, 0x33, 0x34, 0x2d, 0x45, 0x46, /* a..34-EF */
|
||||
0x2d, 0x42, 0x36, 0x2d, 0x41, 0x46, 0x2d, 0x34, /* -B6-AF-4 */
|
||||
0x41, 0x2d, 0x36, 0x30, 0x3a, 0x4f, 0x70, 0x65, /* A-60:Ope */
|
||||
0x6e, 0x57, 0x69, 0x66, 0x69, 0x3d, 0x06, 0x00, /* nWifi=.. */
|
||||
0x00, 0x00, 0x13, 0x06, 0x06, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x02, 0x05, 0x06, 0x00, 0x00, 0x00, 0x01, 0x1f, /* ........ */
|
||||
0x13, 0x42, 0x36, 0x2d, 0x43, 0x34, 0x2d, 0x30, /* .B6-C4-0 */
|
||||
0x36, 0x2d, 0x30, 0x39, 0x2d, 0x31, 0x35, 0x2d, /* 6-09-15- */
|
||||
0x42, 0x37, 0x4d, 0x18, 0x43, 0x4f, 0x4e, 0x4e, /* B7M.CONN */
|
||||
0x45, 0x43, 0x54, 0x20, 0x35, 0x34, 0x4d, 0x62, /* ECT 54Mb */
|
||||
0x70, 0x73, 0x20, 0x38, 0x30, 0x32, 0x2e, 0x31, /* ps 802.1 */
|
||||
0x31, 0x61, 0x2c, 0x12, 0x33, 0x42, 0x45, 0x44, /* 1a,.3BED */
|
||||
0x37, 0x32, 0x39, 0x30, 0x44, 0x30, 0x43, 0x38, /* 7290D0C8 */
|
||||
0x35, 0x36, 0x44, 0x33, 0xba, 0x06, 0x00, 0x0f, /* 56D3.... */
|
||||
0xac, 0x04, 0xbb, 0x06, 0x00, 0x0f, 0xac, 0x04, /* ........ */
|
||||
0xbc, 0x06, 0x00, 0x0f, 0xac, 0x05, 0xbd, 0x06, /* ........ */
|
||||
0x00, 0x0f, 0xac, 0x06, 0x1a, 0x1b, 0x00, 0x00, /* ........ */
|
||||
0xe6, 0x08, 0x47, 0x15, 0x01, 0x13, 0x33, 0x34, /* ..G...34 */
|
||||
0x2d, 0x65, 0x66, 0x2d, 0x62, 0x36, 0x2d, 0x61, /* -ef-b6-a */
|
||||
0x66, 0x2d, 0x34, 0x61, 0x2d, 0x35, 0x63, 0x0c, /* f-4a-5c. */
|
||||
0x06, 0x00, 0x00, 0x05, 0x78, 0x4f, 0x08, 0x02, /* ....xO.. */
|
||||
0x01, 0x00, 0x06, 0x01, 0x61, 0x50, 0x12, 0x20, /* ....aP. */
|
||||
0x9c, 0xae, 0xe5, 0xe3, 0x77, 0xaf, 0x0b, 0x1b, /* ....w... */
|
||||
0xaf, 0x0e, 0xb5, 0x08, 0x82, 0x9e, 0xeb /* ....... */
|
||||
};
|
||||
|
||||
/* Reassembled EAP (6 bytes) */
|
||||
static const unsigned char pkt41_1[6] = {
|
||||
0x02, 0x01, 0x00, 0x06, 0x01, 0x61 /* .....a */
|
||||
};
|
||||
|
||||
1
pcap/radius.blob.bin
Normal file
1
pcap/radius.blob.bin
Normal file
@@ -0,0 +1 @@
|
||||
192.168.178.1
|
||||
BIN
pcap/radius.pcapng
Normal file
BIN
pcap/radius.pcapng
Normal file
Binary file not shown.
@@ -16,7 +16,6 @@
|
||||
"weight" : 10,
|
||||
"radsec" : true,
|
||||
"radsecPort" : 2083,
|
||||
"allowSelfSigned" : false,
|
||||
"radsecSecret" : "radsec",
|
||||
"radsecKey" : "LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUR6RnpXeTZlYXg0QVoxTySG9VUURRZ0FFS3BnWVBHMktPTVd2S0w1Z3NMRXpUc09rREg1M3NHaEQyS3RsRXBDTXVnNDNIZlFnTFVpUgpTR1R2S1l0bDFmbmJaU1lnY0RJdncxdjNYRy9hVDhOY2JBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=",
|
||||
"radsecCert" : "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNRVENDQWVpZ0F3SUJBZ0lVY3BKS3pVM0Ba0dBMVVFQmhNQ1ZWTXhFekFSQmdOVkJBb1RDa0oxZEhSdmJuZHZiMlF4SFRBYkJnTlZCQU1URkVKMQpkSFJ2Ym5kdmIyUWdVbUZrYzJWaklFTkJNQjRYRFRJeU1EY3dNekExTWpVeE5Gb1hEVEkzTURVeE9UQTFNalV4Ck5Gb3dkVEVMTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFvVENrSjFkSFJ2Ym5kdmIyUXhOakEwQmdOVkJBTVQKTFdGeWFXeHBZUzVqWWpFd2FtTnVjemgxYlhCbk9HWnBjRFowTUM1dmNtbHZiaTVoY21WaE1USXdMbU52YlRFWgpNQmNHQ2dtU0pvbVQ4aXhrQVFFVENVZHZiMmRzWlRwVlV6QlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VICkEwSUFCQ3FZR0R4dGlqakZyeWkrWUxDeE0wN0RwQXgrZDdCb1E5aXJaUktRakxvT054MzBJQzFJa1Voazd5bUwKWmRYNTIyVW1JSEF5TDhOYjkxeHYyay9EWEd5amdZa3dnWVl3RGdZRFZSMFBBUUgvQkFRREFnZUFNQk1HQTFVZApKUVFNTUFvR0NDc0dBUVVGQndNQ01Bd0dBMVVkRXdFQi93UUNNQUF3T0FZRFZSMFJCREV3TDRJdFlYSnBiR2xoCkxtTmlNVEJxWTI1ek9IVnRjR2M0Wm1sd05uUXdMbTl5YVc5dUxtRnlaV0V4TWpBdVkyOXRNQmNHQTFVZElBUVEKTUE0d0RBWUtLd1lCQkFIdUtnRUJCVEFLQmdncWhrak9QUVFEQWdOSEFEQkVBaUFwTmM1dUNBSkp6KzVyakdqdwpCWGtOdHE3UU83bWU5dUg5bkNsTDZnSVE5Z0lnUHM2VkVKVW5CcEZ0RktXbFF4eWJ1YlBxYnpJNjBPSERHQ0ExCmhXUk1PS1U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K",
|
||||
|
||||
24
run.sh
Executable file
24
run.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
daemon=ucentralgw
|
||||
|
||||
if [[ "$1" == "aws" ]]
|
||||
then
|
||||
cp ${daemon}.properties.aws ${daemon}.properties
|
||||
. ./set_env.sh
|
||||
cd cmake-build
|
||||
./${daemon} --daemon
|
||||
echo "Running AWS version as daemon..."
|
||||
fi
|
||||
|
||||
if [[ "$1" == "priv" ]]
|
||||
then
|
||||
cp ${daemon}.properties.priv ${daemon}.properties
|
||||
. ./set_env.sh
|
||||
cd cmake-build
|
||||
./${daemon} --daemon
|
||||
echo "Running private version as daemon..."
|
||||
fi
|
||||
|
||||
|
||||
|
||||
@@ -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) ,
|
||||
@@ -70,17 +62,33 @@ namespace OpenWifi {
|
||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
|
||||
*this, &AP_WS_Connection::OnSocketError));
|
||||
Registered_ = true;
|
||||
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;
|
||||
|
||||
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 +96,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 +136,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 +145,6 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
State_.certificateExpiryDate = PeerCert.expiresOn().timestamp().epochTime();
|
||||
SerialNumber_ = CN_;
|
||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
||||
|
||||
@@ -182,12 +189,131 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
void AP_WS_Connection::CompleteStartup() {
|
||||
|
||||
std::lock_guard Guard(Mutex_);
|
||||
auto TC = ThreadedCounter(Threaded_,ConcurrentStartingDevices_);
|
||||
|
||||
try {
|
||||
auto SockImpl = dynamic_cast<Poco::Net::WebSocketImpl *>(WS_->impl());
|
||||
auto SS = dynamic_cast<Poco::Net::SecureStreamSocketImpl*>(SockImpl->streamSocketImpl());
|
||||
|
||||
/* while (true) {
|
||||
auto V = SS->completeHandshake();
|
||||
if (V == 1)
|
||||
break;
|
||||
}
|
||||
*/
|
||||
PeerAddress_ = SS->peerAddress().host();
|
||||
CId_ = Utils::FormatIPv6(SS->peerAddress().toString());
|
||||
|
||||
State_.started = OpenWifi::Now();
|
||||
|
||||
if (!SS->secure()) {
|
||||
poco_warning(Logger_,fmt::format("CONNECTION({}): Session={} Connection is NOT secure. Device is not allowed.", CId_, State_.sessionId ));
|
||||
return EndConnection();
|
||||
}
|
||||
|
||||
poco_debug(Logger_,fmt::format("CONNECTION({}): Session={} Connection is secure.", CId_, State_.sessionId ));
|
||||
|
||||
if (!SS->havePeerCertificate()) {
|
||||
State_.VerifiedCertificate = GWObjects::NO_CERTIFICATE;
|
||||
poco_warning(Logger_,fmt::format("CONNECTION({}): Session={} No certificates available..", CId_, State_.sessionId ));
|
||||
return EndConnection();
|
||||
}
|
||||
|
||||
Poco::Crypto::X509Certificate PeerCert(SS->peerCertificate());
|
||||
if (!AP_WS_Server()->ValidateCertificate(CId_, PeerCert)) {
|
||||
State_.VerifiedCertificate = GWObjects::NO_CERTIFICATE;
|
||||
poco_warning(Logger_, fmt::format("CONNECTION({}): Session={} Device certificate is not valid. Device is not allowed.",
|
||||
CId_, State_.sessionId ));
|
||||
return EndConnection();
|
||||
}
|
||||
CN_ = Poco::trim(Poco::toLower(PeerCert.commonName()));
|
||||
State_.VerifiedCertificate = GWObjects::VALID_CERTIFICATE;
|
||||
poco_debug(Logger_,
|
||||
fmt::format("CONNECTION({}): Session={} Valid certificate: CN={}", CId_, State_.sessionId , CN_));
|
||||
|
||||
if (AP_WS_Server::IsSim(CN_) && !AP_WS_Server()->IsSimEnabled()) {
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("CONNECTION({}): Session={} Sim Device {} is not allowed. Disconnecting.",
|
||||
CId_, State_.sessionId , CN_));
|
||||
return EndConnection();
|
||||
}
|
||||
|
||||
if (!CN_.empty() && StorageService()->IsBlackListed(SerialNumber_)) {
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("CONNECTION({}): Session={} Device {} is black listed. Disconnecting.",
|
||||
CId_, State_.sessionId , CN_));
|
||||
return EndConnection();
|
||||
}
|
||||
|
||||
SerialNumber_ = CN_;
|
||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
||||
|
||||
WS_->setMaxPayloadSize(BufSize);
|
||||
auto TS = Poco::Timespan(360, 0);
|
||||
WS_->setReceiveTimeout(TS);
|
||||
WS_->setNoDelay(true);
|
||||
WS_->setKeepAlive(true);
|
||||
WS_->setBlocking(false);
|
||||
|
||||
Reactor_.addEventHandler(
|
||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
|
||||
*this, &AP_WS_Connection::OnSocketReadable));
|
||||
Reactor_.addEventHandler(
|
||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
|
||||
*this, &AP_WS_Connection::OnSocketShutdown));
|
||||
Reactor_.addEventHandler(
|
||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
|
||||
*this, &AP_WS_Connection::OnSocketError));
|
||||
Registered_ = true;
|
||||
poco_debug(Logger_, fmt::format("CONNECTION({}): Session={} CN={} Completed. (t={})", CId_, State_.sessionId , CN_, ConcurrentStartingDevices_));
|
||||
return;
|
||||
} catch (const Poco::Net::CertificateValidationException &E) {
|
||||
poco_error(Logger_,fmt::format("CONNECTION({}): Session:{} Poco::CertificateValidationException Certificate Validation failed during connection. Device will have to retry.",
|
||||
CId_, State_.sessionId ));
|
||||
Logger_.log(E);
|
||||
} catch (const Poco::Net::WebSocketException &E) {
|
||||
poco_error(Logger_,fmt::format("CONNECTION({}): Session:{} Poco::WebSocketException WebSocket error during connection. Device will have to retry.",
|
||||
CId_, State_.sessionId ));
|
||||
Logger_.log(E);
|
||||
} catch (const Poco::Net::ConnectionAbortedException &E) {
|
||||
poco_error(Logger_,fmt::format("CONNECTION({}):Session:{} Poco::ConnectionAbortedException Connection was aborted during connection. Device will have to retry.",
|
||||
CId_, State_.sessionId ));
|
||||
Logger_.log(E);
|
||||
} catch (const Poco::Net::ConnectionResetException &E) {
|
||||
poco_error(Logger_,fmt::format("CONNECTION({}): Session:{} Poco::ConnectionResetException Connection was reset during connection. Device will have to retry.",
|
||||
CId_, State_.sessionId ));
|
||||
Logger_.log(E);
|
||||
} catch (const Poco::Net::InvalidCertificateException &E) {
|
||||
poco_error(Logger_,fmt::format(
|
||||
"CONNECTION({}): Session:{} Poco::InvalidCertificateException Invalid certificate. Device will have to retry.",
|
||||
CId_, State_.sessionId ));
|
||||
Logger_.log(E);
|
||||
} catch (const Poco::Net::SSLException &E) {
|
||||
poco_error(Logger_,fmt::format("CONNECTION({}): Session:{} Poco::SSLException SSL Exception during connection. Device will have to retry.",
|
||||
CId_, State_.sessionId ));
|
||||
Logger_.log(E);
|
||||
} catch (const Poco::Exception &E) {
|
||||
poco_error(Logger_,fmt::format("CONNECTION({}): Session:{} Poco::Exception caught during device connection. Device will have to retry.",
|
||||
CId_, State_.sessionId ));
|
||||
Logger_.log(E);
|
||||
} catch (...) {
|
||||
poco_error(Logger_,fmt::format("CONNECTION({}): Session:{} Exception caught during device connection. Device will have to retry. Unsecure connect denied.",
|
||||
CId_, State_.sessionId ));
|
||||
}
|
||||
return EndConnection();
|
||||
}
|
||||
|
||||
static void NotifyKafkaDisconnect(const std::string & SerialNumber) {
|
||||
try {
|
||||
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;
|
||||
@@ -198,41 +324,36 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
AP_WS_Connection::~AP_WS_Connection() {
|
||||
Valid_=false;
|
||||
EndConnection();
|
||||
if(!Dead_)
|
||||
EndConnection();
|
||||
}
|
||||
|
||||
void AP_WS_Connection::EndConnection() {
|
||||
Valid_=false;
|
||||
if(!Dead_.test_and_set()) {
|
||||
Dead_=true;
|
||||
poco_information(Logger_,fmt::format("CONNECTION-CLOSING({}): Session={} Serial={}.", CId_, State_.sessionId, SerialNumber_));
|
||||
auto SessionDeleted = DeviceRegistry()->EndSession(State_.sessionId, SerialNumberInt_);
|
||||
|
||||
if (Registered_) {
|
||||
Registered_ = false;
|
||||
Reactor_.removeEventHandler(
|
||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
|
||||
*this, &AP_WS_Connection::OnSocketReadable));
|
||||
Reactor_.removeEventHandler(
|
||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
|
||||
*this, &AP_WS_Connection::OnSocketShutdown));
|
||||
Reactor_.removeEventHandler(
|
||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
|
||||
*this, &AP_WS_Connection::OnSocketError));
|
||||
}
|
||||
WS_->close();
|
||||
|
||||
if (KafkaManager()->Enabled() && !SerialNumber_.empty()) {
|
||||
std::string s(SerialNumber_);
|
||||
std::thread t([s]() { NotifyKafkaDisconnect(s); });
|
||||
t.detach();
|
||||
}
|
||||
|
||||
auto SessionDeleted = AP_WS_Server()->EndSession(State_.sessionId, SerialNumberInt_);
|
||||
if (SessionDeleted) {
|
||||
GWWebSocketNotifications::SingleDevice_t N;
|
||||
N.content.serialNumber = SerialNumber_;
|
||||
GWWebSocketNotifications::DeviceDisconnected(N);
|
||||
}
|
||||
if (Registered_) {
|
||||
Reactor_.removeEventHandler(
|
||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
|
||||
*this, &AP_WS_Connection::OnSocketReadable));
|
||||
Reactor_.removeEventHandler(
|
||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
|
||||
*this, &AP_WS_Connection::OnSocketShutdown));
|
||||
Reactor_.removeEventHandler(
|
||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
|
||||
*this, &AP_WS_Connection::OnSocketError));
|
||||
}
|
||||
WS_->close();
|
||||
|
||||
if (KafkaManager()->Enabled() && !SerialNumber_.empty()) {
|
||||
std::string s(SerialNumber_);
|
||||
std::thread t([s]() { NotifyKafkaDisconnect(s); });
|
||||
t.detach();
|
||||
}
|
||||
if(SessionDeleted)
|
||||
WebSocketClientNotificationDeviceDisconnected(SerialNumber_);
|
||||
AP_WS_Server()->DeleteConnection(State_.sessionId);
|
||||
}
|
||||
|
||||
bool AP_WS_Connection::LookForUpgrade(const uint64_t UUID, uint64_t & UpgradedUUID) {
|
||||
@@ -272,7 +393,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 +413,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 +424,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 +549,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 +570,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 +593,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 +608,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 +622,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 +634,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_--;
|
||||
@@ -530,19 +647,19 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void AP_WS_Connection::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
poco_trace(Logger_, fmt::format("SOCKET-SHUTDOWN({}): Closing.", CId_));
|
||||
return EndConnection();
|
||||
}
|
||||
|
||||
void AP_WS_Connection::OnSocketError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
poco_trace(Logger_, fmt::format("SOCKET-ERROR({}): Closing.", CId_));
|
||||
return EndConnection();
|
||||
}
|
||||
|
||||
void AP_WS_Connection::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
||||
|
||||
if(!Valid_)
|
||||
return;
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
if(!AP_WS_Server()->Running())
|
||||
return EndConnection();
|
||||
@@ -582,7 +699,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 +707,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 +716,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;
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <shared_mutex>
|
||||
|
||||
#include "Poco/Net/SocketReactor.h"
|
||||
#include "Poco/Net/StreamSocket.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
@@ -14,8 +12,10 @@
|
||||
#include "Poco/Logger.h"
|
||||
#include "Poco/Net/WebSocket.h"
|
||||
|
||||
#include "DeviceRegistry.h"
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class AP_WS_Connection {
|
||||
@@ -23,7 +23,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 +43,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 +82,10 @@ namespace OpenWifi {
|
||||
return true;
|
||||
}
|
||||
|
||||
friend class AP_WS_Server;
|
||||
|
||||
inline GWObjects::DeviceRestrictions Restrictions() const {
|
||||
std::shared_lock G(ConnectionMutex_);
|
||||
return Restrictions_;
|
||||
}
|
||||
friend class DeviceRegistry;
|
||||
|
||||
private:
|
||||
mutable std::shared_mutex ConnectionMutex_;
|
||||
std::recursive_mutex Mutex_;
|
||||
std::shared_mutex TelemetryMutex_;
|
||||
Poco::Logger &Logger_;
|
||||
Poco::Net::SocketReactor &Reactor_;
|
||||
@@ -133,28 +98,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};
|
||||
std::atomic_flag Dead_=false;
|
||||
bool Threaded_=false;
|
||||
std::atomic_bool 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);
|
||||
void CompleteStartup();
|
||||
bool StartTelemetry(std::uint64_t RPCID);
|
||||
bool StopTelemetry(std::uint64_t RPCID);
|
||||
void UpdateCounts();
|
||||
};
|
||||
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
//
|
||||
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "fmt/format.h"
|
||||
#include "framework/ow_constants.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_cfgpending(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
|
||||
@@ -6,157 +6,119 @@
|
||||
#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 Capabilities = ParamsObj->get(uCentralProtocol::CAPABILITIES).toString();
|
||||
|
||||
SerialNumber_ = Serial;
|
||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
||||
//// change this
|
||||
SerialNumber_ = Serial;
|
||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
||||
|
||||
CommandManager()->ClearQueue(SerialNumberInt_);
|
||||
CommandManager()->ClearQueue(SerialNumberInt_);
|
||||
|
||||
AP_WS_Server()->SetSessionDetails(State_.sessionId,SerialNumberInt_);
|
||||
DeviceRegistry()->SetSessionDetails(State_.sessionId,SerialNumberInt_);
|
||||
State_.UUID = UUID;
|
||||
State_.Firmware = Firmware;
|
||||
State_.PendingUUID = 0;
|
||||
State_.Address = Utils::FormatIPv6(WS_->peerAddress().toString());
|
||||
CId_ = SerialNumber_ + "@" + CId_;
|
||||
|
||||
std::lock_guard Lock(ConnectionMutex_);
|
||||
Config::Capabilities Caps(Capabilities);
|
||||
|
||||
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_, Capabilities, Firmware,
|
||||
Compatible_, PeerAddress_);
|
||||
} else if (DeviceExists) {
|
||||
StorageService()->UpdateDeviceCapabilities(SerialNumber_, Capabilities,
|
||||
Compatible_);
|
||||
bool Updated = false;
|
||||
if(!Firmware.empty() && Firmware!=DeviceInfo.Firmware) {
|
||||
DeviceInfo.Firmware = Firmware;
|
||||
Updated = true;
|
||||
WebSocketClientNotificationDeviceFirmwareUpdated(SerialNumber_, Firmware);
|
||||
}
|
||||
|
||||
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_);
|
||||
|
||||
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_++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
//
|
||||
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "fmt/format.h"
|
||||
#include "framework/ow_constants.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_ping(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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_));
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,8 +10,6 @@
|
||||
#include "Poco/Net/SocketAcceptor.h"
|
||||
#include "Poco/Environment.h"
|
||||
|
||||
#include "framework/utils.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class AP_WS_ReactorThreadPool {
|
||||
public:
|
||||
|
||||
@@ -7,19 +7,13 @@
|
||||
//
|
||||
|
||||
#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"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void AP_WS_RequestHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||
@@ -44,8 +38,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 +70,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 +126,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,66 +139,18 @@ 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());
|
||||
|
||||
Running_ = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AP_WS_Server::onGarbageCollecting([[maybe_unused]] Poco::Timer &timer) {
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
if(!Garbage_.empty()) {
|
||||
Garbage_.clear();
|
||||
}
|
||||
|
||||
static uint64_t last_log = Utils::Now();
|
||||
|
||||
NumberOfConnectedDevices_ = 0;
|
||||
NumberOfConnectingDevices_ = 0;
|
||||
AverageDeviceConnectionTime_ = 0;
|
||||
uint64_t total_connected_time=0;
|
||||
|
||||
auto now = Utils::Now();
|
||||
for (const auto & connection:SerialNumbers_) {
|
||||
if(connection.second.second == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (connection.second.second->State_.Connected) {
|
||||
NumberOfConnectedDevices_++;
|
||||
total_connected_time += (now - connection.second.second->State_.started);
|
||||
} else {
|
||||
NumberOfConnectingDevices_++;
|
||||
}
|
||||
}
|
||||
|
||||
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_));
|
||||
}
|
||||
|
||||
GWWebSocketNotifications::NumberOfConnection_t Notification;
|
||||
Notification.content.numberOfConnectingDevices = NumberOfConnectingDevices_;
|
||||
Notification.content.numberOfDevices = NumberOfConnectedDevices_;
|
||||
Notification.content.averageConnectedTime = AverageDeviceConnectionTime_;
|
||||
GWWebSocketNotifications::NumberOfConnections(Notification);
|
||||
}
|
||||
|
||||
void AP_WS_Server::Stop() {
|
||||
poco_information(Logger(),"Stopping...");
|
||||
Running_ = false;
|
||||
|
||||
Timer_.stop();
|
||||
|
||||
for(auto &server:WebServers_) {
|
||||
server->stopAll();
|
||||
}
|
||||
@@ -214,264 +160,4 @@ 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);
|
||||
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);
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AP_WS_Server::SetSessionDetails(uint64_t connection_id, uint64_t SerialNumber) {
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
|
||||
auto Conn = Sessions_.find(connection_id);
|
||||
if(Conn == end(Sessions_))
|
||||
return;
|
||||
|
||||
auto CurrentSerialNumber = SerialNumbers_.find(SerialNumber);
|
||||
if( (CurrentSerialNumber==SerialNumbers_.end()) ||
|
||||
(CurrentSerialNumber->second.first<connection_id)) {
|
||||
SerialNumbers_[SerialNumber] = std::make_pair(connection_id, Conn->second);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool AP_WS_Server::EndSession(uint64_t session_id, uint64_t serial_number) {
|
||||
std::lock_guard G(WSServerMutex_);
|
||||
|
||||
auto Session = Sessions_.find(session_id);
|
||||
if(Session==end(Sessions_))
|
||||
return false;
|
||||
|
||||
Garbage_.push_back(Session->second);
|
||||
|
||||
auto Device = SerialNumbers_.find(serial_number);
|
||||
if (Device == end(SerialNumbers_)) {
|
||||
Sessions_.erase(Session);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(Device->second.first==session_id) {
|
||||
Sessions_.erase(Session);
|
||||
SerialNumbers_.erase(Device);
|
||||
return true;
|
||||
}
|
||||
|
||||
Sessions_.erase(Session);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
try {
|
||||
return DevicePtr->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_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||
return;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->StopWebSocketTelemetry(RPCID);
|
||||
}
|
||||
|
||||
void AP_WS_Server::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||
return;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime);
|
||||
}
|
||||
|
||||
void AP_WS_Server::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||
return;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime);
|
||||
}
|
||||
|
||||
void AP_WS_Server::StopKafkaTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||
return;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->StopKafkaTelemetry(RPCID);
|
||||
}
|
||||
|
||||
void AP_WS_Server::GetTelemetryParameters(uint64_t SerialNumber , bool & TelemetryRunning,
|
||||
uint64_t & TelemetryInterval,
|
||||
uint64_t & TelemetryWebSocketTimer,
|
||||
uint64_t & TelemetryKafkaTimer,
|
||||
uint64_t & TelemetryWebSocketCount,
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
try {
|
||||
return DevicePtr->SendRadiusAccountingData(buffer,size);
|
||||
} catch (...) {
|
||||
poco_debug(Logger(),fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'", SerialNumber));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
try {
|
||||
return DevicePtr->SendRadiusAuthenticationData(buffer,size);
|
||||
} catch (...) {
|
||||
poco_debug(Logger(),fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'", SerialNumber));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
try {
|
||||
return DevicePtr->SendRadiusCoAData(buffer,size);
|
||||
} catch (...) {
|
||||
poco_debug(Logger(),fmt::format(": SendRadiusCoAData: Could not send data to device '{}'", SerialNumber));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} //namespace
|
||||
@@ -13,27 +13,21 @@
|
||||
#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 +36,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 +57,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 +89,7 @@ namespace OpenWifi {
|
||||
return AllowSerialNumberMismatch_;
|
||||
}
|
||||
|
||||
inline uint64_t MismatchDepth() const {
|
||||
inline std::uint64_t MismatchDepth() const {
|
||||
return MismatchDepth_;
|
||||
}
|
||||
|
||||
@@ -105,101 +99,42 @@ 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::unique_lock Lock(LocalMutex_);
|
||||
Connections_[session_id] = Connection;
|
||||
}
|
||||
|
||||
inline std::shared_ptr<AP_WS_Connection> FindConnection(uint64_t session_id) const {
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
inline void DeleteConnection(std::uint64_t session_id) {
|
||||
std::unique_lock Lock(LocalMutex_);
|
||||
Connections_.erase(session_id);
|
||||
}
|
||||
|
||||
auto Connection = Sessions_.find(session_id);
|
||||
if(Connection!=end(Sessions_))
|
||||
inline std::shared_ptr<AP_WS_Connection> FindConnection(std::uint64_t session_id) const {
|
||||
std::shared_lock Lock(LocalMutex_);
|
||||
|
||||
auto Connection = Connections_.find(session_id);
|
||||
if(Connection!=end(Connections_))
|
||||
return Connection->second;
|
||||
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 ;
|
||||
|
||||
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;
|
||||
|
||||
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 Connected(uint64_t SerialNumber, GWObjects::DeviceRestrictions & Restrictions) const ;
|
||||
bool Connected(uint64_t SerialNumber) const ;
|
||||
|
||||
inline bool SendFrame(const std::string & SerialNumber, const std::string & Payload) const {
|
||||
return SendFrame(Utils::SerialNumberToInt(SerialNumber), Payload);
|
||||
}
|
||||
|
||||
bool SendFrame(uint64_t SerialNumber, const std::string & Payload) const ;
|
||||
|
||||
bool SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, 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 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 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 onGarbageCollecting(Poco::Timer & timer);
|
||||
|
||||
inline void AverageDeviceStatistics( uint64_t & Connections, uint64_t & AverageConnectionTime, uint64_t & NumberOfConnectingDevices) const {
|
||||
Connections = NumberOfConnectedDevices_;
|
||||
AverageConnectionTime = AverageDeviceConnectionTime_;
|
||||
NumberOfConnectingDevices = NumberOfConnectingDevices_;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::recursive_mutex WSServerMutex_;
|
||||
mutable std::shared_mutex LocalMutex_;
|
||||
std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_;
|
||||
std::list<std::unique_ptr<Poco::Net::HTTPServer>> WebServers_;
|
||||
Poco::Net::SocketReactor Reactor_;
|
||||
Poco::Thread ReactorThread_;
|
||||
std::string SimulatorId_;
|
||||
Poco::ThreadPool DeviceConnectionPool_{"ws:dev-pool", 2, 64};
|
||||
Poco::ThreadPool DeviceConnectionPool_{"ws:dev-pool", 2, 32};
|
||||
bool LookAtProvisioning_ = false;
|
||||
bool UseDefaultConfig_ = true;
|
||||
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::shared_ptr<AP_WS_Connection>> Connections_;
|
||||
std::atomic_bool AllowSerialNumberMismatch_=true;
|
||||
std::atomic_uint64_t MismatchDepth_=2;
|
||||
|
||||
std::atomic_uint64_t NumberOfConnectedDevices_=0;
|
||||
std::atomic_uint64_t AverageDeviceConnectionTime_=0;
|
||||
std::atomic_uint64_t NumberOfConnectingDevices_=0;
|
||||
|
||||
std::vector<std::shared_ptr<AP_WS_Connection>> Garbage_;
|
||||
|
||||
std::unique_ptr<Poco::TimerCallback<AP_WS_Server>> GarbageCollectorCallback_;
|
||||
Poco::Timer Timer_;
|
||||
Poco::Thread GarbageCollector_;
|
||||
|
||||
AP_WS_Server() noexcept:
|
||||
SubSystemServer("WebSocketServer", "WS-SVR", "ucentral.websocket") {
|
||||
}
|
||||
|
||||
@@ -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(); };
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -8,16 +8,14 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
#include "CommandManager.h"
|
||||
#include "AP_WS_Server.h"
|
||||
#include "DeviceRegistry.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_);
|
||||
std::unique_lock 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;
|
||||
}
|
||||
@@ -160,7 +110,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void CommandManager::onJanitorTimer([[maybe_unused]] Poco::Timer & timer) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
std::unique_lock Lock(LocalMutex_);
|
||||
Utils::SetThreadName("cmd:janitor");
|
||||
Poco::Logger & MyLogger = Poco::Logger::get("CMD-MGR-JANITOR");
|
||||
auto now = std::chrono::high_resolution_clock::now();
|
||||
@@ -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 {
|
||||
@@ -181,7 +131,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
bool CommandManager::IsCommandRunning(const std::string &C) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
std::shared_lock Lock(LocalMutex_);
|
||||
for (const auto &request : OutStandingRequests_) {
|
||||
if (request.second.UUID == C) {
|
||||
return true;
|
||||
@@ -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(
|
||||
@@ -228,7 +178,7 @@ namespace OpenWifi {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!AP_WS_Server()->Connected(
|
||||
if (!DeviceRegistry()->Connected(
|
||||
Utils::SerialNumberToInt(Cmd.SerialNumber))) {
|
||||
poco_trace(
|
||||
MyLogger,
|
||||
@@ -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));
|
||||
if(AP_WS_Server()->SendFrame(SerialNumber, ToSend.str())) {
|
||||
poco_debug(Logger(), fmt::format("{}: Sending command. ID: {}", UUID, RPCID));
|
||||
if(DeviceRegistry()->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
|
||||
@@ -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,15 +144,16 @@ 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) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
inline bool CommandRunningForDevice(std::uint64_t SerialNumber, std::string & uuid, std::string &command) {
|
||||
std::shared_lock Lock(LocalMutex_);
|
||||
|
||||
for(const auto &[Request,Command]:OutStandingRequests_) {
|
||||
if(Command.SerialNumber==SerialNumber) {
|
||||
@@ -178,7 +166,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
inline void ClearQueue(std::uint64_t SerialNumber) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
std::unique_lock Lock(LocalMutex_);
|
||||
for(auto Request = OutStandingRequests_.begin(); Request != OutStandingRequests_.end() ; ) {
|
||||
if(Request->second.SerialNumber==SerialNumber)
|
||||
Request = OutStandingRequests_.erase(Request);
|
||||
@@ -188,7 +176,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::recursive_mutex LocalMutex_;
|
||||
mutable std::shared_mutex LocalMutex_;
|
||||
std::atomic_bool Running_ = false;
|
||||
Poco::Thread ManagerThread;
|
||||
std::atomic_uint64_t Id_=3; // do not start @1. We ignore ID=1 & 0 is illegal..
|
||||
@@ -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,
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class ConfigurationCache {
|
||||
|
||||
@@ -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"
|
||||
@@ -15,6 +17,7 @@
|
||||
#include "AP_WS_Server.h"
|
||||
#include "CommandManager.h"
|
||||
#include "Daemon.h"
|
||||
#include "DeviceRegistry.h"
|
||||
#include "FileUploader.h"
|
||||
#include "FindCountry.h"
|
||||
#include "OUIServer.h"
|
||||
@@ -26,10 +29,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 +41,10 @@ namespace OpenWifi {
|
||||
StorageService(),
|
||||
SerialNumberCache(),
|
||||
ConfigurationValidator(),
|
||||
UI_WebSocketClientServer(),
|
||||
WebSocketClientServer(),
|
||||
OUIServer(),
|
||||
FindCountryFromIP(),
|
||||
DeviceRegistry(),
|
||||
CommandManager(),
|
||||
FileUploader(),
|
||||
StorageArchiver(),
|
||||
@@ -52,8 +52,6 @@ namespace OpenWifi {
|
||||
RTTYS_server(),
|
||||
RADIUS_proxy_server(),
|
||||
VenueBroadcaster(),
|
||||
ScriptManager(),
|
||||
SignatureManager(),
|
||||
AP_WS_Server()
|
||||
});
|
||||
return &instance;
|
||||
@@ -107,11 +105,6 @@ namespace OpenWifi {
|
||||
}
|
||||
return "AP";
|
||||
}
|
||||
|
||||
void DaemonPostInitialization(Poco::Util::Application &self) {
|
||||
Daemon()->PostInitialization(self);
|
||||
GWWebSocketNotifications::Register();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
15
src/Daemon.h
15
src/Daemon.h
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,49 +3,18 @@
|
||||
//
|
||||
|
||||
#include "Dashboard.h"
|
||||
#include "DeviceRegistry.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
263
src/DeviceRegistry.cpp
Normal file
263
src/DeviceRegistry.cpp
Normal file
@@ -0,0 +1,263 @@
|
||||
//
|
||||
// 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
104
src/DeviceRegistry.h
Normal 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
|
||||
|
||||
@@ -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_ )
|
||||
|
||||
@@ -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_;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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"};
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -11,42 +11,20 @@
|
||||
#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";
|
||||
|
||||
bool Recovered = false;
|
||||
Poco::File OuiFile(CurrentOUIFileName_);
|
||||
if(OuiFile.exists()) {
|
||||
std::unique_lock Lock(LocalMutex_);
|
||||
Recovered = ProcessFile(CurrentOUIFileName_,OUIs_);
|
||||
if(Recovered) {
|
||||
poco_notice(Logger(),
|
||||
fmt::format("Recovered last OUI file - {}", CurrentOUIFileName_));
|
||||
}
|
||||
} else {
|
||||
poco_notice(Logger(),
|
||||
fmt::format("No existing OUIFile.", CurrentOUIFileName_));
|
||||
}
|
||||
LatestOUIFileName_ = MicroService::instance().DataDir() + "/newOUIFile.txt";
|
||||
CurrentOUIFileName_ = MicroService::instance().DataDir() + "/current_oui.txt";
|
||||
|
||||
UpdaterCallBack_ = std::make_unique<Poco::TimerCallback<OUIServer>>(*this, &OUIServer::onTimer);
|
||||
if(Recovered) {
|
||||
Timer_.setStartInterval(60 * 60 * 1000); // first run in 1 hour
|
||||
} else {
|
||||
Timer_.setStartInterval(30 * 1000); // first run in 5 minutes
|
||||
}
|
||||
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 +36,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void OUIServer::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
||||
MicroServiceLoadConfigurationFile();
|
||||
MicroService::instance().LoadConfigurationFile();
|
||||
poco_information(Logger(),"Reinitializing.");
|
||||
Stop();
|
||||
Start();
|
||||
@@ -66,15 +44,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);
|
||||
@@ -124,12 +102,10 @@ namespace OpenWifi {
|
||||
return;
|
||||
Updating_ = true;
|
||||
|
||||
poco_information(Logger(),"Starting to process OUI file...");
|
||||
|
||||
// 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;
|
||||
@@ -146,9 +122,9 @@ namespace OpenWifi {
|
||||
|
||||
OUIMap TmpOUIs;
|
||||
if(GetFile(LatestOUIFileName_) && ProcessFile(LatestOUIFileName_, TmpOUIs)) {
|
||||
std::unique_lock G(LocalMutex_);
|
||||
std::lock_guard G(Mutex_);
|
||||
OUIs_ = std::move(TmpOUIs);
|
||||
LastUpdate_ = Utils::Now();
|
||||
LastUpdate_ = OpenWifi::Now();
|
||||
Poco::File F1(CurrentOUIFileName_);
|
||||
if(F1.exists())
|
||||
F1.remove();
|
||||
@@ -157,19 +133,17 @@ namespace OpenWifi {
|
||||
poco_information(Logger(), fmt::format("New OUI file {} downloaded.",LatestOUIFileName_));
|
||||
} else if(OUIs_.empty()) {
|
||||
if(ProcessFile(CurrentOUIFileName_, TmpOUIs)) {
|
||||
LastUpdate_ = Utils::Now();
|
||||
std::unique_lock G(LocalMutex_);
|
||||
LastUpdate_ = OpenWifi::Now();
|
||||
std::lock_guard G(Mutex_);
|
||||
OUIs_ = std::move(TmpOUIs);
|
||||
}
|
||||
}
|
||||
Initialized_=true;
|
||||
Updating_ = false;
|
||||
poco_information(Logger(),"Done processing OUI file...");
|
||||
}
|
||||
|
||||
std::string OUIServer::GetManufacturer(const std::string &MAC) {
|
||||
std::shared_lock Lock(LocalMutex_);
|
||||
|
||||
std::lock_guard Guard(Mutex_);
|
||||
auto Manufacturer = OUIs_.find(Utils::SerialNumberToOUI(MAC));
|
||||
if(Manufacturer != OUIs_.end())
|
||||
return Manufacturer->second;
|
||||
|
||||
@@ -4,10 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <shared_mutex>
|
||||
|
||||
#include "framework/SubSystemServer.h"
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "Poco/Timer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
@@ -33,7 +30,6 @@ namespace OpenWifi {
|
||||
[[nodiscard]] bool ProcessFile(const std::string &FileName, OUIMap &Map);
|
||||
|
||||
private:
|
||||
std::shared_mutex LocalMutex_;
|
||||
uint64_t LastUpdate_ = 0 ;
|
||||
bool Initialized_ = false;
|
||||
OUIMap OUIs_;
|
||||
|
||||
@@ -4,12 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -2,13 +2,9 @@
|
||||
// Created by stephane bourque on 2022-05-18.
|
||||
//
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
#include "RADIUS_proxy_server.h"
|
||||
#include "DeviceRegistry.h"
|
||||
#include "RADIUS_helpers.h"
|
||||
#include "AP_WS_Server.h"
|
||||
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -19,133 +15,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) {
|
||||
@@ -166,8 +147,8 @@ namespace OpenWifi {
|
||||
auto CallingStationID = P.ExtractCallingStationID();
|
||||
auto CalledStationID = P.ExtractCalledStationID();
|
||||
|
||||
poco_debug(Logger(), fmt::format("Accounting Packet received for {}, CalledStationID: {}, CallingStationID:{}",SerialNumber, CalledStationID, CallingStationID));
|
||||
AP_WS_Server()->SendRadiusAccountingData(SerialNumber,P.Buffer(),P.Size());
|
||||
poco_information(Logger(), fmt::format("Accounting Packet received for {}, CalledStationID: {}, CallingStationID:{}",SerialNumber, CalledStationID, CallingStationID));
|
||||
DeviceRegistry()->SendRadiusAccountingData(SerialNumber,P.Buffer(),P.Size());
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::OnAuthenticationSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
@@ -188,8 +169,8 @@ namespace OpenWifi {
|
||||
auto CallingStationID = P.ExtractCallingStationID();
|
||||
auto CalledStationID = P.ExtractCalledStationID();
|
||||
|
||||
poco_debug(Logger(), fmt::format("Authentication Packet received for {}, CalledStationID: {}, CallingStationID:{}",SerialNumber, CalledStationID, CallingStationID));
|
||||
AP_WS_Server()->SendRadiusAuthenticationData(SerialNumber,P.Buffer(),P.Size());
|
||||
poco_information(Logger(), fmt::format("Authentication Packet received for {}, CalledStationID: {}, CallingStationID:{}",SerialNumber, CalledStationID, CallingStationID));
|
||||
DeviceRegistry()->SendRadiusAuthenticationData(SerialNumber,P.Buffer(),P.Size());
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::OnCoASocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
@@ -210,61 +191,38 @@ namespace OpenWifi {
|
||||
auto CallingStationID = P.ExtractCallingStationID();
|
||||
auto CalledStationID = P.ExtractCalledStationID();
|
||||
|
||||
poco_debug(Logger(), fmt::format("CoA Packet received for {}, CalledStationID: {}, CallingStationID:{}",SerialNumber, CalledStationID, CallingStationID));
|
||||
AP_WS_Server()->SendRadiusCoAData(SerialNumber,P.Buffer(),P.Size());
|
||||
poco_information(Logger(), fmt::format("CoA Packet received for {}, CalledStationID: {}, CallingStationID:{}",SerialNumber, CalledStationID, CallingStationID));
|
||||
DeviceRegistry()->SendRadiusCoAData(SerialNumber,P.Buffer(),P.Size());
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::SendAccountingData(const std::string &serialNumber, const char *buffer, std::size_t size) {
|
||||
RADIUS::RadiusPacket P((unsigned char *)buffer,size);
|
||||
auto Destination = P.ExtractProxyStateDestination();
|
||||
auto CallingStationID = P.ExtractCallingStationID();
|
||||
auto CalledStationID = P.ExtractCalledStationID();
|
||||
Poco::Net::SocketAddress Dst(Destination);
|
||||
|
||||
if(!Continue())
|
||||
return;
|
||||
|
||||
try {
|
||||
RADIUS::RadiusPacket P((unsigned char *)buffer, size);
|
||||
auto Destination = P.ExtractProxyStateDestination();
|
||||
auto CallingStationID = P.ExtractCallingStationID();
|
||||
auto CalledStationID = P.ExtractCalledStationID();
|
||||
Poco::Net::SocketAddress Dst(Destination);
|
||||
|
||||
std::lock_guard G(Mutex_);
|
||||
bool UseRADSEC = false;
|
||||
auto FinalDestination = Route(radius_type::acct, Dst, P, UseRADSEC);
|
||||
if (UseRADSEC) {
|
||||
Poco::Net::SocketAddress RSP(FinalDestination.host(), 0);
|
||||
auto DestinationServer = RADSECservers_.find(RSP);
|
||||
if (DestinationServer != end(RADSECservers_)) {
|
||||
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer,
|
||||
size);
|
||||
}
|
||||
} else {
|
||||
if ((Dst.family() == Poco::Net::SocketAddress::IPv4 &&
|
||||
AccountingSocketV4_ == nullptr) ||
|
||||
(Dst.family() == Poco::Net::SocketAddress::IPv6 &&
|
||||
AccountingSocketV6_ == nullptr)) {
|
||||
poco_debug(
|
||||
Logger(),
|
||||
fmt::format(
|
||||
"ACCT: Trying to use RADIUS GW PROXY but not configured. Device={}",
|
||||
serialNumber));
|
||||
return;
|
||||
}
|
||||
auto AllSent =
|
||||
SendData(Dst.family() == Poco::Net::SocketAddress::IPv4 ? *AccountingSocketV4_
|
||||
: *AccountingSocketV6_,
|
||||
(const unsigned char *)buffer, size, FinalDestination);
|
||||
if (!AllSent)
|
||||
poco_error(Logger(),
|
||||
fmt::format("{}: Could not send Accounting packet packet to {}.",
|
||||
serialNumber, Destination));
|
||||
else
|
||||
poco_debug(Logger(), fmt::format("{}: Sending Accounting Packet to {}, CalledStationID: {}, CallingStationID:{}",
|
||||
serialNumber, FinalDestination.toString(),
|
||||
CalledStationID, CallingStationID));
|
||||
std::lock_guard G(Mutex_);
|
||||
bool UseRADSEC = false;
|
||||
auto FinalDestination = Route(radius_type::acct, Dst, P, UseRADSEC);
|
||||
if(UseRADSEC) {
|
||||
Poco::Net::SocketAddress RSP(FinalDestination.host(),0);
|
||||
auto DestinationServer = RADSECservers_.find(RSP);
|
||||
if(DestinationServer!=end(RADSECservers_)) {
|
||||
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer, size);
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
} catch (...) {
|
||||
poco_warning(Logger(),fmt::format("Bad RADIUS ACCT Packet from {}. Dropped.",serialNumber));
|
||||
} else {
|
||||
auto AllSent =
|
||||
SendData(Dst.family() == Poco::Net::SocketAddress::IPv4 ? *AccountingSocketV4_
|
||||
: *AccountingSocketV6_,
|
||||
(const unsigned char *)buffer, size, FinalDestination);
|
||||
if (!AllSent)
|
||||
poco_error(Logger(),fmt::format("{}: Could not send Accounting packet packet to {}.",
|
||||
serialNumber, Destination));
|
||||
else
|
||||
poco_information(Logger(), fmt::format(
|
||||
"{}: Sending Accounting Packet to {}, CalledStationID: {}, CallingStationID:{}",
|
||||
serialNumber, FinalDestination.toString(), CalledStationID, CallingStationID));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,101 +231,64 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::SendAuthenticationData(const std::string &serialNumber, const char *buffer, std::size_t size) {
|
||||
RADIUS::RadiusPacket P((unsigned char *)buffer,size);
|
||||
auto Destination = P.ExtractProxyStateDestination();
|
||||
auto CallingStationID = P.ExtractCallingStationID();
|
||||
auto CalledStationID = P.ExtractCalledStationID();
|
||||
Poco::Net::SocketAddress Dst(Destination);
|
||||
|
||||
if(!Continue())
|
||||
return;
|
||||
|
||||
try {
|
||||
RADIUS::RadiusPacket P((unsigned char *)buffer,size);
|
||||
auto Destination = P.ExtractProxyStateDestination();
|
||||
auto CallingStationID = P.ExtractCallingStationID();
|
||||
auto CalledStationID = P.ExtractCalledStationID();
|
||||
Poco::Net::SocketAddress Dst(Destination);
|
||||
|
||||
std::lock_guard G(Mutex_);
|
||||
bool UseRADSEC = false;
|
||||
auto FinalDestination = Route(radius_type::auth, Dst, P, UseRADSEC);
|
||||
if(UseRADSEC) {
|
||||
Poco::Net::SocketAddress RSP(FinalDestination.host(),0);
|
||||
auto DestinationServer = RADSECservers_.find(RSP);
|
||||
if(DestinationServer!=end(RADSECservers_)) {
|
||||
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer, size);
|
||||
}
|
||||
} else {
|
||||
if ((Dst.family() == Poco::Net::SocketAddress::IPv4 &&
|
||||
AuthenticationSocketV4_ == nullptr) ||
|
||||
(Dst.family() == Poco::Net::SocketAddress::IPv6 &&
|
||||
AuthenticationSocketV6_ == nullptr)) {
|
||||
poco_debug(
|
||||
Logger(),
|
||||
fmt::format("AUTH: Trying to use RADIUS GW PROXY but not configured. Device={}",
|
||||
serialNumber));
|
||||
return;
|
||||
}
|
||||
auto AllSent =
|
||||
SendData(Dst.family() == Poco::Net::SocketAddress::IPv4 ? *AuthenticationSocketV4_
|
||||
: *AuthenticationSocketV6_,
|
||||
(const unsigned char *)buffer, size, FinalDestination);
|
||||
if (!AllSent)
|
||||
poco_error(Logger(),
|
||||
fmt::format("{}: Could not send Authentication packet packet to {}.",
|
||||
serialNumber, Destination));
|
||||
else
|
||||
poco_debug(Logger(), fmt::format("{}: Sending Authentication Packet to {}, CalledStationID: {}, CallingStationID:{}",
|
||||
serialNumber, FinalDestination.toString(),
|
||||
CalledStationID, CallingStationID));
|
||||
std::lock_guard G(Mutex_);
|
||||
bool UseRADSEC = false;
|
||||
auto FinalDestination = Route(radius_type::auth, Dst, P, UseRADSEC);
|
||||
if(UseRADSEC) {
|
||||
Poco::Net::SocketAddress RSP(FinalDestination.host(),0);
|
||||
auto DestinationServer = RADSECservers_.find(RSP);
|
||||
if(DestinationServer!=end(RADSECservers_)) {
|
||||
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer, size);
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
} catch (...) {
|
||||
poco_warning(Logger(),fmt::format("Bad RADIUS AUTH Packet from {}. Dropped.",serialNumber));
|
||||
} else {
|
||||
auto AllSent =
|
||||
SendData(Dst.family() == Poco::Net::SocketAddress::IPv4 ? *AuthenticationSocketV4_
|
||||
: *AuthenticationSocketV6_,
|
||||
(const unsigned char *)buffer, size, FinalDestination);
|
||||
if (!AllSent)
|
||||
poco_error(Logger(),fmt::format("{}: Could not send Authentication packet packet to {}.",
|
||||
serialNumber, Destination));
|
||||
else
|
||||
poco_information(Logger(), fmt::format("{}: Sending Authentication Packet to {}, CalledStationID: {}, CallingStationID:{}",
|
||||
serialNumber, FinalDestination.toString(),
|
||||
CalledStationID, CallingStationID));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::SendCoAData(const std::string &serialNumber, const char *buffer, std::size_t size) {
|
||||
RADIUS::RadiusPacket P((unsigned char *)buffer,size);
|
||||
auto Destination = P.ExtractProxyStateDestination();
|
||||
|
||||
if(!Continue())
|
||||
return;
|
||||
if(Destination.empty()) {
|
||||
Destination = "0.0.0.0:0";
|
||||
}
|
||||
|
||||
try {
|
||||
RADIUS::RadiusPacket P((unsigned char *)buffer,size);
|
||||
auto Destination = P.ExtractProxyStateDestination();
|
||||
|
||||
if(Destination.empty()) {
|
||||
Destination = "0.0.0.0:0";
|
||||
Poco::Net::SocketAddress Dst(Destination);
|
||||
std::lock_guard G(Mutex_);
|
||||
bool UseRADSEC = false;
|
||||
auto FinalDestination = Route(radius_type::coa, Dst, P, UseRADSEC);
|
||||
if(UseRADSEC) {
|
||||
Poco::Net::SocketAddress RSP(FinalDestination.host(),0);
|
||||
auto DestinationServer = RADSECservers_.find(RSP);
|
||||
if(DestinationServer!=end(RADSECservers_)) {
|
||||
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer, size);
|
||||
}
|
||||
|
||||
Poco::Net::SocketAddress Dst(Destination);
|
||||
std::lock_guard G(Mutex_);
|
||||
bool UseRADSEC = false;
|
||||
auto FinalDestination = Route(radius_type::coa, Dst, P, UseRADSEC);
|
||||
if(UseRADSEC) {
|
||||
Poco::Net::SocketAddress RSP(FinalDestination.host(),0);
|
||||
auto DestinationServer = RADSECservers_.find(RSP);
|
||||
if(DestinationServer!=end(RADSECservers_)) {
|
||||
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer, size);
|
||||
}
|
||||
} else {
|
||||
if( (Dst.family() == Poco::Net::SocketAddress::IPv4 && CoASocketV4_== nullptr) ||
|
||||
(Dst.family() == Poco::Net::SocketAddress::IPv6 && CoASocketV6_== nullptr)) {
|
||||
poco_debug(Logger(),fmt::format("CoA: Trying to use RADIUS GW PROXY but not configured. Device={}",serialNumber));
|
||||
return;
|
||||
}
|
||||
auto AllSent = SendData(Dst.family() == Poco::Net::SocketAddress::IPv4 ? *CoASocketV4_
|
||||
: *CoASocketV6_,
|
||||
(const unsigned char *)buffer, size, FinalDestination);
|
||||
if (!AllSent)
|
||||
poco_error(Logger(),fmt::format("{}: Could not send CoA packet packet to {}.",
|
||||
serialNumber, Destination));
|
||||
else
|
||||
poco_debug(Logger(), fmt::format("{}: Sending CoA Packet to {}", serialNumber,
|
||||
FinalDestination.toString()));
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
} catch (...) {
|
||||
poco_warning(Logger(),fmt::format("Bad RADIUS CoA/DM Packet from {}. Dropped.",serialNumber));
|
||||
} else {
|
||||
auto AllSent = SendData(Dst.family() == Poco::Net::SocketAddress::IPv4 ? *CoASocketV4_
|
||||
: *CoASocketV6_,
|
||||
(const unsigned char *)buffer, size, FinalDestination);
|
||||
if (!AllSent)
|
||||
poco_error(Logger(),fmt::format("{}: Could not send CoA packet packet to {}.",
|
||||
serialNumber, Destination));
|
||||
else
|
||||
poco_information(Logger(), fmt::format("{}: Sending CoA Packet to {}", serialNumber,
|
||||
FinalDestination.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,7 +318,7 @@ namespace OpenWifi {
|
||||
};
|
||||
|
||||
if(setAsDefault && D.useRADSEC)
|
||||
DefaultIsRADSEC_ = true;
|
||||
defaultIsRADSEC_ = true;
|
||||
|
||||
if(S.family()==Poco::Net::IPAddress::IPv4) {
|
||||
TotalV4 += server.weight;
|
||||
@@ -491,26 +412,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);
|
||||
}
|
||||
}
|
||||
@@ -560,9 +481,7 @@ namespace OpenWifi {
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
UseRADSEC = false;
|
||||
return RequestedAddress;
|
||||
return DefaultRoute(rtype, RequestedAddress, P, UseRADSEC);
|
||||
}
|
||||
|
||||
Poco::Net::SocketAddress RADIUS_proxy_server::ChooseAddress(std::vector<Destination> &Pool, const Poco::Net::SocketAddress & OriginalAddress) {
|
||||
@@ -629,6 +548,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 +557,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 +580,8 @@ namespace OpenWifi {
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
Stop();
|
||||
ResetConfig();
|
||||
Stop();
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::GetConfig(GWObjects::RadiusProxyPoolList &C) {
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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"
|
||||
#include "DeviceRegistry.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));
|
||||
Logger_.debug(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));
|
||||
Logger_.debug(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,94 +75,65 @@ namespace OpenWifi {
|
||||
|
||||
try {
|
||||
auto NumberOfReceivedBytes = Socket_->receiveBytes(Buffer,sizeof(Buffer));
|
||||
if(NumberOfReceivedBytes>=20) {
|
||||
if(NumberOfReceivedBytes>40) {
|
||||
RADIUS::RadiusPacket P(Buffer,NumberOfReceivedBytes);
|
||||
// P.Log(std::cout);
|
||||
// std::cout << "RADSEC: " << P.PacketType() << " " << (int) P.PacketTypeInt() << " Received " << NumberOfReceivedBytes << " bytes" << std::endl;
|
||||
if (P.IsAuthentication()) {
|
||||
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
||||
if(!SerialNumber.empty()) {
|
||||
poco_debug(Logger_,
|
||||
fmt::format("{}: {} Received {} bytes.", SerialNumber,
|
||||
P.PacketType(), NumberOfReceivedBytes));
|
||||
AP_WS_Server()->SendRadiusAuthenticationData(SerialNumber, Buffer,
|
||||
NumberOfReceivedBytes);
|
||||
} else {
|
||||
poco_debug(Logger_, "AUTH packet dropped.");
|
||||
}
|
||||
Logger_.debug(fmt::format("{}: {} Received {} bytes.", SerialNumber, P.PacketType(), NumberOfReceivedBytes));
|
||||
DeviceRegistry()->SendRadiusAuthenticationData(
|
||||
SerialNumber, Buffer,
|
||||
NumberOfReceivedBytes);
|
||||
} else if (P.IsAccounting()) {
|
||||
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
||||
if(!SerialNumber.empty()) {
|
||||
poco_debug(Logger_,
|
||||
fmt::format("{}: {} Received {} bytes.", SerialNumber,
|
||||
P.PacketType(), NumberOfReceivedBytes));
|
||||
AP_WS_Server()->SendRadiusAccountingData(SerialNumber, Buffer,
|
||||
NumberOfReceivedBytes);
|
||||
} else {
|
||||
poco_debug(Logger_, "ACCT packet dropped.");
|
||||
}
|
||||
Logger_.debug(fmt::format("{}: {} Received {} bytes.", SerialNumber, P.PacketType(), NumberOfReceivedBytes));
|
||||
DeviceRegistry()->SendRadiusAccountingData(
|
||||
SerialNumber, Buffer,
|
||||
NumberOfReceivedBytes);
|
||||
} 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 +145,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 +154,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 +188,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 +238,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;
|
||||
};
|
||||
}
|
||||
@@ -8,12 +8,10 @@
|
||||
#include "RESTAPI_RPC.h"
|
||||
|
||||
#include "CommandManager.h"
|
||||
#include "AP_WS_Server.h"
|
||||
#include "DeviceRegistry.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,
|
||||
@@ -51,21 +48,21 @@ namespace OpenWifi::RESTAPI_RPC {
|
||||
// then we should just add the command to
|
||||
// the DB and let it figure out when to deliver the command.
|
||||
auto SerialNumberInt = Utils::SerialNumberToInt(Cmd.SerialNumber);
|
||||
if (Cmd.RunAt || (!AP_WS_Server()->Connected(SerialNumberInt) && RetryLater)) {
|
||||
if (Cmd.RunAt || (!DeviceRegistry()->Connected(SerialNumberInt) && RetryLater)) {
|
||||
Logger.information(fmt::format("{},{}: Command will be run in the future or when device is connected again.", Cmd.UUID, RPCID));
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::CommandExecutionType::COMMAND_PENDING, Logger);
|
||||
return;
|
||||
} else if ((!AP_WS_Server()->Connected(SerialNumberInt) && !RetryLater)){
|
||||
} else if ((!DeviceRegistry()->Connected(SerialNumberInt) && !RetryLater)){
|
||||
Logger.information(fmt::format("{},{}: Command canceled. Device is not connected. Command will not be retried.", Cmd.UUID, RPCID));
|
||||
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 = "";
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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},
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user