mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2025-11-01 19:28:01 +00:00
Compare commits
149 Commits
v2.0.0-RC1
...
release/v2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9dde85495e | ||
|
|
6faec0718b | ||
|
|
e4e2075021 | ||
|
|
314ae21d6a | ||
|
|
935cc78bb4 | ||
|
|
417d94476b | ||
|
|
6318cd0c33 | ||
|
|
7892489e96 | ||
|
|
24785e2f63 | ||
|
|
52736f4a4c | ||
|
|
e7334122b5 | ||
|
|
33168f35d5 | ||
|
|
cf69a47195 | ||
|
|
df71d60c2c | ||
|
|
9eef500eb9 | ||
|
|
8172b9c55e | ||
|
|
a35d3d73c2 | ||
|
|
5ae99dd04b | ||
|
|
5f118b51d4 | ||
|
|
b7a762ad44 | ||
|
|
a236bd7e4a | ||
|
|
25af9bee46 | ||
|
|
897f5076b2 | ||
|
|
dd7a7bbc74 | ||
|
|
ef4af5b379 | ||
|
|
cfb562bb7a | ||
|
|
0675192f2c | ||
|
|
27f0c5fe75 | ||
|
|
5153f16d00 | ||
|
|
deff8e5253 | ||
|
|
152ba10a13 | ||
|
|
36cb68fef7 | ||
|
|
7874cf3bd0 | ||
|
|
6ea7e93cb0 | ||
|
|
3520fb5ed4 | ||
|
|
c2266581b9 | ||
|
|
389de28cfb | ||
|
|
595dc5d42b | ||
|
|
c1d75c09be | ||
|
|
c0941512ae | ||
|
|
1f83f954dd | ||
|
|
3f7385d248 | ||
|
|
25d13d3cb2 | ||
|
|
5120b2cb64 | ||
|
|
bca4f6cfcd | ||
|
|
0b2ca909ed | ||
|
|
3a5a5ae7bc | ||
|
|
1d102cf1e9 | ||
|
|
4644d231c4 | ||
|
|
c50ed2f252 | ||
|
|
7bba3da732 | ||
|
|
6f9abd32e7 | ||
|
|
1c3e98619a | ||
|
|
20fe93fcdc | ||
|
|
57a9114ac5 | ||
|
|
4b2eecf8b0 | ||
|
|
ed88cbfce6 | ||
|
|
f7e70f5839 | ||
|
|
d76ef5e1d0 | ||
|
|
a4cf28c858 | ||
|
|
4f5e21d658 | ||
|
|
bd5f7cd373 | ||
|
|
d74795fd96 | ||
|
|
3fe17e58de | ||
|
|
adba0fbe22 | ||
|
|
64a99e5079 | ||
|
|
34def33f69 | ||
|
|
de34051cd4 | ||
|
|
346d845ee9 | ||
|
|
83ada431de | ||
|
|
2563d7e9b3 | ||
|
|
1f0f3e8f38 | ||
|
|
f13ecd0d1c | ||
|
|
54f35de99f | ||
|
|
f7b6c6f90f | ||
|
|
f003149b8d | ||
|
|
4f9e7c9677 | ||
|
|
14d7aad56c | ||
|
|
aa4d2ae764 | ||
|
|
4e60b248ca | ||
|
|
685f9024d7 | ||
|
|
104d429b69 | ||
|
|
8cf5672a73 | ||
|
|
186f7624a6 | ||
|
|
8986cde273 | ||
|
|
0abc3de4cd | ||
|
|
d219fab455 | ||
|
|
3b3e79ac14 | ||
|
|
2ff32a69e6 | ||
|
|
2b66f15bda | ||
|
|
508ff00663 | ||
|
|
d0fc391cde | ||
|
|
77a031eaa3 | ||
|
|
a6f6421992 | ||
|
|
fdf497397e | ||
|
|
ab605655e1 | ||
|
|
422574ed65 | ||
|
|
34f9b6f761 | ||
|
|
27e8178444 | ||
|
|
ba6796cd16 | ||
|
|
816d5da3ba | ||
|
|
c9c3c16e0b | ||
|
|
35dc055c40 | ||
|
|
6760ca1da1 | ||
|
|
36e6ee3ac4 | ||
|
|
362d97de1f | ||
|
|
530a2bb772 | ||
|
|
b333af3465 | ||
|
|
1b405987bf | ||
|
|
6dd52f86b9 | ||
|
|
76081e82af | ||
|
|
ebe2d16a87 | ||
|
|
60e4ced29a | ||
|
|
5683054349 | ||
|
|
210a96c143 | ||
|
|
92e108aa6b | ||
|
|
691b82589d | ||
|
|
4b471af065 | ||
|
|
3c556da991 | ||
|
|
9ddd371c86 | ||
|
|
5391468ea2 | ||
|
|
8daffc2ccf | ||
|
|
f58c204f51 | ||
|
|
5e857d6019 | ||
|
|
a7fe50f956 | ||
|
|
40239079a4 | ||
|
|
27c4602fca | ||
|
|
c107c6da93 | ||
|
|
f67995b4a9 | ||
|
|
851fdb1f1d | ||
|
|
8f52dc57ba | ||
|
|
427ee37b16 | ||
|
|
fc153f7fc9 | ||
|
|
5c9f571565 | ||
|
|
ab3905f6d8 | ||
|
|
9cee7d4588 | ||
|
|
dd95731b22 | ||
|
|
101384d595 | ||
|
|
77297d5a3e | ||
|
|
8b3c3a50ed | ||
|
|
4b5128e41d | ||
|
|
b11d713e5b | ||
|
|
143c4078d4 | ||
|
|
b6babaa2f8 | ||
|
|
57f0425bc0 | ||
|
|
c28159ebe7 | ||
|
|
2a0be33c23 | ||
|
|
f1c77c0a63 | ||
|
|
64fd80f489 |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -25,3 +25,6 @@ _deps
|
||||
test_scripts/curl/token.json
|
||||
.vscode/c_cpp_properties.json
|
||||
test_scripts/curl/result.json
|
||||
*.swp
|
||||
helm/charts/*
|
||||
!helm/charts/.gitkeep
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(ucentralgw VERSION 2.0.0)
|
||||
project(ucentralgw VERSION 2.1.0)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
@@ -73,21 +73,29 @@ add_executable( ucentralgw
|
||||
src/RESTAPI_command.cpp src/RESTAPI_command.h
|
||||
src/FileUploader.cpp src/FileUploader.h
|
||||
src/RESTAPI_file.cpp src/RESTAPI_file.h
|
||||
src/CommandChannel.cpp src/CommandChannel.h
|
||||
src/RESTAPI_system_command.cpp src/RESTAPI_system_command.h
|
||||
src/RESTAPI_BlackList.cpp src/RESTAPI_BlackList.h
|
||||
src/Utils.h src/Utils.cpp src/storage_blacklist.cpp
|
||||
src/storage_command.cpp src/storage_healthcheck.cpp src/storage_statistics.cpp src/storage_logs.cpp
|
||||
src/storage_device.cpp src/storage_capabilities.cpp src/storage_defconfig.cpp src/storage_sqlite.cpp
|
||||
src/storage_mysql.cpp src/storage_pgql.cpp src/storage_tables.cpp
|
||||
src/storage_device.cpp src/storage_capabilities.cpp src/storage_defconfig.cpp
|
||||
src/storage_tables.cpp
|
||||
src/storage_setup.cpp
|
||||
src/StateProcessor.cpp src/StateProcessor.h
|
||||
src/storage_lifetime_stats.cpp src/uCentralProtocol.h src/RESTAPI_protocol.h
|
||||
src/ALBHealthCheckServer.h src/Kafka_topics.h src/uCentralTypes.h
|
||||
src/ALBHealthCheckServer.h src/Kafka_topics.h
|
||||
src/OUIServer.cpp src/OUIServer.h
|
||||
src/RESTAPI_ouis.cpp src/RESTAPI_ouis.h
|
||||
src/MicroService.cpp src/MicroService.h
|
||||
src/RESTAPI_RPC.cpp src/RESTAPI_RPC.h src/AuthClient.cpp src/AuthClient.h src/OpenAPIRequest.cpp src/OpenAPIRequest.h
|
||||
src/RESTAPI_utils.h src/RESTAPI_utils.cpp src/StorageArchiver.cpp src/StorageArchiver.h src/Dashboard.cpp src/Dashboard.h src/RESTAPI_deviceDashboardHandler.cpp src/RESTAPI_deviceDashboardHandler.h)
|
||||
src/RESTAPI_RPC.cpp src/RESTAPI_RPC.h
|
||||
src/AuthClient.cpp src/AuthClient.h
|
||||
src/OpenAPIRequest.cpp src/OpenAPIRequest.h
|
||||
src/RESTAPI_utils.h src/RESTAPI_utils.cpp
|
||||
src/StorageArchiver.cpp src/StorageArchiver.h
|
||||
src/Dashboard.cpp src/Dashboard.h
|
||||
src/RESTAPI_deviceDashboardHandler.cpp src/RESTAPI_deviceDashboardHandler.h
|
||||
src/SerialNumberCache.cpp src/SerialNumberCache.h
|
||||
src/RESTAPI_webSocketServer.cpp src/RESTAPI_webSocketServer.h
|
||||
src/OpenWifiTypes.h)
|
||||
|
||||
if(NOT SMALL_BUILD)
|
||||
target_sources(ucentralgw PUBLIC src/KafkaManager.cpp src/KafkaManager.h)
|
||||
|
||||
@@ -46,12 +46,15 @@ RUN addgroup -S "$UCENTRALGW_USER" && \
|
||||
adduser -S -G "$UCENTRALGW_USER" "$UCENTRALGW_USER"
|
||||
|
||||
RUN mkdir /ucentral
|
||||
RUN mkdir -p "$UCENTRALGW_ROOT" "$UCENTRALGW_CONFIG"
|
||||
RUN apk add --update --no-cache librdkafka mariadb-connector-c libpq unixodbc su-exec
|
||||
RUN mkdir -p "$UCENTRALGW_ROOT" "$UCENTRALGW_CONFIG" && \
|
||||
chown "$UCENTRALGW_USER": "$UCENTRALGW_ROOT" "$UCENTRALGW_CONFIG"
|
||||
RUN apk add --update --no-cache librdkafka mariadb-connector-c libpq unixodbc su-exec gettext
|
||||
|
||||
COPY --from=builder /ucentralgw/cmake-build/ucentralgw /ucentral/ucentralgw
|
||||
COPY --from=builder /cppkafka/cmake-build/src/lib/* /lib/
|
||||
COPY --from=builder /poco/cmake-build/lib/* /lib/
|
||||
|
||||
COPY ucentralgw.properties.tmpl ${UCENTRALGW_CONFIG}/
|
||||
COPY docker-entrypoint.sh /
|
||||
|
||||
EXPOSE 15002 16002 16003 17002 16102
|
||||
|
||||
50
README.md
50
README.md
@@ -26,9 +26,9 @@ Poco may take several minutes depending on the platform you are building on.
|
||||
### Ubuntu
|
||||
These instructions have proven to work on Ubuntu 20.4.
|
||||
```
|
||||
sudo apt install git cmake g++ libssl-dev libmariabd-dev unixodbc-dev
|
||||
sudo apt install git cmake g++ libssl-dev libmariadb-dev unixodbc-dev
|
||||
sudo apt install libpq-dev libaprutil1-dev apache2-dev libboost-all-dev
|
||||
sudo apt install librdkafka-dev liblua5.3-dev
|
||||
sudo apt install librdkafka-dev liblua5.3-dev libmysqlclient-dev
|
||||
|
||||
git clone https://github.com/stephb9959/poco
|
||||
cd poco
|
||||
@@ -153,8 +153,8 @@ cmake -DSMALL_BUILD=1 ..
|
||||
make
|
||||
```
|
||||
|
||||
### After the build step is completed
|
||||
Once your build is done. You can remove the Poco source as it is no longer needed.
|
||||
### After completing the build
|
||||
After completing the build, you can remove the Poco source as it is no longer needed.
|
||||
|
||||
#### Expected directory layout
|
||||
From the directory where your cloned source is, you will need to create the `certs`, `logs`, and `uploads` directories.
|
||||
@@ -220,13 +220,13 @@ in your browner
|
||||
#### Configuration
|
||||
The configuration for this service is kept in a properties file. This file is called `ucentralgw.properties` and you can
|
||||
see the latest version [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/ucentralgw.properties). The file will be loaded from
|
||||
the directory set by the environment variable `UCENTRAL_CONFIG`. To use environment variables in the configuration,
|
||||
the directory set by the environment variable `UCENTRALGW_CONFIG`. To use environment variables in the configuration,
|
||||
you must use `$<varname>`. Only `path names` support the use of environment variables. The sample configuration requires very
|
||||
little changes if you keep the suggested directory structure. For the sample configuration to work, you need to define 2
|
||||
environment variables.
|
||||
```
|
||||
export UCENTRAL_ROOT=`pwd`
|
||||
export UCENTRAL_CONFIG=`pwd`
|
||||
export UCENTRALGW_ROOT=`pwd`
|
||||
export UCENTRALGW_CONFIG=`pwd`
|
||||
```
|
||||
If you current working directory is the root of the project, this will set the variables properly. Otherwise, you can set the variables
|
||||
to point to wherever is necessary.
|
||||
@@ -234,7 +234,7 @@ to point to wherever is necessary.
|
||||
##### Important config entries
|
||||
###### This is the logging directory
|
||||
```
|
||||
logging.channels.c2.path = $UCENTRAL_ROOT/logs/sample.log
|
||||
logging.channels.c2.path = $UCENTRALGW_ROOT/logs/sample.log
|
||||
```
|
||||
|
||||
###### This is the type of storage in use
|
||||
@@ -255,11 +255,11 @@ ucentral.devicetypes.2 = IOT:esp32
|
||||
```asm
|
||||
ucentral.restapi.host.0.backlog = 100
|
||||
ucentral.restapi.host.0.security = relaxed
|
||||
ucentral.restapi.host.0.rootca = $UCENTRAL_ROOT/certs/restapi-ca.pem
|
||||
ucentral.restapi.host.0.rootca = $UCENTRALGW_ROOT/certs/restapi-ca.pem
|
||||
ucentral.restapi.host.0.address = *
|
||||
ucentral.restapi.host.0.port = 16002
|
||||
ucentral.restapi.host.0.cert = $UCENTRAL_ROOT/certs/restapi-cert.pem
|
||||
ucentral.restapi.host.0.key = $UCENTRAL_ROOT/certs/restapi-key.pem
|
||||
ucentral.restapi.host.0.cert = $UCENTRALGW_ROOT/certs/restapi-cert.pem
|
||||
ucentral.restapi.host.0.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
|
||||
ucentral.restapi.host.0.key.password = mypassword
|
||||
```
|
||||
|
||||
@@ -309,12 +309,12 @@ You will need to get the `cert.pem` and `key.pem` from Digicert. The rest is her
|
||||
|
||||
```asm
|
||||
ucentral.websocket.host.0.backlog = 500
|
||||
ucentral.websocket.host.0.rootca = $UCENTRAL_ROOT/certs/root.pem
|
||||
ucentral.websocket.host.0.issuer = $UCENTRAL_ROOT/certs/issuer.pem
|
||||
ucentral.websocket.host.0.cert = $UCENTRAL_ROOT/certs/websocket-cert.pem
|
||||
ucentral.websocket.host.0.key = $UCENTRAL_ROOT/certs/websocket-key.pem
|
||||
ucentral.websocket.host.0.clientcas = $UCENTRAL_ROOT/certs/clientcas.pem
|
||||
ucentral.websocket.host.0.cas = $UCENTRAL_ROOT/certs/cas
|
||||
ucentral.websocket.host.0.rootca = $UCENTRALGW_ROOT/certs/root.pem
|
||||
ucentral.websocket.host.0.issuer = $UCENTRALGW_ROOT/certs/issuer.pem
|
||||
ucentral.websocket.host.0.cert = $UCENTRALGW_ROOT/certs/websocket-cert.pem
|
||||
ucentral.websocket.host.0.key = $UCENTRALGW_ROOT/certs/websocket-key.pem
|
||||
ucentral.websocket.host.0.clientcas = $UCENTRALGW_ROOT/certs/clientcas.pem
|
||||
ucentral.websocket.host.0.cas = $UCENTRALGW_ROOT/certs/cas
|
||||
ucentral.websocket.host.0.address = *
|
||||
ucentral.websocket.host.0.port = 15002
|
||||
ucentral.websocket.host.0.security = strict
|
||||
@@ -325,15 +325,15 @@ ucentral.websocket.maxreactors = 20
|
||||
###### This is the end point for the devices when uploading files
|
||||
```asm
|
||||
ucentral.fileuploader.host.0.backlog = 100
|
||||
ucentral.fileuploader.host.0.rootca = $UCENTRAL_ROOT/certs/restapi-ca.pem
|
||||
ucentral.fileuploader.host.0.rootca = $UCENTRALGW_ROOT/certs/restapi-ca.pem
|
||||
ucentral.fileuploader.host.0.security = relaxed
|
||||
ucentral.fileuploader.host.0.address = *
|
||||
ucentral.fileuploader.host.0.name = 192.168.1.176
|
||||
ucentral.fileuploader.host.0.port = 16003
|
||||
ucentral.fileuploader.host.0.cert = $UCENTRAL_ROOT/certs/restapi-cert.pem
|
||||
ucentral.fileuploader.host.0.key = $UCENTRAL_ROOT/certs/restapi-key.pem
|
||||
ucentral.fileuploader.host.0.cert = $UCENTRALGW_ROOT/certs/restapi-cert.pem
|
||||
ucentral.fileuploader.host.0.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
|
||||
ucentral.fileuploader.host.0.key.password = mypassword
|
||||
ucentral.fileuploader.path = $UCENTRAL_ROOT/uploads
|
||||
ucentral.fileuploader.path = $UCENTRALGW_ROOT/uploads
|
||||
ucentral.fileuploader.maxsize = 10000
|
||||
```
|
||||
|
||||
@@ -369,7 +369,7 @@ can be any of the keys you are already using. You must keep that keep secret and
|
||||
this is the entry
|
||||
|
||||
```asm
|
||||
ucentral.service.key = $UCENTRAL_ROOT/certs/websocket-key.pem
|
||||
ucentral.service.key = $UCENTRALGW_ROOT/certs/websocket-key.pem
|
||||
```
|
||||
|
||||
#### Command line options
|
||||
@@ -391,7 +391,7 @@ A uCentral gateway implementation for TIP.
|
||||
```
|
||||
|
||||
##### file
|
||||
This allows you to point to another file without specifying the UCENTRAL_CONFIG variable. The file name must end in `.properties`.
|
||||
This allows you to point to another file without specifying the UCENTRALGW_CONFIG variable. The file name must end in `.properties`.
|
||||
##### daemon
|
||||
Run this as a UNIX service
|
||||
##### pidfile
|
||||
@@ -452,7 +452,7 @@ docker run -d -p 15002:15002 \
|
||||
--init \
|
||||
--volume="$PWD:/ucentral-data" \
|
||||
-e UCENTRAL_ROOT="/ucentral-data" \
|
||||
-e UCENTRAL_CONFIG="/ucentral-data" \
|
||||
-e UCENTRALGW_CONFIG="/ucentral-data" \
|
||||
--name="ucentralgw" $DOCKER_NAME
|
||||
|
||||
```
|
||||
@@ -493,7 +493,7 @@ Please refer to the `certs` directory from the sections above.
|
||||
The configuration for this service is kept in a properties file. Currently, this configuration file must be kept in the
|
||||
current directory of uCentral or one level up. This file is called `ucentralgw.properties` and you can see the latest version
|
||||
[here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/ucentralgw.properties). The file will be loaded from
|
||||
the directory set by the environment variable `UCENTRAL_CONFIG`. To use environment variables in the configuration,
|
||||
the directory set by the environment variable `UCENTRALGW_CONFIG`. To use environment variables in the configuration,
|
||||
you must use `$<varname>`. The path for the logs for the service must exist prior to starting the
|
||||
service. The path is defined under `logging.channels.c2.path`. Only `path names` support the use of
|
||||
environment variables. Here is a sample configuration:
|
||||
|
||||
@@ -1,6 +1,60 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$UCENTRALGW_CONFIG"/ucentralgw.properties ]]; then
|
||||
WEBSOCKET_HOST_ROOTCA=${WEBSOCKET_HOST_ROOTCA:-"\$UCENTRALGW_ROOT/certs/root.pem"} \
|
||||
WEBSOCKET_HOST_ISSUER=${WEBSOCKET_HOST_ISSUER:-"\$UCENTRALGW_ROOT/certs/issuer.pem"} \
|
||||
WEBSOCKET_HOST_CERT=${WEBSOCKET_HOST_CERT:-"\$UCENTRALGW_ROOT/certs/websocket-cert.pem"} \
|
||||
WEBSOCKET_HOST_KEY=${WEBSOCKET_HOST_KEY:-"\$UCENTRALGW_ROOT/certs/websocket-key.pem"} \
|
||||
WEBSOCKET_HOST_CLIENTCAS=${WEBSOCKET_HOST_CLIENTCAS:-"\$UCENTRALGW_ROOT/certs/clientcas.pem"} \
|
||||
WEBSOCKET_HOST_CAS=${WEBSOCKET_HOST_CAS:-"\$UCENTRALGW_ROOT/certs/cas"} \
|
||||
WEBSOCKET_HOST_PORT=${WEBSOCKET_HOST_PORT:-"15002"} \
|
||||
WEBSOCKET_HOST_KEY_PASSWORD=${WEBSOCKET_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$UCENTRALGW_ROOT/certs/restapi-ca.pem"} \
|
||||
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16002"} \
|
||||
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$UCENTRALGW_ROOT/certs/restapi-cert.pem"} \
|
||||
RESTAPI_HOST_KEY=${RESTAPI_HOST_KEY:-"\$UCENTRALGW_ROOT/certs/restapi-key.pem"} \
|
||||
RESTAPI_HOST_KEY_PASSWORD=${RESTAPI_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
INTERNAL_RESTAPI_HOST_ROOTCA=${INTERNAL_RESTAPI_HOST_ROOTCA:-"\$UCENTRALGW_ROOT/certs/restapi-ca.pem"} \
|
||||
INTERNAL_RESTAPI_HOST_PORT=${INTERNAL_RESTAPI_HOST_PORT:-"17002"} \
|
||||
INTERNAL_RESTAPI_HOST_CERT=${INTERNAL_RESTAPI_HOST_CERT:-"\$UCENTRALGW_ROOT/certs/restapi-cert.pem"} \
|
||||
INTERNAL_RESTAPI_HOST_KEY=${INTERNAL_RESTAPI_HOST_KEY:-"\$UCENTRALGW_ROOT/certs/restapi-key.pem"} \
|
||||
INTERNAL_RESTAPI_HOST_KEY_PASSWORD=${INTERNAL_RESTAPI_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
FILEUPLOADER_HOST_ROOTCA=${FILEUPLOADER_HOST_ROOTCA:-"\$UCENTRALGW_ROOT/certs/restapi-ca.pem"} \
|
||||
FILEUPLOADER_HOST_NAME=${FILEUPLOADER_HOST_NAME:-"localhost"} \
|
||||
FILEUPLOADER_HOST_PORT=${FILEUPLOADER_HOST_PORT:-"16003"} \
|
||||
FILEUPLOADER_HOST_CERT=${FILEUPLOADER_HOST_CERT:-"\$UCENTRALGW_ROOT/certs/restapi-cert.pem"} \
|
||||
FILEUPLOADER_HOST_KEY=${FILEUPLOADER_HOST_KEY:-"\$UCENTRALGW_ROOT/certs/restapi-key.pem"} \
|
||||
FILEUPLOADER_HOST_KEY_PASSWORD=${FILEUPLOADER_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
FILEUPLOADER_PATH=${FILEUPLOADER_PATH:-"\$UCENTRALGW_ROOT/uploads"} \
|
||||
SERVICE_KEY=${SERVICE_KEY:-"\$UCENTRALGW_ROOT/certs/restapi-key.pem"} \
|
||||
SERVICE_KEY_PASSWORD=${SERVICE_KEY_PASSWORD:-"mypassword"} \
|
||||
SYSTEM_DATA=${SYSTEM_DATA:-"\$UCENTRALGW_ROOT/data"} \
|
||||
SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17002"} \
|
||||
SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16002"} \
|
||||
SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
|
||||
RTTY_ENABLED=${RTTY_ENABLED:-"false"} \
|
||||
RTTY_SERVER=${RTTY_SERVER:-"localhost"} \
|
||||
RTTY_PORT=${RTTY_PORT:-"5912"} \
|
||||
RTTY_TOKEN=${RTTY_TOKEN:-"96181c567b4d0d98c50f127230068fa8"} \
|
||||
RTTY_TIMEOUT=${RTTY_TIMEOUT:-"60"} \
|
||||
RTTY_VIEWPORT=${RTTY_VIEWPORT:-"5913"} \
|
||||
KAFKA_ENABLE=${KAFKA_ENABLE:-"true"} \
|
||||
KAFKA_BROKERLIST=${KAFKA_BROKERLIST:-"localhost:9092"} \
|
||||
STORAGE_TYPE=${STORAGE_TYPE:-"sqlite"} \
|
||||
STORAGE_TYPE_POSTGRESQL_HOST=${STORAGE_TYPE_POSTGRESQL_HOST:-"localhost"} \
|
||||
STORAGE_TYPE_POSTGRESQL_USERNAME=${STORAGE_TYPE_POSTGRESQL_USERNAME:-"ucentralgw"} \
|
||||
STORAGE_TYPE_POSTGRESQL_PASSWORD=${STORAGE_TYPE_POSTGRESQL_PASSWORD:-"ucentralgw"} \
|
||||
STORAGE_TYPE_POSTGRESQL_DATABASE=${STORAGE_TYPE_POSTGRESQL_DATABASE:-"ucentralgw"} \
|
||||
STORAGE_TYPE_POSTGRESQL_PORT=${STORAGE_TYPE_POSTGRESQL_PORT:-"5432"} \
|
||||
STORAGE_TYPE_MYSQL_HOST=${STORAGE_TYPE_MYSQL_HOST:-"localhost"} \
|
||||
STORAGE_TYPE_MYSQL_USERNAME=${STORAGE_TYPE_MYSQL_USERNAME:-"ucentralgw"} \
|
||||
STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"ucentralgw"} \
|
||||
STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"ucentralgw"} \
|
||||
STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \
|
||||
envsubst < $UCENTRALGW_CONFIG/ucentralgw.properties.tmpl > $UCENTRALGW_CONFIG/ucentralgw.properties
|
||||
fi
|
||||
|
||||
if [ "$1" = '/ucentral/ucentralgw' -a "$(id -u)" = '0' ]; then
|
||||
if [ "$RUN_CHOWN" = 'true' ]; then
|
||||
chown -R "$UCENTRALGW_USER": "$UCENTRALGW_ROOT" "$UCENTRALGW_CONFIG"
|
||||
|
||||
@@ -26,7 +26,7 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f ucentral.properties ]]
|
||||
if [[ ! -f ucentralgw.properties ]]
|
||||
then
|
||||
echo "Configuration file ucentral.properties is missing in the current directory"
|
||||
exit 2
|
||||
@@ -37,7 +37,7 @@ docker run -d -p 15002:15002 \
|
||||
-p 16003:16003 \
|
||||
--init \
|
||||
--volume="$PWD:/ucentral-data" \
|
||||
-e UCENTRAL_ROOT="/ucentral-data" \
|
||||
-e UCENTRAL_CONFIG="/ucentral-data" \
|
||||
-e UCENTRALGW_ROOT="/ucentral-data" \
|
||||
-e UCENTRALGW_CONFIG="/ucentral-data" \
|
||||
--name="ucentralgw" $DOCKER_NAME
|
||||
|
||||
|
||||
0
helm/.gitkeep
Normal file
0
helm/.gitkeep
Normal file
12
helm/Chart.lock
Normal file
12
helm/Chart.lock
Normal file
@@ -0,0 +1,12 @@
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
version: 10.9.2
|
||||
- name: mysql
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
version: 8.8.3
|
||||
- name: mariadb
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
version: 9.4.2
|
||||
digest: sha256:1fdae7cbea906e41dccd8618ff9e2c68d0c684724ae27c79a12bb6089968df5c
|
||||
generated: "2021-08-17T12:18:40.341427893+03:00"
|
||||
@@ -1,5 +1,18 @@
|
||||
apiVersion: v1
|
||||
apiVersion: v2
|
||||
appVersion: "1.0"
|
||||
description: A Helm chart for Kubernetes
|
||||
name: ucentralgw
|
||||
version: 0.1.0
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
version: 10.9.2
|
||||
condition: postgresql.enabled
|
||||
- name: mysql
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
version: 8.8.3
|
||||
condition: mysql.enabled
|
||||
- name: mariadb
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
version: 9.4.2
|
||||
condition: mariadb.enabled
|
||||
|
||||
@@ -83,6 +83,11 @@ spec:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
|
||||
{{- with .Values.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
|
||||
imagePullSecrets:
|
||||
{{- range $image, $imageValue := .Values.images }}
|
||||
{{- if $imageValue.regcred }}
|
||||
|
||||
@@ -8,7 +8,7 @@ fullnameOverride: ""
|
||||
images:
|
||||
ucentralgw:
|
||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/ucentralgw
|
||||
tag: master
|
||||
tag: v2.1.0-RC3
|
||||
pullPolicy: Always
|
||||
# regcred:
|
||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||
@@ -109,6 +109,9 @@ resources: {}
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
|
||||
securityContext:
|
||||
fsGroup: 101
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
@@ -168,7 +171,7 @@ configProperties:
|
||||
ucentral.fileuploader.host.0.port: 16003
|
||||
ucentral.fileuploader.host.0.cert: $UCENTRALGW_ROOT/certs/restapi-cert.pem
|
||||
ucentral.fileuploader.host.0.key: $UCENTRALGW_ROOT/certs/restapi-key.pem
|
||||
ucentral.fileuploader.path: $UCENTRALGW_ROOT/uploads
|
||||
ucentral.fileuploader.path: $UCENTRALGW_ROOT/persist/uploads
|
||||
ucentral.fileuploader.maxsize: 10000
|
||||
# Auto provisioning
|
||||
ucentral.autoprovisioning: "true"
|
||||
@@ -227,7 +230,7 @@ configProperties:
|
||||
ucentral.system.commandchannel: /tmp/app_ucentralgw
|
||||
# Logging
|
||||
logging.formatters.f1.class: PatternFormatter
|
||||
logging.formatters.f1.pattern: "%s: [%p] %t"
|
||||
logging.formatters.f1.pattern: "%Y-%m-%d %H:%M:%S %s: [%p] %t"
|
||||
logging.formatters.f1.times: UTC
|
||||
logging.channels.c1.class: ConsoleChannel
|
||||
logging.channels.c1.formatter: f1
|
||||
@@ -240,7 +243,7 @@ configProperties:
|
||||
logging.channels.c2.purgeCount: 20
|
||||
logging.channels.c3.class: ConsoleChannel
|
||||
logging.channels.c3.pattern: "%s: [%p] %t"
|
||||
logging.loggers.root.channel: c2
|
||||
logging.loggers.root.channel: c1
|
||||
logging.loggers.root.level: debug
|
||||
|
||||
# -> Secret part
|
||||
@@ -425,3 +428,64 @@ certsCAs:
|
||||
L+/DtiR5fDVMNdBSGU89UNTi0wHY9+RFuNlIuvZC+x/swF0V9R5mN+ywquTPtDLA
|
||||
5IOM7ItsRmen6u3qu+JXros54e4juQ==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
# PostgreSQL (https://github.com/bitnami/charts/tree/master/bitnami/postgresql)
|
||||
postgresql:
|
||||
enabled: false
|
||||
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: bitnami/postgresql
|
||||
tag: 11.13.0-debian-10-r0
|
||||
|
||||
postgresqlPostgresPassword: ""
|
||||
postgresqlUsername: postgres
|
||||
postgresqlPassword: ""
|
||||
postgresqlDatabase: ""
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
storageClass: ""
|
||||
size: 8Gi
|
||||
|
||||
# MySQL (https://github.com/bitnami/charts/tree/master/bitnami/mysql)
|
||||
mysql:
|
||||
enabled: false
|
||||
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: bitnami/mysql
|
||||
tag: 8.0.26-debian-10-r10
|
||||
|
||||
auth:
|
||||
rootPassword: ""
|
||||
database: my_database
|
||||
username: ""
|
||||
password: ""
|
||||
|
||||
primary:
|
||||
persistence:
|
||||
enabled: true
|
||||
storageClass: ""
|
||||
size: 8Gi
|
||||
|
||||
# MariaDB (https://github.com/bitnami/charts/tree/master/bitnami/mariadb)
|
||||
mariadb:
|
||||
enabled: false
|
||||
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: bitnami/mariadb
|
||||
tag: 10.5.12-debian-10-r0
|
||||
|
||||
auth:
|
||||
rootPassword: ""
|
||||
database: my_database
|
||||
username: ""
|
||||
password: ""
|
||||
|
||||
primary:
|
||||
persistence:
|
||||
enabled: true
|
||||
storageClass: ""
|
||||
size: 8Gi
|
||||
|
||||
@@ -180,6 +180,12 @@ components:
|
||||
rxBytes:
|
||||
type: integer
|
||||
format: int64
|
||||
associations_2G:
|
||||
type: integer
|
||||
format: int64
|
||||
associations_5G:
|
||||
type: integer
|
||||
format: int64
|
||||
devicePassword:
|
||||
type: string
|
||||
lastContact:
|
||||
@@ -248,6 +254,12 @@ components:
|
||||
format: int64
|
||||
firmware:
|
||||
type: string
|
||||
associations_2G:
|
||||
type: integer
|
||||
format: int64
|
||||
associations_5G:
|
||||
type: integer
|
||||
format: int64
|
||||
verifiedCertificate:
|
||||
type: string
|
||||
enum:
|
||||
@@ -584,6 +596,12 @@ components:
|
||||
DeviceDashboard:
|
||||
type: object
|
||||
properties:
|
||||
snapshot:
|
||||
type: integer
|
||||
format: int64
|
||||
numberOfDevices:
|
||||
type: integer
|
||||
format: int64
|
||||
commands:
|
||||
$ref: '#/components/schemas/TagIntPairList'
|
||||
upTimes:
|
||||
@@ -610,6 +628,8 @@ components:
|
||||
$ref: '#/components/schemas/TagIntPairList'
|
||||
lastContact:
|
||||
$ref: '#/components/schemas/TagIntPairList'
|
||||
associations:
|
||||
$ref: '#/components/schemas/TagIntPairList'
|
||||
|
||||
#########################################################################################
|
||||
##
|
||||
@@ -852,6 +872,7 @@ paths:
|
||||
name: countOnly
|
||||
schema:
|
||||
type: boolean
|
||||
example: countOnly=true
|
||||
- in: query
|
||||
description: Return extra information with the device information
|
||||
name: deviceWithStatus
|
||||
@@ -950,7 +971,7 @@ paths:
|
||||
format: int64
|
||||
|
||||
responses:
|
||||
200:
|
||||
204:
|
||||
description: Successfully deleted commands for the device.
|
||||
content:
|
||||
application/json:
|
||||
@@ -1001,7 +1022,7 @@ paths:
|
||||
format: uuid
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
204:
|
||||
description: Delete command success
|
||||
content:
|
||||
application/json:
|
||||
@@ -1096,7 +1117,7 @@ paths:
|
||||
type: string
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
204:
|
||||
$ref: '#/components/responses/Success'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
@@ -1224,7 +1245,7 @@ paths:
|
||||
type: string
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
204:
|
||||
$ref: '#/components/responses/Success'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
@@ -1319,7 +1340,7 @@ paths:
|
||||
format: int64
|
||||
|
||||
responses:
|
||||
200:
|
||||
204:
|
||||
description: Successfully deleted logs for the device.
|
||||
content:
|
||||
application/json:
|
||||
@@ -1416,7 +1437,7 @@ paths:
|
||||
required: false
|
||||
|
||||
responses:
|
||||
200:
|
||||
204:
|
||||
description: Successfully deleted health checks for the device.
|
||||
content:
|
||||
application/json:
|
||||
@@ -1463,7 +1484,7 @@ paths:
|
||||
type: string
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
204:
|
||||
description: List of logs for this device
|
||||
content:
|
||||
application/json:
|
||||
@@ -1568,7 +1589,7 @@ paths:
|
||||
required: false
|
||||
|
||||
responses:
|
||||
200:
|
||||
204:
|
||||
description: Array of statistics for this device
|
||||
content:
|
||||
application/json:
|
||||
@@ -1837,7 +1858,7 @@ paths:
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/device/{serialNumber}/eventrequest:
|
||||
/device/{serialNumber}/eventqueue:
|
||||
post:
|
||||
tags:
|
||||
- Commands
|
||||
@@ -1956,7 +1977,7 @@ paths:
|
||||
type: string
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
204:
|
||||
$ref: '#/components/responses/Success'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
@@ -2033,7 +2054,7 @@ paths:
|
||||
type: string
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
204:
|
||||
$ref: '#/components/responses/Success'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include "Daemon.h"
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class ALBRequestHandler: public Poco::Net::HTTPRequestHandler
|
||||
/// Return a HTML document with the current date and time.
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include "Daemon.h"
|
||||
#include "OpenAPIRequest.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class AuthClient * AuthClient::instance_ = nullptr;
|
||||
|
||||
int AuthClient::Start() {
|
||||
@@ -38,7 +38,7 @@ namespace uCentral {
|
||||
} else {
|
||||
Types::StringPairVec QueryData;
|
||||
QueryData.push_back(std::make_pair("token",SessionToken));
|
||||
OpenAPIRequestGet Req(uSERVICE_SECURITY,
|
||||
OpenAPIRequestGet Req( uSERVICE_SECURITY,
|
||||
"/api/v1/validateToken",
|
||||
QueryData,
|
||||
5000);
|
||||
@@ -56,4 +56,33 @@ namespace uCentral {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AuthClient::IsTokenAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo) {
|
||||
SubMutexGuard G(Mutex_);
|
||||
|
||||
auto User = UserCache_.find(SessionToken);
|
||||
if(User != UserCache_.end() && !IsTokenExpired(User->second.webtoken)) {
|
||||
UInfo = User->second;
|
||||
return true;
|
||||
} else {
|
||||
Types::StringPairVec QueryData;
|
||||
QueryData.push_back(std::make_pair("token",SessionToken));
|
||||
OpenAPIRequestGet Req(uSERVICE_SECURITY,
|
||||
"/api/v1/validateToken",
|
||||
QueryData,
|
||||
5000);
|
||||
Poco::JSON::Object::Ptr Response;
|
||||
if(Req.Do(Response)==Poco::Net::HTTPResponse::HTTP_OK) {
|
||||
if(Response->has("tokenInfo") && Response->has("userInfo")) {
|
||||
SecurityObjects::UserInfoAndPolicy P;
|
||||
P.from_json(Response);
|
||||
UserCache_[SessionToken] = P;
|
||||
UInfo = P;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -13,9 +13,9 @@
|
||||
#include "RESTAPI_SecurityObjects.h"
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class AuthClient : public SubSystemServer {
|
||||
class AuthClient : public SubSystemServer {
|
||||
public:
|
||||
explicit AuthClient() noexcept:
|
||||
SubSystemServer("Authentication", "AUTH-CLNT", "authentication")
|
||||
@@ -31,12 +31,12 @@ namespace uCentral {
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
bool IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo );
|
||||
bool IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string &SessionToken, OpenWifi::SecurityObjects::UserInfoAndPolicy & UInfo );
|
||||
void RemovedCachedToken(const std::string &Token);
|
||||
|
||||
bool IsTokenAuthorized(const std::string &Token, SecurityObjects::UserInfoAndPolicy & UInfo);
|
||||
private:
|
||||
static AuthClient *instance_;
|
||||
SecurityObjects::UserInfoCache UserCache_;
|
||||
OpenWifi::SecurityObjects::UserInfoCache UserCache_;
|
||||
};
|
||||
|
||||
inline AuthClient * AuthClient() { return AuthClient::instance(); }
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/File.h"
|
||||
|
||||
namespace uCentral::Config {
|
||||
namespace OpenWifi::Config {
|
||||
|
||||
static std::string DefaultConfiguration;
|
||||
|
||||
@@ -232,7 +232,7 @@ namespace uCentral::Config {
|
||||
}
|
||||
catch ( const Poco::Exception & E )
|
||||
{
|
||||
uCentral::Daemon::instance()->logger().warning(Poco::format("%s: Failed with: %s", std::string(__func__) , E.displayText()));
|
||||
Daemon::instance()->logger().warning(Poco::format("%s: Failed with: %s", std::string(__func__) , E.displayText()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <string>
|
||||
#include "Poco/JSON/Object.h"
|
||||
|
||||
namespace uCentral::Config {
|
||||
namespace OpenWifi::Config {
|
||||
|
||||
class Config {
|
||||
public:
|
||||
|
||||
@@ -1,164 +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 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
#include "CommandChannel.h"
|
||||
#include "AuthClient.h"
|
||||
#include "CommandManager.h"
|
||||
#include "Daemon.h"
|
||||
#include "FileUploader.h"
|
||||
#include "RESTAPI_server.h"
|
||||
#include "StorageService.h"
|
||||
#include "WebSocketServer.h"
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
||||
namespace uCentral {
|
||||
|
||||
class CommandChannel * CommandChannel::instance_ = nullptr;
|
||||
|
||||
std::string CommandChannel::ProcessCommand(const std::string &Command) {
|
||||
std::vector<std::string> Tokens{};
|
||||
std::string Result{"OK"};
|
||||
|
||||
|
||||
try {
|
||||
size_t pos, old_pos = 0 ;
|
||||
|
||||
Logger_.notice(Poco::format("COMMAND: %s",Command));
|
||||
|
||||
while((pos = Command.find(' ', old_pos)) != std::string::npos) {
|
||||
Tokens.push_back(Command.substr(old_pos,pos-old_pos));
|
||||
old_pos = pos + 1 ;
|
||||
}
|
||||
|
||||
Tokens.push_back(Command.substr(old_pos));
|
||||
boost::algorithm::to_lower(Tokens[0]);
|
||||
boost::algorithm::to_lower(Tokens[1]);
|
||||
|
||||
if(Tokens[0]=="set") {
|
||||
if(Tokens[1]=="loglevel") {
|
||||
if(!Daemon()->SetSubsystemLogLevel(Tokens[3],Tokens[2]))
|
||||
Result = "ERROR: Invalid: set logLevel subsystem name:" + Tokens[3];
|
||||
}
|
||||
} else if(Tokens[0]=="get") {
|
||||
if(Tokens[1]=="loglevel") {
|
||||
std::cout << "LogLevels:" << std::endl;
|
||||
std::cout << " Auth: " << AuthClient()->Logger().getLevel() << std::endl;
|
||||
std::cout << " uFileUploader: " << FileUploader()->Logger().getLevel() << std::endl;
|
||||
std::cout << " WebSocket: " << WebSocketServer()->Logger().getLevel() << std::endl;
|
||||
std::cout << " Storage: " << Storage()->Logger().getLevel() << std::endl;
|
||||
std::cout << " RESTAPI: " << RESTAPI_server()->Logger().getLevel() << std::endl;
|
||||
std::cout << " CommandManager: " << Logger_.getLevel() << std::endl;
|
||||
std::cout << " DeviceRegistry: " << DeviceRegistry()->Logger().getLevel() << std::endl;
|
||||
} else if (Tokens[1]=="stats") {
|
||||
|
||||
} else {
|
||||
Result = "ERROR: Invalid: get command:" + Tokens[1];
|
||||
}
|
||||
} else if(Tokens[0]=="restart") {
|
||||
Logger_.information("RESTART...");
|
||||
} else if(Tokens[0]=="stop") {
|
||||
Logger_.information("STOP...");
|
||||
} else if(Tokens[0]=="stats") {
|
||||
Logger_.information("STATS...");
|
||||
} else {
|
||||
Result = "ERROR: Invalid command: " + Tokens[0];
|
||||
}
|
||||
Logger_.notice(Poco::format("COMMAND-RESULT: %s",Result));
|
||||
}
|
||||
catch ( const Poco::Exception & E) {
|
||||
Logger_.warning(Poco::format("COMMAND: Poco exception %s in performing command.",E.displayText()));
|
||||
}
|
||||
catch ( const std::exception & E) {
|
||||
Logger_.warning(Poco::format("COMMAND: std::exception %s in performing command.",std::string(E.what())));
|
||||
}
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
/// This class handles all client connections.
|
||||
class UnixSocketServerConnection: public Poco::Net::TCPServerConnection
|
||||
{
|
||||
public:
|
||||
explicit UnixSocketServerConnection(const Poco::Net::StreamSocket & S, Poco::Logger & Logger):
|
||||
TCPServerConnection(S),
|
||||
Logger_(Logger)
|
||||
{
|
||||
}
|
||||
|
||||
void run() override
|
||||
{
|
||||
try
|
||||
{
|
||||
std::string Message;
|
||||
std::vector<char> buffer(1024);
|
||||
int n = 1;
|
||||
while (n > 0)
|
||||
{
|
||||
n = socket().receiveBytes(&buffer[0], (int)buffer.size());
|
||||
buffer[n] = '\0';
|
||||
Message += &buffer[0];
|
||||
Logger_.information(Poco::format("COMMAND-CHANNEL: %s",Message));
|
||||
if(buffer.size() > n && !Message.empty())
|
||||
{
|
||||
CommandChannel()->ProcessCommand(Message);
|
||||
Message.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (const Poco::Exception & E)
|
||||
{
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
Poco::Logger & Logger_;
|
||||
};
|
||||
|
||||
class UnixSocketServerConnectionFactory: public Poco::Net::TCPServerConnectionFactory
|
||||
{
|
||||
public:
|
||||
explicit UnixSocketServerConnectionFactory() :
|
||||
Logger_(CommandChannel()->Logger())
|
||||
{
|
||||
}
|
||||
|
||||
Poco::Net::TCPServerConnection* createConnection(const Poco::Net::StreamSocket& socket) override
|
||||
{
|
||||
return new UnixSocketServerConnection(socket,Logger_);
|
||||
}
|
||||
private:
|
||||
Poco::Logger & Logger_;
|
||||
};
|
||||
|
||||
CommandChannel::CommandChannel() noexcept:
|
||||
SubSystemServer("CommandChannel", "COMMAND-CHANNEL", "commandchannel")
|
||||
{
|
||||
}
|
||||
|
||||
void CommandChannel::Stop() {
|
||||
Logger_.notice("Stopping...");
|
||||
Srv_->stop();
|
||||
}
|
||||
|
||||
int CommandChannel::Start() {
|
||||
Poco::File F(Daemon()->ConfigPath("ucentral.system.commandchannel","/tmp/app.ucentralgw"));
|
||||
try {
|
||||
if (F.exists())
|
||||
F.remove();
|
||||
} catch (const Poco::Exception &E ) {
|
||||
|
||||
}
|
||||
SocketFile_ = std::make_unique<Poco::File>(F);
|
||||
UnixSocket_ = std::make_unique<Poco::Net::SocketAddress>(Poco::Net::SocketAddress::UNIX_LOCAL, SocketFile_->path());
|
||||
Svs_ = std::make_unique<Poco::Net::ServerSocket>(*UnixSocket_);
|
||||
Srv_ = std::make_unique<Poco::Net::TCPServer>(new UnixSocketServerConnectionFactory, *Svs_);
|
||||
Srv_->start();
|
||||
Logger_.notice("Starting...");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,51 +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 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALGW_COMMANDCHANNEL_H
|
||||
#define UCENTRALGW_COMMANDCHANNEL_H
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/Net/Socket.h"
|
||||
#include "Poco/Net/SocketAddress.h"
|
||||
#include "Poco/Net/TCPServer.h"
|
||||
#include "Poco/Net/TCPServerConnection.h"
|
||||
#include "Poco/Net/TCPServerConnectionFactory.h"
|
||||
#include "Poco/Net/StreamSocket.h"
|
||||
#include "Poco/Net/ServerSocket.h"
|
||||
|
||||
namespace uCentral {
|
||||
|
||||
class CommandChannel : public SubSystemServer {
|
||||
public:
|
||||
static CommandChannel *instance() {
|
||||
if (instance_ == nullptr) {
|
||||
instance_ = new CommandChannel;
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
std::string ProcessCommand(const std::string &Command);
|
||||
|
||||
private:
|
||||
static CommandChannel * instance_;
|
||||
std::unique_ptr<Poco::File> SocketFile_;
|
||||
std::unique_ptr<Poco::Net::SocketAddress> UnixSocket_;
|
||||
std::unique_ptr<Poco::Net::ServerSocket> Svs_;
|
||||
std::unique_ptr<Poco::Net::TCPServer> Srv_;
|
||||
|
||||
CommandChannel() noexcept;
|
||||
};
|
||||
|
||||
inline CommandChannel * CommandChannel() { return CommandChannel::instance(); }
|
||||
} //namespace
|
||||
|
||||
#endif // UCENTRALGW_COMMANDCHANNEL_H
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class CommandManager * CommandManager::instance_ = nullptr;
|
||||
|
||||
@@ -31,15 +31,18 @@ namespace uCentral {
|
||||
Running_ = true;
|
||||
while(Running_)
|
||||
{
|
||||
Poco::Thread::trySleep(10000);
|
||||
Poco::Thread::trySleep(30000);
|
||||
if(!Running_)
|
||||
break;
|
||||
std::vector<GWObjects::CommandDetails> Commands;
|
||||
|
||||
if(Storage()->GetReadyToExecuteCommands(0,1000,Commands))
|
||||
if(Storage()->GetReadyToExecuteCommands(1,200,Commands))
|
||||
{
|
||||
for(auto & Cmd: Commands)
|
||||
{
|
||||
if(!Running_)
|
||||
break;
|
||||
|
||||
if(!SendCommand(Cmd)) {
|
||||
Logger_.information(Poco::format("Failed to send command '%s' to %s",Cmd.Command,Cmd.SerialNumber));
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class CommandManager : public SubSystemServer, Poco::Runnable {
|
||||
public:
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
#include "Daemon.h"
|
||||
|
||||
#include "CommandChannel.h"
|
||||
#include "CommandManager.h"
|
||||
#include "DeviceRegistry.h"
|
||||
#include "FileUploader.h"
|
||||
@@ -28,8 +27,9 @@
|
||||
#include "RESTAPI_InternalServer.h"
|
||||
#include "AuthClient.h"
|
||||
#include "StorageArchiver.h"
|
||||
#include "SerialNumberCache.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class Daemon *Daemon::instance_ = nullptr;
|
||||
|
||||
class Daemon *Daemon::instance() {
|
||||
@@ -41,6 +41,7 @@ namespace uCentral {
|
||||
vDAEMON_BUS_TIMER,
|
||||
Types::SubSystemVec{
|
||||
Storage(),
|
||||
SerialNumberCache(),
|
||||
AuthClient(),
|
||||
DeviceRegistry(),
|
||||
RESTAPI_server(),
|
||||
@@ -49,7 +50,6 @@ namespace uCentral {
|
||||
CommandManager(),
|
||||
FileUploader(),
|
||||
OUIServer(),
|
||||
CommandChannel(),
|
||||
StorageArchiver(),
|
||||
});
|
||||
}
|
||||
@@ -71,7 +71,7 @@ namespace uCentral {
|
||||
auto Type = Line.substr(0, P1);
|
||||
auto List = Line.substr(P1+1);
|
||||
|
||||
Types::StringVec Tokens = uCentral::Utils::Split(List);
|
||||
Types::StringVec Tokens = Utils::Split(List);
|
||||
|
||||
auto Entry = DeviceTypeIdentifications_.find(Type);
|
||||
if(DeviceTypeIdentifications_.end() == Entry) {
|
||||
@@ -96,7 +96,7 @@ namespace uCentral {
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
try {
|
||||
auto App = uCentral::Daemon::instance();
|
||||
auto App = OpenWifi::Daemon::instance();
|
||||
auto ExitCode = App->run(argc, argv);
|
||||
delete App;
|
||||
|
||||
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
#include "Dashboard.h"
|
||||
#include "MicroService.h"
|
||||
#include "uCentralTypes.h"
|
||||
#include "OpenWifiTypes.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
static const char * vDAEMON_PROPERTIES_FILENAME = "ucentralgw.properties";
|
||||
static const char * vDAEMON_ROOT_ENV_VAR = "UCENTRALGW_ROOT";
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
#include "DeviceRegistry.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
void DeviceDashboard::Create() {
|
||||
uint64_t Now = std::time(nullptr);
|
||||
|
||||
if(LastRun_==0 || (Now-LastRun_)>120) {
|
||||
DB_.reset();
|
||||
Storage()->AnalyzeCommands(DB_.commands);
|
||||
DeviceRegistry()->AnalyzeRegistry(DB_);
|
||||
// DeviceRegistry()->AnalyzeRegistry(DB_);
|
||||
Storage()->AnalyzeDevices(DB_);
|
||||
LastRun_ = Now;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,18 +5,18 @@
|
||||
#ifndef UCENTRALGW_DASHBOARD_H
|
||||
#define UCENTRALGW_DASHBOARD_H
|
||||
|
||||
#include "uCentralTypes.h"
|
||||
#include "OpenWifiTypes.h"
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class DeviceDashboard {
|
||||
public:
|
||||
void Create();
|
||||
const GWObjects::Dashboard & Report() const { return DB_;}
|
||||
inline void Reset() { LastRun_=0; DB_.reset(); }
|
||||
private:
|
||||
GWObjects::Dashboard DB_;
|
||||
uint64_t LastRun_=0;
|
||||
inline void Reset() { DB_.reset(); }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class DeviceRegistry *DeviceRegistry::instance_ = nullptr;
|
||||
|
||||
DeviceRegistry::DeviceRegistry() noexcept:
|
||||
@@ -207,7 +207,7 @@ namespace uCentral {
|
||||
if( T==100) return "100%";
|
||||
if( T>90) return ">90%";
|
||||
if( T>60) return ">60%";
|
||||
return "<60%%>";
|
||||
return "<60%";
|
||||
}
|
||||
|
||||
std::string ComputeUpTimeTag(uint64_t T) {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
// class uCentral::WebSocket::WSConnection;
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class WSConnection;
|
||||
class DeviceRegistry : public SubSystemServer {
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class FileUploader *FileUploader::instance_ = nullptr;
|
||||
|
||||
static const std::string URI_BASE{"/v1/upload/"};
|
||||
@@ -42,7 +42,16 @@ namespace uCentral {
|
||||
|
||||
Logger_.information(l);
|
||||
|
||||
Path_ = Daemon()->ConfigPath("ucentral.fileuploader.path","/tmp");
|
||||
Poco::File UploadsDir(Daemon()->ConfigPath("ucentral.fileuploader.path","/tmp"));
|
||||
Path_ = UploadsDir.path();
|
||||
if(!UploadsDir.exists()) {
|
||||
try {
|
||||
UploadsDir.createDirectory();
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
Path_ = "/tmp";
|
||||
}
|
||||
}
|
||||
|
||||
auto Sock{Svr.CreateSecureSocket(Logger_)};
|
||||
|
||||
@@ -63,6 +72,8 @@ namespace uCentral {
|
||||
Servers_.push_back(std::move(NewServer));
|
||||
}
|
||||
|
||||
MaxSize_ = 1000 * Daemon()->ConfigGetInt("ucentral.fileuploader.maxsize", 10000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -112,35 +123,49 @@ namespace uCentral {
|
||||
|
||||
void handlePart(const Poco::Net::MessageHeader& Header, std::istream& Stream) override
|
||||
{
|
||||
FileType_ = Header.get("Content-Type", "(unspecified)");
|
||||
if (Header.has("Content-Disposition"))
|
||||
{
|
||||
std::string Disposition;
|
||||
Poco::Net::NameValueCollection Parameters;
|
||||
Poco::Net::MessageHeader::splitParameters(Header["Content-Disposition"], Disposition, Parameters);
|
||||
Name_ = Parameters.get("name", "(unnamed)");
|
||||
}
|
||||
try {
|
||||
Name_ = "(unnamed)";
|
||||
if (Header.has("Content-Disposition")) {
|
||||
std::string Disposition;
|
||||
Poco::Net::NameValueCollection Parameters;
|
||||
Poco::Net::MessageHeader::splitParameters(Header["Content-Disposition"],
|
||||
Disposition, Parameters);
|
||||
Name_ = Parameters.get("filename", "(unnamed)");
|
||||
}
|
||||
|
||||
Poco::TemporaryFile TmpFile;
|
||||
std::string FinalFileName = FileUploader()->Path() + "/" + UUID_ ;
|
||||
Logger_.information(Poco::format("FILE-UPLOADER: uploading trace for %s",UUID_));
|
||||
Poco::TemporaryFile TmpFile;
|
||||
std::string FinalFileName = FileUploader()->Path() + "/" + UUID_;
|
||||
Logger_.information(Poco::format("FILE-UPLOADER: uploading trace for %s", UUID_));
|
||||
|
||||
Poco::CountingInputStream InputStream(Stream);
|
||||
std::ofstream OutputStream(TmpFile.path(), std::ofstream::out);
|
||||
Poco::StreamCopier::copyStream(InputStream, OutputStream);
|
||||
Length_ = InputStream.chars();
|
||||
rename(TmpFile.path().c_str(),FinalFileName.c_str());
|
||||
}
|
||||
Poco::CountingInputStream InputStream(Stream);
|
||||
std::ofstream OutputStream(TmpFile.path(), std::ofstream::out);
|
||||
Poco::StreamCopier::copyStream(InputStream, OutputStream);
|
||||
Length_ = TmpFile.getSize();
|
||||
|
||||
if (Length_ < FileUploader()->MaxSize()) {
|
||||
rename(TmpFile.path().c_str(), FinalFileName.c_str());
|
||||
Good_=true;
|
||||
} else {
|
||||
Error_ = "File is too large.";
|
||||
}
|
||||
return;
|
||||
} catch (const Poco::Exception &E ) {
|
||||
Logger_.log(E);
|
||||
Error_ = std::string("Upload caused an internal error: ") + E.what() ;
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] uint64_t Length() const { return Length_; }
|
||||
[[nodiscard]] const std::string& Name() const { return Name_; }
|
||||
[[nodiscard]] const std::string& ContentType() const { return FileType_; }
|
||||
[[nodiscard]] bool Good() const { return Good_; }
|
||||
std::string & Error() { return Error_; }
|
||||
|
||||
private:
|
||||
uint64_t Length_=0;
|
||||
std::string FileType_;
|
||||
bool Good_=false;
|
||||
std::string Name_;
|
||||
std::string UUID_;
|
||||
std::string Error_;
|
||||
Poco::Logger & Logger_;
|
||||
};
|
||||
|
||||
@@ -165,14 +190,15 @@ namespace uCentral {
|
||||
Response.setContentType("application/json");
|
||||
|
||||
Poco::JSON::Object Answer;
|
||||
if (!partHandler.Name().empty()) {
|
||||
if (partHandler.Good()) {
|
||||
Answer.set("filename", UUID_);
|
||||
Answer.set("error", 0);
|
||||
Storage()->AttachFileToCommand(UUID_);
|
||||
} else {
|
||||
Answer.set("filename", UUID_);
|
||||
Answer.set("error", 13);
|
||||
Answer.set("errorText", "File could not be uploaded");
|
||||
Answer.set("errorText", partHandler.Error() );
|
||||
Storage()->CancelWaitFile(UUID_, partHandler.Error() );
|
||||
}
|
||||
std::ostream &ResponseStream = Response.send();
|
||||
Poco::JSON::Stringifier::stringify(Answer, ResponseStream);
|
||||
@@ -193,7 +219,7 @@ namespace uCentral {
|
||||
|
||||
Poco::Net::HTTPRequestHandler *FileUpLoaderRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest & Request) {
|
||||
|
||||
Logger_.debug(Poco::format("REQUEST(%s): %s %s", uCentral::Utils::FormatIPv6(Request.clientAddress().toString()), Request.getMethod(), Request.getURI()));
|
||||
Logger_.debug(Poco::format("REQUEST(%s): %s %s", Utils::FormatIPv6(Request.clientAddress().toString()), Request.getMethod(), Request.getURI()));
|
||||
|
||||
// The UUID should be after the /v1/upload/ part...
|
||||
auto UUIDLocation = Request.getURI().find_first_of(URI_BASE);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class FileUploader : public SubSystemServer {
|
||||
public:
|
||||
@@ -36,6 +36,8 @@ namespace uCentral {
|
||||
return instance_;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline uint64_t MaxSize() const { return MaxSize_; }
|
||||
|
||||
private:
|
||||
static FileUploader *instance_;
|
||||
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> Servers_;
|
||||
@@ -43,6 +45,7 @@ namespace uCentral {
|
||||
std::string FullName_;
|
||||
std::map<std::string,uint64_t> OutStandingUploads_;
|
||||
std::string Path_;
|
||||
uint64_t MaxSize_=10000000;
|
||||
|
||||
explicit FileUploader() noexcept:
|
||||
SubSystemServer("FileUploader", "FILE-UPLOAD", "ucentral.fileuploader")
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "Daemon.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class KafkaManager *KafkaManager::instance_ = nullptr;
|
||||
|
||||
|
||||
@@ -13,11 +13,11 @@
|
||||
#include <thread>
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
#include "uCentralTypes.h"
|
||||
#include "OpenWifiTypes.h"
|
||||
|
||||
#include "cppkafka/cppkafka.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class KafkaManager : public SubSystemServer {
|
||||
public:
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#ifndef UCENTRALGW_KAFKA_TOPICS_H
|
||||
#define UCENTRALGW_KAFKA_TOPICS_H
|
||||
|
||||
namespace uCentral::KafkaTopics {
|
||||
namespace OpenWifi::KafkaTopics {
|
||||
static const std::string HEALTHCHECK{"healthcheck"};
|
||||
static const std::string STATE{"state"};
|
||||
static const std::string CONNECTION{"connection"};
|
||||
@@ -13,6 +13,7 @@ namespace uCentral::KafkaTopics {
|
||||
static const std::string ALERTS{"alerts"};
|
||||
static const std::string COMMAND{"command"};
|
||||
static const std::string SERVICE_EVENTS{"service_events"};
|
||||
static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"};
|
||||
|
||||
namespace ServiceEvents {
|
||||
static const std::string EVENT_JOIN{"join"};
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "AuthClient.h"
|
||||
#endif
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
void MyErrorHandler::exception(const Poco::Exception & E) {
|
||||
Poco::Thread * CurrentThread = Poco::Thread::current();
|
||||
@@ -112,6 +112,16 @@ namespace uCentral {
|
||||
} else {
|
||||
logger().error("Bad bus message.");
|
||||
}
|
||||
|
||||
auto i=Services_.begin();
|
||||
auto Now = (uint64_t )std::time(nullptr);
|
||||
for(;i!=Services_.end();) {
|
||||
if((Now - i->second.LastUpdate)>60) {
|
||||
i = Services_.erase(i);
|
||||
} else
|
||||
++i;
|
||||
}
|
||||
|
||||
} catch (const Poco::Exception &E) {
|
||||
logger().log(E);
|
||||
}
|
||||
|
||||
@@ -24,16 +24,16 @@
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Process.h"
|
||||
|
||||
#include "uCentralTypes.h"
|
||||
#include "OpenWifiTypes.h"
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
static const std::string uSERVICE_SECURITY{"ucentralsec"};
|
||||
static const std::string uSERVICE_GATEWAY{"ucentralgw"};
|
||||
static const std::string uSERVICE_FIRMWARE{ "ucentralfws"};
|
||||
static const std::string uSERVICE_TOPOLOGY{ "ucentraltopo"};
|
||||
static const std::string uSERVICE_PROVISIONING{ "ucentralprov"};
|
||||
static const std::string uSERVICE_FIRMWARE{ "ucentralfms"};
|
||||
static const std::string uSERVICE_TOPOLOGY{ "owtopo"};
|
||||
static const std::string uSERVICE_PROVISIONING{ "owprov"};
|
||||
|
||||
class MyErrorHandler : public Poco::ErrorHandler {
|
||||
public:
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class OUIServer * OUIServer::instance_;
|
||||
|
||||
int OUIServer::Start() {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class OUIServer : public SubSystemServer {
|
||||
public:
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "Utils.h"
|
||||
#include "Daemon.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
OpenAPIRequestGet::OpenAPIRequestGet( const std::string & ServiceType,
|
||||
const std::string & EndPoint,
|
||||
@@ -32,7 +32,7 @@ namespace uCentral {
|
||||
|
||||
int OpenAPIRequestGet::Do(Poco::JSON::Object::Ptr &ResponseObject) {
|
||||
try {
|
||||
auto Services = Daemon()->GetServices(Type_);
|
||||
auto Services = Daemon()->GetServices(Type_);
|
||||
for(auto const &Svc:Services) {
|
||||
Poco::URI URI(Svc.PrivateEndPoint);
|
||||
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
|
||||
@@ -42,7 +42,7 @@ namespace uCentral {
|
||||
URI.addQueryParameter(qp.first, qp.second);
|
||||
|
||||
std::string Path(URI.getPathAndQuery());
|
||||
Session.setTimeout(Poco::Timespan(5, 0));
|
||||
Session.setTimeout(Poco::Timespan(msTimeout_/1000, msTimeout_ % 1000));
|
||||
|
||||
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Path,
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
|
||||
#include "uCentralTypes.h"
|
||||
#include "OpenWifiTypes.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class OpenAPIRequestGet {
|
||||
public:
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
#include <utility>
|
||||
#include <queue>
|
||||
|
||||
namespace uCentral::Types {
|
||||
#include "Poco/StringTokenizer.h"
|
||||
|
||||
namespace OpenWifi::Types {
|
||||
typedef std::pair<std::string,std::string> StringPair;
|
||||
typedef std::vector<StringPair> StringPairVec;
|
||||
typedef std::queue<StringPair> StringPairQueue;
|
||||
@@ -28,12 +30,38 @@ namespace uCentral::Types {
|
||||
typedef std::map<std::string, TopicNotifyFunctionList> NotifyTable;
|
||||
typedef std::map<std::string,uint64_t> CountedMap;
|
||||
|
||||
inline void UpdateCountedMap(CountedMap &M, const std::string &S ) {
|
||||
typedef std::string UUID_t;
|
||||
typedef std::vector<UUID_t> UUIDvec_t;
|
||||
|
||||
inline void UpdateCountedMap(CountedMap &M, const std::string &S, uint64_t Increment=1) {
|
||||
auto it = M.find(S);
|
||||
if(it==M.end())
|
||||
M[S]=1;
|
||||
M[S] = Increment;
|
||||
else
|
||||
it->second += 1;
|
||||
it->second += Increment;
|
||||
}
|
||||
|
||||
inline std::string to_string( const StringVec &V) {
|
||||
std::string Result;
|
||||
|
||||
bool first=true;
|
||||
for(const auto &i:V) {
|
||||
if(first) {
|
||||
Result += i;
|
||||
first = false;
|
||||
} else {
|
||||
Result += ",";
|
||||
Result += i;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
inline void from_string(const std::string &S, StringVec &V) {
|
||||
Poco::StringTokenizer Tokens(S,",",Poco::StringTokenizer::TOK_TRIM | Poco::StringTokenizer::TOK_IGNORE_EMPTY);
|
||||
|
||||
for(auto const &i:Tokens)
|
||||
V.emplace_back(i);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "RESTAPI_protocol.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_BlackList::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace uCentral {
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
|
||||
try {
|
||||
auto SerialNumber = GetBinding(uCentral::RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
auto SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
if (!SerialNumber.empty()) {
|
||||
if (Storage()->DeleteBlackListDevice(SerialNumber)) {
|
||||
@@ -63,7 +63,10 @@ namespace uCentral {
|
||||
void RESTAPI_BlackList::DoGet(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
try {
|
||||
InitQueryBlock();
|
||||
if(!InitQueryBlock()) {
|
||||
BadRequest(Request, Response, "Illegal parameter value.");
|
||||
return;
|
||||
}
|
||||
std::vector<GWObjects::BlackListedDevice> Devices;
|
||||
|
||||
Poco::JSON::Array Objects;
|
||||
@@ -75,7 +78,7 @@ namespace uCentral {
|
||||
}
|
||||
}
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::DEVICES, Objects);
|
||||
RetObj.set(RESTAPI::Protocol::DEVICES, Objects);
|
||||
ReturnObject(Request, RetObj, Response);
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
@@ -91,18 +94,18 @@ namespace uCentral {
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (Obj->has(uCentral::RESTAPI::Protocol::DEVICES) &&
|
||||
Obj->isArray(uCentral::RESTAPI::Protocol::DEVICES)) {
|
||||
if (Obj->has(RESTAPI::Protocol::DEVICES) &&
|
||||
Obj->isArray(RESTAPI::Protocol::DEVICES)) {
|
||||
std::vector<GWObjects::BlackListedDevice> Devices;
|
||||
auto DeviceArray = Obj->getArray(uCentral::RESTAPI::Protocol::DEVICES);
|
||||
auto DeviceArray = Obj->getArray(RESTAPI::Protocol::DEVICES);
|
||||
for (const auto &i : *DeviceArray) {
|
||||
Poco::JSON::Parser pp;
|
||||
auto InnerObj = pp.parse(i).extract<Poco::JSON::Object::Ptr>();
|
||||
Poco::DynamicStruct Vars = *InnerObj;
|
||||
if (Vars.contains(uCentral::RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Vars.contains(uCentral::RESTAPI::Protocol::REASON)) {
|
||||
auto SerialNumber = Vars[uCentral::RESTAPI::Protocol::SERIALNUMBER].toString();
|
||||
auto Reason = Vars[uCentral::RESTAPI::Protocol::REASON].toString();
|
||||
if (Vars.contains(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Vars.contains(RESTAPI::Protocol::REASON)) {
|
||||
auto SerialNumber = Vars[RESTAPI::Protocol::SERIALNUMBER].toString();
|
||||
auto Reason = Vars[RESTAPI::Protocol::REASON].toString();
|
||||
GWObjects::BlackListedDevice D{.SerialNumber = SerialNumber,
|
||||
.Reason = Reason,
|
||||
.Author = UserInfo_.webtoken.username_,
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_BlackList : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_BlackList(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
|
||||
@@ -19,16 +19,16 @@
|
||||
#include "RESTAPI_utils.h"
|
||||
#include "Utils.h"
|
||||
|
||||
using uCentral::RESTAPI_utils::field_to_json;
|
||||
using uCentral::RESTAPI_utils::field_from_json;
|
||||
using uCentral::RESTAPI_utils::EmbedDocument;
|
||||
using OpenWifi::RESTAPI_utils::field_to_json;
|
||||
using OpenWifi::RESTAPI_utils::field_from_json;
|
||||
using OpenWifi::RESTAPI_utils::EmbedDocument;
|
||||
|
||||
namespace uCentral::GWObjects {
|
||||
namespace OpenWifi::GWObjects {
|
||||
|
||||
void Device::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"serialNumber", SerialNumber);
|
||||
#ifdef TIP_GATEWAY_SERVICE
|
||||
field_to_json(Obj,"deviceType", uCentral::Daemon::instance()->IdentifyDevice(Compatible));
|
||||
field_to_json(Obj,"deviceType", Daemon::instance()->IdentifyDevice(Compatible));
|
||||
#endif
|
||||
field_to_json(Obj,"macAddress", MACAddress);
|
||||
field_to_json(Obj,"manufacturer", Manufacturer);
|
||||
@@ -57,13 +57,15 @@ namespace uCentral::GWObjects {
|
||||
if (DeviceRegistry()->GetState(SerialNumber, ConState)) {
|
||||
ConState.to_json(Obj);
|
||||
} else {
|
||||
field_to_json(Obj,"ipAddress", "N/A");
|
||||
field_to_json(Obj,"ipAddress", "");
|
||||
field_to_json(Obj,"txBytes", (uint64_t) 0);
|
||||
field_to_json(Obj,"rxBytes", (uint64_t )0);
|
||||
field_to_json(Obj,"messageCount", (uint64_t )0);
|
||||
field_to_json(Obj,"connected", false);
|
||||
field_to_json(Obj,"lastContact", "N/A");
|
||||
field_to_json(Obj,"lastContact", "");
|
||||
field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE");
|
||||
field_to_json(Obj,"associations_2G", (uint64_t) 0);
|
||||
field_to_json(Obj,"associations_5G", (uint64_t) 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -176,6 +178,9 @@ namespace uCentral::GWObjects {
|
||||
field_to_json(Obj,"connected", Connected);
|
||||
field_to_json(Obj,"firmware", Firmware);
|
||||
field_to_json(Obj,"lastContact", LastContact);
|
||||
field_to_json(Obj,"associations_2G", Associations_2G);
|
||||
field_to_json(Obj,"associations_5G", Associations_5G);
|
||||
|
||||
switch(VerifiedCertificate) {
|
||||
case NO_CERTIFICATE:
|
||||
field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); break;
|
||||
@@ -216,6 +221,9 @@ namespace uCentral::GWObjects {
|
||||
field_to_json(Obj,"healths",healths);
|
||||
field_to_json(Obj,"certificates",certificates);
|
||||
field_to_json(Obj,"lastContact",lastContact);
|
||||
field_to_json(Obj,"associations",associations);
|
||||
field_to_json(Obj,"snapshot",snapshot);
|
||||
field_to_json(Obj,"numberOfDevices",numberOfDevices);
|
||||
}
|
||||
|
||||
void Dashboard::reset() {
|
||||
@@ -231,6 +239,9 @@ namespace uCentral::GWObjects {
|
||||
healths.clear();
|
||||
certificates.clear();
|
||||
lastContact.clear();
|
||||
associations.clear();
|
||||
numberOfDevices = 0 ;
|
||||
snapshot = std::time(nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "RESTAPI_SecurityObjects.h"
|
||||
|
||||
namespace uCentral::GWObjects {
|
||||
namespace OpenWifi::GWObjects {
|
||||
|
||||
enum CertificateValidation {
|
||||
NO_CERTIFICATE,
|
||||
@@ -24,10 +24,12 @@ namespace uCentral::GWObjects {
|
||||
struct ConnectionState {
|
||||
uint64_t MessageCount = 0 ;
|
||||
std::string SerialNumber;
|
||||
std::string Address = "N/A";
|
||||
std::string Address;
|
||||
uint64_t UUID = 0 ;
|
||||
uint64_t PendingUUID = 0 ;
|
||||
uint64_t TX = 0, RX = 0;
|
||||
uint64_t Associations_2G=0;
|
||||
uint64_t Associations_5G=0;
|
||||
bool Connected = false;
|
||||
uint64_t LastContact=0;
|
||||
std::string Firmware;
|
||||
@@ -159,6 +161,8 @@ namespace uCentral::GWObjects {
|
||||
};
|
||||
|
||||
struct Dashboard {
|
||||
uint64_t snapshot;
|
||||
uint64_t numberOfDevices;
|
||||
Types::CountedMap commands;
|
||||
Types::CountedMap upTimes;
|
||||
Types::CountedMap memoryUsed;
|
||||
@@ -171,6 +175,7 @@ namespace uCentral::GWObjects {
|
||||
Types::CountedMap healths;
|
||||
Types::CountedMap certificates;
|
||||
Types::CountedMap lastContact;
|
||||
Types::CountedMap associations;
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
void reset();
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "RESTAPI_ouis.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class RESTAPI_InternalServer *RESTAPI_InternalServer::instance_ = nullptr;
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace uCentral {
|
||||
|
||||
Poco::Net::HTTPRequestHandler *InternalRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest & Request) {
|
||||
|
||||
Logger_.debug(Poco::format("REQUEST(%s): %s %s", uCentral::Utils::FormatIPv6(Request.clientAddress().toString()), Request.getMethod(), Request.getURI()));
|
||||
Logger_.debug(Poco::format("REQUEST(%s): %s %s", Utils::FormatIPv6(Request.clientAddress().toString()), Request.getMethod(), Request.getURI()));
|
||||
|
||||
Poco::URI uri(Request.getURI());
|
||||
const auto & Path = uri.getPath();
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class RESTAPI_InternalServer : public SubSystemServer {
|
||||
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
#include "StorageService.h"
|
||||
#include "DeviceRegistry.h"
|
||||
#include "CommandManager.h"
|
||||
#include "uCentralProtocol.h"
|
||||
|
||||
namespace uCentral::RESTAPI_RPC {
|
||||
namespace OpenWifi::RESTAPI_RPC {
|
||||
void SetCommandAsPending(GWObjects::CommandDetails &Cmd,
|
||||
Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response, RESTAPIHandler *Handler) {
|
||||
@@ -70,6 +71,12 @@ namespace uCentral::RESTAPI_RPC {
|
||||
Cmd.Status = "completed";
|
||||
Cmd.Completed = time(nullptr);
|
||||
|
||||
if(Cmd.ErrorCode && Cmd.Command==uCentralProtocol::TRACE) {
|
||||
Cmd.WaitingForFile = 0;
|
||||
Cmd.AttachDate = Cmd.AttachSize = 0 ;
|
||||
Cmd.AttachType = "";
|
||||
}
|
||||
|
||||
// Add the completed command to the database...
|
||||
Storage()->AddCommand(Cmd.SerialNumber, Cmd,Storage::COMMAND_COMPLETED);
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace uCentral::RESTAPI_RPC {
|
||||
namespace OpenWifi::RESTAPI_RPC {
|
||||
|
||||
bool WaitForRPC(GWObjects::CommandDetails &Cmd,
|
||||
Poco::Net::HTTPServerRequest &Request,
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
#include "RESTAPI_SecurityObjects.h"
|
||||
#include "RESTAPI_utils.h"
|
||||
|
||||
using uCentral::RESTAPI_utils::field_to_json;
|
||||
using uCentral::RESTAPI_utils::field_from_json;
|
||||
using OpenWifi::RESTAPI_utils::field_to_json;
|
||||
using OpenWifi::RESTAPI_utils::field_from_json;
|
||||
|
||||
namespace uCentral::SecurityObjects {
|
||||
namespace OpenWifi::SecurityObjects {
|
||||
|
||||
void AclTemplate::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"Read",Read_);
|
||||
@@ -303,6 +303,20 @@ namespace uCentral::SecurityObjects {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool append_from_json(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes) {
|
||||
try {
|
||||
SecurityObjects::NoteInfoVec NIV;
|
||||
NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(Obj->get("notes").toString());
|
||||
for(auto const &i:NIV) {
|
||||
SecurityObjects::NoteInfo ii{.created=(uint64_t)std::time(nullptr), .createdBy=UInfo.email, .note=i.note};
|
||||
Notes.push_back(ii);
|
||||
}
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ProfileAction::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"resource", resource);
|
||||
field_to_json<ResourceAccessType>(Obj,"access", access, ResourceAccessTypeToString);
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
#define UCENTRAL_RESTAPI_SECURITYOBJECTS_H
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "uCentralTypes.h"
|
||||
#include "OpenWifiTypes.h"
|
||||
|
||||
namespace uCentral::SecurityObjects {
|
||||
namespace OpenWifi::SecurityObjects {
|
||||
|
||||
struct AclTemplate {
|
||||
bool Read_ = true;
|
||||
@@ -94,6 +94,8 @@ namespace uCentral::SecurityObjects {
|
||||
};
|
||||
typedef std::vector<UserInfo> UserInfoVec;
|
||||
|
||||
bool append_from_json(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes);
|
||||
|
||||
struct InternalServiceInfo {
|
||||
std::string privateURI;
|
||||
std::string publicURI;
|
||||
@@ -114,9 +116,9 @@ namespace uCentral::SecurityObjects {
|
||||
struct SystemEndpoint {
|
||||
std::string type;
|
||||
uint64_t id = 0;
|
||||
std::string vendor;
|
||||
std::string vendor{"OpenWiFi"};
|
||||
std::string uri;
|
||||
std::string authenticationType;
|
||||
std::string authenticationType{"internal_v1"};
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "RESTAPI_protocol.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_command::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
@@ -24,7 +24,7 @@ void RESTAPI_command::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
ParseParameters(Request);
|
||||
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
|
||||
auto CommandUUID = GetBinding(uCentral::RESTAPI::Protocol::COMMANDUUID, "");
|
||||
auto CommandUUID = GetBinding(RESTAPI::Protocol::COMMANDUUID, "");
|
||||
GWObjects::CommandDetails Command;
|
||||
if (Storage()->GetCommand(CommandUUID, Command)) {
|
||||
Poco::JSON::Object RetObj;
|
||||
@@ -33,7 +33,7 @@ void RESTAPI_command::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
} else
|
||||
NotFound(Request, Response);
|
||||
} else if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE) {
|
||||
auto CommandUUID = GetBinding(uCentral::RESTAPI::Protocol::COMMANDUUID, "");
|
||||
auto CommandUUID = GetBinding(RESTAPI::Protocol::COMMANDUUID, "");
|
||||
if (Storage()->DeleteCommand(CommandUUID)) {
|
||||
OK(Request, Response);
|
||||
} else {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_command : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "StorageService.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_commands::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
@@ -22,9 +22,12 @@ void RESTAPI_commands::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
|
||||
try {
|
||||
ParseParameters(Request);
|
||||
InitQueryBlock();
|
||||
if(!InitQueryBlock()) {
|
||||
BadRequest(Request, Response, "Illegal parameter value.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto SerialNumber = GetParameter(uCentral::RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
auto SerialNumber = GetParameter(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
|
||||
std::vector<GWObjects::CommandDetails> Commands;
|
||||
@@ -41,7 +44,7 @@ void RESTAPI_commands::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
ArrayObj.add(Obj);
|
||||
}
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::COMMANDS, ArrayObj);
|
||||
RetObj.set(RESTAPI::Protocol::COMMANDS, ArrayObj);
|
||||
ReturnObject(Request, RetObj, Response);
|
||||
return;
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_commands : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_commands(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#include "RESTAPI_protocol.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_default_configuration::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
@@ -23,7 +23,7 @@ void RESTAPI_default_configuration::handleRequest(Poco::Net::HTTPServerRequest &
|
||||
if (!IsAuthorized(Request, Response))
|
||||
return;
|
||||
|
||||
std::string Name = GetBinding(uCentral::RESTAPI::Protocol::NAME, "");
|
||||
std::string Name = GetBinding(RESTAPI::Protocol::NAME, "");
|
||||
ParseParameters(Request);
|
||||
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_default_configuration : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_default_configuration(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
|
||||
@@ -13,45 +13,49 @@
|
||||
#include "RESTAPI_protocol.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace uCentral {
|
||||
void RESTAPI_default_configurations::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
return;
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_default_configurations::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
return;
|
||||
|
||||
if (!IsAuthorized(Request, Response))
|
||||
return;
|
||||
if (!IsAuthorized(Request, Response))
|
||||
return;
|
||||
|
||||
try {
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
|
||||
ParseParameters(Request);
|
||||
InitQueryBlock();
|
||||
try {
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
|
||||
ParseParameters(Request);
|
||||
if(!InitQueryBlock()) {
|
||||
BadRequest(Request, Response, "Illegal parameter value.");
|
||||
return;
|
||||
}
|
||||
|
||||
Logger_.information(
|
||||
Poco::format("DEFAULT_CONFIGURATIONS: from %Lu, limit of %Lu, filter=%s.",
|
||||
(int64_t)QB_.Offset, (int64_t)QB_.Limit, QB_.Filter));
|
||||
RESTAPIHandler::PrintBindings();
|
||||
Logger_.information(
|
||||
Poco::format("DEFAULT_CONFIGURATIONS: from %Lu, limit of %Lu, filter=%s.",
|
||||
(int64_t)QB_.Offset, (int64_t)QB_.Limit, QB_.Filter));
|
||||
RESTAPIHandler::PrintBindings();
|
||||
|
||||
std::vector<GWObjects::DefaultConfiguration> DefConfigs;
|
||||
std::vector<GWObjects::DefaultConfiguration> DefConfigs;
|
||||
|
||||
Storage()->GetDefaultConfigurations(QB_.Offset, QB_.Limit, DefConfigs);
|
||||
Storage()->GetDefaultConfigurations(QB_.Offset, QB_.Limit, DefConfigs);
|
||||
|
||||
Poco::JSON::Array Objects;
|
||||
for (const auto &i : DefConfigs) {
|
||||
Poco::JSON::Object Obj;
|
||||
i.to_json(Obj);
|
||||
Objects.add(Obj);
|
||||
}
|
||||
Poco::JSON::Array Objects;
|
||||
for (const auto &i : DefConfigs) {
|
||||
Poco::JSON::Object Obj;
|
||||
i.to_json(Obj);
|
||||
Objects.add(Obj);
|
||||
}
|
||||
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::CONFIGURATIONS, Objects);
|
||||
ReturnObject(Request, RetObj, Response);
|
||||
} else
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.warning(
|
||||
Poco::format("%s: Failed with: %s", std::string(__func__), E.displayText()));
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(RESTAPI::Protocol::CONFIGURATIONS, Objects);
|
||||
ReturnObject(Request, RetObj, Response);
|
||||
} else
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.warning(
|
||||
Poco::format("%s: Failed with: %s", std::string(__func__), E.displayText()));
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_default_configurations : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_default_configurations(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "Daemon.h"
|
||||
#include "Dashboard.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_deviceDashboardHandler::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
|
||||
@@ -18,7 +18,8 @@ namespace uCentral {
|
||||
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
|
||||
DoGet(Request, Response);
|
||||
BadRequest(Request, Response);
|
||||
} else {
|
||||
BadRequest(Request, Response, "Unsupported method.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_deviceDashboardHandler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_deviceDashboardHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include "KafkaManager.h"
|
||||
#include "Kafka_topics.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_device_commandHandler::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
@@ -40,14 +40,14 @@ void RESTAPI_device_commandHandler::handleRequest(Poco::Net::HTTPServerRequest &
|
||||
if (!IsAuthorized(Request, Response))
|
||||
return;
|
||||
|
||||
std::string Command = GetBinding(uCentral::RESTAPI::Protocol::COMMAND, "");
|
||||
std::string Command = GetBinding(RESTAPI::Protocol::COMMAND, "");
|
||||
if (Command.empty()) {
|
||||
Logger_.error(Poco::format("Unrecognized command '%s'", Command));
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
}
|
||||
|
||||
SerialNumber_ = GetBinding(uCentral::RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
SerialNumber_ = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
if (SerialNumber_.empty()) {
|
||||
Logger_.error(Poco::format("Missing serial number for command '%s'", Command));
|
||||
BadRequest(Request, Response);
|
||||
@@ -55,66 +55,69 @@ void RESTAPI_device_commandHandler::handleRequest(Poco::Net::HTTPServerRequest &
|
||||
}
|
||||
|
||||
ParseParameters(Request);
|
||||
InitQueryBlock();
|
||||
if(!InitQueryBlock()) {
|
||||
BadRequest(Request, Response, "Illegal parameter value.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command == uCentral::RESTAPI::Protocol::CAPABILITIES &&
|
||||
if (Command == RESTAPI::Protocol::CAPABILITIES &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_GET) {
|
||||
GetCapabilities(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::CAPABILITIES &&
|
||||
} else if (Command == RESTAPI::Protocol::CAPABILITIES &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_DELETE) {
|
||||
DeleteCapabilities(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::LOGS &&
|
||||
} else if (Command == RESTAPI::Protocol::LOGS &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_GET) {
|
||||
GetLogs(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::LOGS &&
|
||||
} else if (Command == RESTAPI::Protocol::LOGS &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_DELETE) {
|
||||
DeleteLogs(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::HEALTHCHECKS &&
|
||||
} else if (Command == RESTAPI::Protocol::HEALTHCHECKS &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_GET) {
|
||||
GetChecks(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::HEALTHCHECKS &&
|
||||
} else if (Command == RESTAPI::Protocol::HEALTHCHECKS &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_DELETE) {
|
||||
DeleteChecks(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::STATISTICS &&
|
||||
} else if (Command == RESTAPI::Protocol::STATISTICS &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_GET) {
|
||||
GetStatistics(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::STATISTICS &&
|
||||
} else if (Command == RESTAPI::Protocol::STATISTICS &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_DELETE) {
|
||||
DeleteStatistics(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::STATUS &&
|
||||
} else if (Command == RESTAPI::Protocol::STATUS &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_GET) {
|
||||
GetStatus(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::PERFORM &&
|
||||
} else if (Command == RESTAPI::Protocol::PERFORM &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_POST) {
|
||||
ExecuteCommand(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::CONFIGURE &&
|
||||
} else if (Command == RESTAPI::Protocol::CONFIGURE &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_POST) {
|
||||
Configure(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::UPGRADE &&
|
||||
} else if (Command == RESTAPI::Protocol::UPGRADE &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_POST) {
|
||||
Upgrade(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::REBOOT &&
|
||||
} else if (Command == RESTAPI::Protocol::REBOOT &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_POST) {
|
||||
Reboot(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::FACTORY &&
|
||||
} else if (Command == RESTAPI::Protocol::FACTORY &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_POST) {
|
||||
Factory(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::LEDS &&
|
||||
} else if (Command == RESTAPI::Protocol::LEDS &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_POST) {
|
||||
LEDs(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::TRACE &&
|
||||
} else if (Command == RESTAPI::Protocol::TRACE &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_POST) {
|
||||
Trace(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::REQUEST &&
|
||||
} else if (Command == RESTAPI::Protocol::REQUEST &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_POST) {
|
||||
MakeRequest(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::WIFISCAN &&
|
||||
} else if (Command == RESTAPI::Protocol::WIFISCAN &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_POST) {
|
||||
WifiScan(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::EVENTQUEUE &&
|
||||
} else if (Command == RESTAPI::Protocol::EVENTQUEUE &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_POST) {
|
||||
EventQueue(Request, Response);
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::RTTY &&
|
||||
} else if (Command == RESTAPI::Protocol::RTTY &&
|
||||
Request.getMethod() == Poco::Net::HTTPServerRequest::HTTP_GET) {
|
||||
Rtty(Request, Response);
|
||||
} else {
|
||||
@@ -122,7 +125,7 @@ void RESTAPI_device_commandHandler::handleRequest(Poco::Net::HTTPServerRequest &
|
||||
}
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -134,14 +137,14 @@ void RESTAPI_device_commandHandler::GetCapabilities(Poco::Net::HTTPServerRequest
|
||||
if (Storage()->GetDeviceCapabilities(SerialNumber_, Caps)) {
|
||||
Poco::JSON::Object RetObj;
|
||||
Caps.to_json(RetObj);
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
|
||||
RetObj.set(RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
|
||||
ReturnObject(Request, RetObj, Response);
|
||||
} else {
|
||||
NotFound(Request, Response);
|
||||
}
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -155,7 +158,7 @@ void RESTAPI_device_commandHandler::DeleteCapabilities(Poco::Net::HTTPServerRequ
|
||||
NotFound(Request, Response);
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -168,7 +171,7 @@ void RESTAPI_device_commandHandler::GetStatistics(Poco::Net::HTTPServerRequest &
|
||||
Storage()->GetLifetimeStats(SerialNumber_, Stats);
|
||||
Poco::JSON::Parser P;
|
||||
if (Stats.empty())
|
||||
Stats = uCentral::uCentralProtocol::EMPTY_JSON_DOC;
|
||||
Stats = uCentralProtocol::EMPTY_JSON_DOC;
|
||||
auto Obj = P.parse(Stats).extract<Poco::JSON::Object::Ptr>();
|
||||
ReturnObject(Request, *Obj, Response);
|
||||
} else if (QB_.LastOnly) {
|
||||
@@ -176,7 +179,7 @@ void RESTAPI_device_commandHandler::GetStatistics(Poco::Net::HTTPServerRequest &
|
||||
if (DeviceRegistry()->GetStatistics(SerialNumber_, Stats)) {
|
||||
Poco::JSON::Parser P;
|
||||
if (Stats.empty())
|
||||
Stats = uCentral::uCentralProtocol::EMPTY_JSON_DOC;
|
||||
Stats = uCentralProtocol::EMPTY_JSON_DOC;
|
||||
auto Obj = P.parse(Stats).extract<Poco::JSON::Object::Ptr>();
|
||||
ReturnObject(Request, *Obj, Response);
|
||||
} else {
|
||||
@@ -197,13 +200,13 @@ void RESTAPI_device_commandHandler::GetStatistics(Poco::Net::HTTPServerRequest &
|
||||
ArrayObj.add(Obj);
|
||||
}
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::DATA, ArrayObj);
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
|
||||
RetObj.set(RESTAPI::Protocol::DATA, ArrayObj);
|
||||
RetObj.set(RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
|
||||
ReturnObject(Request, RetObj, Response);
|
||||
}
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -227,7 +230,7 @@ void RESTAPI_device_commandHandler::DeleteStatistics(Poco::Net::HTTPServerReques
|
||||
}
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -246,7 +249,7 @@ void RESTAPI_device_commandHandler::GetStatus(Poco::Net::HTTPServerRequest &Requ
|
||||
}
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -258,19 +261,19 @@ void RESTAPI_device_commandHandler::Configure(Poco::Net::HTTPServerRequest &Requ
|
||||
Poco::JSON::Parser Parser;
|
||||
auto Obj = Parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (Obj->has(uCentral::RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Obj->has(uCentral::RESTAPI::Protocol::UUID) &&
|
||||
Obj->has(uCentral::RESTAPI::Protocol::CONFIGURATION)) {
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Obj->has(RESTAPI::Protocol::UUID) &&
|
||||
Obj->has(RESTAPI::Protocol::CONFIGURATION)) {
|
||||
|
||||
auto SNum = Obj->get(uCentral::RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
}
|
||||
|
||||
auto UUID = Obj->get(uCentral::RESTAPI::Protocol::UUID);
|
||||
auto Configuration = GetS(uCentral::RESTAPI::Protocol::CONFIGURATION, Obj,
|
||||
uCentral::uCentralProtocol::EMPTY_JSON_DOC);
|
||||
auto UUID = Obj->get(RESTAPI::Protocol::UUID);
|
||||
auto Configuration = GetS(RESTAPI::Protocol::CONFIGURATION, Obj,
|
||||
uCentralProtocol::EMPTY_JSON_DOC);
|
||||
auto When = GetWhen(Obj);
|
||||
|
||||
uint64_t NewUUID;
|
||||
@@ -283,17 +286,17 @@ void RESTAPI_device_commandHandler::Configure(Poco::Net::HTTPServerRequest &Requ
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = Daemon()->CreateUUID();
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentral::uCentralProtocol::CONFIGURE;
|
||||
Cmd.Command = uCentralProtocol::CONFIGURE;
|
||||
Cmd.RunAt = When;
|
||||
|
||||
uCentral::Config::Config Cfg(Configuration);
|
||||
Config::Config Cfg(Configuration);
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
Poco::JSON::Object CfgObj;
|
||||
Params.set(uCentral::uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentral::uCentralProtocol::UUID, NewUUID);
|
||||
Params.set(uCentral::uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentral::uCentralProtocol::CONFIG, Cfg.to_json());
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::UUID, NewUUID);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentralProtocol::CONFIG, Cfg.to_json());
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
@@ -305,7 +308,7 @@ void RESTAPI_device_commandHandler::Configure(Poco::Net::HTTPServerRequest &Requ
|
||||
}
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -316,16 +319,16 @@ void RESTAPI_device_commandHandler::Upgrade(Poco::Net::HTTPServerRequest &Reques
|
||||
Poco::JSON::Parser parser;
|
||||
auto Obj = parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (Obj->has(uCentral::RESTAPI::Protocol::URI) &&
|
||||
Obj->has(uCentral::RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
if (Obj->has(RESTAPI::Protocol::URI) &&
|
||||
Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
|
||||
auto SNum = Obj->get(uCentral::RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
}
|
||||
|
||||
auto URI = GetS(uCentral::RESTAPI::Protocol::URI, Obj);
|
||||
auto URI = GetS(RESTAPI::Protocol::URI, Obj);
|
||||
auto When = GetWhen(Obj);
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
@@ -333,14 +336,14 @@ void RESTAPI_device_commandHandler::Upgrade(Poco::Net::HTTPServerRequest &Reques
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = Daemon()->CreateUUID();
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentral::uCentralProtocol::UPGRADE;
|
||||
Cmd.Command = uCentralProtocol::UPGRADE;
|
||||
Cmd.RunAt = When;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentral::uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentral::uCentralProtocol::URI, URI);
|
||||
Params.set(uCentral::uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::URI, URI);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
@@ -350,7 +353,7 @@ void RESTAPI_device_commandHandler::Upgrade(Poco::Net::HTTPServerRequest &Reques
|
||||
return;
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -374,13 +377,13 @@ void RESTAPI_device_commandHandler::GetLogs(Poco::Net::HTTPServerRequest &Reques
|
||||
ArrayObj.add(Obj);
|
||||
}
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::VALUES, ArrayObj);
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
|
||||
RetObj.set(RESTAPI::Protocol::VALUES, ArrayObj);
|
||||
RetObj.set(RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
|
||||
ReturnObject(Request, RetObj, Response);
|
||||
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -394,7 +397,7 @@ void RESTAPI_device_commandHandler::DeleteLogs(Poco::Net::HTTPServerRequest &Req
|
||||
return;
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -429,13 +432,13 @@ void RESTAPI_device_commandHandler::GetChecks(Poco::Net::HTTPServerRequest &Requ
|
||||
}
|
||||
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::VALUES, ArrayObj);
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
|
||||
RetObj.set(RESTAPI::Protocol::VALUES, ArrayObj);
|
||||
RetObj.set(RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
|
||||
ReturnObject(Request, RetObj, Response);
|
||||
}
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -448,7 +451,7 @@ void RESTAPI_device_commandHandler::DeleteChecks(Poco::Net::HTTPServerRequest &R
|
||||
return;
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -460,18 +463,18 @@ void RESTAPI_device_commandHandler::ExecuteCommand(Poco::Net::HTTPServerRequest
|
||||
Poco::JSON::Parser parser;
|
||||
auto Obj = parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (Obj->has(uCentral::RESTAPI::Protocol::COMMAND) &&
|
||||
Obj->has(uCentral::RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Obj->has(uCentral::RESTAPI::Protocol::PAYLOAD)) {
|
||||
if (Obj->has(RESTAPI::Protocol::COMMAND) &&
|
||||
Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Obj->has(RESTAPI::Protocol::PAYLOAD)) {
|
||||
|
||||
auto SNum = Obj->get(uCentral::RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
}
|
||||
|
||||
auto Command = GetS(uCentral::RESTAPI::Protocol::COMMAND, Obj);
|
||||
auto Payload = GetS(uCentral::RESTAPI::Protocol::PAYLOAD, Obj);
|
||||
auto Command = GetS(RESTAPI::Protocol::COMMAND, Obj);
|
||||
auto Payload = GetS(RESTAPI::Protocol::PAYLOAD, Obj);
|
||||
auto When = GetWhen(Obj);
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
@@ -490,10 +493,10 @@ void RESTAPI_device_commandHandler::ExecuteCommand(Poco::Net::HTTPServerRequest
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentral::uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentral::uCentralProtocol::COMMAND, Command);
|
||||
Params.set(uCentral::uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentral::uCentralProtocol::PAYLOAD, PayloadObject);
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::COMMAND, Command);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentralProtocol::PAYLOAD, PayloadObject);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
@@ -503,7 +506,7 @@ void RESTAPI_device_commandHandler::ExecuteCommand(Poco::Net::HTTPServerRequest
|
||||
return;
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -515,8 +518,8 @@ void RESTAPI_device_commandHandler::Reboot(Poco::Net::HTTPServerRequest &Request
|
||||
Poco::JSON::Parser IncomingParser;
|
||||
auto Obj = IncomingParser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (Obj->has(uCentral::RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
auto SNum = Obj->get(uCentral::RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
@@ -527,13 +530,13 @@ void RESTAPI_device_commandHandler::Reboot(Poco::Net::HTTPServerRequest &Request
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = Daemon()->CreateUUID();
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentral::uCentralProtocol::REBOOT;
|
||||
Cmd.Command = uCentralProtocol::REBOOT;
|
||||
Cmd.RunAt = When;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentral::uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentral::uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
@@ -543,7 +546,7 @@ void RESTAPI_device_commandHandler::Reboot(Poco::Net::HTTPServerRequest &Request
|
||||
return;
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -556,17 +559,17 @@ void RESTAPI_device_commandHandler::Factory(Poco::Net::HTTPServerRequest &Reques
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (Obj->has(uCentral::RESTAPI::Protocol::KEEPREDIRECTOR) &&
|
||||
Obj->has(uCentral::RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
if (Obj->has(RESTAPI::Protocol::KEEPREDIRECTOR) &&
|
||||
Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
|
||||
auto SNum = Obj->get(uCentral::RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
|
||||
if (SerialNumber_ != SNum) {
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
}
|
||||
|
||||
auto KeepRedirector = GetB(uCentral::RESTAPI::Protocol::KEEPREDIRECTOR, Obj, true);
|
||||
auto KeepRedirector = GetB(RESTAPI::Protocol::KEEPREDIRECTOR, Obj, true);
|
||||
uint64_t When = GetWhen(Obj);
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
@@ -574,14 +577,14 @@ void RESTAPI_device_commandHandler::Factory(Poco::Net::HTTPServerRequest &Reques
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = Daemon()->CreateUUID();
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentral::uCentralProtocol::FACTORY;
|
||||
Cmd.Command = uCentralProtocol::FACTORY;
|
||||
Cmd.RunAt = When;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentral::uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentral::uCentralProtocol::KEEP_REDIRECTOR, KeepRedirector ? 1 : 0);
|
||||
Params.set(uCentral::uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::KEEP_REDIRECTOR, KeepRedirector ? 1 : 0);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
@@ -591,7 +594,7 @@ void RESTAPI_device_commandHandler::Factory(Poco::Net::HTTPServerRequest &Reques
|
||||
return;
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -603,26 +606,26 @@ void RESTAPI_device_commandHandler::LEDs(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (Obj->has(uCentral::uCentralProtocol::PATTERN) &&
|
||||
Obj->has(uCentral::RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
if (Obj->has(uCentralProtocol::PATTERN) &&
|
||||
Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
|
||||
auto SNum = Obj->get(uCentral::RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
}
|
||||
|
||||
auto Pattern =
|
||||
GetS(uCentral::uCentralProtocol::PATTERN, Obj, uCentral::uCentralProtocol::BLINK);
|
||||
if (Pattern != uCentral::uCentralProtocol::ON &&
|
||||
Pattern != uCentral::uCentralProtocol::OFF &&
|
||||
Pattern != uCentral::uCentralProtocol::BLINK) {
|
||||
GetS(uCentralProtocol::PATTERN, Obj, uCentralProtocol::BLINK);
|
||||
if (Pattern != uCentralProtocol::ON &&
|
||||
Pattern != uCentralProtocol::OFF &&
|
||||
Pattern != uCentralProtocol::BLINK) {
|
||||
Logger_.warning(Poco::format("LEDs(%s): Bad pattern", SerialNumber_));
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
}
|
||||
|
||||
auto Duration = Get(uCentral::uCentralProtocol::DURATION, Obj, 30);
|
||||
auto Duration = Get(uCentralProtocol::DURATION, Obj, 30);
|
||||
auto When = GetWhen(Obj);
|
||||
Logger_.information(Poco::format("LEDS(%s): Pattern:%s Duration: %Lu", SerialNumber_,
|
||||
Pattern, Duration));
|
||||
@@ -632,14 +635,14 @@ void RESTAPI_device_commandHandler::LEDs(Poco::Net::HTTPServerRequest &Request,
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = Daemon()->CreateUUID();
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentral::uCentralProtocol::LEDS;
|
||||
Cmd.Command = uCentralProtocol::LEDS;
|
||||
Cmd.RunAt = When;
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentral::uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentral::uCentralProtocol::DURATION, Duration);
|
||||
Params.set(uCentral::uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentral::uCentralProtocol::PATTERN, Pattern);
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::DURATION, Duration);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentralProtocol::PATTERN, Pattern);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
@@ -649,7 +652,7 @@ void RESTAPI_device_commandHandler::LEDs(Poco::Net::HTTPServerRequest &Request,
|
||||
return;
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -661,22 +664,22 @@ void RESTAPI_device_commandHandler::Trace(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (Obj->has(uCentral::RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
(Obj->has(uCentral::RESTAPI::Protocol::NETWORK) ||
|
||||
Obj->has(uCentral::RESTAPI::Protocol::INTERFACE))) {
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
(Obj->has(RESTAPI::Protocol::NETWORK) ||
|
||||
Obj->has(RESTAPI::Protocol::INTERFACE))) {
|
||||
|
||||
auto SNum = Obj->get(uCentral::RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
BadRequest(Request, Response);
|
||||
BadRequest(Request, Response, "Missing serial number.");
|
||||
return;
|
||||
}
|
||||
|
||||
auto Duration = Get(uCentral::RESTAPI::Protocol::DURATION, Obj);
|
||||
auto Duration = Get(RESTAPI::Protocol::DURATION, Obj, 30);
|
||||
auto When = GetWhen(Obj);
|
||||
auto NumberOfPackets = Get(uCentral::RESTAPI::Protocol::NUMBEROFPACKETS, Obj);
|
||||
auto NumberOfPackets = Get(RESTAPI::Protocol::NUMBEROFPACKETS, Obj, 100);
|
||||
|
||||
auto Network = GetS(uCentral::RESTAPI::Protocol::NETWORK, Obj);
|
||||
auto Interface = GetS(uCentral::RESTAPI::Protocol::INTERFACE, Obj);
|
||||
auto Network = GetS(RESTAPI::Protocol::NETWORK, Obj);
|
||||
auto Interface = GetS(RESTAPI::Protocol::INTERFACE, Obj);
|
||||
auto UUID = Daemon()->CreateUUID();
|
||||
auto URI = FileUploader()->FullName() + UUID;
|
||||
|
||||
@@ -684,31 +687,33 @@ void RESTAPI_device_commandHandler::Trace(Poco::Net::HTTPServerRequest &Request,
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = UUID;
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentral::uCentralProtocol::TRACE;
|
||||
Cmd.Command = uCentralProtocol::TRACE;
|
||||
Cmd.RunAt = When;
|
||||
Cmd.WaitingForFile = 1;
|
||||
Cmd.AttachType = uCentral::RESTAPI::Protocol::PCAP_FILE_TYPE;
|
||||
Cmd.AttachType = RESTAPI::Protocol::PCAP_FILE_TYPE;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentral::uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentral::uCentralProtocol::DURATION, Duration);
|
||||
Params.set(uCentral::uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentral::uCentralProtocol::PACKETS, NumberOfPackets);
|
||||
Params.set(uCentral::uCentralProtocol::NETWORK, Network);
|
||||
Params.set(uCentral::uCentralProtocol::INTERFACE, Interface);
|
||||
Params.set(uCentral::uCentralProtocol::URI, URI);
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::DURATION, Duration);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentralProtocol::PACKETS, NumberOfPackets);
|
||||
Params.set(uCentralProtocol::NETWORK, Network);
|
||||
Params.set(uCentralProtocol::INTERFACE, Interface);
|
||||
Params.set(uCentralProtocol::URI, URI);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
FileUploader()->AddUUID(UUID);
|
||||
RESTAPI_RPC::WaitForCommand(Cmd, Params, Request, Response, std::chrono::milliseconds(3000), nullptr, this);
|
||||
return;
|
||||
RESTAPI_RPC::WaitForCommand(Cmd, Params, Request, Response, std::chrono::milliseconds(5000), nullptr, this);
|
||||
} else {
|
||||
BadRequest(Request, Response, "Missing SerialNumber, Network, or Interface.");
|
||||
}
|
||||
return;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -721,62 +726,64 @@ void RESTAPI_device_commandHandler::WifiScan(Poco::Net::HTTPServerRequest &Reque
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
auto SNum = Obj->get(uCentral::RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((Obj->has(uCentral::RESTAPI::Protocol::BANDS) &&
|
||||
Obj->isArray(uCentral::RESTAPI::Protocol::BANDS) ||
|
||||
(Obj->has(uCentral::RESTAPI::Protocol::CHANNELS) &&
|
||||
Obj->isArray(uCentral::RESTAPI::Protocol::CHANNELS)) ||
|
||||
(!Obj->has(uCentral::RESTAPI::Protocol::BANDS) &&
|
||||
!Obj->has(uCentral::RESTAPI::Protocol::CHANNELS)))) {
|
||||
bool Verbose = GetB(uCentral::RESTAPI::Protocol::VERBOSE, Obj);
|
||||
if ((Obj->has(RESTAPI::Protocol::BANDS) &&
|
||||
Obj->isArray(RESTAPI::Protocol::BANDS) ||
|
||||
(Obj->has(RESTAPI::Protocol::CHANNELS) &&
|
||||
Obj->isArray(RESTAPI::Protocol::CHANNELS)) ||
|
||||
(!Obj->has(RESTAPI::Protocol::BANDS) &&
|
||||
!Obj->has(RESTAPI::Protocol::CHANNELS)))) {
|
||||
bool Verbose = GetB(RESTAPI::Protocol::VERBOSE, Obj);
|
||||
auto UUID = Daemon()->CreateUUID();
|
||||
GWObjects::CommandDetails Cmd;
|
||||
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = UUID;
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentral::uCentralProtocol::WIFISCAN;
|
||||
Cmd.Command = uCentralProtocol::WIFISCAN;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentral::uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentral::uCentralProtocol::VERBOSE, Verbose);
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::VERBOSE, Verbose);
|
||||
|
||||
if (Obj->has(uCentral::uCentralProtocol::BANDS)) {
|
||||
Params.set(uCentral::uCentralProtocol::BANDS,
|
||||
Obj->get(uCentral::RESTAPI::Protocol::BANDS));
|
||||
} else if (Obj->has(uCentral::uCentralProtocol::CHANNELS)) {
|
||||
Params.set(uCentral::uCentralProtocol::CHANNELS,
|
||||
Obj->get(uCentral::RESTAPI::Protocol::CHANNELS));
|
||||
if (Obj->has(uCentralProtocol::BANDS)) {
|
||||
Params.set(uCentralProtocol::BANDS,
|
||||
Obj->get(RESTAPI::Protocol::BANDS));
|
||||
} else if (Obj->has(uCentralProtocol::CHANNELS)) {
|
||||
Params.set(uCentralProtocol::CHANNELS,
|
||||
Obj->get(RESTAPI::Protocol::CHANNELS));
|
||||
}
|
||||
|
||||
if (Obj->has(uCentral::RESTAPI::Protocol::ACTIVESCAN)) {
|
||||
if (Obj->has(RESTAPI::Protocol::ACTIVESCAN)) {
|
||||
Params.set(
|
||||
uCentral::uCentralProtocol::ACTIVE,
|
||||
(int)(Obj->get(uCentral::RESTAPI::Protocol::ACTIVESCAN).toString() == "true")
|
||||
uCentralProtocol::ACTIVE,
|
||||
(int)(Obj->get(RESTAPI::Protocol::ACTIVESCAN).toString() == "true")
|
||||
? 1
|
||||
: 0);
|
||||
} else {
|
||||
Params.set(uCentral::uCentralProtocol::ACTIVE, 0);
|
||||
Params.set(uCentralProtocol::ACTIVE, 0);
|
||||
}
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
RESTAPI_RPC::WaitForCommand(Cmd, Params, Request, Response, std::chrono::milliseconds(20000), nullptr, this);
|
||||
KafkaManager()->PostMessage(uCentral::KafkaTopics::WIFISCAN, SerialNumber_,
|
||||
Cmd.Results);
|
||||
if(Cmd.ErrorCode==0) {
|
||||
KafkaManager()->PostMessage(KafkaTopics::WIFISCAN, SerialNumber_,
|
||||
Cmd.Results);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -789,11 +796,11 @@ void RESTAPI_device_commandHandler::EventQueue(Poco::Net::HTTPServerRequest &Req
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (Obj->has(uCentral::RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Obj->has(uCentral::RESTAPI::Protocol::TYPES) &&
|
||||
Obj->isArray(uCentral::RESTAPI::Protocol::TYPES)) {
|
||||
auto SNum = Obj->get(uCentral::RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
auto Types = Obj->getArray(uCentral::RESTAPI::Protocol::TYPES);
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Obj->isArray(RESTAPI::Protocol::TYPES)) {
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
auto Types = Obj->getArray(RESTAPI::Protocol::TYPES);
|
||||
|
||||
if (SerialNumber_ == SNum) {
|
||||
auto UUID = Daemon()->CreateUUID();
|
||||
@@ -802,23 +809,26 @@ void RESTAPI_device_commandHandler::EventQueue(Poco::Net::HTTPServerRequest &Req
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = UUID;
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.Command = uCentral::uCentralProtocol::EVENT;
|
||||
Cmd.Command = uCentralProtocol::EVENT;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentral::uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentral::uCentralProtocol::TYPES, Types);
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::TYPES, Types);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
RESTAPI_RPC::WaitForCommand(Cmd, Params, Request, Response, std::chrono::milliseconds(20000), nullptr, this);
|
||||
if(Cmd.ErrorCode==0) {
|
||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, SerialNumber_,
|
||||
Cmd.Results);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -831,15 +841,15 @@ void RESTAPI_device_commandHandler::MakeRequest(Poco::Net::HTTPServerRequest &Re
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (Obj->has(uCentral::RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Obj->has(uCentral::uCentralProtocol::MESSAGE)) {
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Obj->has(uCentralProtocol::MESSAGE)) {
|
||||
|
||||
auto SNum = GetS(uCentral::RESTAPI::Protocol::SERIALNUMBER, Obj);
|
||||
auto MessageType = GetS(uCentral::uCentralProtocol::MESSAGE, Obj);
|
||||
auto SNum = GetS(RESTAPI::Protocol::SERIALNUMBER, Obj);
|
||||
auto MessageType = GetS(uCentralProtocol::MESSAGE, Obj);
|
||||
|
||||
if ((SerialNumber_ != SNum) ||
|
||||
(MessageType != uCentral::uCentralProtocol::STATE &&
|
||||
MessageType != uCentral::uCentralProtocol::HEALTHCHECK)) {
|
||||
(MessageType != uCentralProtocol::STATE &&
|
||||
MessageType != uCentralProtocol::HEALTHCHECK)) {
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
}
|
||||
@@ -850,15 +860,15 @@ void RESTAPI_device_commandHandler::MakeRequest(Poco::Net::HTTPServerRequest &Re
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.UUID = Daemon()->CreateUUID();
|
||||
Cmd.Command = uCentral::uCentralProtocol::REQUEST;
|
||||
Cmd.Command = uCentralProtocol::REQUEST;
|
||||
Cmd.RunAt = When;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentral::uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentral::uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentral::uCentralProtocol::MESSAGE, MessageType);
|
||||
Params.set(uCentral::uCentralProtocol::REQUEST_UUID, Cmd.UUID);
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentralProtocol::MESSAGE, MessageType);
|
||||
Params.set(uCentralProtocol::REQUEST_UUID, Cmd.UUID);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
@@ -868,7 +878,7 @@ void RESTAPI_device_commandHandler::MakeRequest(Poco::Net::HTTPServerRequest &Re
|
||||
return;
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
@@ -879,7 +889,7 @@ void RESTAPI_device_commandHandler::Rtty(Poco::Net::HTTPServerRequest &Request,
|
||||
if (Daemon()->ConfigGetString("rtty.enabled", "false") == "true") {
|
||||
GWObjects::Device Device;
|
||||
if (Storage()->GetDevice(SerialNumber_, Device)) {
|
||||
auto CommandUUID = uCentral::Daemon::instance()->CreateUUID();
|
||||
auto CommandUUID = Daemon::instance()->CreateUUID();
|
||||
|
||||
GWObjects::RttySessionDetails Rtty{
|
||||
.SerialNumber = SerialNumber_,
|
||||
@@ -902,19 +912,19 @@ void RESTAPI_device_commandHandler::Rtty(Poco::Net::HTTPServerRequest &Request,
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.SubmittedBy = UserInfo_.webtoken.username_;
|
||||
Cmd.UUID = CommandUUID;
|
||||
Cmd.Command = uCentral::uCentralProtocol::RTTY;
|
||||
Cmd.Command = uCentralProtocol::RTTY;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentral::uCentralProtocol::METHOD, uCentral::uCentralProtocol::RTTY);
|
||||
Params.set(uCentral::uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentral::uCentralProtocol::ID, Rtty.ConnectionId);
|
||||
Params.set(uCentral::uCentralProtocol::TOKEN, Rtty.Token);
|
||||
Params.set(uCentral::uCentralProtocol::SERVER, Rtty.Server);
|
||||
Params.set(uCentral::uCentralProtocol::PORT, Rtty.Port);
|
||||
Params.set(uCentral::uCentralProtocol::USER, UserInfo_.webtoken.username_);
|
||||
Params.set(uCentral::uCentralProtocol::TIMEOUT, Rtty.TimeOut);
|
||||
Params.set(uCentral::uCentralProtocol::PASSWORD, Device.DevicePassword);
|
||||
Params.set(uCentralProtocol::METHOD, uCentralProtocol::RTTY);
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::ID, Rtty.ConnectionId);
|
||||
Params.set(uCentralProtocol::TOKEN, Rtty.Token);
|
||||
Params.set(uCentralProtocol::SERVER, Rtty.Server);
|
||||
Params.set(uCentralProtocol::PORT, Rtty.Port);
|
||||
Params.set(uCentralProtocol::USER, UserInfo_.webtoken.username_);
|
||||
Params.set(uCentralProtocol::TIMEOUT, Rtty.TimeOut);
|
||||
Params.set(uCentralProtocol::PASSWORD, Device.DevicePassword);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
@@ -930,7 +940,7 @@ void RESTAPI_device_commandHandler::Rtty(Poco::Net::HTTPServerRequest &Request,
|
||||
return;
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_device_commandHandler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_device_commandHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "StorageService.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_device_handler::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
@@ -23,7 +23,7 @@ void RESTAPI_device_handler::handleRequest(Poco::Net::HTTPServerRequest &Request
|
||||
|
||||
ParseParameters(Request);
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
|
||||
std::string SerialNumber = GetBinding(uCentral::RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
GWObjects::Device Device;
|
||||
|
||||
if (Storage()->GetDevice(SerialNumber, Device)) {
|
||||
@@ -34,7 +34,7 @@ void RESTAPI_device_handler::handleRequest(Poco::Net::HTTPServerRequest &Request
|
||||
NotFound(Request, Response);
|
||||
}
|
||||
} else if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE) {
|
||||
std::string SerialNumber = GetBinding(uCentral::RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
if (Storage()->DeleteDevice(SerialNumber)) {
|
||||
OK(Request, Response);
|
||||
@@ -42,7 +42,7 @@ void RESTAPI_device_handler::handleRequest(Poco::Net::HTTPServerRequest &Request
|
||||
NotFound(Request, Response);
|
||||
}
|
||||
} else if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST) {
|
||||
std::string SerialNumber = GetBinding(uCentral::RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
Poco::JSON::Parser IncomingParser;
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
@@ -57,7 +57,7 @@ void RESTAPI_device_handler::handleRequest(Poco::Net::HTTPServerRequest &Request
|
||||
for(auto &i:Device.Notes)
|
||||
i.createdBy = UserInfo_.userinfo.email;
|
||||
|
||||
if (!uCentral::Utils::ValidSerialNumber(Device.SerialNumber)) {
|
||||
if (!Utils::ValidSerialNumber(Device.SerialNumber)) {
|
||||
Logger_.warning(Poco::format("CREATE-DEVICE(%s): Illegal name.", Device.SerialNumber));
|
||||
BadRequest(Request, Response);
|
||||
return;
|
||||
@@ -74,7 +74,7 @@ void RESTAPI_device_handler::handleRequest(Poco::Net::HTTPServerRequest &Request
|
||||
BadRequest(Request, Response);
|
||||
}
|
||||
} else if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_PUT) {
|
||||
std::string SerialNumber = GetBinding(uCentral::RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
Poco::JSON::Parser IncomingParser;
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
|
||||
@@ -10,11 +10,10 @@
|
||||
#define UCENTRAL_RESTAPI_DEVICEHANDLER_H
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_device_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_device_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
#include "Utils.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_devices_handler::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
|
||||
@@ -29,11 +29,14 @@ namespace uCentral {
|
||||
try {
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
|
||||
ParseParameters(Request);
|
||||
InitQueryBlock();
|
||||
auto serialOnly = GetBoolParameter(uCentral::RESTAPI::Protocol::SERIALONLY, false);
|
||||
auto countOnly = GetBoolParameter(uCentral::RESTAPI::Protocol::COUNTONLY, false);
|
||||
if(!InitQueryBlock()) {
|
||||
BadRequest(Request, Response, "Illegal parameter value.");
|
||||
return;
|
||||
}
|
||||
auto serialOnly = GetBoolParameter(RESTAPI::Protocol::SERIALONLY, false);
|
||||
auto countOnly = GetBoolParameter(RESTAPI::Protocol::COUNTONLY, false);
|
||||
auto deviceWithStatus =
|
||||
GetBoolParameter(uCentral::RESTAPI::Protocol::DEVICEWITHSTATUS, false);
|
||||
GetBoolParameter(RESTAPI::Protocol::DEVICEWITHSTATUS, false);
|
||||
|
||||
Logger_.debug(Poco::format("DEVICES: from %Lu, limit of %Lu, filter='%s'.",
|
||||
(uint64_t)QB_.Offset, (uint64_t)QB_.Limit, QB_.Filter));
|
||||
@@ -45,7 +48,7 @@ namespace uCentral {
|
||||
if (!QB_.Select.empty()) {
|
||||
|
||||
Poco::JSON::Array Objects;
|
||||
std::vector<std::string> Numbers = uCentral::Utils::Split(QB_.Select);
|
||||
std::vector<std::string> Numbers = Utils::Split(QB_.Select);
|
||||
for (auto &i : Numbers) {
|
||||
GWObjects::Device D;
|
||||
if (Storage()->GetDevice(i, D)) {
|
||||
@@ -62,14 +65,14 @@ namespace uCentral {
|
||||
}
|
||||
|
||||
if (deviceWithStatus)
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::DEVICESWITHSTATUS, Objects);
|
||||
RetObj.set(RESTAPI::Protocol::DEVICESWITHSTATUS, Objects);
|
||||
else
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::DEVICES, Objects);
|
||||
RetObj.set(RESTAPI::Protocol::DEVICES, Objects);
|
||||
|
||||
} else if (countOnly == true) {
|
||||
uint64_t Count = 0;
|
||||
if (Storage()->GetDeviceCount(Count)) {
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::COUNT, Count);
|
||||
RetObj.set(RESTAPI::Protocol::COUNT, Count);
|
||||
}
|
||||
} else if (serialOnly) {
|
||||
std::vector<std::string> SerialNumbers;
|
||||
@@ -78,7 +81,7 @@ namespace uCentral {
|
||||
for (const auto &i : SerialNumbers) {
|
||||
Objects.add(i);
|
||||
}
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::SERIALNUMBERS, Objects);
|
||||
RetObj.set(RESTAPI::Protocol::SERIALNUMBERS, Objects);
|
||||
} else {
|
||||
std::vector<GWObjects::Device> Devices;
|
||||
Storage()->GetDevices(QB_.Offset, QB_.Limit, Devices);
|
||||
@@ -92,9 +95,9 @@ namespace uCentral {
|
||||
Objects.add(Obj);
|
||||
}
|
||||
if (deviceWithStatus)
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::DEVICESWITHSTATUS, Objects);
|
||||
RetObj.set(RESTAPI::Protocol::DEVICESWITHSTATUS, Objects);
|
||||
else
|
||||
RetObj.set(uCentral::RESTAPI::Protocol::DEVICES, Objects);
|
||||
RetObj.set(RESTAPI::Protocol::DEVICES, Objects);
|
||||
}
|
||||
ReturnObject(Request, RetObj, Response);
|
||||
return;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_devices_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_devices_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <fstream>
|
||||
#include "RESTAPI_protocol.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_file::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
@@ -28,8 +28,8 @@ namespace uCentral {
|
||||
ParseParameters(Request);
|
||||
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
|
||||
auto UUID = GetBinding(uCentral::RESTAPI::Protocol::FILEUUID, "");
|
||||
auto SerialNumber = GetParameter(uCentral::RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
auto UUID = GetBinding(RESTAPI::Protocol::FILEUUID, "");
|
||||
auto SerialNumber = GetParameter(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
|
||||
// does the file exist
|
||||
Poco::File DownloadFile(FileUploader()->Path() + "/" + UUID);
|
||||
@@ -45,7 +45,7 @@ namespace uCentral {
|
||||
return;
|
||||
|
||||
} else if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE) {
|
||||
auto UUID = GetBinding(uCentral::RESTAPI::Protocol::FILEUUID, "");
|
||||
auto UUID = GetBinding(RESTAPI::Protocol::FILEUUID, "");
|
||||
|
||||
if (UUID.empty()) {
|
||||
BadRequest(Request, Response);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_file : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_file(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
|
||||
@@ -27,16 +27,16 @@
|
||||
#include "Utils.h"
|
||||
#include "Daemon.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
bool RESTAPIHandler::ParseBindings(const std::string & Request, const std::list<const char *> & EndPoints, BindingMap &bindings) {
|
||||
std::string Param, Value;
|
||||
|
||||
bindings.clear();
|
||||
std::vector<std::string> PathItems = uCentral::Utils::Split(Request, '/');
|
||||
std::vector<std::string> PathItems = Utils::Split(Request, '/');
|
||||
|
||||
for(const auto &EndPoint:EndPoints) {
|
||||
std::vector<std::string> ParamItems = uCentral::Utils::Split(EndPoint, '/');
|
||||
std::vector<std::string> ParamItems = Utils::Split(EndPoint, '/');
|
||||
if (PathItems.size() != ParamItems.size())
|
||||
continue;
|
||||
|
||||
@@ -64,9 +64,9 @@ namespace uCentral {
|
||||
}
|
||||
|
||||
void RESTAPIHandler::ParseParameters(Poco::Net::HTTPServerRequest &request) {
|
||||
|
||||
Poco::URI uri(request.getURI());
|
||||
Parameters_ = uri.getQueryParameters();
|
||||
InitQueryBlock();
|
||||
}
|
||||
|
||||
static bool is_number(const std::string &s) {
|
||||
@@ -111,6 +111,26 @@ namespace uCentral {
|
||||
return Default;
|
||||
}
|
||||
|
||||
bool RESTAPIHandler::HasParameter(const std::string &Name, std::string &Value) {
|
||||
for (const auto &i : Parameters_) {
|
||||
if (i.first == Name) {
|
||||
Value = i.second;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RESTAPIHandler::HasParameter(const std::string &Name, uint64_t & Value) {
|
||||
for (const auto &i : Parameters_) {
|
||||
if (i.first == Name) {
|
||||
Value = std::stoi(i.second);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const std::string &RESTAPIHandler::GetBinding(const std::string &Name, const std::string &Default) {
|
||||
auto E = Bindings_.find(Poco::toLower(Name));
|
||||
if (E == Bindings_.end())
|
||||
@@ -364,18 +384,25 @@ namespace uCentral {
|
||||
Poco::JSON::Stringifier::stringify(Object, Answer);
|
||||
}
|
||||
|
||||
void RESTAPIHandler::InitQueryBlock() {
|
||||
QB_.SerialNumber = GetParameter(uCentral::RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
QB_.StartDate = GetParameter(uCentral::RESTAPI::Protocol::STARTDATE, 0);
|
||||
QB_.EndDate = GetParameter(uCentral::RESTAPI::Protocol::ENDDATE, 0);
|
||||
QB_.Offset = GetParameter(uCentral::RESTAPI::Protocol::OFFSET, 0);
|
||||
QB_.Limit = GetParameter(uCentral::RESTAPI::Protocol::LIMIT, 100);
|
||||
QB_.Filter = GetParameter(uCentral::RESTAPI::Protocol::FILTER, "");
|
||||
QB_.Select = GetParameter(uCentral::RESTAPI::Protocol::SELECT, "");
|
||||
QB_.Lifetime = GetBoolParameter(uCentral::RESTAPI::Protocol::LIFETIME,false);
|
||||
QB_.LogType = GetParameter(uCentral::RESTAPI::Protocol::LOGTYPE,0);
|
||||
QB_.LastOnly = GetBoolParameter(uCentral::RESTAPI::Protocol::LASTONLY,false);
|
||||
QB_.Newest = GetBoolParameter(uCentral::RESTAPI::Protocol::NEWEST,false);
|
||||
bool RESTAPIHandler::InitQueryBlock() {
|
||||
if(QueryBlockInitialized_)
|
||||
return true;
|
||||
QueryBlockInitialized_=true;
|
||||
QB_.SerialNumber = GetParameter(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
QB_.StartDate = GetParameter(RESTAPI::Protocol::STARTDATE, 0);
|
||||
QB_.EndDate = GetParameter(RESTAPI::Protocol::ENDDATE, 0);
|
||||
QB_.Offset = GetParameter(RESTAPI::Protocol::OFFSET, 1);
|
||||
QB_.Limit = GetParameter(RESTAPI::Protocol::LIMIT, 100);
|
||||
QB_.Filter = GetParameter(RESTAPI::Protocol::FILTER, "");
|
||||
QB_.Select = GetParameter(RESTAPI::Protocol::SELECT, "");
|
||||
QB_.Lifetime = GetBoolParameter(RESTAPI::Protocol::LIFETIME,false);
|
||||
QB_.LogType = GetParameter(RESTAPI::Protocol::LOGTYPE,0);
|
||||
QB_.LastOnly = GetBoolParameter(RESTAPI::Protocol::LASTONLY,false);
|
||||
QB_.Newest = GetBoolParameter(RESTAPI::Protocol::NEWEST,false);
|
||||
|
||||
if(QB_.Offset<1)
|
||||
QB_.Offset=1;
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] uint64_t RESTAPIHandler::Get(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, uint64_t Default){
|
||||
@@ -397,7 +424,7 @@ namespace uCentral {
|
||||
}
|
||||
|
||||
[[nodiscard]] uint64_t RESTAPIHandler::GetWhen(const Poco::JSON::Object::Ptr &Obj) {
|
||||
return RESTAPIHandler::Get(uCentral::RESTAPI::Protocol::WHEN, Obj);
|
||||
return RESTAPIHandler::Get(RESTAPI::Protocol::WHEN, Obj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "RESTAPI_SecurityObjects.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class RESTAPI_PartHandler: public Poco::Net::PartHandler
|
||||
{
|
||||
@@ -140,12 +140,14 @@ namespace uCentral {
|
||||
void SendFile(Poco::File & File, Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response);
|
||||
|
||||
const std::string &GetBinding(const std::string &Name, const std::string &Default);
|
||||
void InitQueryBlock();
|
||||
bool InitQueryBlock();
|
||||
|
||||
[[nodiscard]] static uint64_t Get(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, uint64_t Default=0);
|
||||
[[nodiscard]] static std::string GetS(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, const std::string & Default="");
|
||||
[[nodiscard]] static bool GetB(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, bool Default=false);
|
||||
[[nodiscard]] static uint64_t GetWhen(const Poco::JSON::Object::Ptr &Obj);
|
||||
bool HasParameter(const std::string &QueryParameter, std::string &Value);
|
||||
bool HasParameter(const std::string &QueryParameter, uint64_t & Value);
|
||||
|
||||
protected:
|
||||
BindingMap Bindings_;
|
||||
@@ -156,6 +158,7 @@ namespace uCentral {
|
||||
std::vector<std::string> Methods_;
|
||||
QueryBlock QB_;
|
||||
bool Internal_=false;
|
||||
bool QueryBlockInitialized_=false;
|
||||
};
|
||||
|
||||
class RESTAPI_UnknownRequestHandler : public RESTAPIHandler {
|
||||
@@ -166,7 +169,7 @@ namespace uCentral {
|
||||
Poco::Net::HTTPServerResponse &Response) override {
|
||||
if (!IsAuthorized(Request, Response))
|
||||
return;
|
||||
BadRequest(Request, Response);
|
||||
BadRequest(Request, Response, "Unknown API endpoint");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "Utils.h"
|
||||
#include "OUIServer.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_ouis::handleRequest(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
@@ -21,7 +21,7 @@ namespace uCentral {
|
||||
if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
|
||||
Poco::JSON::Array Objects;
|
||||
auto Select = GetParameter("macList","");
|
||||
std::vector<std::string> Macs = uCentral::Utils::Split(Select);
|
||||
std::vector<std::string> Macs = Utils::Split(Select);
|
||||
for (auto &i : Macs) {
|
||||
Poco::JSON::Object O;
|
||||
auto Manufacturer = OUIServer()->GetManufacturer(i);
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_ouis : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_ouis(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#ifndef UCENTRALGW_RESTAPI_PROTOCOL_H
|
||||
#define UCENTRALGW_RESTAPI_PROTOCOL_H
|
||||
|
||||
namespace uCentral::RESTAPI::Protocol {
|
||||
namespace OpenWifi::RESTAPI::Protocol {
|
||||
static const char * CAPABILITIES = "capabilities";
|
||||
static const char * LOGS = "logs";
|
||||
static const char * HEALTHCHECKS = "healthchecks";
|
||||
|
||||
@@ -24,8 +24,9 @@
|
||||
#include "RESTAPI_deviceDashboardHandler.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "RESTAPI_webSocketServer.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class RESTAPI_server *RESTAPI_server::instance_ = nullptr;
|
||||
|
||||
@@ -67,7 +68,7 @@ namespace uCentral {
|
||||
|
||||
Poco::Net::HTTPRequestHandler *RESTAPIServerRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest & Request) {
|
||||
|
||||
Logger_.debug(Poco::format("REQUEST(%s): %s %s", uCentral::Utils::FormatIPv6(Request.clientAddress().toString()), Request.getMethod(), Request.getURI()));
|
||||
Logger_.debug(Poco::format("REQUEST(%s): %s %s", Utils::FormatIPv6(Request.clientAddress().toString()), Request.getMethod(), Request.getURI()));
|
||||
|
||||
Poco::URI uri(Request.getURI());
|
||||
const auto & Path = uri.getPath();
|
||||
@@ -85,6 +86,7 @@ namespace uCentral {
|
||||
RESTAPI_file,
|
||||
RESTAPI_system_command,
|
||||
RESTAPI_deviceDashboardHandler,
|
||||
RESTAPI_webSocketServer,
|
||||
RESTAPI_BlackList>(Path,Bindings,Logger_);
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class RESTAPI_server : public SubSystemServer {
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "Daemon.h"
|
||||
#include "RESTAPI_protocol.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_system_command::handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) {
|
||||
|
||||
@@ -27,8 +27,8 @@ namespace uCentral {
|
||||
DoPost(Request, Response);
|
||||
else if(Request.getMethod()==Poco::Net::HTTPRequest::HTTP_GET)
|
||||
DoGet(Request, Response);
|
||||
|
||||
BadRequest(Request, Response);
|
||||
else
|
||||
BadRequest(Request, Response, "Unsupported method.");
|
||||
}
|
||||
|
||||
void RESTAPI_system_command::DoPost(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
|
||||
@@ -36,19 +36,19 @@ namespace uCentral {
|
||||
Poco::JSON::Parser parser;
|
||||
auto Obj = parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (Obj->has(uCentral::RESTAPI::Protocol::COMMAND)) {
|
||||
auto Command = Poco::toLower(Obj->get(uCentral::RESTAPI::Protocol::COMMAND).toString());
|
||||
if (Command == uCentral::RESTAPI::Protocol::SETLOGLEVEL) {
|
||||
if (Obj->has(uCentral::RESTAPI::Protocol::PARAMETERS) &&
|
||||
Obj->isArray(uCentral::RESTAPI::Protocol::PARAMETERS)) {
|
||||
auto ParametersBlock = Obj->getArray(uCentral::RESTAPI::Protocol::PARAMETERS);
|
||||
if (Obj->has(RESTAPI::Protocol::COMMAND)) {
|
||||
auto Command = Poco::toLower(Obj->get(RESTAPI::Protocol::COMMAND).toString());
|
||||
if (Command == RESTAPI::Protocol::SETLOGLEVEL) {
|
||||
if (Obj->has(RESTAPI::Protocol::PARAMETERS) &&
|
||||
Obj->isArray(RESTAPI::Protocol::PARAMETERS)) {
|
||||
auto ParametersBlock = Obj->getArray(RESTAPI::Protocol::PARAMETERS);
|
||||
for (const auto &i:*ParametersBlock) {
|
||||
Poco::JSON::Parser pp;
|
||||
auto InnerObj = pp.parse(i).extract<Poco::JSON::Object::Ptr>();
|
||||
if (InnerObj->has(uCentral::RESTAPI::Protocol::TAG) &&
|
||||
InnerObj->has(uCentral::RESTAPI::Protocol::VALUE)) {
|
||||
auto Name = GetS(uCentral::RESTAPI::Protocol::TAG, InnerObj);
|
||||
auto Value = GetS(uCentral::RESTAPI::Protocol::VALUE, InnerObj);
|
||||
if (InnerObj->has(RESTAPI::Protocol::TAG) &&
|
||||
InnerObj->has(RESTAPI::Protocol::VALUE)) {
|
||||
auto Name = GetS(RESTAPI::Protocol::TAG, InnerObj);
|
||||
auto Value = GetS(RESTAPI::Protocol::VALUE, InnerObj);
|
||||
Daemon()->SetSubsystemLogLevel(Name, Value);
|
||||
Logger_.information(Poco::format("Setting log level for %s at %s", Name, Value));
|
||||
}
|
||||
@@ -56,45 +56,45 @@ namespace uCentral {
|
||||
OK(Request, Response);
|
||||
return;
|
||||
}
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::GETLOGLEVELS) {
|
||||
} else if (Command == RESTAPI::Protocol::GETLOGLEVELS) {
|
||||
auto CurrentLogLevels = Daemon()->GetLogLevels();
|
||||
Poco::JSON::Object Result;
|
||||
Poco::JSON::Array Array;
|
||||
for(auto &[Name,Level]:CurrentLogLevels) {
|
||||
Poco::JSON::Object Pair;
|
||||
Pair.set( uCentral::RESTAPI::Protocol::TAG,Name);
|
||||
Pair.set(uCentral::RESTAPI::Protocol::VALUE,Level);
|
||||
Pair.set( RESTAPI::Protocol::TAG,Name);
|
||||
Pair.set(RESTAPI::Protocol::VALUE,Level);
|
||||
Array.add(Pair);
|
||||
}
|
||||
Result.set(uCentral::RESTAPI::Protocol::TAGLIST,Array);
|
||||
Result.set(RESTAPI::Protocol::TAGLIST,Array);
|
||||
ReturnObject(Request,Result,Response);
|
||||
return;
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::GETLOGLEVELNAMES) {
|
||||
} else if (Command == RESTAPI::Protocol::GETLOGLEVELNAMES) {
|
||||
Poco::JSON::Object Result;
|
||||
Poco::JSON::Array LevelNamesArray;
|
||||
const Types::StringVec & LevelNames = Daemon()->GetLogLevelNames();
|
||||
for(const auto &i:LevelNames)
|
||||
LevelNamesArray.add(i);
|
||||
Result.set(uCentral::RESTAPI::Protocol::LIST,LevelNamesArray);
|
||||
Result.set(RESTAPI::Protocol::LIST,LevelNamesArray);
|
||||
ReturnObject(Request,Result,Response);
|
||||
return;
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::GETSUBSYSTEMNAMES) {
|
||||
} else if (Command == RESTAPI::Protocol::GETSUBSYSTEMNAMES) {
|
||||
Poco::JSON::Object Result;
|
||||
Poco::JSON::Array LevelNamesArray;
|
||||
const Types::StringVec & SubSystemNames = Daemon()->GetSubSystems();
|
||||
for(const auto &i:SubSystemNames)
|
||||
LevelNamesArray.add(i);
|
||||
Result.set(uCentral::RESTAPI::Protocol::LIST,LevelNamesArray);
|
||||
Result.set(RESTAPI::Protocol::LIST,LevelNamesArray);
|
||||
ReturnObject(Request,Result,Response);
|
||||
return;
|
||||
} else if (Command == uCentral::RESTAPI::Protocol::STATS) {
|
||||
} else if (Command == RESTAPI::Protocol::STATS) {
|
||||
|
||||
}
|
||||
}
|
||||
} catch(const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
BadRequest(Request, Response, "Unsupported or missing parameters.");
|
||||
}
|
||||
|
||||
void RESTAPI_system_command::DoGet(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
|
||||
@@ -126,7 +126,7 @@ namespace uCentral {
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
BadRequest(Request, Response);
|
||||
BadRequest(Request, Response, "Unsupported or missing parameters.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_system_command : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_system_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "RESTAPI_utils.h"
|
||||
|
||||
namespace uCentral::RESTAPI_utils {
|
||||
namespace OpenWifi::RESTAPI_utils {
|
||||
|
||||
void EmbedDocument(const std::string & ObjName, Poco::JSON::Object & Obj, const std::string &ObjStr) {
|
||||
std::string D = ObjStr.empty() ? "{}" : ObjStr;
|
||||
|
||||
@@ -9,10 +9,10 @@
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "uCentralTypes.h"
|
||||
#include "OpenWifiTypes.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace uCentral::RESTAPI_utils {
|
||||
namespace OpenWifi::RESTAPI_utils {
|
||||
|
||||
void EmbedDocument(const std::string & ObjName, Poco::JSON::Object & Obj, const std::string &ObjStr);
|
||||
|
||||
|
||||
151
src/RESTAPI_webSocketServer.cpp
Normal file
151
src/RESTAPI_webSocketServer.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-08-12.
|
||||
//
|
||||
|
||||
#include "RESTAPI_webSocketServer.h"
|
||||
#include "Poco/Net/WebSocket.h"
|
||||
#include "Poco/Net/HTTPResponse.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
|
||||
#include "SerialNumberCache.h"
|
||||
|
||||
#include "Utils.h"
|
||||
#include "AuthClient.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_webSocketServer::handleRequest(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
|
||||
|
||||
if (!ContinueProcessing(Request, Response))
|
||||
return;
|
||||
|
||||
if(Request.getMethod()==Poco::Net::HTTPRequest::HTTP_GET)
|
||||
DoGet(Request,Response);
|
||||
else
|
||||
BadRequest(Request, Response, "Can only do get for WebSocket.");
|
||||
}
|
||||
|
||||
void RESTAPI_webSocketServer::DoGet(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
|
||||
|
||||
// try and upgrade this session to websocket...
|
||||
if(Request.find("Upgrade") != Request.end() && Poco::icompare(Request["Upgrade"], "websocket") == 0) {
|
||||
try
|
||||
{
|
||||
Poco::Net::WebSocket WS(Request, Response);
|
||||
Logger_.information("WebSocket connection established.");
|
||||
int flags;
|
||||
int n;
|
||||
bool Authenticated=false;
|
||||
bool Done=false;
|
||||
do
|
||||
{
|
||||
Poco::Buffer<char> IncomingFrame(0);
|
||||
n = WS.receiveFrame(IncomingFrame, flags);
|
||||
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
||||
switch(Op) {
|
||||
case Poco::Net::WebSocket::FRAME_OP_PING: {
|
||||
WS.sendFrame("", 0,
|
||||
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
|
||||
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
||||
}
|
||||
break;
|
||||
case Poco::Net::WebSocket::FRAME_OP_PONG: {
|
||||
}
|
||||
break;
|
||||
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
|
||||
IncomingFrame.append(0);
|
||||
if(!Authenticated) {
|
||||
std::string Frame{IncomingFrame.begin()};
|
||||
auto Tokens = Utils::Split(Frame,':');
|
||||
if(Tokens.size()==2 && AuthClient()->IsTokenAuthorized(Tokens[1], UserInfo_)) {
|
||||
Authenticated=true;
|
||||
std::string S{"Welcome! Bienvenue! Bienvenidos!"};
|
||||
WS.sendFrame(S.c_str(),S.size());
|
||||
} else {
|
||||
std::string S{"Invalid token. Closing connection."};
|
||||
WS.sendFrame(S.c_str(),S.size());
|
||||
Done=true;
|
||||
}
|
||||
|
||||
} else {
|
||||
try {
|
||||
Poco::JSON::Parser P;
|
||||
auto Obj = P.parse(IncomingFrame.begin())
|
||||
.extract<Poco::JSON::Object::Ptr>();
|
||||
std::string Answer;
|
||||
Process(Obj, Answer);
|
||||
if (!Answer.empty())
|
||||
WS.sendFrame(Answer.c_str(), Answer.size());
|
||||
else {
|
||||
WS.sendFrame("{}", 2);
|
||||
}
|
||||
} catch (const Poco::JSON::JSONException & E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!Done && (n > 0 && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE));
|
||||
Logger_.information("WebSocket connection closed.");
|
||||
}
|
||||
catch (const Poco::Net::WebSocketException & E)
|
||||
{
|
||||
Logger_.log(E);
|
||||
switch (E.code())
|
||||
{
|
||||
case Poco::Net::WebSocket::WS_ERR_HANDSHAKE_UNSUPPORTED_VERSION:
|
||||
Response.set("Sec-WebSocket-Version", Poco::Net::WebSocket::WEBSOCKET_VERSION);
|
||||
// fallthrough
|
||||
case Poco::Net::WebSocket::WS_ERR_NO_HANDSHAKE:
|
||||
case Poco::Net::WebSocket::WS_ERR_HANDSHAKE_NO_VERSION:
|
||||
case Poco::Net::WebSocket::WS_ERR_HANDSHAKE_NO_KEY:
|
||||
Response.setStatusAndReason(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
|
||||
Response.setContentLength(0);
|
||||
Response.send();
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RESTAPI_webSocketServer::Process(const Poco::JSON::Object::Ptr &O, std::string &Answer ) {
|
||||
try {
|
||||
if (O->has("command")) {
|
||||
auto Command = O->get("command").toString();
|
||||
if (Command == "serial_number_search" && O->has("serial_prefix")) {
|
||||
auto Prefix = O->get("serial_prefix").toString();
|
||||
uint64_t HowMany = 32;
|
||||
if (O->has("howMany"))
|
||||
HowMany = O->get("howMany");
|
||||
Logger_.information(Poco::format("serial_number_search: %s", Prefix));
|
||||
if (!Prefix.empty() && Prefix.length() < 13) {
|
||||
std::vector<uint64_t> Numbers;
|
||||
SerialNumberCache()->FindNumbers(Prefix, 50, Numbers);
|
||||
Poco::JSON::Array A;
|
||||
for (const auto &i : Numbers)
|
||||
A.add(Utils::int_to_hex(i));
|
||||
Poco::JSON::Object AO;
|
||||
AO.set("serialNumbers", A);
|
||||
AO.set("command","serial_number_search");
|
||||
std::ostringstream SS;
|
||||
Poco::JSON::Stringifier::stringify(AO, SS);
|
||||
Answer = SS.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
30
src/RESTAPI_webSocketServer.h
Normal file
30
src/RESTAPI_webSocketServer.h
Normal file
@@ -0,0 +1,30 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-08-12.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALGW_RESTAPI_WEBSOCKETSERVER_H
|
||||
#define UCENTRALGW_RESTAPI_WEBSOCKETSERVER_H
|
||||
|
||||
class RESTAPI_webSocketServer {};
|
||||
|
||||
#include "RESTAPI_handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_webSocketServer : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Internal) {}
|
||||
void handleRequest(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response) override final;
|
||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/ws"};}
|
||||
void DoGet(Poco::Net::HTTPServerRequest &Request,
|
||||
Poco::Net::HTTPServerResponse &Response);
|
||||
private:
|
||||
void Process(const Poco::JSON::Object::Ptr &O, std::string &Answer);
|
||||
};
|
||||
}
|
||||
|
||||
#endif // UCENTRALGW_RESTAPI_WEBSOCKETSERVER_H
|
||||
73
src/SerialNumberCache.cpp
Normal file
73
src/SerialNumberCache.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-08-11.
|
||||
//
|
||||
|
||||
#include "SerialNumberCache.h"
|
||||
#include <mutex>
|
||||
|
||||
#include "Utils.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class SerialNumberCache * SerialNumberCache::instance_ = nullptr;
|
||||
|
||||
int SerialNumberCache::Start() {
|
||||
Storage()->UpdateSerialNumberCache();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SerialNumberCache::Stop() {
|
||||
|
||||
}
|
||||
|
||||
void SerialNumberCache::AddSerialNumber(const std::string &S) {
|
||||
std::lock_guard G(M_);
|
||||
|
||||
uint64_t SN = std::stoull(S,0,16);
|
||||
if(std::find(SNs_.begin(),SNs_.end(),SN) == SNs_.end()) {
|
||||
if(SNs_.size()+1 == SNs_.capacity())
|
||||
SNs_.resize(SNs_.capacity()+2000);
|
||||
SNs_.push_back(SN);
|
||||
std::sort(SNs_.begin(),SNs_.end());
|
||||
}
|
||||
}
|
||||
|
||||
void SerialNumberCache::DeleteSerialNumber(const std::string &S) {
|
||||
std::lock_guard G(M_);
|
||||
|
||||
uint64_t SN = std::stoull(S,0,16);
|
||||
auto It = std::find(SNs_.begin(),SNs_.end(),SN);
|
||||
if(It != SNs_.end()) {
|
||||
SNs_.erase(It);
|
||||
}
|
||||
}
|
||||
|
||||
void SerialNumberCache::FindNumbers(const std::string &S, uint HowMany, std::vector<uint64_t> &A) {
|
||||
std::lock_guard G(M_);
|
||||
|
||||
if(S.length()==12) {
|
||||
uint64_t SN = std::stoull(S,0,16);
|
||||
auto It = std::find(SNs_.begin(),SNs_.end(),SN);
|
||||
if(It != SNs_.end()) {
|
||||
A.push_back(*It);
|
||||
}
|
||||
} else if (S.length()<12){
|
||||
std::string SS{S};
|
||||
SS.insert(SS.end(), 12 - SS.size(), '0');
|
||||
uint64_t SN = std::stoull(SS,0,16);
|
||||
|
||||
auto LB = std::lower_bound(SNs_.begin(),SNs_.end(),SN);
|
||||
if(LB!=SNs_.end()) {
|
||||
for(;LB!=SNs_.end() && HowMany;++LB,--HowMany) {
|
||||
std::string TSN = Utils::int_to_hex(*LB);
|
||||
if(S == TSN.substr(0,S.size())) {
|
||||
A.emplace_back(*LB);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
44
src/SerialNumberCache.h
Normal file
44
src/SerialNumberCache.h
Normal file
@@ -0,0 +1,44 @@
|
||||
//
|
||||
// Created by stephane bourque on 2021-08-11.
|
||||
//
|
||||
|
||||
#ifndef UCENTRALGW_SERIALNUMBERCACHE_H
|
||||
#define UCENTRALGW_SERIALNUMBERCACHE_H
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class SerialNumberCache : public SubSystemServer {
|
||||
public:
|
||||
|
||||
static SerialNumberCache *instance() {
|
||||
if (instance_ == nullptr) {
|
||||
instance_ = new SerialNumberCache;
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void AddSerialNumber(const std::string &S);
|
||||
void DeleteSerialNumber(const std::string &S);
|
||||
void FindNumbers(const std::string &S, uint HowMany, std::vector<uint64_t> &A);
|
||||
|
||||
private:
|
||||
static SerialNumberCache * instance_;
|
||||
uint64_t LastUpdate_ = 0 ;
|
||||
std::vector<uint64_t> SNs_;
|
||||
std::mutex M_;
|
||||
|
||||
SerialNumberCache() noexcept:
|
||||
SubSystemServer("SerialNumberCache", "SNCACHE-SVR", "serialcache")
|
||||
{
|
||||
SNs_.reserve(2000);
|
||||
}
|
||||
};
|
||||
|
||||
inline SerialNumberCache * SerialNumberCache() { return SerialNumberCache::instance(); }
|
||||
|
||||
} // namespace OpenWiFi
|
||||
|
||||
#endif // UCENTRALGW_SERIALNUMBERCACHE_H
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
bool StateProcessor::Add(const Poco::JSON::Object::Ptr & O) {
|
||||
try {
|
||||
@@ -43,6 +43,10 @@ namespace uCentral {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(Conn_)
|
||||
GetAssociations(O,Conn_->Associations_2G,Conn_->Associations_5G);
|
||||
|
||||
if(UpdatesSinceLastWrite_>10)
|
||||
Save();
|
||||
return true;
|
||||
@@ -129,4 +133,52 @@ namespace uCentral {
|
||||
std::string StatsToSave = toString();
|
||||
return Storage()->SetLifetimeStats(SerialNumber_, StatsToSave);
|
||||
}
|
||||
|
||||
static int ChannelToBand(uint64_t C) {
|
||||
if(C>=1 && C<=16) return 2;
|
||||
return 5;
|
||||
}
|
||||
|
||||
bool StateProcessor::GetAssociations(const Poco::JSON::Object::Ptr &RawObject, uint64_t &Radios_2G, uint64_t &Radios_5G) {
|
||||
Radios_2G = 0 ;
|
||||
Radios_5G = 0;
|
||||
if(RawObject->isArray("radios") && RawObject->isArray("interfaces")) {
|
||||
auto RA = RawObject->getArray("radios");
|
||||
// map of phy to 2g/5g
|
||||
std::map<std::string,int> RadioPHYs;
|
||||
// parse radios and get the phy out with the band
|
||||
for(auto const &i:*RA) {
|
||||
Poco::JSON::Parser p2;
|
||||
auto RadioObj = i.extract<Poco::JSON::Object::Ptr>();
|
||||
if(RadioObj->has("phy") && RadioObj->has("channel")) {
|
||||
RadioPHYs[RadioObj->get("phy").toString()]= ChannelToBand(RadioObj->get("channel"));
|
||||
}
|
||||
}
|
||||
|
||||
auto IA = RawObject->getArray("interfaces");
|
||||
for(auto const &i:*IA) {
|
||||
auto InterfaceObj = i.extract<Poco::JSON::Object::Ptr>();
|
||||
if(InterfaceObj->isArray("ssids")) {
|
||||
auto SSIDA = InterfaceObj->getArray("ssids");
|
||||
for(const auto &s:*SSIDA) {
|
||||
auto SSIDinfo = s.extract<Poco::JSON::Object::Ptr>();
|
||||
if(SSIDinfo->isArray("associations") && SSIDinfo->has("phy")) {
|
||||
auto PHY = SSIDinfo->get("phy").toString();
|
||||
int Radio = 2;
|
||||
auto Rit = RadioPHYs.find(PHY);
|
||||
if(Rit!=RadioPHYs.end())
|
||||
Radio = Rit->second;
|
||||
auto AssocA = SSIDinfo->getArray("associations");
|
||||
if(Radio==2)
|
||||
Radios_2G+=AssocA->size();
|
||||
else
|
||||
Radios_5G+=AssocA->size();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,13 @@
|
||||
|
||||
#include <map>
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class StateProcessor {
|
||||
public:
|
||||
StateProcessor(GWObjects::ConnectionState * Conn):
|
||||
Conn_(Conn) {}
|
||||
|
||||
~StateProcessor() {
|
||||
Save();
|
||||
@@ -24,13 +27,15 @@ namespace uCentral {
|
||||
[[nodiscard]] std::string toString() const;
|
||||
bool Initialize(std::string & SerialNumber);
|
||||
bool Save();
|
||||
static bool GetAssociations(const Poco::JSON::Object::Ptr &Ptr, uint64_t &Radios_2G, uint64_t &Radios_5G);
|
||||
|
||||
private:
|
||||
std::string SerialNumber_;
|
||||
std::string SerialNumber_;
|
||||
Poco::JSON::Object State_;
|
||||
// interface name is the key, each entry is a map with the stats name as key and then the value
|
||||
std::map<std::string,std::map<std::string,uint64_t>> Stats_;
|
||||
uint64_t UpdatesSinceLastWrite_ = 0 ;
|
||||
uint64_t UpdatesSinceLastWrite_ = 0 ;
|
||||
GWObjects::ConnectionState * Conn_ = nullptr;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "Daemon.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class StorageArchiver *StorageArchiver::instance_ = nullptr;
|
||||
|
||||
@@ -126,6 +126,7 @@ namespace uCentral {
|
||||
if(Running_) {
|
||||
Running_=false;
|
||||
Janitor_.wakeUp();
|
||||
Janitor_.wakeUp();
|
||||
Janitor_.join();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
struct ArchiverDBEntry {
|
||||
std::string DBName;
|
||||
|
||||
@@ -12,15 +12,10 @@
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Utils.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class Storage *Storage::instance_ = nullptr;
|
||||
|
||||
Storage::Storage() noexcept:
|
||||
SubSystemServer("Storage", "STORAGE-SVR", "storage")
|
||||
{
|
||||
}
|
||||
|
||||
std::string Storage::ConvertParams(const std::string & S) const {
|
||||
std::string R;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
#include "SubSystemServer.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class Storage : public SubSystemServer {
|
||||
|
||||
@@ -81,6 +81,7 @@ namespace uCentral {
|
||||
bool GetDevicesWithoutFirmware(std::string &DeviceType, std::string &Version, std::vector<std::string> & SerialNumbers);
|
||||
bool GetDeviceFWUpdatePolicy(std::string & SerialNumber, std::string & Policy);
|
||||
bool SetDevicePassword(std::string & SerialNumber, std::string & Password);
|
||||
bool UpdateSerialNumberCache();
|
||||
|
||||
bool ExistingConfiguration(std::string &SerialNumber, uint64_t CurrentConfig, std::string &NewConfig, uint64_t &);
|
||||
|
||||
@@ -111,6 +112,7 @@ namespace uCentral {
|
||||
bool CommandExecuted(std::string & UUID);
|
||||
bool CommandCompleted(std::string & UUID, const Poco::JSON::Object::Ptr & ReturnVars, bool FullCommand);
|
||||
bool AttachFileToCommand(std::string & UUID);
|
||||
bool CancelWaitFile( std::string & UUID, std::string & ErrorText );
|
||||
bool GetAttachedFile(std::string & UUID, std::string & SerialNumber, const std::string & FileName, std::string &Type);
|
||||
bool RemoveAttachedFile(std::string & UUID);
|
||||
bool SetCommandResult(std::string & UUID, std::string & Result);
|
||||
@@ -144,16 +146,22 @@ namespace uCentral {
|
||||
int Create_LifetimeStats();
|
||||
|
||||
bool AnalyzeCommands(Types::CountedMap &R);
|
||||
bool AnalyzeDevices(GWObjects::Dashboard &D);
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
int Setup_SQLite();
|
||||
[[nodiscard]] std::string ConvertParams(const std::string &S) const;
|
||||
|
||||
#ifndef SMALL_BUILD
|
||||
int Setup_MySQL();
|
||||
int Setup_PostgreSQL();
|
||||
#endif
|
||||
[[nodiscard]] std::string ConvertParams(const std::string &S) const;
|
||||
[[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
|
||||
if(dbType_==sqlite) {
|
||||
return " LIMIT " + std::to_string(From-1) + ", " + std::to_string(HowMany) + " ";
|
||||
} else if(dbType_==pgsql) {
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
|
||||
} else if(dbType_==mysql) {
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
|
||||
}
|
||||
return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
|
||||
}
|
||||
|
||||
private:
|
||||
static Storage *instance_;
|
||||
@@ -165,7 +173,15 @@ namespace uCentral {
|
||||
std::unique_ptr<Poco::Data::MySQL::Connector> MySQLConn_= nullptr;
|
||||
#endif
|
||||
|
||||
Storage() noexcept;
|
||||
Storage() noexcept:
|
||||
SubSystemServer("Storage", "STORAGE-SVR", "storage")
|
||||
{
|
||||
}
|
||||
|
||||
int Setup_SQLite();
|
||||
int Setup_MySQL();
|
||||
int Setup_PostgreSQL();
|
||||
|
||||
};
|
||||
|
||||
inline Storage * Storage() { return Storage::instance(); }
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "Daemon.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
SubSystemServer::SubSystemServer(std::string Name, const std::string &LoggingPrefix,
|
||||
std::string SubSystemConfigPrefix)
|
||||
: Name_(std::move(Name)), Logger_(Poco::Logger::get(LoggingPrefix)),
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
using SubMutex = std::recursive_mutex;
|
||||
using SubMutexGuard = std::lock_guard<SubMutex>;
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
class PropertiesFileServerEntry {
|
||||
public:
|
||||
PropertiesFileServerEntry(std::string Address, uint32_t port, std::string Key_file,
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "uCentralProtocol.h"
|
||||
#include "Daemon.h"
|
||||
|
||||
namespace uCentral::Utils {
|
||||
namespace OpenWifi::Utils {
|
||||
|
||||
[[nodiscard]] bool ValidSerialNumber(const std::string &Serial) {
|
||||
return ((Serial.size() < uCentralProtocol::SERIAL_NUMBER_LENGTH) &&
|
||||
|
||||
17
src/Utils.h
17
src/Utils.h
@@ -11,16 +11,18 @@
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include "Poco/Net/NetworkInterface.h"
|
||||
#include "Poco/Net/IPAddress.h"
|
||||
#include "Poco/String.h"
|
||||
#include "Poco/File.h"
|
||||
#include "uCentralTypes.h"
|
||||
#include "OpenWifiTypes.h"
|
||||
|
||||
#define DBGLINE { std::cout << __FILE__ << ":" << __func__ << ":" << __LINE__ << std::endl; };
|
||||
|
||||
namespace uCentral::Utils {
|
||||
namespace OpenWifi::Utils {
|
||||
|
||||
enum MediaTypeEncodings {
|
||||
PLAIN,
|
||||
@@ -73,5 +75,16 @@ namespace uCentral::Utils {
|
||||
[[nodiscard]] std::string SecondsToNiceText(uint64_t Seconds);
|
||||
|
||||
[[nodiscard]] bool IPinRange(const std::string &Range, const Poco::Net::IPAddress &IP);
|
||||
|
||||
template< typename T >
|
||||
std::string int_to_hex( T i )
|
||||
{
|
||||
std::stringstream stream;
|
||||
stream << std::setfill ('0') << std::setw(12)
|
||||
<< std::hex << i;
|
||||
return stream.str();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#endif // UCENTRALGW_UTILS_H
|
||||
|
||||
@@ -25,12 +25,11 @@
|
||||
#include "WebSocketServer.h"
|
||||
#include "uCentralProtocol.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
class WebSocketServer *WebSocketServer::instance_ = nullptr;
|
||||
|
||||
WebSocketServer::WebSocketServer() noexcept: SubSystemServer("WebSocketServer", "WS-SVR", "ucentral.websocket"),
|
||||
Factory_(Logger_)
|
||||
WebSocketServer::WebSocketServer() noexcept: SubSystemServer("WebSocketServer", "WS-SVR", "ucentral.websocket")
|
||||
{
|
||||
|
||||
}
|
||||
@@ -63,158 +62,137 @@ namespace uCentral {
|
||||
IssuerCert_ = std::make_unique<Poco::Crypto::X509Certificate>(Svr.IssuerCertFile());
|
||||
Logger_.information(Poco::format("Certificate Issuer Name:%s",IssuerCert_->issuerName()));
|
||||
}
|
||||
|
||||
auto NewSocketReactor = std::make_unique<Poco::Net::SocketReactor>();
|
||||
auto NewSocketAcceptor = std::make_unique<Poco::Net::SocketAcceptor<WSConnection>>( Sock, *NewSocketReactor);
|
||||
auto NewThread = std::make_unique<Poco::Thread>();
|
||||
NewThread->setName("WebSocketAcceptor."+Svr.Address()+":"+std::to_string(Svr.Port()));
|
||||
NewThread->start(*NewSocketReactor);
|
||||
|
||||
WebSocketServerEntry WSE { .SocketReactor{std::move(NewSocketReactor)} ,
|
||||
.SocketAcceptor{std::move(NewSocketAcceptor)} ,
|
||||
.SocketReactorThread{std::move(NewThread)}};
|
||||
Servers_.push_back(std::move(WSE));
|
||||
auto NewSocketAcceptor = std::make_unique<Poco::Net::ParallelSocketAcceptor<WSConnection, Poco::Net::SocketReactor>>( Sock, Reactor_);
|
||||
Acceptors_.push_back(std::move(NewSocketAcceptor));
|
||||
}
|
||||
|
||||
uint64_t MaxThreads = Daemon()->ConfigGetInt("ucentral.websocket.maxreactors",5);
|
||||
Factory_.Init(MaxThreads);
|
||||
|
||||
ReactorThread_.start(Reactor_);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void WebSocketServer::Stop() {
|
||||
Logger_.notice("Stopping reactors...");
|
||||
|
||||
for(auto const &Svr : Servers_) {
|
||||
Svr.SocketReactor->stop();
|
||||
Svr.SocketReactorThread->join();
|
||||
}
|
||||
Factory_.Close();
|
||||
}
|
||||
|
||||
CountedReactor::CountedReactor()
|
||||
{
|
||||
Reactor_ = WebSocketServer()->GetAReactor();
|
||||
}
|
||||
|
||||
CountedReactor::~CountedReactor()
|
||||
{
|
||||
Reactor_->Release();
|
||||
Reactor_.stop();
|
||||
ReactorThread_.join();
|
||||
}
|
||||
|
||||
void WSConnection::LogException(const Poco::Exception &E) {
|
||||
Logger_.information(Poco::format("EXCEPTION(%s): %s",CId_,E.displayText()));
|
||||
}
|
||||
|
||||
void WSConnection::CompleteStartup() {
|
||||
std::lock_guard Guard(WSMutex_);
|
||||
|
||||
try {
|
||||
auto SS = dynamic_cast<Poco::Net::SecureStreamSocketImpl *>(Socket_.impl());
|
||||
|
||||
SS->completeHandshake();
|
||||
|
||||
CId_ = Utils::FormatIPv6(SS->peerAddress().toString());
|
||||
|
||||
if (!SS->secure()) {
|
||||
Logger_.error(Poco::format("%s: Connection is NOT secure.", CId_));
|
||||
} else {
|
||||
Logger_.debug(Poco::format("%s: Connection is secure.", CId_));
|
||||
}
|
||||
|
||||
if (SS->havePeerCertificate()) {
|
||||
// Get the cert info...
|
||||
CertValidation_ = GWObjects::VALID_CERTIFICATE;
|
||||
try {
|
||||
Poco::Crypto::X509Certificate PeerCert(SS->peerCertificate());
|
||||
|
||||
if (WebSocketServer()->ValidateCertificate(CId_, PeerCert)) {
|
||||
CN_ = Poco::trim(Poco::toLower(PeerCert.commonName()));
|
||||
CertValidation_ = GWObjects::MISMATCH_SERIAL;
|
||||
Logger_.debug(Poco::format("%s: Valid certificate: CN=%s", CId_, CN_));
|
||||
} else {
|
||||
Logger_.debug(Poco::format("%s: Certificate is not valid", CId_));
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
LogException(E);
|
||||
}
|
||||
} else {
|
||||
Logger_.error(Poco::format("%s: No certificates available..", CId_));
|
||||
}
|
||||
|
||||
auto Params =
|
||||
Poco::AutoPtr<Poco::Net::HTTPServerParams>(new Poco::Net::HTTPServerParams);
|
||||
Poco::Net::HTTPServerSession Session(Socket_, Params);
|
||||
Poco::Net::HTTPServerResponseImpl Response(Session);
|
||||
Poco::Net::HTTPServerRequestImpl Request(Response, Session, Params);
|
||||
|
||||
auto Now = time(nullptr);
|
||||
Response.setDate(Now);
|
||||
Response.setVersion(Request.getVersion());
|
||||
Response.setKeepAlive(Params->getKeepAlive() && Request.getKeepAlive() &&
|
||||
Session.canKeepAlive());
|
||||
WS_ = std::make_unique<Poco::Net::WebSocket>(Request, Response);
|
||||
WS_->setMaxPayloadSize(BufSize);
|
||||
|
||||
auto TS = Poco::Timespan(240,0);
|
||||
|
||||
WS_->setReceiveTimeout(TS);
|
||||
WS_->setNoDelay(true);
|
||||
WS_->setKeepAlive(true);
|
||||
Reactor_.addEventHandler(*WS_,
|
||||
Poco::NObserver<WSConnection, Poco::Net::ReadableNotification>(
|
||||
*this, &WSConnection::OnSocketReadable));
|
||||
Reactor_.addEventHandler(*WS_,
|
||||
Poco::NObserver<WSConnection, Poco::Net::ShutdownNotification>(
|
||||
*this, &WSConnection::OnSocketShutdown));
|
||||
Reactor_.addEventHandler(*WS_,
|
||||
Poco::NObserver<WSConnection, Poco::Net::ErrorNotification>(
|
||||
*this, &WSConnection::OnSocketError));
|
||||
Registered_ = true;
|
||||
return;
|
||||
} catch (const Poco::Exception &E ) {
|
||||
Logger_.error("Exception caught during device connection. Device will have to retry.");
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
WSConnection::WSConnection(Poco::Net::StreamSocket & socket, Poco::Net::SocketReactor & reactor):
|
||||
Socket_(socket),
|
||||
Logger_(WebSocketServer()->Logger())
|
||||
Reactor_(reactor),
|
||||
Logger_(WebSocketServer()->Logger())
|
||||
{
|
||||
auto SS = dynamic_cast<Poco::Net::SecureStreamSocketImpl *>(Socket_.impl());
|
||||
|
||||
SS->completeHandshake();
|
||||
|
||||
CId_ = uCentral::Utils::FormatIPv6(SS->peerAddress().toString());
|
||||
|
||||
if(!SS->secure()) {
|
||||
Logger_.error(Poco::format("%s: Connection is NOT secure.",CId_));
|
||||
} else {
|
||||
Logger_.debug(Poco::format("%s: Connection is secure.",CId_));
|
||||
}
|
||||
|
||||
if(SS->havePeerCertificate()) {
|
||||
// Get the cert info...
|
||||
CertValidation_ = GWObjects::VALID_CERTIFICATE;
|
||||
try {
|
||||
Poco::Crypto::X509Certificate PeerCert(SS->peerCertificate());
|
||||
|
||||
if(WebSocketServer()->ValidateCertificate(CId_, PeerCert)) {
|
||||
CN_ = Poco::trim(Poco::toLower(PeerCert.commonName()));
|
||||
CertValidation_ = GWObjects::MISMATCH_SERIAL;
|
||||
Logger_.debug(Poco::format("%s: Valid certificate: CN=%s", CId_, CN_));
|
||||
} else {
|
||||
Logger_.debug( Poco::format("%s: Certificate is not valid", CId_));
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
LogException(E);
|
||||
}
|
||||
} else {
|
||||
Logger_.error(Poco::format("%s: No certificates available..",CId_));
|
||||
}
|
||||
|
||||
auto Params = Poco::AutoPtr<Poco::Net::HTTPServerParams>(new Poco::Net::HTTPServerParams);
|
||||
Poco::Net::HTTPServerSession Session(Socket_, Params);
|
||||
Poco::Net::HTTPServerResponseImpl Response(Session);
|
||||
Poco::Net::HTTPServerRequestImpl Request(Response,Session,Params);
|
||||
|
||||
auto Now = time(nullptr);
|
||||
Response.setDate(Now);
|
||||
Response.setVersion(Request.getVersion());
|
||||
Response.setKeepAlive(Params->getKeepAlive() && Request.getKeepAlive() && Session.canKeepAlive());
|
||||
WS_ = std::make_unique<Poco::Net::WebSocket>(Request, Response);
|
||||
WS_->setMaxPayloadSize(BufSize);
|
||||
|
||||
Register();
|
||||
std::thread T([this](){ this->CompleteStartup();});
|
||||
T.detach();
|
||||
}
|
||||
|
||||
WSConnection::~WSConnection() {
|
||||
// std::cout << "Connection " << CId_ << " shutting down." << std::endl;
|
||||
DeviceRegistry()->UnRegister(SerialNumber_,this);
|
||||
DeRegister();
|
||||
}
|
||||
|
||||
void WSConnection::Register() {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
if(!Registered_ && WS_)
|
||||
{
|
||||
auto TS = Poco::Timespan();
|
||||
|
||||
WS_->setReceiveTimeout(TS);
|
||||
WS_->setNoDelay(true);
|
||||
WS_->setKeepAlive(true);
|
||||
Reactor_.Reactor()->addEventHandler(*WS_,
|
||||
Poco::NObserver<WSConnection,
|
||||
Poco::Net::ReadableNotification>(*this,&WSConnection::OnSocketReadable));
|
||||
Reactor_.Reactor()->addEventHandler(*WS_,
|
||||
Poco::NObserver<WSConnection,
|
||||
Poco::Net::ShutdownNotification>(*this,&WSConnection::OnSocketShutdown));
|
||||
Reactor_.Reactor()->addEventHandler(*WS_,
|
||||
Poco::NObserver<WSConnection,
|
||||
Poco::Net::ErrorNotification>(*this,&WSConnection::OnSocketError));
|
||||
Registered_ = true ;
|
||||
}
|
||||
}
|
||||
|
||||
void WSConnection::DeRegister() {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
if(Registered_ && WS_)
|
||||
{
|
||||
Reactor_.Reactor()->removeEventHandler(*WS_,
|
||||
Poco::NObserver<WSConnection,
|
||||
Poco::Net::ReadableNotification>(*this,&WSConnection::OnSocketReadable));
|
||||
Reactor_.Reactor()->removeEventHandler(*WS_,
|
||||
Poco::NObserver<WSConnection,
|
||||
Poco::Net::ShutdownNotification>(*this,&WSConnection::OnSocketShutdown));
|
||||
Reactor_.Reactor()->removeEventHandler(*WS_,
|
||||
Poco::NObserver<WSConnection,
|
||||
Poco::Net::ErrorNotification>(*this,&WSConnection::OnSocketError));
|
||||
(*WS_).close();
|
||||
Registered_ = false ;
|
||||
}
|
||||
|
||||
if(KafkaManager()->Enabled() && !SerialNumber_.empty()) {
|
||||
Poco::JSON::Object Disconnect;
|
||||
Poco::JSON::Object Details;
|
||||
Details.set(uCentralProtocol::SERIALNUMBER, SerialNumber_);
|
||||
Details.set(uCentralProtocol::TIMESTAMP,std::time(nullptr));
|
||||
Disconnect.set(uCentralProtocol::DISCONNECTION,Details);
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
std::ostringstream OS;
|
||||
Stringify.condense(Disconnect,OS);
|
||||
KafkaManager()->PostMessage(uCentral::KafkaTopics::CONNECTION, SerialNumber_, OS.str());
|
||||
Reactor_.removeEventHandler(*WS_,
|
||||
Poco::NObserver<WSConnection,
|
||||
Poco::Net::ReadableNotification>(*this,&WSConnection::OnSocketReadable));
|
||||
Reactor_.removeEventHandler(*WS_,
|
||||
Poco::NObserver<WSConnection,
|
||||
Poco::Net::ShutdownNotification>(*this,&WSConnection::OnSocketShutdown));
|
||||
Reactor_.removeEventHandler(*WS_,
|
||||
Poco::NObserver<WSConnection,
|
||||
Poco::Net::ErrorNotification>(*this,&WSConnection::OnSocketError));
|
||||
(*WS_).close();
|
||||
Socket_.shutdown();
|
||||
} else if(WS_) {
|
||||
(*WS_).close();
|
||||
Socket_.shutdown();
|
||||
}
|
||||
|
||||
}
|
||||
if(KafkaManager()->Enabled() && !SerialNumber_.empty()) {
|
||||
Poco::JSON::Object Disconnect;
|
||||
Poco::JSON::Object Details;
|
||||
Details.set(uCentralProtocol::SERIALNUMBER, SerialNumber_);
|
||||
Details.set(uCentralProtocol::TIMESTAMP,std::time(nullptr));
|
||||
Disconnect.set(uCentralProtocol::DISCONNECTION,Details);
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
std::ostringstream OS;
|
||||
Stringify.condense(Disconnect,OS);
|
||||
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_, OS.str());
|
||||
}
|
||||
}
|
||||
|
||||
bool WSConnection::LookForUpgrade(uint64_t UUID) {
|
||||
|
||||
@@ -269,7 +247,7 @@ namespace uCentral {
|
||||
|
||||
bool WSConnection::ExtractCompressedData(const std::string & CompressedData, std::string & UnCompressedData)
|
||||
{
|
||||
std::vector<uint8_t> OB = uCentral::Utils::base64decode(CompressedData);
|
||||
std::vector<uint8_t> OB = Utils::base64decode(CompressedData);
|
||||
|
||||
unsigned long MaxSize=OB.size()*10;
|
||||
std::vector<char> UncompressedBuffer(MaxSize);
|
||||
@@ -282,14 +260,14 @@ namespace uCentral {
|
||||
return false;
|
||||
}
|
||||
|
||||
void WSConnection::ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc) {
|
||||
void WSConnection::ProcessJSONRPCResult(Poco::JSON::Object::Ptr & Doc) {
|
||||
CommandManager()->PostCommandResult(SerialNumber_, Doc);
|
||||
}
|
||||
|
||||
void WSConnection::ProcessJSONRPCEvent(Poco::JSON::Object::Ptr Doc) {
|
||||
void WSConnection::ProcessJSONRPCEvent(Poco::JSON::Object::Ptr & Doc) {
|
||||
|
||||
auto Method = Doc->get(uCentralProtocol::METHOD).toString();
|
||||
auto EventType = uCentral::uCentralProtocol::EventFromString(Method);
|
||||
auto EventType = uCentralProtocol::EventFromString(Method);
|
||||
if(EventType == uCentralProtocol::ET_UNKNOWN) {
|
||||
Logger_.error(Poco::format("ILLEGAL-PROTOCOL(%s): Unknown message type '%s'",Method));
|
||||
Errors_++;
|
||||
@@ -326,7 +304,7 @@ namespace uCentral {
|
||||
}
|
||||
|
||||
auto Serial = Poco::trim(Poco::toLower(ParamsObj->get(uCentralProtocol::SERIAL).toString()));
|
||||
if(!uCentral::Utils::ValidSerialNumber(Serial)) {
|
||||
if(!Utils::ValidSerialNumber(Serial)) {
|
||||
Poco::Exception E(Poco::format("ILLEGAL-DEVICE-NAME(%s): device name is illegal and not allowed to connect.",Serial), EACCES);
|
||||
E.rethrow();
|
||||
}
|
||||
@@ -355,7 +333,7 @@ namespace uCentral {
|
||||
Conn_->Firmware = Firmware;
|
||||
Conn_->PendingUUID = 0;
|
||||
Conn_->LastContact = std::time(nullptr);
|
||||
Conn_->Address = uCentral::Utils::FormatIPv6(WS_->peerAddress().toString());
|
||||
Conn_->Address = Utils::FormatIPv6(WS_->peerAddress().toString());
|
||||
CId_ = SerialNumber_ + "@" + CId_ ;
|
||||
|
||||
// We need to verify the certificate if we have one
|
||||
@@ -381,7 +359,7 @@ namespace uCentral {
|
||||
}
|
||||
Conn_->Compatible = Compatible_;
|
||||
|
||||
StatsProcessor_ = std::make_unique<uCentral::StateProcessor>();
|
||||
StatsProcessor_ = std::make_unique<StateProcessor>(Conn_);
|
||||
StatsProcessor_->Initialize(Serial);
|
||||
LookForUpgrade(UUID);
|
||||
|
||||
@@ -389,7 +367,7 @@ namespace uCentral {
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
std::ostringstream OS;
|
||||
Stringify.condense(ParamsObj,OS);
|
||||
KafkaManager()->PostMessage(uCentral::KafkaTopics::CONNECTION, SerialNumber_, OS.str());
|
||||
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_, OS.str());
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -429,7 +407,7 @@ namespace uCentral {
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
std::ostringstream OS;
|
||||
Stringify.condense(ParamsObj,OS);
|
||||
KafkaManager()->PostMessage(uCentral::KafkaTopics::STATE, SerialNumber_, OS.str());
|
||||
KafkaManager()->PostMessage(KafkaTopics::STATE, SerialNumber_, OS.str());
|
||||
}
|
||||
} else {
|
||||
Logger_.warning(Poco::format(
|
||||
@@ -477,7 +455,7 @@ namespace uCentral {
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
std::ostringstream OS;
|
||||
Stringify.condense(ParamsObj,OS);
|
||||
KafkaManager()->PostMessage(uCentral::KafkaTopics::HEALTHCHECK, SerialNumber_, OS.str());
|
||||
KafkaManager()->PostMessage(KafkaTopics::HEALTHCHECK, SerialNumber_, OS.str());
|
||||
}
|
||||
} else {
|
||||
Logger_.warning(Poco::format("HEALTHCHECK(%s): Missing parameter", CId_));
|
||||
@@ -610,22 +588,24 @@ namespace uCentral {
|
||||
}
|
||||
|
||||
void WSConnection::OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(WSMutex_);
|
||||
|
||||
// std::cout << "Socket shutdown: " << CId_ << std::endl;
|
||||
Logger_.information(Poco::format("SOCKET-SHUTDOWN(%s): Closing.",CId_));
|
||||
std::cout << "Socket shutdown for " << SerialNumber_ << std::endl;
|
||||
delete this;
|
||||
}
|
||||
|
||||
void WSConnection::OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(WSMutex_);
|
||||
|
||||
// std::cout << "Socket error: " << CId_ << std::endl;
|
||||
Logger_.information(Poco::format("SOCKET-ERROR(%s): Closing.",CId_));
|
||||
std::cout << "Socket error for " << SerialNumber_ << std::endl;
|
||||
delete this;
|
||||
}
|
||||
|
||||
void WSConnection::OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
std::lock_guard Guard(WSMutex_);
|
||||
|
||||
try
|
||||
{
|
||||
ProcessIncomingFrame();
|
||||
@@ -658,8 +638,6 @@ namespace uCentral {
|
||||
Poco::Buffer<char> IncomingFrame(0);
|
||||
|
||||
try {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
|
||||
IncomingSize = WS_->receiveFrame(IncomingFrame,flags);
|
||||
Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
||||
|
||||
@@ -685,7 +663,7 @@ namespace uCentral {
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
std::ostringstream OS;
|
||||
Stringify.condense(PingObject, OS);
|
||||
KafkaManager()->PostMessage(uCentral::KafkaTopics::CONNECTION, SerialNumber_,
|
||||
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_,
|
||||
OS.str());
|
||||
}
|
||||
}
|
||||
@@ -796,14 +774,20 @@ namespace uCentral {
|
||||
MustDisconnect = true ;
|
||||
}
|
||||
|
||||
if(!MustDisconnect || Errors_>10)
|
||||
return;
|
||||
if(!MustDisconnect && Errors_<10) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(Errors_>10) {
|
||||
Logger_.information(Poco::format("DISCONNECTING(%s): Too many errors",CId_));
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
|
||||
bool WSConnection::Send(const std::string &Payload) {
|
||||
SubMutexGuard Guard(Mutex_);
|
||||
std::lock_guard Guard(WSMutex_);
|
||||
|
||||
auto BytesSent = WS_->sendFrame(Payload.c_str(),(int)Payload.size());
|
||||
if(Conn_)
|
||||
Conn_->TX += BytesSent;
|
||||
|
||||
@@ -32,144 +32,32 @@
|
||||
#include "Poco/Net/StreamSocket.h"
|
||||
#include "Poco/Net/SecureStreamSocket.h"
|
||||
#include "Poco/Net/SecureStreamSocketImpl.h"
|
||||
#include "Poco/Net/ParallelSocketAcceptor.h"
|
||||
|
||||
namespace uCentral {
|
||||
|
||||
class CountedSocketReactor : public Poco::Net::SocketReactor {
|
||||
public:
|
||||
explicit CountedSocketReactor(uint64_t Id): Id_(Id),SocketCount_(0) {
|
||||
setTimeout(Poco::Timespan(0,10000));
|
||||
}
|
||||
|
||||
~CountedSocketReactor() override {
|
||||
Poco::Net::SocketReactor::stop();
|
||||
}
|
||||
|
||||
uint64_t Count() const {
|
||||
return SocketCount_; }
|
||||
void Get() {
|
||||
std::lock_guard<std::mutex> guard(Mutex_);
|
||||
SocketCount_++; }
|
||||
void Release() {
|
||||
std::lock_guard<std::mutex> guard(Mutex_);
|
||||
SocketCount_--; }
|
||||
uint64_t Id() const { return Id_;}
|
||||
|
||||
private:
|
||||
std::mutex Mutex_{};
|
||||
uint64_t SocketCount_;
|
||||
uint64_t Id_;
|
||||
};
|
||||
|
||||
class CountedSocketReactorFactory {
|
||||
public:
|
||||
explicit CountedSocketReactorFactory(Poco::Logger & Logger):
|
||||
Logger_(Logger),
|
||||
NumReactors_(0)
|
||||
{
|
||||
}
|
||||
|
||||
void Init(unsigned int NumReactors) {
|
||||
NumReactors_ = NumReactors;
|
||||
for(auto i=0;i<NumReactors_;i++)
|
||||
{
|
||||
auto NewReactor = new CountedSocketReactor(i);
|
||||
auto NewThread = new Poco::Thread;
|
||||
|
||||
ReactorThreads_.emplace_back( std::pair(NewReactor, NewThread));
|
||||
NewThread->start(*NewReactor);
|
||||
NewThread->setName( "Reactor:" + std::to_string(i));
|
||||
}
|
||||
}
|
||||
|
||||
void Close() {
|
||||
Logger_.information("Closing Reactor factory...");
|
||||
for(auto &[Reactor,Thread]:ReactorThreads_)
|
||||
{
|
||||
Reactor->stop();
|
||||
Thread->join();
|
||||
}
|
||||
}
|
||||
|
||||
~CountedSocketReactorFactory() {
|
||||
for(auto &[Reactor,Thread]:ReactorThreads_)
|
||||
{
|
||||
delete Reactor;
|
||||
delete Thread;
|
||||
}
|
||||
}
|
||||
|
||||
CountedSocketReactor * GetAReactor() {
|
||||
uint64_t Min;
|
||||
|
||||
std::lock_guard<std::mutex> guard(Mutex_);
|
||||
|
||||
auto Tmp = ReactorThreads_.end();
|
||||
uint64_t TotalSockets = 0 ;
|
||||
|
||||
for( auto i = ReactorThreads_.begin() ; i != ReactorThreads_.end() ; i++ )
|
||||
{
|
||||
TotalSockets += i->first->Count();
|
||||
if((Tmp == ReactorThreads_.end()) || (i->first->Count()<Min) ) {
|
||||
Tmp = i;
|
||||
Min = i->first->Count();
|
||||
}
|
||||
}
|
||||
|
||||
Tmp->first->Get();
|
||||
|
||||
return Tmp->first;
|
||||
}
|
||||
|
||||
private:
|
||||
std::mutex Mutex_{};
|
||||
Poco::Logger & Logger_;
|
||||
uint64_t NumReactors_;
|
||||
std::vector<std::pair<CountedSocketReactor *, Poco::Thread *>> ReactorThreads_;
|
||||
};
|
||||
|
||||
struct CommandIDPair {
|
||||
std::string UUID;
|
||||
bool Full=true;
|
||||
};
|
||||
|
||||
class CountedReactor {
|
||||
public:
|
||||
CountedReactor();
|
||||
~CountedReactor();
|
||||
CountedSocketReactor * Reactor() { return Reactor_; }
|
||||
private:
|
||||
CountedSocketReactor * Reactor_;
|
||||
};
|
||||
|
||||
using SubMutex = std::recursive_mutex;
|
||||
using SubMutexGuard = std::lock_guard<SubMutex>;
|
||||
namespace OpenWifi {
|
||||
|
||||
class WSConnection {
|
||||
static constexpr int BufSize = 64000;
|
||||
public:
|
||||
WSConnection(Poco::Net::StreamSocket& socket, Poco::Net::SocketReactor& reactor);
|
||||
WSConnection(Poco::Net::StreamSocket& Socket, Poco::Net::SocketReactor& Reactor);
|
||||
~WSConnection();
|
||||
|
||||
void ProcessJSONRPCEvent(Poco::JSON::Object::Ptr Doc);
|
||||
void ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc);
|
||||
void ProcessJSONRPCEvent(Poco::JSON::Object::Ptr & Doc);
|
||||
void ProcessJSONRPCResult(Poco::JSON::Object::Ptr & Doc);
|
||||
void ProcessIncomingFrame();
|
||||
// bool SendCommand(uCentral::Objects::CommandDetails & Command);
|
||||
bool Send(const std::string &Payload);
|
||||
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
||||
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf);
|
||||
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf);
|
||||
bool LookForUpgrade(uint64_t UUID);
|
||||
static bool ExtractCompressedData(const std::string & CompressedData, std::string & UnCompressedData);
|
||||
void Register();
|
||||
void DeRegister();
|
||||
void LogException(const Poco::Exception &E);
|
||||
[[nodiscard]] GWObjects::CertificateValidation CertificateValidation() const { return CertValidation_; };
|
||||
private:
|
||||
SubMutex Mutex_{};
|
||||
CountedReactor Reactor_;
|
||||
Poco::Logger & Logger_;
|
||||
std::recursive_mutex WSMutex_;
|
||||
Poco::Logger &Logger_;
|
||||
Poco::Net::StreamSocket Socket_;
|
||||
Poco::Net::SocketReactor & Reactor_;
|
||||
std::unique_ptr<Poco::Net::WebSocket> WS_;
|
||||
std::string SerialNumber_;
|
||||
std::string Compatible_;
|
||||
@@ -179,13 +67,9 @@ namespace uCentral {
|
||||
std::string CN_;
|
||||
GWObjects::CertificateValidation CertValidation_ = GWObjects::CertificateValidation::NO_CERTIFICATE;
|
||||
uint64_t Errors_=0;
|
||||
std::unique_ptr<uCentral::StateProcessor> StatsProcessor_;
|
||||
};
|
||||
std::unique_ptr<StateProcessor> StatsProcessor_;
|
||||
|
||||
struct WebSocketServerEntry {
|
||||
std::unique_ptr<Poco::Net::SocketReactor> SocketReactor;
|
||||
std::unique_ptr<Poco::Net::SocketAcceptor<WSConnection>> SocketAcceptor;
|
||||
std::unique_ptr<Poco::Thread> SocketReactorThread;
|
||||
void CompleteStartup();
|
||||
};
|
||||
|
||||
class WebSocketServer : public SubSystemServer {
|
||||
@@ -197,10 +81,6 @@ namespace uCentral {
|
||||
return instance_;
|
||||
}
|
||||
|
||||
CountedSocketReactor * GetAReactor() {
|
||||
return Factory_.GetAReactor();
|
||||
}
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
bool IsCertOk() { return IssuerCert_!= nullptr; }
|
||||
@@ -210,8 +90,9 @@ namespace uCentral {
|
||||
private:
|
||||
static WebSocketServer *instance_;
|
||||
std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_;
|
||||
std::vector<WebSocketServerEntry> Servers_;
|
||||
CountedSocketReactorFactory Factory_;
|
||||
std::vector<std::unique_ptr<Poco::Net::ParallelSocketAcceptor<WSConnection, Poco::Net::SocketReactor>>> Acceptors_;
|
||||
Poco::Net::SocketReactor Reactor_;
|
||||
Poco::Thread ReactorThread_;
|
||||
WebSocketServer() noexcept;
|
||||
};
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
bool Storage::AddBlackListDevices(std::vector<GWObjects::BlackListedDevice> &Devices) {
|
||||
try {
|
||||
@@ -70,9 +70,9 @@ namespace uCentral {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Statement Select(Sess);
|
||||
|
||||
Select << "SELECT SerialNumber, Reason, Author, Created FROM BlackList",
|
||||
Poco::Data::Keywords::into(Records),
|
||||
Poco::Data::Keywords::range(Offset, Offset + HowMany);
|
||||
Select << "SELECT SerialNumber, Reason, Author, Created FROM BlackList"
|
||||
+ ComputeRange(Offset,HowMany),
|
||||
Poco::Data::Keywords::into(Records);
|
||||
Select.execute();
|
||||
|
||||
for (auto i : Records) {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
bool Storage::UpdateDeviceCapabilities(std::string &SerialNumber, std::string & Capabilities, std::string & Compat) {
|
||||
// std::lock_guard<std::mutex> guard(Mutex_);
|
||||
@@ -75,7 +75,7 @@ namespace uCentral {
|
||||
Update.execute();
|
||||
}
|
||||
|
||||
uCentral::Storage::SetDeviceCompatibility(SerialNumber, Compatible);
|
||||
Storage::SetDeviceCompatibility(SerialNumber, Compatible);
|
||||
return true;
|
||||
}
|
||||
catch (const Poco::Exception &E) {
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
#include "Daemon.h"
|
||||
#include "DeviceRegistry.h"
|
||||
#include "StorageService.h"
|
||||
#include "FileUploader.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
typedef Poco::Tuple<
|
||||
std::string,
|
||||
@@ -142,7 +143,7 @@ namespace uCentral {
|
||||
std::string Fields{
|
||||
"SELECT UUID, SerialNumber, Command, Status, SubmittedBy, Results, Details, ErrorText, "
|
||||
"Submitted, Executed, Completed, RunAt, ErrorCode, Custom, WaitingForFile, AttachDate, "
|
||||
"AttachSize, AttachType FROM CommandList "};
|
||||
"AttachSize, AttachType FROM CommandList ORDER BY UUID ASC "};
|
||||
std::string IntroStatement = SerialNumber.empty()
|
||||
? Fields + std::string(DatesIncluded ? "WHERE " : "")
|
||||
: Fields + "WHERE SerialNumber='" + SerialNumber + "'" +
|
||||
@@ -160,8 +161,8 @@ namespace uCentral {
|
||||
|
||||
Poco::Data::Statement Select(Sess);
|
||||
|
||||
Select << IntroStatement + DateSelector, Poco::Data::Keywords::into(Records),
|
||||
Poco::Data::Keywords::range(Offset, Offset + HowMany);
|
||||
Select << IntroStatement + DateSelector +
|
||||
ComputeRange(Offset, HowMany), Poco::Data::Keywords::into(Records);
|
||||
|
||||
Select.execute();
|
||||
|
||||
@@ -268,11 +269,10 @@ namespace uCentral {
|
||||
// range(Offset, Offset + HowMany - 1)
|
||||
std::string st{ "SELECT UUID, SerialNumber, Command, Status, SubmittedBy, Results, Details, ErrorText,"
|
||||
"Submitted, Executed, Completed, RunAt, ErrorCode, Custom, WaitingForFile, AttachDate,"
|
||||
"AttachSize, AttachType FROM CommandList "
|
||||
"WHERE Executed=0"};
|
||||
Select << ConvertParams(st),
|
||||
Poco::Data::Keywords::into(Records),
|
||||
Poco::Data::Keywords::range(Offset, Offset + HowMany);
|
||||
"AttachSize, AttachType FROM CommandList ORDER BY UUID ASC "
|
||||
"WHERE Executed=0" };
|
||||
Select << ConvertParams(st) + ComputeRange(Offset, HowMany),
|
||||
Poco::Data::Keywords::into(Records);
|
||||
Select.execute();
|
||||
|
||||
for (auto i : Records) {
|
||||
@@ -513,7 +513,7 @@ namespace uCentral {
|
||||
|
||||
bool Storage::GetReadyToExecuteCommands(uint64_t Offset, uint64_t HowMany,
|
||||
std::vector<GWObjects::CommandDetails> &Commands) {
|
||||
// todo: finish the GetReadyToExecuteCommands call...
|
||||
|
||||
try {
|
||||
typedef std::vector<CommandDetailsRecordTuple> RecordList;
|
||||
uint64_t Now = time(nullptr);
|
||||
@@ -522,13 +522,14 @@ namespace uCentral {
|
||||
|
||||
std::string St{
|
||||
"SELECT UUID, SerialNumber, Command, Status, SubmittedBy, Results, Details, ErrorText, "
|
||||
"Submitted, Executed, Completed, RunAt, ErrorCode, Custom, WaitingForFile, AttachDate, AttachSize, AttachType FROM CommandList "
|
||||
"WHERE RunAt < ? And Executed=0"};
|
||||
|
||||
" Submitted, Executed, Completed, RunAt, ErrorCode, Custom, WaitingForFile, AttachDate, AttachSize, AttachType FROM CommandList "
|
||||
" WHERE ((RunAt<=?) And (Executed=0)) ORDER BY UUID ASC "};
|
||||
RecordList Records;
|
||||
|
||||
Select << ConvertParams(St), Poco::Data::Keywords::into(Records),
|
||||
Poco::Data::Keywords::use(Now), Poco::Data::Keywords::range(Offset, Offset + HowMany);
|
||||
std::string SS = ConvertParams(St) + ComputeRange(Offset, HowMany);
|
||||
Select << SS,
|
||||
Poco::Data::Keywords::into(Records),
|
||||
Poco::Data::Keywords::use(Now);
|
||||
Select.execute();
|
||||
|
||||
for (auto i : Records) {
|
||||
@@ -554,9 +555,9 @@ namespace uCentral {
|
||||
if (DeviceRegistry()->Connected(R.SerialNumber))
|
||||
Commands.push_back(R);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
// std::cout << "Exception: " << E.displayText() << std::endl;
|
||||
Logger_.warning(Poco::format("GetReadyToExecuteCommands(): Failed to retrieve the list. %s",
|
||||
E.displayText()));
|
||||
}
|
||||
@@ -633,6 +634,33 @@ namespace uCentral {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Storage::CancelWaitFile( std::string & UUID, std::string & ErrorText ) {
|
||||
try {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
uint64_t Now = time(nullptr);
|
||||
uint64_t Size = 0, WaitForFile = 0;
|
||||
|
||||
Poco::Data::Statement Update(Sess);
|
||||
|
||||
std::string St{
|
||||
"UPDATE CommandList SET WaitingForFile=?, AttachDate=?, AttachSize=?, ErrorText=?, Completed=? WHERE UUID=?"};
|
||||
|
||||
Update << ConvertParams(St),
|
||||
Poco::Data::Keywords::use(WaitForFile),
|
||||
Poco::Data::Keywords::use(Now),
|
||||
Poco::Data::Keywords::use(Size),
|
||||
Poco::Data::Keywords::use(ErrorText),
|
||||
Poco::Data::Keywords::use(Now),
|
||||
Poco::Data::Keywords::use(UUID);
|
||||
Update.execute();
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
bool Storage::AttachFileToCommand(std::string &UUID) {
|
||||
try {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
@@ -641,14 +669,16 @@ namespace uCentral {
|
||||
|
||||
Poco::Data::Statement Update(Sess);
|
||||
|
||||
Poco::File FileName = Daemon()->ConfigPath("ucentral.fileuploader.path", "/tmp") + "/" + UUID;
|
||||
Poco::File FileName = FileUploader()->Path() + "/" + UUID;
|
||||
uint64_t Size = FileName.getSize();
|
||||
|
||||
std::string St{
|
||||
"UPDATE CommandList SET WaitingForFile=?, AttachDate=?, AttachSize=? WHERE UUID=?"};
|
||||
|
||||
Update << ConvertParams(St), Poco::Data::Keywords::use(WaitForFile),
|
||||
Poco::Data::Keywords::use(Now), Poco::Data::Keywords::use(Size),
|
||||
Update << ConvertParams(St),
|
||||
Poco::Data::Keywords::use(WaitForFile),
|
||||
Poco::Data::Keywords::use(Now),
|
||||
Poco::Data::Keywords::use(Size),
|
||||
Poco::Data::Keywords::use(UUID);
|
||||
Update.execute();
|
||||
|
||||
@@ -673,7 +703,8 @@ namespace uCentral {
|
||||
"INSERT INTO FileUploads (UUID,Type,Created,FileContent) VALUES(?,?,?,?)"};
|
||||
|
||||
Insert << ConvertParams(St2), Poco::Data::Keywords::use(UUID),
|
||||
Poco::Data::Keywords::use(FileType), Poco::Data::Keywords::use(Now),
|
||||
Poco::Data::Keywords::use(FileType),
|
||||
Poco::Data::Keywords::use(Now),
|
||||
Poco::Data::Keywords::use(L);
|
||||
Insert.execute();
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
#include "CentralConfig.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
/*
|
||||
* Data model for DefaultConfigurations:
|
||||
@@ -40,7 +40,7 @@ namespace uCentral {
|
||||
|
||||
if (TmpName.empty()) {
|
||||
|
||||
uCentral::Config::Config Cfg(DefConfig.Configuration);
|
||||
Config::Config Cfg(DefConfig.Configuration);
|
||||
/*
|
||||
"Name VARCHAR(30) PRIMARY KEY, "
|
||||
"Configuration TEXT, "
|
||||
@@ -108,7 +108,7 @@ namespace uCentral {
|
||||
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
|
||||
uCentral::Config::Config Cfg(DefConfig.Configuration);
|
||||
Config::Config Cfg(DefConfig.Configuration);
|
||||
|
||||
if (Cfg.Valid()) {
|
||||
|
||||
@@ -199,9 +199,9 @@ namespace uCentral {
|
||||
"Description, "
|
||||
"Created, "
|
||||
"LastModified "
|
||||
"FROM DefaultConfigs",
|
||||
Poco::Data::Keywords::into(Records),
|
||||
Poco::Data::Keywords::range(From, From + HowMany );
|
||||
"FROM DefaultConfigs ORDER BY NAME ASC " +
|
||||
ComputeRange(From, HowMany),
|
||||
Poco::Data::Keywords::into(Records);
|
||||
|
||||
Select.execute();
|
||||
|
||||
@@ -267,9 +267,9 @@ namespace uCentral {
|
||||
"Description, "
|
||||
"Created, "
|
||||
"LastModified "
|
||||
"FROM DefaultConfigs",
|
||||
Poco::Data::Keywords::into(Records),
|
||||
Poco::Data::Keywords::range(0, 2);
|
||||
"FROM DefaultConfigs ORDER BY NAME ASC " +
|
||||
ComputeRange(1,1),
|
||||
Poco::Data::Keywords::into(Records);
|
||||
Select.execute();
|
||||
|
||||
for (auto i: Records) {
|
||||
|
||||
@@ -6,14 +6,18 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "Poco/Data/RecordSet.h"
|
||||
#include "CentralConfig.h"
|
||||
#include "StorageService.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#include "RESTAPI_utils.h"
|
||||
#include "Daemon.h"
|
||||
#include "DeviceRegistry.h"
|
||||
#include "OUIServer.h"
|
||||
#include "StateProcessor.h"
|
||||
#include "SerialNumberCache.h"
|
||||
|
||||
namespace uCentral {
|
||||
namespace OpenWifi {
|
||||
|
||||
bool Storage::GetDeviceCount(uint64_t &Count) {
|
||||
try {
|
||||
@@ -37,11 +41,10 @@ namespace uCentral {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Statement Select(Sess);
|
||||
|
||||
std::string st{"SELECT SerialNumber From Devices"};
|
||||
std::string st{"SELECT SerialNumber From Devices ORDER BY SerialNumber ASC " };
|
||||
|
||||
Select << st,
|
||||
Poco::Data::Keywords::into(SerialNumbers),
|
||||
Poco::Data::Keywords::range(From, From + HowMany );
|
||||
Select << st + ComputeRange(From, HowMany),
|
||||
Poco::Data::Keywords::into(SerialNumbers);
|
||||
Select.execute();
|
||||
return true;
|
||||
} catch (const Poco::Exception &E ) {
|
||||
@@ -53,7 +56,7 @@ namespace uCentral {
|
||||
bool Storage::UpdateDeviceConfiguration(std::string &SerialNumber, std::string &Configuration, uint64_t &NewUUID) {
|
||||
try {
|
||||
|
||||
uCentral::Config::Config Cfg(Configuration);
|
||||
Config::Config Cfg(Configuration);
|
||||
if (!Cfg.Valid()) {
|
||||
Logger_.warning(Poco::format("CONFIG-UPDATE(%s): Configuration was not valid", SerialNumber));
|
||||
return false;
|
||||
@@ -118,7 +121,7 @@ namespace uCentral {
|
||||
Select.execute();
|
||||
|
||||
if (SerialNumber.empty()) {
|
||||
uCentral::Config::Config Cfg(DeviceDetails.Configuration);
|
||||
Config::Config Cfg(DeviceDetails.Configuration);
|
||||
|
||||
if (Cfg.Valid() && Cfg.SetUUID(DeviceDetails.UUID)) {
|
||||
DeviceDetails.Configuration = Cfg.get();
|
||||
@@ -168,6 +171,7 @@ namespace uCentral {
|
||||
Poco::Data::Keywords::use(Now),
|
||||
Poco::Data::Keywords::use(DeviceDetails.Venue);
|
||||
Insert.execute();
|
||||
SerialNumberCache()->AddSerialNumber(DeviceDetails.SerialNumber);
|
||||
return true;
|
||||
} else {
|
||||
Logger_.warning("Cannot create device: invalid configuration.");
|
||||
@@ -188,15 +192,15 @@ namespace uCentral {
|
||||
Logger_.information(Poco::format("AUTO-CREATION(%s)", SerialNumber));
|
||||
uint64_t Now = time(nullptr);
|
||||
|
||||
uCentral::Config::Capabilities Caps(Capabilities);
|
||||
Config::Capabilities Caps(Capabilities);
|
||||
GWObjects::DefaultConfiguration DefConfig;
|
||||
|
||||
if (FindDefaultConfigurationForModel(Caps.Model(), DefConfig)) {
|
||||
uCentral::Config::Config NewConfig(DefConfig.Configuration);
|
||||
Config::Config NewConfig(DefConfig.Configuration);
|
||||
NewConfig.SetUUID(Now);
|
||||
D.Configuration = NewConfig.get();
|
||||
} else {
|
||||
uCentral::Config::Config NewConfig;
|
||||
Config::Config NewConfig;
|
||||
NewConfig.SetUUID(Now);
|
||||
D.Configuration = NewConfig.get();
|
||||
}
|
||||
@@ -357,6 +361,7 @@ namespace uCentral {
|
||||
Delete << ConvertParams(St),
|
||||
Poco::Data::Keywords::use(SerialNumber);
|
||||
Delete.execute();
|
||||
SerialNumberCache()->DeleteSerialNumber(SerialNumber);
|
||||
return true;
|
||||
}
|
||||
catch (const Poco::Exception &E) {
|
||||
@@ -536,10 +541,6 @@ namespace uCentral {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Storage::GetDevices(uint64_t From, uint64_t HowMany, const std::string &Select, std::vector<GWObjects::Device> &Devices) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Storage::GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices) {
|
||||
|
||||
typedef Poco::Tuple<
|
||||
@@ -589,9 +590,9 @@ namespace uCentral {
|
||||
"LastFWUpdate, "
|
||||
"Venue, "
|
||||
"DevicePassword "
|
||||
"FROM Devices",
|
||||
Poco::Data::Keywords::into(Records),
|
||||
Poco::Data::Keywords::range(From, From + HowMany );
|
||||
"FROM Devices ORDER BY SerialNumber ASC " +
|
||||
ComputeRange(From, HowMany),
|
||||
Poco::Data::Keywords::into(Records);
|
||||
Select.execute();
|
||||
|
||||
|
||||
@@ -687,5 +688,164 @@ namespace uCentral {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Storage::UpdateSerialNumberCache() {
|
||||
try {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Statement Select(Sess);
|
||||
|
||||
Select << "SELECT SerialNumber FROM Devices";
|
||||
Select.execute();
|
||||
|
||||
Poco::Data::RecordSet RSet(Select);
|
||||
|
||||
bool More = RSet.moveFirst();
|
||||
while(More) {
|
||||
auto SerialNumber = RSet[0].convert<std::string>();
|
||||
SerialNumberCache()->AddSerialNumber(SerialNumber);
|
||||
More = RSet.moveNext();
|
||||
}
|
||||
return true;
|
||||
} catch(const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static std::string ComputeCertificateTag( GWObjects::CertificateValidation V) {
|
||||
switch(V) {
|
||||
case GWObjects::NO_CERTIFICATE: return "no certificate";
|
||||
case GWObjects::VALID_CERTIFICATE: return "non TIP certificate";
|
||||
case GWObjects::MISMATCH_SERIAL: return "serial mismatch";
|
||||
case GWObjects::VERIFIED: return "verified";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static const uint64_t SECONDS_MONTH = 30*24*60*60;
|
||||
static const uint64_t SECONDS_WEEK = 7*24*60*60;
|
||||
static const uint64_t SECONDS_DAY = 1*24*60*60;
|
||||
static const uint64_t SECONDS_HOUR = 1*24*60*60;
|
||||
|
||||
static std::string ComputeUpLastContactTag(uint64_t T1) {
|
||||
uint64_t T = T1 - std::time(nullptr);
|
||||
if( T>SECONDS_MONTH) return ">month";
|
||||
if( T>SECONDS_WEEK) return ">week";
|
||||
if( T>SECONDS_DAY) return ">day";
|
||||
if( T>SECONDS_HOUR) return ">hour";
|
||||
return "now";
|
||||
}
|
||||
|
||||
static std::string ComputeSanityTag(uint64_t T) {
|
||||
if( T==100) return "100%";
|
||||
if( T>90) return ">90%";
|
||||
if( T>60) return ">60%";
|
||||
return "<60%";
|
||||
}
|
||||
|
||||
static std::string ComputeUpTimeTag(uint64_t T) {
|
||||
if( T>SECONDS_MONTH) return ">month";
|
||||
if( T>SECONDS_WEEK) return ">week";
|
||||
if( T>SECONDS_DAY) return ">day";
|
||||
if( T>SECONDS_HOUR) return ">hour";
|
||||
return "now";
|
||||
}
|
||||
|
||||
static std::string ComputeLoadTag(uint64_t T) {
|
||||
float V=100.0*((float)T/65536.0);
|
||||
if(V<5.0) return "< 5%";
|
||||
if(V<25.0) return "< 25%";
|
||||
if(V<50.0) return "< 50%";
|
||||
if(V<75.0) return "< 75%";
|
||||
return ">75%";
|
||||
}
|
||||
|
||||
static std::string ComputeFreeMemoryTag(uint64_t Free, uint64_t Total) {
|
||||
float V = 100.0 * ((float)Free/(float(Total)));
|
||||
if(V<5.0) return "< 5%";
|
||||
if(V<25.0) return "< 25%";
|
||||
if(V<50.0) return "< 50%";
|
||||
if(V<75.0) return "< 75%";
|
||||
return ">75%";
|
||||
}
|
||||
|
||||
int ChannelToBand(uint64_t C) {
|
||||
if(C>=1 && C<=16) return 2;
|
||||
return 5;
|
||||
}
|
||||
|
||||
bool Storage::AnalyzeDevices(GWObjects::Dashboard &Dashboard) {
|
||||
try {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Statement Select(Sess);
|
||||
|
||||
Select << "SELECT SerialNumber, Compatible, Firmware FROM Devices";
|
||||
Select.execute();
|
||||
|
||||
Poco::Data::RecordSet RSet(Select);
|
||||
|
||||
bool More = RSet.moveFirst();
|
||||
while(More) {
|
||||
Dashboard.numberOfDevices++;
|
||||
auto SerialNumber = RSet[0].convert<std::string>();
|
||||
auto DeviceType = RSet[1].convert<std::string>();
|
||||
auto Revision = RSet[2].convert<std::string>();
|
||||
Types::UpdateCountedMap(Dashboard.vendors, OUIServer()->GetManufacturer(SerialNumber));
|
||||
Types::UpdateCountedMap(Dashboard.deviceType, DeviceType);
|
||||
|
||||
GWObjects::ConnectionState ConnState;
|
||||
if(DeviceRegistry()->GetState(SerialNumber, ConnState)) {
|
||||
Types::UpdateCountedMap(Dashboard.status, ConnState.Connected ? "connected" : "not connected");
|
||||
Types::UpdateCountedMap(Dashboard.certificates, ComputeCertificateTag(ConnState.VerifiedCertificate));
|
||||
Types::UpdateCountedMap(Dashboard.lastContact, ComputeUpLastContactTag(ConnState.LastContact));
|
||||
GWObjects::HealthCheck HC;
|
||||
if(DeviceRegistry()->GetHealthcheck(SerialNumber,HC))
|
||||
Types::UpdateCountedMap(Dashboard.healths, ComputeSanityTag(HC.Sanity));
|
||||
std::string LastStats;
|
||||
if(DeviceRegistry()->GetStatistics(SerialNumber, LastStats) && !LastStats.empty()) {
|
||||
Poco::JSON::Parser P;
|
||||
|
||||
auto RawObject = P.parse(LastStats).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if(RawObject->has("unit")) {
|
||||
auto Unit = RawObject->getObject("unit");
|
||||
if (Unit->has("uptime")) {
|
||||
Types::UpdateCountedMap(Dashboard.upTimes, ComputeUpTimeTag(Unit->get("uptime")));
|
||||
}
|
||||
if (Unit->has("memory")) {
|
||||
auto Memory = Unit->getObject("memory");
|
||||
uint64_t Free = Memory->get("free");
|
||||
uint64_t Total = Memory->get("total");
|
||||
Types::UpdateCountedMap(Dashboard.memoryUsed, ComputeFreeMemoryTag(Free, Total));
|
||||
}
|
||||
if (Unit->has("load")) {
|
||||
auto Load = Unit->getArray("load");
|
||||
Types::UpdateCountedMap(Dashboard.load1,
|
||||
ComputeLoadTag(Load->getElement<uint64_t>(0)));
|
||||
Types::UpdateCountedMap(Dashboard.load5,
|
||||
ComputeLoadTag(Load->getElement<uint64_t>(1)));
|
||||
Types::UpdateCountedMap(Dashboard.load15,
|
||||
ComputeLoadTag(Load->getElement<uint64_t>(2)));
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t Associations_2G, Associations_5G;
|
||||
StateProcessor::GetAssociations(RawObject, Associations_2G, Associations_5G);
|
||||
Types::UpdateCountedMap(Dashboard.associations, "2G", Associations_2G);
|
||||
Types::UpdateCountedMap(Dashboard.associations, "5G", Associations_5G);
|
||||
|
||||
}
|
||||
Types::UpdateCountedMap(Dashboard.status, ConnState.Connected ? "connected" : "not connected");
|
||||
} else {
|
||||
Types::UpdateCountedMap(Dashboard.status, "not connected");
|
||||
}
|
||||
More = RSet.moveNext();
|
||||
}
|
||||
return true;
|
||||
} catch(const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user