mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2025-11-21 20:45:11 +00:00
Compare commits
6 Commits
sqlopt1
...
release/v2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d75db91521 | ||
|
|
ef161ee1a9 | ||
|
|
70d07a80e5 | ||
|
|
54e3854300 | ||
|
|
c077c7682f | ||
|
|
b518ce96e1 |
2
.idea/ucentral.iml
generated
2
.idea/ucentral.iml
generated
@@ -2,7 +2,7 @@
|
|||||||
<module classpath="CMake" type="CPP_MODULE" version="4">
|
<module classpath="CMake" type="CPP_MODULE" version="4">
|
||||||
<component name="FacetManager">
|
<component name="FacetManager">
|
||||||
<facet type="Python" name="Python facet">
|
<facet type="Python" name="Python facet">
|
||||||
<configuration sdkName="Python 3.9 (wlan-cloud-ucentralgw)" />
|
<configuration sdkName="Python 3.9 (venv)" />
|
||||||
</facet>
|
</facet>
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
1
.idea/vcs.xml
generated
1
.idea/vcs.xml
generated
@@ -2,6 +2,5 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/cmake-build-debug/rapidjson-test" vcs="Git" />
|
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@@ -24,7 +24,7 @@ sudo apt install librdkafka-dev // default-libmysqlclient-dev
|
|||||||
sudo apt install nlohmann-json-dev
|
sudo apt install nlohmann-json-dev
|
||||||
|
|
||||||
cd ~
|
cd ~
|
||||||
git clone https://github.com/AriliaWireless/poco --branch poco-tip-v2
|
git clone https://github.com/AriliaWireless/poco --branch poco-tip-v1
|
||||||
cd poco
|
cd poco
|
||||||
mkdir cmake-build
|
mkdir cmake-build
|
||||||
cd cmake-build
|
cd cmake-build
|
||||||
@@ -75,7 +75,7 @@ sudo yum install yaml-cpp-devel lua-devel
|
|||||||
sudo dnf install postgresql.x86_64 librdkafka-devel
|
sudo dnf install postgresql.x86_64 librdkafka-devel
|
||||||
sudo dnf install postgresql-devel json-devel
|
sudo dnf install postgresql-devel json-devel
|
||||||
|
|
||||||
git clone https://github.com/AriliaWireless/poco --branch poco-tip-v2
|
git clone https://github.com/AriliaWireless/poco --branch poco-tip-v1
|
||||||
cd poco
|
cd poco
|
||||||
mkdir cmake-build
|
mkdir cmake-build
|
||||||
cd cmake-build
|
cd cmake-build
|
||||||
@@ -125,7 +125,7 @@ brew install openssl \
|
|||||||
nlohmann-json \
|
nlohmann-json \
|
||||||
fmt
|
fmt
|
||||||
|
|
||||||
git clone https://github.com/AriliaWireless/poco --branch poco-tip-v2
|
git clone https://github.com/AriliaWireless/poco --branch poco-tip-v1
|
||||||
pushd poco
|
pushd poco
|
||||||
mkdir cmake-build
|
mkdir cmake-build
|
||||||
push cmake-build
|
push cmake-build
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
project(owgw VERSION 3.0.0)
|
project(owgw VERSION 2.9.0)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
|
|||||||
string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}")
|
string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_definitions(-DTIP_GATEWAY_SERVICE="1" -DPOCO_LOG_DEBUG="1" -DBOOST_NO_CXX98_FUNCTION_BASE=1)
|
add_definitions(-DTIP_GATEWAY_SERVICE="1" -DPOCO_LOG_DEBUG="1")
|
||||||
|
|
||||||
find_package(OpenSSL REQUIRED)
|
find_package(OpenSSL REQUIRED)
|
||||||
find_package(ZLIB REQUIRED)
|
find_package(ZLIB REQUIRED)
|
||||||
@@ -144,14 +144,9 @@ add_executable( owgw
|
|||||||
src/RESTAPI/RESTAPI_RPC.cpp src/RESTAPI/RESTAPI_RPC.h
|
src/RESTAPI/RESTAPI_RPC.cpp src/RESTAPI/RESTAPI_RPC.h
|
||||||
src/RESTAPI/RESTAPI_deviceDashboardHandler.cpp src/RESTAPI/RESTAPI_deviceDashboardHandler.h
|
src/RESTAPI/RESTAPI_deviceDashboardHandler.cpp src/RESTAPI/RESTAPI_deviceDashboardHandler.h
|
||||||
src/RESTAPI/RESTAPI_telemetryWebSocket.cpp src/RESTAPI/RESTAPI_telemetryWebSocket.h
|
src/RESTAPI/RESTAPI_telemetryWebSocket.cpp src/RESTAPI/RESTAPI_telemetryWebSocket.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/RESTAPI/RESTAPI_regulatory.cpp src/RESTAPI/RESTAPI_regulatory.h
|
|
||||||
src/RESTAPI/RESTAPI_radiussessions_handler.cpp src/RESTAPI/RESTAPI_radiussessions_handler.h
|
|
||||||
src/storage/storage_blacklist.cpp src/storage/storage_tables.cpp src/storage/storage_logs.cpp
|
src/storage/storage_blacklist.cpp src/storage/storage_tables.cpp src/storage/storage_logs.cpp
|
||||||
src/storage/storage_command.cpp src/storage/storage_healthcheck.cpp src/storage/storage_statistics.cpp
|
src/storage/storage_command.cpp src/storage/storage_healthcheck.cpp src/storage/storage_statistics.cpp
|
||||||
src/storage/storage_device.cpp src/storage/storage_capabilities.cpp src/storage/storage_defconfig.cpp
|
src/storage/storage_device.cpp src/storage/storage_capabilities.cpp src/storage/storage_defconfig.cpp
|
||||||
src/storage/storage_scripts.cpp src/storage/storage_scripts.h
|
|
||||||
src/storage/storage_tables.cpp
|
src/storage/storage_tables.cpp
|
||||||
src/RESTAPI/RESTAPI_routers.cpp
|
src/RESTAPI/RESTAPI_routers.cpp
|
||||||
src/Daemon.cpp src/Daemon.h
|
src/Daemon.cpp src/Daemon.h
|
||||||
@@ -175,7 +170,7 @@ add_executable( owgw
|
|||||||
src/SDKcalls.cpp
|
src/SDKcalls.cpp
|
||||||
src/SDKcalls.h
|
src/SDKcalls.h
|
||||||
src/StateUtils.cpp src/StateUtils.h
|
src/StateUtils.cpp src/StateUtils.h
|
||||||
src/AP_WS_Reactor_Pool.h
|
src/AP_WS_ReactorPool.h
|
||||||
src/AP_WS_Connection.h
|
src/AP_WS_Connection.h
|
||||||
src/AP_WS_Connection.cpp
|
src/AP_WS_Connection.cpp
|
||||||
src/TelemetryClient.h src/TelemetryClient.cpp
|
src/TelemetryClient.h src/TelemetryClient.cpp
|
||||||
@@ -199,20 +194,8 @@ add_executable( owgw
|
|||||||
src/AP_WS_Process_deviceupdate.cpp
|
src/AP_WS_Process_deviceupdate.cpp
|
||||||
src/AP_WS_Process_telemetry.cpp
|
src/AP_WS_Process_telemetry.cpp
|
||||||
src/AP_WS_Process_venuebroadcast.cpp
|
src/AP_WS_Process_venuebroadcast.cpp
|
||||||
src/RADIUS_Destination.h
|
src/RADSEC_server.h
|
||||||
src/UI_GW_WebSocketNotifications.cpp src/UI_GW_WebSocketNotifications.h
|
src/UI_GW_WebSocketNotifications.cpp src/UI_GW_WebSocketNotifications.h src/framework/RESTAPI_SystemConfiguration.h src/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.h src/AP_WS_Process_event.cpp src/AP_WS_Process_wifiscan.cpp src/AP_WS_Process_alarm.cpp src/GWKafkaEvents.cpp src/GWKafkaEvents.h src/RegulatoryInfo.cpp src/RegulatoryInfo.h src/RESTAPI/RESTAPI_regulatory.cpp src/RESTAPI/RESTAPI_regulatory.h)
|
||||||
src/framework/RESTAPI_SystemConfiguration.h
|
|
||||||
src/ScriptManager.cpp src/ScriptManager.h
|
|
||||||
src/SignatureMgr.h
|
|
||||||
src/AP_WS_Process_event.cpp
|
|
||||||
src/AP_WS_Process_wifiscan.cpp
|
|
||||||
src/AP_WS_Process_alarm.cpp
|
|
||||||
src/GWKafkaEvents.cpp src/GWKafkaEvents.h
|
|
||||||
src/RegulatoryInfo.cpp src/RegulatoryInfo.h
|
|
||||||
src/RADIUSSessionTracker.cpp src/RADIUSSessionTracker.h
|
|
||||||
src/libs/Scheduler.h src/libs/InterruptableSleep.h src/libs/ctpl_stl.h src/libs/Cron.h
|
|
||||||
src/GenericScheduler.cpp src/GenericScheduler.h src/framework/default_device_types.h src/AP_WS_Process_rebootLog.cpp src/AP_WS_ConfigAutoUpgrader.cpp src/AP_WS_ConfigAutoUpgrader.h src/RESTAPI/RESTAPI_default_firmwares.cpp src/RESTAPI/RESTAPI_default_firmwares.h src/RESTAPI/RESTAPI_default_firmware.cpp src/RESTAPI/RESTAPI_default_firmware.h src/storage/storage_def_firmware.cpp src/firmware_revision_cache.h src/sdks/sdk_fms.h
|
|
||||||
src/AP_WS_LookForUpgrade.cpp)
|
|
||||||
|
|
||||||
if(NOT SMALL_BUILD)
|
if(NOT SMALL_BUILD)
|
||||||
|
|
||||||
@@ -224,16 +207,13 @@ INSTALL(TARGETS owgw
|
|||||||
|
|
||||||
target_link_libraries(owgw PUBLIC
|
target_link_libraries(owgw PUBLIC
|
||||||
${Poco_LIBRARIES}
|
${Poco_LIBRARIES}
|
||||||
${ZLIB_LIBRARIES}
|
${ZLIB_LIBRARIES})
|
||||||
)
|
|
||||||
|
|
||||||
if(NOT SMALL_BUILD)
|
if(NOT SMALL_BUILD)
|
||||||
target_link_libraries(owgw PUBLIC
|
target_link_libraries(owgw PUBLIC
|
||||||
${MySQL_LIBRARIES}
|
${MySQL_LIBRARIES} ${ZLIB_LIBRARIES}
|
||||||
${ZLIB_LIBRARIES}
|
|
||||||
CppKafka::cppkafka
|
CppKafka::cppkafka
|
||||||
fmt::fmt
|
fmt::fmt
|
||||||
resolv
|
|
||||||
)
|
)
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
target_link_libraries(owgw PUBLIC PocoJSON)
|
target_link_libraries(owgw PUBLIC PocoJSON)
|
||||||
|
|||||||
48
Dockerfile
48
Dockerfile
@@ -2,8 +2,6 @@ ARG DEBIAN_VERSION=11.5-slim
|
|||||||
ARG POCO_VERSION=poco-tip-v2
|
ARG POCO_VERSION=poco-tip-v2
|
||||||
ARG CPPKAFKA_VERSION=tip-v1
|
ARG CPPKAFKA_VERSION=tip-v1
|
||||||
ARG VALIJASON_VERSION=tip-v1
|
ARG VALIJASON_VERSION=tip-v1
|
||||||
ARG APP_NAME=owgw
|
|
||||||
ARG APP_HOME_DIR=/openwifi
|
|
||||||
|
|
||||||
FROM debian:$DEBIAN_VERSION AS build-base
|
FROM debian:$DEBIAN_VERSION AS build-base
|
||||||
|
|
||||||
@@ -55,14 +53,12 @@ RUN cmake ..
|
|||||||
RUN cmake --build . --config Release -j8
|
RUN cmake --build . --config Release -j8
|
||||||
RUN cmake --build . --target install
|
RUN cmake --build . --target install
|
||||||
|
|
||||||
FROM build-base AS app-build
|
FROM build-base AS owgw-build
|
||||||
|
|
||||||
ARG APP_NAME
|
ADD CMakeLists.txt build /owgw/
|
||||||
|
ADD cmake /owgw/cmake
|
||||||
ADD CMakeLists.txt build /${APP_NAME}/
|
ADD src /owgw/src
|
||||||
ADD cmake /${APP_NAME}/cmake
|
ADD .git /owgw/.git
|
||||||
ADD src /${APP_NAME}/src
|
|
||||||
ADD .git /${APP_NAME}/.git
|
|
||||||
|
|
||||||
COPY --from=poco-build /usr/local/include /usr/local/include
|
COPY --from=poco-build /usr/local/include /usr/local/include
|
||||||
COPY --from=poco-build /usr/local/lib /usr/local/lib
|
COPY --from=poco-build /usr/local/lib /usr/local/lib
|
||||||
@@ -70,33 +66,23 @@ COPY --from=cppkafka-build /usr/local/include /usr/local/include
|
|||||||
COPY --from=cppkafka-build /usr/local/lib /usr/local/lib
|
COPY --from=cppkafka-build /usr/local/lib /usr/local/lib
|
||||||
COPY --from=valijson-build /usr/local/include /usr/local/include
|
COPY --from=valijson-build /usr/local/include /usr/local/include
|
||||||
|
|
||||||
WORKDIR /${APP_NAME}
|
WORKDIR /owgw
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
WORKDIR /${APP_NAME}/cmake-build
|
WORKDIR /owgw/cmake-build
|
||||||
RUN cmake ..
|
RUN cmake ..
|
||||||
RUN cmake --build . --config Release -j8
|
RUN cmake --build . --config Release -j8
|
||||||
|
|
||||||
FROM debian:$DEBIAN_VERSION
|
FROM debian:$DEBIAN_VERSION
|
||||||
|
|
||||||
ARG APP_NAME
|
ENV OWGW_USER=owgw \
|
||||||
ARG APP_HOME_DIR
|
OWGW_ROOT=/owgw-data \
|
||||||
|
OWGW_CONFIG=/owgw-data
|
||||||
|
|
||||||
ENV APP_NAME=$APP_NAME \
|
RUN useradd "$OWGW_USER"
|
||||||
APP_USER=$APP_NAME \
|
|
||||||
APP_ROOT=/$APP_NAME-data \
|
|
||||||
APP_CONFIG=/$APP_NAME-data \
|
|
||||||
APP_HOME_DIR=$APP_HOME_DIR
|
|
||||||
|
|
||||||
# This is for legacy
|
RUN mkdir /openwifi
|
||||||
ENV OWGW_USER=$APP_USER \
|
RUN mkdir -p "$OWGW_ROOT" "$OWGW_CONFIG" && \
|
||||||
OWGW_ROOT=$APP_ROOT \
|
chown "$OWGW_USER": "$OWGW_ROOT" "$OWGW_CONFIG"
|
||||||
OWGW_CONFIG=$APP_CONFIG
|
|
||||||
|
|
||||||
RUN useradd $APP_USER
|
|
||||||
|
|
||||||
RUN mkdir $APP_HOME_DIR
|
|
||||||
RUN mkdir -p $APP_ROOT $APP_CONFIG && \
|
|
||||||
chown $APP_USER: $APP_ROOT $APP_CONFIG
|
|
||||||
|
|
||||||
RUN apt-get update && apt-get install --no-install-recommends -y \
|
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||||
librdkafka++1 gosu gettext ca-certificates bash jq curl wget \
|
librdkafka++1 gosu gettext ca-certificates bash jq curl wget \
|
||||||
@@ -105,14 +91,14 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
|
|||||||
COPY readiness_check /readiness_check
|
COPY readiness_check /readiness_check
|
||||||
COPY test_scripts/curl/cli /cli
|
COPY test_scripts/curl/cli /cli
|
||||||
|
|
||||||
COPY $APP_NAME.properties.tmpl /
|
COPY owgw.properties.tmpl /
|
||||||
COPY docker-entrypoint.sh /
|
COPY docker-entrypoint.sh /
|
||||||
COPY wait-for-postgres.sh /
|
COPY wait-for-postgres.sh /
|
||||||
COPY rtty_ui /dist/rtty_ui
|
COPY rtty_ui /dist/rtty_ui
|
||||||
RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \
|
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.crt
|
||||||
|
|
||||||
COPY --from=app-build /$APP_NAME/cmake-build/$APP_NAME $APP_HOME_DIR/$APP_NAME
|
COPY --from=owgw-build /owgw/cmake-build/owgw /openwifi/owgw
|
||||||
COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib /usr/local/lib/
|
COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib /usr/local/lib/
|
||||||
COPY --from=poco-build /poco/cmake-build/lib /usr/local/lib/
|
COPY --from=poco-build /poco/cmake-build/lib /usr/local/lib/
|
||||||
|
|
||||||
@@ -121,4 +107,4 @@ RUN ldconfig
|
|||||||
EXPOSE 15002 16002 16003 17002 16102
|
EXPOSE 15002 16002 16003 17002 16102
|
||||||
|
|
||||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||||
CMD ${APP_HOME_DIR}/${APP_NAME}
|
CMD ["/openwifi/owgw"]
|
||||||
|
|||||||
159
PROTOCOL.md
159
PROTOCOL.md
@@ -149,7 +149,7 @@ The `severity` matches the `syslog` levels. Here are the details:
|
|||||||
- 7 : LOG_DEBUG 7 /* debug-level messages */
|
- 7 : LOG_DEBUG 7 /* debug-level messages */
|
||||||
|
|
||||||
#### Crash Log event
|
#### Crash Log event
|
||||||
Device may send a `crash log event` during rebooting after a crash. The event cannot be sent until a connection event has been established.
|
Device may send a crash log event after rebooting after a crash. The event cannot be sent until a connection event has been sent.
|
||||||
```json
|
```json
|
||||||
{ "jsonrpc" : "2.0" ,
|
{ "jsonrpc" : "2.0" ,
|
||||||
"method" : "crashlog" ,
|
"method" : "crashlog" ,
|
||||||
@@ -161,23 +161,6 @@ Device may send a `crash log event` during rebooting after a crash. The event ca
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Reboot Log event
|
|
||||||
The device may send a `reboot log event` after a reboot. This maybe a scheduled reboot or caused in some other way.
|
|
||||||
```json
|
|
||||||
{ "jsonrpc" : "2.0" ,
|
|
||||||
"method" : "rebootLog" ,
|
|
||||||
"params" : {
|
|
||||||
"serial" : <serial number> ,
|
|
||||||
"uuid" : <the UUID of the configuration that generated the reboot log>,
|
|
||||||
"date" : <Unix time when this reboot occurred>,
|
|
||||||
"type" : <string>,
|
|
||||||
"info" : [ "info 1", "info 2"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Here is a possible list of reboot reasons:
|
|
||||||
|
|
||||||
#### Config change pending event
|
#### Config change pending event
|
||||||
Device sends this message to tell the controller that the device
|
Device sends this message to tell the controller that the device
|
||||||
has received a configuration but is still running an older configuration. The controller will not
|
has received a configuration but is still running an older configuration. The controller will not
|
||||||
@@ -775,146 +758,6 @@ The device should answer:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Controller wants the device to replace its certificates
|
|
||||||
Controller sends this command to run a predefined script. Extreme care must be taken.
|
|
||||||
```json
|
|
||||||
{ "jsonrpc" : "2.0" ,
|
|
||||||
"method" : "certupdate" ,
|
|
||||||
"params" : {
|
|
||||||
"serial" : <serial number>,
|
|
||||||
"certificates" : <BASE64 encoded tar file of the cert package from the certificate portal>
|
|
||||||
},
|
|
||||||
"id" : <some number>
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The device should answer:
|
|
||||||
```json
|
|
||||||
{ "jsonrpc" : "2.0" ,
|
|
||||||
"result" : {
|
|
||||||
"serial" : <serial number> ,
|
|
||||||
"status" : {
|
|
||||||
"error" : <0 or the value of $? from the shell running the command, 255 signifies a timeout>,
|
|
||||||
"txt" : <text describing the error or success>
|
|
||||||
},
|
|
||||||
"id" : <same number as request>
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Controller wants the device to switch to another controller
|
|
||||||
Controller sends this when the device should change the controller it connects to without looking up a new redirector.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{ "jsonrpc" : "2.0" ,
|
|
||||||
"method" : "transfer" ,
|
|
||||||
"params" : {
|
|
||||||
"serial" : <serial number>,
|
|
||||||
"server" : <controller hostname>,
|
|
||||||
"port" : <controller port number (integer)>,
|
|
||||||
},
|
|
||||||
"id" : <some number>
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The device should answer:
|
|
||||||
```json
|
|
||||||
{ "jsonrpc" : "2.0" ,
|
|
||||||
"result" : {
|
|
||||||
"serial" : <serial number> ,
|
|
||||||
"status" : {
|
|
||||||
"error" : <0 or the value of $? from the shell running the command, 255 signifies a timeout>,
|
|
||||||
"txt" : <text describing the error or success>
|
|
||||||
},
|
|
||||||
"id" : <same number as request>
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### RRM AP device commands
|
|
||||||
The following command is used to send RRM commands to an AP. RRM commands are send to an AP, however the
|
|
||||||
controller will not or cannot verify if they have been sent or the action was performed.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{ "jsonrpc" : "2.0" ,
|
|
||||||
"method" : "rrm" ,
|
|
||||||
"params" : {
|
|
||||||
"serial" : <serial number>,
|
|
||||||
"actions" : [ array of actions. Each possible action is defined next]
|
|
||||||
},
|
|
||||||
"id" : <some number>
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The device should answer:
|
|
||||||
```json
|
|
||||||
{ "jsonrpc" : "2.0" ,
|
|
||||||
"result" : {
|
|
||||||
"serial" : <serial number> ,
|
|
||||||
"status" : {
|
|
||||||
"error" : <0 or the value of $? from the shell running the command, 255 signifies a timeout>,
|
|
||||||
"txt" : <text describing the error or success>
|
|
||||||
},
|
|
||||||
"id" : <same number as request>
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### RRM Roam action
|
|
||||||
|
|
||||||
##### Kick
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"action" : "kick" ,
|
|
||||||
"addr" : <mac if the client that shall be kicked> ,
|
|
||||||
"reason": <number>, (default: 5, https://www.cisco.com/assets/sol/sb/WAP371_Emulators/WAP371_Emulator_v1-0-1-5/help/Apx_ReasonCodes2.html)
|
|
||||||
"ban_time": <number> (seconds, optional)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Channel Switch Announcement
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"action" : "channel_switch" ,
|
|
||||||
"bssid" : <mac of the SSID> , (all other SSIDs on the same radio will perform the same action)
|
|
||||||
"channel" : <number> (HT/HW mode will be retained upon issuing the CSA)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Change TX-Power
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"action" : "tx_power" ,
|
|
||||||
"bssid" : <mac of the SSID> , (all other SSIDs on the same radio will perform the same action)
|
|
||||||
"level" : <number> (DBm inside the positive number space)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Beacon Scan
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"action" : "beacon_request" ,
|
|
||||||
"addr" : <mac if the client that shall perform the scan> ,
|
|
||||||
"ssid": <string>, (the SSID the client shall scan for on all frequencies),
|
|
||||||
"channel": <number> (the channel that shall be scanned)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### BSS Transition
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"action" : "bss_transition" ,
|
|
||||||
"addr" : <mac if the client that shall perform the roam> ,
|
|
||||||
"neighbors": [ <string> ], (an array of BSSIDs the client shall consider as roamin candidates)
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Update neighbours
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"action" : "neighbors" ,
|
|
||||||
"bssid" : <mac of the SSID> , (the SSID of the specific VAP)
|
|
||||||
"neighbors": [ [ <BSS>, <ssid>, <neighbor report> ] ]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### `rtty server`
|
### `rtty server`
|
||||||
More information about the [rtty server](https://github.com/zhaojh329/rtty) can be found here.
|
More information about the [rtty server](https://github.com/zhaojh329/rtty) can be found here.
|
||||||
|
|
||||||
|
|||||||
@@ -6,35 +6,35 @@ if [ "$SELFSIGNED_CERTS" = 'true' ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
||||||
WEBSOCKET_HOST_ROOTCA=${WEBSOCKET_HOST_ROOTCA:-"\${APP_ROOT}/certs/root.pem"} \
|
WEBSOCKET_HOST_ROOTCA=${WEBSOCKET_HOST_ROOTCA:-"\$OWGW_ROOT/certs/root.pem"} \
|
||||||
WEBSOCKET_HOST_ISSUER=${WEBSOCKET_HOST_ISSUER:-"\${APP_ROOT}/certs/issuer.pem"} \
|
WEBSOCKET_HOST_ISSUER=${WEBSOCKET_HOST_ISSUER:-"\$OWGW_ROOT/certs/issuer.pem"} \
|
||||||
WEBSOCKET_HOST_CERT=${WEBSOCKET_HOST_CERT:-"\${APP_ROOT}/certs/websocket-cert.pem"} \
|
WEBSOCKET_HOST_CERT=${WEBSOCKET_HOST_CERT:-"\$OWGW_ROOT/certs/websocket-cert.pem"} \
|
||||||
WEBSOCKET_HOST_KEY=${WEBSOCKET_HOST_KEY:-"\${APP_ROOT}/certs/websocket-key.pem"} \
|
WEBSOCKET_HOST_KEY=${WEBSOCKET_HOST_KEY:-"\$OWGW_ROOT/certs/websocket-key.pem"} \
|
||||||
WEBSOCKET_HOST_CLIENTCAS=${WEBSOCKET_HOST_CLIENTCAS:-"\${APP_ROOT}/certs/clientcas.pem"} \
|
WEBSOCKET_HOST_CLIENTCAS=${WEBSOCKET_HOST_CLIENTCAS:-"\$OWGW_ROOT/certs/clientcas.pem"} \
|
||||||
WEBSOCKET_HOST_CAS=${WEBSOCKET_HOST_CAS:-"\${APP_ROOT}/certs/cas"} \
|
WEBSOCKET_HOST_CAS=${WEBSOCKET_HOST_CAS:-"\$OWGW_ROOT/certs/cas"} \
|
||||||
WEBSOCKET_HOST_PORT=${WEBSOCKET_HOST_PORT:-"15002"} \
|
WEBSOCKET_HOST_PORT=${WEBSOCKET_HOST_PORT:-"15002"} \
|
||||||
WEBSOCKET_HOST_KEY_PASSWORD=${WEBSOCKET_HOST_KEY_PASSWORD:-"mypassword"} \
|
WEBSOCKET_HOST_KEY_PASSWORD=${WEBSOCKET_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||||
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\${APP_ROOT}/certs/restapi-ca.pem"} \
|
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWGW_ROOT/certs/restapi-ca.pem"} \
|
||||||
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16002"} \
|
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16002"} \
|
||||||
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\${APP_ROOT}/certs/restapi-cert.pem"} \
|
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWGW_ROOT/certs/restapi-cert.pem"} \
|
||||||
RESTAPI_HOST_KEY=${RESTAPI_HOST_KEY:-"\${APP_ROOT}/certs/restapi-key.pem"} \
|
RESTAPI_HOST_KEY=${RESTAPI_HOST_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||||
RESTAPI_HOST_KEY_PASSWORD=${RESTAPI_HOST_KEY_PASSWORD:-"mypassword"} \
|
RESTAPI_HOST_KEY_PASSWORD=${RESTAPI_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||||
INTERNAL_RESTAPI_HOST_ROOTCA=${INTERNAL_RESTAPI_HOST_ROOTCA:-"\${APP_ROOT}/certs/restapi-ca.pem"} \
|
INTERNAL_RESTAPI_HOST_ROOTCA=${INTERNAL_RESTAPI_HOST_ROOTCA:-"\$OWGW_ROOT/certs/restapi-ca.pem"} \
|
||||||
INTERNAL_RESTAPI_HOST_PORT=${INTERNAL_RESTAPI_HOST_PORT:-"17002"} \
|
INTERNAL_RESTAPI_HOST_PORT=${INTERNAL_RESTAPI_HOST_PORT:-"17002"} \
|
||||||
INTERNAL_RESTAPI_HOST_CERT=${INTERNAL_RESTAPI_HOST_CERT:-"\${APP_ROOT}/certs/restapi-cert.pem"} \
|
INTERNAL_RESTAPI_HOST_CERT=${INTERNAL_RESTAPI_HOST_CERT:-"\$OWGW_ROOT/certs/restapi-cert.pem"} \
|
||||||
INTERNAL_RESTAPI_HOST_KEY=${INTERNAL_RESTAPI_HOST_KEY:-"\${APP_ROOT}/certs/restapi-key.pem"} \
|
INTERNAL_RESTAPI_HOST_KEY=${INTERNAL_RESTAPI_HOST_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||||
INTERNAL_RESTAPI_HOST_KEY_PASSWORD=${INTERNAL_RESTAPI_HOST_KEY_PASSWORD:-"mypassword"} \
|
INTERNAL_RESTAPI_HOST_KEY_PASSWORD=${INTERNAL_RESTAPI_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||||
FILEUPLOADER_HOST_ROOTCA=${FILEUPLOADER_HOST_ROOTCA:-"\${APP_ROOT}/certs/restapi-ca.pem"} \
|
FILEUPLOADER_HOST_ROOTCA=${FILEUPLOADER_HOST_ROOTCA:-"\$OWGW_ROOT/certs/restapi-ca.pem"} \
|
||||||
FILEUPLOADER_HOST_NAME=${FILEUPLOADER_HOST_NAME:-"localhost"} \
|
FILEUPLOADER_HOST_NAME=${FILEUPLOADER_HOST_NAME:-"localhost"} \
|
||||||
FILEUPLOADER_HOST_PORT=${FILEUPLOADER_HOST_PORT:-"16003"} \
|
FILEUPLOADER_HOST_PORT=${FILEUPLOADER_HOST_PORT:-"16003"} \
|
||||||
FILEUPLOADER_HOST_CERT=${FILEUPLOADER_HOST_CERT:-"\${APP_ROOT}/certs/restapi-cert.pem"} \
|
FILEUPLOADER_HOST_CERT=${FILEUPLOADER_HOST_CERT:-"\$OWGW_ROOT/certs/restapi-cert.pem"} \
|
||||||
FILEUPLOADER_HOST_KEY=${FILEUPLOADER_HOST_KEY:-"\${APP_ROOT}/certs/restapi-key.pem"} \
|
FILEUPLOADER_HOST_KEY=${FILEUPLOADER_HOST_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||||
FILEUPLOADER_HOST_KEY_PASSWORD=${FILEUPLOADER_HOST_KEY_PASSWORD:-"mypassword"} \
|
FILEUPLOADER_HOST_KEY_PASSWORD=${FILEUPLOADER_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||||
FILEUPLOADER_PATH=${FILEUPLOADER_PATH:-"\${APP_ROOT}/uploads"} \
|
FILEUPLOADER_PATH=${FILEUPLOADER_PATH:-"\$OWGW_ROOT/uploads"} \
|
||||||
FILEUPLOADER_URI=${FILEUPLOADER_URI:-"https://localhost:16003"} \
|
FILEUPLOADER_URI=${FILEUPLOADER_URI:-"https://localhost:16003"} \
|
||||||
SERVICE_KEY=${SERVICE_KEY:-"\${APP_ROOT}/certs/restapi-key.pem"} \
|
SERVICE_KEY=${SERVICE_KEY:-"\$OWGW_ROOT/certs/restapi-key.pem"} \
|
||||||
SERVICE_KEY_PASSWORD=${SERVICE_KEY_PASSWORD:-"mypassword"} \
|
SERVICE_KEY_PASSWORD=${SERVICE_KEY_PASSWORD:-"mypassword"} \
|
||||||
SYSTEM_DATA=${SYSTEM_DATA:-"\${APP_ROOT}/data"} \
|
SYSTEM_DATA=${SYSTEM_DATA:-"\$OWGW_ROOT/data"} \
|
||||||
SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17002"} \
|
SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17002"} \
|
||||||
SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16002"} \
|
SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16002"} \
|
||||||
SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
|
SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
|
||||||
@@ -51,7 +51,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
|||||||
RTTY_TOKEN=${RTTY_TOKEN:-""} \
|
RTTY_TOKEN=${RTTY_TOKEN:-""} \
|
||||||
RTTY_TIMEOUT=${RTTY_TIMEOUT:-"60"} \
|
RTTY_TIMEOUT=${RTTY_TIMEOUT:-"60"} \
|
||||||
RTTY_VIEWPORT=${RTTY_VIEWPORT:-"5913"} \
|
RTTY_VIEWPORT=${RTTY_VIEWPORT:-"5913"} \
|
||||||
RTTY_ASSETS=${RTTY_ASSETS:-"\${APP_ROOT}/rtty_ui"} \
|
RTTY_ASSETS=${RTTY_ASSETS:-"\$OWGW_ROOT/rtty_ui"} \
|
||||||
RADIUS_PROXY_ENABLE=${RADIUS_PROXY_ENABLE:-"false"} \
|
RADIUS_PROXY_ENABLE=${RADIUS_PROXY_ENABLE:-"false"} \
|
||||||
RADIUS_PROXY_ACCOUNTING_PORT=${RADIUS_PROXY_ACCOUNTING_PORT:-"1813"} \
|
RADIUS_PROXY_ACCOUNTING_PORT=${RADIUS_PROXY_ACCOUNTING_PORT:-"1813"} \
|
||||||
RADIUS_PROXY_AUTHENTICATION_PORT=${RADIUS_PROXY_AUTHENTICATION_PORT:-"1812"} \
|
RADIUS_PROXY_AUTHENTICATION_PORT=${RADIUS_PROXY_AUTHENTICATION_PORT:-"1812"} \
|
||||||
@@ -64,41 +64,39 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
|||||||
KAFKA_SSL_KEY_PASSWORD=${KAFKA_SSL_KEY_PASSWORD:-""} \
|
KAFKA_SSL_KEY_PASSWORD=${KAFKA_SSL_KEY_PASSWORD:-""} \
|
||||||
STORAGE_TYPE=${STORAGE_TYPE:-"sqlite"} \
|
STORAGE_TYPE=${STORAGE_TYPE:-"sqlite"} \
|
||||||
STORAGE_TYPE_POSTGRESQL_HOST=${STORAGE_TYPE_POSTGRESQL_HOST:-"localhost"} \
|
STORAGE_TYPE_POSTGRESQL_HOST=${STORAGE_TYPE_POSTGRESQL_HOST:-"localhost"} \
|
||||||
STORAGE_TYPE_POSTGRESQL_USERNAME=${STORAGE_TYPE_POSTGRESQL_USERNAME:-"${APP_USER}"} \
|
STORAGE_TYPE_POSTGRESQL_USERNAME=${STORAGE_TYPE_POSTGRESQL_USERNAME:-"owgw"} \
|
||||||
STORAGE_TYPE_POSTGRESQL_PASSWORD=${STORAGE_TYPE_POSTGRESQL_PASSWORD:-"${APP_USER}"} \
|
STORAGE_TYPE_POSTGRESQL_PASSWORD=${STORAGE_TYPE_POSTGRESQL_PASSWORD:-"owgw"} \
|
||||||
STORAGE_TYPE_POSTGRESQL_DATABASE=${STORAGE_TYPE_POSTGRESQL_DATABASE:-"${APP_NAME}"} \
|
STORAGE_TYPE_POSTGRESQL_DATABASE=${STORAGE_TYPE_POSTGRESQL_DATABASE:-"owgw"} \
|
||||||
STORAGE_TYPE_POSTGRESQL_PORT=${STORAGE_TYPE_POSTGRESQL_PORT:-"5432"} \
|
STORAGE_TYPE_POSTGRESQL_PORT=${STORAGE_TYPE_POSTGRESQL_PORT:-"5432"} \
|
||||||
STORAGE_TYPE_MYSQL_HOST=${STORAGE_TYPE_MYSQL_HOST:-"localhost"} \
|
STORAGE_TYPE_MYSQL_HOST=${STORAGE_TYPE_MYSQL_HOST:-"localhost"} \
|
||||||
STORAGE_TYPE_MYSQL_USERNAME=${STORAGE_TYPE_MYSQL_USERNAME:-"${APP_USER}"} \
|
STORAGE_TYPE_MYSQL_USERNAME=${STORAGE_TYPE_MYSQL_USERNAME:-"owgw"} \
|
||||||
STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"${APP_USER}"} \
|
STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"owgw"} \
|
||||||
STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"${APP_NAME}"} \
|
STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"owgw"} \
|
||||||
STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \
|
STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \
|
||||||
CERTIFICATES_ALLOWMISMATCH=${CERTIFICATES_ALLOWMISMATCH:-"false"} \
|
CERTIFICATES_ALLOWMISMATCH=${CERTIFICATES_ALLOWMISMATCH:-"false"} \
|
||||||
IPINFO_DEFAULT_COUNTRY=${IPINFO_DEFAULT_COUNTRY:-"US"} \
|
envsubst < /owgw.properties.tmpl > $OWGW_CONFIG/owgw.properties
|
||||||
DEVICE_SESSION_TIMEOUT=${DEVICE_SESSION_TIMEOUT:-"600"} \
|
|
||||||
envsubst < /"${APP_NAME}".properties.tmpl > "${APP_CONFIG}"/"${APP_NAME}".properties
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Check if rtty_ui directory exists
|
# Check if rtty_ui directory exists
|
||||||
export RTTY_ASSETS=$(grep 'rtty.assets' "${APP_CONFIG}"/"${APP_NAME}".properties | awk -F '=' '{print $2}' | xargs | envsubst)
|
export RTTY_ASSETS=$(grep 'rtty.assets' $OWGW_CONFIG/owgw.properties | awk -F '=' '{print $2}' | xargs | envsubst)
|
||||||
|
|
||||||
if [ -z "$RTTY_ASSETS" ]; then
|
if [ -z "$RTTY_ASSETS" ]; then
|
||||||
export RTTY_ASSETS="${APP_ROOT}/rtty_ui"
|
export RTTY_ASSETS="$OWGW_ROOT/rtty_ui"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! -d "$(dirname $RTTY_ASSETS)" ]]; then
|
if [[ ! -d "$(dirname $RTTY_ASSETS)" ]]; then
|
||||||
mkdir -p "$(dirname $RTTY_ASSETS)"
|
mkdir -p $(dirname $RTTY_ASSETS)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! -d "$RTTY_ASSETS" ]]; then
|
if [[ ! -d "$RTTY_ASSETS" ]]; then
|
||||||
cp -r /dist/rtty_ui $RTTY_ASSETS
|
cp -r /dist/rtty_ui $RTTY_ASSETS
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$1" = "${APP_HOME_DIR}/${APP_NAME}" -a "$(id -u)" = '0' ]; then
|
if [ "$1" = '/openwifi/owgw' -a "$(id -u)" = '0' ]; then
|
||||||
if [ "$RUN_CHOWN" = 'true' ]; then
|
if [ "$RUN_CHOWN" = 'true' ]; then
|
||||||
chown -R "$APP_USER": "${APP_ROOT}" "$APP_CONFIG"
|
chown -R "$OWGW_USER": "$OWGW_ROOT" "$OWGW_CONFIG"
|
||||||
fi
|
fi
|
||||||
exec gosu "$APP_USER" "$@"
|
exec gosu "$OWGW_USER" "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ fullnameOverride: ""
|
|||||||
images:
|
images:
|
||||||
owgw:
|
owgw:
|
||||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owgw
|
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owgw
|
||||||
tag: master
|
tag: v2.9.0
|
||||||
pullPolicy: Always
|
pullPolicy: Always
|
||||||
# regcred:
|
# regcred:
|
||||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||||
|
|||||||
22213
issues/OWGW Logs.txt
22213
issues/OWGW Logs.txt
File diff suppressed because it is too large
Load Diff
2158
issues/OWLS Logs.rtf
2158
issues/OWLS Logs.rtf
File diff suppressed because it is too large
Load Diff
2154
issues/OWLS Logs.txt
2154
issues/OWLS Logs.txt
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@ openapi: 3.0.1
|
|||||||
info:
|
info:
|
||||||
title: uCentral gateway API
|
title: uCentral gateway API
|
||||||
description: A process to manage configuration for devices.
|
description: A process to manage configuration for devices.
|
||||||
version: 2.11.0
|
version: 2.5.0
|
||||||
license:
|
license:
|
||||||
name: BSD3
|
name: BSD3
|
||||||
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||||
@@ -152,11 +152,6 @@ components:
|
|||||||
format: uuid
|
format: uuid
|
||||||
restrictionDetails:
|
restrictionDetails:
|
||||||
$ref: '#/components/schemas/DeviceRestrictions'
|
$ref: '#/components/schemas/DeviceRestrictions'
|
||||||
simulated:
|
|
||||||
type: boolean
|
|
||||||
lastRecordedContact:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
|
|
||||||
DeviceWithStatus:
|
DeviceWithStatus:
|
||||||
type: object
|
type: object
|
||||||
@@ -265,22 +260,6 @@ components:
|
|||||||
format: uuid
|
format: uuid
|
||||||
restrictionDetails:
|
restrictionDetails:
|
||||||
$ref: '#/components/schemas/DeviceRestrictions'
|
$ref: '#/components/schemas/DeviceRestrictions'
|
||||||
hasGPS:
|
|
||||||
type: boolean
|
|
||||||
sanity:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
memoryUsed:
|
|
||||||
type: number
|
|
||||||
format: float
|
|
||||||
load:
|
|
||||||
type: number
|
|
||||||
format: float
|
|
||||||
temperature:
|
|
||||||
type: number
|
|
||||||
format: float
|
|
||||||
connectReason:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
DeviceList:
|
DeviceList:
|
||||||
type: object
|
type: object
|
||||||
@@ -350,9 +329,6 @@ components:
|
|||||||
associations_5G:
|
associations_5G:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
associations_6G:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
verifiedCertificate:
|
verifiedCertificate:
|
||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
@@ -360,7 +336,6 @@ components:
|
|||||||
- VALID_CERTIFICATE,
|
- VALID_CERTIFICATE,
|
||||||
- MISMATCH_SERIAL,
|
- MISMATCH_SERIAL,
|
||||||
- VERIFIED
|
- VERIFIED
|
||||||
- SIMULATED
|
|
||||||
|
|
||||||
DeviceCapabilities:
|
DeviceCapabilities:
|
||||||
type: object
|
type: object
|
||||||
@@ -445,7 +420,7 @@ components:
|
|||||||
type: string
|
type: string
|
||||||
|
|
||||||
CommandSubmitSuccess:
|
CommandSubmitSuccess:
|
||||||
description: The command was submitted successfully.
|
description: The command was submitted succesfully.
|
||||||
properties:
|
properties:
|
||||||
serialNumber:
|
serialNumber:
|
||||||
type: string
|
type: string
|
||||||
@@ -483,10 +458,6 @@ components:
|
|||||||
logType:
|
logType:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
example:
|
|
||||||
- 0 normal logs
|
|
||||||
- 1 crash logs
|
|
||||||
- 2 reboot logs
|
|
||||||
UUID:
|
UUID:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
@@ -553,35 +524,6 @@ components:
|
|||||||
items:
|
items:
|
||||||
$ref : '#/components/schemas/DefaultConfiguration'
|
$ref : '#/components/schemas/DefaultConfiguration'
|
||||||
|
|
||||||
DefaultFirmware:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
deviceType:
|
|
||||||
type: string
|
|
||||||
description:
|
|
||||||
type: string
|
|
||||||
uri:
|
|
||||||
type: string
|
|
||||||
revision:
|
|
||||||
type: string
|
|
||||||
imageCreationDate:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
created:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
lastModified:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
|
|
||||||
DefaultFirmwareList:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
firmwares:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/DefaultFirmware'
|
|
||||||
|
|
||||||
UpgradeRequest:
|
UpgradeRequest:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@@ -903,114 +845,6 @@ components:
|
|||||||
kafkaClients:
|
kafkaClients:
|
||||||
type: integer
|
type: integer
|
||||||
|
|
||||||
RRM_Kick:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
action:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- kick
|
|
||||||
addr:
|
|
||||||
type: string
|
|
||||||
format: mac
|
|
||||||
reason:
|
|
||||||
type: integer
|
|
||||||
default: 5
|
|
||||||
ban_time:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
|
|
||||||
RRM_channel_switch:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
action:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- channel_switch
|
|
||||||
bssid:
|
|
||||||
type: string
|
|
||||||
format: mac
|
|
||||||
channel:
|
|
||||||
type: integer
|
|
||||||
|
|
||||||
RRM_tx_power:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
action:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- tx_power
|
|
||||||
bssid:
|
|
||||||
type: string
|
|
||||||
format: mac
|
|
||||||
level:
|
|
||||||
type: integer
|
|
||||||
|
|
||||||
RRM_beacon_request:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
action:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- beacon_request
|
|
||||||
addr:
|
|
||||||
type: string
|
|
||||||
format: mac
|
|
||||||
ssid:
|
|
||||||
type: string
|
|
||||||
channel:
|
|
||||||
type: integer
|
|
||||||
|
|
||||||
RRM_bss_transition:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
action:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- bss_transition
|
|
||||||
addr:
|
|
||||||
type: string
|
|
||||||
format: mac
|
|
||||||
neighbors:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
format: mac
|
|
||||||
|
|
||||||
RRM_neighbors:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
action:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- neighbors
|
|
||||||
bssid:
|
|
||||||
type: string
|
|
||||||
format: mac
|
|
||||||
neighbors:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
type: string
|
|
||||||
format: mac
|
|
||||||
|
|
||||||
RRM_action:
|
|
||||||
type: object
|
|
||||||
oneOf:
|
|
||||||
- $ref: '#/components/schemas/RRM_Kick'
|
|
||||||
- $ref: '#/components/schemas/RRM_channel_switch'
|
|
||||||
- $ref: '#/components/schemas/RRM_tx_power'
|
|
||||||
- $ref: '#/components/schemas/RRM_beacon_request'
|
|
||||||
- $ref: '#/components/schemas/RRM_bss_transition'
|
|
||||||
- $ref: '#/components/schemas/RRM_neighbors'
|
|
||||||
|
|
||||||
RRM_actions:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
actions:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/RRM_action'
|
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
##
|
##
|
||||||
## These are endpoints that all services in the uCentral stack must provide
|
## These are endpoints that all services in the uCentral stack must provide
|
||||||
@@ -1079,6 +913,12 @@ components:
|
|||||||
- $ref: '#/components/schemas/StringList'
|
- $ref: '#/components/schemas/StringList'
|
||||||
- $ref: '#/components/schemas/TagValuePairList'
|
- $ref: '#/components/schemas/TagValuePairList'
|
||||||
|
|
||||||
|
SystemCommandResults:
|
||||||
|
type: object
|
||||||
|
oneOf:
|
||||||
|
- $ref: '#/components/schemas/StringList'
|
||||||
|
- $ref: '#/components/schemas/TagValuePairList'
|
||||||
|
|
||||||
NoteInfo:
|
NoteInfo:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@@ -1118,33 +958,6 @@ components:
|
|||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
|
|
||||||
SystemResources:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
numberOfFileDescriptors:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
currRealMem:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
peakRealMem:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
currVirtMem:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
peakVirtMem:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
|
|
||||||
SystemCommandResults:
|
|
||||||
type: object
|
|
||||||
oneOf:
|
|
||||||
- $ref: '#/components/schemas/SystemResources'
|
|
||||||
- $ref: '#/components/schemas/SystemInfoResults'
|
|
||||||
- $ref: '#/components/schemas/StringList'
|
|
||||||
- $ref: '#/components/schemas/TagValuePairList'
|
|
||||||
|
|
||||||
SystemCommandSetLogLevel:
|
SystemCommandSetLogLevel:
|
||||||
type: object
|
type: object
|
||||||
properties:
|
properties:
|
||||||
@@ -1447,30 +1260,6 @@ components:
|
|||||||
$ref: '#/components/schemas/RadiusProxyServerConfig'
|
$ref: '#/components/schemas/RadiusProxyServerConfig'
|
||||||
coaConfig:
|
coaConfig:
|
||||||
$ref: '#/components/schemas/RadiusProxyServerConfig'
|
$ref: '#/components/schemas/RadiusProxyServerConfig'
|
||||||
radsecPoolType:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- generic
|
|
||||||
- orion
|
|
||||||
- globalreach
|
|
||||||
- radsec
|
|
||||||
default:
|
|
||||||
generic
|
|
||||||
poolProxyIp:
|
|
||||||
type: string
|
|
||||||
description: This is the fake IP for the entire pool
|
|
||||||
example:
|
|
||||||
- These addresses must match the addresses in the AP configuration and must start with 0.0
|
|
||||||
- 0.0.0.1
|
|
||||||
- 0.0.1.1
|
|
||||||
radsecPoolKeepAlive:
|
|
||||||
type: integer
|
|
||||||
description: The keep alive value in seconds. Usually 30s or less.
|
|
||||||
format: int64
|
|
||||||
default: 25
|
|
||||||
enabled:
|
|
||||||
type: boolean
|
|
||||||
default: true
|
|
||||||
|
|
||||||
RadiusProxyPoolList:
|
RadiusProxyPoolList:
|
||||||
type: object
|
type: object
|
||||||
@@ -1480,92 +1269,6 @@ components:
|
|||||||
items:
|
items:
|
||||||
$ref: '#/components/schemas/RadiusProxyPool'
|
$ref: '#/components/schemas/RadiusProxyPool'
|
||||||
|
|
||||||
RadiusSession:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
started:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
lastTransaction:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
inputPackets:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
outputPackets:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
inputOctets:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
outputOctets:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
inputGigaWords:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
outputGigaWords:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
sessionTime:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
destination:
|
|
||||||
type: string
|
|
||||||
userName:
|
|
||||||
type: string
|
|
||||||
accountingSessionId:
|
|
||||||
type: string
|
|
||||||
accountingMultiSessionId:
|
|
||||||
type: string
|
|
||||||
callingStationId:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
RadiusSessionList:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
sessions:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/RadiusSession'
|
|
||||||
|
|
||||||
RadiusCoADMParameters:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
accountingSessionId:
|
|
||||||
type: string
|
|
||||||
accountingMultiSessionId:
|
|
||||||
type: string
|
|
||||||
callingStationId:
|
|
||||||
type: string
|
|
||||||
chargeableUserIdentity:
|
|
||||||
type: string
|
|
||||||
userName:
|
|
||||||
type: string
|
|
||||||
|
|
||||||
DeviceTransferRequest:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
serialNumber:
|
|
||||||
type: string
|
|
||||||
format: uuid
|
|
||||||
server:
|
|
||||||
type: string
|
|
||||||
format: hostname
|
|
||||||
port:
|
|
||||||
type: integer
|
|
||||||
format: int32
|
|
||||||
|
|
||||||
DeviceCertificateUpdateRequest:
|
|
||||||
type: object
|
|
||||||
properties:
|
|
||||||
serialNumber:
|
|
||||||
type: string
|
|
||||||
encodedCertificate:
|
|
||||||
type: string
|
|
||||||
format: base64
|
|
||||||
description: This is a base64 encoded string of the certificate bundle (the current bundle .tar.gz file from the PKI portal)
|
|
||||||
|
|
||||||
paths:
|
paths:
|
||||||
/devices:
|
/devices:
|
||||||
get:
|
get:
|
||||||
@@ -1674,58 +1377,6 @@ paths:
|
|||||||
404:
|
404:
|
||||||
$ref: '#/components/responses/NotFound'
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
delete:
|
|
||||||
tags:
|
|
||||||
- Devices
|
|
||||||
summary: Delete a list of devices matching a criteria
|
|
||||||
description: Delete a list of devices matching a criteria
|
|
||||||
operationId: deleteDeviceList
|
|
||||||
parameters:
|
|
||||||
- in: query
|
|
||||||
description: Supply a list of devices comma separated
|
|
||||||
name: select
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
example: serial1,serial2,serial3
|
|
||||||
required: false
|
|
||||||
- in: query
|
|
||||||
description: Only simulated devices
|
|
||||||
name: simulatedOnly
|
|
||||||
schema:
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
required: false
|
|
||||||
- in: query
|
|
||||||
description: MAC address must match this pattern. Mutually exclusive with oldestContact
|
|
||||||
name: macPattern
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
example:
|
|
||||||
- "aabbcc*"
|
|
||||||
- "*aabbcc*"
|
|
||||||
- "*cccddee"
|
|
||||||
required: false
|
|
||||||
- in: query
|
|
||||||
description: lastRecordedContact older than this value. Mutually exclusive with macPattern
|
|
||||||
name: oldestContact
|
|
||||||
schema:
|
|
||||||
type: integer
|
|
||||||
format: int64
|
|
||||||
required: false
|
|
||||||
- in: query
|
|
||||||
description: Filter the results
|
|
||||||
name: simulatedDevices
|
|
||||||
schema:
|
|
||||||
type: boolean
|
|
||||||
required: false
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
$ref: '#/components/responses/Success'
|
|
||||||
403:
|
|
||||||
$ref: '#/components/responses/Unauthorized'
|
|
||||||
404:
|
|
||||||
$ref: '#/components/responses/NotFound'
|
|
||||||
|
|
||||||
/commands:
|
/commands:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@@ -1982,123 +1633,6 @@ paths:
|
|||||||
404:
|
404:
|
||||||
$ref: '#/components/responses/NotFound'
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
/default_firmwares:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- Firmware
|
|
||||||
summary: Retrieve the lists of all default firmwares.
|
|
||||||
description: Retrieve the lists of all default firmwares.
|
|
||||||
operationId: getDefaultFirmwares
|
|
||||||
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: List of default firmwares
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/DefaultFirmwareList'
|
|
||||||
403:
|
|
||||||
$ref: '#/components/responses/Unauthorized'
|
|
||||||
404:
|
|
||||||
$ref: '#/components/responses/NotFound'
|
|
||||||
|
|
||||||
/default_firmware/{deviceType}:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- Firmware
|
|
||||||
summary: Retrieve a default firmware.
|
|
||||||
description: Retrieve a default firmware.
|
|
||||||
operationId: getDefaultFirmware
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: deviceType
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: Default firmware included
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/DefaultFirmware'
|
|
||||||
403:
|
|
||||||
$ref: '#/components/responses/Unauthorized'
|
|
||||||
404:
|
|
||||||
$ref: '#/components/responses/NotFound'
|
|
||||||
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- Firmware
|
|
||||||
summary: Create a default firmware.
|
|
||||||
description: Create a default firmware.
|
|
||||||
operationId: createDefaultFirmware
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: deviceType
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
requestBody:
|
|
||||||
description: Information used to create the new firmware entry
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/DefaultFirmware'
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
$ref: '#/components/responses/Success'
|
|
||||||
403:
|
|
||||||
$ref: '#/components/responses/Unauthorized'
|
|
||||||
404:
|
|
||||||
$ref: '#/components/responses/NotFound'
|
|
||||||
|
|
||||||
delete:
|
|
||||||
tags:
|
|
||||||
- Firmware
|
|
||||||
summary: Delete a default default firmware
|
|
||||||
description: Delete a default default firmware
|
|
||||||
operationId: deleteDefaultFirmware
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: deviceType
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
responses:
|
|
||||||
204:
|
|
||||||
$ref: '#/components/responses/Success'
|
|
||||||
403:
|
|
||||||
$ref: '#/components/responses/Unauthorized'
|
|
||||||
404:
|
|
||||||
$ref: '#/components/responses/NotFound'
|
|
||||||
|
|
||||||
put:
|
|
||||||
tags:
|
|
||||||
- Firmware
|
|
||||||
summary: Update a default firmware
|
|
||||||
description: Update a default firmware
|
|
||||||
operationId: updateDefaultFirmware
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: deviceType
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
requestBody:
|
|
||||||
description: Firmware details
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/DefaultFirmware'
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
$ref: '#/components/responses/Success'
|
|
||||||
403:
|
|
||||||
$ref: '#/components/responses/Unauthorized'
|
|
||||||
404:
|
|
||||||
$ref: '#/components/responses/NotFound'
|
|
||||||
|
|
||||||
/device/{serialNumber}:
|
/device/{serialNumber}:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@@ -2241,7 +1775,7 @@ paths:
|
|||||||
format: int64
|
format: int64
|
||||||
- in: query
|
- in: query
|
||||||
name: logType
|
name: logType
|
||||||
description: 0=any kind of logs (default) 0=normal logs, 1=crash logs, 2=reboot logs only
|
description: 0=any kind of logs (default) 0=normal logs only 1=crash logs only
|
||||||
schema:
|
schema:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
@@ -2579,6 +2113,32 @@ paths:
|
|||||||
404:
|
404:
|
||||||
$ref: '#/components/responses/NotFound'
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
/device/{serialNumber}/command:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Commands
|
||||||
|
summary: Post a command to a device
|
||||||
|
operationId: executeCommand
|
||||||
|
parameters:
|
||||||
|
- in: path
|
||||||
|
name: serialNumber
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
required: true
|
||||||
|
requestBody:
|
||||||
|
description: Command details
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: '#/components/schemas/CommandDetails'
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
$ref: '#/components/schemas/CommandInfo'
|
||||||
|
403:
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
404:
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
/device/{serialNumber}/configure:
|
/device/{serialNumber}/configure:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
@@ -2710,7 +2270,7 @@ paths:
|
|||||||
404:
|
404:
|
||||||
$ref: '#/components/responses/NotFound'
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
/device/{serialNumber}/script:
|
/device/{serialNumber}/:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
- Commands
|
- Commands
|
||||||
@@ -2924,88 +2484,6 @@ paths:
|
|||||||
404:
|
404:
|
||||||
$ref: '#/components/responses/NotFound'
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
/device/{serialNumber}/rrm:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- Commands
|
|
||||||
summary: Send RRM commands to a device.
|
|
||||||
operationId: sendRRMcommandsForADevice
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: serialNumber
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
requestBody:
|
|
||||||
description: Commands to send
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
$ref: '#/components/schemas/RRM_actions'
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
$ref: '#/components/responses/Success'
|
|
||||||
403:
|
|
||||||
$ref: '#/components/responses/Unauthorized'
|
|
||||||
404:
|
|
||||||
$ref: '#/components/responses/NotFound'
|
|
||||||
|
|
||||||
/device/{serialNumber}/transfer:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- Commands
|
|
||||||
summary: Transfer a device to a new redirector.
|
|
||||||
operationId: transferDevice
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: serialNumber
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
requestBody:
|
|
||||||
description: Transfer details
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/DeviceTransferRequest'
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
$ref: '#/components/responses/Success'
|
|
||||||
403:
|
|
||||||
$ref: '#/components/responses/Unauthorized'
|
|
||||||
404:
|
|
||||||
$ref: '#/components/responses/NotFound'
|
|
||||||
|
|
||||||
/device/{serialNumber}/certupdate:
|
|
||||||
post:
|
|
||||||
tags:
|
|
||||||
- Commands
|
|
||||||
summary: Update the certificates for a device.
|
|
||||||
operationId: updateCertificates
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: serialNumber
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
requestBody:
|
|
||||||
description: Certificate update details
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
type: array
|
|
||||||
items:
|
|
||||||
$ref: '#/components/schemas/DeviceCertificateUpdateRequest'
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
$ref: '#/components/responses/Success'
|
|
||||||
403:
|
|
||||||
$ref: '#/components/responses/Unauthorized'
|
|
||||||
404:
|
|
||||||
$ref: '#/components/responses/NotFound'
|
|
||||||
|
|
||||||
/ouis:
|
/ouis:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@@ -3245,6 +2723,9 @@ paths:
|
|||||||
404:
|
404:
|
||||||
$ref: '#/components/responses/NotFound'
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/blacklist:
|
/blacklist:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@@ -3437,81 +2918,6 @@ paths:
|
|||||||
403:
|
403:
|
||||||
$ref: '#/components/responses/Unauthorized'
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
|
||||||
/radiusSessions/{serialNumber}:
|
|
||||||
get:
|
|
||||||
tags:
|
|
||||||
- Radius Sessions
|
|
||||||
summary: Retrieve the RADIUS sessions for a given AP
|
|
||||||
operationId: getAPRadiusSessions
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: serialNumber
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
example: for searches or listing only serial number, set the serialNumber to 0
|
|
||||||
required: true
|
|
||||||
- in: query
|
|
||||||
name: serialNumberOnly
|
|
||||||
schema:
|
|
||||||
type: boolean
|
|
||||||
required: false
|
|
||||||
- in: query
|
|
||||||
name: userName
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: false
|
|
||||||
- in: query
|
|
||||||
name: mac
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: false
|
|
||||||
example: aa:bb:cc:dd:ee:ff
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
description: AP List
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
oneOf:
|
|
||||||
- $ref: '#/components/schemas/RadiusSessionList'
|
|
||||||
- $ref: '#/components/schemas/SerialNumberList'
|
|
||||||
403:
|
|
||||||
$ref: '#/components/responses/Unauthorized'
|
|
||||||
404:
|
|
||||||
$ref: '#/components/responses/NotFound'
|
|
||||||
put:
|
|
||||||
tags:
|
|
||||||
- Radius Sessions
|
|
||||||
summary: Retrieve the RADIUS sessions for a given AP
|
|
||||||
operationId: putAPRadiusSessions
|
|
||||||
parameters:
|
|
||||||
- in: path
|
|
||||||
name: serialNumber
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
required: true
|
|
||||||
- in: query
|
|
||||||
name: operation
|
|
||||||
schema:
|
|
||||||
type: string
|
|
||||||
enum:
|
|
||||||
- coadm
|
|
||||||
- disconnectUser
|
|
||||||
requestBody:
|
|
||||||
description: operationParameters
|
|
||||||
content:
|
|
||||||
application/json:
|
|
||||||
schema:
|
|
||||||
oneOf:
|
|
||||||
- $ref: '#/components/schemas/RadiusCoADMParameters'
|
|
||||||
responses:
|
|
||||||
200:
|
|
||||||
$ref: '#/components/responses/Success'
|
|
||||||
403:
|
|
||||||
$ref: '#/components/responses/Unauthorized'
|
|
||||||
404:
|
|
||||||
$ref: '#/components/responses/NotFound'
|
|
||||||
|
|
||||||
/deviceDashboard:
|
/deviceDashboard:
|
||||||
get:
|
get:
|
||||||
tags:
|
tags:
|
||||||
@@ -3608,12 +3014,16 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
enum:
|
enum:
|
||||||
- info
|
- info
|
||||||
- extraConfiguration
|
|
||||||
- resources
|
|
||||||
required: true
|
required: true
|
||||||
|
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
$ref: '#/components/schemas/SystemCommandResults'
|
description: Successful command execution
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
oneOf:
|
||||||
|
- $ref: '#/components/schemas/SystemInfoResults'
|
||||||
403:
|
403:
|
||||||
$ref: '#/components/responses/Unauthorized'
|
$ref: '#/components/responses/Unauthorized'
|
||||||
404:
|
404:
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ iptocountry.ipdata.apikey = ${IPTOCOUNTRY_IPDATA_APIKEY}
|
|||||||
|
|
||||||
autoprovisioning.process = ${AUTOPROVISIONING_PROCESS}
|
autoprovisioning.process = ${AUTOPROVISIONING_PROCESS}
|
||||||
|
|
||||||
openwifi.session.timeout = ${DEVICE_SESSION_TIMEOUT}
|
|
||||||
#
|
#
|
||||||
# rtty
|
# rtty
|
||||||
#
|
#
|
||||||
@@ -104,12 +103,6 @@ radius.proxy.accounting.port = ${RADIUS_PROXY_ACCOUNTING_PORT}
|
|||||||
radius.proxy.authentication.port = ${RADIUS_PROXY_AUTHENTICATION_PORT}
|
radius.proxy.authentication.port = ${RADIUS_PROXY_AUTHENTICATION_PORT}
|
||||||
radius.proxy.coa.port = ${RADIUS_PROXY_COA_PORT}
|
radius.proxy.coa.port = ${RADIUS_PROXY_COA_PORT}
|
||||||
|
|
||||||
iptocountry.default = ${IPINFO_DEFAULT_COUNTRY}
|
|
||||||
#iptocountry.provider = ipinfo
|
|
||||||
#iptocountry.provider = ipdata
|
|
||||||
#iptocountry.ipinfo.token =
|
|
||||||
#iptocountry.ipdata.apikey =
|
|
||||||
|
|
||||||
#############################
|
#############################
|
||||||
# Generic information for all micro services
|
# Generic information for all micro services
|
||||||
#############################
|
#############################
|
||||||
@@ -145,7 +138,7 @@ storage.type.sqlite.db = devices.db
|
|||||||
storage.type.sqlite.idletime = 120
|
storage.type.sqlite.idletime = 120
|
||||||
storage.type.sqlite.maxsessions = 128
|
storage.type.sqlite.maxsessions = 128
|
||||||
|
|
||||||
storage.type.postgresql.maxsessions = 250
|
storage.type.postgresql.maxsessions = 64
|
||||||
storage.type.postgresql.idletime = 60
|
storage.type.postgresql.idletime = 60
|
||||||
storage.type.postgresql.host = ${STORAGE_TYPE_POSTGRESQL_HOST}
|
storage.type.postgresql.host = ${STORAGE_TYPE_POSTGRESQL_HOST}
|
||||||
storage.type.postgresql.username = ${STORAGE_TYPE_POSTGRESQL_USERNAME}
|
storage.type.postgresql.username = ${STORAGE_TYPE_POSTGRESQL_USERNAME}
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2023-05-23.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "AP_WS_ConfigAutoUpgrader.h"
|
|
||||||
#include <framework/utils.h>
|
|
||||||
#include <RESTObjects/RESTAPI_GWobjects.h>
|
|
||||||
#include <StorageService.h>
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
|
|
||||||
int AP_WS_ConfigAutoUpgrader::Start() {
|
|
||||||
poco_notice(Logger(), "Starting...");
|
|
||||||
QueueManager_.start(*this);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AP_WS_ConfigAutoUpgrader::Stop() {
|
|
||||||
poco_notice(Logger(), "Stopping...");
|
|
||||||
Running_ = false;
|
|
||||||
Queue_.wakeUpAll();
|
|
||||||
QueueManager_.join();
|
|
||||||
poco_notice(Logger(), "Stopped...");
|
|
||||||
}
|
|
||||||
|
|
||||||
void AP_WS_ConfigAutoUpgrader::run() {
|
|
||||||
Utils::SetThreadName("auto:cfgmgr");
|
|
||||||
Running_ = true;
|
|
||||||
|
|
||||||
while (Running_) {
|
|
||||||
Poco::AutoPtr<Poco::Notification> NextMsg(Queue_.waitDequeueNotification());
|
|
||||||
try {
|
|
||||||
auto Entry = dynamic_cast<CheckConfiguration *>(NextMsg.get());
|
|
||||||
if (Entry != nullptr) {
|
|
||||||
GWObjects::Device DeviceInfo;
|
|
||||||
std::string SerialNumber = Utils::IntToSerialNumber(Entry->serial_);
|
|
||||||
if (StorageService()->GetDevice(SerialNumber, DeviceInfo)) {
|
|
||||||
if(DeviceInfo.pendingUUID!=0 && Entry->uuid_==DeviceInfo.pendingUUID) {
|
|
||||||
StorageService()->CompleteDeviceConfigurationChange(SerialNumber);
|
|
||||||
SetDeviceCacheEntry(Entry->serial_, Utils::Now(), Entry->uuid_, 0);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(DeviceInfo.UUID==Entry->uuid_) {
|
|
||||||
SetDeviceCacheEntry(Entry->serial_, Utils::Now(), Entry->uuid_, 0);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
Logger().log(E);
|
|
||||||
} catch (...) {
|
|
||||||
poco_warning(Logger(), "Exception occurred during run.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2023-05-23.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Poco/Notification.h"
|
|
||||||
#include "Poco/NotificationQueue.h"
|
|
||||||
#include "Poco/Timer.h"
|
|
||||||
|
|
||||||
#include <framework/SubSystemServer.h>
|
|
||||||
#include <framework/utils.h>
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
|
|
||||||
class CheckConfiguration : public Poco::Notification {
|
|
||||||
public:
|
|
||||||
explicit CheckConfiguration(std::uint64_t s, std::uint64_t c) :
|
|
||||||
serial_(s), uuid_(c) {
|
|
||||||
}
|
|
||||||
std::uint64_t serial_;
|
|
||||||
std::uint64_t uuid_;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ConfigurationCacheEntry {
|
|
||||||
std::uint64_t last_check_=0;
|
|
||||||
std::uint64_t current_config_=0;
|
|
||||||
std::uint64_t pending_config_=0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AP_WS_ConfigAutoUpgrader : public SubSystemServer, Poco::Runnable {
|
|
||||||
public:
|
|
||||||
int Start() final;
|
|
||||||
void Stop() final;
|
|
||||||
void run() final;
|
|
||||||
|
|
||||||
static auto instance() {
|
|
||||||
static auto instance = new AP_WS_ConfigAutoUpgrader;
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void AddConfiguration(std::uint64_t serial, std::uint64_t config_uuid) {
|
|
||||||
std::lock_guard Guard(CacheMutex_);
|
|
||||||
auto hint = Cache_.find(serial);
|
|
||||||
if(hint==end(Cache_)) {
|
|
||||||
Cache_[serial] = { Utils::Now(),config_uuid , 0 };
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(hint->second.pending_config_==0) {
|
|
||||||
hint->second.last_check_ = Utils::Now();
|
|
||||||
hint->second.current_config_ = config_uuid;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void AddConfiguration(std::uint64_t serial, std::uint64_t config_uuid, std::uint64_t pending_config_uuid) {
|
|
||||||
std::lock_guard Guard(CacheMutex_);
|
|
||||||
auto hint = Cache_.find(serial);
|
|
||||||
if(hint==end(Cache_)) {
|
|
||||||
Cache_[serial] = { Utils::Now(), config_uuid , pending_config_uuid };
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(hint->second.pending_config_==0) {
|
|
||||||
hint->second.last_check_ = Utils::Now();
|
|
||||||
hint->second.current_config_ = config_uuid;
|
|
||||||
hint->second.pending_config_ = pending_config_uuid;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] inline ConfigurationCacheEntry GetSerialInfo(std::uint64_t serial) const {
|
|
||||||
std::lock_guard Guard(CacheMutex_);
|
|
||||||
auto hint = Cache_.find(serial);
|
|
||||||
if(hint==end(Cache_)) {
|
|
||||||
return {0,0,0};
|
|
||||||
}
|
|
||||||
return hint->second;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool UpdateConfiguration(std::uint64_t serial, std::uint64_t config) {
|
|
||||||
|
|
||||||
if(serial==0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
std::lock_guard Guard(CacheMutex_);
|
|
||||||
auto hint = Cache_.find(serial);
|
|
||||||
if(hint!=end(Cache_)) {
|
|
||||||
|
|
||||||
if(hint->second.current_config_==config) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(config==hint->second.pending_config_) {
|
|
||||||
Queue_.enqueueNotification(new CheckConfiguration(serial,config));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(config!=hint->second.current_config_ && hint->second.pending_config_==0) {
|
|
||||||
Queue_.enqueueNotification(new CheckConfiguration(serial,config));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((Utils::Now()-hint->second.last_check_)<60*5) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(hint->second.pending_config_!=0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void SetDeviceCacheEntry(std::uint64_t serial, std::uint64_t t, std::uint64_t uuid, std::uint64_t pending_uuid) {
|
|
||||||
std::lock_guard Guard(CacheMutex_);
|
|
||||||
Cache_[serial] = { t, uuid, pending_uuid };
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
Poco::NotificationQueue Queue_;
|
|
||||||
Poco::Thread QueueManager_;
|
|
||||||
std::atomic_bool Running_=false;
|
|
||||||
|
|
||||||
mutable std::mutex CacheMutex_;
|
|
||||||
std::map<std::uint64_t, ConfigurationCacheEntry> Cache_;
|
|
||||||
|
|
||||||
AP_WS_ConfigAutoUpgrader() noexcept
|
|
||||||
: SubSystemServer("AutoConfigUpgrade", "AUTO-CFG-MGR", "auto.config.updater") {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline auto AP_WS_ConfigAutoUpgrader() { return AP_WS_ConfigAutoUpgrader::instance(); }
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
|
||||||
|
|
||||||
@@ -31,25 +31,26 @@
|
|||||||
|
|
||||||
#include "framework/ow_constants.h"
|
#include "framework/ow_constants.h"
|
||||||
|
|
||||||
#include "RADIUSSessionTracker.h"
|
|
||||||
#include "RADIUS_proxy_server.h"
|
#include "RADIUS_proxy_server.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
|
#define DBL \
|
||||||
|
{ \
|
||||||
|
std::cout << __LINE__ << " ID: " << ConnectionId_ << " Ser: " << SerialNumber_ \
|
||||||
|
<< std::endl; \
|
||||||
|
}
|
||||||
|
|
||||||
void AP_WS_Connection::LogException(const Poco::Exception &E) {
|
void AP_WS_Connection::LogException(const Poco::Exception &E) {
|
||||||
poco_information(Logger_, fmt::format("EXCEPTION({}): {}", CId_, E.displayText()));
|
poco_information(Logger_, fmt::format("EXCEPTION({}): {}", CId_, E.displayText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
AP_WS_Connection::AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
|
AP_WS_Connection::AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
|
||||||
Poco::Net::HTTPServerResponse &response,
|
Poco::Net::HTTPServerResponse &response,
|
||||||
uint64_t session_id, Poco::Logger &L,
|
uint64_t connection_id, Poco::Logger &L,
|
||||||
std::pair<std::shared_ptr<Poco::Net::SocketReactor>, std::shared_ptr<LockedDbSession>> R)
|
Poco::Net::SocketReactor &R)
|
||||||
: Logger_(L) {
|
: Logger_(L), Reactor_(R) {
|
||||||
|
State_.sessionId = connection_id;
|
||||||
Reactor_ = R.first;
|
|
||||||
DbSession_ = R.second;
|
|
||||||
State_.sessionId = session_id;
|
|
||||||
|
|
||||||
WS_ = std::make_unique<Poco::Net::WebSocket>(request, response);
|
WS_ = std::make_unique<Poco::Net::WebSocket>(request, response);
|
||||||
|
|
||||||
auto TS = Poco::Timespan(360, 0);
|
auto TS = Poco::Timespan(360, 0);
|
||||||
@@ -59,89 +60,28 @@ namespace OpenWifi {
|
|||||||
WS_->setNoDelay(false);
|
WS_->setNoDelay(false);
|
||||||
WS_->setKeepAlive(true);
|
WS_->setKeepAlive(true);
|
||||||
WS_->setBlocking(false);
|
WS_->setBlocking(false);
|
||||||
uuid_ = MicroServiceRandom(std::numeric_limits<std::uint64_t>::max()-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AP_WS_Connection::Start() {
|
Reactor_.addEventHandler(*WS_,
|
||||||
Registered_ = true;
|
|
||||||
LastContact_ = Utils::Now();
|
|
||||||
|
|
||||||
Reactor_->addEventHandler(*WS_,
|
|
||||||
Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
|
Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
|
||||||
*this, &AP_WS_Connection::OnSocketReadable));
|
*this, &AP_WS_Connection::OnSocketReadable));
|
||||||
Reactor_->addEventHandler(*WS_,
|
Reactor_.addEventHandler(*WS_,
|
||||||
Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
|
Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
|
||||||
*this, &AP_WS_Connection::OnSocketShutdown));
|
*this, &AP_WS_Connection::OnSocketShutdown));
|
||||||
Reactor_->addEventHandler(*WS_,
|
Reactor_.addEventHandler(*WS_,
|
||||||
Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
|
Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
|
||||||
*this, &AP_WS_Connection::OnSocketError));
|
*this, &AP_WS_Connection::OnSocketError));
|
||||||
|
Registered_ = true;
|
||||||
}
|
Valid_ = true;
|
||||||
|
|
||||||
AP_WS_Connection::~AP_WS_Connection() {
|
|
||||||
// poco_information(Logger_, fmt::format("DESTRUCTOR({}): 0 - Session={} Connection closed.", SerialNumber_,
|
|
||||||
// State_.sessionId));
|
|
||||||
std::lock_guard G(ConnectionMutex_);
|
|
||||||
// poco_information(Logger_, fmt::format("DESTRUCTOR({}): 1 - Session={} Connection closed.", SerialNumber_,
|
|
||||||
// State_.sessionId));
|
|
||||||
EndConnection(false);
|
|
||||||
poco_debug(Logger_, fmt::format("TERMINATION({}): Session={}, Connection removed.", SerialNumber_,
|
|
||||||
State_.sessionId));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void NotifyKafkaDisconnect(const std::string &SerialNumber, std::uint64_t uuid) {
|
|
||||||
try {
|
|
||||||
Poco::JSON::Object Disconnect;
|
|
||||||
Poco::JSON::Object Details;
|
|
||||||
Details.set(uCentralProtocol::SERIALNUMBER, SerialNumber);
|
|
||||||
Details.set(uCentralProtocol::TIMESTAMP, Utils::Now());
|
|
||||||
Details.set(uCentralProtocol::UUID,uuid);
|
|
||||||
Disconnect.set(uCentralProtocol::DISCONNECTION, Details);
|
|
||||||
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber, Disconnect);
|
|
||||||
} catch (...) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AP_WS_Connection::EndConnection(bool Clean) {
|
|
||||||
bool expectedValue=false;
|
|
||||||
if (Dead_.compare_exchange_strong(expectedValue,true,std::memory_order_release,std::memory_order_relaxed)) {
|
|
||||||
|
|
||||||
if(!SerialNumber_.empty() && State_.LastContact!=0) {
|
|
||||||
StorageService()->SetDeviceLastRecordedContact(SerialNumber_, State_.LastContact);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Registered_) {
|
|
||||||
Registered_ = false;
|
|
||||||
Reactor_->removeEventHandler(
|
|
||||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &AP_WS_Connection::OnSocketReadable));
|
|
||||||
Reactor_->removeEventHandler(
|
|
||||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
|
|
||||||
*this, &AP_WS_Connection::OnSocketShutdown));
|
|
||||||
Reactor_->removeEventHandler(
|
|
||||||
*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
|
|
||||||
*this, &AP_WS_Connection::OnSocketError));
|
|
||||||
Registered_=false;
|
|
||||||
}
|
|
||||||
WS_->close();
|
|
||||||
|
|
||||||
if(!SerialNumber_.empty()) {
|
|
||||||
DeviceDisconnectionCleanup(SerialNumber_, uuid_);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Clean)
|
|
||||||
AP_WS_Server()->EndSession(State_.sessionId, SerialNumberInt_);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Connection::ValidatedDevice() {
|
bool AP_WS_Connection::ValidatedDevice() {
|
||||||
|
|
||||||
if(Dead_)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (DeviceValidated_)
|
if (DeviceValidated_)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (!Valid_)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
std::lock_guard Lock(ConnectionMutex_);
|
||||||
try {
|
try {
|
||||||
auto SockImpl = dynamic_cast<Poco::Net::WebSocketImpl *>(WS_->impl());
|
auto SockImpl = dynamic_cast<Poco::Net::WebSocketImpl *>(WS_->impl());
|
||||||
auto SS =
|
auto SS =
|
||||||
@@ -156,6 +96,7 @@ namespace OpenWifi {
|
|||||||
poco_warning(Logger_, fmt::format("TLS-CONNECTION({}): Session={} Connection is "
|
poco_warning(Logger_, fmt::format("TLS-CONNECTION({}): Session={} Connection is "
|
||||||
"NOT secure. Device is not allowed.",
|
"NOT secure. Device is not allowed.",
|
||||||
CId_, State_.sessionId));
|
CId_, State_.sessionId));
|
||||||
|
EndConnection();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,6 +109,7 @@ namespace OpenWifi {
|
|||||||
Logger_,
|
Logger_,
|
||||||
fmt::format("TLS-CONNECTION({}): Session={} No certificates available..", CId_,
|
fmt::format("TLS-CONNECTION({}): Session={} No certificates available..", CId_,
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
|
EndConnection();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,21 +120,13 @@ namespace OpenWifi {
|
|||||||
fmt::format("TLS-CONNECTION({}): Session={} Device certificate is not "
|
fmt::format("TLS-CONNECTION({}): Session={} Device certificate is not "
|
||||||
"valid. Device is not allowed.",
|
"valid. Device is not allowed.",
|
||||||
CId_, State_.sessionId));
|
CId_, State_.sessionId));
|
||||||
|
EndConnection();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CN_ = Poco::trim(Poco::toLower(PeerCert.commonName()));
|
CN_ = Poco::trim(Poco::toLower(PeerCert.commonName()));
|
||||||
if(!Utils::ValidSerialNumber(CN_)) {
|
|
||||||
poco_trace(Logger_,
|
|
||||||
fmt::format("TLS-CONNECTION({}): Session={} Invalid serial number: CN={}", CId_,
|
|
||||||
State_.sessionId, CN_));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
SerialNumber_ = CN_;
|
|
||||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
|
||||||
|
|
||||||
State_.VerifiedCertificate = GWObjects::VALID_CERTIFICATE;
|
State_.VerifiedCertificate = GWObjects::VALID_CERTIFICATE;
|
||||||
poco_trace(Logger_,
|
poco_information(Logger_,
|
||||||
fmt::format("TLS-CONNECTION({}): Session={} Valid certificate: CN={}", CId_,
|
fmt::format("TLS-CONNECTION({}): Session={} Valid certificate: CN={}", CId_,
|
||||||
State_.sessionId, CN_));
|
State_.sessionId, CN_));
|
||||||
|
|
||||||
@@ -200,27 +134,26 @@ namespace OpenWifi {
|
|||||||
poco_warning(Logger_, fmt::format("TLS-CONNECTION({}): Session={} Sim Device {} is "
|
poco_warning(Logger_, fmt::format("TLS-CONNECTION({}): Session={} Sim Device {} is "
|
||||||
"not allowed. Disconnecting.",
|
"not allowed. Disconnecting.",
|
||||||
CId_, State_.sessionId, CN_));
|
CId_, State_.sessionId, CN_));
|
||||||
|
EndConnection();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(AP_WS_Server::IsSim(SerialNumber_)) {
|
|
||||||
State_.VerifiedCertificate = GWObjects::SIMULATED;
|
|
||||||
Simulated_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string reason, author;
|
std::string reason, author;
|
||||||
std::uint64_t created;
|
std::uint64_t created;
|
||||||
if (!CN_.empty() && StorageService()->IsBlackListed(SerialNumberInt_, reason, author, created)) {
|
if (!CN_.empty() && StorageService()->IsBlackListed(CN_, reason, author, created)) {
|
||||||
DeviceBlacklistedKafkaEvent KE(Utils::SerialNumberToInt(CN_), Utils::Now(), reason, author, created, CId_);
|
DeviceBlacklistedKafkaEvent KE(CN_, Utils::Now(), reason, author, created, CId_);
|
||||||
poco_warning(
|
poco_warning(
|
||||||
Logger_,
|
Logger_,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"TLS-CONNECTION({}): Session={} Device {} is black listed. Disconnecting.",
|
"TLS-CONNECTION({}): Session={} Device {} is black listed. Disconnecting.",
|
||||||
CId_, State_.sessionId, CN_));
|
CId_, State_.sessionId, CN_));
|
||||||
|
EndConnection();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
State_.certificateExpiryDate = PeerCert.expiresOn().timestamp().epochTime();
|
State_.certificateExpiryDate = PeerCert.expiresOn().timestamp().epochTime();
|
||||||
|
SerialNumber_ = CN_;
|
||||||
|
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
||||||
|
|
||||||
poco_trace(Logger_,
|
poco_trace(Logger_,
|
||||||
fmt::format("TLS-CONNECTION({}): Session={} CN={} Completed. (t={})", CId_,
|
fmt::format("TLS-CONNECTION({}): Session={} CN={} Completed. (t={})", CId_,
|
||||||
@@ -284,15 +217,139 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Connection::DeviceDisconnectionCleanup(const std::string &SerialNumber, std::uint64_t uuid) {
|
static void NotifyKafkaDisconnect(const std::string &SerialNumber) {
|
||||||
if (KafkaManager()->Enabled()) {
|
try {
|
||||||
NotifyKafkaDisconnect(SerialNumber, uuid);
|
Poco::JSON::Object Disconnect;
|
||||||
|
Poco::JSON::Object Details;
|
||||||
|
Details.set(uCentralProtocol::SERIALNUMBER, SerialNumber);
|
||||||
|
Details.set(uCentralProtocol::TIMESTAMP, Utils::Now());
|
||||||
|
Disconnect.set(uCentralProtocol::DISCONNECTION, Details);
|
||||||
|
Poco::JSON::Stringifier Stringify;
|
||||||
|
std::ostringstream OS;
|
||||||
|
Stringify.condense(Disconnect, OS);
|
||||||
|
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber, OS.str());
|
||||||
|
} catch (...) {
|
||||||
}
|
}
|
||||||
RADIUSSessionTracker()->DeviceDisconnect(SerialNumber);
|
}
|
||||||
|
|
||||||
|
AP_WS_Connection::~AP_WS_Connection() {
|
||||||
|
Valid_ = false;
|
||||||
|
EndConnection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AP_WS_Connection::EndConnection() {
|
||||||
|
Valid_ = false;
|
||||||
|
if (!Dead_.test_and_set()) {
|
||||||
|
|
||||||
|
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;
|
GWWebSocketNotifications::SingleDevice_t N;
|
||||||
N.content.serialNumber = SerialNumber;
|
N.content.serialNumber = SerialNumber_;
|
||||||
GWWebSocketNotifications::DeviceDisconnected(N);
|
GWWebSocketNotifications::DeviceDisconnected(N);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AP_WS_Connection::LookForUpgrade(const uint64_t UUID, uint64_t &UpgradedUUID) {
|
||||||
|
|
||||||
|
// A UUID of zero means ignore updates for that connection.
|
||||||
|
if (UUID == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
uint64_t GoodConfig = ConfigurationCache().CurrentConfig(SerialNumberInt_);
|
||||||
|
if (GoodConfig && (GoodConfig == UUID || GoodConfig == State_.PendingUUID)) {
|
||||||
|
UpgradedUUID = UUID;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GWObjects::Device D;
|
||||||
|
if (StorageService()->GetDevice(SerialNumber_, D)) {
|
||||||
|
|
||||||
|
if(D.pendingUUID!=0 && UUID==D.pendingUUID) {
|
||||||
|
// so we sent an upgrade to a device, and now it is completing now...
|
||||||
|
UpgradedUUID = D.pendingUUID;
|
||||||
|
StorageService()->CompleteDeviceConfigurationChange(SerialNumber_);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the case where the cache is empty after a restart. So GoodConfig will 0. If
|
||||||
|
// the device already has the right UUID, we just return.
|
||||||
|
if (D.UUID == UUID) {
|
||||||
|
UpgradedUUID = UUID;
|
||||||
|
ConfigurationCache().Add(SerialNumberInt_, UUID);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Config::Config Cfg(D.Configuration);
|
||||||
|
if (UUID > D.UUID) {
|
||||||
|
// so we have a problem, the device has a newer config than we have. So we need to
|
||||||
|
// make sure our config is newer.
|
||||||
|
D.UUID = UUID + 2;
|
||||||
|
UpgradedUUID = D.UUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cfg.SetUUID(D.UUID);
|
||||||
|
D.Configuration = Cfg.get();
|
||||||
|
State_.PendingUUID = UpgradedUUID = D.UUID;
|
||||||
|
|
||||||
|
GWObjects::CommandDetails Cmd;
|
||||||
|
Cmd.SerialNumber = SerialNumber_;
|
||||||
|
Cmd.UUID = MicroServiceCreateUUID();
|
||||||
|
Cmd.SubmittedBy = uCentralProtocol::SUBMITTED_BY_SYSTEM;
|
||||||
|
Cmd.Status = uCentralProtocol::PENDING;
|
||||||
|
Cmd.Command = uCentralProtocol::CONFIGURE;
|
||||||
|
Poco::JSON::Parser P;
|
||||||
|
auto ParsedConfig = P.parse(D.Configuration).extract<Poco::JSON::Object::Ptr>();
|
||||||
|
Poco::JSON::Object Params;
|
||||||
|
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||||
|
Params.set(uCentralProtocol::UUID, D.UUID);
|
||||||
|
Params.set(uCentralProtocol::WHEN, 0);
|
||||||
|
Params.set(uCentralProtocol::CONFIG, ParsedConfig);
|
||||||
|
|
||||||
|
std::ostringstream O;
|
||||||
|
Poco::JSON::Stringifier::stringify(Params, O);
|
||||||
|
Cmd.Details = O.str();
|
||||||
|
poco_information(Logger_,
|
||||||
|
fmt::format("CFG-UPGRADE({}): Current ID: {}, newer configuration {}.",
|
||||||
|
CId_, UUID, D.UUID));
|
||||||
|
bool Sent;
|
||||||
|
|
||||||
|
StorageService()->AddCommand(SerialNumber_, Cmd,
|
||||||
|
Storage::CommandExecutionType::COMMAND_EXECUTED);
|
||||||
|
CommandManager()->PostCommand(
|
||||||
|
CommandManager()->Next_RPC_ID(), APCommands::to_apcommand(Cmd.Command.c_str()),
|
||||||
|
SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent, false, false);
|
||||||
|
|
||||||
|
GWWebSocketNotifications::SingleDeviceConfigurationChange_t Notification;
|
||||||
|
Notification.content.serialNumber = D.SerialNumber;
|
||||||
|
Notification.content.oldUUID = UUID;
|
||||||
|
Notification.content.newUUID = UpgradedUUID;
|
||||||
|
GWWebSocketNotifications::DeviceConfigurationChange(Notification);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void AP_WS_Connection::ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc) {
|
void AP_WS_Connection::ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc) {
|
||||||
poco_trace(Logger_, fmt::format("RECEIVED-RPC({}): {}.", CId_,
|
poco_trace(Logger_, fmt::format("RECEIVED-RPC({}): {}.", CId_,
|
||||||
@@ -372,8 +429,8 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
std::string reason, author;
|
std::string reason, author;
|
||||||
std::uint64_t created;
|
std::uint64_t created;
|
||||||
if (StorageService()->IsBlackListed(SerialNumberInt_, reason, author, created)) {
|
if (StorageService()->IsBlackListed(Serial, reason, author, created)) {
|
||||||
DeviceBlacklistedKafkaEvent KE(Utils::SerialNumberToInt(CN_), Utils::Now(), reason, author, created, CId_);
|
DeviceBlacklistedKafkaEvent KE(CN_, Utils::Now(), reason, author, created, CId_);
|
||||||
Poco::Exception E(
|
Poco::Exception E(
|
||||||
fmt::format("BLACKLIST({}): device is blacklisted and not allowed to connect.",
|
fmt::format("BLACKLIST({}): device is blacklisted and not allowed to connect.",
|
||||||
Serial),
|
Serial),
|
||||||
@@ -438,10 +495,6 @@ namespace OpenWifi {
|
|||||||
Process_wifiscan(ParamsObj);
|
Process_wifiscan(ParamsObj);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case uCentralProtocol::Events::ET_REBOOTLOG: {
|
|
||||||
Process_rebootLog(ParamsObj);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
// this will never be called but some compilers will complain if we do not have a case for
|
// this will never be called but some compilers will complain if we do not have a case for
|
||||||
// every single values of an enum
|
// every single values of an enum
|
||||||
case uCentralProtocol::Events::ET_UNKNOWN: {
|
case uCentralProtocol::Events::ET_UNKNOWN: {
|
||||||
@@ -503,17 +556,17 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Connection::SetWebSocketTelemetryReporting(
|
bool AP_WS_Connection::SetWebSocketTelemetryReporting(
|
||||||
std::uint64_t RPCID, std::uint64_t Interval, std::uint64_t LifeTime,
|
uint64_t RPCID, uint64_t Interval, uint64_t LifeTime,
|
||||||
const std::vector<std::string> &TelemetryTypes) {
|
const std::vector<std::string> &TelemetryTypes) {
|
||||||
std::unique_lock Lock(TelemetryMutex_);
|
std::unique_lock Lock(TelemetryMutex_);
|
||||||
TelemetryWebSocketRefCount_++;
|
TelemetryWebSocketRefCount_++;
|
||||||
TelemetryInterval_ = TelemetryInterval_
|
TelemetryInterval_ = TelemetryInterval_
|
||||||
? (Interval < (std::uint64_t)TelemetryInterval_ ? Interval : (std::uint64_t )TelemetryInterval_)
|
? (Interval < TelemetryInterval_ ? Interval : TelemetryInterval_)
|
||||||
: Interval;
|
: Interval;
|
||||||
auto TelemetryWebSocketTimer = LifeTime + Utils::Now();
|
auto TelemetryWebSocketTimer = LifeTime + Utils::Now();
|
||||||
TelemetryWebSocketTimer_ = TelemetryWebSocketTimer > (std::uint64_t)TelemetryWebSocketTimer_
|
TelemetryWebSocketTimer_ = TelemetryWebSocketTimer > TelemetryWebSocketTimer_
|
||||||
? (std::uint64_t)TelemetryWebSocketTimer
|
? TelemetryWebSocketTimer
|
||||||
: (std::uint64_t)TelemetryWebSocketTimer_;
|
: TelemetryWebSocketTimer_;
|
||||||
UpdateCounts();
|
UpdateCounts();
|
||||||
if (!TelemetryReporting_) {
|
if (!TelemetryReporting_) {
|
||||||
TelemetryReporting_ = true;
|
TelemetryReporting_ = true;
|
||||||
@@ -529,11 +582,11 @@ namespace OpenWifi {
|
|||||||
std::unique_lock Lock(TelemetryMutex_);
|
std::unique_lock Lock(TelemetryMutex_);
|
||||||
TelemetryKafkaRefCount_++;
|
TelemetryKafkaRefCount_++;
|
||||||
TelemetryInterval_ = TelemetryInterval_
|
TelemetryInterval_ = TelemetryInterval_
|
||||||
? (Interval < (std::uint64_t)TelemetryInterval_ ? (std::uint64_t)Interval : (std::uint64_t)TelemetryInterval_)
|
? (Interval < TelemetryInterval_ ? Interval : TelemetryInterval_)
|
||||||
: Interval;
|
: Interval;
|
||||||
auto TelemetryKafkaTimer = LifeTime + Utils::Now();
|
auto TelemetryKafkaTimer = LifeTime + Utils::Now();
|
||||||
TelemetryKafkaTimer_ =
|
TelemetryKafkaTimer_ =
|
||||||
TelemetryKafkaTimer > (std::uint64_t)TelemetryKafkaTimer_ ? (std::uint64_t)TelemetryKafkaTimer : (std::uint64_t)TelemetryKafkaTimer_;
|
TelemetryKafkaTimer > TelemetryKafkaTimer_ ? TelemetryKafkaTimer : TelemetryKafkaTimer_;
|
||||||
UpdateCounts();
|
UpdateCounts();
|
||||||
if (!TelemetryReporting_) {
|
if (!TelemetryReporting_) {
|
||||||
TelemetryReporting_ = true;
|
TelemetryReporting_ = true;
|
||||||
@@ -569,48 +622,47 @@ namespace OpenWifi {
|
|||||||
void AP_WS_Connection::OnSocketShutdown(
|
void AP_WS_Connection::OnSocketShutdown(
|
||||||
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
|
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
|
||||||
poco_trace(Logger_, fmt::format("SOCKET-SHUTDOWN({}): Closing.", CId_));
|
poco_trace(Logger_, fmt::format("SOCKET-SHUTDOWN({}): Closing.", CId_));
|
||||||
std::lock_guard G(ConnectionMutex_);
|
|
||||||
return EndConnection();
|
return EndConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Connection::OnSocketError(
|
void AP_WS_Connection::OnSocketError(
|
||||||
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
|
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
|
||||||
poco_trace(Logger_, fmt::format("SOCKET-ERROR({}): Closing.", CId_));
|
poco_trace(Logger_, fmt::format("SOCKET-ERROR({}): Closing.", CId_));
|
||||||
std::lock_guard G(ConnectionMutex_);
|
|
||||||
return EndConnection();
|
return EndConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Connection::OnSocketReadable(
|
void AP_WS_Connection::OnSocketReadable(
|
||||||
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
||||||
|
|
||||||
if (Dead_) // we are dead, so we do not process anything.
|
if (!Valid_)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::lock_guard DeviceLock(ConnectionMutex_);
|
if (!AP_WS_Server()->Running())
|
||||||
|
return EndConnection();
|
||||||
|
|
||||||
|
if (!ValidatedDevice())
|
||||||
|
return;
|
||||||
|
|
||||||
State_.LastContact = LastContact_ = Utils::Now();
|
|
||||||
if (AP_WS_Server()->Running() && (DeviceValidated_ || ValidatedDevice())) {
|
|
||||||
try {
|
try {
|
||||||
return ProcessIncomingFrame();
|
return ProcessIncomingFrame();
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger_.log(E);
|
Logger_.log(E);
|
||||||
|
return EndConnection();
|
||||||
} catch (const std::exception &E) {
|
} catch (const std::exception &E) {
|
||||||
std::string W = E.what();
|
std::string W = E.what();
|
||||||
poco_information(
|
poco_information(
|
||||||
Logger_, fmt::format("std::exception caught: {}. Connection terminated with {}",
|
Logger_,
|
||||||
W, CId_));
|
fmt::format("std::exception caught: {}. Connection terminated with {}", W, CId_));
|
||||||
|
return EndConnection();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_information(
|
poco_information(Logger_,
|
||||||
Logger_, fmt::format("Unknown exception for {}. Connection terminated.", CId_));
|
fmt::format("Unknown exception for {}. Connection terminated.", CId_));
|
||||||
|
return EndConnection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EndConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AP_WS_Connection::ProcessIncomingFrame() {
|
void AP_WS_Connection::ProcessIncomingFrame() {
|
||||||
Poco::Buffer<char> IncomingFrame(0);
|
Poco::Buffer<char> IncomingFrame(0);
|
||||||
|
|
||||||
bool KillConnection=false;
|
|
||||||
try {
|
try {
|
||||||
int Op, flags;
|
int Op, flags;
|
||||||
auto IncomingSize = WS_->receiveFrame(IncomingFrame, flags);
|
auto IncomingSize = WS_->receiveFrame(IncomingFrame, flags);
|
||||||
@@ -646,16 +698,19 @@ namespace OpenWifi {
|
|||||||
PingDetails.set(uCentralProtocol::COMPATIBLE, Compatible_);
|
PingDetails.set(uCentralProtocol::COMPATIBLE, Compatible_);
|
||||||
PingDetails.set(uCentralProtocol::CONNECTIONIP, CId_);
|
PingDetails.set(uCentralProtocol::CONNECTIONIP, CId_);
|
||||||
PingDetails.set(uCentralProtocol::TIMESTAMP, Utils::Now());
|
PingDetails.set(uCentralProtocol::TIMESTAMP, Utils::Now());
|
||||||
PingDetails.set(uCentralProtocol::UUID, uuid_);
|
|
||||||
PingDetails.set("locale", State_.locale);
|
PingDetails.set("locale", State_.locale);
|
||||||
PingObject.set(uCentralProtocol::PING, PingDetails);
|
PingObject.set(uCentralProtocol::PING, PingDetails);
|
||||||
poco_trace(Logger_,fmt::format("Sending PING for {}", SerialNumber_));
|
Poco::JSON::Stringifier Stringify;
|
||||||
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_,PingObject);
|
std::ostringstream OS;
|
||||||
|
Stringify.condense(PingObject, OS);
|
||||||
|
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_, OS.str());
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Poco::Net::WebSocket::FRAME_OP_PONG: {
|
case Poco::Net::WebSocket::FRAME_OP_PONG: {
|
||||||
poco_trace(Logger_, fmt::format("PONG({}): received and ignored.", CId_));
|
poco_trace(Logger_, fmt::format("PONG({}): received and ignored.", CId_));
|
||||||
|
return;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
|
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
|
||||||
@@ -687,26 +742,26 @@ namespace OpenWifi {
|
|||||||
} else {
|
} else {
|
||||||
std::ostringstream iS;
|
std::ostringstream iS;
|
||||||
IncomingJSON->stringify(iS);
|
IncomingJSON->stringify(iS);
|
||||||
|
std::cout << iS.str() << std::endl;
|
||||||
poco_warning(
|
poco_warning(
|
||||||
Logger_,
|
Logger_,
|
||||||
fmt::format("FRAME({}): illegal transaction header, missing 'jsonrpc': {}",
|
fmt::format("FRAME({}): illegal transaction header, missing 'jsonrpc'",
|
||||||
CId_, iS.str()));
|
CId_));
|
||||||
Errors_++;
|
Errors_++;
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
|
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
|
||||||
poco_information(Logger_,
|
poco_information(Logger_,
|
||||||
fmt::format("CLOSE({}): Device is closing its connection.", CId_));
|
fmt::format("CLOSE({}): Device is closing its connection.", CId_));
|
||||||
KillConnection=true;
|
return EndConnection();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
poco_warning(Logger_, fmt::format("UNKNOWN({}): unknown WS Frame operation: {}",
|
poco_warning(Logger_, fmt::format("UNKNOWN({}): unknown WS Frame operation: {}",
|
||||||
CId_, std::to_string(Op)));
|
CId_, std::to_string(Op)));
|
||||||
Errors_++;
|
} break;
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (const Poco::Net::ConnectionResetException &E) {
|
} catch (const Poco::Net::ConnectionResetException &E) {
|
||||||
poco_warning(Logger_,
|
poco_warning(Logger_,
|
||||||
@@ -714,21 +769,21 @@ namespace OpenWifi {
|
|||||||
CId_, E.displayText(),
|
CId_, E.displayText(),
|
||||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
KillConnection=true;
|
return EndConnection();
|
||||||
} catch (const Poco::JSON::JSONException &E) {
|
} catch (const Poco::JSON::JSONException &E) {
|
||||||
poco_warning(Logger_,
|
poco_warning(Logger_,
|
||||||
fmt::format("JSONException({}): Text:{} Payload:{} Session:{}", CId_,
|
fmt::format("JSONException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||||
E.displayText(),
|
E.displayText(),
|
||||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
KillConnection=true;
|
return EndConnection();
|
||||||
} catch (const Poco::Net::WebSocketException &E) {
|
} catch (const Poco::Net::WebSocketException &E) {
|
||||||
poco_warning(Logger_,
|
poco_warning(Logger_,
|
||||||
fmt::format("WebSocketException({}): Text:{} Payload:{} Session:{}", CId_,
|
fmt::format("WebSocketException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||||
E.displayText(),
|
E.displayText(),
|
||||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
KillConnection=true;
|
return EndConnection();
|
||||||
} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) {
|
} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) {
|
||||||
poco_warning(
|
poco_warning(
|
||||||
Logger_,
|
Logger_,
|
||||||
@@ -737,54 +792,54 @@ namespace OpenWifi {
|
|||||||
CId_, E.displayText(),
|
CId_, E.displayText(),
|
||||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
KillConnection=true;
|
return EndConnection();
|
||||||
} catch (const Poco::Net::SSLException &E) {
|
} catch (const Poco::Net::SSLException &E) {
|
||||||
poco_warning(Logger_,
|
poco_warning(Logger_,
|
||||||
fmt::format("SSLException({}): Text:{} Payload:{} Session:{}", CId_,
|
fmt::format("SSLException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||||
E.displayText(),
|
E.displayText(),
|
||||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
KillConnection=true;
|
return EndConnection();
|
||||||
} catch (const Poco::Net::NetException &E) {
|
} catch (const Poco::Net::NetException &E) {
|
||||||
poco_warning(Logger_,
|
poco_warning(Logger_,
|
||||||
fmt::format("NetException({}): Text:{} Payload:{} Session:{}", CId_,
|
fmt::format("NetException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||||
E.displayText(),
|
E.displayText(),
|
||||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
KillConnection=true;
|
return EndConnection();
|
||||||
} catch (const Poco::IOException &E) {
|
} catch (const Poco::IOException &E) {
|
||||||
poco_warning(Logger_,
|
poco_warning(Logger_,
|
||||||
fmt::format("IOException({}): Text:{} Payload:{} Session:{}", CId_,
|
fmt::format("IOException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||||
E.displayText(),
|
E.displayText(),
|
||||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
KillConnection=true;
|
return EndConnection();
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
poco_warning(Logger_,
|
poco_warning(Logger_,
|
||||||
fmt::format("Exception({}): Text:{} Payload:{} Session:{}", CId_,
|
fmt::format("Exception({}): Text:{} Payload:{} Session:{}", CId_,
|
||||||
E.displayText(),
|
E.displayText(),
|
||||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
KillConnection=true;
|
return EndConnection();
|
||||||
} catch (const std::exception &E) {
|
} catch (const std::exception &E) {
|
||||||
poco_warning(Logger_,
|
poco_warning(Logger_,
|
||||||
fmt::format("std::exception({}): Text:{} Payload:{} Session:{}", CId_,
|
fmt::format("std::exception({}): Text:{} Payload:{} Session:{}", CId_,
|
||||||
E.what(),
|
E.what(),
|
||||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||||
State_.sessionId));
|
State_.sessionId));
|
||||||
KillConnection=true;
|
return EndConnection();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_error(Logger_, fmt::format("UnknownException({}): Device must be disconnected. "
|
poco_error(Logger_, fmt::format("UnknownException({}): Device must be disconnected. "
|
||||||
"Unknown exception. Session:{}",
|
"Unknown exception. Session:{}",
|
||||||
CId_, State_.sessionId));
|
CId_, State_.sessionId));
|
||||||
KillConnection=true;
|
return EndConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!KillConnection && Errors_ < 10)
|
if (Errors_ < 10)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
poco_warning(Logger_, fmt::format("DISCONNECTING({}): ConnectionException: {} Errors: {}", CId_, KillConnection, Errors_ ));
|
poco_warning(Logger_, fmt::format("DISCONNECTING({}): Too many errors", CId_));
|
||||||
EndConnection();
|
return EndConnection();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Connection::Send(const std::string &Payload) {
|
bool AP_WS_Connection::Send(const std::string &Payload) {
|
||||||
@@ -896,36 +951,4 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Connection::SetLastStats(const std::string &LastStats) {
|
|
||||||
RawLastStats_ = LastStats;
|
|
||||||
try {
|
|
||||||
Poco::JSON::Parser P;
|
|
||||||
auto Stats = P.parse(LastStats).extract<Poco::JSON::Object::Ptr>();
|
|
||||||
hasGPS_ = Stats->isObject("gps");
|
|
||||||
auto Unit = Stats->getObject("unit");
|
|
||||||
auto Memory = Unit->getObject("memory");
|
|
||||||
std::uint64_t TotalMemory = Memory->get("total");
|
|
||||||
std::uint64_t FreeMemory = Memory->get("free");
|
|
||||||
if (TotalMemory > 0) {
|
|
||||||
memory_used_ =
|
|
||||||
(100.0 * ((double)TotalMemory - (double)FreeMemory)) / (double)TotalMemory;
|
|
||||||
}
|
|
||||||
if (Unit->isArray("load")) {
|
|
||||||
Poco::JSON::Array::Ptr Load = Unit->getArray("load");
|
|
||||||
if (Load->size() > 1) {
|
|
||||||
cpu_load_ = Load->get(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Unit->isArray("temperature")) {
|
|
||||||
Poco::JSON::Array::Ptr Temperature = Unit->getArray("temperature");
|
|
||||||
if (Temperature->size() > 1) {
|
|
||||||
temperature_ = Temperature->get(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
poco_error(Logger_, "Failed to parse last stats: " + E.displayText());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
@@ -4,20 +4,17 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <mutex>
|
#include <shared_mutex>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "Poco/JSON/Object.h"
|
#include "Poco/JSON/Object.h"
|
||||||
#include <Poco/JSON/Parser.h>
|
|
||||||
#include "Poco/Logger.h"
|
#include "Poco/Logger.h"
|
||||||
#include "Poco/Net/SocketNotification.h"
|
#include "Poco/Net/SocketNotification.h"
|
||||||
#include "Poco/Net/SocketReactor.h"
|
#include "Poco/Net/SocketReactor.h"
|
||||||
#include "Poco/Net/StreamSocket.h"
|
#include "Poco/Net/StreamSocket.h"
|
||||||
#include "Poco/Net/WebSocket.h"
|
#include "Poco/Net/WebSocket.h"
|
||||||
#include <Poco/Data/Session.h>
|
|
||||||
|
|
||||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||||
#include <AP_WS_Reactor_Pool.h>
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
@@ -27,17 +24,16 @@ namespace OpenWifi {
|
|||||||
public:
|
public:
|
||||||
explicit AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
|
explicit AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
|
||||||
Poco::Net::HTTPServerResponse &response, uint64_t connection_id,
|
Poco::Net::HTTPServerResponse &response, uint64_t connection_id,
|
||||||
Poco::Logger &L, std::pair<std::shared_ptr<Poco::Net::SocketReactor>, std::shared_ptr<LockedDbSession>> R);
|
Poco::Logger &L, Poco::Net::SocketReactor &R);
|
||||||
~AP_WS_Connection();
|
~AP_WS_Connection();
|
||||||
|
|
||||||
void EndConnection(bool Clean = true);
|
void EndConnection();
|
||||||
void ProcessJSONRPCEvent(Poco::JSON::Object::Ptr &Doc);
|
void ProcessJSONRPCEvent(Poco::JSON::Object::Ptr &Doc);
|
||||||
void ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc);
|
void ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc);
|
||||||
void ProcessIncomingFrame();
|
void ProcessIncomingFrame();
|
||||||
void ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc);
|
void ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc);
|
||||||
|
|
||||||
[[nodiscard]] bool Send(const std::string &Payload);
|
[[nodiscard]] bool Send(const std::string &Payload);
|
||||||
[[nodiscard]] inline bool MustBeSecureRTTY() const { return RTTYMustBeSecure_; }
|
|
||||||
|
|
||||||
bool SendRadiusAuthenticationData(const unsigned char *buffer, std::size_t size);
|
bool SendRadiusAuthenticationData(const unsigned char *buffer, std::size_t size);
|
||||||
bool SendRadiusAccountingData(const unsigned char *buffer, std::size_t size);
|
bool SendRadiusAccountingData(const unsigned char *buffer, std::size_t size);
|
||||||
@@ -46,7 +42,10 @@ namespace OpenWifi {
|
|||||||
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
|
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
|
||||||
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf);
|
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf);
|
||||||
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf);
|
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf);
|
||||||
bool LookForUpgrade(Poco::Data::Session &Session, uint64_t UUID, uint64_t &UpgradedUUID);
|
bool LookForUpgrade(uint64_t UUID, uint64_t &UpgradedUUID);
|
||||||
|
static bool ExtractBase64CompressedData(const std::string &CompressedData,
|
||||||
|
std::string &UnCompressedData,
|
||||||
|
uint64_t compress_sz);
|
||||||
void LogException(const Poco::Exception &E);
|
void LogException(const Poco::Exception &E);
|
||||||
inline Poco::Logger &Logger() { return Logger_; }
|
inline Poco::Logger &Logger() { return Logger_; }
|
||||||
bool SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t interval,
|
bool SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t interval,
|
||||||
@@ -58,35 +57,53 @@ namespace OpenWifi {
|
|||||||
bool StopWebSocketTelemetry(uint64_t RPCID);
|
bool StopWebSocketTelemetry(uint64_t RPCID);
|
||||||
bool StopKafkaTelemetry(uint64_t RPCID);
|
bool StopKafkaTelemetry(uint64_t RPCID);
|
||||||
|
|
||||||
inline void GetLastStats(std::string &LastStats) {
|
inline void GetLastStats(std::string &LastStats) const {
|
||||||
if(!Dead_) {
|
std::shared_lock G(ConnectionMutex_);
|
||||||
std::lock_guard G(ConnectionMutex_);
|
|
||||||
LastStats = RawLastStats_;
|
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) {
|
inline void GetLastHealthCheck(GWObjects::HealthCheck &H) {
|
||||||
if(!Dead_) {
|
std::shared_lock G(ConnectionMutex_);
|
||||||
std::lock_guard G(ConnectionMutex_);
|
|
||||||
H = RawLastHealthcheck_;
|
H = RawLastHealthcheck_;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
inline void GetState(GWObjects::ConnectionState &State) {
|
inline void GetState(GWObjects::ConnectionState &State) const {
|
||||||
if(!Dead_) {
|
std::shared_lock G(ConnectionMutex_);
|
||||||
std::lock_guard G(ConnectionMutex_);
|
|
||||||
State = State_;
|
State = State_;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] inline bool HasGPS() const { return hasGPS_; }
|
inline void GetRestrictions(GWObjects::DeviceRestrictions &R) const {
|
||||||
[[nodiscard]] bool ValidatedDevice();
|
std::shared_lock G(ConnectionMutex_);
|
||||||
|
|
||||||
inline void GetRestrictions(GWObjects::DeviceRestrictions &R) {
|
|
||||||
std::lock_guard G(ConnectionMutex_);
|
|
||||||
R = Restrictions_;
|
R = Restrictions_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Process_connect(Poco::JSON::Object::Ptr ParamsObj, const std::string &Serial);
|
||||||
|
void Process_state(Poco::JSON::Object::Ptr ParamsObj);
|
||||||
|
void Process_healthcheck(Poco::JSON::Object::Ptr ParamsObj);
|
||||||
|
void Process_log(Poco::JSON::Object::Ptr ParamsObj);
|
||||||
|
void Process_crashlog(Poco::JSON::Object::Ptr ParamsObj);
|
||||||
|
void Process_ping(Poco::JSON::Object::Ptr ParamsObj);
|
||||||
|
void Process_cfgpending(Poco::JSON::Object::Ptr ParamsObj);
|
||||||
|
void Process_recovery(Poco::JSON::Object::Ptr ParamsObj);
|
||||||
|
void Process_deviceupdate(Poco::JSON::Object::Ptr ParamsObj, std::string &Serial);
|
||||||
|
void Process_telemetry(Poco::JSON::Object::Ptr ParamsObj);
|
||||||
|
void Process_venuebroadcast(Poco::JSON::Object::Ptr ParamsObj);
|
||||||
|
void Process_event(Poco::JSON::Object::Ptr ParamsObj);
|
||||||
|
void Process_wifiscan(Poco::JSON::Object::Ptr ParamsObj);
|
||||||
|
void Process_alarm(Poco::JSON::Object::Ptr ParamsObj);
|
||||||
|
|
||||||
|
bool ValidatedDevice();
|
||||||
|
|
||||||
inline bool GetTelemetryParameters(bool &Reporting, uint64_t &Interval,
|
inline bool GetTelemetryParameters(bool &Reporting, uint64_t &Interval,
|
||||||
uint64_t &WebSocketTimer, uint64_t &KafkaTimer,
|
uint64_t &WebSocketTimer, uint64_t &KafkaTimer,
|
||||||
uint64_t &WebSocketCount, uint64_t &KafkaCount,
|
uint64_t &WebSocketCount, uint64_t &KafkaCount,
|
||||||
@@ -105,18 +122,18 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
friend class AP_WS_Server;
|
friend class AP_WS_Server;
|
||||||
|
|
||||||
inline GWObjects::DeviceRestrictions Restrictions() {
|
inline GWObjects::DeviceRestrictions Restrictions() const {
|
||||||
std::lock_guard G(ConnectionMutex_);
|
std::shared_lock G(ConnectionMutex_);
|
||||||
return Restrictions_;
|
return Restrictions_;
|
||||||
}
|
}
|
||||||
void Start();
|
|
||||||
|
inline bool MustBeSecureRtty() const { return RttyMustBeSecure_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::recursive_mutex ConnectionMutex_;
|
mutable std::shared_mutex ConnectionMutex_;
|
||||||
std::mutex TelemetryMutex_;
|
std::shared_mutex TelemetryMutex_;
|
||||||
Poco::Logger &Logger_;
|
Poco::Logger &Logger_;
|
||||||
std::shared_ptr<Poco::Net::SocketReactor> Reactor_;
|
Poco::Net::SocketReactor &Reactor_;
|
||||||
std::shared_ptr<LockedDbSession> DbSession_;
|
|
||||||
std::unique_ptr<Poco::Net::WebSocket> WS_;
|
std::unique_ptr<Poco::Net::WebSocket> WS_;
|
||||||
std::string SerialNumber_;
|
std::string SerialNumber_;
|
||||||
uint64_t SerialNumberInt_ = 0;
|
uint64_t SerialNumberInt_ = 0;
|
||||||
@@ -127,56 +144,30 @@ namespace OpenWifi {
|
|||||||
uint64_t Errors_ = 0;
|
uint64_t Errors_ = 0;
|
||||||
Poco::Net::IPAddress PeerAddress_;
|
Poco::Net::IPAddress PeerAddress_;
|
||||||
volatile bool TelemetryReporting_ = false;
|
volatile bool TelemetryReporting_ = false;
|
||||||
std::atomic_uint64_t TelemetryWebSocketRefCount_ = 0;
|
volatile uint64_t TelemetryWebSocketRefCount_ = 0;
|
||||||
std::atomic_uint64_t TelemetryKafkaRefCount_ = 0;
|
volatile uint64_t TelemetryKafkaRefCount_ = 0;
|
||||||
std::atomic_uint64_t TelemetryWebSocketTimer_ = 0;
|
volatile uint64_t TelemetryWebSocketTimer_ = 0;
|
||||||
std::atomic_uint64_t TelemetryKafkaTimer_ = 0;
|
volatile uint64_t TelemetryKafkaTimer_ = 0;
|
||||||
std::atomic_uint64_t TelemetryInterval_ = 0;
|
volatile uint64_t TelemetryInterval_ = 0;
|
||||||
std::atomic_uint64_t TelemetryWebSocketPackets_ = 0;
|
volatile uint64_t TelemetryWebSocketPackets_ = 0;
|
||||||
std::atomic_uint64_t TelemetryKafkaPackets_ = 0;
|
volatile uint64_t TelemetryKafkaPackets_ = 0;
|
||||||
GWObjects::ConnectionState State_;
|
GWObjects::ConnectionState State_;
|
||||||
Utils::CompressedString RawLastStats_;
|
std::string RawLastStats_;
|
||||||
GWObjects::HealthCheck RawLastHealthcheck_;
|
GWObjects::HealthCheck RawLastHealthcheck_;
|
||||||
std::chrono::time_point<std::chrono::high_resolution_clock> ConnectionStart_ =
|
std::chrono::time_point<std::chrono::high_resolution_clock> ConnectionStart_ =
|
||||||
std::chrono::high_resolution_clock::now();
|
std::chrono::high_resolution_clock::now();
|
||||||
std::chrono::duration<double, std::milli> ConnectionCompletionTime_{0.0};
|
std::chrono::duration<double, std::milli> ConnectionCompletionTime_{0.0};
|
||||||
std::atomic<bool> Dead_ = false;
|
std::atomic_flag Dead_ = false;
|
||||||
std::atomic_bool DeviceValidated_ = false;
|
std::atomic_bool DeviceValidated_ = false;
|
||||||
|
std::atomic_bool Valid_ = false;
|
||||||
OpenWifi::GWObjects::DeviceRestrictions Restrictions_;
|
OpenWifi::GWObjects::DeviceRestrictions Restrictions_;
|
||||||
bool RTTYMustBeSecure_ = false;
|
bool RttyMustBeSecure_ = false;
|
||||||
bool hasGPS_=false;
|
|
||||||
std::double_t memory_used_=0.0, cpu_load_ = 0.0, temperature_ = 0.0;
|
|
||||||
std::uint64_t uuid_=0;
|
|
||||||
bool Simulated_=false;
|
|
||||||
std::uint64_t LastContact_=0;
|
|
||||||
|
|
||||||
static inline std::atomic_uint64_t ConcurrentStartingDevices_ = 0;
|
static inline std::atomic_uint64_t ConcurrentStartingDevices_ = 0;
|
||||||
|
|
||||||
bool StartTelemetry(uint64_t RPCID, const std::vector<std::string> &TelemetryTypes);
|
bool StartTelemetry(uint64_t RPCID, const std::vector<std::string> &TelemetryTypes);
|
||||||
bool StopTelemetry(uint64_t RPCID);
|
bool StopTelemetry(uint64_t RPCID);
|
||||||
void UpdateCounts();
|
void UpdateCounts();
|
||||||
static void DeviceDisconnectionCleanup(const std::string &SerialNumber, std::uint64_t uuid);
|
|
||||||
void SetLastStats(const std::string &LastStats);
|
|
||||||
void Process_connect(Poco::JSON::Object::Ptr ParamsObj, const std::string &Serial);
|
|
||||||
void Process_state(Poco::JSON::Object::Ptr ParamsObj);
|
|
||||||
void Process_healthcheck(Poco::JSON::Object::Ptr ParamsObj);
|
|
||||||
void Process_log(Poco::JSON::Object::Ptr ParamsObj);
|
|
||||||
void Process_crashlog(Poco::JSON::Object::Ptr ParamsObj);
|
|
||||||
void Process_ping(Poco::JSON::Object::Ptr ParamsObj);
|
|
||||||
void Process_cfgpending(Poco::JSON::Object::Ptr ParamsObj);
|
|
||||||
void Process_recovery(Poco::JSON::Object::Ptr ParamsObj);
|
|
||||||
void Process_deviceupdate(Poco::JSON::Object::Ptr ParamsObj, std::string &Serial);
|
|
||||||
void Process_telemetry(Poco::JSON::Object::Ptr ParamsObj);
|
|
||||||
void Process_venuebroadcast(Poco::JSON::Object::Ptr ParamsObj);
|
|
||||||
void Process_event(Poco::JSON::Object::Ptr ParamsObj);
|
|
||||||
void Process_wifiscan(Poco::JSON::Object::Ptr ParamsObj);
|
|
||||||
void Process_alarm(Poco::JSON::Object::Ptr ParamsObj);
|
|
||||||
void Process_rebootLog(Poco::JSON::Object::Ptr ParamsObj);
|
|
||||||
|
|
||||||
inline void SetLastHealthCheck(const GWObjects::HealthCheck &H) {
|
|
||||||
RawLastHealthcheck_ = H;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
|
|
||||||
#include <AP_WS_Connection.h>
|
|
||||||
#include "ConfigurationCache.h"
|
|
||||||
#include "UI_GW_WebSocketNotifications.h"
|
|
||||||
#include "CommandManager.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
bool AP_WS_Connection::LookForUpgrade(Poco::Data::Session &Session, const uint64_t UUID, uint64_t &UpgradedUUID) {
|
|
||||||
|
|
||||||
// A UUID of zero means ignore updates for that connection.
|
|
||||||
if (UUID == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
uint64_t GoodConfig = ConfigurationCache().CurrentConfig(SerialNumberInt_);
|
|
||||||
if (GoodConfig && (GoodConfig == UUID || GoodConfig == State_.PendingUUID)) {
|
|
||||||
UpgradedUUID = UUID;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
GWObjects::Device D;
|
|
||||||
if (StorageService()->GetDevice(Session,SerialNumber_, D)) {
|
|
||||||
if(D.pendingUUID!=0 && UUID==D.pendingUUID) {
|
|
||||||
// so we sent an upgrade to a device, and now it is completing now...
|
|
||||||
UpgradedUUID = D.pendingUUID;
|
|
||||||
StorageService()->CompleteDeviceConfigurationChange(Session, SerialNumber_);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is the case where the cache is empty after a restart. So GoodConfig will 0. If
|
|
||||||
// the device already has the right UUID, we just return.
|
|
||||||
if (D.UUID == UUID) {
|
|
||||||
UpgradedUUID = UUID;
|
|
||||||
ConfigurationCache().Add(SerialNumberInt_, UUID);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Config::Config Cfg(D.Configuration);
|
|
||||||
if (UUID > D.UUID) {
|
|
||||||
// so we have a problem, the device has a newer config than we have. So we need to
|
|
||||||
// make sure our config is newer.
|
|
||||||
D.UUID = UUID + 2;
|
|
||||||
UpgradedUUID = D.UUID;
|
|
||||||
}
|
|
||||||
|
|
||||||
Cfg.SetUUID(D.UUID);
|
|
||||||
D.Configuration = Cfg.get();
|
|
||||||
State_.PendingUUID = UpgradedUUID = D.UUID;
|
|
||||||
|
|
||||||
GWObjects::CommandDetails Cmd;
|
|
||||||
Cmd.SerialNumber = SerialNumber_;
|
|
||||||
Cmd.UUID = MicroServiceCreateUUID();
|
|
||||||
Cmd.SubmittedBy = uCentralProtocol::SUBMITTED_BY_SYSTEM;
|
|
||||||
Cmd.Status = uCentralProtocol::PENDING;
|
|
||||||
Cmd.Command = uCentralProtocol::CONFIGURE;
|
|
||||||
Poco::JSON::Parser P;
|
|
||||||
auto ParsedConfig = P.parse(D.Configuration).extract<Poco::JSON::Object::Ptr>();
|
|
||||||
Poco::JSON::Object Params;
|
|
||||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
|
||||||
Params.set(uCentralProtocol::UUID, D.UUID);
|
|
||||||
Params.set(uCentralProtocol::WHEN, 0);
|
|
||||||
Params.set(uCentralProtocol::CONFIG, ParsedConfig);
|
|
||||||
|
|
||||||
std::ostringstream O;
|
|
||||||
Poco::JSON::Stringifier::stringify(Params, O);
|
|
||||||
Cmd.Details = O.str();
|
|
||||||
poco_information(Logger_,
|
|
||||||
fmt::format("CFG-UPGRADE({}): Current ID: {}, newer configuration {}.",
|
|
||||||
CId_, UUID, D.UUID));
|
|
||||||
bool Sent;
|
|
||||||
|
|
||||||
StorageService()->AddCommand(SerialNumber_, Cmd,
|
|
||||||
Storage::CommandExecutionType::COMMAND_EXECUTED);
|
|
||||||
CommandManager()->PostCommand(
|
|
||||||
CommandManager()->Next_RPC_ID(), APCommands::to_apcommand(Cmd.Command.c_str()),
|
|
||||||
SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent, false, false);
|
|
||||||
|
|
||||||
GWWebSocketNotifications::SingleDeviceConfigurationChange_t Notification;
|
|
||||||
Notification.content.serialNumber = D.SerialNumber;
|
|
||||||
Notification.content.oldUUID = UUID;
|
|
||||||
Notification.content.newUUID = UpgradedUUID;
|
|
||||||
GWWebSocketNotifications::DeviceConfigurationChange(Notification);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -21,7 +21,11 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
if (ParamsObj->has(uCentralProtocol::SERIAL) && ParamsObj->has(uCentralProtocol::DATA)) {
|
if (ParamsObj->has(uCentralProtocol::SERIAL) && ParamsObj->has(uCentralProtocol::DATA)) {
|
||||||
if (KafkaManager()->Enabled()) {
|
if (KafkaManager()->Enabled()) {
|
||||||
KafkaManager()->PostMessage(KafkaTopics::ALERTS, SerialNumber_, *ParamsObj);
|
auto Data = ParamsObj->get(uCentralProtocol::DATA);
|
||||||
|
Poco::JSON::Stringifier Stringify;
|
||||||
|
std::ostringstream OS;
|
||||||
|
Stringify.condense(ParamsObj, OS);
|
||||||
|
KafkaManager()->PostMessage(KafkaTopics::ALERTS, SerialNumber_, OS.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,6 @@
|
|||||||
#include "framework/KafkaManager.h"
|
#include "framework/KafkaManager.h"
|
||||||
#include "framework/utils.h"
|
#include "framework/utils.h"
|
||||||
|
|
||||||
#include "firmware_revision_cache.h"
|
|
||||||
|
|
||||||
#include "UI_GW_WebSocketNotifications.h"
|
#include "UI_GW_WebSocketNotifications.h"
|
||||||
#include <GWKafkaEvents.h>
|
#include <GWKafkaEvents.h>
|
||||||
|
|
||||||
@@ -32,7 +30,9 @@ namespace OpenWifi {
|
|||||||
Event.set("type", "device.firmware_change");
|
Event.set("type", "device.firmware_change");
|
||||||
Event.set("timestamp", Utils::Now());
|
Event.set("timestamp", Utils::Now());
|
||||||
Event.set("payload", EventDetails);
|
Event.set("payload", EventDetails);
|
||||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, SerialNumber, Event);
|
std::ostringstream OS;
|
||||||
|
Event.stringify(OS);
|
||||||
|
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, SerialNumber, OS.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +49,9 @@ namespace OpenWifi {
|
|||||||
Event.set("type", "device.not_provisioned");
|
Event.set("type", "device.not_provisioned");
|
||||||
Event.set("timestamp", Utils::Now());
|
Event.set("timestamp", Utils::Now());
|
||||||
Event.set("payload", EventDetails);
|
Event.set("payload", EventDetails);
|
||||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, SerialNumber, Event);
|
std::ostringstream OS;
|
||||||
|
Event.stringify(OS);
|
||||||
|
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, SerialNumber, OS.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,18 +63,14 @@ namespace OpenWifi {
|
|||||||
auto Firmware = ParamsObj->get(uCentralProtocol::FIRMWARE).toString();
|
auto Firmware = ParamsObj->get(uCentralProtocol::FIRMWARE).toString();
|
||||||
auto Capabilities = ParamsObj->getObject(uCentralProtocol::CAPABILITIES);
|
auto Capabilities = ParamsObj->getObject(uCentralProtocol::CAPABILITIES);
|
||||||
|
|
||||||
std::string DevicePassword;
|
|
||||||
if(ParamsObj->has("password")) {
|
|
||||||
DevicePassword = ParamsObj->get("password").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
SerialNumber_ = Serial;
|
SerialNumber_ = Serial;
|
||||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
||||||
|
|
||||||
CommandManager()->ClearQueue(SerialNumberInt_);
|
CommandManager()->ClearQueue(SerialNumberInt_);
|
||||||
|
|
||||||
AP_WS_Server()->StartSession(State_.sessionId, SerialNumberInt_);
|
AP_WS_Server()->SetSessionDetails(State_.sessionId, SerialNumberInt_);
|
||||||
|
|
||||||
|
std::lock_guard Lock(ConnectionMutex_);
|
||||||
Config::Capabilities Caps(Capabilities);
|
Config::Capabilities Caps(Capabilities);
|
||||||
|
|
||||||
Compatible_ = Caps.Compatible();
|
Compatible_ = Caps.Compatible();
|
||||||
@@ -83,10 +81,6 @@ namespace OpenWifi {
|
|||||||
State_.Address = Utils::FormatIPv6(WS_->peerAddress().toString());
|
State_.Address = Utils::FormatIPv6(WS_->peerAddress().toString());
|
||||||
CId_ = SerialNumber_ + "@" + CId_;
|
CId_ = SerialNumber_ + "@" + CId_;
|
||||||
|
|
||||||
if(ParamsObj->has("reason")) {
|
|
||||||
State_.connectReason = ParamsObj->get("reason").toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto IP = PeerAddress_.toString();
|
auto IP = PeerAddress_.toString();
|
||||||
if (IP.substr(0, 7) == "::ffff:") {
|
if (IP.substr(0, 7) == "::ffff:") {
|
||||||
IP = IP.substr(7);
|
IP = IP.substr(7);
|
||||||
@@ -99,65 +93,29 @@ namespace OpenWifi {
|
|||||||
Restrictions_.from_json(RestrictionObject);
|
Restrictions_.from_json(RestrictionObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Capabilities->has("developer") && !Capabilities->isNull("developer")) {
|
if (Capabilities->has("developer")) {
|
||||||
Restrictions_.developer = Capabilities->getValue<bool>("developer");
|
Restrictions_.developer = Capabilities->getValue<bool>("developer");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Capabilities->has("secure-rtty")) {
|
if(Capabilities->has("secure-rtty")) {
|
||||||
RTTYMustBeSecure_ = Capabilities->getValue<bool>("secure-rtty");
|
RttyMustBeSecure_ = Capabilities->getValue<bool>("secure-rtty");
|
||||||
}
|
}
|
||||||
|
|
||||||
State_.locale = FindCountryFromIP()->Get(IP);
|
State_.locale = FindCountryFromIP()->Get(IP);
|
||||||
GWObjects::Device DeviceInfo;
|
GWObjects::Device DeviceInfo;
|
||||||
std::lock_guard DbSessionLock(DbSession_->Mutex());
|
auto DeviceExists = StorageService()->GetDevice(SerialNumber_, DeviceInfo);
|
||||||
|
|
||||||
auto DeviceExists = StorageService()->GetDevice(DbSession_->Session(), SerialNumber_, DeviceInfo);
|
|
||||||
if (Daemon()->AutoProvisioning() && !DeviceExists) {
|
if (Daemon()->AutoProvisioning() && !DeviceExists) {
|
||||||
// check the firmware version. if this is too old, we cannot let that device connect yet, we must
|
StorageService()->CreateDefaultDevice(SerialNumber_, Caps, Firmware, PeerAddress_);
|
||||||
// force a firmware upgrade
|
|
||||||
GWObjects::DefaultFirmware MinimumFirmware;
|
|
||||||
if(FirmwareRevisionCache()->DeviceMustUpgrade(Compatible_, Firmware, MinimumFirmware)) {
|
|
||||||
Poco::JSON::Object UpgradeCommand, Params;
|
|
||||||
UpgradeCommand.set(uCentralProtocol::JSONRPC,uCentralProtocol::JSONRPC_VERSION);
|
|
||||||
UpgradeCommand.set(uCentralProtocol::METHOD,uCentralProtocol::UPGRADE);
|
|
||||||
Params.set(uCentralProtocol::SERIALNUMBER, SerialNumber_);
|
|
||||||
Params.set(uCentralProtocol::WHEN, 0);
|
|
||||||
Params.set(uCentralProtocol::URI, MinimumFirmware.uri);
|
|
||||||
Params.set(uCentralProtocol::KEEP_REDIRECTOR,1);
|
|
||||||
UpgradeCommand.set(uCentralProtocol::PARAMS, Params);
|
|
||||||
UpgradeCommand.set(uCentralProtocol::ID, 1);
|
|
||||||
|
|
||||||
std::ostringstream Command;
|
|
||||||
UpgradeCommand.stringify(Command);
|
|
||||||
if(Send(Command.str())) {
|
|
||||||
poco_information(
|
|
||||||
Logger(),
|
|
||||||
fmt::format(
|
|
||||||
"Forcing device {} to upgrade to {} before connection is allowed.",
|
|
||||||
SerialNumber_, MinimumFirmware.revision));
|
|
||||||
} else {
|
|
||||||
poco_error(
|
|
||||||
Logger(),
|
|
||||||
fmt::format(
|
|
||||||
"Could not force device {} to upgrade to {} before connection is allowed.",
|
|
||||||
SerialNumber_, MinimumFirmware.revision));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
StorageService()->CreateDefaultDevice( DbSession_->Session(),
|
|
||||||
SerialNumber_, Caps, Firmware, PeerAddress_,
|
|
||||||
State_.VerifiedCertificate == GWObjects::SIMULATED);
|
|
||||||
}
|
|
||||||
} else if (!Daemon()->AutoProvisioning() && !DeviceExists) {
|
} else if (!Daemon()->AutoProvisioning() && !DeviceExists) {
|
||||||
SendKafkaDeviceNotProvisioned(SerialNumber_, Firmware, Compatible_, CId_);
|
SendKafkaDeviceNotProvisioned(SerialNumber_, Firmware, Compatible_, CId_);
|
||||||
poco_warning(Logger(),fmt::format("Device {} is a {} from {} and cannot be provisioned.",SerialNumber_,Compatible_, CId_));
|
poco_warning(Logger(),fmt::format("Device {} is a {} from {} and cannot be provisioned.",SerialNumber_,Compatible_, CId_));
|
||||||
return EndConnection();
|
return EndConnection();
|
||||||
} else if (DeviceExists) {
|
} else if (DeviceExists) {
|
||||||
StorageService()->UpdateDeviceCapabilities(DbSession_->Session(), SerialNumber_, Caps);
|
StorageService()->UpdateDeviceCapabilities(SerialNumber_, Caps);
|
||||||
int Updated{0};
|
int Updated{0};
|
||||||
if (!Firmware.empty()) {
|
if (!Firmware.empty()) {
|
||||||
if (Firmware != DeviceInfo.Firmware) {
|
if (Firmware != DeviceInfo.Firmware) {
|
||||||
DeviceFirmwareChangeKafkaEvent KEvent(SerialNumberInt_, Utils::Now(),
|
DeviceFirmwareChangeKafkaEvent KEvent(SerialNumber_, Utils::Now(),
|
||||||
DeviceInfo.Firmware, Firmware);
|
DeviceInfo.Firmware, Firmware);
|
||||||
DeviceInfo.Firmware = Firmware;
|
DeviceInfo.Firmware = Firmware;
|
||||||
DeviceInfo.LastFWUpdate = Utils::Now();
|
DeviceInfo.LastFWUpdate = Utils::Now();
|
||||||
@@ -173,32 +131,6 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ParamsObj->has("reason")) {
|
|
||||||
State_.connectReason = ParamsObj->get("reason").toString();
|
|
||||||
DeviceInfo.connectReason = State_.connectReason;
|
|
||||||
++Updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(DeviceInfo.DevicePassword!=DevicePassword) {
|
|
||||||
DeviceInfo.DevicePassword = DevicePassword.empty() ? "openwifi" : DevicePassword ;
|
|
||||||
++Updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DeviceInfo.lastRecordedContact==0) {
|
|
||||||
DeviceInfo.lastRecordedContact = Utils::Now();
|
|
||||||
++Updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DeviceInfo.simulated && (State_.VerifiedCertificate!=GWObjects::SIMULATED)) {
|
|
||||||
DeviceInfo.simulated = false;
|
|
||||||
++Updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!DeviceInfo.simulated && (State_.VerifiedCertificate==GWObjects::SIMULATED)) {
|
|
||||||
DeviceInfo.simulated = true;
|
|
||||||
++Updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DeviceInfo.locale != State_.locale) {
|
if (DeviceInfo.locale != State_.locale) {
|
||||||
DeviceInfo.locale = State_.locale;
|
DeviceInfo.locale = State_.locale;
|
||||||
++Updated;
|
++Updated;
|
||||||
@@ -219,21 +151,14 @@ namespace OpenWifi {
|
|||||||
++Updated;
|
++Updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(DeviceInfo.certificateExpiryDate!=State_.certificateExpiryDate) {
|
|
||||||
DeviceInfo.certificateExpiryDate = State_.certificateExpiryDate;
|
|
||||||
++Updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Updated) {
|
if (Updated) {
|
||||||
StorageService()->UpdateDevice(DbSession_->Session(), DeviceInfo);
|
StorageService()->UpdateDevice(DeviceInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!Simulated_) {
|
|
||||||
uint64_t UpgradedUUID = 0;
|
uint64_t UpgradedUUID = 0;
|
||||||
LookForUpgrade(DbSession_->Session(), UUID, UpgradedUUID);
|
LookForUpgrade(UUID, UpgradedUUID);
|
||||||
State_.UUID = UpgradedUUID;
|
State_.UUID = UpgradedUUID;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
State_.Compatible = Compatible_;
|
State_.Compatible = Compatible_;
|
||||||
State_.Connected = true;
|
State_.Connected = true;
|
||||||
@@ -268,12 +193,6 @@ namespace OpenWifi {
|
|||||||
return EndConnection();
|
return EndConnection();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
poco_information(Logger_,
|
|
||||||
fmt::format("CONNECT({}): Simulator device. "
|
|
||||||
"Session={} ConnectionCompletion Time={}",
|
|
||||||
CId_, State_.sessionId,
|
|
||||||
State_.connectionCompletionTime));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GWWebSocketNotifications::SingleDevice_t Notification;
|
GWWebSocketNotifications::SingleDevice_t Notification;
|
||||||
@@ -281,11 +200,14 @@ namespace OpenWifi {
|
|||||||
GWWebSocketNotifications::DeviceConnected(Notification);
|
GWWebSocketNotifications::DeviceConnected(Notification);
|
||||||
|
|
||||||
if (KafkaManager()->Enabled()) {
|
if (KafkaManager()->Enabled()) {
|
||||||
|
Poco::JSON::Stringifier Stringify;
|
||||||
|
|
||||||
ParamsObj->set(uCentralProtocol::CONNECTIONIP, CId_);
|
ParamsObj->set(uCentralProtocol::CONNECTIONIP, CId_);
|
||||||
ParamsObj->set("locale", State_.locale);
|
ParamsObj->set("locale", State_.locale);
|
||||||
ParamsObj->set(uCentralProtocol::TIMESTAMP, Utils::Now());
|
ParamsObj->set(uCentralProtocol::TIMESTAMP, Utils::Now());
|
||||||
ParamsObj->set(uCentralProtocol::UUID, uuid_);
|
std::ostringstream OS;
|
||||||
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_, *ParamsObj);
|
Stringify.condense(ParamsObj, OS);
|
||||||
|
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_, OS.str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
poco_warning(
|
poco_warning(
|
||||||
|
|||||||
@@ -7,12 +7,10 @@
|
|||||||
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "framework/ow_constants.h"
|
#include "framework/ow_constants.h"
|
||||||
#include <GWKafkaEvents.h>
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
void AP_WS_Connection::Process_crashlog(Poco::JSON::Object::Ptr ParamsObj) {
|
void AP_WS_Connection::Process_crashlog(Poco::JSON::Object::Ptr ParamsObj) {
|
||||||
if (ParamsObj->has(uCentralProtocol::UUID)
|
if (ParamsObj->has(uCentralProtocol::UUID) && ParamsObj->has(uCentralProtocol::LOGLINES)) {
|
||||||
&& ParamsObj->has(uCentralProtocol::LOGLINES)) {
|
|
||||||
poco_trace(Logger_, fmt::format("CRASH-LOG({}): new entry.", CId_));
|
poco_trace(Logger_, fmt::format("CRASH-LOG({}): new entry.", CId_));
|
||||||
auto LogLines = ParamsObj->get(uCentralProtocol::LOGLINES);
|
auto LogLines = ParamsObj->get(uCentralProtocol::LOGLINES);
|
||||||
std::string LogText;
|
std::string LogText;
|
||||||
@@ -26,11 +24,11 @@ namespace OpenWifi {
|
|||||||
.Log = LogText,
|
.Log = LogText,
|
||||||
.Data = "",
|
.Data = "",
|
||||||
.Severity = GWObjects::DeviceLog::LOG_EMERG,
|
.Severity = GWObjects::DeviceLog::LOG_EMERG,
|
||||||
.Recorded = Utils::Now(),
|
.Recorded = (uint64_t)time(nullptr),
|
||||||
.LogType = 1,
|
.LogType = 1,
|
||||||
.UUID = ParamsObj->get(uCentralProtocol::UUID)};
|
.UUID = 0};
|
||||||
StorageService()->AddLog(*DbSession_, DeviceLog);
|
StorageService()->AddLog(DeviceLog);
|
||||||
DeviceLogKafkaEvent E(DeviceLog);
|
|
||||||
} else {
|
} else {
|
||||||
poco_warning(Logger_, fmt::format("LOG({}): Missing parameters.", CId_));
|
poco_warning(Logger_, fmt::format("LOG({}): Missing parameters.", CId_));
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -21,10 +21,10 @@ namespace OpenWifi {
|
|||||||
if (ParamsObj->has("currentPassword")) {
|
if (ParamsObj->has("currentPassword")) {
|
||||||
auto Password = ParamsObj->get("currentPassword").toString();
|
auto Password = ParamsObj->get("currentPassword").toString();
|
||||||
|
|
||||||
StorageService()->SetDevicePassword(*DbSession_,Serial, Password);
|
StorageService()->SetDevicePassword(Serial, Password);
|
||||||
poco_trace(
|
poco_trace(
|
||||||
Logger_,
|
Logger_,
|
||||||
fmt::format("DEVICE-UPDATE({}): Device is updating its login password.", Serial));
|
fmt::format("DEVICEUPDATE({}): Device is updating its login password.", Serial));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,13 +34,11 @@ namespace OpenWifi {
|
|||||||
FullEvent.set("type", EventType);
|
FullEvent.set("type", EventType);
|
||||||
FullEvent.set("timestamp", EventTimeStamp);
|
FullEvent.set("timestamp", EventTimeStamp);
|
||||||
FullEvent.set("payload", EventPayload);
|
FullEvent.set("payload", EventPayload);
|
||||||
if(strncmp(EventType.c_str(),"rrm.",4) == 0 ) {
|
|
||||||
KafkaManager()->PostMessage(KafkaTopics::RRM, SerialNumber_,
|
std::ostringstream OS;
|
||||||
FullEvent);
|
FullEvent.stringify(OS);
|
||||||
} else {
|
|
||||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, SerialNumber_,
|
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, SerialNumber_,
|
||||||
FullEvent);
|
OS.str());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "AP_WS_Connection.h"
|
#include "AP_WS_Connection.h"
|
||||||
#include "AP_WS_Server.h"
|
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
@@ -20,10 +19,8 @@ namespace OpenWifi {
|
|||||||
Errors_++;
|
Errors_++;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ParamsObj->has(uCentralProtocol::UUID) &&
|
if (ParamsObj->has(uCentralProtocol::UUID) && ParamsObj->has(uCentralProtocol::SANITY) &&
|
||||||
ParamsObj->has(uCentralProtocol::SANITY) &&
|
|
||||||
ParamsObj->has(uCentralProtocol::DATA)) {
|
ParamsObj->has(uCentralProtocol::DATA)) {
|
||||||
|
|
||||||
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
|
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
|
||||||
auto Sanity = ParamsObj->get(uCentralProtocol::SANITY);
|
auto Sanity = ParamsObj->get(uCentralProtocol::SANITY);
|
||||||
auto CheckData = ParamsObj->get(uCentralProtocol::DATA).toString();
|
auto CheckData = ParamsObj->get(uCentralProtocol::DATA).toString();
|
||||||
@@ -41,6 +38,10 @@ namespace OpenWifi {
|
|||||||
CId_, UUID, request_uuid));
|
CId_, UUID, request_uuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t UpgradedUUID;
|
||||||
|
LookForUpgrade(UUID, UpgradedUUID);
|
||||||
|
State_.UUID = UpgradedUUID;
|
||||||
|
|
||||||
GWObjects::HealthCheck Check;
|
GWObjects::HealthCheck Check;
|
||||||
|
|
||||||
Check.SerialNumber = SerialNumber_;
|
Check.SerialNumber = SerialNumber_;
|
||||||
@@ -49,15 +50,19 @@ namespace OpenWifi {
|
|||||||
Check.Data = CheckData;
|
Check.Data = CheckData;
|
||||||
Check.Sanity = Sanity;
|
Check.Sanity = Sanity;
|
||||||
|
|
||||||
StorageService()->AddHealthCheckData(*DbSession_, Check);
|
StorageService()->AddHealthCheckData(Check);
|
||||||
|
|
||||||
if (!request_uuid.empty()) {
|
if (!request_uuid.empty()) {
|
||||||
StorageService()->SetCommandResult(request_uuid, CheckData);
|
StorageService()->SetCommandResult(request_uuid, CheckData);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetLastHealthCheck(Check);
|
SetLastHealthCheck(Check);
|
||||||
if (KafkaManager()->Enabled() && !AP_WS_Server()->KafkaDisableHealthChecks()) {
|
if (KafkaManager()->Enabled()) {
|
||||||
KafkaManager()->PostMessage(KafkaTopics::HEALTHCHECK, SerialNumber_, *ParamsObj);
|
Poco::JSON::Stringifier Stringify;
|
||||||
|
std::ostringstream OS;
|
||||||
|
ParamsObj->set("timestamp", Utils::Now());
|
||||||
|
Stringify.condense(ParamsObj, OS);
|
||||||
|
KafkaManager()->PostMessage(KafkaTopics::HEALTHCHECK, SerialNumber_, OS.str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
poco_warning(Logger_, fmt::format("HEALTHCHECK({}): Missing parameter", CId_));
|
poco_warning(Logger_, fmt::format("HEALTHCHECK({}): Missing parameter", CId_));
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "framework/ow_constants.h"
|
#include "framework/ow_constants.h"
|
||||||
#include <GWKafkaEvents.h>
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
void AP_WS_Connection::Process_log(Poco::JSON::Object::Ptr ParamsObj) {
|
void AP_WS_Connection::Process_log(Poco::JSON::Object::Ptr ParamsObj) {
|
||||||
@@ -36,8 +35,7 @@ namespace OpenWifi {
|
|||||||
.Recorded = (uint64_t)time(nullptr),
|
.Recorded = (uint64_t)time(nullptr),
|
||||||
.LogType = 0,
|
.LogType = 0,
|
||||||
.UUID = State_.UUID};
|
.UUID = State_.UUID};
|
||||||
StorageService()->AddLog(*DbSession_, DeviceLog);
|
StorageService()->AddLog(DeviceLog);
|
||||||
DeviceLogKafkaEvent E(DeviceLog);
|
|
||||||
} else {
|
} else {
|
||||||
poco_warning(Logger_, fmt::format("LOG({}): Missing parameters.", CId_));
|
poco_warning(Logger_, fmt::format("LOG({}): Missing parameters.", CId_));
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2023-05-16.
|
|
||||||
//
|
|
||||||
#include "AP_WS_Connection.h"
|
|
||||||
#include "StorageService.h"
|
|
||||||
|
|
||||||
#include "fmt/format.h"
|
|
||||||
#include "framework/ow_constants.h"
|
|
||||||
#include <GWKafkaEvents.h>
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
|
|
||||||
void StripNulls(std::string &S) {
|
|
||||||
for(std::size_t i=0;i<S.size();++i) {
|
|
||||||
if(S[i]==0)
|
|
||||||
S[i]=' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AP_WS_Connection::Process_rebootLog(Poco::JSON::Object::Ptr ParamsObj) {
|
|
||||||
if (ParamsObj->has(uCentralProtocol::UUID)
|
|
||||||
&& ParamsObj->isArray(uCentralProtocol::INFO)
|
|
||||||
&& ParamsObj->has(uCentralProtocol::TYPE)
|
|
||||||
&& ParamsObj->has(uCentralProtocol::DATE) ) {
|
|
||||||
poco_warning(Logger_, fmt::format("REBOOT-LOG({}): new entry.", CId_));
|
|
||||||
|
|
||||||
auto InfoLines = ParamsObj->getArray(uCentralProtocol::INFO);
|
|
||||||
std::ostringstream os;
|
|
||||||
InfoLines->stringify(os);
|
|
||||||
|
|
||||||
GWObjects::DeviceLog DeviceLog{.SerialNumber = SerialNumber_,
|
|
||||||
.Log = ParamsObj->get(uCentralProtocol::TYPE).toString(),
|
|
||||||
.Data = "{ \"info\" : " + os.str() + "}",
|
|
||||||
.Severity = GWObjects::DeviceLog::LOG_INFO,
|
|
||||||
.Recorded = ParamsObj->get(uCentralProtocol::DATE),
|
|
||||||
.LogType = 2,
|
|
||||||
.UUID = ParamsObj->get(uCentralProtocol::UUID)};
|
|
||||||
StorageService()->AddLog(*DbSession_, DeviceLog);
|
|
||||||
DeviceLogKafkaEvent E(DeviceLog);
|
|
||||||
} else {
|
|
||||||
poco_warning(Logger_, fmt::format("REBOOT-LOG({}): Missing parameters.", CId_));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // namespace OpenWifi
|
|
||||||
@@ -35,7 +35,7 @@ namespace OpenWifi {
|
|||||||
.LogType = 1,
|
.LogType = 1,
|
||||||
.UUID = 0};
|
.UUID = 0};
|
||||||
|
|
||||||
StorageService()->AddLog(*DbSession_, DeviceLog);
|
StorageService()->AddLog(DeviceLog);
|
||||||
|
|
||||||
if (ParamsObj->get(uCentralProtocol::REBOOT).toString() == "true") {
|
if (ParamsObj->get(uCentralProtocol::REBOOT).toString() == "true") {
|
||||||
GWObjects::CommandDetails Cmd;
|
GWObjects::CommandDetails Cmd;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "AP_WS_Connection.h"
|
#include "AP_WS_Connection.h"
|
||||||
#include "AP_WS_Server.h"
|
|
||||||
#include "StateUtils.h"
|
#include "StateUtils.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
|
|
||||||
@@ -40,19 +39,15 @@ namespace OpenWifi {
|
|||||||
UUID, request_uuid));
|
UUID, request_uuid));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard Guard(DbSession_->Mutex());
|
|
||||||
if(!Simulated_) {
|
|
||||||
uint64_t UpgradedUUID;
|
uint64_t UpgradedUUID;
|
||||||
LookForUpgrade(DbSession_->Session(), UUID, UpgradedUUID);
|
LookForUpgrade(UUID, UpgradedUUID);
|
||||||
State_.UUID = UpgradedUUID;
|
State_.UUID = UpgradedUUID;
|
||||||
}
|
|
||||||
|
|
||||||
SetLastStats(StateStr);
|
SetLastStats(StateStr);
|
||||||
|
|
||||||
GWObjects::Statistics Stats{
|
GWObjects::Statistics Stats{
|
||||||
.SerialNumber = SerialNumber_, .UUID = UUID, .Data = StateStr};
|
.SerialNumber = SerialNumber_, .UUID = UUID, .Data = StateStr};
|
||||||
Stats.Recorded = Utils::Now();
|
Stats.Recorded = Utils::Now();
|
||||||
StorageService()->AddStatisticsData(DbSession_->Session(),Stats);
|
StorageService()->AddStatisticsData(Stats);
|
||||||
if (!request_uuid.empty()) {
|
if (!request_uuid.empty()) {
|
||||||
StorageService()->SetCommandResult(request_uuid, StateStr);
|
StorageService()->SetCommandResult(request_uuid, StateStr);
|
||||||
}
|
}
|
||||||
@@ -60,8 +55,11 @@ namespace OpenWifi {
|
|||||||
StateUtils::ComputeAssociations(StateObj, State_.Associations_2G,
|
StateUtils::ComputeAssociations(StateObj, State_.Associations_2G,
|
||||||
State_.Associations_5G, State_.Associations_6G);
|
State_.Associations_5G, State_.Associations_6G);
|
||||||
|
|
||||||
if (KafkaManager()->Enabled() && !AP_WS_Server()->KafkaDisableState()) {
|
if (KafkaManager()->Enabled()) {
|
||||||
KafkaManager()->PostMessage(KafkaTopics::STATE, SerialNumber_, *ParamsObj);
|
Poco::JSON::Stringifier Stringify;
|
||||||
|
std::ostringstream OS;
|
||||||
|
Stringify.condense(ParamsObj, OS);
|
||||||
|
KafkaManager()->PostMessage(KafkaTopics::STATE, SerialNumber_, OS.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
GWWebSocketNotifications::SingleDevice_t N;
|
GWWebSocketNotifications::SingleDevice_t N;
|
||||||
|
|||||||
@@ -27,28 +27,29 @@ namespace OpenWifi {
|
|||||||
std::ostringstream SS;
|
std::ostringstream SS;
|
||||||
Payload->stringify(SS);
|
Payload->stringify(SS);
|
||||||
auto now = Utils::Now();
|
auto now = Utils::Now();
|
||||||
auto KafkaPayload = SS.str();
|
|
||||||
if (ParamsObj->has("adhoc")) {
|
if (ParamsObj->has("adhoc")) {
|
||||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_TELEMETRY, SerialNumber_,
|
KafkaManager()->PostMessage(KafkaTopics::DEVICE_TELEMETRY, SerialNumber_,
|
||||||
KafkaPayload);
|
SS.str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (TelemetryWebSocketRefCount_) {
|
if (TelemetryWebSocketRefCount_) {
|
||||||
if (now < TelemetryWebSocketTimer_) {
|
if (now < TelemetryWebSocketTimer_) {
|
||||||
|
// std::cout << SerialNumber_ << ": Updating WebSocket telemetry" <<
|
||||||
|
// std::endl;
|
||||||
TelemetryWebSocketPackets_++;
|
TelemetryWebSocketPackets_++;
|
||||||
State_.websocketPackets = TelemetryWebSocketPackets_;
|
State_.websocketPackets = TelemetryWebSocketPackets_;
|
||||||
TelemetryStream()->NotifyEndPoint(SerialNumberInt_, KafkaPayload);
|
TelemetryStream()->NotifyEndPoint(SerialNumberInt_, SS.str());
|
||||||
} else {
|
} else {
|
||||||
StopWebSocketTelemetry(CommandManager()->Next_RPC_ID());
|
StopWebSocketTelemetry(CommandManager()->Next_RPC_ID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (TelemetryKafkaRefCount_) {
|
if (TelemetryKafkaRefCount_) {
|
||||||
if (KafkaManager()->Enabled() && now < TelemetryKafkaTimer_) {
|
if (KafkaManager()->Enabled() && now < TelemetryKafkaTimer_) {
|
||||||
|
// std::cout << SerialNumber_ << ": Updating Kafka telemetry" << std::endl;
|
||||||
TelemetryKafkaPackets_++;
|
TelemetryKafkaPackets_++;
|
||||||
State_.kafkaPackets = TelemetryKafkaPackets_;
|
State_.kafkaPackets = TelemetryKafkaPackets_;
|
||||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_TELEMETRY, SerialNumber_,
|
KafkaManager()->PostMessage(KafkaTopics::DEVICE_TELEMETRY, SerialNumber_,
|
||||||
KafkaPayload);
|
SS.str());
|
||||||
} else {
|
} else {
|
||||||
StopKafkaTelemetry(CommandManager()->Next_RPC_ID());
|
StopKafkaTelemetry(CommandManager()->Next_RPC_ID());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,11 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
if (ParamsObj->has(uCentralProtocol::SERIAL) && ParamsObj->has(uCentralProtocol::DATA)) {
|
if (ParamsObj->has(uCentralProtocol::SERIAL) && ParamsObj->has(uCentralProtocol::DATA)) {
|
||||||
if (KafkaManager()->Enabled()) {
|
if (KafkaManager()->Enabled()) {
|
||||||
KafkaManager()->PostMessage(KafkaTopics::WIFISCAN, SerialNumber_, *ParamsObj);
|
auto Data = ParamsObj->get(uCentralProtocol::DATA);
|
||||||
|
Poco::JSON::Stringifier Stringify;
|
||||||
|
std::ostringstream OS;
|
||||||
|
Stringify.condense(ParamsObj, OS);
|
||||||
|
KafkaManager()->PostMessage(KafkaTopics::WIFISCAN, SerialNumber_, OS.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
62
src/AP_WS_ReactorPool.h
Normal file
62
src/AP_WS_ReactorPool.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2022-02-03.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <shared_mutex>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "Poco/Environment.h"
|
||||||
|
#include "Poco/Net/SocketAcceptor.h"
|
||||||
|
|
||||||
|
#include "framework/utils.h"
|
||||||
|
|
||||||
|
namespace OpenWifi {
|
||||||
|
class AP_WS_ReactorThreadPool {
|
||||||
|
public:
|
||||||
|
explicit AP_WS_ReactorThreadPool() {
|
||||||
|
NumberOfThreads_ = Poco::Environment::processorCount() * 2;
|
||||||
|
if (NumberOfThreads_ == 0)
|
||||||
|
NumberOfThreads_ = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
~AP_WS_ReactorThreadPool() { Stop(); }
|
||||||
|
|
||||||
|
void Start() {
|
||||||
|
for (uint64_t i = 0; i < NumberOfThreads_; ++i) {
|
||||||
|
auto NewReactor = std::make_unique<Poco::Net::SocketReactor>();
|
||||||
|
auto NewThread = std::make_unique<Poco::Thread>();
|
||||||
|
NewThread->start(*NewReactor);
|
||||||
|
std::string ThreadName{"ap:react:" + std::to_string(i)};
|
||||||
|
Utils::SetThreadName(*NewThread, ThreadName.c_str());
|
||||||
|
Reactors_.emplace_back(std::move(NewReactor));
|
||||||
|
Threads_.emplace_back(std::move(NewThread));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stop() {
|
||||||
|
for (auto &i : Reactors_)
|
||||||
|
i->stop();
|
||||||
|
for (auto &i : Threads_) {
|
||||||
|
i->join();
|
||||||
|
}
|
||||||
|
Reactors_.clear();
|
||||||
|
Threads_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
Poco::Net::SocketReactor &NextReactor() {
|
||||||
|
std::shared_lock Lock(Mutex_);
|
||||||
|
NextReactor_++;
|
||||||
|
NextReactor_ %= NumberOfThreads_;
|
||||||
|
return *Reactors_[NextReactor_];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_mutex Mutex_;
|
||||||
|
uint64_t NumberOfThreads_;
|
||||||
|
uint64_t NextReactor_ = 0;
|
||||||
|
std::vector<std::unique_ptr<Poco::Net::SocketReactor>> Reactors_;
|
||||||
|
std::vector<std::unique_ptr<Poco::Thread>> Threads_;
|
||||||
|
};
|
||||||
|
} // namespace OpenWifi
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2022-02-03.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "Poco/Environment.h"
|
|
||||||
#include "Poco/Net/SocketAcceptor.h"
|
|
||||||
#include <Poco/Data/SessionPool.h>
|
|
||||||
#include "framework/utils.h"
|
|
||||||
#include <StorageService.h>
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
|
|
||||||
class AP_WS_ReactorThreadPool {
|
|
||||||
public:
|
|
||||||
explicit AP_WS_ReactorThreadPool(Poco::Logger &Logger) : Logger_(Logger) {
|
|
||||||
NumberOfThreads_ = Poco::Environment::processorCount() * 4;
|
|
||||||
if (NumberOfThreads_ == 0)
|
|
||||||
NumberOfThreads_ = 8;
|
|
||||||
NumberOfThreads_ = std::min(NumberOfThreads_, (std::uint64_t) 128);
|
|
||||||
}
|
|
||||||
|
|
||||||
~AP_WS_ReactorThreadPool() { Stop(); }
|
|
||||||
|
|
||||||
void Start() {
|
|
||||||
Reactors_.reserve(NumberOfThreads_);
|
|
||||||
DbSessions_.reserve(NumberOfThreads_);
|
|
||||||
Threads_.reserve(NumberOfThreads_);
|
|
||||||
Logger_.information(fmt::format("WebSocket Processor: starting {} threads.", NumberOfThreads_));
|
|
||||||
for (uint64_t i = 0; i < NumberOfThreads_; ++i) {
|
|
||||||
auto NewReactor = std::make_shared<Poco::Net::SocketReactor>();
|
|
||||||
auto NewThread = std::make_unique<Poco::Thread>();
|
|
||||||
NewThread->start(*NewReactor);
|
|
||||||
std::string ThreadName{"ap:react:" + std::to_string(i)};
|
|
||||||
Utils::SetThreadName(*NewThread, ThreadName.c_str());
|
|
||||||
Reactors_.emplace_back(std::move(NewReactor));
|
|
||||||
Threads_.emplace_back(std::move(NewThread));
|
|
||||||
DbSessions_.emplace_back(std::make_shared<LockedDbSession>());
|
|
||||||
}
|
|
||||||
Logger_.information(fmt::format("WebSocket Processor: {} threads started.", NumberOfThreads_));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Stop() {
|
|
||||||
for (auto &i : Reactors_)
|
|
||||||
i->stop();
|
|
||||||
for (auto &i : Threads_) {
|
|
||||||
i->join();
|
|
||||||
}
|
|
||||||
Reactors_.clear();
|
|
||||||
Threads_.clear();
|
|
||||||
DbSessions_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<std::shared_ptr<Poco::Net::SocketReactor>, std::shared_ptr<LockedDbSession> > NextReactor() {
|
|
||||||
std::lock_guard Lock(Mutex_);
|
|
||||||
NextReactor_++;
|
|
||||||
NextReactor_ %= NumberOfThreads_;
|
|
||||||
return std::make_pair(Reactors_[NextReactor_], DbSessions_[NextReactor_]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::mutex Mutex_;
|
|
||||||
uint64_t NumberOfThreads_;
|
|
||||||
uint64_t NextReactor_ = 0;
|
|
||||||
std::vector<std::shared_ptr<Poco::Net::SocketReactor>> Reactors_;
|
|
||||||
std::vector<std::unique_ptr<Poco::Thread>> Threads_;
|
|
||||||
std::vector<std::shared_ptr<LockedDbSession>> DbSessions_;
|
|
||||||
Poco::Logger &Logger_;
|
|
||||||
|
|
||||||
};
|
|
||||||
} // namespace OpenWifi
|
|
||||||
@@ -19,53 +19,20 @@
|
|||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
#include "framework/utils.h"
|
#include "framework/utils.h"
|
||||||
#include <framework/KafkaManager.h>
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
class AP_WS_RequestHandler : public Poco::Net::HTTPRequestHandler {
|
void AP_WS_RequestHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||||
public:
|
Poco::Net::HTTPServerResponse &response) {
|
||||||
explicit AP_WS_RequestHandler(Poco::Logger &L, std::uint64_t session_id) : Logger_(L),
|
|
||||||
session_id_(session_id) {
|
|
||||||
};
|
|
||||||
|
|
||||||
void handleRequest( Poco::Net::HTTPServerRequest &request,
|
|
||||||
Poco::Net::HTTPServerResponse &response) override {
|
|
||||||
try {
|
try {
|
||||||
auto NewConnection = std::make_shared<AP_WS_Connection>(request, response, session_id_, Logger_,
|
AP_WS_Server()->AddConnection(
|
||||||
AP_WS_Server()->NextReactor());
|
id_, std::make_shared<AP_WS_Connection>(request, response, id_, Logger_,
|
||||||
AP_WS_Server()->AddConnection(NewConnection);
|
AP_WS_Server()->NextReactor()));
|
||||||
NewConnection->Start();
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_warning(Logger_, "Exception during WS creation");
|
poco_warning(Logger_, "Exception during WS creation");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
|
||||||
Poco::Logger &Logger_;
|
|
||||||
std::uint64_t session_id_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AP_WS_RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
|
|
||||||
public:
|
|
||||||
inline explicit AP_WS_RequestHandlerFactory(Poco::Logger &L) : Logger_(L) {}
|
|
||||||
|
|
||||||
inline Poco::Net::HTTPRequestHandler *
|
|
||||||
createRequestHandler(const Poco::Net::HTTPServerRequest &request) override {
|
|
||||||
if (request.find("Upgrade") != request.end() &&
|
|
||||||
Poco::icompare(request["Upgrade"], "websocket") == 0) {
|
|
||||||
Utils::SetThreadName("ws:conn-init");
|
|
||||||
session_id_++;
|
|
||||||
return new AP_WS_RequestHandler(Logger_, session_id_);
|
|
||||||
} else {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
Poco::Logger &Logger_;
|
|
||||||
inline static std::atomic_uint64_t session_id_ = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
bool AP_WS_Server::ValidateCertificate(const std::string &ConnectionId,
|
bool AP_WS_Server::ValidateCertificate(const std::string &ConnectionId,
|
||||||
const Poco::Crypto::X509Certificate &Certificate) {
|
const Poco::Crypto::X509Certificate &Certificate) {
|
||||||
if (IsCertOk()) {
|
if (IsCertOk()) {
|
||||||
@@ -87,9 +54,7 @@ namespace OpenWifi {
|
|||||||
MicroServiceConfigGetBool("openwifi.certificates.allowmismatch", true);
|
MicroServiceConfigGetBool("openwifi.certificates.allowmismatch", true);
|
||||||
MismatchDepth_ = MicroServiceConfigGetInt("openwifi.certificates.mismatchdepth", 2);
|
MismatchDepth_ = MicroServiceConfigGetInt("openwifi.certificates.mismatchdepth", 2);
|
||||||
|
|
||||||
SessionTimeOut_ = MicroServiceConfigGetInt("openwifi.session.timeout", 10*60);
|
Reactor_pool_ = std::make_unique<AP_WS_ReactorThreadPool>();
|
||||||
|
|
||||||
Reactor_pool_ = std::make_unique<AP_WS_ReactorThreadPool>(Logger());
|
|
||||||
Reactor_pool_->Start();
|
Reactor_pool_->Start();
|
||||||
|
|
||||||
for (const auto &Svr : ConfigServersList_) {
|
for (const auto &Svr : ConfigServersList_) {
|
||||||
@@ -139,6 +104,7 @@ namespace OpenWifi {
|
|||||||
Context->flushSessionCache();
|
Context->flushSessionCache();
|
||||||
Context->enableSessionCache(true);
|
Context->enableSessionCache(true);
|
||||||
Context->enableExtendedCertificateVerification(false);
|
Context->enableExtendedCertificateVerification(false);
|
||||||
|
// Context->disableStatelessSessionResumption();
|
||||||
Context->disableProtocols(Poco::Net::Context::PROTO_TLSV1 |
|
Context->disableProtocols(Poco::Net::Context::PROTO_TLSV1 |
|
||||||
Poco::Net::Context::PROTO_TLSV1_1);
|
Poco::Net::Context::PROTO_TLSV1_1);
|
||||||
|
|
||||||
@@ -167,9 +133,6 @@ namespace OpenWifi {
|
|||||||
WebServerHttpParams);
|
WebServerHttpParams);
|
||||||
WebServers_.push_back(std::move(NewWebServer));
|
WebServers_.push_back(std::move(NewWebServer));
|
||||||
}
|
}
|
||||||
|
|
||||||
KafkaDisableState_ = MicroServiceConfigGetBool("openwifi.kafka.disablestate", false);
|
|
||||||
KafkaDisableHealthChecks_ = MicroServiceConfigGetBool("openwifi.kafka.disablehealthchecks", false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto &server : WebServers_) {
|
for (auto &server : WebServers_) {
|
||||||
@@ -191,168 +154,56 @@ namespace OpenWifi {
|
|||||||
UseDefaultConfig_ = true;
|
UseDefaultConfig_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimulatorId_ = Poco::toLower(MicroServiceConfigGetString("simulatorid", ""));
|
SimulatorId_ = MicroServiceConfigGetString("simulatorid", "");
|
||||||
SimulatorEnabled_ = !SimulatorId_.empty();
|
SimulatorEnabled_ = !SimulatorId_.empty();
|
||||||
Utils::SetThreadName(ReactorThread_, "dev:react:head");
|
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;
|
Running_ = true;
|
||||||
GarbageCollector_.setName("ws:garbage");
|
|
||||||
GarbageCollector_.start(*this);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Server::run() {
|
void AP_WS_Server::onGarbageCollecting([[maybe_unused]] Poco::Timer &timer) {
|
||||||
uint64_t last_log = Utils::Now(),
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
last_zombie_run = 0,
|
if (!Garbage_.empty()) {
|
||||||
last_garbage_run = 0;
|
Garbage_.clear();
|
||||||
|
|
||||||
Poco::Logger &LocalLogger = Poco::Logger::create(
|
|
||||||
"WS-Session-Janitor", Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel());
|
|
||||||
|
|
||||||
while(Running_) {
|
|
||||||
|
|
||||||
if(!Poco::Thread::trySleep(30000)) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalLogger.information(fmt::format("Garbage collecting starting run." ));
|
static uint64_t last_log = Utils::Now();
|
||||||
|
|
||||||
uint64_t total_connected_time = 0, now = Utils::Now();
|
|
||||||
|
|
||||||
if(now-last_zombie_run > 60) {
|
|
||||||
try {
|
|
||||||
poco_information(LocalLogger,
|
|
||||||
fmt::format("Garbage collecting zombies... (step 1)"));
|
|
||||||
NumberOfConnectedDevices_ = 0;
|
NumberOfConnectedDevices_ = 0;
|
||||||
NumberOfConnectingDevices_ = 0;
|
NumberOfConnectingDevices_ = 0;
|
||||||
AverageDeviceConnectionTime_ = 0;
|
AverageDeviceConnectionTime_ = 0;
|
||||||
int waits = 0;
|
uint64_t total_connected_time = 0;
|
||||||
for (int hashIndex = 0; hashIndex < MACHash::HashMax(); hashIndex++) {
|
|
||||||
last_zombie_run = now;
|
|
||||||
waits = 0;
|
|
||||||
while (true) {
|
|
||||||
if (SerialNumbersMutex_[hashIndex].try_lock()) {
|
|
||||||
waits = 0;
|
|
||||||
auto hint = SerialNumbers_[hashIndex].begin();
|
|
||||||
while (hint != end(SerialNumbers_[hashIndex])) {
|
|
||||||
|
|
||||||
if (hint->second == nullptr) {
|
auto now = Utils::Now();
|
||||||
poco_information(
|
for (const auto &connection : SerialNumbers_) {
|
||||||
LocalLogger,
|
if (connection.second.second == nullptr) {
|
||||||
fmt::format("Dead device found in hash index {}", hashIndex));
|
|
||||||
// hint = SerialNumbers_[hashIndex].erase(hint);
|
|
||||||
hint++;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto Device = hint->second;
|
if (connection.second.second->State_.Connected) {
|
||||||
if(Device->ConnectionMutex_.try_lock()) {
|
|
||||||
auto RightNow = Utils::Now();
|
|
||||||
if (RightNow > Device->LastContact_ &&
|
|
||||||
(RightNow - Device->LastContact_) > SessionTimeOut_) {
|
|
||||||
poco_information(
|
|
||||||
LocalLogger,
|
|
||||||
fmt::format("{}: Session seems idle. Controller disconnecting device.",
|
|
||||||
Device->SerialNumber_));
|
|
||||||
hint = SerialNumbers_[hashIndex].erase(hint);
|
|
||||||
} else if (Device->State_.Connected) {
|
|
||||||
NumberOfConnectedDevices_++;
|
NumberOfConnectedDevices_++;
|
||||||
total_connected_time +=
|
total_connected_time += (now - connection.second.second->State_.started);
|
||||||
(RightNow - Device->State_.started);
|
|
||||||
++hint;
|
|
||||||
} else {
|
} else {
|
||||||
++hint;
|
NumberOfConnectingDevices_++;
|
||||||
}
|
|
||||||
Device->ConnectionMutex_.unlock();
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
poco_warning(LocalLogger, fmt::format("Could not lock device mutex for {}",
|
|
||||||
Device->SerialNumber_));
|
|
||||||
}
|
|
||||||
++NumberOfConnectingDevices_;
|
|
||||||
++hint;
|
|
||||||
}
|
|
||||||
SerialNumbersMutex_[hashIndex].unlock();
|
|
||||||
break;
|
|
||||||
} else if (waits < 5) {
|
|
||||||
waits++;
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
poco_information(LocalLogger,
|
|
||||||
fmt::format("Garbage collecting zombies... (step 2)"));
|
|
||||||
LeftOverSessions_ = 0;
|
|
||||||
for (int i = 0; i < SessionHash::HashMax(); i++) {
|
|
||||||
waits = 0;
|
|
||||||
while (true) {
|
|
||||||
if (SessionMutex_[i].try_lock()) {
|
|
||||||
waits = 0;
|
|
||||||
auto hint = Sessions_[i].begin();
|
|
||||||
auto RightNow = Utils::Now();
|
|
||||||
while (hint != end(Sessions_[i])) {
|
|
||||||
if (hint->second == nullptr) {
|
|
||||||
hint = Sessions_[i].erase(hint);
|
|
||||||
} else if (RightNow > hint->second->LastContact_ &&
|
|
||||||
(RightNow - hint->second->LastContact_) >
|
|
||||||
SessionTimeOut_) {
|
|
||||||
poco_information(
|
|
||||||
LocalLogger,
|
|
||||||
fmt::format("{}: Session seems idle. Controller disconnecting device.",
|
|
||||||
hint->second->SerialNumber_));
|
|
||||||
hint = Sessions_[i].erase(hint);
|
|
||||||
} else {
|
|
||||||
++LeftOverSessions_;
|
|
||||||
++hint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SessionMutex_[i].unlock();
|
|
||||||
break;
|
|
||||||
} else if (waits < 5) {
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
|
||||||
waits++;
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AverageDeviceConnectionTime_ =
|
AverageDeviceConnectionTime_ =
|
||||||
NumberOfConnectedDevices_ > 0
|
(NumberOfConnectedDevices_ != 0) ? total_connected_time / NumberOfConnectedDevices_ : 0;
|
||||||
? total_connected_time / NumberOfConnectedDevices_
|
if ((now - last_log) > 120) {
|
||||||
: 0;
|
|
||||||
poco_information(LocalLogger, fmt::format("Garbage collecting zombies done..."));
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
poco_error(LocalLogger, fmt::format("Poco::Exception: Garbage collecting zombies failed: {}", E.displayText()));
|
|
||||||
} catch (const std::exception &E) {
|
|
||||||
poco_error(LocalLogger, fmt::format("std::exception: Garbage collecting zombies failed: {}", E.what()));
|
|
||||||
} catch (...) {
|
|
||||||
poco_error(LocalLogger, fmt::format("exception:Garbage collecting zombies failed: {}", "unknown"));
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
NumberOfConnectedDevices_=0;
|
|
||||||
for(int i=0;i<MACHash::HashMax();i++) {
|
|
||||||
std::lock_guard Lock(SerialNumbersMutex_[i]);
|
|
||||||
NumberOfConnectedDevices_ += SerialNumbers_[i].size();
|
|
||||||
}
|
|
||||||
if(NumberOfConnectedDevices_) {
|
|
||||||
if (last_garbage_run > 0) {
|
|
||||||
AverageDeviceConnectionTime_ += (now - last_garbage_run);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
AverageDeviceConnectionTime_ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((now - last_log) > 60) {
|
|
||||||
last_log = now;
|
last_log = now;
|
||||||
poco_information(LocalLogger,
|
poco_information(
|
||||||
fmt::format("Active AP connections: {} Connecting: {} Average connection time: {} seconds. Left Over Sessions: {}",
|
Logger(),
|
||||||
|
fmt::format(
|
||||||
|
"Active AP connections: {} Connecting: {} Average connection time: {} seconds",
|
||||||
NumberOfConnectedDevices_, NumberOfConnectingDevices_,
|
NumberOfConnectedDevices_, NumberOfConnectingDevices_,
|
||||||
AverageDeviceConnectionTime_, LeftOverSessions_));
|
AverageDeviceConnectionTime_));
|
||||||
}
|
}
|
||||||
|
|
||||||
GWWebSocketNotifications::NumberOfConnection_t Notification;
|
GWWebSocketNotifications::NumberOfConnection_t Notification;
|
||||||
@@ -361,175 +212,146 @@ namespace OpenWifi {
|
|||||||
Notification.content.averageConnectedTime = AverageDeviceConnectionTime_;
|
Notification.content.averageConnectedTime = AverageDeviceConnectionTime_;
|
||||||
GetTotalDataStatistics(Notification.content.tx,Notification.content.rx);
|
GetTotalDataStatistics(Notification.content.tx,Notification.content.rx);
|
||||||
GWWebSocketNotifications::NumberOfConnections(Notification);
|
GWWebSocketNotifications::NumberOfConnections(Notification);
|
||||||
|
|
||||||
Poco::JSON::Object KafkaNotification;
|
|
||||||
Notification.to_json(KafkaNotification);
|
|
||||||
|
|
||||||
Poco::JSON::Object FullEvent;
|
|
||||||
FullEvent.set("type", "load-update");
|
|
||||||
FullEvent.set("timestamp", now);
|
|
||||||
FullEvent.set("payload", KafkaNotification);
|
|
||||||
|
|
||||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, "system", FullEvent);
|
|
||||||
LocalLogger.information(fmt::format("Garbage collection finished run." ));
|
|
||||||
last_garbage_run = now;
|
|
||||||
}
|
|
||||||
LocalLogger.information(fmt::format("Garbage collector done for the day." ));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Server::Stop() {
|
void AP_WS_Server::Stop() {
|
||||||
poco_information(Logger(), "Stopping...");
|
poco_information(Logger(), "Stopping...");
|
||||||
Running_ = false;
|
Running_ = false;
|
||||||
|
|
||||||
GarbageCollector_.wakeUp();
|
Timer_.stop();
|
||||||
GarbageCollector_.join();
|
|
||||||
|
|
||||||
for (auto &server : WebServers_) {
|
for (auto &server : WebServers_) {
|
||||||
server->stopAll();
|
server->stopAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
Reactor_pool_->Stop();
|
Reactor_pool_->Stop();
|
||||||
Reactor_.stop();
|
Reactor_.stop();
|
||||||
ReactorThread_.join();
|
ReactorThread_.join();
|
||||||
poco_information(Logger(), "Stopped...");
|
poco_information(Logger(), "Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Server::GetHealthDevices(std::uint64_t lowLimit, std::uint64_t highLimit, std::vector<std::string> & SerialNumbers) {
|
|
||||||
SerialNumbers.clear();
|
|
||||||
for(int i=0;i<SessionHash::HashMax();i++) {
|
|
||||||
std::lock_guard Lock(SessionMutex_[i]);
|
|
||||||
for (const auto &connection : Sessions_[i]) {
|
|
||||||
if (connection.second->RawLastHealthcheck_.Sanity >= lowLimit &&
|
|
||||||
connection.second->RawLastHealthcheck_.Sanity <= highLimit) {
|
|
||||||
SerialNumbers.push_back(connection.second->SerialNumber_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AP_WS_Server::GetStatistics(uint64_t SerialNumber, std::string &Statistics) const {
|
bool AP_WS_Server::GetStatistics(uint64_t SerialNumber, std::string &Statistics) const {
|
||||||
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
auto hashIndex = MACHash::Hash(SerialNumber);
|
{
|
||||||
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
|
auto Device = SerialNumbers_.find(SerialNumber);
|
||||||
if (Device == SerialNumbers_[hashIndex].end() || Device->second == nullptr) {
|
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Device->second->GetLastStats(Statistics);
|
DevicePtr = Device->second.second;
|
||||||
|
}
|
||||||
|
DevicePtr->GetLastStats(Statistics);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Server::GetState(uint64_t SerialNumber, GWObjects::ConnectionState &State) const {
|
bool AP_WS_Server::GetState(uint64_t SerialNumber, GWObjects::ConnectionState &State) const {
|
||||||
std::shared_ptr<AP_WS_Connection> Connection;
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
{
|
{
|
||||||
auto hashIndex = MACHash::Hash(SerialNumber);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
|
auto Device = SerialNumbers_.find(SerialNumber);
|
||||||
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
|
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
|
||||||
if (DeviceHint == SerialNumbers_[hashIndex].end() ||
|
|
||||||
DeviceHint->second == nullptr) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Connection = DeviceHint->second;
|
DevicePtr = Device->second.second;
|
||||||
}
|
}
|
||||||
Connection->GetState(State);
|
DevicePtr->GetState(State);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Server::GetHealthcheck(uint64_t SerialNumber,
|
bool AP_WS_Server::GetHealthcheck(uint64_t SerialNumber,
|
||||||
GWObjects::HealthCheck &CheckData) const {
|
GWObjects::HealthCheck &CheckData) const {
|
||||||
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
auto hashIndex = MACHash::Hash(SerialNumber);
|
{
|
||||||
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
|
auto Device = SerialNumbers_.find(SerialNumber);
|
||||||
if (Device == SerialNumbers_[hashIndex].end() || Device->second == nullptr) {
|
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Device->second->GetLastHealthCheck(CheckData);
|
DevicePtr = Device->second.second;
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void AP_WS_Server::StartSession(uint64_t session_id, uint64_t SerialNumber) {
|
|
||||||
auto deviceHash = MACHash::Hash(SerialNumber);
|
|
||||||
auto sessionHash = SessionHash::Hash(session_id);
|
|
||||||
std::lock_guard SessionLock(SessionMutex_[sessionHash]);
|
|
||||||
auto SessionHint = Sessions_[sessionHash].find(session_id);
|
|
||||||
if (SessionHint != end(Sessions_[sessionHash])) {
|
|
||||||
std::lock_guard Lock(SerialNumbersMutex_[deviceHash]);
|
|
||||||
SerialNumbers_[deviceHash][SerialNumber] = SessionHint->second;
|
|
||||||
Sessions_[sessionHash].erase(SessionHint);
|
|
||||||
} else {
|
|
||||||
poco_error(Logger(), fmt::format("StartSession: Could not find session '{}'", session_id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AP_WS_Server::EndSession(uint64_t session_id, uint64_t SerialNumber) {
|
|
||||||
{
|
|
||||||
auto sessionHash = SessionHash::Hash(session_id);
|
|
||||||
std::lock_guard SessionLock(SessionMutex_[sessionHash]);
|
|
||||||
Sessions_[sessionHash].erase(session_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
auto hashIndex = MACHash::Hash(SerialNumber);
|
|
||||||
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
|
|
||||||
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
|
|
||||||
if (DeviceHint == SerialNumbers_[hashIndex].end()
|
|
||||||
|| DeviceHint->second == nullptr
|
|
||||||
|| DeviceHint->second->State_.sessionId != session_id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
SerialNumbers_[hashIndex].erase(DeviceHint);
|
|
||||||
}
|
}
|
||||||
|
DevicePtr->GetLastHealthCheck(CheckData);
|
||||||
return true;
|
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,
|
bool AP_WS_Server::Connected(uint64_t SerialNumber,
|
||||||
GWObjects::DeviceRestrictions &Restrictions) const {
|
GWObjects::DeviceRestrictions &Restrictions) const {
|
||||||
auto hashIndex = MACHash::Hash(SerialNumber);
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
|
{
|
||||||
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
|
auto Device = SerialNumbers_.find(SerialNumber);
|
||||||
|
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(!DeviceHint->second->Dead_) {
|
DevicePtr = Device->second.second;
|
||||||
DeviceHint->second->GetRestrictions(Restrictions);
|
|
||||||
return DeviceHint->second->State_.Connected;
|
|
||||||
}
|
}
|
||||||
return false;
|
DevicePtr->GetRestrictions(Restrictions);
|
||||||
|
return DevicePtr->State_.Connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool AP_WS_Server::Connected(uint64_t SerialNumber) const {
|
bool AP_WS_Server::Connected(uint64_t SerialNumber) const {
|
||||||
auto hashIndex = MACHash::Hash(SerialNumber);
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
|
{
|
||||||
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
|
auto Device = SerialNumbers_.find(SerialNumber);
|
||||||
|
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if(!DeviceHint->second->Dead_) {
|
DevicePtr = Device->second.second;
|
||||||
return DeviceHint->second->State_.Connected;
|
|
||||||
}
|
}
|
||||||
return false;
|
return DevicePtr->State_.Connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Server::SendFrame(uint64_t SerialNumber, const std::string &Payload) const {
|
bool AP_WS_Server::SendFrame(uint64_t SerialNumber, const std::string &Payload) const {
|
||||||
auto hashIndex = MACHash::Hash(SerialNumber);
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
|
{
|
||||||
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
|
auto Device = SerialNumbers_.find(SerialNumber);
|
||||||
|
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
DevicePtr = Device->second.second;
|
||||||
if(DeviceHint->second->Dead_) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return DeviceHint->second->Send(Payload);
|
return DevicePtr->Send(Payload);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_debug(Logger(), fmt::format(": SendFrame: Could not send data to device '{}'",
|
poco_debug(Logger(), fmt::format(": SendFrame: Could not send data to device '{}'",
|
||||||
Utils::IntToSerialNumber(SerialNumber)));
|
Utils::IntToSerialNumber(SerialNumber)));
|
||||||
@@ -538,48 +360,61 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Server::StopWebSocketTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
|
void AP_WS_Server::StopWebSocketTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
|
||||||
auto hashIndex = MACHash::Hash(SerialNumber);
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
|
{
|
||||||
auto Device = SerialNumbers_[hashIndex].find(SerialNumber);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
if (Device == end(SerialNumbers_[hashIndex]) || Device->second == nullptr) {
|
|
||||||
|
auto Device = SerialNumbers_.find(SerialNumber);
|
||||||
|
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Device->second->StopWebSocketTelemetry(RPCID);
|
DevicePtr = Device->second.second;
|
||||||
|
}
|
||||||
|
DevicePtr->StopWebSocketTelemetry(RPCID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AP_WS_Server::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber,
|
AP_WS_Server::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber,
|
||||||
uint64_t Interval, uint64_t Lifetime,
|
uint64_t Interval, uint64_t Lifetime,
|
||||||
const std::vector<std::string> &TelemetryTypes) {
|
const std::vector<std::string> &TelemetryTypes) {
|
||||||
auto hashIndex = MACHash::Hash(SerialNumber);
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
std::lock_guard DeviceLock(SerialNumbersMutex_[hashIndex]);
|
{
|
||||||
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
|
auto Device = SerialNumbers_.find(SerialNumber);
|
||||||
|
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DeviceHint->second->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime, TelemetryTypes);
|
DevicePtr = Device->second.second;
|
||||||
|
}
|
||||||
|
DevicePtr->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime, TelemetryTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Server::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber,
|
void AP_WS_Server::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber,
|
||||||
uint64_t Interval, uint64_t Lifetime,
|
uint64_t Interval, uint64_t Lifetime,
|
||||||
const std::vector<std::string> &TelemetryTypes) {
|
const std::vector<std::string> &TelemetryTypes) {
|
||||||
auto hashIndex = MACHash::Hash(SerialNumber);
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
std::lock_guard Lock(SerialNumbersMutex_[hashIndex]);
|
{
|
||||||
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
|
auto Device = SerialNumbers_.find(SerialNumber);
|
||||||
|
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DeviceHint->second->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime, TelemetryTypes);
|
DevicePtr = Device->second.second;
|
||||||
|
}
|
||||||
|
DevicePtr->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime, TelemetryTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Server::StopKafkaTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
|
void AP_WS_Server::StopKafkaTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
|
||||||
auto hashIndex = MACHash::Hash(SerialNumber);
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]);
|
{
|
||||||
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
|
auto Device = SerialNumbers_.find(SerialNumber);
|
||||||
|
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DeviceHint->second->StopKafkaTelemetry(RPCID);
|
DevicePtr = Device->second.second;
|
||||||
|
}
|
||||||
|
DevicePtr->StopKafkaTelemetry(RPCID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AP_WS_Server::GetTelemetryParameters(
|
void AP_WS_Server::GetTelemetryParameters(
|
||||||
@@ -587,15 +422,16 @@ namespace OpenWifi {
|
|||||||
uint64_t &TelemetryWebSocketTimer, uint64_t &TelemetryKafkaTimer,
|
uint64_t &TelemetryWebSocketTimer, uint64_t &TelemetryKafkaTimer,
|
||||||
uint64_t &TelemetryWebSocketCount, uint64_t &TelemetryKafkaCount,
|
uint64_t &TelemetryWebSocketCount, uint64_t &TelemetryKafkaCount,
|
||||||
uint64_t &TelemetryWebSocketPackets, uint64_t &TelemetryKafkaPackets) {
|
uint64_t &TelemetryWebSocketPackets, uint64_t &TelemetryKafkaPackets) {
|
||||||
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
auto hashIndex = MACHash::Hash(SerialNumber);
|
{
|
||||||
std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
auto DeviceHint = SerialNumbers_[hashIndex].find(SerialNumber);
|
auto Device = SerialNumbers_.find(SerialNumber);
|
||||||
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
|
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
DevicePtr = Device->second.second;
|
||||||
DeviceHint->second->GetTelemetryParameters(TelemetryRunning, TelemetryInterval,
|
}
|
||||||
|
DevicePtr->GetTelemetryParameters(TelemetryRunning, TelemetryInterval,
|
||||||
TelemetryWebSocketTimer, TelemetryKafkaTimer,
|
TelemetryWebSocketTimer, TelemetryKafkaTimer,
|
||||||
TelemetryWebSocketCount, TelemetryKafkaCount,
|
TelemetryWebSocketCount, TelemetryKafkaCount,
|
||||||
TelemetryWebSocketPackets, TelemetryKafkaPackets);
|
TelemetryWebSocketPackets, TelemetryKafkaPackets);
|
||||||
@@ -603,21 +439,18 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
bool AP_WS_Server::SendRadiusAccountingData(const std::string &SerialNumber,
|
bool AP_WS_Server::SendRadiusAccountingData(const std::string &SerialNumber,
|
||||||
const unsigned char *buffer, std::size_t size) {
|
const unsigned char *buffer, std::size_t size) {
|
||||||
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber);
|
{
|
||||||
auto hashIndex = MACHash::Hash(IntSerialNumber);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]);
|
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||||
auto DeviceHint = SerialNumbers_[hashIndex].find(IntSerialNumber);
|
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
|
||||||
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
DevicePtr = Device->second.second;
|
||||||
if(DeviceHint->second->Dead_) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return DeviceHint->second->SendRadiusAccountingData(buffer, size);
|
return DevicePtr->SendRadiusAccountingData(buffer, size);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_debug(
|
poco_debug(
|
||||||
Logger(),
|
Logger(),
|
||||||
@@ -629,20 +462,18 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
bool AP_WS_Server::SendRadiusAuthenticationData(const std::string &SerialNumber,
|
bool AP_WS_Server::SendRadiusAuthenticationData(const std::string &SerialNumber,
|
||||||
const unsigned char *buffer, std::size_t size) {
|
const unsigned char *buffer, std::size_t size) {
|
||||||
auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber);
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
auto hashIndex = MACHash::Hash(IntSerialNumber);
|
{
|
||||||
std::lock_guard DevicesLock(SerialNumbersMutex_[hashIndex]);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
auto DeviceHint = SerialNumbers_[hashIndex].find(IntSerialNumber);
|
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||||
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
|
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
DevicePtr = Device->second.second;
|
||||||
if(DeviceHint->second->Dead_) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return DeviceHint->second->SendRadiusAuthenticationData(buffer, size);
|
return DevicePtr->SendRadiusAuthenticationData(buffer, size);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_debug(
|
poco_debug(
|
||||||
Logger(),
|
Logger(),
|
||||||
@@ -654,19 +485,18 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
bool AP_WS_Server::SendRadiusCoAData(const std::string &SerialNumber,
|
bool AP_WS_Server::SendRadiusCoAData(const std::string &SerialNumber,
|
||||||
const unsigned char *buffer, std::size_t size) {
|
const unsigned char *buffer, std::size_t size) {
|
||||||
auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber);
|
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||||
auto hashIndex = MACHash::Hash(IntSerialNumber);
|
{
|
||||||
std::lock_guard DevicesGuard(SerialNumbersMutex_[hashIndex]);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
auto DeviceHint = SerialNumbers_[hashIndex].find(IntSerialNumber);
|
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||||
if (DeviceHint == end(SerialNumbers_[hashIndex]) || DeviceHint->second == nullptr) {
|
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
DevicePtr = Device->second.second;
|
||||||
|
}
|
||||||
|
|
||||||
if(DeviceHint->second->Dead_) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
return DeviceHint->second->SendRadiusCoAData(buffer, size);
|
return DevicePtr->SendRadiusCoAData(buffer, size);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_debug(Logger(),
|
poco_debug(Logger(),
|
||||||
fmt::format(": SendRadiusCoAData: Could not send data to device '{}'",
|
fmt::format(": SendRadiusCoAData: Could not send data to device '{}'",
|
||||||
@@ -675,32 +505,4 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AP_WS_Server::ExtendedAttributes(const std::string &serialNumber,
|
|
||||||
bool & hasGPS,
|
|
||||||
std::uint64_t &Sanity,
|
|
||||||
std::double_t &MemoryUsed,
|
|
||||||
std::double_t &Load,
|
|
||||||
std::double_t &Temperature
|
|
||||||
) {
|
|
||||||
|
|
||||||
auto serialNumberInt = Utils::SerialNumberToInt(serialNumber);
|
|
||||||
auto hashIndex = MACHash::Hash(serialNumberInt);
|
|
||||||
std::lock_guard DevicesGuard(SerialNumbersMutex_[hashIndex]);
|
|
||||||
auto DeviceHint = SerialNumbers_[hashIndex].find(Utils::SerialNumberToInt(serialNumber));
|
|
||||||
if(DeviceHint==end(SerialNumbers_[hashIndex])) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(DeviceHint->second->Dead_) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
std::lock_guard DeviceGuard(DeviceHint->second->ConnectionMutex_);
|
|
||||||
hasGPS = DeviceHint->second->hasGPS_;
|
|
||||||
Sanity = DeviceHint->second->RawLastHealthcheck_.Sanity;
|
|
||||||
MemoryUsed = DeviceHint->second->memory_used_;
|
|
||||||
Load = DeviceHint->second->cpu_load_;
|
|
||||||
Temperature = DeviceHint->second->temperature_;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
@@ -24,51 +24,46 @@
|
|||||||
#include "Poco/Timer.h"
|
#include "Poco/Timer.h"
|
||||||
|
|
||||||
#include "AP_WS_Connection.h"
|
#include "AP_WS_Connection.h"
|
||||||
#include "AP_WS_Reactor_Pool.h"
|
#include "AP_WS_ReactorPool.h"
|
||||||
|
|
||||||
#include "framework/SubSystemServer.h"
|
#include "framework/SubSystemServer.h"
|
||||||
#include "framework/utils.h"
|
#include "framework/utils.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
constexpr uint MACHashMax = 256;
|
class AP_WS_RequestHandler : public Poco::Net::HTTPRequestHandler {
|
||||||
constexpr uint MACHashMask = MACHashMax-1;
|
|
||||||
class MACHash {
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] static inline uint16_t Hash(std::uint64_t value) {
|
explicit AP_WS_RequestHandler(Poco::Logger &L, uint64_t id) : Logger_(L), id_(id){};
|
||||||
uint8_t hash = 0, i=6;
|
|
||||||
while(i) {
|
|
||||||
hash ^= (value & MACHashMask) + 1;
|
|
||||||
value >>= 8;
|
|
||||||
--i;
|
|
||||||
}
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] static inline uint16_t Hash(const std::string & value) {
|
void handleRequest(Poco::Net::HTTPServerRequest &request,
|
||||||
return Hash(Utils::MACToInt(value));
|
Poco::Net::HTTPServerResponse &response) override;
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] static inline uint16_t HashMax() {
|
private:
|
||||||
return MACHashMax;
|
Poco::Logger &Logger_;
|
||||||
}
|
uint64_t id_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr uint SessionHashMax = 256;
|
class AP_WS_RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
|
||||||
constexpr uint SessionHashMask = SessionHashMax-1;
|
|
||||||
class SessionHash {
|
|
||||||
public:
|
public:
|
||||||
[[nodiscard]] static inline uint16_t Hash(std::uint64_t value) {
|
inline explicit AP_WS_RequestHandlerFactory(Poco::Logger &L) : Logger_(L) {}
|
||||||
return (value & SessionHashMask);
|
|
||||||
|
inline Poco::Net::HTTPRequestHandler *
|
||||||
|
createRequestHandler(const Poco::Net::HTTPServerRequest &request) override {
|
||||||
|
if (request.find("Upgrade") != request.end() &&
|
||||||
|
Poco::icompare(request["Upgrade"], "websocket") == 0) {
|
||||||
|
Utils::SetThreadName("ws:conn-init");
|
||||||
|
return new AP_WS_RequestHandler(Logger_, id_++);
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] static inline uint16_t HashMax() {
|
private:
|
||||||
return SessionHashMax;
|
Poco::Logger &Logger_;
|
||||||
}
|
inline static uint64_t id_ = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class AP_WS_Server : public SubSystemServer {
|
||||||
class AP_WS_Server : public SubSystemServer, public Poco::Runnable {
|
|
||||||
public:
|
public:
|
||||||
static auto instance() {
|
static auto instance() {
|
||||||
static auto instance_ = new AP_WS_Server;
|
static auto instance_ = new AP_WS_Server;
|
||||||
@@ -80,49 +75,59 @@ namespace OpenWifi {
|
|||||||
bool IsCertOk() { return IssuerCert_ != nullptr; }
|
bool IsCertOk() { return IssuerCert_ != nullptr; }
|
||||||
bool ValidateCertificate(const std::string &ConnectionId,
|
bool ValidateCertificate(const std::string &ConnectionId,
|
||||||
const Poco::Crypto::X509Certificate &Certificate);
|
const Poco::Crypto::X509Certificate &Certificate);
|
||||||
|
// Poco::Net::SocketReactor & GetNextReactor() { return ReactorPool_.NextReactor(); }
|
||||||
|
|
||||||
inline bool IsSimSerialNumber(const std::string &SerialNumber) const {
|
inline bool IsSimSerialNumber(const std::string &SerialNumber) const {
|
||||||
return IsSim(SerialNumber) &&
|
return IsSim(Poco::toLower(SerialNumber)) &&
|
||||||
SerialNumber == SimulatorId_;
|
Poco::toLower(SerialNumber) == Poco::toLower(SimulatorId_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static bool IsSim(const std::string &SerialNumber) {
|
inline static bool IsSim(const std::string &SerialNumber) {
|
||||||
return SerialNumber.substr(0, 6) == "53494d";
|
return SerialNumber.substr(0, 6) == "53494d";
|
||||||
}
|
}
|
||||||
|
|
||||||
void run() override; // Garbage collector thread.
|
inline bool IsSimEnabled() const { return SimulatorEnabled_; }
|
||||||
[[nodiscard]] inline bool IsSimEnabled() const { return SimulatorEnabled_; }
|
|
||||||
[[nodiscard]] inline bool AllowSerialNumberMismatch() const { return AllowSerialNumberMismatch_; }
|
inline bool AllowSerialNumberMismatch() const { return AllowSerialNumberMismatch_; }
|
||||||
[[nodiscard]] inline uint64_t MismatchDepth() const { return MismatchDepth_; }
|
|
||||||
[[nodiscard]] inline bool UseProvisioning() const { return LookAtProvisioning_; }
|
inline uint64_t MismatchDepth() const { return MismatchDepth_; }
|
||||||
[[nodiscard]] inline bool UseDefaults() const { return UseDefaultConfig_; }
|
|
||||||
[[nodiscard]] inline bool Running() const { return Running_; }
|
inline bool UseProvisioning() const { return LookAtProvisioning_; }
|
||||||
[[nodiscard]] inline std::pair<std::shared_ptr<Poco::Net::SocketReactor>, std::shared_ptr<LockedDbSession>> NextReactor() {
|
inline bool UseDefaults() const { return UseDefaultConfig_; }
|
||||||
|
|
||||||
|
[[nodiscard]] inline Poco::Net::SocketReactor &NextReactor() {
|
||||||
return Reactor_pool_->NextReactor();
|
return Reactor_pool_->NextReactor();
|
||||||
}
|
}
|
||||||
|
[[nodiscard]] inline bool Running() const { return Running_; }
|
||||||
|
|
||||||
inline void AddConnection(std::shared_ptr<AP_WS_Connection> Connection) {
|
inline void AddConnection(uint64_t session_id,
|
||||||
std::uint64_t sessionHash = SessionHash::Hash(Connection->State_.sessionId);
|
std::shared_ptr<AP_WS_Connection> Connection) {
|
||||||
std::lock_guard Lock(SessionMutex_[sessionHash]);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
if(Sessions_[sessionHash].find(Connection->State_.sessionId)==end(Sessions_[sessionHash])) {
|
Sessions_[session_id] = std::move(Connection);
|
||||||
Sessions_[sessionHash][Connection->State_.sessionId] = std::move(Connection);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] inline bool DeviceRequiresSecureRTTY(uint64_t serialNumber) const {
|
inline std::shared_ptr<AP_WS_Connection> FindConnection(uint64_t session_id) const {
|
||||||
auto hashIndex = MACHash::Hash(serialNumber);
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
std::lock_guard G(SerialNumbersMutex_[hashIndex]);
|
|
||||||
|
|
||||||
auto Connection = SerialNumbers_[hashIndex].find(serialNumber);
|
auto Connection = Sessions_.find(session_id);
|
||||||
if (Connection==end(SerialNumbers_[hashIndex]) || Connection->second==nullptr)
|
if (Connection != end(Sessions_))
|
||||||
|
return Connection->second;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool DeviceRequiresSecureRtty(uint64_t serialNumber) const {
|
||||||
|
std::lock_guard Lock(WSServerMutex_);
|
||||||
|
|
||||||
|
auto Connection = SerialNumbers_.find(serialNumber);
|
||||||
|
if (Connection==end(SerialNumbers_) || Connection->second.second==nullptr)
|
||||||
return false;
|
return false;
|
||||||
return Connection->second->RTTYMustBeSecure_;
|
return Connection->second.second->RttyMustBeSecure_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool GetStatistics(const std::string &SerialNumber, std::string &Statistics) const {
|
inline bool GetStatistics(const std::string &SerialNumber, std::string &Statistics) const {
|
||||||
return GetStatistics(Utils::SerialNumberToInt(SerialNumber), Statistics);
|
return GetStatistics(Utils::SerialNumberToInt(SerialNumber), Statistics);
|
||||||
}
|
}
|
||||||
[[nodiscard]] bool GetStatistics(uint64_t SerialNumber, std::string &Statistics) const;
|
bool GetStatistics(uint64_t SerialNumber, std::string &Statistics) const;
|
||||||
|
|
||||||
inline bool GetState(const std::string &SerialNumber,
|
inline bool GetState(const std::string &SerialNumber,
|
||||||
GWObjects::ConnectionState &State) const {
|
GWObjects::ConnectionState &State) const {
|
||||||
@@ -138,7 +143,13 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
bool Connected(uint64_t SerialNumber, GWObjects::DeviceRestrictions &Restrictions) const;
|
bool Connected(uint64_t SerialNumber, GWObjects::DeviceRestrictions &Restrictions) const;
|
||||||
bool Connected(uint64_t SerialNumber) const;
|
bool Connected(uint64_t SerialNumber) const;
|
||||||
|
|
||||||
|
inline bool SendFrame(const std::string &SerialNumber, const std::string &Payload) const {
|
||||||
|
return SendFrame(Utils::SerialNumberToInt(SerialNumber), Payload);
|
||||||
|
}
|
||||||
|
|
||||||
bool SendFrame(uint64_t SerialNumber, const std::string &Payload) const;
|
bool SendFrame(uint64_t SerialNumber, const std::string &Payload) const;
|
||||||
|
|
||||||
bool SendRadiusAuthenticationData(const std::string &SerialNumber,
|
bool SendRadiusAuthenticationData(const std::string &SerialNumber,
|
||||||
const unsigned char *buffer, std::size_t size);
|
const unsigned char *buffer, std::size_t size);
|
||||||
bool SendRadiusAccountingData(const std::string &SerialNumber, const unsigned char *buffer,
|
bool SendRadiusAccountingData(const std::string &SerialNumber, const unsigned char *buffer,
|
||||||
@@ -146,8 +157,9 @@ namespace OpenWifi {
|
|||||||
bool SendRadiusCoAData(const std::string &SerialNumber, const unsigned char *buffer,
|
bool SendRadiusCoAData(const std::string &SerialNumber, const unsigned char *buffer,
|
||||||
std::size_t size);
|
std::size_t size);
|
||||||
|
|
||||||
void StartSession(uint64_t session_id, uint64_t SerialNumber);
|
void SetSessionDetails(uint64_t connection_id, uint64_t SerialNumber);
|
||||||
bool EndSession(uint64_t session_id, uint64_t SerialNumber);
|
bool EndSession(uint64_t connection_id, uint64_t serial_number);
|
||||||
|
|
||||||
void SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber,
|
void SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber,
|
||||||
uint64_t Interval, uint64_t Lifetime,
|
uint64_t Interval, uint64_t Lifetime,
|
||||||
const std::vector<std::string> &TelemetryTypes);
|
const std::vector<std::string> &TelemetryTypes);
|
||||||
@@ -164,9 +176,7 @@ namespace OpenWifi {
|
|||||||
uint64_t &TelemetryWebSocketPackets,
|
uint64_t &TelemetryWebSocketPackets,
|
||||||
uint64_t &TelemetryKafkaPackets);
|
uint64_t &TelemetryKafkaPackets);
|
||||||
|
|
||||||
bool GetHealthDevices(std::uint64_t lowLimit, std::uint64_t highLimit, std::vector<std::string> & SerialNumbers);
|
void onGarbageCollecting(Poco::Timer &timer);
|
||||||
bool ExtendedAttributes(const std::string &serialNumber, bool & hasGPS, std::uint64_t &Sanity,
|
|
||||||
std::double_t &MemoryUsed, std::double_t &Load, std::double_t &Temperature);
|
|
||||||
|
|
||||||
inline void AverageDeviceStatistics(uint64_t &Connections, uint64_t &AverageConnectionTime,
|
inline void AverageDeviceStatistics(uint64_t &Connections, uint64_t &AverageConnectionTime,
|
||||||
uint64_t &NumberOfConnectingDevices) const {
|
uint64_t &NumberOfConnectingDevices) const {
|
||||||
@@ -175,59 +185,62 @@ namespace OpenWifi {
|
|||||||
NumberOfConnectingDevices = NumberOfConnectingDevices_;
|
NumberOfConnectingDevices = NumberOfConnectingDevices_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool SendFrame(const std::string &SerialNumber, const std::string &Payload) const {
|
|
||||||
return SendFrame(Utils::SerialNumberToInt(SerialNumber), Payload);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void AddRX(std::uint64_t bytes) {
|
inline void AddRX(std::uint64_t bytes) {
|
||||||
|
std::lock_guard G(StatsMutex_);
|
||||||
RX_ += bytes;
|
RX_ += bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void AddTX(std::uint64_t bytes) {
|
inline void AddTX(std::uint64_t bytes) {
|
||||||
|
std::lock_guard G(StatsMutex_);
|
||||||
TX_ += bytes;
|
TX_ += bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void GetTotalDataStatistics(std::uint64_t &TX, std::uint64_t &RX) const {
|
inline void GetTotalDataStatistics(std::uint64_t &TX, std::uint64_t &RX) const {
|
||||||
|
std::lock_guard G(StatsMutex_);
|
||||||
TX = TX_;
|
TX = TX_;
|
||||||
RX = RX_;
|
RX = RX_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool KafkaDisableState() const { return KafkaDisableState_; }
|
inline bool GetHealthDevices(std::uint64_t lowLimit, std::uint64_t highLimit, std::vector<std::string> & SerialNumbers) {
|
||||||
bool KafkaDisableHealthChecks() const { return KafkaDisableHealthChecks_; }
|
std::lock_guard G(WSServerMutex_);
|
||||||
|
|
||||||
|
for(const auto &connection:Sessions_) {
|
||||||
|
if( connection.second->RawLastHealthcheck_.Sanity>=lowLimit &&
|
||||||
|
connection.second->RawLastHealthcheck_.Sanity<=highLimit) {
|
||||||
|
SerialNumbers.push_back(connection.second->SerialNumber_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
std::array<std::mutex,SessionHashMax> SessionMutex_;
|
mutable std::recursive_mutex WSServerMutex_;
|
||||||
std::array<std::map<std::uint64_t, std::shared_ptr<AP_WS_Connection>>,SessionHashMax> Sessions_;
|
|
||||||
using SerialNumberMap = std::map<uint64_t /* serial number */,
|
|
||||||
std::shared_ptr<AP_WS_Connection>>;
|
|
||||||
std::array<SerialNumberMap,MACHashMax> SerialNumbers_;
|
|
||||||
mutable std::array<std::recursive_mutex,MACHashMax> SerialNumbersMutex_;
|
|
||||||
|
|
||||||
std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_;
|
std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_;
|
||||||
std::list<std::unique_ptr<Poco::Net::HTTPServer>> WebServers_;
|
std::list<std::unique_ptr<Poco::Net::HTTPServer>> WebServers_;
|
||||||
Poco::ThreadPool DeviceConnectionPool_{"ws:dev-pool", 4, 256};
|
|
||||||
Poco::Net::SocketReactor Reactor_;
|
Poco::Net::SocketReactor Reactor_;
|
||||||
Poco::Thread ReactorThread_;
|
Poco::Thread ReactorThread_;
|
||||||
std::string SimulatorId_;
|
std::string SimulatorId_;
|
||||||
|
Poco::ThreadPool DeviceConnectionPool_{"ws:dev-pool", 2, 64};
|
||||||
bool LookAtProvisioning_ = false;
|
bool LookAtProvisioning_ = false;
|
||||||
bool UseDefaultConfig_ = true;
|
bool UseDefaultConfig_ = true;
|
||||||
bool SimulatorEnabled_ = false;
|
bool SimulatorEnabled_ = false;
|
||||||
bool AllowSerialNumberMismatch_ = true;
|
|
||||||
|
|
||||||
std::unique_ptr<AP_WS_ReactorThreadPool> Reactor_pool_;
|
std::unique_ptr<AP_WS_ReactorThreadPool> Reactor_pool_;
|
||||||
std::atomic_bool Running_ = false;
|
std::atomic_bool Running_ = false;
|
||||||
|
std::map<std::uint64_t, std::shared_ptr<AP_WS_Connection>> Sessions_;
|
||||||
|
std::map<uint64_t, std::pair<uint64_t, std::shared_ptr<AP_WS_Connection>>> SerialNumbers_;
|
||||||
|
std::atomic_bool AllowSerialNumberMismatch_ = true;
|
||||||
|
std::atomic_uint64_t MismatchDepth_ = 2;
|
||||||
|
|
||||||
std::uint64_t MismatchDepth_ = 2;
|
std::atomic_uint64_t NumberOfConnectedDevices_ = 0;
|
||||||
std::uint64_t NumberOfConnectedDevices_ = 0;
|
std::atomic_uint64_t AverageDeviceConnectionTime_ = 0;
|
||||||
std::uint64_t AverageDeviceConnectionTime_ = 0;
|
std::atomic_uint64_t NumberOfConnectingDevices_ = 0;
|
||||||
std::uint64_t NumberOfConnectingDevices_ = 0;
|
|
||||||
std::uint64_t SessionTimeOut_ = 10*60;
|
mutable std::mutex StatsMutex_;
|
||||||
std::uint64_t LeftOverSessions_ = 0;
|
|
||||||
std::atomic_uint64_t TX_=0,RX_=0;
|
std::atomic_uint64_t TX_=0,RX_=0;
|
||||||
|
|
||||||
std::atomic_bool KafkaDisableState_=false,
|
std::vector<std::shared_ptr<AP_WS_Connection>> Garbage_;
|
||||||
KafkaDisableHealthChecks_=false;
|
|
||||||
|
|
||||||
|
std::unique_ptr<Poco::TimerCallback<AP_WS_Server>> GarbageCollectorCallback_;
|
||||||
|
Poco::Timer Timer_;
|
||||||
Poco::Thread GarbageCollector_;
|
Poco::Thread GarbageCollector_;
|
||||||
|
|
||||||
AP_WS_Server() noexcept
|
AP_WS_Server() noexcept
|
||||||
|
|||||||
@@ -45,9 +45,11 @@ namespace OpenWifi {
|
|||||||
std::lock_guard Lock(LocalMutex_);
|
std::lock_guard Lock(LocalMutex_);
|
||||||
auto RPC = OutStandingRequests_.find(ID);
|
auto RPC = OutStandingRequests_.find(ID);
|
||||||
if (RPC == OutStandingRequests_.end()) {
|
if (RPC == OutStandingRequests_.end()) {
|
||||||
|
// std::cout << __LINE__ << std::endl;
|
||||||
poco_debug(Logger(), fmt::format("({}): RPC {} cannot be found.",
|
poco_debug(Logger(), fmt::format("({}): RPC {} cannot be found.",
|
||||||
SerialNumberStr, ID));
|
SerialNumberStr, ID));
|
||||||
} else if (RPC->second.SerialNumber != Resp->SerialNumber_) {
|
} else if (RPC->second.SerialNumber != Resp->SerialNumber_) {
|
||||||
|
// std::cout << __LINE__ << std::endl;
|
||||||
poco_debug(
|
poco_debug(
|
||||||
Logger(),
|
Logger(),
|
||||||
fmt::format("({}): RPC {} serial number mismatch {}!={}.",
|
fmt::format("({}): RPC {} serial number mismatch {}!={}.",
|
||||||
@@ -58,6 +60,7 @@ namespace OpenWifi {
|
|||||||
std::chrono::duration<double, std::milli> rpc_execution_time =
|
std::chrono::duration<double, std::milli> rpc_execution_time =
|
||||||
std::chrono::high_resolution_clock::now() -
|
std::chrono::high_resolution_clock::now() -
|
||||||
RPC->second.submitted;
|
RPC->second.submitted;
|
||||||
|
// std::cout << __LINE__ << std::endl;
|
||||||
poco_debug(Logger(),
|
poco_debug(Logger(),
|
||||||
fmt::format("({}): Received RPC answer {}. Command={}",
|
fmt::format("({}): Received RPC answer {}. Command={}",
|
||||||
SerialNumberStr, ID,
|
SerialNumberStr, ID,
|
||||||
@@ -137,6 +140,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// std::cout << __LINE__ << std::endl;
|
||||||
}
|
}
|
||||||
Command.State = 0;
|
Command.State = 0;
|
||||||
|
|
||||||
@@ -159,6 +163,7 @@ namespace OpenWifi {
|
|||||||
if (Command.rpc_entry) {
|
if (Command.rpc_entry) {
|
||||||
TmpRpcEntry = Command.rpc_entry;
|
TmpRpcEntry = Command.rpc_entry;
|
||||||
}
|
}
|
||||||
|
// std::cout << __LINE__ << " State=" << Command.State << std::endl;
|
||||||
if (Command.State == 2) {
|
if (Command.State == 2) {
|
||||||
// look at the payload to see if we should continue or not...
|
// look at the payload to see if we should continue or not...
|
||||||
if (Payload->has("result")) {
|
if (Payload->has("result")) {
|
||||||
@@ -168,10 +173,12 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
std::uint64_t Error = Status->get("error");
|
std::uint64_t Error = Status->get("error");
|
||||||
if (Error == 0) {
|
if (Error == 0) {
|
||||||
|
// std::cout << __LINE__ << std::endl;
|
||||||
StorageService()->CommandCompleted(Command.UUID, Payload,
|
StorageService()->CommandCompleted(Command.UUID, Payload,
|
||||||
rpc_execution_time, true);
|
rpc_execution_time, true);
|
||||||
Command.State = 1;
|
Command.State = 1;
|
||||||
} else {
|
} else {
|
||||||
|
// std::cout << __LINE__ << std::endl;
|
||||||
StorageService()->CommandCompleted(Command.UUID, Payload,
|
StorageService()->CommandCompleted(Command.UUID, Payload,
|
||||||
rpc_execution_time, true);
|
rpc_execution_time, true);
|
||||||
std::string ErrorTxt = Status->get("result");
|
std::string ErrorTxt = Status->get("result");
|
||||||
@@ -179,11 +186,14 @@ namespace OpenWifi {
|
|||||||
Command.State = 0;
|
Command.State = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// std::cout << __LINE__ << std::endl;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// std::cout << __LINE__ << std::endl;
|
||||||
Command.State = 0;
|
Command.State = 0;
|
||||||
}
|
}
|
||||||
} else if (Command.State == 1) {
|
} else if (Command.State == 1) {
|
||||||
|
// std::cout << "Completing script 2 phase commit." << std::endl;
|
||||||
StorageService()->CommandCompleted(Command.UUID, Payload, rpc_execution_time, true);
|
StorageService()->CommandCompleted(Command.UUID, Payload, rpc_execution_time, true);
|
||||||
if (Command.Deferred) {
|
if (Command.Deferred) {
|
||||||
Reply = false;
|
Reply = false;
|
||||||
@@ -192,6 +202,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (Command.State == 0) {
|
if (Command.State == 0) {
|
||||||
|
// std::cout << __LINE__ << " State=" << Command.State << std::endl;
|
||||||
OutStandingRequests_.erase(Command.Id);
|
OutStandingRequests_.erase(Command.Id);
|
||||||
}
|
}
|
||||||
if (Reply && TmpRpcEntry != nullptr)
|
if (Reply && TmpRpcEntry != nullptr)
|
||||||
@@ -251,6 +262,8 @@ namespace OpenWifi {
|
|||||||
for (auto request = OutStandingRequests_.begin(); request != OutStandingRequests_.end();) {
|
for (auto request = OutStandingRequests_.begin(); request != OutStandingRequests_.end();) {
|
||||||
std::chrono::duration<double, std::milli> delta = now - request->second.submitted;
|
std::chrono::duration<double, std::milli> delta = now - request->second.submitted;
|
||||||
if (delta > 10min) {
|
if (delta > 10min) {
|
||||||
|
// std::cout << __LINE__ << " -->> " << request->second.Id <<
|
||||||
|
// std::endl;
|
||||||
MyLogger.debug(fmt::format("{}: Command={} for {} Timed out.", request->second.UUID,
|
MyLogger.debug(fmt::format("{}: Command={} for {} Timed out.", request->second.UUID,
|
||||||
APCommands::to_string(request->second.Command),
|
APCommands::to_string(request->second.Command),
|
||||||
Utils::IntToSerialNumber(request->second.SerialNumber)));
|
Utils::IntToSerialNumber(request->second.SerialNumber)));
|
||||||
@@ -262,6 +275,8 @@ namespace OpenWifi {
|
|||||||
StorageService()->SetCommandTimedOut(request->second.UUID);
|
StorageService()->SetCommandTimedOut(request->second.UUID);
|
||||||
request = OutStandingRequests_.erase(request);
|
request = OutStandingRequests_.erase(request);
|
||||||
} else {
|
} else {
|
||||||
|
// std::cout << __LINE__ << " -->> " << request->second.Id <<
|
||||||
|
// std::endl;
|
||||||
++request;
|
++request;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -287,21 +302,13 @@ namespace OpenWifi {
|
|||||||
StorageService()->RemovedExpiredCommands();
|
StorageService()->RemovedExpiredCommands();
|
||||||
StorageService()->RemoveTimedOutCommands();
|
StorageService()->RemoveTimedOutCommands();
|
||||||
|
|
||||||
std::uint64_t offset = 0;
|
|
||||||
bool Done = false;
|
|
||||||
while (!Done) {
|
|
||||||
std::vector<GWObjects::CommandDetails> Commands;
|
std::vector<GWObjects::CommandDetails> Commands;
|
||||||
if (StorageService()->GetReadyToExecuteCommands(offset, 200, Commands)) {
|
if (StorageService()->GetReadyToExecuteCommands(0, 200, Commands)) {
|
||||||
if(Commands.empty()) {
|
poco_trace(MyLogger,
|
||||||
Done=true;
|
fmt::format("Scheduler about to process {} commands.", Commands.size()));
|
||||||
continue;
|
|
||||||
}
|
|
||||||
poco_trace(MyLogger, fmt::format("Scheduler about to process {} commands.",
|
|
||||||
Commands.size()));
|
|
||||||
for (auto &Cmd : Commands) {
|
for (auto &Cmd : Commands) {
|
||||||
if (!Running_) {
|
if (!Running_) {
|
||||||
poco_warning(MyLogger,
|
poco_warning(MyLogger, "Scheduler quitting because service is stopping.");
|
||||||
"Scheduler quitting because service is stopping.");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
poco_trace(MyLogger,
|
poco_trace(MyLogger,
|
||||||
@@ -317,8 +324,8 @@ namespace OpenWifi {
|
|||||||
auto now = Utils::Now();
|
auto now = Utils::Now();
|
||||||
// 2 hour timeout for commands
|
// 2 hour timeout for commands
|
||||||
if ((now - Cmd.Submitted) > commandTimeOut_) {
|
if ((now - Cmd.Submitted) > commandTimeOut_) {
|
||||||
poco_information(
|
poco_information(MyLogger,
|
||||||
MyLogger, fmt::format("{}: Serial={} Command={} has expired.",
|
fmt::format("{}: Serial={} Command={} has expired.",
|
||||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||||
StorageService()->SetCommandTimedOut(Cmd.UUID);
|
StorageService()->SetCommandTimedOut(Cmd.UUID);
|
||||||
continue;
|
continue;
|
||||||
@@ -342,8 +349,7 @@ namespace OpenWifi {
|
|||||||
MyLogger,
|
MyLogger,
|
||||||
fmt::format("{}: Serial={} Command={} Device is already busy "
|
fmt::format("{}: Serial={} Command={} Device is already busy "
|
||||||
"with command {} (Command={}).",
|
"with command {} (Command={}).",
|
||||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command,
|
Cmd.UUID, Cmd.SerialNumber, Cmd.Command, ExecutingUUID,
|
||||||
ExecutingUUID,
|
|
||||||
APCommands::to_string(ExecutingCommand)));
|
APCommands::to_string(ExecutingCommand)));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -351,8 +357,7 @@ namespace OpenWifi {
|
|||||||
Poco::JSON::Parser P;
|
Poco::JSON::Parser P;
|
||||||
bool Sent;
|
bool Sent;
|
||||||
poco_information(
|
poco_information(
|
||||||
MyLogger,
|
MyLogger, fmt::format("{}: Serial={} Command={} Preparing execution.",
|
||||||
fmt::format("{}: Serial={} Command={} Preparing execution.",
|
|
||||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||||
auto Params = P.parse(Cmd.Details).extract<Poco::JSON::Object::Ptr>();
|
auto Params = P.parse(Cmd.Details).extract<Poco::JSON::Object::Ptr>();
|
||||||
auto Result = PostCommandDisk(
|
auto Result = PostCommandDisk(
|
||||||
@@ -364,8 +369,7 @@ namespace OpenWifi {
|
|||||||
fmt::format("{}: Serial={} Command={} Sent.", Cmd.UUID,
|
fmt::format("{}: Serial={} Command={} Sent.", Cmd.UUID,
|
||||||
Cmd.SerialNumber, Cmd.Command));
|
Cmd.SerialNumber, Cmd.Command));
|
||||||
} else {
|
} else {
|
||||||
poco_debug(
|
poco_debug(MyLogger,
|
||||||
MyLogger,
|
|
||||||
fmt::format("{}: Serial={} Command={} Re-queued command.",
|
fmt::format("{}: Serial={} Command={} Re-queued command.",
|
||||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||||
StorageService()->SetCommandLastTry(Cmd.UUID);
|
StorageService()->SetCommandLastTry(Cmd.UUID);
|
||||||
@@ -379,24 +383,16 @@ namespace OpenWifi {
|
|||||||
MyLogger.log(E);
|
MyLogger.log(E);
|
||||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_debug(MyLogger,
|
poco_debug(MyLogger, fmt::format("{}: Serial={} Command={} Hard failure. "
|
||||||
fmt::format("{}: Serial={} Command={} Hard failure. "
|
|
||||||
"Command marked as completed.",
|
"Command marked as completed.",
|
||||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
offset += Commands.size();
|
|
||||||
} else {
|
|
||||||
Done=true;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
} catch (Poco::Exception &E) {
|
||||||
}
|
|
||||||
catch (Poco::Exception &E) {
|
|
||||||
MyLogger.log(E);
|
MyLogger.log(E);
|
||||||
}
|
} catch (...) {
|
||||||
catch (...) {
|
|
||||||
poco_warning(MyLogger, "Exception during command processing.");
|
poco_warning(MyLogger, "Exception during command processing.");
|
||||||
}
|
}
|
||||||
poco_trace(MyLogger, "Scheduler done.");
|
poco_trace(MyLogger, "Scheduler done.");
|
||||||
@@ -452,16 +448,4 @@ namespace OpenWifi {
|
|||||||
poco_warning(Logger(), fmt::format("{}: Failed to send command. ID: {}", UUID, RPC_ID));
|
poco_warning(Logger(), fmt::format("{}: Failed to send command. ID: {}", UUID, RPC_ID));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CommandManager::FireAndForget(const std::string &SerialNumber, const std::string &Method, const Poco::JSON::Object &Params) {
|
|
||||||
Poco::JSON::Object CompleteRPC;
|
|
||||||
CompleteRPC.set(uCentralProtocol::JSONRPC, uCentralProtocol::JSONRPC_VERSION);
|
|
||||||
CompleteRPC.set(uCentralProtocol::ID, 0);
|
|
||||||
CompleteRPC.set(uCentralProtocol::METHOD, Method);
|
|
||||||
CompleteRPC.set(uCentralProtocol::PARAMS, Params);
|
|
||||||
std::stringstream ToSend;
|
|
||||||
CompleteRPC.stringify(ToSend);
|
|
||||||
poco_debug(Logger(), fmt::format("{}: Fire and forget command {}.", SerialNumber, Method));
|
|
||||||
return AP_WS_Server()->SendFrame(SerialNumber, ToSend.str())>0;
|
|
||||||
}
|
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <future>
|
#include <future>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <mutex>
|
#include <shared_mutex>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "Poco/JSON/Object.h"
|
#include "Poco/JSON/Object.h"
|
||||||
@@ -162,10 +162,8 @@ namespace OpenWifi {
|
|||||||
inline auto CommandTimeout() const { return commandTimeOut_; }
|
inline auto CommandTimeout() const { return commandTimeOut_; }
|
||||||
inline auto CommandRetry() const { return commandRetry_; }
|
inline auto CommandRetry() const { return commandRetry_; }
|
||||||
|
|
||||||
bool FireAndForget(const std::string &SerialNumber, const std::string &Method,
|
|
||||||
const Poco::JSON::Object &Params);
|
|
||||||
private:
|
private:
|
||||||
mutable std::mutex LocalMutex_;
|
mutable std::recursive_mutex LocalMutex_;
|
||||||
std::atomic_bool Running_ = false;
|
std::atomic_bool Running_ = false;
|
||||||
Poco::Thread ManagerThread;
|
Poco::Thread ManagerThread;
|
||||||
std::atomic_uint64_t Id_ = 3; // do not start @1. We ignore ID=1 & 0 is illegal..
|
std::atomic_uint64_t Id_ = 3; // do not start @1. We ignore ID=1 & 0 is illegal..
|
||||||
|
|||||||
@@ -11,17 +11,12 @@
|
|||||||
#include "Poco/Util/Application.h"
|
#include "Poco/Util/Application.h"
|
||||||
#include "Poco/Util/Option.h"
|
#include "Poco/Util/Option.h"
|
||||||
|
|
||||||
#include <framework/ConfigurationValidator.h>
|
|
||||||
#include <framework/UI_WebSocketClientServer.h>
|
|
||||||
#include <framework/default_device_types.h>
|
|
||||||
|
|
||||||
#include "AP_WS_Server.h"
|
#include "AP_WS_Server.h"
|
||||||
#include "CommandManager.h"
|
#include "CommandManager.h"
|
||||||
#include "Daemon.h"
|
#include "Daemon.h"
|
||||||
#include "FileUploader.h"
|
#include "FileUploader.h"
|
||||||
#include "FindCountry.h"
|
#include "FindCountry.h"
|
||||||
#include "OUIServer.h"
|
#include "OUIServer.h"
|
||||||
#include "RADIUSSessionTracker.h"
|
|
||||||
#include "RADIUS_proxy_server.h"
|
#include "RADIUS_proxy_server.h"
|
||||||
#include "RegulatoryInfo.h"
|
#include "RegulatoryInfo.h"
|
||||||
#include "ScriptManager.h"
|
#include "ScriptManager.h"
|
||||||
@@ -30,47 +25,64 @@
|
|||||||
#include "StorageArchiver.h"
|
#include "StorageArchiver.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "TelemetryStream.h"
|
#include "TelemetryStream.h"
|
||||||
#include "GenericScheduler.h"
|
|
||||||
#include "UI_GW_WebSocketNotifications.h"
|
#include "UI_GW_WebSocketNotifications.h"
|
||||||
#include "VenueBroadcaster.h"
|
#include "VenueBroadcaster.h"
|
||||||
#include "AP_WS_ConfigAutoUpgrader.h"
|
#include "framework/ConfigurationValidator.h"
|
||||||
|
#include "framework/UI_WebSocketClientServer.h"
|
||||||
#include "rttys/RTTYS_server.h"
|
#include "rttys/RTTYS_server.h"
|
||||||
#include "firmware_revision_cache.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
class Daemon *Daemon::instance() {
|
class Daemon *Daemon::instance() {
|
||||||
static Daemon instance(
|
static Daemon instance(
|
||||||
vDAEMON_PROPERTIES_FILENAME, vDAEMON_ROOT_ENV_VAR, vDAEMON_CONFIG_ENV_VAR,
|
vDAEMON_PROPERTIES_FILENAME, vDAEMON_ROOT_ENV_VAR, vDAEMON_CONFIG_ENV_VAR,
|
||||||
vDAEMON_APP_NAME, vDAEMON_BUS_TIMER,
|
vDAEMON_APP_NAME, vDAEMON_BUS_TIMER,
|
||||||
SubSystemVec{GenericScheduler(), StorageService(), SerialNumberCache(), ConfigurationValidator(),
|
SubSystemVec{StorageService(), SerialNumberCache(), ConfigurationValidator(),
|
||||||
UI_WebSocketClientServer(), OUIServer(), FindCountryFromIP(),
|
UI_WebSocketClientServer(), OUIServer(), FindCountryFromIP(),
|
||||||
CommandManager(), FileUploader(), StorageArchiver(), TelemetryStream(),
|
CommandManager(), FileUploader(), StorageArchiver(), TelemetryStream(),
|
||||||
RTTYS_server(), RADIUS_proxy_server(), VenueBroadcaster(), ScriptManager(),
|
RTTYS_server(), RADIUS_proxy_server(), VenueBroadcaster(), ScriptManager(),
|
||||||
SignatureManager(), AP_WS_Server(),
|
SignatureManager(), AP_WS_Server(),
|
||||||
RegulatoryInfo(),
|
RegulatoryInfo()
|
||||||
RADIUSSessionTracker(),
|
|
||||||
AP_WS_ConfigAutoUpgrader(),
|
|
||||||
FirmwareRevisionCache()
|
|
||||||
});
|
});
|
||||||
return &instance;
|
return &instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string ALBHealthCallback() {
|
static const std::vector<std::pair<std::string, std::string>> DefaultDeviceTypes{
|
||||||
uint64_t Connections, AverageConnectionTime, NumberOfConnectingDevices;
|
{"cig_wf160d", "AP"},
|
||||||
AP_WS_Server()->AverageDeviceStatistics(Connections, AverageConnectionTime,
|
{"cig_wf188", "AP"},
|
||||||
NumberOfConnectingDevices);
|
{"cig_wf188n", "AP"},
|
||||||
std::ostringstream os;
|
{"cig_wf194c", "AP"},
|
||||||
os << "Connections: " << Connections << std::endl <<
|
{"cig_wf194c4", "AP"},
|
||||||
"ConnectingDevices: " << NumberOfConnectingDevices << std::endl <<
|
{"edgecore_eap101", "AP"},
|
||||||
"ConnectionTime: " << AverageConnectionTime << std::endl;
|
{"edgecore_eap102", "AP"},
|
||||||
return os.str();
|
{"edgecore_ecs4100-12ph", "AP"},
|
||||||
}
|
{"edgecore_ecw5211", "AP"},
|
||||||
|
{"edgecore_ecw5410", "AP"},
|
||||||
|
{"edgecore_oap100", "AP"},
|
||||||
|
{"edgecore_spw2ac1200", "SWITCH"},
|
||||||
|
{"edgecore_spw2ac1200-lan-poe", "SWITCH"},
|
||||||
|
{"edgecore_ssw2ac2600", "SWITCH"},
|
||||||
|
{"hfcl_ion4", "AP"},
|
||||||
|
{"indio_um-305ac", "AP"},
|
||||||
|
{"linksys_e8450-ubi", "AP"},
|
||||||
|
{"linksys_ea6350", "AP"},
|
||||||
|
{"linksys_ea6350-v4", "AP"},
|
||||||
|
{"linksys_ea8300", "AP"},
|
||||||
|
{"mikrotik_nand", "AP"},
|
||||||
|
{"tp-link_ec420-g1", "AP"},
|
||||||
|
{"tplink_cpe210_v3", "AP"},
|
||||||
|
{"tplink_cpe510_v3", "AP"},
|
||||||
|
{"tplink_eap225_outdoor_v1", "AP"},
|
||||||
|
{"tplink_ec420", "AP"},
|
||||||
|
{"tplink_ex227", "AP"},
|
||||||
|
{"tplink_ex228", "AP"},
|
||||||
|
{"tplink_ex447", "AP"},
|
||||||
|
{"wallys_dr40x9", "AP"}};
|
||||||
|
|
||||||
void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) {
|
void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) {
|
||||||
AutoProvisioning_ = config().getBool("openwifi.autoprovisioning", false);
|
AutoProvisioning_ = config().getBool("openwifi.autoprovisioning", false);
|
||||||
DeviceTypes_ = DefaultDeviceTypeList;
|
DeviceTypes_ = DefaultDeviceTypes;
|
||||||
|
|
||||||
WebSocketProcessor_ = std::make_unique<GwWebSocketClient>(logger());
|
WebSocketProcessor_ = std::make_unique<GwWebSocketClient>(logger());
|
||||||
MicroServiceALBCallback(ALBHealthCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::string Daemon::IdentifyDevice(const std::string &Id) const {
|
[[nodiscard]] std::string Daemon::IdentifyDevice(const std::string &Id) const {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
void DeviceDashboard::Generate(GWObjects::Dashboard &D, Poco::Logger &Logger) {
|
void DeviceDashboard::Generate(GWObjects::Dashboard &D, Poco::Logger &Logger) {
|
||||||
if (GeneratingDashboard_.load()) {
|
if (GeneratingDashboard_.load()) {
|
||||||
|
// std::cout << "Trying to generate dashboard but already being generated" << std::endl;
|
||||||
while (GeneratingDashboard_.load()) {
|
while (GeneratingDashboard_.load()) {
|
||||||
Poco::Thread::trySleep(100);
|
Poco::Thread::trySleep(100);
|
||||||
}
|
}
|
||||||
@@ -30,6 +31,7 @@ namespace OpenWifi {
|
|||||||
GeneratingDashboard_ = true;
|
GeneratingDashboard_ = true;
|
||||||
ValidDashboard_ = false;
|
ValidDashboard_ = false;
|
||||||
try {
|
try {
|
||||||
|
// std::cout << "Generating dashboard." << std::endl;
|
||||||
poco_information(Logger, "DASHBOARD: Generating a new dashboard.");
|
poco_information(Logger, "DASHBOARD: Generating a new dashboard.");
|
||||||
GWObjects::Dashboard NewData;
|
GWObjects::Dashboard NewData;
|
||||||
StorageService()->AnalyzeCommands(NewData.commands);
|
StorageService()->AnalyzeCommands(NewData.commands);
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ namespace OpenWifi {
|
|||||||
Event.set("type", type_);
|
Event.set("type", type_);
|
||||||
Event.set("timestamp", timestamp_);
|
Event.set("timestamp", timestamp_);
|
||||||
Event.set("payload", payload_);
|
Event.set("payload", payload_);
|
||||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, Utils::IntToSerialNumber(serialNumber_), Event);
|
std::ostringstream OS;
|
||||||
|
Event.stringify(OS);
|
||||||
|
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, serialNumber_, OS.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,26 +4,23 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <Poco/JSON/Object.h>
|
#include <Poco/JSON/Object.h>
|
||||||
#include <RESTObjects/RESTAPI_GWobjects.h>
|
|
||||||
#include <framework/KafkaManager.h>
|
#include <framework/KafkaManager.h>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
class GWKafkaEvents {
|
class GWKafkaEvents {
|
||||||
public:
|
public:
|
||||||
GWKafkaEvents(std::uint64_t serialNumber, const std::string &type,
|
GWKafkaEvents(const std::string &serialNumber, const std::string &type,
|
||||||
std::uint64_t timestamp)
|
std::uint64_t timestamp)
|
||||||
: serialNumber_(serialNumber), type_(type), timestamp_(timestamp) {
|
: serialNumber_(serialNumber), type_(type), timestamp_(timestamp) {}
|
||||||
payload_ = Poco::SharedPtr<Poco::JSON::Object>(new Poco::JSON::Object);
|
|
||||||
}
|
|
||||||
void Send();
|
|
||||||
[[nodiscard]] inline std::uint64_t Serial() const { return serialNumber_;};
|
|
||||||
|
|
||||||
protected:
|
inline void SetPayload(Poco::JSON::Object::Ptr payload) { payload_ = std::move(payload); }
|
||||||
std::uint64_t serialNumber_;
|
void Send();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string serialNumber_;
|
||||||
std::string type_;
|
std::string type_;
|
||||||
std::uint64_t timestamp_ = 0;
|
std::uint64_t timestamp_ = 0;
|
||||||
Poco::JSON::Object::Ptr payload_;
|
Poco::JSON::Object::Ptr payload_;
|
||||||
@@ -31,15 +28,17 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
class DeviceFirmwareChangeKafkaEvent : public GWKafkaEvents {
|
class DeviceFirmwareChangeKafkaEvent : public GWKafkaEvents {
|
||||||
public:
|
public:
|
||||||
DeviceFirmwareChangeKafkaEvent(std::uint64_t serialNumber, std::uint64_t timestamp,
|
DeviceFirmwareChangeKafkaEvent(const std::string &serialNumber, std::uint64_t timestamp,
|
||||||
const std::string &oldFirmware,
|
const std::string &oldFirmware,
|
||||||
const std::string &newFirmware)
|
const std::string &newFirmware)
|
||||||
: GWKafkaEvents(serialNumber, "unit.firmware_change", timestamp),
|
: GWKafkaEvents(serialNumber, "unit.firmware_change", timestamp),
|
||||||
oldFirmware_(oldFirmware), newFirmware_(newFirmware) {}
|
oldFirmware_(oldFirmware), newFirmware_(newFirmware) {}
|
||||||
|
|
||||||
~DeviceFirmwareChangeKafkaEvent() {
|
~DeviceFirmwareChangeKafkaEvent() {
|
||||||
payload_->set("oldFirmware", oldFirmware_);
|
Poco::JSON::Object::Ptr payload = new Poco::JSON::Object;
|
||||||
payload_->set("newFirmware", newFirmware_);
|
payload->set("oldFirmware", oldFirmware_);
|
||||||
|
payload->set("newFirmware", newFirmware_);
|
||||||
|
SetPayload(payload);
|
||||||
Send();
|
Send();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,23 +48,25 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
class DeviceConfigurationChangeKafkaEvent : public GWKafkaEvents {
|
class DeviceConfigurationChangeKafkaEvent : public GWKafkaEvents {
|
||||||
public:
|
public:
|
||||||
DeviceConfigurationChangeKafkaEvent(std::uint64_t serialNumber,
|
DeviceConfigurationChangeKafkaEvent(const std::string &serialNumber,
|
||||||
std::uint64_t timestamp, const Poco::JSON::Object::Ptr config)
|
std::uint64_t timestamp, const std::string config)
|
||||||
: GWKafkaEvents(serialNumber, "unit.configuration_change", timestamp), config_(config) {
|
: GWKafkaEvents(serialNumber, "unit.configuration_change", timestamp), config_(config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
~DeviceConfigurationChangeKafkaEvent() {
|
~DeviceConfigurationChangeKafkaEvent() {
|
||||||
payload_->set("configuration", *config_);
|
Poco::JSON::Object::Ptr payload = new Poco::JSON::Object;
|
||||||
|
payload->set("configuration", config_);
|
||||||
|
SetPayload(payload);
|
||||||
Send();
|
Send();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Poco::JSON::Object::Ptr config_;
|
std::string config_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DeviceBlacklistedKafkaEvent : public GWKafkaEvents {
|
class DeviceBlacklistedKafkaEvent : public GWKafkaEvents {
|
||||||
public:
|
public:
|
||||||
explicit DeviceBlacklistedKafkaEvent(std::uint64_t serialNumber,
|
explicit DeviceBlacklistedKafkaEvent(const std::string &serialNumber,
|
||||||
std::uint64_t timestamp, const std::string &reason,
|
std::uint64_t timestamp, const std::string &reason,
|
||||||
const std::string &author, std::uint64_t created,
|
const std::string &author, std::uint64_t created,
|
||||||
std::string &IP)
|
std::string &IP)
|
||||||
@@ -73,10 +74,12 @@ namespace OpenWifi {
|
|||||||
author_(author), created_(created), IP_(IP) {}
|
author_(author), created_(created), IP_(IP) {}
|
||||||
|
|
||||||
~DeviceBlacklistedKafkaEvent() {
|
~DeviceBlacklistedKafkaEvent() {
|
||||||
payload_->set("reason", reason_);
|
Poco::JSON::Object::Ptr payload = new Poco::JSON::Object;
|
||||||
payload_->set("author", author_);
|
payload->set("reason", reason_);
|
||||||
payload_->set("created", created_);
|
payload->set("author", author_);
|
||||||
payload_->set("ipaddress", IP_);
|
payload->set("created", created_);
|
||||||
|
payload->set("ipaddress", IP_);
|
||||||
|
SetPayload(payload);
|
||||||
Send();
|
Send();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,21 +89,4 @@ namespace OpenWifi {
|
|||||||
std::string IP_;
|
std::string IP_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DeviceLogKafkaEvent : public GWKafkaEvents {
|
|
||||||
public:
|
|
||||||
explicit DeviceLogKafkaEvent( const GWObjects::DeviceLog &L)
|
|
||||||
: GWKafkaEvents(Utils::MACToInt(L.SerialNumber), "device_log", L.Recorded),
|
|
||||||
DL_(L)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~DeviceLogKafkaEvent() {
|
|
||||||
DL_.to_json(*payload_);
|
|
||||||
Send();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
GWObjects::DeviceLog DL_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2023-04-19.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "GenericScheduler.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
|
|
||||||
int GenericScheduler::Start() {
|
|
||||||
poco_information(Logger(),"Starting...");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenericScheduler::Stop() {
|
|
||||||
poco_information(Logger(),"Stopping...");
|
|
||||||
poco_information(Logger(),"Stopped...");
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2023-04-19.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <framework/SubSystemServer.h>
|
|
||||||
#include <libs/Scheduler.h>
|
|
||||||
#include <Poco/Environment.h>
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
|
|
||||||
class GenericScheduler : public SubSystemServer {
|
|
||||||
public:
|
|
||||||
|
|
||||||
static auto instance() {
|
|
||||||
static auto instance_ = new GenericScheduler;
|
|
||||||
return instance_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Start() override;
|
|
||||||
void Stop() override;
|
|
||||||
|
|
||||||
auto & Scheduler() { return Scheduler_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
GenericScheduler() noexcept
|
|
||||||
: SubSystemServer("Scheduler", "SCHEDULER", "scheduler"),
|
|
||||||
Scheduler_(Poco::Environment::processorCount()*2) {
|
|
||||||
|
|
||||||
}
|
|
||||||
Bosma::Scheduler Scheduler_;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline auto GenericScheduler() { return GenericScheduler::instance(); }
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
|
||||||
@@ -28,7 +28,7 @@ namespace OpenWifi {
|
|||||||
bool Recovered = false;
|
bool Recovered = false;
|
||||||
Poco::File OuiFile(CurrentOUIFileName_);
|
Poco::File OuiFile(CurrentOUIFileName_);
|
||||||
if (OuiFile.exists()) {
|
if (OuiFile.exists()) {
|
||||||
std::lock_guard Lock(LocalMutex_);
|
std::unique_lock Lock(LocalMutex_);
|
||||||
Recovered = ProcessFile(CurrentOUIFileName_, OUIs_);
|
Recovered = ProcessFile(CurrentOUIFileName_, OUIs_);
|
||||||
if (Recovered) {
|
if (Recovered) {
|
||||||
poco_notice(Logger(),
|
poco_notice(Logger(),
|
||||||
@@ -150,7 +150,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
OUIMap TmpOUIs;
|
OUIMap TmpOUIs;
|
||||||
if (GetFile(LatestOUIFileName_) && ProcessFile(LatestOUIFileName_, TmpOUIs)) {
|
if (GetFile(LatestOUIFileName_) && ProcessFile(LatestOUIFileName_, TmpOUIs)) {
|
||||||
std::lock_guard G(LocalMutex_);
|
std::unique_lock G(LocalMutex_);
|
||||||
OUIs_ = std::move(TmpOUIs);
|
OUIs_ = std::move(TmpOUIs);
|
||||||
LastUpdate_ = Utils::Now();
|
LastUpdate_ = Utils::Now();
|
||||||
Poco::File F1(CurrentOUIFileName_);
|
Poco::File F1(CurrentOUIFileName_);
|
||||||
@@ -163,7 +163,7 @@ namespace OpenWifi {
|
|||||||
} else if (OUIs_.empty()) {
|
} else if (OUIs_.empty()) {
|
||||||
if (ProcessFile(CurrentOUIFileName_, TmpOUIs)) {
|
if (ProcessFile(CurrentOUIFileName_, TmpOUIs)) {
|
||||||
LastUpdate_ = Utils::Now();
|
LastUpdate_ = Utils::Now();
|
||||||
std::lock_guard G(LocalMutex_);
|
std::unique_lock G(LocalMutex_);
|
||||||
OUIs_ = std::move(TmpOUIs);
|
OUIs_ = std::move(TmpOUIs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -173,7 +173,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string OUIServer::GetManufacturer(const std::string &MAC) {
|
std::string OUIServer::GetManufacturer(const std::string &MAC) {
|
||||||
std::lock_guard Lock(LocalMutex_);
|
std::shared_lock Lock(LocalMutex_);
|
||||||
|
|
||||||
auto Manufacturer = OUIs_.find(Utils::SerialNumberToOUI(MAC));
|
auto Manufacturer = OUIs_.find(Utils::SerialNumberToOUI(MAC));
|
||||||
if (Manufacturer != OUIs_.end())
|
if (Manufacturer != OUIs_.end())
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <mutex>
|
#include <shared_mutex>
|
||||||
|
|
||||||
#include "framework/SubSystemServer.h"
|
#include "framework/SubSystemServer.h"
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ namespace OpenWifi {
|
|||||||
[[nodiscard]] bool ProcessFile(const std::string &FileName, OUIMap &Map);
|
[[nodiscard]] bool ProcessFile(const std::string &FileName, OUIMap &Map);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex LocalMutex_;
|
std::shared_mutex LocalMutex_;
|
||||||
uint64_t LastUpdate_ = 0;
|
uint64_t LastUpdate_ = 0;
|
||||||
bool Initialized_ = false;
|
bool Initialized_ = false;
|
||||||
OUIMap OUIs_;
|
OUIMap OUIs_;
|
||||||
|
|||||||
@@ -1753,6 +1753,7 @@ namespace OpenWifi {
|
|||||||
nlohmann::json new_ie;
|
nlohmann::json new_ie;
|
||||||
nlohmann::json content;
|
nlohmann::json content;
|
||||||
|
|
||||||
|
// std::cout << BufferToHex(&data[0],data.size()) << std::endl;
|
||||||
uint offset = 0;
|
uint offset = 0;
|
||||||
auto sub_ie = data[offset++];
|
auto sub_ie = data[offset++];
|
||||||
switch (sub_ie) {
|
switch (sub_ie) {
|
||||||
@@ -1787,6 +1788,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
nlohmann::json D = nlohmann::json::parse(ofs.str());
|
nlohmann::json D = nlohmann::json::parse(ofs.str());
|
||||||
|
// std::cout << "Start of parsing wifi" << std::endl;
|
||||||
if (D.contains("status")) {
|
if (D.contains("status")) {
|
||||||
auto Status = D["status"];
|
auto Status = D["status"];
|
||||||
if (Status.contains("scan") && Status["scan"].is_array()) {
|
if (Status.contains("scan") && Status["scan"].is_array()) {
|
||||||
@@ -1801,6 +1803,8 @@ namespace OpenWifi {
|
|||||||
if (ie.contains("type") && ie.contains("data")) {
|
if (ie.contains("type") && ie.contains("data")) {
|
||||||
uint64_t ie_type = ie["type"];
|
uint64_t ie_type = ie["type"];
|
||||||
std::string ie_data = ie["data"];
|
std::string ie_data = ie["data"];
|
||||||
|
// std::cout << "TYPE:" << ie_type << " DATA:" << ie_data
|
||||||
|
// << std::endl;
|
||||||
auto data = Base64Decode2Vec(ie_data);
|
auto data = Base64Decode2Vec(ie_data);
|
||||||
if (ie_type == ieee80211_eid::WLAN_EID_COUNTRY) {
|
if (ie_type == ieee80211_eid::WLAN_EID_COUNTRY) {
|
||||||
new_ies.push_back(WFS_WLAN_EID_COUNTRY(data));
|
new_ies.push_back(WFS_WLAN_EID_COUNTRY(data));
|
||||||
@@ -1854,12 +1858,18 @@ namespace OpenWifi {
|
|||||||
} else if (ie_type == ieee80211_eid::WLAN_EID_EXTENSION) {
|
} else if (ie_type == ieee80211_eid::WLAN_EID_EXTENSION) {
|
||||||
new_ies.push_back(WFS_WLAN_EID_EXTENSION(data));
|
new_ies.push_back(WFS_WLAN_EID_EXTENSION(data));
|
||||||
} else {
|
} else {
|
||||||
|
// std::cout
|
||||||
|
// << "Skipping IE: no parsing available: " << ie_type
|
||||||
|
// << std::endl;
|
||||||
new_ies.push_back(ie);
|
new_ies.push_back(ie);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// std::cout << "Skipping IE: no data and type" <<
|
||||||
|
// std::endl;
|
||||||
new_ies.push_back(ie);
|
new_ies.push_back(ie);
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
// std::cout << "Skipping IE: exception" << std::endl;
|
||||||
Logger.information(fmt::format("Error parsing IEs"));
|
Logger.information(fmt::format("Error parsing IEs"));
|
||||||
new_ies.push_back(ie);
|
new_ies.push_back(ie);
|
||||||
}
|
}
|
||||||
@@ -1867,6 +1877,7 @@ namespace OpenWifi {
|
|||||||
scan_entry["ies"] = new_ies;
|
scan_entry["ies"] = new_ies;
|
||||||
ParsedScan.push_back(scan_entry);
|
ParsedScan.push_back(scan_entry);
|
||||||
} else {
|
} else {
|
||||||
|
// std::cout << "Skipping scan" << std::endl;
|
||||||
ParsedScan.push_back(scan_entry);
|
ParsedScan.push_back(scan_entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1875,6 +1886,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Result << to_string(D);
|
Result << to_string(D);
|
||||||
|
// std::cout << "End of parsing wifi" << std::endl;
|
||||||
return true;
|
return true;
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger.log(E);
|
Logger.log(E);
|
||||||
|
|||||||
@@ -1,443 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2023-03-19.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "RADIUSSessionTracker.h"
|
|
||||||
#include <fmt/format.h>
|
|
||||||
#include <framework/utils.h>
|
|
||||||
|
|
||||||
#include "RADIUS_proxy_server.h"
|
|
||||||
#include "framework/RESTAPI_utils.h"
|
|
||||||
|
|
||||||
using OpenWifi::RESTAPI_utils::field_from_json;
|
|
||||||
using OpenWifi::RESTAPI_utils::field_to_json;
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
|
|
||||||
int RADIUSSessionTracker::Start() {
|
|
||||||
poco_information(Logger(),"Starting...");
|
|
||||||
QueueManager_.start(*this);
|
|
||||||
GarbageCollectionCallback_ = std::make_unique<Poco::TimerCallback<RADIUSSessionTracker>>(
|
|
||||||
*this, &RADIUSSessionTracker::GarbageCollection);
|
|
||||||
GarbageCollectionTimer_.setStartInterval(10000);
|
|
||||||
GarbageCollectionTimer_.setPeriodicInterval(2*60*1000); // every 2 minutes
|
|
||||||
GarbageCollectionTimer_.start(*GarbageCollectionCallback_, MicroServiceTimerPool());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RADIUSSessionTracker::Stop() {
|
|
||||||
poco_information(Logger(),"Stopping...");
|
|
||||||
Running_ = false;
|
|
||||||
GarbageCollectionTimer_.stop();
|
|
||||||
SessionMessageQueue_.wakeUpAll();
|
|
||||||
QueueManager_.join();
|
|
||||||
poco_information(Logger(),"Stopped...");
|
|
||||||
}
|
|
||||||
|
|
||||||
void RADIUSSessionTracker::GarbageCollection([[maybe_unused]] Poco::Timer &timer) {
|
|
||||||
std::lock_guard G(Mutex_);
|
|
||||||
|
|
||||||
auto Now = Utils::Now();
|
|
||||||
std::uint64_t active_sessions=0, active_devices=0;
|
|
||||||
for(auto device_it = AccountingSessions_.begin(); device_it != end(AccountingSessions_); ) {
|
|
||||||
auto & serialNumber = device_it->first;
|
|
||||||
auto & session_list = device_it->second;
|
|
||||||
for(auto session_it=session_list.begin();session_it!=end(session_list);) {
|
|
||||||
auto & session_name = session_it->first;
|
|
||||||
auto & session = session_it->second;
|
|
||||||
if((Now-session->lastTransaction)>SessionTimeout_) {
|
|
||||||
poco_debug(Logger(),fmt::format("{}: Session {} timeout for {}", serialNumber, session_name, session->userName));
|
|
||||||
session_it = session_list.erase(session_it);
|
|
||||||
} else {
|
|
||||||
++active_sessions;
|
|
||||||
++session_it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(session_list.empty()) {
|
|
||||||
device_it = AccountingSessions_.erase(device_it);
|
|
||||||
} else {
|
|
||||||
++active_devices;
|
|
||||||
++device_it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
poco_information(Logger(),fmt::format("{} active sessions on {} devices",active_sessions, active_devices));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RADIUSSessionTracker::run() {
|
|
||||||
Utils::SetThreadName("rad:sessmgr");
|
|
||||||
Running_ = true;
|
|
||||||
|
|
||||||
Poco::AutoPtr<Poco::Notification> NextSession(SessionMessageQueue_.waitDequeueNotification());
|
|
||||||
while (NextSession && Running_) {
|
|
||||||
auto Session = dynamic_cast<SessionNotification *>(NextSession.get());
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (Session != nullptr) {
|
|
||||||
switch(Session->Type_) {
|
|
||||||
case SessionNotification::NotificationType::accounting_session_message: {
|
|
||||||
ProcessAccountingSession(*Session);
|
|
||||||
} break;
|
|
||||||
case SessionNotification::NotificationType::authentication_session_message: {
|
|
||||||
ProcessAuthenticationSession(*Session);
|
|
||||||
} break;
|
|
||||||
case SessionNotification::NotificationType::ap_disconnect: {
|
|
||||||
DisconnectSession(Session->SerialNumber_);
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
Logger().log(E);
|
|
||||||
} catch (...) {
|
|
||||||
poco_warning(Logger(), "Exception occurred during run.");
|
|
||||||
}
|
|
||||||
NextSession = SessionMessageQueue_.waitDequeueNotification();
|
|
||||||
}
|
|
||||||
poco_information(Logger(), "RADIUS session manager stopping.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void RADIUSSessionTracker::ProcessAuthenticationSession([[maybe_unused]] OpenWifi::SessionNotification &Notification) {
|
|
||||||
std::lock_guard Guard(Mutex_);
|
|
||||||
|
|
||||||
std::string CallingStationId, CalledStationId, AccountingSessionId, AccountingMultiSessionId, UserName, ChargeableUserIdentity, Interface, nasId;
|
|
||||||
for (const auto &attribute : Notification.Packet_.Attrs_) {
|
|
||||||
switch (attribute.type) {
|
|
||||||
case RADIUS::Attributes::AUTH_USERNAME: {
|
|
||||||
UserName.assign(
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos],
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos + attribute.len]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::CALLING_STATION_ID: {
|
|
||||||
CallingStationId.assign(
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos],
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos + attribute.len]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::CALLED_STATION_ID: {
|
|
||||||
CalledStationId.assign(
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos],
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos + attribute.len]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::ACCT_SESSION_ID: {
|
|
||||||
AccountingSessionId.assign(
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos],
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos + attribute.len]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::ACCT_MULTI_SESSION_ID: {
|
|
||||||
AccountingMultiSessionId.assign(
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos],
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos + attribute.len]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::CHARGEABLE_USER_IDENTITY:{
|
|
||||||
ChargeableUserIdentity.assign(
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos],
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos + attribute.len]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::NAS_IDENTIFIER:{
|
|
||||||
nasId.assign(
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos],
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos + attribute.len]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::PROXY_STATE: {
|
|
||||||
std::string Tmp;
|
|
||||||
Tmp.assign(
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos],
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos + attribute.len]);
|
|
||||||
auto ProxyParts = Poco::StringTokenizer(Tmp,":");
|
|
||||||
if(ProxyParts.count()==4)
|
|
||||||
Interface=ProxyParts[3];
|
|
||||||
|
|
||||||
} break;
|
|
||||||
default: {
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ap_hint = AccountingSessions_.find(Notification.SerialNumber_);
|
|
||||||
if(ap_hint==end(AccountingSessions_)) {
|
|
||||||
SessionMap M;
|
|
||||||
AccountingSessions_[Notification.SerialNumber_ ] = M;
|
|
||||||
ap_hint = AccountingSessions_.find(Notification.SerialNumber_);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Index = AccountingSessionId +AccountingMultiSessionId;
|
|
||||||
auto session_hint = ap_hint->second.find(Index);
|
|
||||||
if(session_hint==end(ap_hint->second)) {
|
|
||||||
auto NewSession = std::make_shared<GWObjects::RADIUSSession>();
|
|
||||||
NewSession->serialNumber = Notification.SerialNumber_;
|
|
||||||
NewSession->started = NewSession->lastTransaction = Utils::Now();
|
|
||||||
NewSession->userName = UserName;
|
|
||||||
NewSession->callingStationId = CallingStationId;
|
|
||||||
NewSession->calledStationId = CalledStationId;
|
|
||||||
NewSession->accountingSessionId = AccountingSessionId;
|
|
||||||
NewSession->accountingMultiSessionId = AccountingMultiSessionId;
|
|
||||||
NewSession->chargeableUserIdentity = ChargeableUserIdentity;
|
|
||||||
NewSession->interface = Interface;
|
|
||||||
NewSession->nasId = nasId;
|
|
||||||
NewSession->secret = Notification.Secret_;
|
|
||||||
ap_hint->second[Index] = NewSession;
|
|
||||||
} else {
|
|
||||||
session_hint->second->lastTransaction = Utils::Now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::uint32_t GetUiInt32(const std::uint8_t *buf) {
|
|
||||||
return (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + (buf[3] << 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
std::string RADIUSSessionTracker::ComputeSessionIndex(OpenWifi::RADIUSSessionPtr S) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
|
||||||
RADIUSSessionTracker::ProcessAccountingSession(OpenWifi::SessionNotification &Notification) {
|
|
||||||
std::lock_guard Guard(Mutex_);
|
|
||||||
|
|
||||||
std::string CallingStationId, CalledStationId, AccountingSessionId, AccountingMultiSessionId, UserName, ChargeableUserIdentity, Interface;
|
|
||||||
std::uint8_t AccountingPacketType = 0;
|
|
||||||
std::uint32_t InputOctets=0, OutputOctets=0, InputPackets=0, OutputPackets=0, InputGigaWords=0, OutputGigaWords=0,
|
|
||||||
SessionTime = 0;
|
|
||||||
for (const auto &attribute : Notification.Packet_.Attrs_) {
|
|
||||||
switch (attribute.type) {
|
|
||||||
case RADIUS::Attributes::AUTH_USERNAME: {
|
|
||||||
UserName.assign(
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos],
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos + attribute.len]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::CALLING_STATION_ID: {
|
|
||||||
CallingStationId.assign(
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos],
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos + attribute.len]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::CALLED_STATION_ID: {
|
|
||||||
CalledStationId.assign(
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos],
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos + attribute.len]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::ACCT_SESSION_ID: {
|
|
||||||
AccountingSessionId.assign(
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos],
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos + attribute.len]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::ACCT_MULTI_SESSION_ID: {
|
|
||||||
AccountingMultiSessionId.assign(
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos],
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos + attribute.len]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::CHARGEABLE_USER_IDENTITY:{
|
|
||||||
ChargeableUserIdentity.assign(
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos],
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos + attribute.len]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::ACCT_STATUS_TYPE: {
|
|
||||||
AccountingPacketType = Notification.Packet_.P_.attributes[attribute.pos + 3];
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::ACCT_INPUT_OCTETS: {
|
|
||||||
InputOctets = GetUiInt32(&Notification.Packet_.P_.attributes[attribute.pos]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::ACCT_INPUT_PACKETS: {
|
|
||||||
InputPackets = GetUiInt32(&Notification.Packet_.P_.attributes[attribute.pos]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::ACCT_INPUT_GIGAWORDS: {
|
|
||||||
InputGigaWords = GetUiInt32(&Notification.Packet_.P_.attributes[attribute.pos]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::ACCT_OUTPUT_OCTETS: {
|
|
||||||
OutputOctets = GetUiInt32(&Notification.Packet_.P_.attributes[attribute.pos]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::ACCT_OUTPUT_PACKETS: {
|
|
||||||
OutputPackets= GetUiInt32(&Notification.Packet_.P_.attributes[attribute.pos]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::ACCT_OUTPUT_GIGAWORDS: {
|
|
||||||
OutputGigaWords = GetUiInt32(&Notification.Packet_.P_.attributes[attribute.pos]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::ACCT_SESSION_TIME: {
|
|
||||||
SessionTime = GetUiInt32(&Notification.Packet_.P_.attributes[attribute.pos]);
|
|
||||||
} break;
|
|
||||||
case RADIUS::Attributes::PROXY_STATE: {
|
|
||||||
std::string Tmp;
|
|
||||||
Tmp.assign(
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos],
|
|
||||||
&Notification.Packet_.P_.attributes[attribute.pos + attribute.len]);
|
|
||||||
auto ProxyParts = Poco::StringTokenizer(Tmp,":");
|
|
||||||
if(ProxyParts.count()==4)
|
|
||||||
Interface=ProxyParts[3];
|
|
||||||
|
|
||||||
} break;
|
|
||||||
default: {
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto ap_hint = AccountingSessions_.find(Notification.SerialNumber_);
|
|
||||||
if(ap_hint==end(AccountingSessions_)) {
|
|
||||||
SessionMap M;
|
|
||||||
AccountingSessions_[Notification.SerialNumber_ ] = M;
|
|
||||||
ap_hint = AccountingSessions_.find(Notification.SerialNumber_);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Index = AccountingSessionId + AccountingMultiSessionId;
|
|
||||||
auto session_hint = ap_hint->second.find(Index);
|
|
||||||
if(session_hint==end(ap_hint->second)) {
|
|
||||||
// find the calling_station_id
|
|
||||||
// if we are getting a stop for something we do not know, nothing to do...
|
|
||||||
if( AccountingPacketType!=OpenWifi::RADIUS::AccountingPacketTypes::ACCT_STATUS_TYPE_START &&
|
|
||||||
AccountingPacketType!=OpenWifi::RADIUS::AccountingPacketTypes::ACCT_STATUS_TYPE_INTERIM_UPDATE) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::cout << "ACT -> " << Notification.SerialNumber_ << ": AccountingSessionId: " << AccountingSessionId << " AccountingMultiSessionId: " << AccountingMultiSessionId << std::endl;
|
|
||||||
|
|
||||||
auto NewSession = std::make_shared<GWObjects::RADIUSSession>();
|
|
||||||
NewSession->serialNumber = Notification.SerialNumber_;
|
|
||||||
NewSession->destination = Notification.Destination_;
|
|
||||||
NewSession->started = NewSession->lastTransaction = Utils::Now();
|
|
||||||
NewSession->userName = UserName;
|
|
||||||
NewSession->callingStationId = CallingStationId;
|
|
||||||
NewSession->calledStationId = CalledStationId;
|
|
||||||
NewSession->accountingSessionId = AccountingSessionId;
|
|
||||||
NewSession->accountingMultiSessionId = AccountingMultiSessionId;
|
|
||||||
NewSession->accountingPacket = Notification.Packet_;
|
|
||||||
NewSession->destination = Notification.Destination_;
|
|
||||||
NewSession->inputOctets = InputOctets;
|
|
||||||
NewSession->inputPackets = InputPackets;
|
|
||||||
NewSession->inputGigaWords = InputGigaWords;
|
|
||||||
NewSession->outputOctets = OutputOctets;
|
|
||||||
NewSession->outputOctets = OutputPackets;
|
|
||||||
NewSession->outputGigaWords = OutputGigaWords;
|
|
||||||
NewSession->sessionTime = SessionTime;
|
|
||||||
NewSession->chargeableUserIdentity = ChargeableUserIdentity;
|
|
||||||
NewSession->interface = Interface;
|
|
||||||
NewSession->secret = Notification.Secret_;
|
|
||||||
|
|
||||||
poco_debug(Logger(),fmt::format("{}: Creating session", CallingStationId));
|
|
||||||
ap_hint->second[Index] = NewSession;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// If we receive a stop, just remove that session
|
|
||||||
if(AccountingPacketType==OpenWifi::RADIUS::AccountingPacketTypes::ACCT_STATUS_TYPE_STOP) {
|
|
||||||
poco_debug(Logger(),fmt::format("{}: Deleting session", CallingStationId));
|
|
||||||
ap_hint->second.erase(Index);
|
|
||||||
} else {
|
|
||||||
poco_debug(Logger(),fmt::format("{}: Updating session", CallingStationId));
|
|
||||||
session_hint->second->accountingPacket = Notification.Packet_;
|
|
||||||
session_hint->second->destination = Notification.Destination_;
|
|
||||||
session_hint->second->lastTransaction = Utils::Now();
|
|
||||||
session_hint->second->inputOctets = InputOctets;
|
|
||||||
session_hint->second->inputPackets = InputPackets;
|
|
||||||
session_hint->second->inputGigaWords = InputGigaWords;
|
|
||||||
session_hint->second->outputOctets = OutputOctets;
|
|
||||||
session_hint->second->outputOctets = OutputPackets;
|
|
||||||
session_hint->second->outputGigaWords = OutputGigaWords;
|
|
||||||
session_hint->second->sessionTime = SessionTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if(ap_hint!=AccountingSessions_.end()) {
|
|
||||||
std::cout << "Acct table:" << std::endl;
|
|
||||||
for(const auto &session:ap_hint->second) {
|
|
||||||
std::cout << Notification.SerialNumber_ << ": Index: " << session.first << ": ID: " << session.second->accountingSessionId << " MID:" << session.second->accountingMultiSessionId << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
[[maybe_unused]] static void store_packet(const std::string &serialNumber, const char *buffer, std::size_t size, int i) {
|
|
||||||
static std::uint64_t pkt=0;
|
|
||||||
|
|
||||||
std::string filename = MicroServiceDataDirectory() + "/radius." + serialNumber + ".stop." +
|
|
||||||
std::to_string(pkt++) + "." + std::to_string(i) + ".bin";
|
|
||||||
|
|
||||||
std::ofstream ofs(filename,std::ios_base::binary | std::ios_base::trunc | std::ios_base::out);
|
|
||||||
ofs.write(buffer,size);
|
|
||||||
ofs.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RADIUSSessionTracker::SendCoADM(const RADIUSSessionPtr &session) {
|
|
||||||
|
|
||||||
RADIUS::RadiusPacket P;
|
|
||||||
|
|
||||||
P.PacketType(RADIUS::Disconnect_Request);
|
|
||||||
P.Identifier(std::rand() & 0x00ff);
|
|
||||||
P.AppendAttribute(RADIUS::Attributes::AUTH_USERNAME, session->userName);
|
|
||||||
P.AppendAttribute(RADIUS::Attributes::NAS_IP, (std::uint32_t)(0x7f000001));
|
|
||||||
if(!session->calledStationId.empty())
|
|
||||||
P.AppendAttribute(RADIUS::Attributes::CALLED_STATION_ID, session->calledStationId);
|
|
||||||
if(!session->callingStationId.empty())
|
|
||||||
P.AppendAttribute(RADIUS::Attributes::CALLING_STATION_ID, session->callingStationId);
|
|
||||||
if(!session->nasId.empty())
|
|
||||||
P.AppendAttribute(RADIUS::Attributes::NAS_IDENTIFIER, session->nasId);
|
|
||||||
if(!session->accountingSessionId.empty())
|
|
||||||
P.AppendAttribute(RADIUS::Attributes::ACCT_SESSION_ID, session->accountingSessionId);
|
|
||||||
if(!session->accountingMultiSessionId.empty())
|
|
||||||
P.AppendAttribute(RADIUS::Attributes::ACCT_MULTI_SESSION_ID, session->accountingMultiSessionId);
|
|
||||||
auto ProxyState = session->serialNumber + ":" + "0.0.0.0" + ":" + "3799" + ":" + session->interface;
|
|
||||||
// std::cout << "Proxy state: " << ProxyState << " Secret: " << session->secret << std::endl;
|
|
||||||
P.AppendAttribute(RADIUS::Attributes::PROXY_STATE, ProxyState);
|
|
||||||
P.RecomputeAuthenticator(session->secret);
|
|
||||||
P.Log(std::cout);
|
|
||||||
AP_WS_Server()->SendRadiusCoAData(session->serialNumber, P.Buffer(), P.Size_);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RADIUSSessionTracker::SendCoADM(const std::string &serialNumber, const std::string &sessionId) {
|
|
||||||
poco_information(Logger(),fmt::format("{}: SendCoADM for {}.", serialNumber, sessionId));
|
|
||||||
std::lock_guard Guard(Mutex_);
|
|
||||||
|
|
||||||
auto ap_hint = AccountingSessions_.find(serialNumber);
|
|
||||||
if(ap_hint==end(AccountingSessions_)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto session_hint = ap_hint->second.find(sessionId);
|
|
||||||
if(session_hint!=ap_hint->second.end()) {
|
|
||||||
SendCoADM(session_hint->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RADIUSSessionTracker::DisconnectUser(const std::string &UserName) {
|
|
||||||
poco_information(Logger(),fmt::format("Disconnect user {}.", UserName));
|
|
||||||
std::lock_guard Guard(Mutex_);
|
|
||||||
|
|
||||||
for(const auto &AP:AccountingSessions_) {
|
|
||||||
for(const auto &Session:AP.second) {
|
|
||||||
if(Session.second->userName==UserName) {
|
|
||||||
SendCoADM(Session.second);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RADIUSSessionTracker::DisconnectSession(const std::string &SerialNumber) {
|
|
||||||
|
|
||||||
std::lock_guard Guard(Mutex_);
|
|
||||||
auto hint = AccountingSessions_.find(SerialNumber);
|
|
||||||
if(hint==end(AccountingSessions_)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
poco_information(Logger(),fmt::format("{}: Disconnecting.", SerialNumber));
|
|
||||||
|
|
||||||
// we need to go through all sessions and send an accounting stop
|
|
||||||
for(const auto &session:hint->second) {
|
|
||||||
poco_debug(Logger(), fmt::format("Stopping accounting for {}:{}", SerialNumber, session.first ));
|
|
||||||
|
|
||||||
RADIUS::RadiusPacket P(session.second->accountingPacket);
|
|
||||||
|
|
||||||
P.P_.identifier++;
|
|
||||||
P.ReplaceAttribute(RADIUS::Attributes::ACCT_STATUS_TYPE, (std::uint32_t) RADIUS::AccountingPacketTypes::ACCT_STATUS_TYPE_STOP);
|
|
||||||
P.ReplaceOrAdd(RADIUS::Attributes::EVENT_TIMESTAMP, (std::uint32_t) std::time(nullptr));
|
|
||||||
P.AppendAttribute(RADIUS::Attributes::ACCT_TERMINATE_CAUSE, (std::uint32_t) RADIUS::AccountingTerminationReasons::ACCT_TERMINATE_LOST_CARRIER);
|
|
||||||
RADIUS_proxy_server()->RouteAndSendAccountingPacket(session.second->destination, SerialNumber, P, true, session.second->secret);
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountingSessions_.erase(hint);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
|
||||||
@@ -1,208 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2023-03-19.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <framework/SubSystemServer.h>
|
|
||||||
#include <Poco/Runnable.h>
|
|
||||||
#include <Poco/Notification.h>
|
|
||||||
#include <Poco/NotificationQueue.h>
|
|
||||||
#include <Poco/JSON/Object.h>
|
|
||||||
#include <Poco/Timer.h>
|
|
||||||
|
|
||||||
#include "RADIUS_helpers.h"
|
|
||||||
|
|
||||||
#include <RESTObjects/RESTAPI_GWobjects.h>
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
|
|
||||||
class SessionNotification : public Poco::Notification {
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum class NotificationType {
|
|
||||||
accounting_session_message,
|
|
||||||
authentication_session_message,
|
|
||||||
ap_disconnect
|
|
||||||
};
|
|
||||||
|
|
||||||
explicit SessionNotification(NotificationType T, const std::string &Destination, const std::string &SerialNumber, const RADIUS::RadiusPacket &P, const std::string &secret)
|
|
||||||
: Type_(T), Destination_(Destination), SerialNumber_(SerialNumber), Packet_(P), Secret_(secret) {
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit SessionNotification(const std::string &SerialNumber)
|
|
||||||
: Type_(NotificationType::ap_disconnect), SerialNumber_(SerialNumber) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationType Type_;
|
|
||||||
std::string Destination_;
|
|
||||||
std::string SerialNumber_;
|
|
||||||
RADIUS::RadiusPacket Packet_;
|
|
||||||
std::string Secret_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TrackerFutureCompletion {
|
|
||||||
public:
|
|
||||||
virtual bool Completed(const RADIUS::RadiusPacket &P) = 0;
|
|
||||||
virtual bool StillValid() = 0;
|
|
||||||
private:
|
|
||||||
};
|
|
||||||
|
|
||||||
class CoADisconnectResponse : public TrackerFutureCompletion {
|
|
||||||
public:
|
|
||||||
CoADisconnectResponse(const std::string &serialNumber, std::uint8_t id, const std::vector<std::uint8_t> &types, const std::string &callingStationId):
|
|
||||||
SerialNumber_(serialNumber),
|
|
||||||
Id_(id),
|
|
||||||
PacketTypes_(types),
|
|
||||||
CallingStationId_(callingStationId) {
|
|
||||||
Created_ = Utils::Now();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Completed(const RADIUS::RadiusPacket &P) final {
|
|
||||||
if(P.Identifier()==Id_) {
|
|
||||||
if(P.P_.code == RADIUS::Disconnect_ACK) {
|
|
||||||
|
|
||||||
} else if (P.P_.code == RADIUS::Disconnect_NAK) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StillValid() final {
|
|
||||||
return (Utils::Now()-Created_) < 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string SerialNumber_;
|
|
||||||
std::uint8_t Id_;
|
|
||||||
std::vector<std::uint8_t> PacketTypes_;
|
|
||||||
std::uint64_t Created_;
|
|
||||||
std::string CallingStationId_;
|
|
||||||
};
|
|
||||||
|
|
||||||
using RADIUSSessionPtr = std::shared_ptr<GWObjects::RADIUSSession>;
|
|
||||||
|
|
||||||
class RADIUSSessionTracker : public SubSystemServer, Poco::Runnable {
|
|
||||||
public:
|
|
||||||
|
|
||||||
static auto instance() {
|
|
||||||
static auto instance_ = new RADIUSSessionTracker;
|
|
||||||
return instance_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Start() override;
|
|
||||||
void Stop() override;
|
|
||||||
void run() final;
|
|
||||||
|
|
||||||
inline void AddAccountingSession(const std::string &Destination, const std::string &SerialNumber,
|
|
||||||
const RADIUS::RadiusPacket &P, const std::string &secret) {
|
|
||||||
SessionMessageQueue_.enqueueNotification(new SessionNotification(SessionNotification::NotificationType::accounting_session_message, Destination, SerialNumber, P, secret));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void AddAuthenticationSession(const std::string &Destination, const std::string &SerialNumber,
|
|
||||||
const RADIUS::RadiusPacket &P, const std::string &secret) {
|
|
||||||
std::lock_guard G(Mutex_);
|
|
||||||
auto ap_hint = AccountingSessions_.find(SerialNumber);
|
|
||||||
if(AccountingSessions_.find(SerialNumber)!=end(AccountingSessions_)) {
|
|
||||||
// if we have already added the info, do not need to add it again
|
|
||||||
auto CallingStationId = P.ExtractCallingStationID();
|
|
||||||
auto AccountingSessionId = P.ExtractAccountingSessionID();
|
|
||||||
if(ap_hint->second.find(CallingStationId+AccountingSessionId)!=end(ap_hint->second)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SessionMessageQueue_.enqueueNotification(new SessionNotification(SessionNotification::NotificationType::authentication_session_message, Destination, SerialNumber, P, secret));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void DeviceDisconnect(const std::string &serialNumber) {
|
|
||||||
SessionMessageQueue_.enqueueNotification(new SessionNotification(serialNumber));
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void GetAPList(std::vector<std::string> &SerialNumbers) {
|
|
||||||
std::lock_guard G(Mutex_);
|
|
||||||
|
|
||||||
for(const auto &[serialNumber,_]:AccountingSessions_) {
|
|
||||||
SerialNumbers.emplace_back(serialNumber);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void GetAPSessions(const std::string &SerialNumber, GWObjects::RADIUSSessionList & list) {
|
|
||||||
std::lock_guard G(Mutex_);
|
|
||||||
|
|
||||||
auto ap_hint = AccountingSessions_.find(SerialNumber);
|
|
||||||
if(ap_hint!=end(AccountingSessions_)) {
|
|
||||||
for(const auto &[index,session]:ap_hint->second) {
|
|
||||||
list.sessions.emplace_back(*session);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void GetUserNameAPSessions(const std::string &userName, GWObjects::RADIUSSessionList & list) {
|
|
||||||
std::lock_guard G(Mutex_);
|
|
||||||
|
|
||||||
for(const auto &[_,sessions]:AccountingSessions_) {
|
|
||||||
for(const auto &[_,session]:sessions) {
|
|
||||||
if(Utils::match(userName.c_str(),session->userName.c_str())) {
|
|
||||||
list.sessions.emplace_back(*session);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void GetMACAPSessions(const std::string &mac, GWObjects::RADIUSSessionList & list) {
|
|
||||||
std::lock_guard G(Mutex_);
|
|
||||||
|
|
||||||
for(const auto &[_,sessions]:AccountingSessions_) {
|
|
||||||
for(const auto &[_,session]:sessions) {
|
|
||||||
if(Utils::match(mac.c_str(),session->callingStationId.c_str())) {
|
|
||||||
list.sessions.emplace_back(*session);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SendCoADM(const std::string &serialNumber, const std::string &sessionId);
|
|
||||||
bool SendCoADM(const RADIUSSessionPtr &session);
|
|
||||||
bool DisconnectUser(const std::string &UserName);
|
|
||||||
|
|
||||||
inline std::uint32_t HasSessions(const std::string & serialNumber) {
|
|
||||||
std::lock_guard G(Mutex_);
|
|
||||||
auto ap_hint = AccountingSessions_.find(serialNumber);
|
|
||||||
if(ap_hint==end(AccountingSessions_)) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return ap_hint->second.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GarbageCollection(Poco::Timer &timer);
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::atomic_bool Running_=false;
|
|
||||||
Poco::NotificationQueue SessionMessageQueue_;
|
|
||||||
Poco::Thread QueueManager_;
|
|
||||||
|
|
||||||
using SessionMap = std::map<std::string,RADIUSSessionPtr>; // calling-station-id + accounting-session-id
|
|
||||||
std::map<std::string,SessionMap> AccountingSessions_; // serial-number -> session< accounting-session -> session>
|
|
||||||
|
|
||||||
Poco::Timer GarbageCollectionTimer_;
|
|
||||||
std::unique_ptr<Poco::TimerCallback<RADIUSSessionTracker>> GarbageCollectionCallback_;
|
|
||||||
|
|
||||||
std::uint64_t SessionTimeout_=10*60;
|
|
||||||
|
|
||||||
|
|
||||||
void ProcessAccountingSession(SessionNotification &Notification);
|
|
||||||
void ProcessAuthenticationSession(SessionNotification &Notification);
|
|
||||||
void DisconnectSession(const std::string &SerialNumber);
|
|
||||||
|
|
||||||
RADIUSSessionTracker() noexcept
|
|
||||||
: SubSystemServer("RADIUSSessionTracker", "RADIUS-SESSION", "radius.session") {}
|
|
||||||
|
|
||||||
std::string ComputeSessionIndex(RADIUSSessionPtr S);
|
|
||||||
};
|
|
||||||
|
|
||||||
inline auto RADIUSSessionTracker() { return RADIUSSessionTracker::instance(); }
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
|
||||||
|
|
||||||
@@ -1,740 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2022-08-15.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
|
||||||
|
|
||||||
#include "Poco/Crypto/X509Certificate.h"
|
|
||||||
#include "Poco/Crypto/RSAKey.h"
|
|
||||||
#include "Poco/Net/Context.h"
|
|
||||||
#include "Poco/Net/NetException.h"
|
|
||||||
#include "Poco/Net/SecureStreamSocket.h"
|
|
||||||
#include "Poco/Net/SocketReactor.h"
|
|
||||||
#include "Poco/TemporaryFile.h"
|
|
||||||
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
|
||||||
|
|
||||||
#include "fmt/format.h"
|
|
||||||
|
|
||||||
#include "AP_WS_Server.h"
|
|
||||||
#include "RADIUS_helpers.h"
|
|
||||||
#include <RESTObjects/RESTAPI_GWobjects.h>
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
|
|
||||||
class RADIUS_Destination : public Poco::Runnable {
|
|
||||||
public:
|
|
||||||
RADIUS_Destination(Poco::Net::SocketReactor &R, const GWObjects::RadiusProxyPool &P)
|
|
||||||
: Reactor_(R),
|
|
||||||
Logger_(Poco::Logger::get(
|
|
||||||
fmt::format("RADSEC: {}", P.name))),
|
|
||||||
Pool_(P)
|
|
||||||
{
|
|
||||||
Type_ = GWObjects::RadiusEndpointType(P.radsecPoolType);
|
|
||||||
Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
~RADIUS_Destination() override { Stop(); }
|
|
||||||
|
|
||||||
const int SMALLEST_RADIUS_PACKET = 20 + 19 + 4;
|
|
||||||
const int DEFAULT_RADIUS_AUTHENTICATION_PORT = 1812;
|
|
||||||
const int DEFAULT_RADIUS_ACCOUNTING_PORT = 1813;
|
|
||||||
const int DEFAULT_RADIUS_CoA_PORT = 3799;
|
|
||||||
|
|
||||||
inline int Start() {
|
|
||||||
ReconnectThread_.start(*this);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Stop() {
|
|
||||||
TryAgain_ = false;
|
|
||||||
Disconnect();
|
|
||||||
ReconnectThread_.wakeUp();
|
|
||||||
ReconnectThread_.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void run() final {
|
|
||||||
Poco::Thread::trySleep(5000);
|
|
||||||
std::uint64_t CurrentDelay = 10, maxDelay=300, LastTry=0, LastKeepAlive=0;
|
|
||||||
while (TryAgain_) {
|
|
||||||
if (!Connected_) {
|
|
||||||
if(!LastTry || (Utils::Now()-LastTry)>CurrentDelay) {
|
|
||||||
LastTry = Utils::Now();
|
|
||||||
if (!Connect()) {
|
|
||||||
CurrentDelay *= 2;
|
|
||||||
if(CurrentDelay>maxDelay) CurrentDelay=10;
|
|
||||||
} else {
|
|
||||||
CurrentDelay = 10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ((Utils::Now() - LastKeepAlive) > Pool_.radsecKeepAlive) {
|
|
||||||
RADIUS::RadiusOutputPacket P(Pool_.authConfig.servers[ServerIndex_].radsecSecret);
|
|
||||||
P.MakeStatusMessage(Pool_.authConfig.servers[ServerIndex_].name);
|
|
||||||
poco_trace(Logger_, fmt::format("{}: Keep-Alive message.", Pool_.authConfig.servers[ServerIndex_].name));
|
|
||||||
Socket_->sendBytes(P.Data(), P.Len());
|
|
||||||
LastKeepAlive = Utils::Now();
|
|
||||||
}
|
|
||||||
Poco::Thread::trySleep(2000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool SendData(const std::string &serial_number, const unsigned char *buffer,
|
|
||||||
int length) {
|
|
||||||
try {
|
|
||||||
if (Connected_) {
|
|
||||||
RADIUS::RadiusPacket P(buffer, length);
|
|
||||||
int sent_bytes;
|
|
||||||
if (P.VerifyMessageAuthenticator(Pool_.authConfig.servers[ServerIndex_].radsecSecret)) {
|
|
||||||
poco_trace(Logger_, fmt::format("{}: {} Sending {} bytes", serial_number,
|
|
||||||
P.PacketType(), length));
|
|
||||||
sent_bytes = Socket_->sendBytes(buffer, length);
|
|
||||||
} else {
|
|
||||||
poco_trace(Logger_, fmt::format("{}: {} Sending {} bytes", serial_number,
|
|
||||||
P.PacketType(), length));
|
|
||||||
P.ComputeMessageAuthenticator(Pool_.authConfig.servers[ServerIndex_].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;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
onData([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
|
||||||
unsigned char Buffer[4096];
|
|
||||||
|
|
||||||
try {
|
|
||||||
auto NumberOfReceivedBytes = Socket_->receiveBytes(Buffer, sizeof(Buffer));
|
|
||||||
std::string ReplySource;
|
|
||||||
if (NumberOfReceivedBytes >= 20) {
|
|
||||||
RADIUS::RadiusPacket P(Buffer, NumberOfReceivedBytes);
|
|
||||||
if (P.IsAuthentication()) {
|
|
||||||
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
|
||||||
if (!SerialNumber.empty()) {
|
|
||||||
poco_debug(Logger_,
|
|
||||||
fmt::format("{}: {}:{} Received {} bytes.", SerialNumber,
|
|
||||||
P.PacketType(),
|
|
||||||
P.PacketTypeToString(),
|
|
||||||
NumberOfReceivedBytes));
|
|
||||||
AP_WS_Server()->SendRadiusAuthenticationData(SerialNumber, Buffer,
|
|
||||||
NumberOfReceivedBytes);
|
|
||||||
} else if(P.IsStatusMessageReply(ReplySource)) {
|
|
||||||
poco_debug(Logger_,
|
|
||||||
fmt::format("{}: Keepalive message received.", ReplySource));
|
|
||||||
} else {
|
|
||||||
poco_debug(Logger_, "AUTH packet dropped.");
|
|
||||||
}
|
|
||||||
} else if (P.IsAccounting()) {
|
|
||||||
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
|
||||||
if (!SerialNumber.empty()) {
|
|
||||||
poco_debug(Logger_,
|
|
||||||
fmt::format("{}: {}:{} Received {} bytes.", SerialNumber,
|
|
||||||
P.PacketType(),
|
|
||||||
P.PacketTypeToString(), NumberOfReceivedBytes));
|
|
||||||
AP_WS_Server()->SendRadiusAccountingData(SerialNumber, Buffer,
|
|
||||||
NumberOfReceivedBytes);
|
|
||||||
} else {
|
|
||||||
poco_debug(Logger_, "ACCT packet dropped.");
|
|
||||||
}
|
|
||||||
} else if (P.IsAuthority()) {
|
|
||||||
auto SerialNumber = P.ExtractSerialNumberTIP();
|
|
||||||
if (!SerialNumber.empty()) {
|
|
||||||
poco_debug(Logger_,
|
|
||||||
fmt::format("{}: {}:{} Received {} bytes.", SerialNumber,
|
|
||||||
P.PacketType(),
|
|
||||||
P.PacketTypeToString(), 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.");
|
|
||||||
Disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
onShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
|
|
||||||
poco_warning(Logger_, "Socker socket shutdown. Terminating connection.");
|
|
||||||
Disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void OnAccountingSocketReadable(
|
|
||||||
const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
|
||||||
Poco::Net::SocketAddress Sender;
|
|
||||||
RADIUS::RadiusPacket P;
|
|
||||||
|
|
||||||
auto ReceiveSize = pNf->socket().impl()->receiveBytes(P.Buffer(), P.BufferLen());
|
|
||||||
if (ReceiveSize < SMALLEST_RADIUS_PACKET) {
|
|
||||||
poco_warning(Logger_, "Accounting: bad packet received.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
P.Evaluate(ReceiveSize);
|
|
||||||
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
|
||||||
if (SerialNumber.empty()) {
|
|
||||||
poco_warning(Logger_, "Accounting: missing serial number. Dropping request.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
poco_debug(
|
|
||||||
Logger_,
|
|
||||||
fmt::format(
|
|
||||||
"Accounting Packet Response received for {}", SerialNumber ));
|
|
||||||
AP_WS_Server()->SendRadiusAccountingData(SerialNumber, P.Buffer(), P.Size());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void OnAuthenticationSocketReadable(
|
|
||||||
const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
|
||||||
Poco::Net::SocketAddress Sender;
|
|
||||||
RADIUS::RadiusPacket P;
|
|
||||||
|
|
||||||
auto ReceiveSize = pNf->socket().impl()->receiveBytes(P.Buffer(), P.BufferLen());
|
|
||||||
if (ReceiveSize < SMALLEST_RADIUS_PACKET) {
|
|
||||||
poco_warning(Logger_, "Authentication: bad packet received.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
P.Evaluate(ReceiveSize);
|
|
||||||
|
|
||||||
if(Logger_.trace()) {
|
|
||||||
P.Log(std::cout);
|
|
||||||
}
|
|
||||||
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
|
||||||
if (SerialNumber.empty()) {
|
|
||||||
poco_warning(Logger_, "Authentication: missing serial number. Dropping request.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void OnCoASocketReadable(
|
|
||||||
const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
|
||||||
Poco::Net::SocketAddress Sender;
|
|
||||||
RADIUS::RadiusPacket P;
|
|
||||||
|
|
||||||
auto ReceiveSize = pNf.get()->socket().impl()->receiveBytes(P.Buffer(), P.BufferLen());
|
|
||||||
if (ReceiveSize < SMALLEST_RADIUS_PACKET) {
|
|
||||||
poco_warning(Logger_, "CoA/DM: bad packet received.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
P.Evaluate(ReceiveSize);
|
|
||||||
auto SerialNumber = P.ExtractSerialNumberTIP();
|
|
||||||
if (SerialNumber.empty()) {
|
|
||||||
poco_warning(Logger_, "CoA/DM: missing serial number. Dropping request.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool IsExpired(const Poco::Crypto::X509Certificate &C) {
|
|
||||||
return C.expiresOn().timestamp().epochTime() < (std::time_t)Utils::Now();
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void Cat(const std::string &F1, const std::string & F2, const std::string &F) {
|
|
||||||
std::ofstream of(F.c_str(),std::ios_base::trunc|std::ios_base::out|std::ios_base::binary);
|
|
||||||
std::ifstream if1(F1.c_str(),std::ios_base::binary|std::ios_base::in);
|
|
||||||
Poco::StreamCopier::copyStream(if1,of);
|
|
||||||
of << std::endl;
|
|
||||||
std::ifstream if2(F2.c_str(),std::ios_base::binary|std::ios_base::in);
|
|
||||||
Poco::StreamCopier::copyStream(if2,of);
|
|
||||||
of << std::endl;
|
|
||||||
of.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Connect_GlobalReach() {
|
|
||||||
|
|
||||||
if (TryAgain_) {
|
|
||||||
std::lock_guard G(LocalMutex_);
|
|
||||||
|
|
||||||
Poco::TemporaryFile CertFile_(MicroServiceDataDirectory());
|
|
||||||
Poco::TemporaryFile KeyFile_(MicroServiceDataDirectory());
|
|
||||||
Poco::TemporaryFile OpenRoamingRootCertFile_(MicroServiceDataDirectory());
|
|
||||||
Poco::TemporaryFile Intermediate0(MicroServiceDataDirectory());
|
|
||||||
Poco::TemporaryFile Intermediate1(MicroServiceDataDirectory());
|
|
||||||
|
|
||||||
DecodeFile(KeyFile_.path(), Pool_.acctConfig.servers[ServerIndex_].radsecKey);
|
|
||||||
DecodeFile(CertFile_.path(), Pool_.acctConfig.servers[ServerIndex_].radsecCert);
|
|
||||||
DecodeFile(Intermediate0.path(), Pool_.acctConfig.servers[ServerIndex_].radsecCacerts[0]);
|
|
||||||
DecodeFile(Intermediate1.path(), Pool_.acctConfig.servers[ServerIndex_].radsecCacerts[1]);
|
|
||||||
|
|
||||||
const static std::string OpenRoamingRootCert{
|
|
||||||
"-----BEGIN CERTIFICATE-----\n"
|
|
||||||
"MIIClDCCAhugAwIBAgIUF1f+h+uJNHyr+ZqTpwew8LYRAW0wCgYIKoZIzj0EAwMw\n"
|
|
||||||
"gYkxCzAJBgNVBAYTAkdCMQ8wDQYDVQQIEwZMb25kb24xDzANBgNVBAcTBkxvbmRv\n"
|
|
||||||
"bjEsMCoGA1UEChMjR2xvYmFsUmVhY2ggVGVjaG5vbG9neSBFTUVBIExpbWl0ZWQx\n"
|
|
||||||
"KjAoBgNVBAMTIUdsb2JhbFJlYWNoIENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0y\n"
|
|
||||||
"MzA3MTQwOTMyMDBaFw00MzA3MDkwOTMyMDBaMIGJMQswCQYDVQQGEwJHQjEPMA0G\n"
|
|
||||||
"A1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xLDAqBgNVBAoTI0dsb2JhbFJl\n"
|
|
||||||
"YWNoIFRlY2hub2xvZ3kgRU1FQSBMaW1pdGVkMSowKAYDVQQDEyFHbG9iYWxSZWFj\n"
|
|
||||||
"aCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARy\n"
|
|
||||||
"f02umFNy5W/TtM5nfMaLhRF61vLxhT8iNQHR1mXiRmNdME3ArForBcAm2eolHPcJ\n"
|
|
||||||
"RH9DcXs59d2zzoPEaBjXADTCjUts3F7G6fjqvfki2e/txx/xfUopQO8G54XcFWqj\n"
|
|
||||||
"QjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRS\n"
|
|
||||||
"tNe7MgAFwTaMZKUtS1/8pVoBqjAKBggqhkjOPQQDAwNnADBkAjA7VKHTybtSMBcN\n"
|
|
||||||
"717jGYvkWlcj4c9/LzPtkHO053wGsPigaq+1SjY7tDhS/g9oUQACMA6UqH2e8cfn\n"
|
|
||||||
"cZqmBNVNN3DBjIb4anug7F+FnYOQF36ua6MLBeGn3aKxvu1aO+hjPg==\n"
|
|
||||||
"-----END CERTIFICATE-----\n"};
|
|
||||||
|
|
||||||
std::ofstream ofs{OpenRoamingRootCertFile_.path().c_str(),
|
|
||||||
std::ios_base::trunc | std::ios_base::out |
|
|
||||||
std::ios_base::binary};
|
|
||||||
ofs << OpenRoamingRootCert;
|
|
||||||
ofs.close();
|
|
||||||
|
|
||||||
Poco::Net::Context::Ptr SecureContext = Poco::AutoPtr<Poco::Net::Context>(
|
|
||||||
new Poco::Net::Context(Poco::Net::Context::TLS_CLIENT_USE, ""));
|
|
||||||
|
|
||||||
if (Pool_.acctConfig.servers[ServerIndex_].allowSelfSigned) {
|
|
||||||
SecureContext->setSecurityLevel(Poco::Net::Context::SECURITY_LEVEL_NONE);
|
|
||||||
SecureContext->enableExtendedCertificateVerification(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
SecureContext->usePrivateKey(Poco::Crypto::RSAKey("", KeyFile_.path(), ""));
|
|
||||||
Poco::Crypto::X509Certificate Cert(CertFile_.path());
|
|
||||||
if (!IsExpired(Cert)) {
|
|
||||||
SecureContext->useCertificate(Poco::Crypto::X509Certificate(CertFile_.path()));
|
|
||||||
} else {
|
|
||||||
poco_error(
|
|
||||||
Logger_,
|
|
||||||
fmt::format(
|
|
||||||
"Certificate for {} has expired. We cannot connect to this server.",
|
|
||||||
Pool_.acctConfig.servers[ServerIndex_].name));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SecureContext->addCertificateAuthority(
|
|
||||||
Poco::Crypto::X509Certificate(OpenRoamingRootCertFile_.path()));
|
|
||||||
SecureContext->addChainCertificate(
|
|
||||||
Poco::Crypto::X509Certificate(Intermediate0.path()));
|
|
||||||
SecureContext->addChainCertificate(
|
|
||||||
Poco::Crypto::X509Certificate(Intermediate1.path()));
|
|
||||||
SecureContext->enableExtendedCertificateVerification(false);
|
|
||||||
|
|
||||||
Socket_ = std::make_unique<Poco::Net::SecureStreamSocket>(SecureContext);
|
|
||||||
ServerIndex_ = 0 ;
|
|
||||||
for (const auto &PoolEntryServer : Pool_.acctConfig.servers) {
|
|
||||||
Poco::Net::SocketAddress Destination(PoolEntryServer.ip, PoolEntryServer.port);
|
|
||||||
try {
|
|
||||||
poco_information(Logger_, fmt::format("Attempting to connect to {}", CommonName()));
|
|
||||||
Socket_->connect(Destination, Poco::Timespan(20, 0));
|
|
||||||
Socket_->completeHandshake();
|
|
||||||
|
|
||||||
if (!Pool_.authConfig.servers[ServerIndex_].allowSelfSigned) {
|
|
||||||
Socket_->verifyPeerCertificate();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Socket_->havePeerCertificate()) {
|
|
||||||
Peer_Cert_ = std::make_unique<Poco::Crypto::X509Certificate>(
|
|
||||||
Socket_->peerCertificate());
|
|
||||||
}
|
|
||||||
|
|
||||||
Socket_->setBlocking(false);
|
|
||||||
Socket_->setNoDelay(true);
|
|
||||||
Socket_->setKeepAlive(true);
|
|
||||||
Socket_->setReceiveTimeout(Poco::Timespan(1 * 60 * 60, 0));
|
|
||||||
|
|
||||||
Reactor_.addEventHandler(
|
|
||||||
*Socket_,
|
|
||||||
Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADIUS_Destination::onData));
|
|
||||||
Reactor_.addEventHandler(
|
|
||||||
*Socket_, Poco::NObserver<RADIUS_Destination, Poco::Net::ErrorNotification>(
|
|
||||||
*this, &RADIUS_Destination::onError));
|
|
||||||
Reactor_.addEventHandler(
|
|
||||||
*Socket_,
|
|
||||||
Poco::NObserver<RADIUS_Destination, Poco::Net::ShutdownNotification>(
|
|
||||||
*this, &RADIUS_Destination::onShutdown));
|
|
||||||
|
|
||||||
Connected_ = true;
|
|
||||||
poco_information(Logger_, fmt::format("Connected. CN={}", CommonName()));
|
|
||||||
return true;
|
|
||||||
} catch (const Poco::Net::NetException &E) {
|
|
||||||
poco_warning(Logger_, "NetException: Could not connect.");
|
|
||||||
Logger_.log(E);
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
poco_warning(Logger_, "Exception: Could not connect.");
|
|
||||||
Logger_.log(E);
|
|
||||||
} catch (...) {
|
|
||||||
poco_warning(Logger_, "Could not connect.");
|
|
||||||
}
|
|
||||||
ServerIndex_++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ServerIndex_=0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Connect_Orion() {
|
|
||||||
if (TryAgain_) {
|
|
||||||
std::lock_guard G(LocalMutex_);
|
|
||||||
|
|
||||||
Poco::TemporaryFile CertFile_(MicroServiceDataDirectory());
|
|
||||||
Poco::TemporaryFile KeyFile_(MicroServiceDataDirectory());
|
|
||||||
std::vector<std::unique_ptr<Poco::TemporaryFile>> CaCertFiles_;
|
|
||||||
|
|
||||||
DecodeFile(CertFile_.path(), Pool_.acctConfig.servers[ServerIndex_].radsecCert);
|
|
||||||
DecodeFile(KeyFile_.path(), Pool_.acctConfig.servers[ServerIndex_].radsecKey);
|
|
||||||
|
|
||||||
Poco::Crypto::X509Certificate Cert(CertFile_.path());
|
|
||||||
if(IsExpired(Cert)) {
|
|
||||||
poco_error(Logger_, fmt::format("Certificate for {} has expired. We cannot connect to this server.", Pool_.acctConfig.servers[ServerIndex_].name));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto &cert : Pool_.acctConfig.servers[ServerIndex_].radsecCacerts) {
|
|
||||||
CaCertFiles_.emplace_back(
|
|
||||||
std::make_unique<Poco::TemporaryFile>(MicroServiceDataDirectory()));
|
|
||||||
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 (Pool_.acctConfig.servers[ServerIndex_].allowSelfSigned) {
|
|
||||||
SecureContext->setSecurityLevel(Poco::Net::Context::SECURITY_LEVEL_NONE);
|
|
||||||
SecureContext->enableExtendedCertificateVerification(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &ca : CaCertFiles_) {
|
|
||||||
Poco::Crypto::X509Certificate cert(ca->path());
|
|
||||||
SecureContext->addCertificateAuthority(cert);
|
|
||||||
}
|
|
||||||
|
|
||||||
Socket_ = std::make_unique<Poco::Net::SecureStreamSocket>(SecureContext);
|
|
||||||
ServerIndex_ = 0 ;
|
|
||||||
for (const auto &PoolEntryServer : Pool_.acctConfig.servers) {
|
|
||||||
Poco::Net::SocketAddress Destination(PoolEntryServer.ip, PoolEntryServer.port);
|
|
||||||
try {
|
|
||||||
poco_information(Logger_, "Attempting to connect");
|
|
||||||
Socket_->connect(Destination, Poco::Timespan(100, 0));
|
|
||||||
Socket_->completeHandshake();
|
|
||||||
|
|
||||||
if (!Pool_.authConfig.servers[ServerIndex_].allowSelfSigned) {
|
|
||||||
Socket_->verifyPeerCertificate();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Socket_->havePeerCertificate()) {
|
|
||||||
Peer_Cert_ = std::make_unique<Poco::Crypto::X509Certificate>(
|
|
||||||
Socket_->peerCertificate());
|
|
||||||
}
|
|
||||||
|
|
||||||
Socket_->setBlocking(false);
|
|
||||||
Socket_->setNoDelay(true);
|
|
||||||
Socket_->setKeepAlive(true);
|
|
||||||
Socket_->setReceiveTimeout(Poco::Timespan(1 * 60 * 60, 0));
|
|
||||||
|
|
||||||
Reactor_.addEventHandler(
|
|
||||||
*Socket_,
|
|
||||||
Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADIUS_Destination::onData));
|
|
||||||
Reactor_.addEventHandler(
|
|
||||||
*Socket_, Poco::NObserver<RADIUS_Destination, Poco::Net::ErrorNotification>(
|
|
||||||
*this, &RADIUS_Destination::onError));
|
|
||||||
Reactor_.addEventHandler(
|
|
||||||
*Socket_,
|
|
||||||
Poco::NObserver<RADIUS_Destination, Poco::Net::ShutdownNotification>(
|
|
||||||
*this, &RADIUS_Destination::onShutdown));
|
|
||||||
|
|
||||||
Connected_ = true;
|
|
||||||
poco_information(Logger_, fmt::format("Connected. CN={}", CommonName()));
|
|
||||||
return true;
|
|
||||||
} catch (const Poco::Net::NetException &E) {
|
|
||||||
poco_information(Logger_, "Could not connect.");
|
|
||||||
Logger_.log(E);
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
poco_information(Logger_, "Could not connect.");
|
|
||||||
Logger_.log(E);
|
|
||||||
} catch (...) {
|
|
||||||
poco_information(Logger_, "Could not connect.");
|
|
||||||
}
|
|
||||||
ServerIndex_++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ServerIndex_=0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Connect_Generic() {
|
|
||||||
if (TryAgain_) {
|
|
||||||
std::lock_guard G(LocalMutex_);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
/*
|
|
||||||
AuthenticationSocketV6_ =
|
|
||||||
std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV6, true, true);
|
|
||||||
Poco::Net::SocketAddress AuthSockAddrV6(
|
|
||||||
Poco::Net::AddressFamily::IPv6,
|
|
||||||
MicroServiceConfigGetInt("radius.proxy.authentication.port",
|
|
||||||
DEFAULT_RADIUS_AUTHENTICATION_PORT));
|
|
||||||
|
|
||||||
Poco::Net::SocketAddress AcctSockAddrV6(
|
|
||||||
Poco::Net::AddressFamily::IPv6,
|
|
||||||
MicroServiceConfigGetInt("radius.proxy.accounting.port",
|
|
||||||
DEFAULT_RADIUS_ACCOUNTING_PORT));
|
|
||||||
AccountingSocketV6_ =
|
|
||||||
std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV6, true, true);
|
|
||||||
|
|
||||||
Poco::Net::SocketAddress CoASockAddrV6(
|
|
||||||
Poco::Net::AddressFamily::IPv6,
|
|
||||||
MicroServiceConfigGetInt("radius.proxy.coa.port", DEFAULT_RADIUS_CoA_PORT));
|
|
||||||
CoASocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV6, true, true);
|
|
||||||
*/
|
|
||||||
Reactor_.addEventHandler(
|
|
||||||
*AuthenticationSocketV4_,
|
|
||||||
Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADIUS_Destination::OnAuthenticationSocketReadable));
|
|
||||||
Reactor_.addEventHandler(
|
|
||||||
*AccountingSocketV4_,
|
|
||||||
Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADIUS_Destination::OnAccountingSocketReadable));
|
|
||||||
Reactor_.addEventHandler(
|
|
||||||
*CoASocketV4_, Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADIUS_Destination::OnCoASocketReadable));
|
|
||||||
/*
|
|
||||||
Reactor_.addEventHandler(
|
|
||||||
*AuthenticationSocketV6_,
|
|
||||||
Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADIUS_Destination::OnAuthenticationSocketReadable));
|
|
||||||
Reactor_.addEventHandler(
|
|
||||||
*AccountingSocketV6_,
|
|
||||||
Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADIUS_Destination::OnAccountingSocketReadable));
|
|
||||||
|
|
||||||
Reactor_.addEventHandler(
|
|
||||||
*CoASocketV6_, Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADIUS_Destination::OnCoASocketReadable));
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Connect_Radsec() {
|
|
||||||
if (TryAgain_) {
|
|
||||||
std::lock_guard G(LocalMutex_);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool Connect() {
|
|
||||||
switch(Type_) {
|
|
||||||
case GWObjects::RadiusEndpointType::orion: return Connect_Orion();
|
|
||||||
case GWObjects::RadiusEndpointType::globalreach: return Connect_GlobalReach();
|
|
||||||
case GWObjects::RadiusEndpointType::radsec: return Connect_Radsec();
|
|
||||||
default:
|
|
||||||
return Connect_Generic();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Disconnect() {
|
|
||||||
if (Connected_) {
|
|
||||||
std::lock_guard G(LocalMutex_);
|
|
||||||
if(Type_==GWObjects::RadiusEndpointType::generic) {
|
|
||||||
if(AuthenticationSocketV4_) {
|
|
||||||
Reactor_.removeEventHandler(
|
|
||||||
*AuthenticationSocketV4_,
|
|
||||||
Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADIUS_Destination::OnAuthenticationSocketReadable));
|
|
||||||
AuthenticationSocketV4_->close();
|
|
||||||
AuthenticationSocketV4_.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(AccountingSocketV4_) {
|
|
||||||
Reactor_.removeEventHandler(
|
|
||||||
*AccountingSocketV4_,
|
|
||||||
Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADIUS_Destination::OnAccountingSocketReadable));
|
|
||||||
AccountingSocketV4_->close();
|
|
||||||
AccountingSocketV4_.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(CoASocketV4_) {
|
|
||||||
Reactor_.removeEventHandler(
|
|
||||||
*CoASocketV4_,
|
|
||||||
Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADIUS_Destination::OnCoASocketReadable));
|
|
||||||
CoASocketV4_->close();
|
|
||||||
CoASocketV4_.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if(AuthenticationSocketV6_) {
|
|
||||||
Reactor_.removeEventHandler(
|
|
||||||
*AuthenticationSocketV6_,
|
|
||||||
Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADIUS_Destination::OnAuthenticationSocketReadable));
|
|
||||||
AuthenticationSocketV6_->close();
|
|
||||||
AuthenticationSocketV6_.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(AccountingSocketV6_) {
|
|
||||||
Reactor_.removeEventHandler(
|
|
||||||
*AccountingSocketV6_,
|
|
||||||
Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADIUS_Destination::OnAccountingSocketReadable));
|
|
||||||
AccountingSocketV6_->close();
|
|
||||||
AccountingSocketV6_.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(CoASocketV6_) {
|
|
||||||
Reactor_.removeEventHandler(
|
|
||||||
*CoASocketV6_,
|
|
||||||
Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADIUS_Destination::OnCoASocketReadable));
|
|
||||||
CoASocketV6_->close();
|
|
||||||
CoASocketV6_.reset();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
} else {
|
|
||||||
if(Socket_!=nullptr) {
|
|
||||||
std::lock_guard G(LocalMutex_);
|
|
||||||
Reactor_.removeEventHandler(
|
|
||||||
*Socket_, Poco::NObserver<RADIUS_Destination, Poco::Net::ReadableNotification>(
|
|
||||||
*this, &RADIUS_Destination::onData));
|
|
||||||
Reactor_.removeEventHandler(
|
|
||||||
*Socket_, Poco::NObserver<RADIUS_Destination, Poco::Net::ErrorNotification>(
|
|
||||||
*this, &RADIUS_Destination::onError));
|
|
||||||
Reactor_.removeEventHandler(
|
|
||||||
*Socket_,
|
|
||||||
Poco::NObserver<RADIUS_Destination, Poco::Net::ShutdownNotification>(
|
|
||||||
*this, &RADIUS_Destination::onShutdown));
|
|
||||||
Socket_->close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Connected_ = false;
|
|
||||||
poco_information(Logger_, "Disconnecting.");
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
Poco::Base64Decoder ds(is);
|
|
||||||
Poco::StreamCopier::copyStream(ds, sec_file);
|
|
||||||
sec_file.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] inline std::string CommonName() {
|
|
||||||
if (Peer_Cert_)
|
|
||||||
return Peer_Cert_->commonName();
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] inline std::string IssuerName() {
|
|
||||||
if (Peer_Cert_)
|
|
||||||
return Peer_Cert_->issuerName();
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] inline std::string SubjectName() {
|
|
||||||
if (Peer_Cert_)
|
|
||||||
return Peer_Cert_->subjectName();
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto &Pool() const { return Pool_; }
|
|
||||||
auto ServerType() const { return Type_; }
|
|
||||||
|
|
||||||
inline bool SendRadiusDataAuthData(const std::string &serialNumber, const unsigned char *buffer, std::size_t size) {
|
|
||||||
poco_trace(Logger_, fmt::format("{}: Sending RADIUS Auth {} bytes.", serialNumber, size));
|
|
||||||
AuthenticationSocketV4_->sendTo(buffer, size, Poco::Net::SocketAddress(Pool_.authConfig.servers[0].ip, Pool_.authConfig.servers[0].port));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool SendRadiusDataAcctData(const std::string &serialNumber, const unsigned char *buffer, std::size_t size) {
|
|
||||||
poco_trace(Logger_, fmt::format("{}: Sending RADIUS Acct {} bytes.", serialNumber, size));
|
|
||||||
AccountingSocketV4_->sendTo(buffer, size, Poco::Net::SocketAddress(Pool_.acctConfig.servers[0].ip, Pool_.acctConfig.servers[0].port));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool SendRadiusDataCoAData(const std::string &serialNumber, const unsigned char *buffer, std::size_t size) {
|
|
||||||
poco_trace(Logger_, fmt::format("{}: Sending RADIUS CoA {} bytes.", serialNumber, size));
|
|
||||||
CoASocketV4_->sendTo(buffer, size, Poco::Net::SocketAddress(Pool_.coaConfig.servers[0].ip, Pool_.coaConfig.servers[0].port));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::recursive_mutex LocalMutex_;
|
|
||||||
Poco::Net::SocketReactor &Reactor_;
|
|
||||||
Poco::Logger &Logger_;
|
|
||||||
|
|
||||||
std::unique_ptr<Poco::Net::SecureStreamSocket> Socket_;
|
|
||||||
|
|
||||||
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV4_;
|
|
||||||
std::unique_ptr<Poco::Net::DatagramSocket> AuthenticationSocketV4_;
|
|
||||||
std::unique_ptr<Poco::Net::DatagramSocket> CoASocketV4_;
|
|
||||||
|
|
||||||
/* std::unique_ptr<Poco::Net::DatagramSocket> CoASocketV6_;
|
|
||||||
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV6_;
|
|
||||||
std::unique_ptr<Poco::Net::DatagramSocket> AuthenticationSocketV6_;
|
|
||||||
*/
|
|
||||||
|
|
||||||
Poco::Thread ReconnectThread_;
|
|
||||||
std::unique_ptr<Poco::Crypto::X509Certificate> Peer_Cert_;
|
|
||||||
volatile bool Connected_ = false;
|
|
||||||
volatile bool TryAgain_ = true;
|
|
||||||
enum GWObjects::RadiusEndpointType Type_{GWObjects::RadiusEndpointType::unknown};
|
|
||||||
GWObjects::RadiusProxyPool Pool_;
|
|
||||||
uint64_t ServerIndex_=0;
|
|
||||||
};
|
|
||||||
} // namespace OpenWifi
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -8,17 +8,14 @@
|
|||||||
#include "RADIUS_helpers.h"
|
#include "RADIUS_helpers.h"
|
||||||
#include "RADIUS_proxy_server.h"
|
#include "RADIUS_proxy_server.h"
|
||||||
|
|
||||||
#include "RADIUSSessionTracker.h"
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
/*
|
|
||||||
const int SMALLEST_RADIUS_PACKET = 20 + 19 + 4;
|
const int SMALLEST_RADIUS_PACKET = 20 + 19 + 4;
|
||||||
const int DEFAULT_RADIUS_AUTHENTICATION_PORT = 1812;
|
const int DEFAULT_RADIUS_AUTHENTICATION_PORT = 1812;
|
||||||
const int DEFAULT_RADIUS_ACCOUNTING_PORT = 1813;
|
const int DEFAULT_RADIUS_ACCOUNTING_PORT = 1813;
|
||||||
const int DEFAULT_RADIUS_CoA_PORT = 3799;
|
const int DEFAULT_RADIUS_CoA_PORT = 3799;
|
||||||
*/
|
|
||||||
|
|
||||||
int RADIUS_proxy_server::Start() {
|
int RADIUS_proxy_server::Start() {
|
||||||
|
|
||||||
@@ -27,7 +24,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
Enabled_ = MicroServiceConfigGetBool("radius.proxy.enable", false);
|
Enabled_ = MicroServiceConfigGetBool("radius.proxy.enable", false);
|
||||||
if (!Enabled_ && !Config.exists()) {
|
if (!Enabled_ && !Config.exists()) {
|
||||||
StopRADIUSDestinations();
|
StopRADSECServers();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,98 +32,224 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
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);
|
||||||
|
Poco::Net::SocketAddress AuthSockAddrV6(
|
||||||
|
Poco::Net::AddressFamily::IPv6,
|
||||||
|
MicroServiceConfigGetInt("radius.proxy.authentication.port",
|
||||||
|
DEFAULT_RADIUS_AUTHENTICATION_PORT));
|
||||||
|
AuthenticationSocketV6_ =
|
||||||
|
std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV6, true, true);
|
||||||
|
|
||||||
|
Poco::Net::SocketAddress AcctSockAddrV4(
|
||||||
|
Poco::Net::AddressFamily::IPv4,
|
||||||
|
MicroServiceConfigGetInt("radius.proxy.accounting.port",
|
||||||
|
DEFAULT_RADIUS_ACCOUNTING_PORT));
|
||||||
|
AccountingSocketV4_ =
|
||||||
|
std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV4, true, 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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
|
||||||
|
RadiusReactor_.reset();
|
||||||
|
RadiusReactor_ = std::make_unique<Poco::Net::SocketReactor>();
|
||||||
|
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>(
|
||||||
|
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||||
|
|
||||||
|
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>(
|
||||||
|
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||||
|
|
||||||
|
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>(
|
||||||
|
*this, &RADIUS_proxy_server::OnCoASocketReadable));
|
||||||
|
|
||||||
ParseConfig();
|
ParseConfig();
|
||||||
StartRADIUSDestinations();
|
StartRADSECServers();
|
||||||
RadiusReactorThread_.start(RadiusReactor_);
|
RadiusReactorThread_.start(*RadiusReactor_);
|
||||||
Utils::SetThreadName(RadiusReactorThread_, "rad:reactor");
|
Utils::SetThreadName(RadiusReactorThread_, "rad:reactor");
|
||||||
Running_ = true;
|
Running_ = true;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RADIUS_proxy_server::Stop() {
|
void RADIUS_proxy_server::Stop() {
|
||||||
if (Enabled_ && Running_) {
|
if (Enabled_ && Running_) {
|
||||||
poco_information(Logger(), "Stopping...");
|
poco_information(Logger(), "Stopping...");
|
||||||
|
RadiusReactor_->removeEventHandler(
|
||||||
|
*AuthenticationSocketV4_,
|
||||||
|
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||||
|
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||||
|
RadiusReactor_->removeEventHandler(
|
||||||
|
*AuthenticationSocketV6_,
|
||||||
|
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||||
|
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||||
|
|
||||||
StopRADIUSDestinations();
|
RadiusReactor_->removeEventHandler(
|
||||||
RadiusReactor_.stop();
|
*AccountingSocketV4_,
|
||||||
|
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||||
|
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||||
|
RadiusReactor_->removeEventHandler(
|
||||||
|
*AccountingSocketV6_,
|
||||||
|
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||||
|
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||||
|
|
||||||
|
RadiusReactor_->removeEventHandler(
|
||||||
|
*CoASocketV4_,
|
||||||
|
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||||
|
*this, &RADIUS_proxy_server::OnCoASocketReadable));
|
||||||
|
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();
|
||||||
|
|
||||||
|
AuthenticationSocketV4_.reset();
|
||||||
|
AuthenticationSocketV6_.reset();
|
||||||
|
AccountingSocketV4_.reset();
|
||||||
|
AccountingSocketV6_.reset();
|
||||||
|
CoASocketV4_.reset();
|
||||||
|
CoASocketV6_.reset();
|
||||||
|
|
||||||
|
StopRADSECServers();
|
||||||
|
RadiusReactor_->stop();
|
||||||
RadiusReactorThread_.join();
|
RadiusReactorThread_.join();
|
||||||
Running_ = false;
|
Running_ = false;
|
||||||
poco_information(Logger(), "Stopped...");
|
poco_information(Logger(), "Stopped...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* inline static bool isRadsec(const GWObjects::RadiusProxyPool &Cfg) {
|
void RADIUS_proxy_server::StartRADSECServers() {
|
||||||
return Cfg.radsecPoolType=="orion" || Cfg.radsecPoolType=="globalreach" || Cfg.radsecPoolType=="radsec";
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
void RADIUS_proxy_server::StartRADIUSDestinations() {
|
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
for (const auto &pool : PoolList_.pools) {
|
for (const auto &pool : PoolList_.pools) {
|
||||||
if(pool.enabled) {
|
for (const auto &entry : pool.authConfig.servers) {
|
||||||
RADIUS_Destinations_[Utils::IPtoInt(pool.poolProxyIp)] =
|
if (entry.radsec) {
|
||||||
std::make_unique<RADIUS_Destination>(RadiusReactor_, pool);
|
RADSECservers_[Poco::Net::SocketAddress(entry.ip, 0)] =
|
||||||
} else {
|
std::make_unique<RADSEC_server>(*RadiusReactor_, entry);
|
||||||
poco_information(Logger(),fmt::format("Pool {} is not enabled.", pool.name));
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RADIUS_proxy_server::StopRADIUSDestinations() {
|
void RADIUS_proxy_server::StopRADSECServers() {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
RADIUS_Destinations_.clear();
|
RADSECservers_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RADIUS_proxy_server::RouteAndSendAccountingPacket(const std::string &Destination,const std::string &serialNumber, RADIUS::RadiusPacket &P, bool RecomputeAuthenticator, std::string &Secret) {
|
void RADIUS_proxy_server::OnAccountingSocketReadable(
|
||||||
try{
|
const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
||||||
|
Poco::Net::SocketAddress Sender;
|
||||||
|
RADIUS::RadiusPacket P;
|
||||||
|
|
||||||
// are we sending this to a pool?
|
auto ReceiveSize = pNf->socket().impl()->receiveBytes(P.Buffer(), P.BufferLen());
|
||||||
auto DstParts = Utils::Split(Destination, ':');
|
if (ReceiveSize < SMALLEST_RADIUS_PACKET) {
|
||||||
std::uint32_t DtsIp = Utils::IPtoInt(DstParts[0]);
|
poco_warning(Logger(), "Accounting: bad packet received.");
|
||||||
|
return;
|
||||||
std::lock_guard G(Mutex_);
|
}
|
||||||
|
P.Evaluate(ReceiveSize);
|
||||||
auto DestinationServer = RADIUS_Destinations_.find(DtsIp);
|
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
||||||
if (DestinationServer != end(RADIUS_Destinations_)) {
|
if (SerialNumber.empty()) {
|
||||||
if(Logger().trace()) {
|
poco_warning(Logger(), "Accounting: missing serial number.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
auto CallingStationID = P.ExtractCallingStationID();
|
auto CallingStationID = P.ExtractCallingStationID();
|
||||||
auto CalledStationID = P.ExtractCalledStationID();
|
auto CalledStationID = P.ExtractCalledStationID();
|
||||||
auto SessionID = P.ExtractAccountingSessionID();
|
|
||||||
auto MultiSessionID = P.ExtractAccountingMultiSessionID();
|
poco_debug(
|
||||||
Logger().trace(
|
Logger(),
|
||||||
fmt::format("{}: Sending Accounting {} bytes to {}. CalledStationID={} CallingStationID={} SessionID={}:{}",
|
fmt::format(
|
||||||
serialNumber, P.Size(),
|
"Accounting Packet received for {}, CalledStationID: {}, CallingStationID:{}",
|
||||||
DestinationServer->second->Pool().authConfig.servers[0].ip,
|
SerialNumber, CalledStationID, CallingStationID));
|
||||||
CalledStationID, CallingStationID, SessionID, MultiSessionID));
|
AP_WS_Server()->SendRadiusAccountingData(SerialNumber, P.Buffer(), P.Size());
|
||||||
}
|
|
||||||
if(DestinationServer->second->ServerType()!=GWObjects::RadiusEndpointType::generic) {
|
|
||||||
Secret = DestinationServer->second->Pool().acctConfig.servers[0].secret;
|
|
||||||
if(RecomputeAuthenticator) {
|
|
||||||
P.RecomputeAuthenticator(Secret);
|
|
||||||
}
|
|
||||||
DestinationServer->second->SendData(serialNumber, (const unsigned char *)P.Buffer(),
|
|
||||||
P.Size());
|
|
||||||
} else {
|
|
||||||
DestinationServer->second->SendRadiusDataAcctData(
|
|
||||||
serialNumber, (const unsigned char *)P.Buffer(), P.Size());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
Logger().log(E);
|
|
||||||
} catch (...) {
|
|
||||||
poco_warning(Logger(),
|
|
||||||
fmt::format("Bad RADIUS ACCT Packet from {}. Dropped.", serialNumber));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void store_packet(const std::string &serialNumber, const char *buffer, std::size_t size) {
|
void RADIUS_proxy_server::OnAuthenticationSocketReadable(
|
||||||
static std::uint64_t pkt=0;
|
const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
||||||
|
Poco::Net::SocketAddress Sender;
|
||||||
|
RADIUS::RadiusPacket P;
|
||||||
|
|
||||||
std::string filename = MicroServiceDataDirectory() + "/radius." + serialNumber + "." + std::to_string(pkt++) + ".bin";
|
auto ReceiveSize = pNf->socket().impl()->receiveBytes(P.Buffer(), P.BufferLen());
|
||||||
|
if (ReceiveSize < SMALLEST_RADIUS_PACKET) {
|
||||||
|
poco_warning(Logger(), "Authentication: bad packet received.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
P.Evaluate(ReceiveSize);
|
||||||
|
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
||||||
|
if (SerialNumber.empty()) {
|
||||||
|
poco_warning(Logger(), "Authentication: missing serial number.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto CallingStationID = P.ExtractCallingStationID();
|
||||||
|
auto CalledStationID = P.ExtractCalledStationID();
|
||||||
|
|
||||||
std::ofstream ofs(filename,std::ios_base::binary | std::ios_base::trunc | std::ios_base::out);
|
poco_debug(
|
||||||
ofs.write(buffer,size);
|
Logger(),
|
||||||
ofs.close();
|
fmt::format(
|
||||||
|
"Authentication Packet received for {}, CalledStationID: {}, CallingStationID:{}",
|
||||||
|
SerialNumber, CalledStationID, CallingStationID));
|
||||||
|
AP_WS_Server()->SendRadiusAuthenticationData(SerialNumber, P.Buffer(), P.Size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void RADIUS_proxy_server::OnCoASocketReadable(
|
||||||
|
const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
||||||
|
Poco::Net::SocketAddress Sender;
|
||||||
|
RADIUS::RadiusPacket P;
|
||||||
|
|
||||||
|
auto ReceiveSize = pNf.get()->socket().impl()->receiveBytes(P.Buffer(), P.BufferLen());
|
||||||
|
if (ReceiveSize < SMALLEST_RADIUS_PACKET) {
|
||||||
|
poco_warning(Logger(), "CoA/DM: bad packet received.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
P.Evaluate(ReceiveSize);
|
||||||
|
auto SerialNumber = P.ExtractSerialNumberTIP();
|
||||||
|
if (SerialNumber.empty()) {
|
||||||
|
poco_warning(Logger(), "CoA/DM: missing serial number.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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());
|
||||||
}
|
}
|
||||||
|
|
||||||
void RADIUS_proxy_server::SendAccountingData(const std::string &serialNumber,
|
void RADIUS_proxy_server::SendAccountingData(const std::string &serialNumber,
|
||||||
@@ -138,9 +261,46 @@ namespace OpenWifi {
|
|||||||
try {
|
try {
|
||||||
RADIUS::RadiusPacket P((unsigned char *)buffer, size);
|
RADIUS::RadiusPacket P((unsigned char *)buffer, size);
|
||||||
auto Destination = P.ExtractProxyStateDestination();
|
auto Destination = P.ExtractProxyStateDestination();
|
||||||
std::string Secret;
|
auto CallingStationID = P.ExtractCallingStationID();
|
||||||
RouteAndSendAccountingPacket(Destination, serialNumber, P, false, Secret);
|
auto CalledStationID = P.ExtractCalledStationID();
|
||||||
RADIUSSessionTracker()->AddAccountingSession(Destination, serialNumber, P, Secret);
|
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));
|
||||||
|
}
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
@@ -162,31 +322,46 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
RADIUS::RadiusPacket P((unsigned char *)buffer, size);
|
RADIUS::RadiusPacket P((unsigned char *)buffer, size);
|
||||||
|
auto Destination = P.ExtractProxyStateDestination();
|
||||||
std::lock_guard G(Mutex_);
|
|
||||||
|
|
||||||
std::uint32_t DstIp = P.ExtractProxyStateDestinationIPint();
|
|
||||||
auto DestinationServer = RADIUS_Destinations_.find(DstIp);
|
|
||||||
if (DestinationServer != end(RADIUS_Destinations_)) {
|
|
||||||
if(Logger().trace()) {
|
|
||||||
auto CallingStationID = P.ExtractCallingStationID();
|
auto CallingStationID = P.ExtractCallingStationID();
|
||||||
auto CalledStationID = P.ExtractCalledStationID();
|
auto CalledStationID = P.ExtractCalledStationID();
|
||||||
auto SessionID = P.ExtractAccountingSessionID();
|
Poco::Net::SocketAddress Dst(Destination);
|
||||||
auto MultiSessionID = P.ExtractAccountingMultiSessionID();
|
|
||||||
Logger().trace(
|
std::lock_guard G(Mutex_);
|
||||||
fmt::format("{}: Sending Authentication {} bytes to {}. CalledStationID={} CallingStationID={} SessionID={}:{}",
|
bool UseRADSEC = false;
|
||||||
serialNumber, P.Size(),
|
auto FinalDestination = Route(radius_type::auth, Dst, P, UseRADSEC);
|
||||||
DestinationServer->second->Pool().authConfig.servers[0].ip,
|
if (UseRADSEC) {
|
||||||
CalledStationID, CallingStationID, SessionID, MultiSessionID));
|
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);
|
||||||
}
|
}
|
||||||
if(DestinationServer->second->ServerType()!=GWObjects::RadiusEndpointType::generic) {
|
} else {
|
||||||
DestinationServer->second->SendData(serialNumber,
|
if ((Dst.family() == Poco::Net::SocketAddress::IPv4 &&
|
||||||
(const unsigned char *)buffer, size);
|
AuthenticationSocketV4_ == nullptr) ||
|
||||||
}
|
(Dst.family() == Poco::Net::SocketAddress::IPv6 &&
|
||||||
else {
|
AuthenticationSocketV6_ == nullptr)) {
|
||||||
DestinationServer->second->SendRadiusDataAuthData(
|
poco_debug(
|
||||||
serialNumber, (const unsigned char *)buffer, size);
|
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));
|
||||||
}
|
}
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
@@ -204,35 +379,54 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
RADIUS::RadiusPacket P((unsigned char *)buffer, size);
|
RADIUS::RadiusPacket P((unsigned char *)buffer, size);
|
||||||
auto CallingStationID = P.ExtractCallingStationID();
|
auto Destination = P.ExtractProxyStateDestination();
|
||||||
auto CalledStationID = P.ExtractCalledStationID();
|
|
||||||
Poco::Net::SocketAddress Dst(Destination);
|
|
||||||
|
|
||||||
|
if (Destination.empty()) {
|
||||||
|
Destination = "0.0.0.0:0";
|
||||||
|
}
|
||||||
|
|
||||||
|
Poco::Net::SocketAddress Dst(Destination);
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
std::uint32_t DstIp = P.ExtractProxyStateDestinationIPint();
|
bool UseRADSEC = false;
|
||||||
auto DestinationServer = RADIUS_Destinations_.find(DstIp);
|
auto FinalDestination = Route(radius_type::coa, Dst, P, UseRADSEC);
|
||||||
if (DestinationServer != end(RADIUS_Destinations_)) {
|
if (UseRADSEC) {
|
||||||
poco_trace(Logger(),fmt::format("{}: Sending CoA {} bytes to {}", serialNumber, P.Size(), DestinationServer->second->Pool().coaConfig.servers[0].ip));
|
Poco::Net::SocketAddress RSP(FinalDestination.host(), 0);
|
||||||
if(DestinationServer->second->ServerType()!=GWObjects::RadiusEndpointType::generic) {
|
auto DestinationServer = RADSECservers_.find(RSP);
|
||||||
|
if (DestinationServer != end(RADSECservers_)) {
|
||||||
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer,
|
DestinationServer->second->SendData(serialNumber, (const unsigned char *)buffer,
|
||||||
size);
|
size);
|
||||||
} else {
|
|
||||||
DestinationServer->second->SendRadiusDataCoAData(
|
|
||||||
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) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
poco_warning(Logger(),
|
poco_warning(Logger(),
|
||||||
fmt::format("Bad RADIUS AUTH Packet from {}. Dropped.", serialNumber));
|
fmt::format("Bad RADIUS CoA/DM Packet from {}. Dropped.", serialNumber));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RADIUS_proxy_server::ParseServerList(const GWObjects::RadiusProxyServerConfig &Config,
|
void RADIUS_proxy_server::ParseServerList(const GWObjects::RadiusProxyServerConfig &Config,
|
||||||
std::vector<Destination> &V4,
|
std::vector<Destination> &V4,
|
||||||
std::vector<Destination> &V6, bool setAsDefault,
|
std::vector<Destination> &V6, bool setAsDefault) {
|
||||||
const std::string &poolProxyIp) {
|
|
||||||
uint64_t TotalV4 = 0, TotalV6 = 0;
|
uint64_t TotalV4 = 0, TotalV6 = 0;
|
||||||
|
|
||||||
for (const auto &server : Config.servers) {
|
for (const auto &server : Config.servers) {
|
||||||
@@ -255,9 +449,7 @@ namespace OpenWifi {
|
|||||||
.methodParameters = Config.methodParameters,
|
.methodParameters = Config.methodParameters,
|
||||||
.useAsDefault = setAsDefault,
|
.useAsDefault = setAsDefault,
|
||||||
.useRADSEC = server.radsec,
|
.useRADSEC = server.radsec,
|
||||||
.realms = server.radsecRealms,
|
.realms = server.radsecRealms};
|
||||||
.secret = server.secret,
|
|
||||||
.poolProxyIp = poolProxyIp};
|
|
||||||
|
|
||||||
if (setAsDefault && D.useRADSEC)
|
if (setAsDefault && D.useRADSEC)
|
||||||
DefaultIsRADSEC_ = true;
|
DefaultIsRADSEC_ = true;
|
||||||
@@ -306,11 +498,11 @@ namespace OpenWifi {
|
|||||||
for (const auto &pool : RPC.pools) {
|
for (const auto &pool : RPC.pools) {
|
||||||
RadiusPool NewPool;
|
RadiusPool NewPool;
|
||||||
ParseServerList(pool.authConfig, NewPool.AuthV4, NewPool.AuthV6,
|
ParseServerList(pool.authConfig, NewPool.AuthV4, NewPool.AuthV6,
|
||||||
pool.useByDefault, pool.poolProxyIp);
|
pool.useByDefault);
|
||||||
ParseServerList(pool.acctConfig, NewPool.AcctV4, NewPool.AcctV6,
|
ParseServerList(pool.acctConfig, NewPool.AcctV4, NewPool.AcctV6,
|
||||||
pool.useByDefault, pool.poolProxyIp);
|
pool.useByDefault);
|
||||||
ParseServerList(pool.coaConfig, NewPool.CoaV4, NewPool.CoaV6,
|
ParseServerList(pool.coaConfig, NewPool.CoaV4, NewPool.CoaV6,
|
||||||
pool.useByDefault, pool.poolProxyIp);
|
pool.useByDefault);
|
||||||
Pools_.push_back(NewPool);
|
Pools_.push_back(NewPool);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -329,7 +521,6 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
static bool RealmMatch(const std::string &user_realm, const std::string &realm) {
|
static bool RealmMatch(const std::string &user_realm, const std::string &realm) {
|
||||||
if (realm.find_first_of('*') == std::string::npos)
|
if (realm.find_first_of('*') == std::string::npos)
|
||||||
return user_realm == realm;
|
return user_realm == realm;
|
||||||
@@ -339,9 +530,7 @@ namespace OpenWifi {
|
|||||||
Poco::Net::SocketAddress
|
Poco::Net::SocketAddress
|
||||||
RADIUS_proxy_server::DefaultRoute(radius_type rtype,
|
RADIUS_proxy_server::DefaultRoute(radius_type rtype,
|
||||||
const Poco::Net::SocketAddress &RequestedAddress,
|
const Poco::Net::SocketAddress &RequestedAddress,
|
||||||
const RADIUS::RadiusPacket &P, bool &UseRADSEC,
|
const RADIUS::RadiusPacket &P, bool &UseRADSEC) {
|
||||||
std::string &Secret) {
|
|
||||||
|
|
||||||
bool IsV4 = RequestedAddress.family() == Poco::Net::SocketAddress::IPv4;
|
bool IsV4 = RequestedAddress.family() == Poco::Net::SocketAddress::IPv4;
|
||||||
|
|
||||||
// find the realm...
|
// find the realm...
|
||||||
@@ -356,6 +545,7 @@ namespace OpenWifi {
|
|||||||
if (!server.realms.empty()) {
|
if (!server.realms.empty()) {
|
||||||
for (const auto &realm : server.realms) {
|
for (const auto &realm : server.realms) {
|
||||||
if (RealmMatch(UserRealm, realm)) {
|
if (RealmMatch(UserRealm, realm)) {
|
||||||
|
std::cout << "Realm match..." << std::endl;
|
||||||
UseRADSEC = true;
|
UseRADSEC = true;
|
||||||
return server.Addr;
|
return server.Addr;
|
||||||
}
|
}
|
||||||
@@ -375,18 +565,18 @@ namespace OpenWifi {
|
|||||||
case radius_type::auth: {
|
case radius_type::auth: {
|
||||||
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].AuthV4
|
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].AuthV4
|
||||||
: Pools_[DefaultPoolIndex_].AuthV6,
|
: Pools_[DefaultPoolIndex_].AuthV6,
|
||||||
RequestedAddress, Secret);
|
RequestedAddress);
|
||||||
}
|
|
||||||
case radius_type::coa: {
|
|
||||||
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].CoaV4
|
|
||||||
: Pools_[DefaultPoolIndex_].CoaV6,
|
|
||||||
RequestedAddress, Secret);
|
|
||||||
}
|
}
|
||||||
case radius_type::acct:
|
case radius_type::acct:
|
||||||
default: {
|
default: {
|
||||||
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].AcctV4
|
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].AcctV4
|
||||||
: Pools_[DefaultPoolIndex_].AcctV6,
|
: Pools_[DefaultPoolIndex_].AcctV6,
|
||||||
RequestedAddress, Secret);
|
RequestedAddress);
|
||||||
|
}
|
||||||
|
case radius_type::coa: {
|
||||||
|
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].CoaV4
|
||||||
|
: Pools_[DefaultPoolIndex_].CoaV6,
|
||||||
|
RequestedAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -394,8 +584,8 @@ namespace OpenWifi {
|
|||||||
Poco::Net::SocketAddress
|
Poco::Net::SocketAddress
|
||||||
RADIUS_proxy_server::Route([[maybe_unused]] radius_type rtype,
|
RADIUS_proxy_server::Route([[maybe_unused]] radius_type rtype,
|
||||||
const Poco::Net::SocketAddress &RequestedAddress,
|
const Poco::Net::SocketAddress &RequestedAddress,
|
||||||
const RADIUS::RadiusPacket &P, bool &UseRADSEC,
|
const RADIUS::RadiusPacket &P, bool &UseRADSEC) {
|
||||||
std::string &Secret) {
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
if (Pools_.empty()) {
|
if (Pools_.empty()) {
|
||||||
UseRADSEC = false;
|
UseRADSEC = false;
|
||||||
@@ -404,47 +594,39 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
bool IsV4 = RequestedAddress.family() == Poco::Net::SocketAddress::IPv4;
|
bool IsV4 = RequestedAddress.family() == Poco::Net::SocketAddress::IPv4;
|
||||||
bool useDefault;
|
bool useDefault;
|
||||||
|
|
||||||
useDefault = IsV4 ? RequestedAddress.host() ==
|
useDefault = IsV4 ? RequestedAddress.host() ==
|
||||||
Poco::Net::IPAddress::wildcard(Poco::Net::IPAddress::IPv4)
|
Poco::Net::IPAddress::wildcard(Poco::Net::IPAddress::IPv4)
|
||||||
: RequestedAddress.host() ==
|
: RequestedAddress.host() ==
|
||||||
Poco::Net::IPAddress::wildcard(Poco::Net::IPAddress::IPv6);
|
Poco::Net::IPAddress::wildcard(Poco::Net::IPAddress::IPv6);
|
||||||
|
|
||||||
if (useDefault) {
|
if (useDefault) {
|
||||||
return DefaultRoute(rtype, RequestedAddress, P, UseRADSEC, Secret);
|
return DefaultRoute(rtype, RequestedAddress, P, UseRADSEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto isAddressInPool = [&](const std::vector<Destination> &D, bool &UseRADSEC) -> bool {
|
auto isAddressInPool = [&](const std::vector<Destination> &D, bool &UseRADSEC) -> bool {
|
||||||
for (const auto &entry : D) {
|
for (const auto &entry : D)
|
||||||
if (!entry.poolProxyIp.empty() &&
|
|
||||||
entry.poolProxyIp == RequestedAddress.host().toString()) {
|
|
||||||
UseRADSEC = entry.useRADSEC;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (entry.Addr.host() == RequestedAddress.host()) {
|
if (entry.Addr.host() == RequestedAddress.host()) {
|
||||||
UseRADSEC = entry.useRADSEC;
|
UseRADSEC = entry.useRADSEC;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto &pool : Pools_) {
|
for (auto &i : Pools_) {
|
||||||
// try and match the pool's address to the destination
|
|
||||||
switch (rtype) {
|
switch (rtype) {
|
||||||
case radius_type::coa: {
|
case radius_type::coa: {
|
||||||
if (isAddressInPool((IsV4 ? pool.CoaV4 : pool.CoaV6), UseRADSEC)) {
|
if (isAddressInPool((IsV4 ? i.CoaV4 : i.CoaV6), UseRADSEC)) {
|
||||||
return ChooseAddress(IsV4 ? pool.CoaV4 : pool.CoaV6, RequestedAddress, Secret);
|
return ChooseAddress(IsV4 ? i.CoaV4 : i.CoaV6, RequestedAddress);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case radius_type::auth: {
|
case radius_type::auth: {
|
||||||
if (isAddressInPool((IsV4 ? pool.AuthV4 : pool.AuthV6), UseRADSEC)) {
|
if (isAddressInPool((IsV4 ? i.AuthV4 : i.AuthV6), UseRADSEC)) {
|
||||||
return ChooseAddress(IsV4 ? pool.AuthV4 : pool.AuthV6, RequestedAddress, Secret);
|
return ChooseAddress(IsV4 ? i.AuthV4 : i.AuthV6, RequestedAddress);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case radius_type::acct: {
|
case radius_type::acct: {
|
||||||
if (isAddressInPool((IsV4 ? pool.AcctV4 : pool.AcctV6), UseRADSEC)) {
|
if (isAddressInPool((IsV4 ? i.AcctV4 : i.AcctV6), UseRADSEC)) {
|
||||||
return ChooseAddress(IsV4 ? pool.AcctV4 : pool.AcctV6, RequestedAddress, Secret);
|
return ChooseAddress(IsV4 ? i.AcctV4 : i.AcctV6, RequestedAddress);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@@ -456,13 +638,10 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
Poco::Net::SocketAddress
|
Poco::Net::SocketAddress
|
||||||
RADIUS_proxy_server::ChooseAddress(std::vector<Destination> &Pool,
|
RADIUS_proxy_server::ChooseAddress(std::vector<Destination> &Pool,
|
||||||
const Poco::Net::SocketAddress &OriginalAddress,
|
const Poco::Net::SocketAddress &OriginalAddress) {
|
||||||
std::string &Secret) {
|
|
||||||
|
|
||||||
if (Pool.size() == 1) {
|
if (Pool.size() == 1) {
|
||||||
Secret = Pool[0].secret;
|
return Pool[0].Addr;
|
||||||
auto A = Pool[0].Addr;
|
|
||||||
return A;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Pool[0].strategy == "weighted") {
|
if (Pool[0].strategy == "weighted") {
|
||||||
@@ -478,7 +657,6 @@ namespace OpenWifi {
|
|||||||
index = pos;
|
index = pos;
|
||||||
cur_state = i.state;
|
cur_state = i.state;
|
||||||
found = true;
|
found = true;
|
||||||
Secret = i.secret ;
|
|
||||||
}
|
}
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
@@ -486,9 +664,9 @@ namespace OpenWifi {
|
|||||||
if (!found) {
|
if (!found) {
|
||||||
return OriginalAddress;
|
return OriginalAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pool[index].state += Pool[index].step;
|
Pool[index].state += Pool[index].step;
|
||||||
return Pool[index].Addr;
|
return Pool[index].Addr;
|
||||||
|
|
||||||
} else if (Pool[0].strategy == "round_robin") {
|
} else if (Pool[0].strategy == "round_robin") {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
uint64_t cur_state = std::numeric_limits<uint64_t>::max();
|
uint64_t cur_state = std::numeric_limits<uint64_t>::max();
|
||||||
@@ -501,30 +679,27 @@ namespace OpenWifi {
|
|||||||
if (i.state < cur_state) {
|
if (i.state < cur_state) {
|
||||||
index = pos;
|
index = pos;
|
||||||
cur_state = i.state;
|
cur_state = i.state;
|
||||||
Secret = i.secret;
|
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
pos++;
|
pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
// return OriginalAddress;
|
return OriginalAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pool[index].state += 1;
|
Pool[index].state += 1;
|
||||||
return Pool[index].Addr;
|
return Pool[index].Addr;
|
||||||
} else if (Pool[0].strategy == "random") {
|
} else if (Pool[0].strategy == "random") {
|
||||||
if (Pool.size() > 1) {
|
if (Pool.size() > 1) {
|
||||||
auto index = std::rand() % Pool.size();
|
return Pool[std::rand() % Pool.size()].Addr;
|
||||||
Secret = Pool[index].secret;
|
|
||||||
return Pool[index].Addr;
|
|
||||||
} else {
|
} else {
|
||||||
return OriginalAddress;
|
return OriginalAddress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return OriginalAddress;
|
return OriginalAddress;
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
void RADIUS_proxy_server::SetConfig(const GWObjects::RadiusProxyPoolList &C) {
|
void RADIUS_proxy_server::SetConfig(const GWObjects::RadiusProxyPoolList &C) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
#include "framework/SubSystemServer.h"
|
#include "framework/SubSystemServer.h"
|
||||||
|
|
||||||
#include "RADIUS_Destination.h"
|
#include "RADSEC_server.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
@@ -28,19 +28,23 @@ namespace OpenWifi {
|
|||||||
void Stop() final;
|
void Stop() final;
|
||||||
inline bool Enabled() const { return Enabled_; }
|
inline bool Enabled() const { return Enabled_; }
|
||||||
|
|
||||||
void SendAccountingData(const std::string &serialNumber, const char *buffer, std::size_t size);
|
void OnAccountingSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
|
||||||
|
void
|
||||||
|
OnAuthenticationSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
|
||||||
|
void OnCoASocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
|
||||||
|
|
||||||
|
void SendAccountingData(const std::string &serialNumber, const char *buffer,
|
||||||
|
std::size_t size);
|
||||||
void SendAuthenticationData(const std::string &serialNumber, const char *buffer,
|
void SendAuthenticationData(const std::string &serialNumber, const char *buffer,
|
||||||
std::size_t size);
|
std::size_t size);
|
||||||
void SendCoAData(const std::string &serialNumber, const char *buffer, std::size_t size);
|
void SendCoAData(const std::string &serialNumber, const char *buffer, std::size_t size);
|
||||||
|
|
||||||
void RouteAndSendAccountingPacket(const std::string &Destination, const std::string &serialNumber, RADIUS::RadiusPacket &P, bool reComputeAuthenticator, std::string &Secret);
|
|
||||||
|
|
||||||
void SetConfig(const GWObjects::RadiusProxyPoolList &C);
|
void SetConfig(const GWObjects::RadiusProxyPoolList &C);
|
||||||
void DeleteConfig();
|
void DeleteConfig();
|
||||||
void GetConfig(GWObjects::RadiusProxyPoolList &C);
|
void GetConfig(GWObjects::RadiusProxyPoolList &C);
|
||||||
|
|
||||||
void StartRADIUSDestinations();
|
void StartRADSECServers();
|
||||||
void StopRADIUSDestinations();
|
void StopRADSECServers();
|
||||||
|
|
||||||
struct Destination {
|
struct Destination {
|
||||||
Poco::Net::SocketAddress Addr;
|
Poco::Net::SocketAddress Addr;
|
||||||
@@ -55,20 +59,24 @@ namespace OpenWifi {
|
|||||||
bool useAsDefault = false;
|
bool useAsDefault = false;
|
||||||
bool useRADSEC = false;
|
bool useRADSEC = false;
|
||||||
std::vector<std::string> realms;
|
std::vector<std::string> realms;
|
||||||
std::string secret;
|
|
||||||
std::string poolProxyIp;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool Continue() const { return Running_ && Enabled_ && !Pools_.empty(); }
|
inline bool Continue() const { return Running_ && Enabled_ && !Pools_.empty(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Poco::Net::SocketReactor RadiusReactor_;
|
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV4_;
|
||||||
|
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV6_;
|
||||||
|
std::unique_ptr<Poco::Net::DatagramSocket> AuthenticationSocketV4_;
|
||||||
|
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::Thread RadiusReactorThread_;
|
||||||
|
|
||||||
GWObjects::RadiusProxyPoolList PoolList_;
|
GWObjects::RadiusProxyPoolList PoolList_;
|
||||||
std::string ConfigFilename_;
|
std::string ConfigFilename_;
|
||||||
|
|
||||||
std::map<std::uint32_t, std::unique_ptr<RADIUS_Destination>> RADIUS_Destinations_;
|
std::map<Poco::Net::SocketAddress, std::unique_ptr<RADSEC_server>> RADSECservers_;
|
||||||
|
|
||||||
struct RadiusPool {
|
struct RadiusPool {
|
||||||
std::vector<Destination> AuthV4;
|
std::vector<Destination> AuthV4;
|
||||||
@@ -93,21 +101,18 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
void ParseConfig();
|
void ParseConfig();
|
||||||
void ResetConfig();
|
void ResetConfig();
|
||||||
// Poco::Net::SocketAddress Route(radius_type rtype, const Poco::Net::SocketAddress &A,
|
Poco::Net::SocketAddress Route(radius_type rtype, const Poco::Net::SocketAddress &A,
|
||||||
// const RADIUS::RadiusPacket &P, bool &UseRADSEC, std::string &secret);
|
const RADIUS::RadiusPacket &P, bool &UseRADSEC);
|
||||||
|
|
||||||
void ParseServerList(const GWObjects::RadiusProxyServerConfig &Config,
|
void ParseServerList(const GWObjects::RadiusProxyServerConfig &Config,
|
||||||
std::vector<Destination> &V4,
|
std::vector<Destination> &V4, std::vector<Destination> &V6,
|
||||||
std::vector<Destination> &V6, bool setAsDefault,
|
bool setAsDefault);
|
||||||
const std::string &poolProxyIp);
|
static Poco::Net::SocketAddress
|
||||||
/* static Poco::Net::SocketAddress
|
|
||||||
ChooseAddress(std::vector<Destination> &Pool,
|
ChooseAddress(std::vector<Destination> &Pool,
|
||||||
const Poco::Net::SocketAddress &OriginalAddress, std::string &Secret);
|
const Poco::Net::SocketAddress &OriginalAddress);
|
||||||
Poco::Net::SocketAddress DefaultRoute([[maybe_unused]] radius_type rtype,
|
Poco::Net::SocketAddress DefaultRoute([[maybe_unused]] radius_type rtype,
|
||||||
const Poco::Net::SocketAddress &RequestedAddress,
|
const Poco::Net::SocketAddress &RequestedAddress,
|
||||||
const RADIUS::RadiusPacket &P, bool &UseRADSEC,
|
const RADIUS::RadiusPacket &P, bool &UseRADSEC);
|
||||||
std::string &Secret);
|
};
|
||||||
*/ };
|
|
||||||
|
|
||||||
inline auto RADIUS_proxy_server() { return RADIUS_proxy_server::instance(); }
|
inline auto RADIUS_proxy_server() { return RADIUS_proxy_server::instance(); }
|
||||||
|
|
||||||
|
|||||||
304
src/RADSEC_server.h
Normal file
304
src/RADSEC_server.h
Normal file
@@ -0,0 +1,304 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2022-08-15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||||
|
|
||||||
|
#include "Poco/Crypto/X509Certificate.h"
|
||||||
|
#include "Poco/Net/Context.h"
|
||||||
|
#include "Poco/Net/NetException.h"
|
||||||
|
#include "Poco/Net/SecureStreamSocket.h"
|
||||||
|
#include "Poco/Net/SocketReactor.h"
|
||||||
|
#include "Poco/TemporaryFile.h"
|
||||||
|
|
||||||
|
#include "framework/MicroServiceFuncs.h"
|
||||||
|
|
||||||
|
#include "fmt/format.h"
|
||||||
|
|
||||||
|
#include "AP_WS_Server.h"
|
||||||
|
#include "RADIUS_helpers.h"
|
||||||
|
|
||||||
|
namespace OpenWifi {
|
||||||
|
|
||||||
|
class RADSEC_server : public Poco::Runnable {
|
||||||
|
public:
|
||||||
|
RADSEC_server(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();
|
||||||
|
}
|
||||||
|
|
||||||
|
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();
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool SendData(const std::string &serial_number, const unsigned char *buffer,
|
||||||
|
int length) {
|
||||||
|
try {
|
||||||
|
if (Connected_) {
|
||||||
|
RADIUS::RadiusPacket P(buffer, length);
|
||||||
|
int sent_bytes;
|
||||||
|
if (P.VerifyMessageAuthenticator(Server_.radsecSecret)) {
|
||||||
|
poco_debug(Logger_, fmt::format("{}: {} Sending {} bytes", serial_number,
|
||||||
|
P.PacketType(), length));
|
||||||
|
sent_bytes = Socket_->sendBytes(buffer, length);
|
||||||
|
} else {
|
||||||
|
poco_debug(Logger_, fmt::format("{}: {} Sending {} bytes", serial_number,
|
||||||
|
P.PacketType(), length));
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
onData([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
||||||
|
unsigned char Buffer[4096];
|
||||||
|
|
||||||
|
try {
|
||||||
|
auto NumberOfReceivedBytes = Socket_->receiveBytes(Buffer, sizeof(Buffer));
|
||||||
|
if (NumberOfReceivedBytes >= 20) {
|
||||||
|
RADIUS::RadiusPacket P(Buffer, NumberOfReceivedBytes);
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
} 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.");
|
||||||
|
}
|
||||||
|
} 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.");
|
||||||
|
Disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
onShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
|
||||||
|
poco_warning(Logger_, "Socker socket shutdown. Terminating connection.");
|
||||||
|
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_;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
SecureContext->addCertificateAuthority(cert);
|
||||||
|
}
|
||||||
|
|
||||||
|
Socket_ = std::make_unique<Poco::Net::SecureStreamSocket>(SecureContext);
|
||||||
|
|
||||||
|
Poco::Net::SocketAddress Destination(Server_.ip, Server_.port);
|
||||||
|
|
||||||
|
try {
|
||||||
|
poco_information(Logger_, "Attempting to connect");
|
||||||
|
Socket_->connect(Destination, Poco::Timespan(100, 0));
|
||||||
|
Socket_->completeHandshake();
|
||||||
|
|
||||||
|
if (!Server_.allowSelfSigned) {
|
||||||
|
Socket_->verifyPeerCertificate();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Socket_->havePeerCertificate()) {
|
||||||
|
Peer_Cert_ = std::make_unique<Poco::Crypto::X509Certificate>(
|
||||||
|
Socket_->peerCertificate());
|
||||||
|
}
|
||||||
|
|
||||||
|
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));
|
||||||
|
Reactor_.addEventHandler(
|
||||||
|
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ErrorNotification>(
|
||||||
|
*this, &RADSEC_server::onError));
|
||||||
|
Reactor_.addEventHandler(
|
||||||
|
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ShutdownNotification>(
|
||||||
|
*this, &RADSEC_server::onShutdown));
|
||||||
|
|
||||||
|
Connected_ = true;
|
||||||
|
poco_information(Logger_, fmt::format("Connected. CN={}", CommonName()));
|
||||||
|
return true;
|
||||||
|
} catch (const Poco::Net::NetException &E) {
|
||||||
|
poco_information(Logger_, "Could not connect.");
|
||||||
|
Logger_.log(E);
|
||||||
|
} catch (const Poco::Exception &E) {
|
||||||
|
poco_information(Logger_, "Could not connect.");
|
||||||
|
Logger_.log(E);
|
||||||
|
} catch (...) {
|
||||||
|
poco_information(Logger_, "Could not connect.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Disconnect() {
|
||||||
|
if (Connected_) {
|
||||||
|
std::lock_guard G(LocalMutex_);
|
||||||
|
|
||||||
|
Reactor_.removeEventHandler(
|
||||||
|
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ReadableNotification>(
|
||||||
|
*this, &RADSEC_server::onData));
|
||||||
|
Reactor_.removeEventHandler(
|
||||||
|
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ErrorNotification>(
|
||||||
|
*this, &RADSEC_server::onError));
|
||||||
|
Reactor_.removeEventHandler(
|
||||||
|
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ShutdownNotification>(
|
||||||
|
*this, &RADSEC_server::onShutdown));
|
||||||
|
Socket_->close();
|
||||||
|
Connected_ = false;
|
||||||
|
}
|
||||||
|
poco_information(Logger_, "Disconnecting.");
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
Poco::Base64Decoder ds(is);
|
||||||
|
Poco::StreamCopier::copyStream(ds, sec_file);
|
||||||
|
sec_file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline std::string CommonName() {
|
||||||
|
if (Peer_Cert_)
|
||||||
|
return Peer_Cert_->commonName();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline std::string IssuerName() {
|
||||||
|
if (Peer_Cert_)
|
||||||
|
return Peer_Cert_->issuerName();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline std::string SubjectName() {
|
||||||
|
if (Peer_Cert_)
|
||||||
|
return Peer_Cert_->subjectName();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::recursive_mutex LocalMutex_;
|
||||||
|
Poco::Net::SocketReactor &Reactor_;
|
||||||
|
GWObjects::RadiusProxyServerEntry Server_;
|
||||||
|
Poco::Logger &Logger_;
|
||||||
|
std::unique_ptr<Poco::Net::SecureStreamSocket> Socket_;
|
||||||
|
Poco::Thread ReconnectThread_;
|
||||||
|
std::unique_ptr<Poco::Crypto::X509Certificate> Peer_Cert_;
|
||||||
|
volatile bool Connected_ = false;
|
||||||
|
volatile bool TryAgain_ = true;
|
||||||
|
};
|
||||||
|
} // namespace OpenWifi
|
||||||
@@ -169,12 +169,10 @@ namespace OpenWifi::RESTAPI_RPC {
|
|||||||
|
|
||||||
if (Cmd.ErrorCode == 0 && Cmd.Command == uCentralProtocol::CONFIGURE) {
|
if (Cmd.ErrorCode == 0 && Cmd.Command == uCentralProtocol::CONFIGURE) {
|
||||||
// we need to post a kafka event for this.
|
// we need to post a kafka event for this.
|
||||||
if (Params.has(uCentralProtocol::CONFIG) && Params.isObject(uCentralProtocol::CONFIG)) {
|
if (Params.has(uCentralProtocol::CONFIG)) {
|
||||||
auto Config = Params.get(uCentralProtocol::CONFIG)
|
|
||||||
.extract<Poco::JSON::Object::Ptr>();
|
|
||||||
DeviceConfigurationChangeKafkaEvent KEvent(
|
DeviceConfigurationChangeKafkaEvent KEvent(
|
||||||
Utils::SerialNumberToInt(Cmd.SerialNumber), Utils::Now(),
|
Cmd.SerialNumber, Utils::Now(),
|
||||||
Config);
|
Params.get(uCentralProtocol::CONFIG).toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ namespace OpenWifi {
|
|||||||
poco_debug(Logger(), fmt::format("BLACKLIST-POST: {}", D.serialNumber));
|
poco_debug(Logger(), fmt::format("BLACKLIST-POST: {}", D.serialNumber));
|
||||||
|
|
||||||
Poco::toLowerInPlace(D.serialNumber);
|
Poco::toLowerInPlace(D.serialNumber);
|
||||||
if (StorageService()->IsBlackListed(Utils::MACToInt(D.serialNumber))) {
|
if (StorageService()->IsBlackListed(D.serialNumber)) {
|
||||||
return BadRequest(RESTAPI::Errors::SerialNumberExists);
|
return BadRequest(RESTAPI::Errors::SerialNumberExists);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "Poco/Array.h"
|
#include "Poco/Array.h"
|
||||||
|
#include "Poco/JSON/Stringifier.h"
|
||||||
|
|
||||||
#include "RESTAPI_default_configurations.h"
|
#include "RESTAPI_default_configurations.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
|
|||||||
@@ -1,117 +0,0 @@
|
|||||||
//
|
|
||||||
// License type: BSD 3-Clause License
|
|
||||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
|
||||||
//
|
|
||||||
// Created by stephane bourque on 2023-07-11.
|
|
||||||
// Arilia Wireless Inc.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "RESTAPI/RESTAPI_default_firmware.h"
|
|
||||||
|
|
||||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
|
||||||
#include "StorageService.h"
|
|
||||||
#include "framework/orm.h"
|
|
||||||
#include "framework/ow_constants.h"
|
|
||||||
#include "framework/utils.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
void RESTAPI_default_firmware::DoGet() {
|
|
||||||
std::string deviceType = ORM::Escape(GetBinding(RESTAPI::Protocol::DEVICETYPE, ""));
|
|
||||||
GWObjects::DefaultFirmware Firmware;
|
|
||||||
if (StorageService()->GetDefaultFirmware(deviceType, Firmware)) {
|
|
||||||
return Object(Firmware);
|
|
||||||
}
|
|
||||||
NotFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RESTAPI_default_firmware::DoDelete() {
|
|
||||||
std::string deviceType = ORM::Escape(GetBinding(RESTAPI::Protocol::DEVICETYPE, ""));
|
|
||||||
if (deviceType.empty()) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StorageService()->DeleteDefaultFirmware(deviceType)) {
|
|
||||||
return OK();
|
|
||||||
}
|
|
||||||
BadRequest(RESTAPI::Errors::CouldNotBeDeleted);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RESTAPI_default_firmware::DoPost() {
|
|
||||||
std::string deviceType = GetBinding(RESTAPI::Protocol::DEVICETYPE, "");
|
|
||||||
|
|
||||||
if (deviceType.empty()) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (StorageService()->DefaultFirmwareAlreadyExists(deviceType)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::DefFirmwareNameExists);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto &Obj = ParsedBody_;
|
|
||||||
GWObjects::DefaultFirmware Firmware;
|
|
||||||
if (!Firmware.from_json(Obj)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Firmware.uri.empty() || Firmware.revision.empty()) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Poco::URI FirmwareURI(Firmware.uri);
|
|
||||||
} catch (...) {
|
|
||||||
return BadRequest(RESTAPI::Errors::InvalidURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
Firmware.Created = Firmware.LastModified = Utils::Now();
|
|
||||||
if (StorageService()->CreateDefaultFirmware(Firmware)) {
|
|
||||||
GWObjects::DefaultFirmware ModifiedFirmware;
|
|
||||||
StorageService()->GetDefaultFirmware(deviceType, ModifiedFirmware);
|
|
||||||
return Object(ModifiedFirmware);
|
|
||||||
}
|
|
||||||
BadRequest(RESTAPI::Errors::RecordNotCreated);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RESTAPI_default_firmware::DoPut() {
|
|
||||||
std::string deviceType = GetBinding(RESTAPI::Protocol::DEVICETYPE, "");
|
|
||||||
|
|
||||||
const auto &Obj = ParsedBody_;
|
|
||||||
GWObjects::DefaultFirmware NewFirmware;
|
|
||||||
if (!NewFirmware.from_json(Obj)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
GWObjects::DefaultFirmware Existing;
|
|
||||||
if (!StorageService()->GetDefaultFirmware(deviceType, Existing)) {
|
|
||||||
return NotFound();
|
|
||||||
}
|
|
||||||
|
|
||||||
Existing.LastModified = Utils::Now();
|
|
||||||
AssignIfPresent(Obj, "description", Existing.Description);
|
|
||||||
AssignIfPresent(Obj, "imageCreationDate", Existing.imageCreationDate);
|
|
||||||
AssignIfPresent(Obj, "revision", Existing.revision);
|
|
||||||
|
|
||||||
|
|
||||||
if (Obj->has("uri")) {
|
|
||||||
if(NewFirmware.uri.empty()) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Poco::URI FirmwareURI(NewFirmware.uri);
|
|
||||||
} catch (...) {
|
|
||||||
return BadRequest(RESTAPI::Errors::InvalidURI);
|
|
||||||
}
|
|
||||||
Existing.uri = NewFirmware.uri;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (StorageService()->UpdateDefaultFirmware(Existing)) {
|
|
||||||
GWObjects::DefaultFirmware ModifiedFirmware;
|
|
||||||
|
|
||||||
StorageService()->GetDefaultFirmware(deviceType, ModifiedFirmware);
|
|
||||||
return Object(ModifiedFirmware);
|
|
||||||
}
|
|
||||||
|
|
||||||
BadRequest(RESTAPI::Errors::RecordNotUpdated);
|
|
||||||
}
|
|
||||||
} // namespace OpenWifi
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2023-07-11.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "framework/RESTAPI_Handler.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
class RESTAPI_default_firmware : public RESTAPIHandler {
|
|
||||||
public:
|
|
||||||
RESTAPI_default_firmware(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
|
|
||||||
RESTAPI_GenericServerAccounting &Server,
|
|
||||||
uint64_t TransactionId, bool Internal)
|
|
||||||
: RESTAPIHandler(bindings, L,
|
|
||||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
|
||||||
Poco::Net::HTTPRequest::HTTP_POST,
|
|
||||||
Poco::Net::HTTPRequest::HTTP_PUT,
|
|
||||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
|
||||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
|
||||||
Server, TransactionId, Internal) {}
|
|
||||||
static auto PathName() {
|
|
||||||
return std::list<std::string>{"/api/v1/default_firmware/{deviceType}"};
|
|
||||||
}
|
|
||||||
void DoGet() final;
|
|
||||||
void DoDelete() final;
|
|
||||||
void DoPost() final;
|
|
||||||
void DoPut() final;
|
|
||||||
};
|
|
||||||
} // namespace OpenWifi
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2023-07-11.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "RESTAPI_default_firmwares.h"
|
|
||||||
|
|
||||||
#include "Poco/Array.h"
|
|
||||||
|
|
||||||
#include "RESTAPI_default_firmwares.h"
|
|
||||||
#include "StorageService.h"
|
|
||||||
#include "framework/ow_constants.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
void RESTAPI_default_firmwares::DoGet() {
|
|
||||||
|
|
||||||
if (QB_.CountOnly) {
|
|
||||||
auto Count = StorageService()->GetDefaultFirmwaresCount();
|
|
||||||
return ReturnCountOnly(Count);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<GWObjects::DefaultFirmware> Firmwares;
|
|
||||||
StorageService()->GetDefaultFirmwares(QB_.Offset, QB_.Limit, Firmwares);
|
|
||||||
return Object(RESTAPI::Protocol::FIRMWARES, Firmwares);
|
|
||||||
}
|
|
||||||
} // namespace OpenWifi
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2023-07-11.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "framework/RESTAPI_Handler.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
class RESTAPI_default_firmwares : public RESTAPIHandler {
|
|
||||||
public:
|
|
||||||
RESTAPI_default_firmwares(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
|
|
||||||
RESTAPI_GenericServerAccounting &Server,
|
|
||||||
uint64_t TransactionId, bool Internal)
|
|
||||||
: RESTAPIHandler(bindings, L,
|
|
||||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
|
||||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
|
||||||
Server, TransactionId, Internal){};
|
|
||||||
static auto PathName() { return std::list<std::string>{"/api/v1/default_firmwares"}; }
|
|
||||||
void DoGet() final;
|
|
||||||
void DoDelete() final{};
|
|
||||||
void DoPost() final{};
|
|
||||||
void DoPut() final{};
|
|
||||||
};
|
|
||||||
} // namespace OpenWifi
|
|
||||||
@@ -87,7 +87,7 @@ namespace OpenWifi {
|
|||||||
poco_debug(
|
poco_debug(
|
||||||
Logger_,
|
Logger_,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"Command RTTY TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
|
"Command rtty TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
|
||||||
TransactionId_, UUID, RPC, Poco::Thread::current()->id()));
|
TransactionId_, UUID, RPC, Poco::Thread::current()->id()));
|
||||||
return Rtty(UUID, RPC, 60000ms, Restrictions);
|
return Rtty(UUID, RPC, 60000ms, Restrictions);
|
||||||
};
|
};
|
||||||
@@ -163,11 +163,8 @@ namespace OpenWifi {
|
|||||||
{APCommands::Commands::telemetry, false, true, &RESTAPI_device_commandHandler::Telemetry,
|
{APCommands::Commands::telemetry, false, true, &RESTAPI_device_commandHandler::Telemetry,
|
||||||
30000ms},
|
30000ms},
|
||||||
{APCommands::Commands::ping, false, true, &RESTAPI_device_commandHandler::Ping, 60000ms},
|
{APCommands::Commands::ping, false, true, &RESTAPI_device_commandHandler::Ping, 60000ms},
|
||||||
{APCommands::Commands::rrm, false, true, &RESTAPI_device_commandHandler::RRM, 60000ms},
|
{APCommands::Commands::script, false, true, &RESTAPI_device_commandHandler::Script,
|
||||||
{APCommands::Commands::certupdate, false, true, &RESTAPI_device_commandHandler::CertUpdate, 60000ms},
|
300000ms}};
|
||||||
{APCommands::Commands::transfer, false, true, &RESTAPI_device_commandHandler::Transfer, 60000ms},
|
|
||||||
{APCommands::Commands::script, false, true, &RESTAPI_device_commandHandler::Script, 60000ms}
|
|
||||||
};
|
|
||||||
|
|
||||||
void RESTAPI_device_commandHandler::DoPost() {
|
void RESTAPI_device_commandHandler::DoPost() {
|
||||||
if (!ValidateParameters()) {
|
if (!ValidateParameters()) {
|
||||||
@@ -312,7 +309,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
if (AP_WS_Server()->GetState(SerialNumber_, State)) {
|
if (AP_WS_Server()->GetState(SerialNumber_, State)) {
|
||||||
Poco::JSON::Object RetObject;
|
Poco::JSON::Object RetObject;
|
||||||
State.to_json(SerialNumber_, RetObject);
|
State.to_json(RetObject);
|
||||||
return ReturnObject(RetObject);
|
return ReturnObject(RetObject);
|
||||||
} else {
|
} else {
|
||||||
Poco::JSON::Object RetObject;
|
Poco::JSON::Object RetObject;
|
||||||
@@ -409,7 +406,6 @@ namespace OpenWifi {
|
|||||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
||||||
poco_debug(Logger_, fmt::format("PING({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC,
|
poco_debug(Logger_, fmt::format("PING({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC,
|
||||||
TransactionId_, Requester(), SerialNumber_));
|
TransactionId_, Requester(), SerialNumber_));
|
||||||
|
|
||||||
const auto &Obj = ParsedBody_;
|
const auto &Obj = ParsedBody_;
|
||||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
|
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
|
||||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||||
@@ -463,14 +459,6 @@ namespace OpenWifi {
|
|||||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RESTAPI_device_commandHandler::IsDeviceSimulated(std::string &Serial) {
|
|
||||||
GWObjects::Device Device;
|
|
||||||
if(StorageService()->GetDevice(Serial,Device)) {
|
|
||||||
return Device.simulated;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RESTAPI_device_commandHandler::CallCanceled(const char *Cmd, const std::string &UUID,
|
void RESTAPI_device_commandHandler::CallCanceled(const char *Cmd, const std::string &UUID,
|
||||||
uint64_t RPC,
|
uint64_t RPC,
|
||||||
const OpenWifi::RESTAPI::Errors::msg &Err) {
|
const OpenWifi::RESTAPI::Errors::msg &Err) {
|
||||||
@@ -486,10 +474,6 @@ namespace OpenWifi {
|
|||||||
poco_debug(Logger_, fmt::format("SCRIPT({},{}): TID={} user={} serial={}", CMD_UUID,
|
poco_debug(Logger_, fmt::format("SCRIPT({},{}): TID={} user={} serial={}", CMD_UUID,
|
||||||
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||||
|
|
||||||
if(IsDeviceSimulated(SerialNumber_)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto &Obj = ParsedBody_;
|
const auto &Obj = ParsedBody_;
|
||||||
GWObjects::ScriptRequest SCR;
|
GWObjects::ScriptRequest SCR;
|
||||||
if (!SCR.from_json(Obj)) {
|
if (!SCR.from_json(Obj)) {
|
||||||
@@ -915,10 +899,6 @@ namespace OpenWifi {
|
|||||||
poco_debug(Logger_, fmt::format("TRACE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC,
|
poco_debug(Logger_, fmt::format("TRACE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC,
|
||||||
TransactionId_, Requester(), SerialNumber_));
|
TransactionId_, Requester(), SerialNumber_));
|
||||||
|
|
||||||
if(IsDeviceSimulated(SerialNumber_)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto &Obj = ParsedBody_;
|
const auto &Obj = ParsedBody_;
|
||||||
|
|
||||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||||
@@ -976,12 +956,6 @@ namespace OpenWifi {
|
|||||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
||||||
poco_debug(Logger_, fmt::format("WIFISCAN({},{}): TID={} user={} serial={}", CMD_UUID,
|
poco_debug(Logger_, fmt::format("WIFISCAN({},{}): TID={} user={} serial={}", CMD_UUID,
|
||||||
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||||
|
|
||||||
|
|
||||||
if(IsDeviceSimulated(SerialNumber_)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto &Obj = ParsedBody_;
|
const auto &Obj = ParsedBody_;
|
||||||
|
|
||||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||||
@@ -1037,10 +1011,6 @@ namespace OpenWifi {
|
|||||||
poco_debug(Logger_, fmt::format("EVENT-QUEUE({},{}): TID={} user={} serial={}", CMD_UUID,
|
poco_debug(Logger_, fmt::format("EVENT-QUEUE({},{}): TID={} user={} serial={}", CMD_UUID,
|
||||||
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||||
|
|
||||||
if(IsDeviceSimulated(SerialNumber_)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto &Obj = ParsedBody_;
|
const auto &Obj = ParsedBody_;
|
||||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) && Obj->isArray(RESTAPI::Protocol::TYPES)) {
|
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) && Obj->isArray(RESTAPI::Protocol::TYPES)) {
|
||||||
|
|
||||||
@@ -1085,10 +1055,6 @@ namespace OpenWifi {
|
|||||||
poco_debug(Logger_, fmt::format("FORCE-REQUEST({},{}): TID={} user={} serial={}", CMD_UUID,
|
poco_debug(Logger_, fmt::format("FORCE-REQUEST({},{}): TID={} user={} serial={}", CMD_UUID,
|
||||||
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||||
|
|
||||||
if(IsDeviceSimulated(SerialNumber_)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto &Obj = ParsedBody_;
|
const auto &Obj = ParsedBody_;
|
||||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) && Obj->has(uCentralProtocol::MESSAGE)) {
|
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) && Obj->has(uCentralProtocol::MESSAGE)) {
|
||||||
|
|
||||||
@@ -1129,16 +1095,15 @@ namespace OpenWifi {
|
|||||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DBGLINE \
|
||||||
|
{ std::cout << __LINE__ << std::endl; }
|
||||||
|
|
||||||
void RESTAPI_device_commandHandler::Rtty(
|
void RESTAPI_device_commandHandler::Rtty(
|
||||||
const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout,
|
const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout,
|
||||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
||||||
poco_debug(Logger_, fmt::format("RTTY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC,
|
poco_debug(Logger_, fmt::format("RTTY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC,
|
||||||
TransactionId_, Requester(), SerialNumber_));
|
TransactionId_, Requester(), SerialNumber_));
|
||||||
|
|
||||||
if(IsDeviceSimulated(SerialNumber_)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Restrictions.developer && Restrictions.rtty) {
|
if (!Restrictions.developer && Restrictions.rtty) {
|
||||||
return BadRequest(RESTAPI::Errors::DeviceIsRestricted);
|
return BadRequest(RESTAPI::Errors::DeviceIsRestricted);
|
||||||
}
|
}
|
||||||
@@ -1147,11 +1112,6 @@ namespace OpenWifi {
|
|||||||
GWObjects::Device Device;
|
GWObjects::Device Device;
|
||||||
|
|
||||||
if (StorageService()->GetDevice(SerialNumber_, Device)) {
|
if (StorageService()->GetDevice(SerialNumber_, Device)) {
|
||||||
|
|
||||||
if(Device.simulated) {
|
|
||||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::uint64_t rtty_sid = 0;
|
static std::uint64_t rtty_sid = 0;
|
||||||
rtty_sid += std::rand();
|
rtty_sid += std::rand();
|
||||||
GWObjects::RttySessionDetails Rtty{
|
GWObjects::RttySessionDetails Rtty{
|
||||||
@@ -1169,7 +1129,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
if (RTTYS_server()->UseInternal()) {
|
if (RTTYS_server()->UseInternal()) {
|
||||||
std::uint64_t SN = Utils::SerialNumberToInt(SerialNumber_);
|
std::uint64_t SN = Utils::SerialNumberToInt(SerialNumber_);
|
||||||
bool mTLS = AP_WS_Server()->DeviceRequiresSecureRTTY(SN);
|
bool mTLS = AP_WS_Server()->DeviceRequiresSecureRtty(SN);
|
||||||
auto Hash = Utils::ComputeHash(UserInfo_.webtoken.refresh_token_, Utils::Now());
|
auto Hash = Utils::ComputeHash(UserInfo_.webtoken.refresh_token_, Utils::Now());
|
||||||
Rtty.Token = Hash.substr(0, RTTY_DEVICE_TOKEN_LENGTH);
|
Rtty.Token = Hash.substr(0, RTTY_DEVICE_TOKEN_LENGTH);
|
||||||
if (!RTTYS_server()->CreateEndPoint(Rtty.ConnectionId, Rtty.Token, Requester(),
|
if (!RTTYS_server()->CreateEndPoint(Rtty.ConnectionId, Rtty.Token, Requester(),
|
||||||
@@ -1225,10 +1185,6 @@ namespace OpenWifi {
|
|||||||
poco_debug(Logger_, fmt::format("TELEMETRY({},{}): TID={} user={} serial={}", CMD_UUID,
|
poco_debug(Logger_, fmt::format("TELEMETRY({},{}): TID={} user={} serial={}", CMD_UUID,
|
||||||
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||||
|
|
||||||
if(IsDeviceSimulated(SerialNumber_)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto &Obj = ParsedBody_;
|
const auto &Obj = ParsedBody_;
|
||||||
|
|
||||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) && Obj->has(RESTAPI::Protocol::INTERVAL) &&
|
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) && Obj->has(RESTAPI::Protocol::INTERVAL) &&
|
||||||
@@ -1342,163 +1298,4 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RESTAPI_device_commandHandler::RRM(
|
|
||||||
const std::string &CMD_UUID, uint64_t CMD_RPC,
|
|
||||||
[[maybe_unused]] std::chrono::milliseconds timeout,
|
|
||||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
|
||||||
|
|
||||||
poco_debug(Logger_, fmt::format("RRM({},{}): TID={} user={} serial={}", CMD_UUID,
|
|
||||||
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
|
||||||
|
|
||||||
if(IsDeviceSimulated(SerialNumber_)) {
|
|
||||||
CallCanceled("RRM", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported);
|
|
||||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(UserInfo_.userinfo.userRole != SecurityObjects::ROOT &&
|
|
||||||
UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) {
|
|
||||||
CallCanceled("RRM", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED);
|
|
||||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!ParsedBody_->has("actions") || !ParsedBody_->isArray("actions")) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto &Actions = *ParsedBody_->getArray("actions");
|
|
||||||
// perform some validation on the commands.
|
|
||||||
for(const auto &action:Actions) {
|
|
||||||
auto ActionDetails = action.extract<Poco::JSON::Object::Ptr>();
|
|
||||||
if(!ActionDetails->has("action")) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
auto ActionStr = ActionDetails->get("action").toString();
|
|
||||||
if( ActionStr != "kick"
|
|
||||||
&& ActionStr != "channel_switch"
|
|
||||||
&& ActionStr != "tx_power"
|
|
||||||
&& ActionStr != "beacon_request"
|
|
||||||
&& ActionStr != "bss_transition"
|
|
||||||
&& ActionStr != "neighbors" ) {
|
|
||||||
return BadRequest(RESTAPI::Errors::InvalidRRMAction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Poco::JSON::Object Params;
|
|
||||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
|
||||||
Params.set(uCentralProtocol::ACTIONS, Actions);
|
|
||||||
|
|
||||||
GWObjects::CommandDetails Cmd;
|
|
||||||
Cmd.SerialNumber = SerialNumber_;
|
|
||||||
Cmd.SubmittedBy = Requester();
|
|
||||||
Cmd.UUID = CMD_UUID;
|
|
||||||
Cmd.Command = uCentralProtocol::RRM;
|
|
||||||
std::ostringstream os;
|
|
||||||
Params.stringify(os);
|
|
||||||
Cmd.Details = os.str();
|
|
||||||
Cmd.RunAt = 0;
|
|
||||||
Cmd.ErrorCode = 0;
|
|
||||||
Cmd.WaitingForFile = 0;
|
|
||||||
Cmd.Status= "completed";
|
|
||||||
if(CommandManager()->FireAndForget(SerialNumber_, uCentralProtocol::RRM, Params)) {
|
|
||||||
StorageService()->AddCommand(SerialNumber_, Cmd,
|
|
||||||
Storage::CommandExecutionType::COMMAND_COMPLETED);
|
|
||||||
Cmd.Status= "completed";
|
|
||||||
return OK();
|
|
||||||
}
|
|
||||||
Cmd.Status= "failed"; // should never happen
|
|
||||||
StorageService()->AddCommand(SerialNumber_, Cmd,
|
|
||||||
Storage::CommandExecutionType::COMMAND_COMPLETED);
|
|
||||||
return BadRequest(RESTAPI::Errors::CouldNotPerformCommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RESTAPI_device_commandHandler::Transfer(
|
|
||||||
const std::string &CMD_UUID, uint64_t CMD_RPC,
|
|
||||||
[[maybe_unused]] std::chrono::milliseconds timeout,
|
|
||||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
|
||||||
|
|
||||||
if(UserInfo_.userinfo.userRole != SecurityObjects::ROOT &&
|
|
||||||
UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) {
|
|
||||||
CallCanceled("RRM", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED);
|
|
||||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
|
||||||
}
|
|
||||||
|
|
||||||
poco_debug(Logger_, fmt::format("TRANSFER({},{}): TID={} user={} serial={}", CMD_UUID,
|
|
||||||
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
|
||||||
|
|
||||||
if(IsDeviceSimulated(SerialNumber_)) {
|
|
||||||
CallCanceled("RRM", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported);
|
|
||||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
GWObjects::DeviceTransferRequest TR;
|
|
||||||
if(!TR.from_json(ParsedBody_)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
GWObjects::CommandDetails Cmd;
|
|
||||||
Cmd.SerialNumber = SerialNumber_;
|
|
||||||
Cmd.SubmittedBy = Requester();
|
|
||||||
Cmd.UUID = CMD_UUID;
|
|
||||||
Cmd.Command = uCentralProtocol::TRANSFER;
|
|
||||||
std::ostringstream os;
|
|
||||||
ParsedBody_->stringify(os);
|
|
||||||
Cmd.Details = os.str();
|
|
||||||
Cmd.RunAt = 0;
|
|
||||||
Cmd.ErrorCode = 0;
|
|
||||||
Cmd.WaitingForFile = 0;
|
|
||||||
|
|
||||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::transfer, false, Cmd,
|
|
||||||
*ParsedBody_, *Request, *Response, timeout, nullptr, this,
|
|
||||||
Logger_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RESTAPI_device_commandHandler::CertUpdate(
|
|
||||||
const std::string &CMD_UUID, uint64_t CMD_RPC,
|
|
||||||
[[maybe_unused]] std::chrono::milliseconds timeout,
|
|
||||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
|
||||||
|
|
||||||
poco_debug(Logger_, fmt::format("CERTUPDATE({},{}): TID={} user={} serial={}", CMD_UUID,
|
|
||||||
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
|
||||||
|
|
||||||
if(UserInfo_.userinfo.userRole != SecurityObjects::ROOT &&
|
|
||||||
UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) {
|
|
||||||
CallCanceled("RRM", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED);
|
|
||||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(IsDeviceSimulated(SerialNumber_)) {
|
|
||||||
CallCanceled("RRM", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported);
|
|
||||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
|
||||||
}
|
|
||||||
|
|
||||||
GWObjects::DeviceCertificateUpdateRequest CR;
|
|
||||||
if(!CR.from_json(ParsedBody_)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
GWObjects::DeviceTransferRequest TR;
|
|
||||||
if(!TR.from_json(ParsedBody_)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
GWObjects::CommandDetails Cmd;
|
|
||||||
Cmd.SerialNumber = SerialNumber_;
|
|
||||||
Cmd.SubmittedBy = Requester();
|
|
||||||
Cmd.UUID = CMD_UUID;
|
|
||||||
Cmd.Command = uCentralProtocol::CERTUPDATE;
|
|
||||||
std::ostringstream os;
|
|
||||||
ParsedBody_->stringify(os);
|
|
||||||
Cmd.Details = os.str();
|
|
||||||
Cmd.RunAt = 0;
|
|
||||||
Cmd.ErrorCode = 0;
|
|
||||||
Cmd.WaitingForFile = 0;
|
|
||||||
|
|
||||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::certupdate, false, Cmd,
|
|
||||||
*ParsedBody_, *Request, *Response, timeout, nullptr, this,
|
|
||||||
Logger_);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
|
|||||||
@@ -34,8 +34,6 @@ namespace OpenWifi {
|
|||||||
void GetChecks();
|
void GetChecks();
|
||||||
void DeleteChecks();
|
void DeleteChecks();
|
||||||
|
|
||||||
bool IsDeviceSimulated(std::string &Serial);
|
|
||||||
|
|
||||||
void Configure(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
void Configure(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
||||||
const GWObjects::DeviceRestrictions &R);
|
const GWObjects::DeviceRestrictions &R);
|
||||||
void Upgrade(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
void Upgrade(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
||||||
@@ -62,12 +60,6 @@ namespace OpenWifi {
|
|||||||
const GWObjects::DeviceRestrictions &R);
|
const GWObjects::DeviceRestrictions &R);
|
||||||
void Script(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
void Script(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
||||||
const GWObjects::DeviceRestrictions &R);
|
const GWObjects::DeviceRestrictions &R);
|
||||||
void RRM(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
|
||||||
const GWObjects::DeviceRestrictions &R);
|
|
||||||
void CertUpdate(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
|
||||||
const GWObjects::DeviceRestrictions &R);
|
|
||||||
void Transfer(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
|
||||||
const GWObjects::DeviceRestrictions &R);
|
|
||||||
|
|
||||||
static auto PathName() {
|
static auto PathName() {
|
||||||
return std::list<std::string>{"/api/v1/device/{serialNumber}/{command}"};
|
return std::list<std::string>{"/api/v1/device/{serialNumber}/{command}"};
|
||||||
|
|||||||
@@ -41,10 +41,6 @@ namespace OpenWifi {
|
|||||||
void RESTAPI_device_handler::DoDelete() {
|
void RESTAPI_device_handler::DoDelete() {
|
||||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||||
|
|
||||||
if(!RESTAPI_utils::IsRootOrAdmin(UserInfo_.userinfo)) {
|
|
||||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Utils::NormalizeMac(SerialNumber)) {
|
if (!Utils::NormalizeMac(SerialNumber)) {
|
||||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace OpenWifi {
|
|||||||
Device.to_json(DeviceInfo);
|
Device.to_json(DeviceInfo);
|
||||||
Answer.set("deviceInfo", DeviceInfo);
|
Answer.set("deviceInfo", DeviceInfo);
|
||||||
Poco::JSON::Object CSInfo;
|
Poco::JSON::Object CSInfo;
|
||||||
CS.to_json(Device.SerialNumber, CSInfo);
|
CS.to_json(CSInfo);
|
||||||
Answer.set("connectionInfo", CSInfo);
|
Answer.set("connectionInfo", CSInfo);
|
||||||
Poco::JSON::Object HCInfo;
|
Poco::JSON::Object HCInfo;
|
||||||
HC.to_json(HCInfo);
|
HC.to_json(HCInfo);
|
||||||
|
|||||||
@@ -158,63 +158,4 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
ReturnObject(RetObj);
|
ReturnObject(RetObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ValidMacPatternOnlyChars(const std::string &s) {
|
|
||||||
return std::for_each(s.begin(),s.end(),[](const char c) {
|
|
||||||
if(c=='%') return true;
|
|
||||||
if(c>='0' && c<='9') return true;
|
|
||||||
if(c>='a' && c<='f') return true;
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void RESTAPI_devices_handler::DoDelete() {
|
|
||||||
|
|
||||||
if(!RESTAPI_utils::IsRootOrAdmin(UserInfo_.userinfo)) {
|
|
||||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(GetBoolParameter("simulatedDevices",false)) {
|
|
||||||
auto F = []() ->void {
|
|
||||||
StorageService()->DeleteSimulatedDevice("");
|
|
||||||
};
|
|
||||||
std::thread T(F);
|
|
||||||
T.detach();
|
|
||||||
return OK();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!QB_.Select.empty() && !Utils::ValidSerialNumbers(QB_.Select)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!QB_.Select.empty()) {
|
|
||||||
for(auto &serialNumber:QB_.Select) {
|
|
||||||
StorageService()->DeleteDevice(serialNumber);
|
|
||||||
}
|
|
||||||
return OK();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto SimulatedOnly = GetBoolParameter("simulatedOnly",false);
|
|
||||||
auto oldestContact = GetParameter("oldestContact",0);
|
|
||||||
if(oldestContact!=0) {
|
|
||||||
StorageService()->DeleteDevices(oldestContact,SimulatedOnly);
|
|
||||||
return OK();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto macPattern = GetParameter("macPattern","");
|
|
||||||
if(macPattern.empty()) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
// rules out wrong values.
|
|
||||||
Poco::toLowerInPlace(macPattern);
|
|
||||||
Poco::replaceInPlace(macPattern,"*","%");
|
|
||||||
if(!ValidMacPatternOnlyChars(macPattern)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
StorageService()->DeleteDevices(macPattern, SimulatedOnly);
|
|
||||||
return OK();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
@@ -18,12 +18,11 @@ namespace OpenWifi {
|
|||||||
bool Internal)
|
bool Internal)
|
||||||
: RESTAPIHandler(bindings, L,
|
: RESTAPIHandler(bindings, L,
|
||||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
|
||||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||||
Server, TransactionId, Internal){};
|
Server, TransactionId, Internal){};
|
||||||
static auto PathName() { return std::list<std::string>{"/api/v1/devices"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/devices"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoDelete() final;
|
void DoDelete() final{};
|
||||||
void DoPost() final{};
|
void DoPost() final{};
|
||||||
void DoPut() final{};
|
void DoPut() final{};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,11 +8,6 @@
|
|||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
static bool ValidRadiusPoolServerType(const std::string &T) {
|
|
||||||
static std::set<std::string> Types{ "radsec", "generic", "orion", "globalreach"};
|
|
||||||
return Types.find(T)!=Types.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RESTAPI_radiusProxyConfig_handler::DoGet() {
|
void RESTAPI_radiusProxyConfig_handler::DoGet() {
|
||||||
Logger_.information(fmt::format("GET-RADIUS-PROXY-CONFIG: TID={} user={} thr_id={}",
|
Logger_.information(fmt::format("GET-RADIUS-PROXY-CONFIG: TID={} user={} thr_id={}",
|
||||||
TransactionId_, Requester(),
|
TransactionId_, Requester(),
|
||||||
@@ -49,22 +44,10 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Logically validate the config.
|
// Logically validate the config.
|
||||||
for (auto &pool : C.pools) {
|
for (const auto &pool : C.pools) {
|
||||||
if (pool.name.empty()) {
|
if (pool.name.empty()) {
|
||||||
return BadRequest(RESTAPI::Errors::PoolNameInvalid);
|
return BadRequest(RESTAPI::Errors::PoolNameInvalid);
|
||||||
}
|
}
|
||||||
if (pool.radsecPoolType.empty()) {
|
|
||||||
pool.radsecPoolType = "generic";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!ValidRadiusPoolServerType(pool.radsecPoolType)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::NotAValidRadiusPoolType);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pool.radsecKeepAlive==0) {
|
|
||||||
pool.radsecKeepAlive=25;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &config : {pool.acctConfig, pool.authConfig, pool.coaConfig}) {
|
for (const auto &config : {pool.acctConfig, pool.authConfig, pool.coaConfig}) {
|
||||||
if (config.servers.empty())
|
if (config.servers.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -1,141 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2023-04-02.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "RESTAPI_radiussessions_handler.h"
|
|
||||||
#include <RESTObjects/RESTAPI_GWobjects.h>
|
|
||||||
#include <RADIUSSessionTracker.h>
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
|
|
||||||
bool MayBeAMAC(const std::string &mac) {
|
|
||||||
return std::all_of(mac.begin(),mac.end(),[](char c)->bool {
|
|
||||||
if ((c>='0' && c<='9') ||
|
|
||||||
(c>='a' && c<='f') ||
|
|
||||||
(c>='A' && c<='F') ||
|
|
||||||
(c==':') ||
|
|
||||||
(c=='-') ||
|
|
||||||
(c=='*')) return true;
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string InsertDelimiters(const std::string &mac, int first=1, char delimiter=':') {
|
|
||||||
std::string res;
|
|
||||||
std::size_t index=0;
|
|
||||||
for(auto c:mac) {
|
|
||||||
res += c;
|
|
||||||
index++;
|
|
||||||
if(index<mac.size()) {
|
|
||||||
if (!first)
|
|
||||||
res += delimiter;
|
|
||||||
}
|
|
||||||
first = 1-first;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string StripDelimiters(const std::string &V) {
|
|
||||||
std::string Res;
|
|
||||||
std::for_each(V.begin(),V.end(),[&](char c){ if(c!=':' && c!='-') { Res += c; }});
|
|
||||||
return Res;
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string ConvertToMac(const std::string & V) {
|
|
||||||
auto res = V;
|
|
||||||
Poco::toUpperInPlace(res);
|
|
||||||
res = StripDelimiters(res);
|
|
||||||
if(res.size()==12) {
|
|
||||||
res = InsertDelimiters(res);
|
|
||||||
} else {
|
|
||||||
if(res.find_first_of('*')==std::string::npos) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if(res[0]=='*') {
|
|
||||||
res = InsertDelimiters(res, 1 - (res.size() % 2) );
|
|
||||||
} else {
|
|
||||||
res = InsertDelimiters(res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RESTAPI_radiussessions_handler::DoGet() {
|
|
||||||
|
|
||||||
if(GetBoolParameter("serialNumberOnly")) {
|
|
||||||
std::vector<std::string> L;
|
|
||||||
RADIUSSessionTracker()->GetAPList(L);
|
|
||||||
return ReturnObject("serialNumbers",L);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto mac = GetParameter("mac","");
|
|
||||||
auto userName = GetParameter("userName","");
|
|
||||||
if(!userName.empty()) {
|
|
||||||
GWObjects::RADIUSSessionList L;
|
|
||||||
Poco::toLowerInPlace(userName);
|
|
||||||
RADIUSSessionTracker()->GetUserNameAPSessions(userName,L);
|
|
||||||
if(L.sessions.empty() && MayBeAMAC(userName)) {
|
|
||||||
mac = ConvertToMac(userName);
|
|
||||||
} else {
|
|
||||||
return ReturnObject("sessions", L.sessions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!mac.empty()) {
|
|
||||||
Poco::toUpperInPlace(mac);
|
|
||||||
Poco::replaceInPlace(mac,":","-");
|
|
||||||
GWObjects::RADIUSSessionList L;
|
|
||||||
RADIUSSessionTracker()->GetMACAPSessions(mac,L);
|
|
||||||
return ReturnObject("sessions",L.sessions);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto SerialNumber = GetBinding("serialNumber","");
|
|
||||||
if(SerialNumber.empty() || !Utils::ValidSerialNumber(SerialNumber)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
GWObjects::RADIUSSessionList L;
|
|
||||||
RADIUSSessionTracker()->GetAPSessions(SerialNumber,L);
|
|
||||||
return ReturnObject("sessions",L.sessions);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RESTAPI_radiussessions_handler::DoPut() {
|
|
||||||
auto SerialNumber = GetBinding("serialNumber","");
|
|
||||||
if(SerialNumber.empty() || !Utils::ValidSerialNumber(SerialNumber)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
GWObjects::RadiusCoADMParameters Parameters;
|
|
||||||
if(!Parameters.from_json(ParsedBody_)) {
|
|
||||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto Command = GetParameter("operation","");
|
|
||||||
|
|
||||||
if(Command=="coadm") {
|
|
||||||
if(Parameters.callingStationId.empty() || Parameters.accountingSessionId.empty() || Parameters.accountingMultiSessionId.empty()) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
auto Index = Parameters.accountingSessionId + Parameters.accountingMultiSessionId;
|
|
||||||
poco_information(Logger(), fmt::format("Disconnecting session {},{}", Parameters.accountingSessionId, Parameters.accountingMultiSessionId ));
|
|
||||||
if(RADIUSSessionTracker()->SendCoADM(SerialNumber, Index)) {
|
|
||||||
return OK();
|
|
||||||
}
|
|
||||||
return BadRequest(RESTAPI::Errors::CouldNotPerformCommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Command=="disconnectUser" && !Parameters.userName.empty()) {
|
|
||||||
if(Parameters.userName.empty()) {
|
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
|
||||||
}
|
|
||||||
poco_information(Logger(), fmt::format("Disconnecting sessions for user: {}", Parameters.userName ));
|
|
||||||
if(RADIUSSessionTracker()->DisconnectUser(Parameters.userName)) {
|
|
||||||
return OK();
|
|
||||||
}
|
|
||||||
return BadRequest(RESTAPI::Errors::CouldNotPerformCommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2023-04-02.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "framework/RESTAPI_Handler.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
|
|
||||||
class RESTAPI_radiussessions_handler : public RESTAPIHandler {
|
|
||||||
public:
|
|
||||||
RESTAPI_radiussessions_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
|
|
||||||
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
|
|
||||||
bool Internal)
|
|
||||||
: RESTAPIHandler(bindings, L,
|
|
||||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
|
||||||
Poco::Net::HTTPRequest::HTTP_PUT,
|
|
||||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
|
||||||
Server, TransactionId, Internal){};
|
|
||||||
static auto PathName() { return std::list<std::string>{"/api/v1/radiusSessions/{serialNumber}"}; };
|
|
||||||
void DoGet() final;
|
|
||||||
void DoDelete() final{};
|
|
||||||
void DoPost() final{};
|
|
||||||
void DoPut();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
|
||||||
@@ -21,9 +21,6 @@
|
|||||||
#include "RESTAPI/RESTAPI_script_handler.h"
|
#include "RESTAPI/RESTAPI_script_handler.h"
|
||||||
#include "RESTAPI/RESTAPI_scripts_handler.h"
|
#include "RESTAPI/RESTAPI_scripts_handler.h"
|
||||||
#include "RESTAPI/RESTAPI_telemetryWebSocket.h"
|
#include "RESTAPI/RESTAPI_telemetryWebSocket.h"
|
||||||
#include "RESTAPI/RESTAPI_radiussessions_handler.h"
|
|
||||||
#include "RESTAPI/RESTAPI_default_firmware.h"
|
|
||||||
#include "RESTAPI/RESTAPI_default_firmwares.h"
|
|
||||||
|
|
||||||
#include "framework/RESTAPI_SystemCommand.h"
|
#include "framework/RESTAPI_SystemCommand.h"
|
||||||
#include "framework/RESTAPI_SystemConfiguration.h"
|
#include "framework/RESTAPI_SystemConfiguration.h"
|
||||||
@@ -42,9 +39,8 @@ namespace OpenWifi {
|
|||||||
RESTAPI_system_configuration, RESTAPI_deviceDashboardHandler, RESTAPI_webSocketServer,
|
RESTAPI_system_configuration, RESTAPI_deviceDashboardHandler, RESTAPI_webSocketServer,
|
||||||
RESTAPI_blacklist, RESTAPI_blacklist_list, RESTAPI_iptocountry_handler,
|
RESTAPI_blacklist, RESTAPI_blacklist_list, RESTAPI_iptocountry_handler,
|
||||||
RESTAPI_radiusProxyConfig_handler, RESTAPI_scripts_handler, RESTAPI_script_handler,
|
RESTAPI_radiusProxyConfig_handler, RESTAPI_scripts_handler, RESTAPI_script_handler,
|
||||||
RESTAPI_capabilities_handler, RESTAPI_telemetryWebSocket, RESTAPI_radiussessions_handler,
|
RESTAPI_capabilities_handler, RESTAPI_telemetryWebSocket,
|
||||||
RESTAPI_regulatory, RESTAPI_default_firmwares,
|
RESTAPI_regulatory>(Path, Bindings, L, S,
|
||||||
RESTAPI_default_firmware>(Path, Bindings, L, S,
|
|
||||||
TransactionId);
|
TransactionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,8 +53,7 @@ namespace OpenWifi {
|
|||||||
RESTAPI_default_configurations, RESTAPI_default_configuration, RESTAPI_command,
|
RESTAPI_default_configurations, RESTAPI_default_configuration, RESTAPI_command,
|
||||||
RESTAPI_commands, RESTAPI_ouis, RESTAPI_file, RESTAPI_blacklist,
|
RESTAPI_commands, RESTAPI_ouis, RESTAPI_file, RESTAPI_blacklist,
|
||||||
RESTAPI_iptocountry_handler, RESTAPI_radiusProxyConfig_handler, RESTAPI_scripts_handler,
|
RESTAPI_iptocountry_handler, RESTAPI_radiusProxyConfig_handler, RESTAPI_scripts_handler,
|
||||||
RESTAPI_script_handler, RESTAPI_blacklist_list, RESTAPI_radiussessions_handler,
|
RESTAPI_script_handler, RESTAPI_blacklist_list,
|
||||||
RESTAPI_regulatory, RESTAPI_default_firmwares,
|
RESTAPI_regulatory>(Path, Bindings, L, S, TransactionId);
|
||||||
RESTAPI_default_firmware>(Path, Bindings, L, S, TransactionId);
|
|
||||||
}
|
}
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
@@ -13,7 +13,6 @@
|
|||||||
#ifdef TIP_GATEWAY_SERVICE
|
#ifdef TIP_GATEWAY_SERVICE
|
||||||
#include "AP_WS_Server.h"
|
#include "AP_WS_Server.h"
|
||||||
#include "CapabilitiesCache.h"
|
#include "CapabilitiesCache.h"
|
||||||
#include "RADIUSSessionTracker.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "RESTAPI_GWobjects.h"
|
#include "RESTAPI_GWobjects.h"
|
||||||
@@ -30,7 +29,6 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj, "serialNumber", SerialNumber);
|
field_to_json(Obj, "serialNumber", SerialNumber);
|
||||||
#ifdef TIP_GATEWAY_SERVICE
|
#ifdef TIP_GATEWAY_SERVICE
|
||||||
field_to_json(Obj, "deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible));
|
field_to_json(Obj, "deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible));
|
||||||
field_to_json(Obj, "hasRADIUSSessions", RADIUSSessionTracker()->HasSessions(SerialNumber));
|
|
||||||
#endif
|
#endif
|
||||||
field_to_json(Obj, "macAddress", MACAddress);
|
field_to_json(Obj, "macAddress", MACAddress);
|
||||||
field_to_json(Obj, "manufacturer", Manufacturer);
|
field_to_json(Obj, "manufacturer", Manufacturer);
|
||||||
@@ -57,10 +55,6 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
|
field_to_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
|
||||||
field_to_json(Obj, "restrictionDetails", restrictionDetails);
|
field_to_json(Obj, "restrictionDetails", restrictionDetails);
|
||||||
field_to_json(Obj, "pendingUUID", pendingUUID);
|
field_to_json(Obj, "pendingUUID", pendingUUID);
|
||||||
field_to_json(Obj, "simulated", simulated);
|
|
||||||
field_to_json(Obj, "lastRecordedContact", lastRecordedContact);
|
|
||||||
field_to_json(Obj, "certificateExpiryDate", certificateExpiryDate);
|
|
||||||
field_to_json(Obj, "connectReason", connectReason);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
|
void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
|
||||||
@@ -70,7 +64,7 @@ namespace OpenWifi::GWObjects {
|
|||||||
ConnectionState ConState;
|
ConnectionState ConState;
|
||||||
|
|
||||||
if (AP_WS_Server()->GetState(SerialNumber, ConState)) {
|
if (AP_WS_Server()->GetState(SerialNumber, ConState)) {
|
||||||
ConState.to_json(SerialNumber,Obj);
|
ConState.to_json(Obj);
|
||||||
} else {
|
} else {
|
||||||
field_to_json(Obj, "ipAddress", "");
|
field_to_json(Obj, "ipAddress", "");
|
||||||
field_to_json(Obj, "txBytes", (uint64_t)0);
|
field_to_json(Obj, "txBytes", (uint64_t)0);
|
||||||
@@ -82,13 +76,6 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj, "associations_2G", (uint64_t)0);
|
field_to_json(Obj, "associations_2G", (uint64_t)0);
|
||||||
field_to_json(Obj, "associations_5G", (uint64_t)0);
|
field_to_json(Obj, "associations_5G", (uint64_t)0);
|
||||||
field_to_json(Obj, "associations_6G", (uint64_t)0);
|
field_to_json(Obj, "associations_6G", (uint64_t)0);
|
||||||
field_to_json(Obj, "hasRADIUSSessions", false);
|
|
||||||
field_to_json(Obj, "hasGPS", ConState.hasGPS);
|
|
||||||
field_to_json(Obj, "sanity", ConState.sanity);
|
|
||||||
field_to_json(Obj, "memoryUsed", ConState.memoryUsed);
|
|
||||||
field_to_json(Obj, "sanity", ConState.sanity);
|
|
||||||
field_to_json(Obj, "load", ConState.load);
|
|
||||||
field_to_json(Obj, "temperature", ConState.temperature);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -122,10 +109,6 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_from_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
|
field_from_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
|
||||||
field_from_json(Obj, "restrictionDetails", restrictionDetails);
|
field_from_json(Obj, "restrictionDetails", restrictionDetails);
|
||||||
field_from_json(Obj, "pendingUUID", pendingUUID);
|
field_from_json(Obj, "pendingUUID", pendingUUID);
|
||||||
field_from_json(Obj, "simulated", simulated);
|
|
||||||
field_from_json(Obj, "lastRecordedContact", lastRecordedContact);
|
|
||||||
field_from_json(Obj, "certificateExpiryDate", certificateExpiryDate);
|
|
||||||
field_from_json(Obj, "connectReason", connectReason);
|
|
||||||
return true;
|
return true;
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
}
|
}
|
||||||
@@ -175,31 +158,6 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj, "lastModified", LastModified);
|
field_to_json(Obj, "lastModified", LastModified);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultFirmware::to_json(Poco::JSON::Object &Obj) const {
|
|
||||||
field_to_json(Obj, "deviceType", deviceType);
|
|
||||||
field_to_json(Obj, "description", Description);
|
|
||||||
field_to_json(Obj, "uri", uri);
|
|
||||||
field_to_json(Obj, "revision", revision);
|
|
||||||
field_to_json(Obj, "imageCreationDate", imageCreationDate);
|
|
||||||
field_to_json(Obj, "created", Created);
|
|
||||||
field_to_json(Obj, "lastModified", LastModified);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DefaultFirmware::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
|
||||||
try {
|
|
||||||
field_from_json(Obj, "deviceType", deviceType);
|
|
||||||
field_from_json(Obj, "description", Description);
|
|
||||||
field_from_json(Obj, "uri", uri);
|
|
||||||
field_from_json(Obj, "revision", revision);
|
|
||||||
field_from_json(Obj, "imageCreationDate", imageCreationDate);
|
|
||||||
field_from_json(Obj, "created", Created);
|
|
||||||
field_from_json(Obj, "lastModified", LastModified);
|
|
||||||
return true;
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommandDetails::to_json(Poco::JSON::Object &Obj) const {
|
void CommandDetails::to_json(Poco::JSON::Object &Obj) const {
|
||||||
EmbedDocument("details", Obj, Details);
|
EmbedDocument("details", Obj, Details);
|
||||||
EmbedDocument("results", Obj, Results);
|
EmbedDocument("results", Obj, Results);
|
||||||
@@ -253,7 +211,7 @@ namespace OpenWifi::GWObjects {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionState::to_json([[maybe_unused]] const std::string &SerialNumber, Poco::JSON::Object &Obj) {
|
void ConnectionState::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj, "ipAddress", Address);
|
field_to_json(Obj, "ipAddress", Address);
|
||||||
field_to_json(Obj, "txBytes", TX);
|
field_to_json(Obj, "txBytes", TX);
|
||||||
field_to_json(Obj, "rxBytes", RX);
|
field_to_json(Obj, "rxBytes", RX);
|
||||||
@@ -275,22 +233,6 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj, "connectionCompletionTime", connectionCompletionTime);
|
field_to_json(Obj, "connectionCompletionTime", connectionCompletionTime);
|
||||||
field_to_json(Obj, "totalConnectionTime", Utils::Now() - started);
|
field_to_json(Obj, "totalConnectionTime", Utils::Now() - started);
|
||||||
field_to_json(Obj, "certificateExpiryDate", certificateExpiryDate);
|
field_to_json(Obj, "certificateExpiryDate", certificateExpiryDate);
|
||||||
field_to_json(Obj, "connectReason", connectReason);
|
|
||||||
|
|
||||||
#ifdef TIP_GATEWAY_SERVICE
|
|
||||||
hasRADIUSSessions = RADIUSSessionTracker()->HasSessions(SerialNumber);
|
|
||||||
AP_WS_Server()->ExtendedAttributes(SerialNumber, hasGPS, sanity,
|
|
||||||
memoryUsed,
|
|
||||||
load,
|
|
||||||
temperature);
|
|
||||||
#endif
|
|
||||||
field_to_json(Obj, "hasRADIUSSessions", hasRADIUSSessions );
|
|
||||||
field_to_json(Obj, "hasGPS", hasGPS);
|
|
||||||
field_to_json(Obj, "sanity", sanity);
|
|
||||||
field_to_json(Obj, "memoryUsed", memoryUsed);
|
|
||||||
field_to_json(Obj, "sanity", sanity);
|
|
||||||
field_to_json(Obj, "load", load);
|
|
||||||
field_to_json(Obj, "temperature", temperature);
|
|
||||||
|
|
||||||
switch (VerifiedCertificate) {
|
switch (VerifiedCertificate) {
|
||||||
case NO_CERTIFICATE:
|
case NO_CERTIFICATE:
|
||||||
@@ -305,9 +247,6 @@ namespace OpenWifi::GWObjects {
|
|||||||
case VERIFIED:
|
case VERIFIED:
|
||||||
field_to_json(Obj, "verifiedCertificate", "VERIFIED");
|
field_to_json(Obj, "verifiedCertificate", "VERIFIED");
|
||||||
break;
|
break;
|
||||||
case SIMULATED:
|
|
||||||
field_to_json(Obj, "verifiedCertificate", "SIMULATED");
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
field_to_json(Obj, "verifiedCertificate", "NO_CERTIFICATE");
|
field_to_json(Obj, "verifiedCertificate", "NO_CERTIFICATE");
|
||||||
break;
|
break;
|
||||||
@@ -434,10 +373,6 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj, "acctConfig", acctConfig);
|
field_to_json(Obj, "acctConfig", acctConfig);
|
||||||
field_to_json(Obj, "coaConfig", coaConfig);
|
field_to_json(Obj, "coaConfig", coaConfig);
|
||||||
field_to_json(Obj, "useByDefault", useByDefault);
|
field_to_json(Obj, "useByDefault", useByDefault);
|
||||||
field_to_json(Obj, "radsecKeepAlive", radsecKeepAlive);
|
|
||||||
field_to_json(Obj, "poolProxyIp", poolProxyIp);
|
|
||||||
field_to_json(Obj, "radsecPoolType", radsecPoolType);
|
|
||||||
field_to_json(Obj, "enabled", enabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
@@ -448,10 +383,6 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_from_json(Obj, "acctConfig", acctConfig);
|
field_from_json(Obj, "acctConfig", acctConfig);
|
||||||
field_from_json(Obj, "coaConfig", coaConfig);
|
field_from_json(Obj, "coaConfig", coaConfig);
|
||||||
field_from_json(Obj, "useByDefault", useByDefault);
|
field_from_json(Obj, "useByDefault", useByDefault);
|
||||||
field_from_json(Obj, "radsecKeepAlive", radsecKeepAlive);
|
|
||||||
field_from_json(Obj, "poolProxyIp", poolProxyIp);
|
|
||||||
field_from_json(Obj, "radsecPoolType", radsecPoolType);
|
|
||||||
field_from_json(Obj, "enabled", enabled);
|
|
||||||
return true;
|
return true;
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
}
|
}
|
||||||
@@ -649,74 +580,4 @@ namespace OpenWifi::GWObjects {
|
|||||||
(T.commands != commands) || (T.developer != developer) || (T.ssh != ssh) ||
|
(T.commands != commands) || (T.developer != developer) || (T.ssh != ssh) ||
|
||||||
(T.key_info != key_info) || (T.country != country));
|
(T.key_info != key_info) || (T.country != country));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RADIUSSession::to_json(Poco::JSON::Object &Obj) const {
|
|
||||||
field_to_json(Obj, "started", started);
|
|
||||||
field_to_json(Obj, "lastTransaction", lastTransaction);
|
|
||||||
field_to_json(Obj, "destination", destination);
|
|
||||||
field_to_json(Obj, "serialNumber", serialNumber);
|
|
||||||
field_to_json(Obj, "userName", userName);
|
|
||||||
field_to_json(Obj, "accountingSessionId", accountingSessionId);
|
|
||||||
field_to_json(Obj, "accountingMultiSessionId", accountingMultiSessionId);
|
|
||||||
field_to_json(Obj, "inputPackets", inputPackets);
|
|
||||||
field_to_json(Obj, "outputPackets", outputPackets);
|
|
||||||
field_to_json(Obj, "inputOctets", inputOctets);
|
|
||||||
field_to_json(Obj, "outputOctets", outputOctets);
|
|
||||||
field_to_json(Obj, "inputGigaWords", inputGigaWords);
|
|
||||||
field_to_json(Obj, "outputGigaWords", outputGigaWords);
|
|
||||||
field_to_json(Obj, "sessionTime", sessionTime);
|
|
||||||
field_to_json(Obj, "callingStationId", callingStationId);
|
|
||||||
field_to_json(Obj, "chargeableUserIdentity", chargeableUserIdentity);
|
|
||||||
field_to_json(Obj, "interface", interface);
|
|
||||||
field_to_json(Obj, "secret", secret);
|
|
||||||
field_to_json(Obj, "nasId", nasId);
|
|
||||||
field_to_json(Obj, "calledStationId", calledStationId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RADIUSSessionList::to_json(Poco::JSON::Object &Obj) const {
|
|
||||||
field_to_json(Obj, "sessions", sessions);
|
|
||||||
}
|
|
||||||
|
|
||||||
void RadiusCoADMParameters::to_json(Poco::JSON::Object &Obj) const {
|
|
||||||
field_to_json(Obj, "accountingSessionId", accountingSessionId);
|
|
||||||
field_to_json(Obj, "accountingMultiSessionId", accountingMultiSessionId);
|
|
||||||
field_to_json(Obj, "callingStationId", callingStationId);
|
|
||||||
field_to_json(Obj, "chargeableUserIdentity", chargeableUserIdentity);
|
|
||||||
field_to_json(Obj, "userName", userName);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RadiusCoADMParameters::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
|
||||||
try {
|
|
||||||
field_from_json(Obj, "accountingSessionId", accountingSessionId);
|
|
||||||
field_from_json(Obj, "accountingMultiSessionId", accountingMultiSessionId);
|
|
||||||
field_from_json(Obj, "callingStationId", callingStationId);
|
|
||||||
field_from_json(Obj, "chargeableUserIdentity", chargeableUserIdentity);
|
|
||||||
field_from_json(Obj, "userName", userName);
|
|
||||||
return true;
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DeviceTransferRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
|
||||||
try {
|
|
||||||
field_from_json(Obj, "serialNumber", serialNumber);
|
|
||||||
field_from_json(Obj, "server", server);
|
|
||||||
field_from_json(Obj, "port", port);
|
|
||||||
return true;
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DeviceCertificateUpdateRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
|
||||||
try {
|
|
||||||
field_from_json(Obj, "serialNumber", serialNumber);
|
|
||||||
field_from_json(Obj, "encodedCertificate", encodedCertificate);
|
|
||||||
return true;
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace OpenWifi::GWObjects
|
} // namespace OpenWifi::GWObjects
|
||||||
|
|||||||
@@ -11,13 +11,9 @@
|
|||||||
#include "Poco/JSON/Object.h"
|
#include "Poco/JSON/Object.h"
|
||||||
#include "RESTAPI_SecurityObjects.h"
|
#include "RESTAPI_SecurityObjects.h"
|
||||||
|
|
||||||
#ifdef TIP_GATEWAY_SERVICE
|
|
||||||
#include <RADIUS_helpers.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace OpenWifi::GWObjects {
|
namespace OpenWifi::GWObjects {
|
||||||
|
|
||||||
enum CertificateValidation { NO_CERTIFICATE, VALID_CERTIFICATE, MISMATCH_SERIAL, VERIFIED, SIMULATED };
|
enum CertificateValidation { NO_CERTIFICATE, VALID_CERTIFICATE, MISMATCH_SERIAL, VERIFIED };
|
||||||
|
|
||||||
struct ConnectionState {
|
struct ConnectionState {
|
||||||
uint64_t MessageCount = 0;
|
uint64_t MessageCount = 0;
|
||||||
@@ -42,15 +38,8 @@ namespace OpenWifi::GWObjects {
|
|||||||
uint64_t sessionId = 0;
|
uint64_t sessionId = 0;
|
||||||
double connectionCompletionTime = 0.0;
|
double connectionCompletionTime = 0.0;
|
||||||
std::uint64_t certificateExpiryDate = 0;
|
std::uint64_t certificateExpiryDate = 0;
|
||||||
std::uint64_t hasRADIUSSessions = 0;
|
|
||||||
bool hasGPS = false;
|
|
||||||
std::uint64_t sanity=0;
|
|
||||||
std::double_t memoryUsed=0.0;
|
|
||||||
std::double_t load=0.0;
|
|
||||||
std::double_t temperature=0.0;
|
|
||||||
std::string connectReason;
|
|
||||||
|
|
||||||
void to_json(const std::string &SerialNumber, Poco::JSON::Object &Obj) ;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DeviceRestrictionsKeyInfo {
|
struct DeviceRestrictionsKeyInfo {
|
||||||
@@ -108,10 +97,6 @@ namespace OpenWifi::GWObjects {
|
|||||||
std::string pendingConfigurationCmd;
|
std::string pendingConfigurationCmd;
|
||||||
DeviceRestrictions restrictionDetails;
|
DeviceRestrictions restrictionDetails;
|
||||||
std::uint64_t pendingUUID = 0;
|
std::uint64_t pendingUUID = 0;
|
||||||
bool simulated=false;
|
|
||||||
std::uint64_t lastRecordedContact=0;
|
|
||||||
std::uint64_t certificateExpiryDate = 0;
|
|
||||||
std::string connectReason;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
void to_json_with_status(Poco::JSON::Object &Obj) const;
|
void to_json_with_status(Poco::JSON::Object &Obj) const;
|
||||||
@@ -184,26 +169,6 @@ namespace OpenWifi::GWObjects {
|
|||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DefaultFirmware {
|
|
||||||
std::string deviceType;
|
|
||||||
std::string Description;
|
|
||||||
std::string uri;
|
|
||||||
std::string revision;
|
|
||||||
uint64_t imageCreationDate;
|
|
||||||
uint64_t Created;
|
|
||||||
uint64_t LastModified;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DefaultFirmwareList {
|
|
||||||
std::vector<DefaultFirmware> firmwares;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CommandDetails {
|
struct CommandDetails {
|
||||||
std::string UUID;
|
std::string UUID;
|
||||||
std::string SerialNumber;
|
std::string SerialNumber;
|
||||||
@@ -362,10 +327,6 @@ namespace OpenWifi::GWObjects {
|
|||||||
RadiusProxyServerConfig acctConfig;
|
RadiusProxyServerConfig acctConfig;
|
||||||
RadiusProxyServerConfig coaConfig;
|
RadiusProxyServerConfig coaConfig;
|
||||||
bool useByDefault = false;
|
bool useByDefault = false;
|
||||||
std::string radsecPoolType;
|
|
||||||
std::string poolProxyIp;
|
|
||||||
std::uint64_t radsecKeepAlive=25;
|
|
||||||
bool enabled=true;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
@@ -409,108 +370,5 @@ namespace OpenWifi::GWObjects {
|
|||||||
|
|
||||||
using RegulatoryInfoCountryMap = std::map<std::string,RegulatoryCountryInfo>;
|
using RegulatoryInfoCountryMap = std::map<std::string,RegulatoryCountryInfo>;
|
||||||
|
|
||||||
struct RADIUSSession {
|
|
||||||
std::uint64_t started=0,
|
|
||||||
lastTransaction=0;
|
|
||||||
std::string serialNumber,
|
|
||||||
destination,
|
|
||||||
userName,
|
|
||||||
accountingSessionId,
|
|
||||||
accountingMultiSessionId,
|
|
||||||
callingStationId,
|
|
||||||
chargeableUserIdentity,
|
|
||||||
secret,
|
|
||||||
interface,
|
|
||||||
nasId;
|
|
||||||
std::uint64_t inputPackets = 0,
|
|
||||||
outputPackets = 0,
|
|
||||||
inputOctets = 0,
|
|
||||||
outputOctets = 0,
|
|
||||||
inputGigaWords = 0,
|
|
||||||
outputGigaWords = 0;
|
|
||||||
std::uint32_t sessionTime = 0;
|
|
||||||
std::string calledStationId;
|
|
||||||
|
|
||||||
#ifdef TIP_GATEWAY_SERVICE
|
|
||||||
RADIUS::RadiusPacket accountingPacket;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RADIUSSessionList {
|
|
||||||
std::vector<RADIUSSession> sessions;
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RadiusCoADMParameters {
|
|
||||||
std::string accountingSessionId,
|
|
||||||
accountingMultiSessionId,
|
|
||||||
callingStationId,
|
|
||||||
chargeableUserIdentity,
|
|
||||||
userName;
|
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class RadiusPoolStrategy {
|
|
||||||
round_robin, random, weighted, unknown
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class RadiusEndpointType {
|
|
||||||
generic, radsec, globalreach, orion, unknown
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline RadiusEndpointType RadiusEndpointType(const std::string &T) {
|
|
||||||
if(T=="generic") return RadiusEndpointType::generic;
|
|
||||||
if(T=="radsec") return RadiusEndpointType::radsec;
|
|
||||||
if(T=="globalreach") return RadiusEndpointType::globalreach;
|
|
||||||
if(T=="orion") return RadiusEndpointType::orion;
|
|
||||||
return RadiusEndpointType::unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline RadiusPoolStrategy RadiusPoolStrategy(const std::string &T) {
|
|
||||||
if(T=="round_robin") return RadiusPoolStrategy::round_robin;
|
|
||||||
if(T=="random") return RadiusPoolStrategy::random;
|
|
||||||
if(T=="weighted") return RadiusPoolStrategy::weighted;
|
|
||||||
return RadiusPoolStrategy::unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline std::string to_string(enum RadiusEndpointType T) {
|
|
||||||
switch(T) {
|
|
||||||
case RadiusEndpointType::generic: return "generic";
|
|
||||||
case RadiusEndpointType::radsec: return "radsec";
|
|
||||||
case RadiusEndpointType::globalreach: return "globalreach";
|
|
||||||
case RadiusEndpointType::orion: return "orion";
|
|
||||||
default:
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline std::string to_string(enum RadiusPoolStrategy T) {
|
|
||||||
switch(T) {
|
|
||||||
case RadiusPoolStrategy::round_robin: return "round_robin";
|
|
||||||
case RadiusPoolStrategy::random: return "random";
|
|
||||||
case RadiusPoolStrategy::weighted: return "weighted";
|
|
||||||
default:
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DeviceTransferRequest {
|
|
||||||
std::string serialNumber;
|
|
||||||
std::string server;
|
|
||||||
std::uint64_t port;
|
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DeviceCertificateUpdateRequest {
|
|
||||||
std::string serialNumber;
|
|
||||||
std::string encodedCertificate;
|
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace OpenWifi::GWObjects
|
} // namespace OpenWifi::GWObjects
|
||||||
|
|||||||
@@ -92,7 +92,6 @@ namespace OpenWifi::OWLSObjects {
|
|||||||
field_to_json(Obj, "endTime", endTime);
|
field_to_json(Obj, "endTime", endTime);
|
||||||
field_to_json(Obj, "errorDevices", errorDevices);
|
field_to_json(Obj, "errorDevices", errorDevices);
|
||||||
field_to_json(Obj, "owner", owner);
|
field_to_json(Obj, "owner", owner);
|
||||||
field_to_json(Obj, "expectedDevices", expectedDevices);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dashboard::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const {}
|
void Dashboard::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const {}
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ namespace OpenWifi::OWLSObjects {
|
|||||||
uint64_t endTime;
|
uint64_t endTime;
|
||||||
uint64_t errorDevices;
|
uint64_t errorDevices;
|
||||||
std::string owner;
|
std::string owner;
|
||||||
uint64_t expectedDevices;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1194,243 +1194,4 @@ namespace OpenWifi::ProvObjects {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBLRAccountInfo::to_json(Poco::JSON::Object &Obj) const {
|
|
||||||
info.to_json(Obj);
|
|
||||||
field_to_json(Obj, "privateKey", privateKey);
|
|
||||||
field_to_json(Obj, "country", country);
|
|
||||||
field_to_json(Obj, "province", province);
|
|
||||||
field_to_json(Obj, "city", city);
|
|
||||||
field_to_json(Obj, "organization", organization);
|
|
||||||
field_to_json(Obj, "commonName", commonName);
|
|
||||||
field_to_json(Obj, "CSR", CSR);
|
|
||||||
field_to_json(Obj, "CSRPrivateKey", CSRPrivateKey);
|
|
||||||
field_to_json(Obj, "CSRPublicKey", CSRPublicKey);
|
|
||||||
field_to_json(Obj, "GlobalReachAcctId", GlobalReachAcctId);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GLBLRAccountInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
|
||||||
try {
|
|
||||||
info.from_json(Obj);
|
|
||||||
field_from_json(Obj, "privateKey", privateKey);
|
|
||||||
field_from_json(Obj, "country", country);
|
|
||||||
field_from_json(Obj, "province", province);
|
|
||||||
field_from_json(Obj, "city", city);
|
|
||||||
field_from_json(Obj, "organization", organization);
|
|
||||||
field_from_json(Obj, "commonName", commonName);
|
|
||||||
field_from_json(Obj, "CSR", CSR);
|
|
||||||
field_from_json(Obj, "CSRPrivateKey", CSRPrivateKey);
|
|
||||||
field_from_json(Obj, "CSRPublicKey", CSRPublicKey);
|
|
||||||
field_from_json(Obj, "GlobalReachAcctId", GlobalReachAcctId);
|
|
||||||
return true;
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLBLRCertificateInfo::to_json(Poco::JSON::Object &Obj) const {
|
|
||||||
field_to_json(Obj, "id", id);
|
|
||||||
field_to_json(Obj, "name", name);
|
|
||||||
field_to_json(Obj, "accountId", accountId);
|
|
||||||
field_to_json(Obj, "csr", csr);
|
|
||||||
field_to_json(Obj, "certificate", certificate);
|
|
||||||
field_to_json(Obj, "certificateChain", certificateChain);
|
|
||||||
field_to_json(Obj, "certificateId", certificateId);
|
|
||||||
field_to_json(Obj, "expiresAt", expiresAt);
|
|
||||||
field_to_json(Obj, "created", created);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GLBLRCertificateInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
|
||||||
try {
|
|
||||||
field_from_json(Obj, "id", id);
|
|
||||||
field_from_json(Obj, "name", name);
|
|
||||||
field_from_json(Obj, "accountId", accountId);
|
|
||||||
field_from_json(Obj, "csr", csr);
|
|
||||||
field_from_json(Obj, "certificate", certificate);
|
|
||||||
field_from_json(Obj, "certificateChain", certificateChain);
|
|
||||||
field_from_json(Obj, "certificateId", certificateId);
|
|
||||||
field_from_json(Obj, "expiresAt", expiresAt);
|
|
||||||
field_from_json(Obj, "created", created);
|
|
||||||
return true;
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GooglOrionAccountInfo::to_json(Poco::JSON::Object &Obj) const {
|
|
||||||
info.to_json(Obj);
|
|
||||||
field_to_json(Obj, "privateKey", privateKey);
|
|
||||||
field_to_json(Obj, "certificate", certificate);
|
|
||||||
field_to_json(Obj, "cacerts", cacerts);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GooglOrionAccountInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
|
||||||
try {
|
|
||||||
info.from_json(Obj);
|
|
||||||
field_from_json(Obj, "privateKey", privateKey);
|
|
||||||
field_from_json(Obj, "certificate", certificate);
|
|
||||||
field_from_json(Obj, "cacerts", cacerts);
|
|
||||||
return true;
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RADIUSServer::to_json(Poco::JSON::Object &Obj) const {
|
|
||||||
field_to_json(Obj, "Hostname", Hostname);
|
|
||||||
field_to_json(Obj, "IP", IP);
|
|
||||||
field_to_json(Obj, "Port", Port);
|
|
||||||
field_to_json(Obj, "Secret", Secret);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RADIUSServer::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
|
||||||
try {
|
|
||||||
field_from_json(Obj, "Hostname", Hostname);
|
|
||||||
field_from_json(Obj, "IP", IP);
|
|
||||||
field_from_json(Obj, "Port", Port);
|
|
||||||
field_from_json(Obj, "Secret", Secret);
|
|
||||||
return true;
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RADIUSEndPointRadiusType::to_json(Poco::JSON::Object &Obj) const {
|
|
||||||
field_to_json(Obj, "Authentication", Authentication);
|
|
||||||
field_to_json(Obj, "Accounting", Accounting);
|
|
||||||
field_to_json(Obj, "CoA", CoA);
|
|
||||||
field_to_json(Obj, "AccountingInterval", AccountingInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RADIUSEndPointRadiusType::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
|
||||||
try {
|
|
||||||
field_from_json(Obj, "Authentication", Authentication);
|
|
||||||
field_from_json(Obj, "Accounting", Accounting);
|
|
||||||
field_from_json(Obj, "CoA", CoA);
|
|
||||||
field_from_json(Obj, "AccountingInterval", AccountingInterval);
|
|
||||||
return true;
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RADIUSEndPointRadsecType::to_json(Poco::JSON::Object &Obj) const {
|
|
||||||
field_to_json(Obj, "Hostname", Hostname);
|
|
||||||
field_to_json(Obj, "IP", IP);
|
|
||||||
field_to_json(Obj, "Port", Port);
|
|
||||||
field_to_json(Obj, "Secret", Secret);
|
|
||||||
field_to_json(Obj, "OpenRoamingType", OpenRoamingType);
|
|
||||||
field_to_json(Obj, "UseOpenRoamingAccount", UseOpenRoamingAccount);
|
|
||||||
field_to_json(Obj, "Weight", Weight);
|
|
||||||
field_to_json(Obj, "Certificate", Certificate);
|
|
||||||
field_to_json(Obj, "PrivateKey", PrivateKey);
|
|
||||||
field_to_json(Obj, "CaCerts", CaCerts);
|
|
||||||
field_to_json(Obj, "AllowSelfSigned", AllowSelfSigned);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RADIUSEndPointRadsecType::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
|
||||||
try {
|
|
||||||
field_from_json(Obj, "Hostname", Hostname);
|
|
||||||
field_from_json(Obj, "IP", IP);
|
|
||||||
field_from_json(Obj, "Port", Port);
|
|
||||||
field_from_json(Obj, "Secret", Secret);
|
|
||||||
field_from_json(Obj, "OpenRoamingType", OpenRoamingType);
|
|
||||||
field_from_json(Obj, "UseOpenRoamingAccount", UseOpenRoamingAccount);
|
|
||||||
field_from_json(Obj, "Weight", Weight);
|
|
||||||
field_from_json(Obj, "Certificate", Certificate);
|
|
||||||
field_from_json(Obj, "PrivateKey", PrivateKey);
|
|
||||||
field_from_json(Obj, "CaCerts", CaCerts);
|
|
||||||
field_from_json(Obj, "AllowSelfSigned", AllowSelfSigned);
|
|
||||||
return true;
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RADIUSEndPoint::to_json(Poco::JSON::Object &Obj) const {
|
|
||||||
info.to_json(Obj);
|
|
||||||
field_to_json(Obj, "Type", Type);
|
|
||||||
field_to_json(Obj, "RadsecServers", RadsecServers);
|
|
||||||
field_to_json(Obj, "RadiusServers", RadiusServers);
|
|
||||||
field_to_json(Obj, "PoolStrategy", PoolStrategy);
|
|
||||||
field_to_json(Obj, "Index", Index);
|
|
||||||
field_to_json(Obj, "UsedBy", UsedBy);
|
|
||||||
field_to_json(Obj, "UseGWProxy", UseGWProxy);
|
|
||||||
field_to_json(Obj, "NasIdentifier", NasIdentifier);
|
|
||||||
field_to_json(Obj, "AccountingInterval", AccountingInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RADIUSEndPoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
|
||||||
try {
|
|
||||||
info.from_json(Obj);
|
|
||||||
field_from_json(Obj, "Type", Type);
|
|
||||||
field_from_json(Obj, "RadsecServers", RadsecServers);
|
|
||||||
field_from_json(Obj, "RadiusServers", RadiusServers);
|
|
||||||
field_from_json(Obj, "PoolStrategy", PoolStrategy);
|
|
||||||
field_from_json(Obj, "Index", Index);
|
|
||||||
field_from_json(Obj, "UsedBy", UsedBy);
|
|
||||||
field_from_json(Obj, "UseGWProxy", UseGWProxy);
|
|
||||||
field_from_json(Obj, "NasIdentifier", NasIdentifier);
|
|
||||||
field_from_json(Obj, "AccountingInterval", AccountingInterval);
|
|
||||||
return true;
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RADIUSEndpointUpdateStatus::to_json(Poco::JSON::Object &Obj) const {
|
|
||||||
field_to_json(Obj, "lastUpdate", lastUpdate);
|
|
||||||
field_to_json(Obj, "lastConfigurationChange", lastConfigurationChange);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RADIUSEndpointUpdateStatus::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
|
||||||
try {
|
|
||||||
field_from_json(Obj, "lastUpdate", lastUpdate);
|
|
||||||
field_from_json(Obj, "lastConfigurationChange", lastConfigurationChange);
|
|
||||||
return true;
|
|
||||||
} catch (const Poco::Exception &E) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RADIUSEndpointUpdateStatus::Read() {
|
|
||||||
Poco::File F(OpenWifi::MicroServiceDataDirectory()+"/RADIUSEndpointUpdateStatus.json");
|
|
||||||
try {
|
|
||||||
if (F.exists()) {
|
|
||||||
Poco::JSON::Parser P;
|
|
||||||
std::ifstream ifs(F.path(), std::ios_base::in | std::ios_base::binary);
|
|
||||||
auto Obj = P.parse(ifs);
|
|
||||||
return from_json(Obj.extract<Poco::JSON::Object::Ptr>());
|
|
||||||
}
|
|
||||||
} catch (...) {
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RADIUSEndpointUpdateStatus::Save() {
|
|
||||||
Poco::File F(OpenWifi::MicroServiceDataDirectory()+"/RADIUSEndpointUpdateStatus.json");
|
|
||||||
try {
|
|
||||||
Poco::JSON::Object Obj;
|
|
||||||
to_json(Obj);
|
|
||||||
std::ofstream O(F.path(), std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
|
|
||||||
Poco::JSON::Stringifier::stringify(Obj, O);
|
|
||||||
return true;
|
|
||||||
} catch (...) {
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RADIUSEndpointUpdateStatus::ChangeConfiguration() {
|
|
||||||
Read();
|
|
||||||
lastConfigurationChange = Utils::Now();
|
|
||||||
return Save();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace OpenWifi::ProvObjects
|
} // namespace OpenWifi::ProvObjects
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::TagList tags;
|
Types::TagList tags;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -37,7 +36,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::UUIDvec_t serialNumbers;
|
Types::UUIDvec_t serialNumbers;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -48,7 +46,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string policy;
|
std::string policy;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -60,18 +57,14 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::UUID_t venue;
|
Types::UUID_t venue;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<ManagementPolicy> ManagementPolicyVec;
|
typedef std::vector<ManagementPolicy> ManagementPolicyVec;
|
||||||
|
|
||||||
struct RRMAlgorithmDetails {
|
struct RRMAlgorithmDetails {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string parameters;
|
std::string parameters;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -79,9 +72,7 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string vendor;
|
std::string vendor;
|
||||||
std::string schedule;
|
std::string schedule;
|
||||||
std::vector<RRMAlgorithmDetails> algorithms;
|
std::vector<RRMAlgorithmDetails> algorithms;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -91,7 +82,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string firmwareUpgrade{"inherit"};
|
std::string firmwareUpgrade{"inherit"};
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -114,10 +104,8 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::UUIDvec_t configurations;
|
Types::UUIDvec_t configurations;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<Entity> EntityVec;
|
typedef std::vector<Entity> EntityVec;
|
||||||
|
|
||||||
struct DiGraphEntry {
|
struct DiGraphEntry {
|
||||||
@@ -125,7 +113,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::UUID_t child;
|
Types::UUID_t child;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -153,10 +140,8 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::UUIDvec_t boards;
|
Types::UUIDvec_t boards;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<Venue> VenueVec;
|
typedef std::vector<Venue> VenueVec;
|
||||||
|
|
||||||
struct UserInfoDigest {
|
struct UserInfoDigest {
|
||||||
@@ -165,7 +150,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string userType;
|
std::string userType;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -178,10 +162,8 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::UUID_t venue;
|
Types::UUID_t venue;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<ManagementRole> ManagementRoleVec;
|
typedef std::vector<ManagementRole> ManagementRoleVec;
|
||||||
|
|
||||||
enum LocationType {
|
enum LocationType {
|
||||||
@@ -250,10 +232,8 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::UUID_t managementPolicy;
|
Types::UUID_t managementPolicy;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<Location> LocationVec;
|
typedef std::vector<Location> LocationVec;
|
||||||
|
|
||||||
struct OperatorLocation {
|
struct OperatorLocation {
|
||||||
@@ -273,10 +253,8 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::UUID_t managementPolicy;
|
Types::UUID_t managementPolicy;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<Location> LocationVec;
|
typedef std::vector<Location> LocationVec;
|
||||||
|
|
||||||
struct SubLocation {
|
struct SubLocation {
|
||||||
@@ -292,7 +270,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string geoCode;
|
std::string geoCode;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -300,7 +277,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::vector<OperatorLocation> locations;
|
std::vector<OperatorLocation> locations;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -380,10 +356,8 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::UUID_t managementPolicy;
|
Types::UUID_t managementPolicy;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<Contact> ContactVec;
|
typedef std::vector<Contact> ContactVec;
|
||||||
|
|
||||||
struct OperatorContact {
|
struct OperatorContact {
|
||||||
@@ -405,7 +379,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::UUID_t managementPolicy;
|
Types::UUID_t managementPolicy;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -424,7 +397,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string accessPIN;
|
std::string accessPIN;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -432,7 +404,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::vector<OperatorContact> contacts;
|
std::vector<OperatorContact> contacts;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -445,10 +416,8 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string configuration;
|
std::string configuration;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<DeviceConfigurationElement> DeviceConfigurationElementVec;
|
typedef std::vector<DeviceConfigurationElement> DeviceConfigurationElementVec;
|
||||||
|
|
||||||
struct DeviceConfiguration {
|
struct DeviceConfiguration {
|
||||||
@@ -465,10 +434,8 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string subscriber;
|
std::string subscriber;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<DeviceConfiguration> DeviceConfigurationVec;
|
typedef std::vector<DeviceConfiguration> DeviceConfigurationVec;
|
||||||
|
|
||||||
struct InventoryTag {
|
struct InventoryTag {
|
||||||
@@ -492,7 +459,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
bool doNotAllowOverrides = false;
|
bool doNotAllowOverrides = false;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -502,7 +468,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
InventoryTagVec taglist;
|
InventoryTagVec taglist;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -513,7 +478,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
uint64_t errorCode;
|
uint64_t errorCode;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -522,7 +486,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::CountedMap tenants;
|
Types::CountedMap tenants;
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -532,7 +495,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string description;
|
std::string description;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -541,7 +503,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::vector<ExpandedUseEntry> entries;
|
std::vector<ExpandedUseEntry> entries;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -549,7 +510,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::vector<ExpandedUseEntryList> entries;
|
std::vector<ExpandedUseEntryList> entries;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -557,13 +517,10 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::UUIDvec_t list;
|
Types::UUIDvec_t list;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ACLACCESS {
|
enum ACLACCESS { NONE = 0, READ = 1, MODIFY = 2, CREATE = 3, DELETE = 4 };
|
||||||
NONE = 0, READ = 1, MODIFY = 2, CREATE = 3, DELETE = 4
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ObjectACL {
|
struct ObjectACL {
|
||||||
UuidList users;
|
UuidList users;
|
||||||
@@ -571,7 +528,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
uint64_t access = (uint64_t)NONE;
|
uint64_t access = (uint64_t)NONE;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -579,7 +535,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::vector<ObjectACL> list;
|
std::vector<ObjectACL> list;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -594,7 +549,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string venue;
|
std::string venue;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -602,7 +556,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::vector<Map> list;
|
std::vector<Map> list;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -632,7 +585,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string operatorId;
|
std::string operatorId;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -643,7 +595,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string value;
|
std::string value;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -651,7 +602,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::vector<Variable> variables;
|
std::vector<Variable> variables;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -666,7 +616,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::UUID_t managementPolicy;
|
Types::UUID_t managementPolicy;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -674,7 +623,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::vector<VariableBlock> variableBlocks;
|
std::vector<VariableBlock> variableBlocks;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -689,7 +637,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string registrationId;
|
std::string registrationId;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -697,7 +644,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::vector<Operator> operators;
|
std::vector<Operator> operators;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -708,7 +654,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::UUIDvec_t devices;
|
Types::UUIDvec_t devices;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -724,7 +669,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
bool defaultService = false;
|
bool defaultService = false;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -732,7 +676,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::vector<ServiceClass> serviceClasses;
|
std::vector<ServiceClass> serviceClasses;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -743,7 +686,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string firmwareRCOnly{"inherit"};
|
std::string firmwareRCOnly{"inherit"};
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -768,7 +710,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string realMacAddress;
|
std::string realMacAddress;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -776,7 +717,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::vector<SubscriberDevice> subscriberDevices;
|
std::vector<SubscriberDevice> subscriberDevices;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -789,7 +729,6 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::uint64_t modified;
|
std::uint64_t modified;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -799,119 +738,12 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::vector<ConfigurationOverride> overrides;
|
std::vector<ConfigurationOverride> overrides;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U,
|
bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U,
|
||||||
ObjectInfo &I);
|
ObjectInfo &I);
|
||||||
|
|
||||||
bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U,
|
bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U,
|
||||||
ObjectInfo &I);
|
ObjectInfo &I);
|
||||||
|
|
||||||
bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I);
|
bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I);
|
||||||
|
|
||||||
struct GLBLRAccountInfo {
|
|
||||||
ObjectInfo info;
|
|
||||||
std::string privateKey;
|
|
||||||
std::string country, province, city, organization, commonName;
|
|
||||||
std::string CSR, CSRPrivateKey, CSRPublicKey;
|
|
||||||
std::string GlobalReachAcctId;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GLBLRCertificateInfo {
|
|
||||||
std::string id;
|
|
||||||
std::string name;
|
|
||||||
std::string accountId;
|
|
||||||
std::string csr;
|
|
||||||
std::string certificate;
|
|
||||||
std::string certificateChain;
|
|
||||||
std::string certificateId;
|
|
||||||
std::uint64_t expiresAt = 0;
|
|
||||||
std::uint64_t created = 0;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
|
||||||
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GooglOrionAccountInfo {
|
|
||||||
ObjectInfo info;
|
|
||||||
std::string privateKey;
|
|
||||||
std::string certificate;
|
|
||||||
std::vector<std::string> cacerts;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RADIUSServer {
|
|
||||||
std::string Hostname;
|
|
||||||
std::string IP;
|
|
||||||
std::uint64_t Port=0;
|
|
||||||
std::string Secret;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RADIUSEndPointRadiusType {
|
|
||||||
std::vector<RADIUSServer> Authentication;
|
|
||||||
std::vector<RADIUSServer> Accounting;
|
|
||||||
std::vector<RADIUSServer> CoA;
|
|
||||||
std::uint64_t AccountingInterval = 60;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RADIUSEndPointRadsecType {
|
|
||||||
std::string Hostname;
|
|
||||||
std::string IP;
|
|
||||||
std::uint64_t Port=2083;
|
|
||||||
std::string Secret{"radsec"};
|
|
||||||
std::string OpenRoamingType;
|
|
||||||
std::string UseOpenRoamingAccount;
|
|
||||||
std::uint64_t Weight=0;
|
|
||||||
std::string Certificate;
|
|
||||||
std::string PrivateKey;
|
|
||||||
std::vector<std::string> CaCerts;
|
|
||||||
bool AllowSelfSigned=false;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RADIUSEndPoint {
|
|
||||||
ObjectInfo info;
|
|
||||||
std::string Type{"radius"};
|
|
||||||
std::string PoolStrategy{"none"};
|
|
||||||
bool UseGWProxy=true;
|
|
||||||
std::string Index;
|
|
||||||
std::vector<std::string> UsedBy;
|
|
||||||
std::vector<RADIUSEndPointRadiusType> RadiusServers;
|
|
||||||
std::vector<RADIUSEndPointRadsecType> RadsecServers;
|
|
||||||
std::string NasIdentifier;
|
|
||||||
std::uint64_t AccountingInterval=600;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
|
||||||
};
|
|
||||||
|
|
||||||
struct RADIUSEndpointUpdateStatus {
|
|
||||||
std::uint64_t lastUpdate=0;
|
|
||||||
std::uint64_t lastConfigurationChange=0;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
|
||||||
bool Read();
|
|
||||||
bool Save();
|
|
||||||
bool ChangeConfiguration();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}; // namespace OpenWifi::ProvObjects
|
}; // namespace OpenWifi::ProvObjects
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <mutex>
|
#include <shared_mutex>
|
||||||
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
#include "framework/SubSystemServer.h"
|
#include "framework/SubSystemServer.h"
|
||||||
@@ -38,7 +38,7 @@ namespace OpenWifi {
|
|||||||
inline int Start() final {
|
inline int Start() final {
|
||||||
poco_notice(Logger(), "Starting...");
|
poco_notice(Logger(), "Starting...");
|
||||||
|
|
||||||
std::lock_guard L(KeyMutex_);
|
std::shared_lock L(KeyMutex_);
|
||||||
|
|
||||||
CacheFilename_ = MicroServiceDataDirectory() + "/signature_cache";
|
CacheFilename_ = MicroServiceDataDirectory() + "/signature_cache";
|
||||||
Poco::File CacheFile(CacheFilename_);
|
Poco::File CacheFile(CacheFilename_);
|
||||||
@@ -91,7 +91,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
inline std::string Sign(const GWObjects::DeviceRestrictions &Restrictions,
|
inline std::string Sign(const GWObjects::DeviceRestrictions &Restrictions,
|
||||||
const std::string &Data) const {
|
const std::string &Data) const {
|
||||||
std::lock_guard L(KeyMutex_);
|
std::shared_lock L(KeyMutex_);
|
||||||
try {
|
try {
|
||||||
if (Restrictions.key_info.algo == "static") {
|
if (Restrictions.key_info.algo == "static") {
|
||||||
return "aaaaaaaaaa";
|
return "aaaaaaaaaa";
|
||||||
@@ -120,7 +120,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
inline std::string Sign(const GWObjects::DeviceRestrictions &Restrictions,
|
inline std::string Sign(const GWObjects::DeviceRestrictions &Restrictions,
|
||||||
const Poco::URI &uri) {
|
const Poco::URI &uri) {
|
||||||
std::lock_guard L(KeyMutex_);
|
std::shared_lock L(KeyMutex_);
|
||||||
try {
|
try {
|
||||||
if (Restrictions.key_info.algo == "static") {
|
if (Restrictions.key_info.algo == "static") {
|
||||||
return "aaaaaaaaaa";
|
return "aaaaaaaaaa";
|
||||||
@@ -172,7 +172,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable std::mutex KeyMutex_;
|
mutable std::shared_mutex KeyMutex_;
|
||||||
std::map<std::string, Poco::SharedPtr<Poco::Crypto::RSAKey>> Keys_;
|
std::map<std::string, Poco::SharedPtr<Poco::Crypto::RSAKey>> Keys_;
|
||||||
std::map<std::string, std::string> SignatureCache_;
|
std::map<std::string, std::string> SignatureCache_;
|
||||||
std::string CacheFilename_;
|
std::string CacheFilename_;
|
||||||
|
|||||||
@@ -16,22 +16,6 @@
|
|||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
class LockedDbSession {
|
|
||||||
public:
|
|
||||||
explicit LockedDbSession();
|
|
||||||
~LockedDbSession() = default;
|
|
||||||
inline std::mutex &Mutex() { return *Mutex_; };
|
|
||||||
inline Poco::Data::Session &Session() {
|
|
||||||
if(!Session_->isConnected()) {
|
|
||||||
Session_->reconnect();
|
|
||||||
}
|
|
||||||
return *Session_;
|
|
||||||
};
|
|
||||||
private:
|
|
||||||
std::shared_ptr<Poco::Data::Session> Session_;
|
|
||||||
std::shared_ptr<std::mutex> Mutex_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Storage : public StorageClass {
|
class Storage : public StorageClass {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -106,8 +90,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
// typedef std::map<std::string,std::string> DeviceCapabilitiesCache;
|
// typedef std::map<std::string,std::string> DeviceCapabilitiesCache;
|
||||||
|
|
||||||
bool AddLog(LockedDbSession &Session, const GWObjects::DeviceLog &Log);
|
bool AddLog(const GWObjects::DeviceLog &Log);
|
||||||
bool AddStatisticsData(Poco::Data::Session &Session, const GWObjects::Statistics &Stats);
|
|
||||||
bool AddStatisticsData(const GWObjects::Statistics &Stats);
|
bool AddStatisticsData(const GWObjects::Statistics &Stats);
|
||||||
bool GetStatisticsData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate,
|
bool GetStatisticsData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate,
|
||||||
uint64_t Offset, uint64_t HowMany,
|
uint64_t Offset, uint64_t HowMany,
|
||||||
@@ -119,7 +102,6 @@ namespace OpenWifi {
|
|||||||
std::vector<GWObjects::Statistics> &Stats);
|
std::vector<GWObjects::Statistics> &Stats);
|
||||||
|
|
||||||
bool AddHealthCheckData(const GWObjects::HealthCheck &Check);
|
bool AddHealthCheckData(const GWObjects::HealthCheck &Check);
|
||||||
bool AddHealthCheckData(LockedDbSession &Session, const GWObjects::HealthCheck &Check);
|
|
||||||
bool GetHealthCheckData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate,
|
bool GetHealthCheckData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate,
|
||||||
uint64_t Offset, uint64_t HowMany,
|
uint64_t Offset, uint64_t HowMany,
|
||||||
std::vector<GWObjects::HealthCheck> &Checks);
|
std::vector<GWObjects::HealthCheck> &Checks);
|
||||||
@@ -133,30 +115,19 @@ namespace OpenWifi {
|
|||||||
uint64_t &NewUUID);
|
uint64_t &NewUUID);
|
||||||
|
|
||||||
bool RollbackDeviceConfigurationChange(std::string & SerialNumber);
|
bool RollbackDeviceConfigurationChange(std::string & SerialNumber);
|
||||||
bool CompleteDeviceConfigurationChange(Poco::Data::Session &Session, std::string & SerialNumber);
|
|
||||||
bool CompleteDeviceConfigurationChange(std::string & SerialNumber);
|
bool CompleteDeviceConfigurationChange(std::string & SerialNumber);
|
||||||
bool CreateDevice(LockedDbSession &Session, GWObjects::Device &);
|
|
||||||
bool CreateDevice(GWObjects::Device &);
|
|
||||||
bool CreateDefaultDevice(Poco::Data::Session &Session,std::string &SerialNumber,
|
|
||||||
const Config::Capabilities &Caps,
|
|
||||||
std::string &Firmware, const Poco::Net::IPAddress &IPAddress,
|
|
||||||
bool simulated);
|
|
||||||
bool CreateDevice(Poco::Data::Session &Sess, GWObjects::Device &DeviceDetails);
|
|
||||||
|
|
||||||
bool GetDevice(LockedDbSession &Session, std::string &SerialNumber, GWObjects::Device &);
|
bool CreateDevice(GWObjects::Device &);
|
||||||
bool GetDevice(Poco::Data::Session &Session, std::string &SerialNumber, GWObjects::Device &DeviceDetails);
|
bool CreateDefaultDevice(std::string &SerialNumber, const Config::Capabilities &Caps,
|
||||||
|
std::string &Firmware, const Poco::Net::IPAddress &IPAddress);
|
||||||
|
|
||||||
bool GetDevice(std::string &SerialNumber, GWObjects::Device &);
|
bool GetDevice(std::string &SerialNumber, GWObjects::Device &);
|
||||||
bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices,
|
bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices,
|
||||||
const std::string &orderBy = "");
|
const std::string &orderBy = "");
|
||||||
// bool GetDevices(uint64_t From, uint64_t HowMany, const std::string & Select,
|
// bool GetDevices(uint64_t From, uint64_t HowMany, const std::string & Select,
|
||||||
// std::vector<GWObjects::Device> &Devices, const std::string & orderBy="");
|
// std::vector<GWObjects::Device> &Devices, const std::string & orderBy="");
|
||||||
bool DeleteDevice(std::string &SerialNumber);
|
bool DeleteDevice(std::string &SerialNumber);
|
||||||
bool DeleteDevices(std::string &SerialPattern, bool SimulatedOnly);
|
|
||||||
bool DeleteDevices(std::uint64_t OlderContact, bool SimulatedOnly);
|
|
||||||
|
|
||||||
bool UpdateDevice(GWObjects::Device &);
|
bool UpdateDevice(GWObjects::Device &);
|
||||||
bool UpdateDevice(LockedDbSession &Session, GWObjects::Device &);
|
|
||||||
bool UpdateDevice(Poco::Data::Session &Sess, GWObjects::Device &NewDeviceDetails);
|
|
||||||
bool DeviceExists(std::string &SerialNumber);
|
bool DeviceExists(std::string &SerialNumber);
|
||||||
bool SetConnectInfo(std::string &SerialNumber, std::string &Firmware);
|
bool SetConnectInfo(std::string &SerialNumber, std::string &Firmware);
|
||||||
bool GetDeviceCount(uint64_t &Count);
|
bool GetDeviceCount(uint64_t &Count);
|
||||||
@@ -164,7 +135,7 @@ namespace OpenWifi {
|
|||||||
std::vector<std::string> &SerialNumbers,
|
std::vector<std::string> &SerialNumbers,
|
||||||
const std::string &orderBy = "");
|
const std::string &orderBy = "");
|
||||||
bool GetDeviceFWUpdatePolicy(std::string &SerialNumber, std::string &Policy);
|
bool GetDeviceFWUpdatePolicy(std::string &SerialNumber, std::string &Policy);
|
||||||
bool SetDevicePassword(LockedDbSession &Session, std::string &SerialNumber, std::string &Password);
|
bool SetDevicePassword(std::string &SerialNumber, std::string &Password);
|
||||||
bool UpdateSerialNumberCache();
|
bool UpdateSerialNumberCache();
|
||||||
static void GetDeviceDbFieldList(Types::StringVec &Fields);
|
static void GetDeviceDbFieldList(Types::StringVec &Fields);
|
||||||
|
|
||||||
@@ -173,11 +144,9 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
bool UpdateDeviceCapabilities(std::string &SerialNumber,
|
bool UpdateDeviceCapabilities(std::string &SerialNumber,
|
||||||
const Config::Capabilities &Capabilities);
|
const Config::Capabilities &Capabilities);
|
||||||
bool UpdateDeviceCapabilities(Poco::Data::Session &Session, std::string &SerialNumber,
|
|
||||||
const Config::Capabilities &Capabilities);
|
|
||||||
bool GetDeviceCapabilities(std::string &SerialNumber, GWObjects::Capabilities &);
|
bool GetDeviceCapabilities(std::string &SerialNumber, GWObjects::Capabilities &);
|
||||||
bool DeleteDeviceCapabilities(std::string &SerialNumber);
|
bool DeleteDeviceCapabilities(std::string &SerialNumber);
|
||||||
bool CreateDeviceCapabilities(Poco::Data::Session &Session, std::string &SerialNumber,
|
bool CreateDeviceCapabilities(std::string &SerialNumber,
|
||||||
const Config::Capabilities &Capabilities);
|
const Config::Capabilities &Capabilities);
|
||||||
bool InitCapabilitiesCache();
|
bool InitCapabilitiesCache();
|
||||||
|
|
||||||
@@ -202,19 +171,6 @@ namespace OpenWifi {
|
|||||||
uint64_t GetDefaultConfigurationsCount();
|
uint64_t GetDefaultConfigurationsCount();
|
||||||
bool DefaultConfigurationAlreadyExists(std::string &Name);
|
bool DefaultConfigurationAlreadyExists(std::string &Name);
|
||||||
|
|
||||||
bool UpdateDefaultFirmware(GWObjects::DefaultFirmware &DefFirmware);
|
|
||||||
bool CreateDefaultFirmware(GWObjects::DefaultFirmware &DefConfig);
|
|
||||||
bool DeleteDefaultFirmware(std::string &name);
|
|
||||||
bool GetDefaultFirmware(std::string &name, GWObjects::DefaultFirmware &DefConfig);
|
|
||||||
bool GetDefaultFirmwares(uint64_t From, uint64_t HowMany,
|
|
||||||
std::vector<GWObjects::DefaultFirmware> &Devices);
|
|
||||||
bool FindDefaultFirmwareForModel(const std::string &Model,
|
|
||||||
GWObjects::DefaultFirmware &DefConfig);
|
|
||||||
uint64_t GetDefaultFirmwaresCount();
|
|
||||||
bool DefaultFirmwareAlreadyExists(std::string &Name);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool AddCommand(std::string &SerialNumber, GWObjects::CommandDetails &Command,
|
bool AddCommand(std::string &SerialNumber, GWObjects::CommandDetails &Command,
|
||||||
CommandExecutionType Type);
|
CommandExecutionType Type);
|
||||||
bool GetCommands(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate,
|
bool GetCommands(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate,
|
||||||
@@ -249,33 +205,27 @@ namespace OpenWifi {
|
|||||||
void RemovedExpiredCommands();
|
void RemovedExpiredCommands();
|
||||||
void RemoveTimedOutCommands();
|
void RemoveTimedOutCommands();
|
||||||
|
|
||||||
bool RemoveOldCommands(std::string &SerialNumber, std::string &Command);
|
bool RemoveOldCommands(std::string &SerilNumber, std::string &Command);
|
||||||
|
|
||||||
bool AddBlackListDevices(std::vector<GWObjects::BlackListedDevice> &Devices);
|
bool AddBlackListDevices(std::vector<GWObjects::BlackListedDevice> &Devices);
|
||||||
bool AddBlackListDevice(GWObjects::BlackListedDevice &Device);
|
bool AddBlackListDevice(GWObjects::BlackListedDevice &Device);
|
||||||
bool GetBlackListDevice(std::string &SerialNumber, GWObjects::BlackListedDevice &Device);
|
bool GetBlackListDevice(std::string &SerialNumber, GWObjects::BlackListedDevice &Device);
|
||||||
bool DeleteBlackListDevice(std::string &SerialNumber);
|
bool DeleteBlackListDevice(std::string &SerialNumber);
|
||||||
bool IsBlackListed(std::uint64_t SerialNumber, std::string &reason,
|
bool IsBlackListed(const std::string &SerialNumber, std::string &reason,
|
||||||
std::string &author, std::uint64_t &created);
|
std::string &author, std::uint64_t &created);
|
||||||
bool IsBlackListed(std::uint64_t SerialNumber);
|
bool IsBlackListed(const std::string &SerialNumber);
|
||||||
bool InitializeBlackListCache();
|
bool InitializeBlackListCache();
|
||||||
bool GetBlackListDevices(uint64_t Offset, uint64_t HowMany,
|
bool GetBlackListDevices(uint64_t Offset, uint64_t HowMany,
|
||||||
std::vector<GWObjects::BlackListedDevice> &Devices);
|
std::vector<GWObjects::BlackListedDevice> &Devices);
|
||||||
bool UpdateBlackListDevice(std::string &SerialNumber, GWObjects::BlackListedDevice &Device);
|
bool UpdateBlackListDevice(std::string &SerialNumber, GWObjects::BlackListedDevice &Device);
|
||||||
uint64_t GetBlackListDeviceCount();
|
uint64_t GetBlackListDeviceCount();
|
||||||
|
|
||||||
bool DeleteSimulatedDevice(const std::string &SerialNumber);
|
|
||||||
|
|
||||||
bool RemoveHealthChecksRecordsOlderThan(uint64_t Date);
|
bool RemoveHealthChecksRecordsOlderThan(uint64_t Date);
|
||||||
bool RemoveDeviceLogsRecordsOlderThan(uint64_t Date);
|
bool RemoveDeviceLogsRecordsOlderThan(uint64_t Date);
|
||||||
bool RemoveStatisticsRecordsOlderThan(uint64_t Date);
|
bool RemoveStatisticsRecordsOlderThan(uint64_t Date);
|
||||||
bool RemoveCommandListRecordsOlderThan(uint64_t Date);
|
bool RemoveCommandListRecordsOlderThan(uint64_t Date);
|
||||||
bool RemoveUploadedFilesRecordsOlderThan(uint64_t Date);
|
bool RemoveUploadedFilesRecordsOlderThan(uint64_t Date);
|
||||||
|
|
||||||
bool SetDeviceLastRecordedContact(LockedDbSession &Session, std::string & SerialNumber, std::uint64_t lastRecordedContact);
|
|
||||||
bool SetDeviceLastRecordedContact(std::string & SerialNumber, std::uint64_t lastRecordedContact);
|
|
||||||
bool SetDeviceLastRecordedContact(Poco::Data::Session & Session, std::string & SerialNumber, std::uint64_t lastRecordedContact);
|
|
||||||
|
|
||||||
int Create_Tables();
|
int Create_Tables();
|
||||||
int Create_Statistics();
|
int Create_Statistics();
|
||||||
int Create_Devices();
|
int Create_Devices();
|
||||||
@@ -286,7 +236,6 @@ namespace OpenWifi {
|
|||||||
int Create_CommandList();
|
int Create_CommandList();
|
||||||
int Create_BlackList();
|
int Create_BlackList();
|
||||||
int Create_FileUploads();
|
int Create_FileUploads();
|
||||||
int Create_DefaultFirmwares();
|
|
||||||
|
|
||||||
bool AnalyzeCommands(Types::CountedMap &R);
|
bool AnalyzeCommands(Types::CountedMap &R);
|
||||||
bool AnalyzeDevices(GWObjects::Dashboard &D);
|
bool AnalyzeDevices(GWObjects::Dashboard &D);
|
||||||
@@ -294,19 +243,10 @@ namespace OpenWifi {
|
|||||||
int Start() override;
|
int Start() override;
|
||||||
void Stop() override;
|
void Stop() override;
|
||||||
|
|
||||||
inline Poco::Data::Session StartSession() {
|
|
||||||
return Pool_->get();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<OpenWifi::ScriptDB> ScriptDB_;
|
std::unique_ptr<OpenWifi::ScriptDB> ScriptDB_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto StorageService() { return Storage::instance(); }
|
inline auto StorageService() { return Storage::instance(); }
|
||||||
|
|
||||||
inline LockedDbSession::LockedDbSession() {
|
|
||||||
Session_ = std::make_shared<Poco::Data::Session>(Poco::Data::Session(StorageService()->StartSession()));
|
|
||||||
Mutex_ = std::make_shared<std::mutex>();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "framework/SubSystemServer.h"
|
#include "framework/SubSystemServer.h"
|
||||||
|
|
||||||
#include "AP_WS_Reactor_Pool.h"
|
#include "AP_WS_ReactorPool.h"
|
||||||
#include "TelemetryClient.h"
|
#include "TelemetryClient.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ namespace OpenWifi::GWWebSocketNotifications {
|
|||||||
|
|
||||||
struct SingleDevice {
|
struct SingleDevice {
|
||||||
std::string serialNumber;
|
std::string serialNumber;
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
inline void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SingleDeviceConfigurationChange {
|
struct SingleDeviceConfigurationChange {
|
||||||
@@ -20,15 +20,15 @@ namespace OpenWifi::GWWebSocketNotifications {
|
|||||||
uint64_t oldUUID;
|
uint64_t oldUUID;
|
||||||
uint64_t newUUID;
|
uint64_t newUUID;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
inline void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SingleDeviceFirmwareChange {
|
struct SingleDeviceFirmwareChange {
|
||||||
std::string serialNumber;
|
std::string serialNumber;
|
||||||
std::string newFirmware;
|
std::string newFirmware;
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
inline void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct NumberOfConnection {
|
struct NumberOfConnection {
|
||||||
@@ -38,8 +38,8 @@ namespace OpenWifi::GWWebSocketNotifications {
|
|||||||
std::uint64_t rx = 0;
|
std::uint64_t rx = 0;
|
||||||
std::uint64_t tx = 0;
|
std::uint64_t tx = 0;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
inline void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
void Register();
|
void Register();
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by stephane bourque on 2023-07-12.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "framework/SubSystemServer.h"
|
|
||||||
#include "Poco/ExpireLRUCache.h"
|
|
||||||
#include "sdks/sdk_fms.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
|
||||||
class FirmwareRevisionCache : public SubSystemServer {
|
|
||||||
public:
|
|
||||||
static auto instance() {
|
|
||||||
static auto instance_ = new FirmwareRevisionCache;
|
|
||||||
return instance_;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline int Start() override {
|
|
||||||
poco_notice(Logger(), "Starting...");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Stop() override {
|
|
||||||
poco_notice(Logger(), "Stopping...");
|
|
||||||
poco_notice(Logger(), "Stopped...");
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool DeviceMustUpgrade([[maybe_unused]] std::string &deviceType,
|
|
||||||
[[maybe_unused]] const std::string &firmware_string,
|
|
||||||
[[maybe_unused]] GWObjects::DefaultFirmware &Firmware) {
|
|
||||||
return false;
|
|
||||||
if(StorageService()->GetDefaultFirmware(deviceType,Firmware)) {
|
|
||||||
|
|
||||||
std::string key{ deviceType + Firmware.revision };
|
|
||||||
|
|
||||||
if(!Cache_.has(key)) {
|
|
||||||
FMSObjects::FirmwareAgeDetails FAD;
|
|
||||||
if(SDK::FMS::GetFirmwareAge(deviceType,Firmware.revision,FAD,Logger())) {
|
|
||||||
Cache_.add(key,FAD);
|
|
||||||
} else {
|
|
||||||
// if we cannot establish the age of the currently running firmware,
|
|
||||||
// then we assume it is too old.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto FAD = Cache_.get(key);
|
|
||||||
if(FAD->imageDate < Firmware.imageCreationDate) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Poco::ExpireLRUCache<std::string, FMSObjects::FirmwareAgeDetails> Cache_{
|
|
||||||
512, 1200000};
|
|
||||||
|
|
||||||
FirmwareRevisionCache() noexcept
|
|
||||||
: SubSystemServer("FirmwareRevisionCache", "FWCACHE-SVR", "firmwarecache") {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
inline auto FirmwareRevisionCache() { return FirmwareRevisionCache::instance(); }
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
|
||||||
@@ -26,7 +26,7 @@ namespace OpenWifi {
|
|||||||
Response.set("Connection", "keep-alive");
|
Response.set("Connection", "keep-alive");
|
||||||
Response.setVersion(Poco::Net::HTTPMessage::HTTP_1_1);
|
Response.setVersion(Poco::Net::HTTPMessage::HTTP_1_1);
|
||||||
std::ostream &Answer = Response.send();
|
std::ostream &Answer = Response.send();
|
||||||
Answer << ALBHealthCheckServer()->CallbackText();
|
Answer << "process Alive and kicking!";
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,8 +37,6 @@ namespace OpenWifi {
|
|||||||
inline static std::atomic_uint64_t req_id_ = 1;
|
inline static std::atomic_uint64_t req_id_ = 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::string ALBHealthMessageCallback();
|
|
||||||
|
|
||||||
class ALBHealthCheckServer : public SubSystemServer {
|
class ALBHealthCheckServer : public SubSystemServer {
|
||||||
public:
|
public:
|
||||||
ALBHealthCheckServer();
|
ALBHealthCheckServer();
|
||||||
@@ -50,22 +48,10 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
int Start() override;
|
int Start() override;
|
||||||
void Stop() override;
|
void Stop() override;
|
||||||
inline void RegisterExtendedHealthMessage(ALBHealthMessageCallback *F) {
|
|
||||||
Callback_=F;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline std::string CallbackText() {
|
|
||||||
if(Callback_== nullptr) {
|
|
||||||
return "process Alive and kicking!";
|
|
||||||
} else {
|
|
||||||
return Callback_();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<Poco::Net::HTTPServer> Server_;
|
std::unique_ptr<Poco::Net::HTTPServer> Server_;
|
||||||
std::unique_ptr<Poco::Net::ServerSocket> Socket_;
|
std::unique_ptr<Poco::Net::ServerSocket> Socket_;
|
||||||
ALBHealthMessageCallback *Callback_= nullptr;
|
|
||||||
int Port_ = 0;
|
int Port_ = 0;
|
||||||
mutable std::atomic_bool Running_ = false;
|
mutable std::atomic_bool Running_ = false;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,12 +11,10 @@
|
|||||||
|
|
||||||
#include "Poco/File.h"
|
#include "Poco/File.h"
|
||||||
#include "Poco/StreamCopier.h"
|
#include "Poco/StreamCopier.h"
|
||||||
#include "Poco/JSON/Object.h"
|
|
||||||
#include "Poco/JSON/Parser.h"
|
|
||||||
|
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
|
|
||||||
// #include "nlohmann/json.hpp"
|
#include "nlohmann/json.hpp"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
@@ -30,11 +28,11 @@ namespace OpenWifi {
|
|||||||
if (F.exists()) {
|
if (F.exists()) {
|
||||||
std::ostringstream OS;
|
std::ostringstream OS;
|
||||||
std::ifstream IF(FileName);
|
std::ifstream IF(FileName);
|
||||||
Poco::JSON::Parser P;
|
Poco::StreamCopier::copyStream(IF, OS);
|
||||||
Registry_ = P.parse(IF).extract<Poco::JSON::Object::Ptr>();
|
Registry_ = nlohmann::json::parse(OS.str());
|
||||||
}
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Registry_ = Poco::makeShared<Poco::JSON::Object>();
|
Registry_ = nlohmann::json::parse("{}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,39 +44,46 @@ namespace OpenWifi {
|
|||||||
inline ~AppServiceRegistry() { Save(); }
|
inline ~AppServiceRegistry() { Save(); }
|
||||||
|
|
||||||
inline void Save() {
|
inline void Save() {
|
||||||
|
std::istringstream IS(to_string(Registry_));
|
||||||
std::ofstream OF;
|
std::ofstream OF;
|
||||||
OF.open(FileName, std::ios::binary | std::ios::trunc);
|
OF.open(FileName, std::ios::binary | std::ios::trunc);
|
||||||
Registry_->stringify(OF);
|
Poco::StreamCopier::copyStream(IS, OF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Set(const char *key, const std::vector<std::string> &V) {
|
inline void Set(const char *Key, uint64_t Value) {
|
||||||
Poco::JSON::Array Arr;
|
Registry_[Key] = Value;
|
||||||
for(const auto &s:V) {
|
|
||||||
Arr.add(s);
|
|
||||||
}
|
|
||||||
Registry_->set(key,Arr);
|
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> void Set(const char *key, const T &Value) {
|
inline void Set(const char *Key, const std::string &Value) {
|
||||||
Registry_->set(key,Value);
|
Registry_[Key] = Value;
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Get(const char *key, std::vector<std::string> &Value) {
|
inline void Set(const char *Key, bool Value) {
|
||||||
if(Registry_->has(key) && !Registry_->isNull(key) && Registry_->isArray(key)) {
|
Registry_[Key] = Value;
|
||||||
auto Arr = Registry_->get(key);
|
Save();
|
||||||
for(const auto &v:Arr) {
|
|
||||||
Value.emplace_back(v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool Get(const char *Key, bool &Value) {
|
||||||
|
if (Registry_[Key].is_boolean()) {
|
||||||
|
Value = Registry_[Key].get<bool>();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> bool Get(const char *key, T &Value) {
|
inline bool Get(const char *Key, uint64_t &Value) {
|
||||||
if(Registry_->has(key) && !Registry_->isNull(key)) {
|
if (Registry_[Key].is_number_unsigned()) {
|
||||||
Value = Registry_->getValue<T>(key);
|
Value = Registry_[Key].get<uint64_t>();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Get(const char *Key, std::string &Value) {
|
||||||
|
if (Registry_[Key].is_string()) {
|
||||||
|
Value = Registry_[Key].get<std::string>();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -86,7 +91,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::string FileName;
|
std::string FileName;
|
||||||
Poco::JSON::Object::Ptr Registry_;
|
nlohmann::json Registry_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto AppServiceRegistry() { return AppServiceRegistry::instance(); }
|
inline auto AppServiceRegistry() { return AppServiceRegistry::instance(); }
|
||||||
|
|||||||
@@ -34,17 +34,9 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"strict": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"uuid": {
|
"uuid": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
"public_ip_lookup": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uc-fqdn"
|
|
||||||
},
|
|
||||||
"unit": {
|
"unit": {
|
||||||
"$ref": "#/$defs/unit"
|
"$ref": "#/$defs/unit"
|
||||||
},
|
},
|
||||||
@@ -118,20 +110,6 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
"random-password": {
|
"random-password": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false
|
"default": false
|
||||||
},
|
|
||||||
"beacon-advertisement": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"device-name": {
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"device-serial": {
|
|
||||||
"type": "boolean"
|
|
||||||
},
|
|
||||||
"network-id": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -240,52 +218,6 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"interface.ssid.encryption": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"proto": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"none",
|
|
||||||
"owe",
|
|
||||||
"owe-transition",
|
|
||||||
"psk",
|
|
||||||
"psk2",
|
|
||||||
"psk-mixed",
|
|
||||||
"psk2-radius",
|
|
||||||
"wpa",
|
|
||||||
"wpa2",
|
|
||||||
"wpa-mixed",
|
|
||||||
"sae",
|
|
||||||
"sae-mixed",
|
|
||||||
"wpa3",
|
|
||||||
"wpa3-192",
|
|
||||||
"wpa3-mixed"
|
|
||||||
],
|
|
||||||
"examples": [
|
|
||||||
"psk2"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"key": {
|
|
||||||
"type": "string",
|
|
||||||
"maxLength": 63,
|
|
||||||
"minLength": 8
|
|
||||||
},
|
|
||||||
"ieee80211w": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"disabled",
|
|
||||||
"optional",
|
|
||||||
"required"
|
|
||||||
],
|
|
||||||
"default": "disabled"
|
|
||||||
},
|
|
||||||
"key-caching": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"definitions": {
|
"definitions": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -702,6 +634,26 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "uc-timeout",
|
"format": "uc-timeout",
|
||||||
"default": "6h"
|
"default": "6h"
|
||||||
|
},
|
||||||
|
"relay-server": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "ipv4",
|
||||||
|
"example": "192.168.2.1"
|
||||||
|
},
|
||||||
|
"circuit-id-format": {
|
||||||
|
"type": "string",
|
||||||
|
"example": [
|
||||||
|
"\\{Interface\\}:\\{VLAN-Id\\}:\\{SSID\\}:\\{Model\\}:\\{Name\\}:\\{AP-MAC\\}:\\{Location\\}",
|
||||||
|
"\\{AP-MAC\\};\\{SSID\\};\\{Crypto\\}",
|
||||||
|
"\\{Name\\} \\{ESSID\\}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"remote-id-format": {
|
||||||
|
"type": "string",
|
||||||
|
"example": [
|
||||||
|
"\\{Client-MAC-hex\\} \\{SSID\\}",
|
||||||
|
"\\{AP-MAC-hex\\} \\{SSID\\}"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -780,8 +732,7 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"dynamic",
|
"dynamic",
|
||||||
"static",
|
"static"
|
||||||
"none"
|
|
||||||
],
|
],
|
||||||
"examples": [
|
"examples": [
|
||||||
"static"
|
"static"
|
||||||
@@ -1071,6 +1022,52 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"interface.ssid.encryption": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"proto": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"none",
|
||||||
|
"owe",
|
||||||
|
"owe-transition",
|
||||||
|
"psk",
|
||||||
|
"psk2",
|
||||||
|
"psk-mixed",
|
||||||
|
"psk2-radius",
|
||||||
|
"wpa",
|
||||||
|
"wpa2",
|
||||||
|
"wpa-mixed",
|
||||||
|
"sae",
|
||||||
|
"sae-mixed",
|
||||||
|
"wpa3",
|
||||||
|
"wpa3-192",
|
||||||
|
"wpa3-mixed"
|
||||||
|
],
|
||||||
|
"examples": [
|
||||||
|
"psk2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 63,
|
||||||
|
"minLength": 8
|
||||||
|
},
|
||||||
|
"ieee80211w": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"disabled",
|
||||||
|
"optional",
|
||||||
|
"required"
|
||||||
|
],
|
||||||
|
"default": "disabled"
|
||||||
|
},
|
||||||
|
"key-caching": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"interface.ssid.multi-psk": {
|
"interface.ssid.multi-psk": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -1235,32 +1232,6 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
"secret"
|
"secret"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"secondary": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"host": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uc-host",
|
|
||||||
"examples": [
|
|
||||||
"192.168.1.10"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"port": {
|
|
||||||
"type": "integer",
|
|
||||||
"maximum": 65535,
|
|
||||||
"minimum": 1024,
|
|
||||||
"examples": [
|
|
||||||
1812
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"secret": {
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
"secret"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"request-attribute": {
|
"request-attribute": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
@@ -1338,25 +1309,6 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
"value": "Example Operator"
|
"value": "Example Operator"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"id": {
|
|
||||||
"type": "integer",
|
|
||||||
"maximum": 255,
|
|
||||||
"minimum": 1
|
|
||||||
},
|
|
||||||
"hex-value": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"id": 32,
|
|
||||||
"value": "0a0b0c0d"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1706,236 +1658,6 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"service.captive.click": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"auth-mode": {
|
|
||||||
"type": "string",
|
|
||||||
"const": "click-to-continue"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"service.captive.radius": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"auth-mode": {
|
|
||||||
"type": "string",
|
|
||||||
"const": "radius"
|
|
||||||
},
|
|
||||||
"auth-server": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uc-host",
|
|
||||||
"examples": [
|
|
||||||
"192.168.1.10"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"auth-port": {
|
|
||||||
"type": "integer",
|
|
||||||
"maximum": 65535,
|
|
||||||
"minimum": 1024,
|
|
||||||
"default": 1812
|
|
||||||
},
|
|
||||||
"auth-secret": {
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
"secret"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"acct-server": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uc-host",
|
|
||||||
"examples": [
|
|
||||||
"192.168.1.10"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"acct-port": {
|
|
||||||
"type": "integer",
|
|
||||||
"maximum": 65535,
|
|
||||||
"minimum": 1024,
|
|
||||||
"default": 1812
|
|
||||||
},
|
|
||||||
"acct-secret": {
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
"secret"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"acct-interval": {
|
|
||||||
"type": "integer",
|
|
||||||
"default": 600
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"service.captive.credentials": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"auth-mode": {
|
|
||||||
"type": "string",
|
|
||||||
"const": "credentials"
|
|
||||||
},
|
|
||||||
"credentials": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"username": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"password": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"service.captive.uam": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"auth-mode": {
|
|
||||||
"type": "string",
|
|
||||||
"const": "uam"
|
|
||||||
},
|
|
||||||
"uam-port": {
|
|
||||||
"type": "integer",
|
|
||||||
"maximum": 65535,
|
|
||||||
"minimum": 1024,
|
|
||||||
"default": 3990
|
|
||||||
},
|
|
||||||
"uam-secret": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"uam-server": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"nasid": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"nasmac": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"auth-server": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uc-host",
|
|
||||||
"examples": [
|
|
||||||
"192.168.1.10"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"auth-port": {
|
|
||||||
"type": "integer",
|
|
||||||
"maximum": 65535,
|
|
||||||
"minimum": 1024,
|
|
||||||
"default": 1812
|
|
||||||
},
|
|
||||||
"auth-secret": {
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
"secret"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"acct-server": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uc-host",
|
|
||||||
"examples": [
|
|
||||||
"192.168.1.10"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"acct-port": {
|
|
||||||
"type": "integer",
|
|
||||||
"maximum": 65535,
|
|
||||||
"minimum": 1024,
|
|
||||||
"default": 1812
|
|
||||||
},
|
|
||||||
"acct-secret": {
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
"secret"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"acct-interval": {
|
|
||||||
"type": "integer",
|
|
||||||
"default": 600
|
|
||||||
},
|
|
||||||
"ssid": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"mac-format": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"aabbccddeeff",
|
|
||||||
"aa-bb-cc-dd-ee-ff",
|
|
||||||
"aa:bb:cc:dd:ee:ff",
|
|
||||||
"AABBCCDDEEFF",
|
|
||||||
"AA:BB:CC:DD:EE:FF",
|
|
||||||
"AA-BB-CC-DD-EE-FF"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"final-redirect-url": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"default",
|
|
||||||
"uam"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"mac-auth": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": "default"
|
|
||||||
},
|
|
||||||
"radius-gw-proxy": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"service.captive": {
|
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"oneOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/$defs/service.captive.click"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"$ref": "#/$defs/service.captive.radius"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"$ref": "#/$defs/service.captive.credentials"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"$ref": "#/$defs/service.captive.uam"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"walled-garden-fqdn": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"walled-garden-ipaddr": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uc-ip"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"web-root": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uc-base64"
|
|
||||||
},
|
|
||||||
"idle-timeout": {
|
|
||||||
"type": "integer",
|
|
||||||
"default": 600
|
|
||||||
},
|
|
||||||
"session-timeout": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"interface.ssid": {
|
"interface.ssid": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -1988,10 +1710,6 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
"isolate-clients": {
|
"isolate-clients": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"strict-forwarding": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": false
|
|
||||||
},
|
|
||||||
"power-save": {
|
"power-save": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
@@ -2039,11 +1757,6 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
"decription": "This option allows embedding custom vendor specific IEs inside the beacons of a BSS in AP mode.",
|
"decription": "This option allows embedding custom vendor specific IEs inside the beacons of a BSS in AP mode.",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"tip-information-element": {
|
|
||||||
"decription": "The device will broadcast the TIP vendor IE inside its beacons if this option is enabled.",
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
},
|
|
||||||
"fils-discovery-interval": {
|
"fils-discovery-interval": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"default": 20,
|
"default": 20,
|
||||||
@@ -2065,15 +1778,8 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
"$ref": "#/$defs/interface.ssid.rate-limit"
|
"$ref": "#/$defs/interface.ssid.rate-limit"
|
||||||
},
|
},
|
||||||
"roaming": {
|
"roaming": {
|
||||||
"anyOf": [
|
|
||||||
{
|
|
||||||
"$ref": "#/$defs/interface.ssid.roaming"
|
"$ref": "#/$defs/interface.ssid.roaming"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"type": "boolean"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"radius": {
|
"radius": {
|
||||||
"$ref": "#/$defs/interface.ssid.radius"
|
"$ref": "#/$defs/interface.ssid.radius"
|
||||||
},
|
},
|
||||||
@@ -2089,9 +1795,6 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
"access-control-list": {
|
"access-control-list": {
|
||||||
"$ref": "#/$defs/interface.ssid.acl"
|
"$ref": "#/$defs/interface.ssid.acl"
|
||||||
},
|
},
|
||||||
"captive": {
|
|
||||||
"$ref": "#/$defs/service.captive"
|
|
||||||
},
|
|
||||||
"hostapd-bss-raw": {
|
"hostapd-bss-raw": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
@@ -2259,17 +1962,6 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"vlan-awareness": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"first": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"last": {
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"vlan": {
|
"vlan": {
|
||||||
"$ref": "#/$defs/interface.vlan"
|
"$ref": "#/$defs/interface.vlan"
|
||||||
},
|
},
|
||||||
@@ -2392,10 +2084,6 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
"examples": [
|
"examples": [
|
||||||
"01234567890123456789012345678901"
|
"01234567890123456789012345678901"
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"mutual-tls": {
|
|
||||||
"type": "boolean",
|
|
||||||
"default": true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2467,24 +2155,6 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
"mode": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"radius",
|
|
||||||
"user"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"port-filter": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
{
|
|
||||||
"LAN1": null
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"server-certificate": {
|
"server-certificate": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -2496,77 +2166,6 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/$defs/interface.ssid.radius.local-user"
|
"$ref": "#/$defs/interface.ssid.radius.local-user"
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"radius": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"nas-identifier": {
|
|
||||||
"type": "string"
|
|
||||||
},
|
|
||||||
"auth-server-addr": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uc-host",
|
|
||||||
"examples": [
|
|
||||||
"192.168.1.10"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"auth-server-port": {
|
|
||||||
"type": "integer",
|
|
||||||
"maximum": 65535,
|
|
||||||
"minimum": 1024,
|
|
||||||
"examples": [
|
|
||||||
1812
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"auth-server-secret": {
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
"secret"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"acct-server-addr": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uc-host",
|
|
||||||
"examples": [
|
|
||||||
"192.168.1.10"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"acct-server-port": {
|
|
||||||
"type": "integer",
|
|
||||||
"maximum": 65535,
|
|
||||||
"minimum": 1024,
|
|
||||||
"examples": [
|
|
||||||
1813
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"acct-server-secret": {
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
"secret"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"coa-server-addr": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uc-host",
|
|
||||||
"examples": [
|
|
||||||
"192.168.1.10"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"coa-server-port": {
|
|
||||||
"type": "integer",
|
|
||||||
"maximum": 65535,
|
|
||||||
"minimum": 1024,
|
|
||||||
"examples": [
|
|
||||||
1814
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"coa-server-secret": {
|
|
||||||
"type": "string",
|
|
||||||
"examples": [
|
|
||||||
"secret"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -2890,12 +2489,6 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"services": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"classifier": {
|
"classifier": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
@@ -3100,6 +2693,236 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"service.captive.click": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"auth-mode": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "click-to-continue"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"service.captive.radius": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"auth-mode": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "radius"
|
||||||
|
},
|
||||||
|
"auth-server": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uc-host",
|
||||||
|
"examples": [
|
||||||
|
"192.168.1.10"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"auth-port": {
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 65535,
|
||||||
|
"minimum": 1024,
|
||||||
|
"default": 1812
|
||||||
|
},
|
||||||
|
"auth-secret": {
|
||||||
|
"type": "string",
|
||||||
|
"examples": [
|
||||||
|
"secret"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"acct-server": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uc-host",
|
||||||
|
"examples": [
|
||||||
|
"192.168.1.10"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"acct-port": {
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 65535,
|
||||||
|
"minimum": 1024,
|
||||||
|
"default": 1812
|
||||||
|
},
|
||||||
|
"acct-secret": {
|
||||||
|
"type": "string",
|
||||||
|
"examples": [
|
||||||
|
"secret"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"acct-interval": {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 600
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"service.captive.credentials": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"auth-mode": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "credentials"
|
||||||
|
},
|
||||||
|
"credentials": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"username": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"password": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"service.captive.uam": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"auth-mode": {
|
||||||
|
"type": "string",
|
||||||
|
"const": "uam"
|
||||||
|
},
|
||||||
|
"uam-port": {
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 65535,
|
||||||
|
"minimum": 1024,
|
||||||
|
"default": 3990
|
||||||
|
},
|
||||||
|
"uam-secret": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"uam-server": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"nasid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"nasmac": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"auth-server": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uc-host",
|
||||||
|
"examples": [
|
||||||
|
"192.168.1.10"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"auth-port": {
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 65535,
|
||||||
|
"minimum": 1024,
|
||||||
|
"default": 1812
|
||||||
|
},
|
||||||
|
"auth-secret": {
|
||||||
|
"type": "string",
|
||||||
|
"examples": [
|
||||||
|
"secret"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"acct-server": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uc-host",
|
||||||
|
"examples": [
|
||||||
|
"192.168.1.10"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"acct-port": {
|
||||||
|
"type": "integer",
|
||||||
|
"maximum": 65535,
|
||||||
|
"minimum": 1024,
|
||||||
|
"default": 1812
|
||||||
|
},
|
||||||
|
"acct-secret": {
|
||||||
|
"type": "string",
|
||||||
|
"examples": [
|
||||||
|
"secret"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"acct-interval": {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 600
|
||||||
|
},
|
||||||
|
"ssid": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"mac-format": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"aabbccddeeff",
|
||||||
|
"aa-bb-cc-dd-ee-ff",
|
||||||
|
"aa:bb:cc:dd:ee:ff",
|
||||||
|
"AABBCCDDEEFF",
|
||||||
|
"AA:BB:CC:DD:EE:FF",
|
||||||
|
"AA-BB-CC-DD-EE-FF"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"final-redirect-url": {
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"default",
|
||||||
|
"uam"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"mac-auth": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": "default"
|
||||||
|
},
|
||||||
|
"radius-gw-proxy": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"service.captive": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/service.captive.click"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/service.captive.radius"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/service.captive.credentials"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"$ref": "#/$defs/service.captive.uam"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"walled-garden-fqdn": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"walled-garden-ipaddr": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uc-ip"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"web-root": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uc-base64"
|
||||||
|
},
|
||||||
|
"idle-timeout": {
|
||||||
|
"type": "integer",
|
||||||
|
"default": 600
|
||||||
|
},
|
||||||
|
"session-timeout": {
|
||||||
|
"type": "integer"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"service.gps": {
|
"service.gps": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -3118,50 +2941,6 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"service.dhcp-relay": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"select-ports": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"vlans": {
|
|
||||||
"type": "array",
|
|
||||||
"items": {
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"vlan": {
|
|
||||||
"type": "number"
|
|
||||||
},
|
|
||||||
"relay-server": {
|
|
||||||
"type": "string",
|
|
||||||
"format": "uc-ip"
|
|
||||||
},
|
|
||||||
"circuit-id-format": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"vlan-id",
|
|
||||||
"ap-mac",
|
|
||||||
"ssid"
|
|
||||||
],
|
|
||||||
"default": "vlan-id"
|
|
||||||
},
|
|
||||||
"remote-id-format": {
|
|
||||||
"type": "string",
|
|
||||||
"enum": [
|
|
||||||
"vlan-id",
|
|
||||||
"ap-mac",
|
|
||||||
"ssid"
|
|
||||||
],
|
|
||||||
"default": "ap-mac"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"service": {
|
"service": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -3221,9 +3000,6 @@ static std::string DefaultUCentralSchema = R"foo(
|
|||||||
},
|
},
|
||||||
"gps": {
|
"gps": {
|
||||||
"$ref": "#/$defs/service.gps"
|
"$ref": "#/$defs/service.gps"
|
||||||
},
|
|
||||||
"dhcp-relay": {
|
|
||||||
"$ref": "#/$defs/service.dhcp-relay"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -9,21 +9,23 @@
|
|||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
|
EventBusManager::EventBusManager(Poco::Logger &L) : Logger_(L) {}
|
||||||
|
|
||||||
void EventBusManager::run() {
|
void EventBusManager::run() {
|
||||||
Running_ = true;
|
Running_ = true;
|
||||||
Utils::SetThreadName("fmwk:EventMgr");
|
Utils::SetThreadName("fmwk:EventMgr");
|
||||||
auto Msg = (MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN));
|
auto Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN);
|
||||||
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg,
|
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg,
|
||||||
false);
|
false);
|
||||||
while (Running_) {
|
while (Running_) {
|
||||||
Poco::Thread::trySleep((unsigned long)MicroServiceDaemonBusTimer());
|
Poco::Thread::trySleep((unsigned long)MicroServiceDaemonBusTimer());
|
||||||
if (!Running_)
|
if (!Running_)
|
||||||
break;
|
break;
|
||||||
Msg = (MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE));
|
Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE);
|
||||||
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(),
|
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(),
|
||||||
Msg, false);
|
Msg, false);
|
||||||
}
|
}
|
||||||
Msg = (MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE));
|
Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE);
|
||||||
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg,
|
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg,
|
||||||
false);
|
false);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -12,16 +12,6 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
class EventBusManager : public Poco::Runnable {
|
class EventBusManager : public Poco::Runnable {
|
||||||
public:
|
public:
|
||||||
EventBusManager() :
|
|
||||||
Logger_(Poco::Logger::create(
|
|
||||||
"EventBusManager", Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel())) {
|
|
||||||
}
|
|
||||||
|
|
||||||
static auto instance() {
|
|
||||||
static auto instance_ = new EventBusManager;
|
|
||||||
return instance_;
|
|
||||||
}
|
|
||||||
|
|
||||||
explicit EventBusManager(Poco::Logger &L);
|
explicit EventBusManager(Poco::Logger &L);
|
||||||
void run() final;
|
void run() final;
|
||||||
void Start();
|
void Start();
|
||||||
@@ -34,6 +24,4 @@ namespace OpenWifi {
|
|||||||
Poco::Logger &Logger_;
|
Poco::Logger &Logger_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline auto EventBusManager() { return EventBusManager::instance(); }
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include "fmt/format.h"
|
#include "fmt/format.h"
|
||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
#include "cppkafka/utils/consumer_dispatcher.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
@@ -100,12 +99,9 @@ namespace OpenWifi {
|
|||||||
try {
|
try {
|
||||||
auto Msg = dynamic_cast<KafkaMessage *>(Note.get());
|
auto Msg = dynamic_cast<KafkaMessage *>(Note.get());
|
||||||
if (Msg != nullptr) {
|
if (Msg != nullptr) {
|
||||||
auto NewMessage = cppkafka::MessageBuilder(Msg->Topic());
|
Producer.produce(cppkafka::MessageBuilder(Msg->Topic())
|
||||||
NewMessage.key(Msg->Key());
|
.key(Msg->Key())
|
||||||
NewMessage.partition(0);
|
.payload(Msg->Payload()));
|
||||||
NewMessage.payload(Msg->Payload());
|
|
||||||
Producer.produce(NewMessage);
|
|
||||||
Producer.flush();
|
|
||||||
}
|
}
|
||||||
} catch (const cppkafka::HandleException &E) {
|
} catch (const cppkafka::HandleException &E) {
|
||||||
poco_warning(Logger_,
|
poco_warning(Logger_,
|
||||||
@@ -160,49 +156,43 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// bool AutoCommit = MicroServiceConfigGetBool("openwifi.kafka.auto.commit", false);
|
bool AutoCommit = MicroServiceConfigGetBool("openwifi.kafka.auto.commit", false);
|
||||||
// auto BatchSize = MicroServiceConfigGetInt("openwifi.kafka.consumer.batchsize", 100);
|
auto BatchSize = MicroServiceConfigGetInt("openwifi.kafka.consumer.batchsize", 20);
|
||||||
|
|
||||||
Types::StringVec Topics;
|
Types::StringVec Topics;
|
||||||
std::for_each(Topics_.begin(),Topics_.end(),
|
KafkaManager()->Topics(Topics);
|
||||||
[&](const std::string & T) { Topics.emplace_back(T); });
|
|
||||||
Consumer.subscribe(Topics);
|
Consumer.subscribe(Topics);
|
||||||
|
|
||||||
Running_ = true;
|
Running_ = true;
|
||||||
std::vector<cppkafka::Message> MsgVec;
|
while (Running_) {
|
||||||
|
|
||||||
Dispatcher_ = std::make_unique<cppkafka::ConsumerDispatcher>(Consumer);
|
|
||||||
|
|
||||||
Dispatcher_->run(
|
|
||||||
// Callback executed whenever a new message is consumed
|
|
||||||
[&](cppkafka::Message msg) {
|
|
||||||
// Print the key (if any)
|
|
||||||
std::lock_guard G(ConsumerMutex_);
|
|
||||||
auto It = Notifiers_.find(msg.get_topic());
|
|
||||||
if (It != Notifiers_.end()) {
|
|
||||||
const auto &FL = It->second;
|
|
||||||
for (const auto &[CallbackFunc, _] : FL) {
|
|
||||||
try {
|
try {
|
||||||
CallbackFunc(msg.get_key(), msg.get_payload());
|
std::vector<cppkafka::Message> MsgVec =
|
||||||
|
Consumer.poll_batch(BatchSize, std::chrono::milliseconds(100));
|
||||||
|
for (auto const &Msg : MsgVec) {
|
||||||
|
if (!Msg)
|
||||||
|
continue;
|
||||||
|
if (Msg.get_error()) {
|
||||||
|
if (!Msg.is_eof()) {
|
||||||
|
poco_error(Logger_,
|
||||||
|
fmt::format("Error: {}", Msg.get_error().to_string()));
|
||||||
|
}
|
||||||
|
if (!AutoCommit)
|
||||||
|
Consumer.async_commit(Msg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
KafkaManager()->Dispatch(Msg.get_topic(), Msg.get_key(), Msg.get_payload());
|
||||||
|
if (!AutoCommit)
|
||||||
|
Consumer.async_commit(Msg);
|
||||||
|
}
|
||||||
|
} catch (const cppkafka::HandleException &E) {
|
||||||
|
poco_warning(Logger_,
|
||||||
|
fmt::format("Caught a Kafka exception (consumer): {}", E.what()));
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
|
Logger_.log(E);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
poco_error(Logger_, "std::exception");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Consumer.commit(msg);
|
|
||||||
},
|
|
||||||
// Whenever there's an error (other than the EOF soft error)
|
|
||||||
[&Logger_](cppkafka::Error error) {
|
|
||||||
poco_warning(Logger_,fmt::format("Error: {}", error.to_string()));
|
|
||||||
},
|
|
||||||
// Whenever EOF is reached on a partition, print this
|
|
||||||
[&Logger_](cppkafka::ConsumerDispatcher::EndOfFile, const cppkafka::TopicPartition& topic_partition) {
|
|
||||||
poco_debug(Logger_,fmt::format("Partition {} EOF", topic_partition.get_partition()));
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
Consumer.unsubscribe();
|
Consumer.unsubscribe();
|
||||||
poco_information(Logger_, "Stopped...");
|
poco_information(Logger_, "Stopped...");
|
||||||
}
|
}
|
||||||
@@ -222,7 +212,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KafkaProducer::Produce(const char *Topic, const std::string &Key,
|
void KafkaProducer::Produce(const std::string &Topic, const std::string &Key,
|
||||||
const std::string &Payload) {
|
const std::string &Payload) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
Queue_.enqueueNotification(new KafkaMessage(Topic, Key, Payload));
|
Queue_.enqueueNotification(new KafkaMessage(Topic, Key, Payload));
|
||||||
@@ -230,6 +220,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
void KafkaConsumer::Start() {
|
void KafkaConsumer::Start() {
|
||||||
if (!Running_) {
|
if (!Running_) {
|
||||||
|
Running_ = true;
|
||||||
Worker_.start(*this);
|
Worker_.start(*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,16 +228,29 @@ namespace OpenWifi {
|
|||||||
void KafkaConsumer::Stop() {
|
void KafkaConsumer::Stop() {
|
||||||
if (Running_) {
|
if (Running_) {
|
||||||
Running_ = false;
|
Running_ = false;
|
||||||
if(Dispatcher_) {
|
Worker_.wakeUp();
|
||||||
Dispatcher_->stop();
|
|
||||||
}
|
|
||||||
Worker_.join();
|
Worker_.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint64_t KafkaConsumer::RegisterTopicWatcher(const std::string &Topic,
|
void KafkaDispatcher::Start() {
|
||||||
|
if (!Running_) {
|
||||||
|
Running_ = true;
|
||||||
|
Worker_.start(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KafkaDispatcher::Stop() {
|
||||||
|
if (Running_) {
|
||||||
|
Running_ = false;
|
||||||
|
Queue_.wakeUpAll();
|
||||||
|
Worker_.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto KafkaDispatcher::RegisterTopicWatcher(const std::string &Topic,
|
||||||
Types::TopicNotifyFunction &F) {
|
Types::TopicNotifyFunction &F) {
|
||||||
std::lock_guard G(ConsumerMutex_);
|
std::lock_guard G(Mutex_);
|
||||||
auto It = Notifiers_.find(Topic);
|
auto It = Notifiers_.find(Topic);
|
||||||
if (It == Notifiers_.end()) {
|
if (It == Notifiers_.end()) {
|
||||||
Types::TopicNotifyFunctionList L;
|
Types::TopicNotifyFunctionList L;
|
||||||
@@ -255,12 +259,11 @@ namespace OpenWifi {
|
|||||||
} else {
|
} else {
|
||||||
It->second.emplace(It->second.end(), std::make_pair(F, FunctionId_));
|
It->second.emplace(It->second.end(), std::make_pair(F, FunctionId_));
|
||||||
}
|
}
|
||||||
Topics_.insert(Topic);
|
|
||||||
return FunctionId_++;
|
return FunctionId_++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KafkaConsumer::UnregisterTopicWatcher(const std::string &Topic, int Id) {
|
void KafkaDispatcher::UnregisterTopicWatcher(const std::string &Topic, int Id) {
|
||||||
std::lock_guard G(ConsumerMutex_);
|
std::lock_guard G(Mutex_);
|
||||||
auto It = Notifiers_.find(Topic);
|
auto It = Notifiers_.find(Topic);
|
||||||
if (It != Notifiers_.end()) {
|
if (It != Notifiers_.end()) {
|
||||||
Types::TopicNotifyFunctionList &L = It->second;
|
Types::TopicNotifyFunctionList &L = It->second;
|
||||||
@@ -272,17 +275,56 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KafkaDispatcher::Dispatch(const std::string &Topic, const std::string &Key,
|
||||||
|
const std::string &Payload) {
|
||||||
|
std::lock_guard G(Mutex_);
|
||||||
|
auto It = Notifiers_.find(Topic);
|
||||||
|
if (It != Notifiers_.end()) {
|
||||||
|
Queue_.enqueueNotification(new KafkaMessage(Topic, Key, Payload));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KafkaDispatcher::run() {
|
||||||
|
Poco::Logger &Logger_ =
|
||||||
|
Poco::Logger::create("KAFKA-DISPATCHER", KafkaManager()->Logger().getChannel());
|
||||||
|
poco_information(Logger_, "Starting...");
|
||||||
|
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
|
||||||
|
Utils::SetThreadName("kafka:dispatch");
|
||||||
|
while (Note && Running_) {
|
||||||
|
auto Msg = dynamic_cast<KafkaMessage *>(Note.get());
|
||||||
|
if (Msg != nullptr) {
|
||||||
|
auto It = Notifiers_.find(Msg->Topic());
|
||||||
|
if (It != Notifiers_.end()) {
|
||||||
|
const auto &FL = It->second;
|
||||||
|
for (const auto &[CallbackFunc, _] : FL) {
|
||||||
|
CallbackFunc(Msg->Key(), Msg->Payload());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Note = Queue_.waitDequeueNotification();
|
||||||
|
}
|
||||||
|
poco_information(Logger_, "Stopped...");
|
||||||
|
}
|
||||||
|
|
||||||
|
void KafkaDispatcher::Topics(std::vector<std::string> &T) {
|
||||||
|
T.clear();
|
||||||
|
for (const auto &[TopicName, _] : Notifiers_)
|
||||||
|
T.push_back(TopicName);
|
||||||
|
}
|
||||||
|
|
||||||
int KafkaManager::Start() {
|
int KafkaManager::Start() {
|
||||||
if (!KafkaEnabled_)
|
if (!KafkaEnabled_)
|
||||||
return 0;
|
return 0;
|
||||||
ConsumerThr_.Start();
|
ConsumerThr_.Start();
|
||||||
ProducerThr_.Start();
|
ProducerThr_.Start();
|
||||||
|
Dispatcher_.Start();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KafkaManager::Stop() {
|
void KafkaManager::Stop() {
|
||||||
if (KafkaEnabled_) {
|
if (KafkaEnabled_) {
|
||||||
poco_information(Logger(), "Stopping...");
|
poco_information(Logger(), "Stopping...");
|
||||||
|
Dispatcher_.Stop();
|
||||||
ProducerThr_.Stop();
|
ProducerThr_.Stop();
|
||||||
ConsumerThr_.Stop();
|
ConsumerThr_.Stop();
|
||||||
poco_information(Logger(), "Stopped...");
|
poco_information(Logger(), "Stopped...");
|
||||||
@@ -290,27 +332,39 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KafkaManager::PostMessage(const char *topic, const std::string &key,
|
void KafkaManager::PostMessage(const std::string &topic, const std::string &key,
|
||||||
const std::string &PayLoad, bool WrapMessage) {
|
const std::string &PayLoad, bool WrapMessage) {
|
||||||
if (KafkaEnabled_) {
|
if (KafkaEnabled_) {
|
||||||
ProducerThr_.Produce(topic, key, WrapMessage ? WrapSystemId(PayLoad) : PayLoad);
|
ProducerThr_.Produce(topic, key, WrapMessage ? WrapSystemId(PayLoad) : PayLoad);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KafkaManager::PostMessage(const char *topic, const std::string &key,
|
void KafkaManager::Dispatch(const std::string &Topic, const std::string &Key,
|
||||||
const Poco::JSON::Object &Object, bool WrapMessage) {
|
const std::string &Payload) {
|
||||||
if (KafkaEnabled_) {
|
Dispatcher_.Dispatch(Topic, Key, Payload);
|
||||||
std::ostringstream ObjectStr;
|
|
||||||
Object.stringify(ObjectStr);
|
|
||||||
ProducerThr_.Produce(topic, key, WrapMessage ? WrapSystemId(ObjectStr.str()) : ObjectStr.str());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::string KafkaManager::WrapSystemId(const std::string &PayLoad) {
|
[[nodiscard]] std::string KafkaManager::WrapSystemId(const std::string &PayLoad) {
|
||||||
return fmt::format( R"lit({{ "system" : {{ "id" : {}, "host" : "{}" }}, "payload" : {} }})lit",
|
return SystemInfoWrapper_ + PayLoad + "}";
|
||||||
MicroServiceID(), MicroServicePrivateEndPoint(), PayLoad ) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t KafkaManager::RegisterTopicWatcher(const std::string &Topic,
|
||||||
|
Types::TopicNotifyFunction &F) {
|
||||||
|
if (KafkaEnabled_) {
|
||||||
|
return Dispatcher_.RegisterTopicWatcher(Topic, F);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KafkaManager::UnregisterTopicWatcher(const std::string &Topic, uint64_t Id) {
|
||||||
|
if (KafkaEnabled_) {
|
||||||
|
Dispatcher_.UnregisterTopicWatcher(Topic, Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KafkaManager::Topics(std::vector<std::string> &T) { Dispatcher_.Topics(T); }
|
||||||
|
|
||||||
void KafkaManager::PartitionAssignment(const cppkafka::TopicPartitionList &partitions) {
|
void KafkaManager::PartitionAssignment(const cppkafka::TopicPartitionList &partitions) {
|
||||||
poco_information(
|
poco_information(
|
||||||
Logger(), fmt::format("Partition assigned: {}...", partitions.front().get_partition()));
|
Logger(), fmt::format("Partition assigned: {}...", partitions.front().get_partition()));
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "Poco/Notification.h"
|
#include "Poco/Notification.h"
|
||||||
#include "Poco/NotificationQueue.h"
|
#include "Poco/NotificationQueue.h"
|
||||||
#include "Poco/JSON/Object.h"
|
|
||||||
#include "framework/KafkaTopics.h"
|
#include "framework/KafkaTopics.h"
|
||||||
#include "framework/OpenWifiTypes.h"
|
#include "framework/OpenWifiTypes.h"
|
||||||
#include "framework/SubSystemServer.h"
|
#include "framework/SubSystemServer.h"
|
||||||
@@ -18,15 +18,15 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
class KafkaMessage : public Poco::Notification {
|
class KafkaMessage : public Poco::Notification {
|
||||||
public:
|
public:
|
||||||
KafkaMessage(const char * Topic, const std::string &Key, const std::string &Payload)
|
KafkaMessage(const std::string &Topic, const std::string &Key, const std::string &Payload)
|
||||||
: Topic_(Topic), Key_(Key), Payload_(Payload) {}
|
: Topic_(Topic), Key_(Key), Payload_(Payload) {}
|
||||||
|
|
||||||
inline const char * Topic() { return Topic_; }
|
inline const std::string &Topic() { return Topic_; }
|
||||||
inline const std::string &Key() { return Key_; }
|
inline const std::string &Key() { return Key_; }
|
||||||
inline const std::string &Payload() { return Payload_; }
|
inline const std::string &Payload() { return Payload_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char *Topic_;
|
std::string Topic_;
|
||||||
std::string Key_;
|
std::string Key_;
|
||||||
std::string Payload_;
|
std::string Payload_;
|
||||||
};
|
};
|
||||||
@@ -36,10 +36,10 @@ namespace OpenWifi {
|
|||||||
void run() override;
|
void run() override;
|
||||||
void Start();
|
void Start();
|
||||||
void Stop();
|
void Stop();
|
||||||
void Produce(const char *Topic, const std::string &Key, const std::string & Payload);
|
void Produce(const std::string &Topic, const std::string &Key, const std::string &Payload);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex Mutex_;
|
std::recursive_mutex Mutex_;
|
||||||
Poco::Thread Worker_;
|
Poco::Thread Worker_;
|
||||||
mutable std::atomic_bool Running_ = false;
|
mutable std::atomic_bool Running_ = false;
|
||||||
Poco::NotificationQueue Queue_;
|
Poco::NotificationQueue Queue_;
|
||||||
@@ -47,22 +47,33 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
class KafkaConsumer : public Poco::Runnable {
|
class KafkaConsumer : public Poco::Runnable {
|
||||||
public:
|
public:
|
||||||
|
void run() override;
|
||||||
void Start();
|
void Start();
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::mutex ConsumerMutex_;
|
std::recursive_mutex Mutex_;
|
||||||
|
Poco::Thread Worker_;
|
||||||
|
mutable std::atomic_bool Running_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
class KafkaDispatcher : public Poco::Runnable {
|
||||||
|
public:
|
||||||
|
void Start();
|
||||||
|
void Stop();
|
||||||
|
auto RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
|
||||||
|
void UnregisterTopicWatcher(const std::string &Topic, int Id);
|
||||||
|
void Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload);
|
||||||
|
void run() override;
|
||||||
|
void Topics(std::vector<std::string> &T);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::recursive_mutex Mutex_;
|
||||||
Types::NotifyTable Notifiers_;
|
Types::NotifyTable Notifiers_;
|
||||||
Poco::Thread Worker_;
|
Poco::Thread Worker_;
|
||||||
mutable std::atomic_bool Running_ = false;
|
mutable std::atomic_bool Running_ = false;
|
||||||
uint64_t FunctionId_ = 1;
|
uint64_t FunctionId_ = 1;
|
||||||
std::unique_ptr<cppkafka::ConsumerDispatcher> Dispatcher_;
|
Poco::NotificationQueue Queue_;
|
||||||
std::set<std::string> Topics_;
|
|
||||||
|
|
||||||
void run() override;
|
|
||||||
friend class KafkaManager;
|
|
||||||
std::uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
|
|
||||||
void UnregisterTopicWatcher(const std::string &Topic, int Id);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class KafkaManager : public SubSystemServer {
|
class KafkaManager : public SubSystemServer {
|
||||||
@@ -80,25 +91,21 @@ namespace OpenWifi {
|
|||||||
int Start() override;
|
int Start() override;
|
||||||
void Stop() override;
|
void Stop() override;
|
||||||
|
|
||||||
void PostMessage(const char *topic, const std::string &key,
|
void PostMessage(const std::string &topic, const std::string &key,
|
||||||
const std::string &PayLoad, bool WrapMessage = true);
|
const std::string &PayLoad, bool WrapMessage = true);
|
||||||
void PostMessage(const char *topic, const std::string &key,
|
void Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload);
|
||||||
const Poco::JSON::Object &Object, bool WrapMessage = true);
|
|
||||||
|
|
||||||
[[nodiscard]] std::string WrapSystemId(const std::string &PayLoad);
|
[[nodiscard]] std::string WrapSystemId(const std::string &PayLoad);
|
||||||
[[nodiscard]] inline bool Enabled() const { return KafkaEnabled_; }
|
[[nodiscard]] inline bool Enabled() const { return KafkaEnabled_; }
|
||||||
inline std::uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) {
|
uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
|
||||||
return ConsumerThr_.RegisterTopicWatcher(Topic,F);
|
void UnregisterTopicWatcher(const std::string &Topic, uint64_t Id);
|
||||||
}
|
void Topics(std::vector<std::string> &T);
|
||||||
inline void UnregisterTopicWatcher(const std::string &Topic, uint64_t Id) {
|
|
||||||
return ConsumerThr_.UnregisterTopicWatcher(Topic,Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool KafkaEnabled_ = false;
|
bool KafkaEnabled_ = false;
|
||||||
std::string SystemInfoWrapper_;
|
std::string SystemInfoWrapper_;
|
||||||
KafkaProducer ProducerThr_;
|
KafkaProducer ProducerThr_;
|
||||||
KafkaConsumer ConsumerThr_;
|
KafkaConsumer ConsumerThr_;
|
||||||
|
KafkaDispatcher Dispatcher_;
|
||||||
|
|
||||||
void PartitionAssignment(const cppkafka::TopicPartitionList &partitions);
|
void PartitionAssignment(const cppkafka::TopicPartitionList &partitions);
|
||||||
void PartitionRevocation(const cppkafka::TopicPartitionList &partitions);
|
void PartitionRevocation(const cppkafka::TopicPartitionList &partitions);
|
||||||
|
|||||||
@@ -10,33 +10,32 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
namespace OpenWifi::KafkaTopics {
|
namespace OpenWifi::KafkaTopics {
|
||||||
inline const char * HEALTHCHECK = "healthcheck";
|
static const std::string HEALTHCHECK{"healthcheck"};
|
||||||
inline const char * STATE = "state";
|
static const std::string STATE{"state"};
|
||||||
inline const char * CONNECTION = "connection";
|
static const std::string CONNECTION{"connection"};
|
||||||
inline const char * WIFISCAN = "wifiscan";
|
static const std::string WIFISCAN{"wifiscan"};
|
||||||
inline const char * ALERTS = "alerts";
|
static const std::string ALERTS{"alerts"};
|
||||||
inline const char * COMMAND = "command";
|
static const std::string COMMAND{"command"};
|
||||||
inline const char * SERVICE_EVENTS = "service_events";
|
static const std::string SERVICE_EVENTS{"service_events"};
|
||||||
inline const char * DEVICE_EVENT_QUEUE = "device_event_queue";
|
static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"};
|
||||||
inline const char * DEVICE_TELEMETRY = "device_telemetry";
|
static const std::string DEVICE_TELEMETRY{"device_telemetry"};
|
||||||
inline const char * PROVISIONING_CHANGE = "provisioning_change";
|
static const std::string PROVISIONING_CHANGE{"provisioning_change"};
|
||||||
inline const char * RRM = "rrm";
|
|
||||||
|
|
||||||
namespace ServiceEvents {
|
namespace ServiceEvents {
|
||||||
inline const char * EVENT_JOIN = "join";
|
static const std::string EVENT_JOIN{"join"};
|
||||||
inline const char * EVENT_LEAVE = "leave";
|
static const std::string EVENT_LEAVE{"leave"};
|
||||||
inline const char * EVENT_KEEP_ALIVE = "keep-alive";
|
static const std::string EVENT_KEEP_ALIVE{"keep-alive"};
|
||||||
inline const char * EVENT_REMOVE_TOKEN = "remove-token";
|
static const std::string EVENT_REMOVE_TOKEN{"remove-token"};
|
||||||
|
|
||||||
namespace Fields {
|
namespace Fields {
|
||||||
inline const char * EVENT = "event";
|
static const std::string EVENT{"event"};
|
||||||
inline const char * ID = "id";
|
static const std::string ID{"id"};
|
||||||
inline const char * TYPE = "type";
|
static const std::string TYPE{"type"};
|
||||||
inline const char * PUBLIC = "publicEndPoint";
|
static const std::string PUBLIC{"publicEndPoint"};
|
||||||
inline const char * PRIVATE = "privateEndPoint";
|
static const std::string PRIVATE{"privateEndPoint"};
|
||||||
inline const char * KEY = "key";
|
static const std::string KEY{"key"};
|
||||||
inline const char * VRSN = "version";
|
static const std::string VRSN{"version"};
|
||||||
inline const char * TOKEN = "token";
|
static const std::string TOKEN{"token"};
|
||||||
} // namespace Fields
|
} // namespace Fields
|
||||||
} // namespace ServiceEvents
|
} // namespace ServiceEvents
|
||||||
} // namespace OpenWifi::KafkaTopics
|
} // namespace OpenWifi::KafkaTopics
|
||||||
|
|||||||
@@ -33,23 +33,9 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
void MicroService::Exit(int Reason) { std::exit(Reason); }
|
void MicroService::Exit(int Reason) { std::exit(Reason); }
|
||||||
|
|
||||||
static std::string MakeServiceListString(const Types::MicroServiceMetaMap &Services) {
|
|
||||||
std::string SvcList;
|
|
||||||
for (const auto &Svc : Services) {
|
|
||||||
if (SvcList.empty())
|
|
||||||
SvcList = Svc.second.Type;
|
|
||||||
else
|
|
||||||
SvcList += ", " + Svc.second.Type;
|
|
||||||
}
|
|
||||||
return SvcList;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MicroService::BusMessageReceived([[maybe_unused]] const std::string &Key,
|
void MicroService::BusMessageReceived([[maybe_unused]] const std::string &Key,
|
||||||
const std::string &Payload) {
|
const std::string &Payload) {
|
||||||
std::lock_guard G(InfraMutex_);
|
std::lock_guard G(InfraMutex_);
|
||||||
|
|
||||||
Poco::Logger &BusLogger = EventBusManager()->Logger();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Poco::JSON::Parser P;
|
Poco::JSON::Parser P;
|
||||||
auto Object = P.parse(Payload).extract<Poco::JSON::Object::Ptr>();
|
auto Object = P.parse(Payload).extract<Poco::JSON::Object::Ptr>();
|
||||||
@@ -69,10 +55,13 @@ namespace OpenWifi {
|
|||||||
Object->has(KafkaTopics::ServiceEvents::Fields::KEY)) {
|
Object->has(KafkaTopics::ServiceEvents::Fields::KEY)) {
|
||||||
auto PrivateEndPoint =
|
auto PrivateEndPoint =
|
||||||
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString();
|
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString();
|
||||||
if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) {
|
if (Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE &&
|
||||||
|
Services_.find(PrivateEndPoint) != Services_.end()) {
|
||||||
|
Services_[PrivateEndPoint].LastUpdate = Utils::Now();
|
||||||
|
} else if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) {
|
||||||
Services_.erase(PrivateEndPoint);
|
Services_.erase(PrivateEndPoint);
|
||||||
poco_information(
|
poco_debug(
|
||||||
BusLogger,
|
logger(),
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"Service {} ID={} leaving system.",
|
"Service {} ID={} leaving system.",
|
||||||
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
|
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
|
||||||
@@ -80,7 +69,14 @@ namespace OpenWifi {
|
|||||||
ID));
|
ID));
|
||||||
} else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN ||
|
} else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN ||
|
||||||
Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) {
|
Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) {
|
||||||
auto ServiceInfo = Types::MicroServiceMeta{
|
poco_debug(
|
||||||
|
logger(),
|
||||||
|
fmt::format(
|
||||||
|
"Service {} ID={} joining system.",
|
||||||
|
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
|
||||||
|
.toString(),
|
||||||
|
ID));
|
||||||
|
Services_[PrivateEndPoint] = Types::MicroServiceMeta{
|
||||||
.Id = ID,
|
.Id = ID,
|
||||||
.Type = Poco::toLower(
|
.Type = Poco::toLower(
|
||||||
Object->get(KafkaTopics::ServiceEvents::Fields::TYPE)
|
Object->get(KafkaTopics::ServiceEvents::Fields::TYPE)
|
||||||
@@ -98,22 +94,6 @@ namespace OpenWifi {
|
|||||||
.toString(),
|
.toString(),
|
||||||
.LastUpdate = Utils::Now()};
|
.LastUpdate = Utils::Now()};
|
||||||
|
|
||||||
auto s1 = MakeServiceListString(Services_);
|
|
||||||
auto PreviousSize = Services_.size();
|
|
||||||
Services_[PrivateEndPoint] = ServiceInfo;
|
|
||||||
auto CurrentSize = Services_.size();
|
|
||||||
if(Event == KafkaTopics::ServiceEvents::EVENT_JOIN) {
|
|
||||||
if(!s1.empty()) {
|
|
||||||
poco_information(
|
|
||||||
BusLogger,
|
|
||||||
fmt::format(
|
|
||||||
"Service {} ID={} is joining the system.",
|
|
||||||
Object
|
|
||||||
->get(
|
|
||||||
KafkaTopics::ServiceEvents::Fields::PRIVATE)
|
|
||||||
.toString(),
|
|
||||||
ID));
|
|
||||||
}
|
|
||||||
std::string SvcList;
|
std::string SvcList;
|
||||||
for (const auto &Svc : Services_) {
|
for (const auto &Svc : Services_) {
|
||||||
if (SvcList.empty())
|
if (SvcList.empty())
|
||||||
@@ -122,22 +102,12 @@ namespace OpenWifi {
|
|||||||
SvcList += ", " + Svc.second.Type;
|
SvcList += ", " + Svc.second.Type;
|
||||||
}
|
}
|
||||||
poco_information(
|
poco_information(
|
||||||
BusLogger,
|
logger(),
|
||||||
fmt::format("Current list of microservices: {}", SvcList));
|
fmt::format("Current list of microservices: {}", SvcList));
|
||||||
} else if(CurrentSize!=PreviousSize) {
|
|
||||||
poco_information(
|
|
||||||
BusLogger,
|
|
||||||
fmt::format(
|
|
||||||
"Service {} ID={} is being added back in.",
|
|
||||||
Object
|
|
||||||
->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
|
|
||||||
.toString(),
|
|
||||||
ID));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
poco_information(
|
poco_error(
|
||||||
BusLogger,
|
logger(),
|
||||||
fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",
|
fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",
|
||||||
Event));
|
Event));
|
||||||
}
|
}
|
||||||
@@ -148,39 +118,30 @@ namespace OpenWifi {
|
|||||||
Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString());
|
Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString());
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
poco_information(
|
poco_error(
|
||||||
BusLogger,
|
logger(),
|
||||||
fmt::format("KAFKA-MSG: invalid event '{}', missing token", Event));
|
fmt::format("KAFKA-MSG: invalid event '{}', missing token", Event));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
poco_information(BusLogger,
|
poco_error(logger(),
|
||||||
fmt::format("Unknown Event: {} Source: {}", Event, ID));
|
fmt::format("Unknown Event: {} Source: {}", Event, ID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::ostringstream os;
|
poco_error(logger(), "Bad bus message.");
|
||||||
Object->stringify(std::cout);
|
|
||||||
poco_error(BusLogger, fmt::format("Bad bus message: {}", os.str()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ServiceHint = Services_.begin();
|
auto i = Services_.begin();
|
||||||
auto now = Utils::Now();
|
auto now = Utils::Now();
|
||||||
auto si1 = Services_.size();
|
for (; i != Services_.end();) {
|
||||||
auto ss1 = MakeServiceListString(Services_);
|
if ((now - i->second.LastUpdate) > 60) {
|
||||||
while(ServiceHint!=Services_.end()) {
|
i = Services_.erase(i);
|
||||||
if ((now - ServiceHint->second.LastUpdate) > 120) {
|
|
||||||
poco_information(BusLogger, fmt::format("ZombieService: Removing service {}, ", ServiceHint->second.PublicEndPoint));
|
|
||||||
ServiceHint = Services_.erase(ServiceHint);
|
|
||||||
} else
|
} else
|
||||||
++ServiceHint;
|
++i;
|
||||||
}
|
|
||||||
if(Services_.size() != si1) {
|
|
||||||
auto ss2 = MakeServiceListString(Services_);
|
|
||||||
poco_information(BusLogger, fmt::format("Current list of microservices: {} -> {}", ss1, ss2));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
BusLogger.log(E);
|
logger().log(E);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -449,7 +410,7 @@ namespace OpenWifi {
|
|||||||
try {
|
try {
|
||||||
DataDir.createDirectory();
|
DataDir.createDirectory();
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger_.log(E);
|
logger().log(E);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets", "");
|
WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets", "");
|
||||||
@@ -567,12 +528,14 @@ namespace OpenWifi {
|
|||||||
for (auto i : SubSystems_) {
|
for (auto i : SubSystems_) {
|
||||||
i->Start();
|
i->Start();
|
||||||
}
|
}
|
||||||
EventBusManager()->Start();
|
EventBusManager_ = std::make_unique<EventBusManager>(Poco::Logger::create(
|
||||||
|
"EventBusManager", Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel()));
|
||||||
|
EventBusManager_->Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MicroService::StopSubSystemServers() {
|
void MicroService::StopSubSystemServers() {
|
||||||
AddActivity("Stopping");
|
AddActivity("Stopping");
|
||||||
EventBusManager()->Stop();
|
EventBusManager_->Stop();
|
||||||
for (auto i = SubSystems_.rbegin(); i != SubSystems_.rend(); ++i) {
|
for (auto i = SubSystems_.rbegin(); i != SubSystems_.rend(); ++i) {
|
||||||
(*i)->Stop();
|
(*i)->Stop();
|
||||||
}
|
}
|
||||||
@@ -732,7 +695,7 @@ namespace OpenWifi {
|
|||||||
auto APIKEY = Request.get("X-API-KEY");
|
auto APIKEY = Request.get("X-API-KEY");
|
||||||
return APIKEY == MyHash_;
|
return APIKEY == MyHash_;
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
Logger_.log(E);
|
logger().log(E);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -201,6 +201,7 @@ namespace OpenWifi {
|
|||||||
Poco::JWT::Signer Signer_;
|
Poco::JWT::Signer Signer_;
|
||||||
Poco::Logger &Logger_;
|
Poco::Logger &Logger_;
|
||||||
Poco::ThreadPool TimerPool_{"timer:pool", 2, 32};
|
Poco::ThreadPool TimerPool_{"timer:pool", 2, 32};
|
||||||
|
std::unique_ptr<EventBusManager> EventBusManager_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline MicroService *MicroService::instance_ = nullptr;
|
inline MicroService *MicroService::instance_ = nullptr;
|
||||||
|
|||||||
@@ -5,8 +5,6 @@
|
|||||||
#include "framework/MicroServiceFuncs.h"
|
#include "framework/MicroServiceFuncs.h"
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
#include "framework/ALBserver.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
const std::string &MicroServiceDataDirectory() { return MicroService::instance().DataDir(); }
|
const std::string &MicroServiceDataDirectory() { return MicroService::instance().DataDir(); }
|
||||||
|
|
||||||
@@ -49,11 +47,11 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
void MicroServiceReload(const std::string &Type) { MicroService::instance().Reload(Type); }
|
void MicroServiceReload(const std::string &Type) { MicroService::instance().Reload(Type); }
|
||||||
|
|
||||||
Types::StringVec MicroServiceGetLogLevelNames() {
|
const Types::StringVec MicroServiceGetLogLevelNames() {
|
||||||
return MicroService::instance().GetLogLevelNames();
|
return MicroService::instance().GetLogLevelNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
Types::StringVec MicroServiceGetSubSystems() {
|
const Types::StringVec MicroServiceGetSubSystems() {
|
||||||
return MicroService::instance().GetSubSystems();
|
return MicroService::instance().GetSubSystems();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +79,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
std::string MicroServiceGetUIURI() { return MicroService::instance().GetUIURI(); }
|
std::string MicroServiceGetUIURI() { return MicroService::instance().GetUIURI(); }
|
||||||
|
|
||||||
SubSystemVec MicroServiceGetFullSubSystems() {
|
const SubSystemVec MicroServiceGetFullSubSystems() {
|
||||||
return MicroService::instance().GetFullSubSystems();
|
return MicroService::instance().GetFullSubSystems();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +87,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
std::uint64_t MicroServiceDaemonBusTimer() { return MicroService::instance().DaemonBusTimer(); }
|
std::uint64_t MicroServiceDaemonBusTimer() { return MicroService::instance().DaemonBusTimer(); }
|
||||||
|
|
||||||
std::string MicroServiceMakeSystemEventMessage(const char *Type) {
|
std::string MicroServiceMakeSystemEventMessage(const std::string &Type) {
|
||||||
return MicroService::instance().MakeSystemEventMessage(Type);
|
return MicroService::instance().MakeSystemEventMessage(Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,12 +123,4 @@ namespace OpenWifi {
|
|||||||
return MicroService::instance().AllowExternalMicroServices();
|
return MicroService::instance().AllowExternalMicroServices();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MicroServiceALBCallback( std::string Callback()) {
|
|
||||||
return ALBHealthCheckServer()->RegisterExtendedHealthMessage(Callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string MicroServiceAccessKey() {
|
|
||||||
return MicroService::instance().Hash();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ namespace OpenWifi {
|
|||||||
std::string MicroServicePublicEndPoint();
|
std::string MicroServicePublicEndPoint();
|
||||||
std::string MicroServiceConfigGetString(const std::string &Key,
|
std::string MicroServiceConfigGetString(const std::string &Key,
|
||||||
const std::string &DefaultValue);
|
const std::string &DefaultValue);
|
||||||
std::string MicroServiceAccessKey();
|
|
||||||
bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue);
|
bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue);
|
||||||
std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue);
|
std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue);
|
||||||
std::string MicroServicePrivateEndPoint();
|
std::string MicroServicePrivateEndPoint();
|
||||||
@@ -32,8 +31,8 @@ namespace OpenWifi {
|
|||||||
void MicroServiceLoadConfigurationFile();
|
void MicroServiceLoadConfigurationFile();
|
||||||
void MicroServiceReload();
|
void MicroServiceReload();
|
||||||
void MicroServiceReload(const std::string &Type);
|
void MicroServiceReload(const std::string &Type);
|
||||||
Types::StringVec MicroServiceGetLogLevelNames();
|
const Types::StringVec MicroServiceGetLogLevelNames();
|
||||||
Types::StringVec MicroServiceGetSubSystems();
|
const Types::StringVec MicroServiceGetSubSystems();
|
||||||
Types::StringPairVec MicroServiceGetLogLevels();
|
Types::StringPairVec MicroServiceGetLogLevels();
|
||||||
bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level);
|
bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level);
|
||||||
void MicroServiceGetExtraConfiguration(Poco::JSON::Object &Answer);
|
void MicroServiceGetExtraConfiguration(Poco::JSON::Object &Answer);
|
||||||
@@ -41,10 +40,10 @@ namespace OpenWifi {
|
|||||||
std::uint64_t MicroServiceUptimeTotalSeconds();
|
std::uint64_t MicroServiceUptimeTotalSeconds();
|
||||||
std::uint64_t MicroServiceStartTimeEpochTime();
|
std::uint64_t MicroServiceStartTimeEpochTime();
|
||||||
std::string MicroServiceGetUIURI();
|
std::string MicroServiceGetUIURI();
|
||||||
SubSystemVec MicroServiceGetFullSubSystems();
|
const SubSystemVec MicroServiceGetFullSubSystems();
|
||||||
std::string MicroServiceCreateUUID();
|
std::string MicroServiceCreateUUID();
|
||||||
std::uint64_t MicroServiceDaemonBusTimer();
|
std::uint64_t MicroServiceDaemonBusTimer();
|
||||||
std::string MicroServiceMakeSystemEventMessage(const char *Type);
|
std::string MicroServiceMakeSystemEventMessage(const std::string &Type);
|
||||||
Poco::ThreadPool &MicroServiceTimerPool();
|
Poco::ThreadPool &MicroServiceTimerPool();
|
||||||
std::string MicroServiceConfigPath(const std::string &Key, const std::string &DefaultValue);
|
std::string MicroServiceConfigPath(const std::string &Key, const std::string &DefaultValue);
|
||||||
std::string MicroServiceWWWAssetsDir();
|
std::string MicroServiceWWWAssetsDir();
|
||||||
@@ -54,5 +53,4 @@ namespace OpenWifi {
|
|||||||
std::string MicroServiceGetPublicAPIEndPoint();
|
std::string MicroServiceGetPublicAPIEndPoint();
|
||||||
void MicroServiceDeleteOverrideConfiguration();
|
void MicroServiceDeleteOverrideConfiguration();
|
||||||
bool AllowExternalMicroServices();
|
bool AllowExternalMicroServices();
|
||||||
void MicroServiceALBCallback( std::string Callback());
|
|
||||||
} // namespace OpenWifi
|
} // namespace OpenWifi
|
||||||
|
|||||||
@@ -28,9 +28,6 @@ namespace OpenWifi::Types {
|
|||||||
typedef std::string UUID_t;
|
typedef std::string UUID_t;
|
||||||
typedef std::vector<UUID_t> UUIDvec_t;
|
typedef std::vector<UUID_t> UUIDvec_t;
|
||||||
typedef std::map<std::string, std::map<uint32_t, uint64_t>> Counted3DMapSII;
|
typedef std::map<std::string, std::map<uint32_t, uint64_t>> Counted3DMapSII;
|
||||||
typedef std::vector<int64_t> IntList;
|
|
||||||
typedef std::vector<uint64_t> UIntList;
|
|
||||||
typedef std::vector<double> DoubleList;
|
|
||||||
|
|
||||||
struct MicroServiceMeta {
|
struct MicroServiceMeta {
|
||||||
uint64_t Id = 0;
|
uint64_t Id = 0;
|
||||||
|
|||||||
@@ -574,36 +574,6 @@ namespace OpenWifi {
|
|||||||
Poco::JSON::Stringifier::stringify(Object, Answer);
|
Poco::JSON::Stringifier::stringify(Object, Answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void ReturnObject(const std::vector<std::string> &Strings) {
|
|
||||||
Poco::JSON::Array Arr;
|
|
||||||
for(const auto &String:Strings) {
|
|
||||||
Arr.add(String);
|
|
||||||
}
|
|
||||||
std::ostringstream os;
|
|
||||||
Arr.stringify(os);
|
|
||||||
return ReturnRawJSON(os.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T> void ReturnObject(const std::vector<T> &Objects) {
|
|
||||||
Poco::JSON::Array Arr;
|
|
||||||
for(const auto &Object:Objects) {
|
|
||||||
Poco::JSON::Object O;
|
|
||||||
Object.to_json(O);
|
|
||||||
Arr.add(O);
|
|
||||||
}
|
|
||||||
std::ostringstream os;
|
|
||||||
Arr.stringify(os);
|
|
||||||
return ReturnRawJSON(os.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T> void ReturnObject(const T &Object) {
|
|
||||||
Poco::JSON::Object O;
|
|
||||||
Object.to_json(O);
|
|
||||||
std::ostringstream os;
|
|
||||||
O.stringify(os);
|
|
||||||
return ReturnRawJSON(os.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void ReturnRawJSON(const std::string &json_doc) {
|
inline void ReturnRawJSON(const std::string &json_doc) {
|
||||||
PrepareResponse();
|
PrepareResponse();
|
||||||
if (Request != nullptr) {
|
if (Request != nullptr) {
|
||||||
|
|||||||
@@ -24,10 +24,9 @@ namespace OpenWifi {
|
|||||||
Server, TransactionId, Internal) {}
|
Server, TransactionId, Internal) {}
|
||||||
static auto PathName() { return std::list<std::string>{"/api/v1/system"}; }
|
static auto PathName() { return std::list<std::string>{"/api/v1/system"}; }
|
||||||
|
|
||||||
inline void DoGet() final {
|
inline void DoGet() {
|
||||||
std::string Arg;
|
std::string Arg;
|
||||||
if (HasParameter("command", Arg)) {
|
if (HasParameter("command", Arg) && Arg == "info") {
|
||||||
if (Arg == "info") {
|
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
Answer.set(RESTAPI::Protocol::VERSION, MicroServiceVersion());
|
Answer.set(RESTAPI::Protocol::VERSION, MicroServiceVersion());
|
||||||
Answer.set(RESTAPI::Protocol::UPTIME, MicroServiceUptimeTotalSeconds());
|
Answer.set(RESTAPI::Protocol::UPTIME, MicroServiceUptimeTotalSeconds());
|
||||||
@@ -65,23 +64,11 @@ namespace OpenWifi {
|
|||||||
Answer.set("certificates", Certificates);
|
Answer.set("certificates", Certificates);
|
||||||
return ReturnObject(Answer);
|
return ReturnObject(Answer);
|
||||||
}
|
}
|
||||||
if (Arg == "extraConfiguration") {
|
if (GetBoolParameter("extraConfiguration")) {
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
MicroServiceGetExtraConfiguration(Answer);
|
MicroServiceGetExtraConfiguration(Answer);
|
||||||
return ReturnObject(Answer);
|
return ReturnObject(Answer);
|
||||||
}
|
}
|
||||||
if (Arg == "resources") {
|
|
||||||
Poco::JSON::Object Answer;
|
|
||||||
Answer.set("numberOfFileDescriptors", Utils::get_open_fds());
|
|
||||||
std::uint64_t currRealMem, peakRealMem, currVirtMem, peakVirtMem;
|
|
||||||
Utils::getMemory(currRealMem, peakRealMem, currVirtMem, peakVirtMem);
|
|
||||||
Answer.set("currRealMem", currRealMem);
|
|
||||||
Answer.set("peakRealMem", peakRealMem);
|
|
||||||
Answer.set("currVirtMem", currVirtMem);
|
|
||||||
Answer.set("peakVirtMem", peakVirtMem);
|
|
||||||
return ReturnObject(Answer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BadRequest(RESTAPI::Errors::InvalidCommand);
|
BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,15 +14,8 @@
|
|||||||
#include "framework/OpenWifiTypes.h"
|
#include "framework/OpenWifiTypes.h"
|
||||||
#include "framework/utils.h"
|
#include "framework/utils.h"
|
||||||
|
|
||||||
#include <RESTObjects/RESTAPI_SecurityObjects.h>
|
|
||||||
|
|
||||||
namespace OpenWifi::RESTAPI_utils {
|
namespace OpenWifi::RESTAPI_utils {
|
||||||
|
|
||||||
inline bool IsRootOrAdmin(const SecurityObjects::UserInfo &UI) {
|
|
||||||
return UI.userRole==SecurityObjects::ROOT ||
|
|
||||||
UI.userRole==SecurityObjects::ADMIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void EmbedDocument(const std::string &ObjName, Poco::JSON::Object &Obj,
|
inline void EmbedDocument(const std::string &ObjName, Poco::JSON::Object &Obj,
|
||||||
const std::string &ObjStr) {
|
const std::string &ObjStr) {
|
||||||
std::string D = ObjStr.empty() ? "{}" : ObjStr;
|
std::string D = ObjStr.empty() ? "{}" : ObjStr;
|
||||||
@@ -102,20 +95,6 @@ namespace OpenWifi::RESTAPI_utils {
|
|||||||
Obj.set(Field, A);
|
Obj.set(Field, A);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::DoubleList &V) {
|
|
||||||
Poco::JSON::Array A;
|
|
||||||
for (const auto &i : V)
|
|
||||||
A.add(i);
|
|
||||||
Obj.set(Field, A);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::IntList &V) {
|
|
||||||
Poco::JSON::Array A;
|
|
||||||
for (const auto &i : V)
|
|
||||||
A.add(i);
|
|
||||||
Obj.set(Field, A);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::TagList &V) {
|
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::TagList &V) {
|
||||||
Poco::JSON::Array A;
|
Poco::JSON::Array A;
|
||||||
for (const auto &i : V)
|
for (const auto &i : V)
|
||||||
@@ -298,28 +277,6 @@ namespace OpenWifi::RESTAPI_utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
|
|
||||||
Types::DoubleList &Value) {
|
|
||||||
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
|
|
||||||
Value.clear();
|
|
||||||
Poco::JSON::Array::Ptr A = Obj->getArray(Field);
|
|
||||||
for (const auto &i : *A) {
|
|
||||||
Value.push_back(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
|
|
||||||
Types::IntList &Value) {
|
|
||||||
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
|
|
||||||
Value.clear();
|
|
||||||
Poco::JSON::Array::Ptr A = Obj->getArray(Field);
|
|
||||||
for (const auto &i : *A) {
|
|
||||||
Value.push_back(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
|
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
|
||||||
std::vector<T> &Value) {
|
std::vector<T> &Value) {
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
class StorageClass : public SubSystemServer {
|
class StorageClass : public SubSystemServer {
|
||||||
public:
|
public:
|
||||||
|
StorageClass() noexcept : SubSystemServer("StorageClass", "STORAGE-SVR", "storage") {}
|
||||||
|
|
||||||
inline int Start() override {
|
int Start() override {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
|
||||||
Logger().notice("Starting.");
|
Logger().notice("Starting.");
|
||||||
@@ -39,24 +40,17 @@ namespace OpenWifi {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Stop() override { Pool_->shutdown(); }
|
void Stop() override { Pool_->shutdown(); }
|
||||||
|
|
||||||
DBType Type() const { return dbType_; };
|
DBType Type() const { return dbType_; };
|
||||||
|
|
||||||
StorageClass() noexcept : SubSystemServer("StorageClass", "STORAGE-SVR", "storage") {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Poco::Data::SessionPool &Pool() { return *Pool_; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline int Setup_SQLite();
|
inline int Setup_SQLite();
|
||||||
inline int Setup_MySQL();
|
inline int Setup_MySQL();
|
||||||
inline int Setup_PostgreSQL();
|
inline int Setup_PostgreSQL();
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<Poco::Data::SessionPool> Pool_;
|
std::unique_ptr<Poco::Data::SessionPool> Pool_;
|
||||||
Poco::Data::SQLite::Connector SQLiteConn_;
|
Poco::Data::SQLite::Connector SQLiteConn_;
|
||||||
Poco::Data::PostgreSQL::Connector PostgresConn_;
|
Poco::Data::PostgreSQL::Connector PostgresConn_;
|
||||||
Poco::Data::MySQL::Connector MySQLConn_;
|
Poco::Data::MySQL::Connector MySQLConn_;
|
||||||
@@ -87,7 +81,7 @@ namespace OpenWifi {
|
|||||||
// Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 8,
|
// Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 8,
|
||||||
// (int)NumSessions,
|
// (int)NumSessions,
|
||||||
// (int)IdleTime));
|
// (int)IdleTime));
|
||||||
Pool_ = std::make_shared<Poco::Data::SessionPool>(SQLiteConn_.name(), DBName, 8,
|
Pool_ = std::make_unique<Poco::Data::SessionPool>(SQLiteConn_.name(), DBName, 8,
|
||||||
(int)NumSessions, (int)IdleTime);
|
(int)NumSessions, (int)IdleTime);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -108,7 +102,7 @@ namespace OpenWifi {
|
|||||||
";compress=true;auto-reconnect=true";
|
";compress=true;auto-reconnect=true";
|
||||||
|
|
||||||
Poco::Data::MySQL::Connector::registerConnector();
|
Poco::Data::MySQL::Connector::registerConnector();
|
||||||
Pool_ = std::make_shared<Poco::Data::SessionPool>(MySQLConn_.name(), ConnectionStr, 8,
|
Pool_ = std::make_unique<Poco::Data::SessionPool>(MySQLConn_.name(), ConnectionStr, 8,
|
||||||
NumSessions, IdleTime);
|
NumSessions, IdleTime);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -132,7 +126,7 @@ namespace OpenWifi {
|
|||||||
" connect_timeout=" + ConnectionTimeout;
|
" connect_timeout=" + ConnectionTimeout;
|
||||||
|
|
||||||
Poco::Data::PostgreSQL::Connector::registerConnector();
|
Poco::Data::PostgreSQL::Connector::registerConnector();
|
||||||
Pool_ = std::make_shared<Poco::Data::SessionPool>(PostgresConn_.name(), ConnectionStr, 8,
|
Pool_ = std::make_unique<Poco::Data::SessionPool>(PostgresConn_.name(), ConnectionStr, 8,
|
||||||
NumSessions, IdleTime);
|
NumSessions, IdleTime);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ namespace OpenWifi {
|
|||||||
P.cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
|
P.cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
|
||||||
P.dhUse2048Bits = true;
|
P.dhUse2048Bits = true;
|
||||||
P.caLocation = cas_;
|
P.caLocation = cas_;
|
||||||
// P.securityLevel =
|
|
||||||
|
|
||||||
auto Context = Poco::AutoPtr<Poco::Net::Context>(
|
auto Context = Poco::AutoPtr<Poco::Net::Context>(
|
||||||
new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
|
new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
|
||||||
@@ -54,6 +53,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
Context->useCertificate(Cert);
|
Context->useCertificate(Cert);
|
||||||
Context->addChainCertificate(Root);
|
Context->addChainCertificate(Root);
|
||||||
|
|
||||||
Context->addCertificateAuthority(Root);
|
Context->addCertificateAuthority(Root);
|
||||||
|
|
||||||
if (level_ == Poco::Net::Context::VERIFY_STRICT) {
|
if (level_ == Poco::Net::Context::VERIFY_STRICT) {
|
||||||
@@ -76,18 +76,18 @@ namespace OpenWifi {
|
|||||||
L.fatal(fmt::format("Wrong Certificate({}) for Key({})", cert_file_, key_file_));
|
L.fatal(fmt::format("Wrong Certificate({}) for Key({})", cert_file_, key_file_));
|
||||||
}
|
}
|
||||||
|
|
||||||
SSL_CTX_set_verify(SSLCtx, level_==Poco::Net::Context::VERIFY_NONE ? SSL_VERIFY_NONE : SSL_VERIFY_PEER, nullptr);
|
SSL_CTX_set_verify(SSLCtx, SSL_VERIFY_PEER, nullptr);
|
||||||
|
|
||||||
if (level_ == Poco::Net::Context::VERIFY_STRICT) {
|
if (level_ == Poco::Net::Context::VERIFY_STRICT) {
|
||||||
SSL_CTX_set_client_CA_list(SSLCtx, SSL_load_client_CA_file(client_cas_.c_str()));
|
SSL_CTX_set_client_CA_list(SSLCtx, SSL_load_client_CA_file(client_cas_.c_str()));
|
||||||
SSL_CTX_enable_ct(SSLCtx, SSL_CT_VALIDATION_STRICT);
|
|
||||||
}
|
}
|
||||||
|
SSL_CTX_enable_ct(SSLCtx, SSL_CT_VALIDATION_STRICT);
|
||||||
SSL_CTX_dane_enable(SSLCtx);
|
SSL_CTX_dane_enable(SSLCtx);
|
||||||
|
|
||||||
Context->enableSessionCache();
|
Context->enableSessionCache();
|
||||||
Context->setSessionCacheSize(0);
|
Context->setSessionCacheSize(0);
|
||||||
Context->setSessionTimeout(60);
|
Context->setSessionTimeout(60);
|
||||||
Context->enableExtendedCertificateVerification( level_!= Poco::Net::Context::VERIFY_NONE );
|
Context->enableExtendedCertificateVerification(true);
|
||||||
Context->disableStatelessSessionResumption();
|
Context->disableStatelessSessionResumption();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user