mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2025-12-24 14:27:00 +00:00
Compare commits
132 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d03dbcf96c | ||
|
|
aaded5fdd1 | ||
|
|
9121892a03 | ||
|
|
7a40cd26e7 | ||
|
|
f32fc95d0b | ||
|
|
9b0c06dc12 | ||
|
|
240b24f7b5 | ||
|
|
afc2c30621 | ||
|
|
46a5d59f99 | ||
|
|
41eb4eca2c | ||
|
|
ccc36c69ad | ||
|
|
94e40fab26 | ||
|
|
80a346e389 | ||
|
|
e0a688f67d | ||
|
|
d35d6b0597 | ||
|
|
98677ab128 | ||
|
|
6f5f51fcc6 | ||
|
|
f3ee562810 | ||
|
|
907e2fc7f1 | ||
|
|
9f67078884 | ||
|
|
86cbf39533 | ||
|
|
d79ab1069f | ||
|
|
f35d141d2c | ||
|
|
d758269f1f | ||
|
|
e301775fcd | ||
|
|
962867f5c9 | ||
|
|
f6c9b98a4b | ||
|
|
2645dd0800 | ||
|
|
374f56425e | ||
|
|
3015bba32d | ||
|
|
5502ea12e1 | ||
|
|
a211c62091 | ||
|
|
efd61ed51a | ||
|
|
5b0c775499 | ||
|
|
1c23a8584e | ||
|
|
c80c3be99e | ||
|
|
eadfa6bfc4 | ||
|
|
e594475f6c | ||
|
|
c4576a6858 | ||
|
|
90671250c1 | ||
|
|
f1d4a81946 | ||
|
|
1504b76dc7 | ||
|
|
9742304822 | ||
|
|
b19fcab532 | ||
|
|
6557e6e297 | ||
|
|
06b656d9e5 | ||
|
|
e215618c2c | ||
|
|
a0ee1a40d4 | ||
|
|
5c5aa3551b | ||
|
|
bd7daf4072 | ||
|
|
dad844795f | ||
|
|
41107af0d0 | ||
|
|
468a2553f8 | ||
|
|
37053a40b7 | ||
|
|
7eff8c9699 | ||
|
|
49d9030bf4 | ||
|
|
9e741c0348 | ||
|
|
95dc3c1a6c | ||
|
|
2fa7081f3f | ||
|
|
288773a727 | ||
|
|
06079115e6 | ||
|
|
5db21677dc | ||
|
|
5c7db88f10 | ||
|
|
0060e81fae | ||
|
|
1a6bf2d71b | ||
|
|
59a6de92d0 | ||
|
|
b7b013f669 | ||
|
|
d8be1eca90 | ||
|
|
d04f8965c3 | ||
|
|
ffdbe6f4da | ||
|
|
fafa915613 | ||
|
|
f5f0af0dcd | ||
|
|
23eb4d6b0b | ||
|
|
f9d6020c4f | ||
|
|
b9dfbdd5e8 | ||
|
|
8f9d708285 | ||
|
|
05b06d3eac | ||
|
|
8b68ab8ac7 | ||
|
|
80021d520f | ||
|
|
363cfa1998 | ||
|
|
9ea1a5cde6 | ||
|
|
faeb6bf6b8 | ||
|
|
1917b1346b | ||
|
|
3feaf9221d | ||
|
|
943b735150 | ||
|
|
02ce04261d | ||
|
|
eae5f4f5f9 | ||
|
|
8ec8a02924 | ||
|
|
12c34ef63d | ||
|
|
a54848b636 | ||
|
|
35c09940b4 | ||
|
|
cb4fdaab28 | ||
|
|
3501de22ed | ||
|
|
1f59fccc97 | ||
|
|
4307d23b00 | ||
|
|
b83345c91a | ||
|
|
76feb208bc | ||
|
|
efa49593da | ||
|
|
361d6fa22f | ||
|
|
f7d1b8f972 | ||
|
|
a9afc2dc2b | ||
|
|
8d949b97ea | ||
|
|
0d5a07ffe1 | ||
|
|
11972c2511 | ||
|
|
3081efebd8 | ||
|
|
b27039dcc8 | ||
|
|
847f107ac2 | ||
|
|
ec9766a544 | ||
|
|
7bdc148063 | ||
|
|
7284e9f100 | ||
|
|
03ecfbea25 | ||
|
|
eb1716e078 | ||
|
|
b11b8a2f22 | ||
|
|
845bb37c8c | ||
|
|
6f9f6495a0 | ||
|
|
04ef327a86 | ||
|
|
913b595587 | ||
|
|
7628af35ba | ||
|
|
cad8b7752b | ||
|
|
7175546f54 | ||
|
|
6186f46ec2 | ||
|
|
2413867bf3 | ||
|
|
545c539a08 | ||
|
|
b0cfed809f | ||
|
|
d5502e1527 | ||
|
|
714d02060c | ||
|
|
c8d0739692 | ||
|
|
d4b9d61e2b | ||
|
|
1f7f2f64ad | ||
|
|
f26ca31dbc | ||
|
|
92b6edc9a4 | ||
|
|
e1a2b46333 |
@@ -4,4 +4,4 @@ TabWidth: 4
|
||||
IndentWidth: 4
|
||||
UseTab: Always
|
||||
ColumnLimit: 100
|
||||
Language: Cpp
|
||||
Language: Cpp
|
||||
|
||||
8
.github/workflows/ci.yml
vendored
8
.github/workflows/ci.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
||||
DOCKER_REGISTRY_USERNAME: ucentral
|
||||
steps:
|
||||
- name: Checkout actions repo
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: Telecominfraproject/.github
|
||||
path: github
|
||||
@@ -58,10 +58,10 @@ jobs:
|
||||
- name: Get base branch name and set as output
|
||||
id: get_base_branch
|
||||
run: |
|
||||
echo ::set-output name=branch::$(echo ${GITHUB_BASE_REF##*/} | sed 's/master/main/g')
|
||||
echo "branch=$(echo ${GITHUB_BASE_REF##*/} | sed 's/master/main/g')" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Checkout actions repo
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: Telecominfraproject/.github
|
||||
path: github
|
||||
@@ -85,7 +85,7 @@ jobs:
|
||||
- docker
|
||||
steps:
|
||||
- name: Checkout actions repo
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: Telecominfraproject/.github
|
||||
path: github
|
||||
|
||||
2
.github/workflows/enforce-jira-issue-key.yml
vendored
2
.github/workflows/enforce-jira-issue-key.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout actions repo
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
repository: Telecominfraproject/.github
|
||||
path: github
|
||||
|
||||
40
.github/workflows/openapi-pages.yml
vendored
Normal file
40
.github/workflows/openapi-pages.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
name: Update OpenAPI docs on GitHub Pages
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'openapi/**'
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
docsgen:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Generate static HTML page with docs from OpenAPI definition
|
||||
run: |
|
||||
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli:v6.2.1 generate -i https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentralgw/master/openapi/owgw.yaml -g html2 --skip-validate-spec -o /local/
|
||||
|
||||
- name: Update OpenAPI docs
|
||||
run: |
|
||||
mkdir tmp-docs
|
||||
mv index.html tmp-docs/index.html
|
||||
mkdir -p ~/.ssh
|
||||
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
|
||||
echo https://tip-automation:${{ secrets.GIT_PUSH_PAT }}@github.com > ~/.git-credentials
|
||||
git config --global credential.helper store
|
||||
git config --global user.email "tip-automation@telecominfraproject.com"
|
||||
git config --global user.name "TIP Automation User"
|
||||
git pull
|
||||
git checkout gh-pages || git checkout -b gh-pages
|
||||
mv tmp-docs docs
|
||||
git add docs
|
||||
git commit -m'Update OpenAPI docs for GitHub pages'
|
||||
git push --set-upstream origin gh-pages
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
HELM_REPO_USERNAME: ucentral
|
||||
steps:
|
||||
- name: Checkout uCentral assembly chart repo
|
||||
uses: actions/checkout@v2
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
path: wlan-cloud-ucentralgw
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(owgw VERSION 2.7.1)
|
||||
project(owgw VERSION 2.8.0)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
@@ -39,12 +39,12 @@ endif()
|
||||
|
||||
find_package(Git QUIET)
|
||||
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} describe --always --tags
|
||||
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
RESULT_VARIABLE GIT_RESULT
|
||||
OUTPUT_VARIABLE GIT_HASH)
|
||||
if(NOT GIT_RESULT EQUAL "0")
|
||||
message(FATAL_ERROR "git describe --always --tags failed with ${GIT_RESULT}")
|
||||
message(FATAL_ERROR "git rev-parse --short HEAD failed with ${GIT_RESULT}")
|
||||
endif()
|
||||
string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}")
|
||||
endif()
|
||||
@@ -79,7 +79,6 @@ add_executable( owgw
|
||||
src/framework/KafkaTopics.h
|
||||
src/framework/MicroService.h
|
||||
src/framework/OpenWifiTypes.h
|
||||
src/framework/MicroServiceErrorHandler.h
|
||||
src/framework/orm.h
|
||||
src/framework/StorageClass.h
|
||||
src/framework/MicroServiceErrorHandler.h
|
||||
@@ -116,6 +115,7 @@ add_executable( owgw
|
||||
src/framework/RESTAPI_IntServer.h
|
||||
src/framework/RESTAPI_SystemCommand.h
|
||||
src/framework/RESTAPI_WebSocketServer.h
|
||||
src/framework/RESTAPI_SystemConfiguration.h
|
||||
src/framework/EventBusManager.cpp
|
||||
src/framework/EventBusManager.h
|
||||
src/framework/RESTAPI_PartHandler.h
|
||||
@@ -199,7 +199,7 @@ add_executable( owgw
|
||||
src/AP_WS_Process_telemetry.cpp
|
||||
src/AP_WS_Process_venuebroadcast.cpp
|
||||
src/RADSEC_server.h
|
||||
src/UI_GW_WebSocketNotifications.cpp src/UI_GW_WebSocketNotifications.h)
|
||||
src/UI_GW_WebSocketNotifications.cpp src/UI_GW_WebSocketNotifications.h src/framework/RESTAPI_SystemConfiguration.h src/AP_restrictions.h)
|
||||
|
||||
if(NOT SMALL_BUILD)
|
||||
|
||||
@@ -223,4 +223,4 @@ if(NOT SMALL_BUILD)
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(owgw PUBLIC PocoJSON)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -101,7 +101,7 @@ RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentr
|
||||
|
||||
COPY --from=owgw-build /owgw/cmake-build/owgw /openwifi/owgw
|
||||
COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib /usr/local/lib/
|
||||
COPY --from=poco-build /poco/cmake-build/lib /usr/local/lib
|
||||
COPY --from=poco-build /poco/cmake-build/lib /usr/local/lib/
|
||||
|
||||
RUN ldconfig
|
||||
|
||||
|
||||
@@ -5,6 +5,11 @@ This document will describe how the API is built and how to use it.
|
||||
This uses OpenAPI definition 3.0 and can be found [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/openapi/ucentral/owgw.yaml).
|
||||
All endpoints begin with `/api/v1`.
|
||||
|
||||
## OpenAPI docs
|
||||
You may get static page with OpenAPI docs generated from the definition on [GitHub Page](https://telecominfraproject.github.io/wlan-cloud-ucentralgw).
|
||||
|
||||
Also you may use [Swagger UI](https://petstore.swagger.io/#/) with OpenAPI definition file raw link (i.e. [latest version file](https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentralgw/master/openapi/owgw.yaml)) to get interactive docs page.
|
||||
|
||||
## The flow
|
||||
In order to use any of the API calls, you must obtain a token (I know - shocking). You do so by calling the end-point
|
||||
`/oauth2`. Once you obtain that `access-token`, you will need to pass it in the headers under `Authorization: Bearer <place your token here>`.
|
||||
|
||||
18
PROTOCOL.md
18
PROTOCOL.md
@@ -298,7 +298,8 @@ Controller sends this command when it believes the device should upgrade its fir
|
||||
"params" : {
|
||||
"serial" : <serial number> ,
|
||||
"when" : Optional - <UTC time when to upgrade the firmware, 0 mean immediate, this is a suggestion>,
|
||||
"uri" : <URI to download the firmware>
|
||||
"uri" : <URI to download the firmware>,
|
||||
"FWsignature" : <string representation of the signature for the FW> (optional)
|
||||
},
|
||||
"id" : <some number>
|
||||
}
|
||||
@@ -318,6 +319,13 @@ The device should answer:
|
||||
"id" : <same number>
|
||||
}
|
||||
```
|
||||
Here are the error values
|
||||
```text
|
||||
0: No error
|
||||
1: Bad firmware
|
||||
2: Missing signature
|
||||
```
|
||||
|
||||
|
||||
#### Controller wants the device to perform a factory reset
|
||||
Controller sends this command when it believes the device should upgrade its firmware.
|
||||
@@ -673,9 +681,11 @@ Controller sends this command to run a predefined script. Extreme care must be t
|
||||
"method" : "script" ,
|
||||
"params" : {
|
||||
"serial" : <serial number>,
|
||||
"type" : <one of "shell", "ucode">,
|
||||
"script" : <text blob containing the script>,
|
||||
"timeout" : <max timeout in seconds, default is 30>,
|
||||
"type" : <one of "shell", "ucode", "bundle">,
|
||||
"script" : <text blob containing the script, This must be vase64 encoded>,
|
||||
"timeout" : <max timeout in seconds, default is 30, unused if URI is supplied>,
|
||||
"uri": "<upload script results using this URI>",
|
||||
"signature" : "<signature for script>: must be supplied to restricted devices",
|
||||
"when" : <time when this will be performed as UTC seconds>
|
||||
},
|
||||
"id" : <some number>
|
||||
|
||||
0
ap_scripts/Author 1/AUTHORS.md
Normal file
0
ap_scripts/Author 1/AUTHORS.md
Normal file
0
ap_scripts/Author 1/LICENSE.md
Normal file
0
ap_scripts/Author 1/LICENSE.md
Normal file
0
ap_scripts/Author 1/README.md
Normal file
0
ap_scripts/Author 1/README.md
Normal file
36
ap_scripts/Author 1/content.yaml
Normal file
36
ap_scripts/Author 1/content.yaml
Normal file
@@ -0,0 +1,36 @@
|
||||
|
||||
scripts:
|
||||
- name: List Antennas
|
||||
description: A script to list all antennas on a device
|
||||
type: shell
|
||||
runtype:
|
||||
timeout: 30
|
||||
filename: listantennas.sh
|
||||
readme: listantennas.md
|
||||
help: https://authors.com/scripts/index.html
|
||||
- name: List AP Noise
|
||||
description: A script to list all noise values on all APs
|
||||
type: shell
|
||||
runtype:
|
||||
deferred: true
|
||||
filename: listnoise.sh
|
||||
readme: listnoise.md
|
||||
help: https://authors.com/scripts/index.html
|
||||
- name: Reset AP Statistics
|
||||
description: A script to reset the statistics on a given AP
|
||||
type: shell
|
||||
runtype:
|
||||
timeout: 30
|
||||
filename: resetstats.sh
|
||||
readme: resetstats.md
|
||||
help: https://authors.com/scripts/index.html
|
||||
- name: Gather kernel stats
|
||||
description: A script to all the kernel stats for an AP
|
||||
type: bundle
|
||||
runtype:
|
||||
deferred: true
|
||||
filename: kstats.uci
|
||||
readme: kstats.md
|
||||
help: https://authors.com/scripts/index.html
|
||||
|
||||
|
||||
0
ap_scripts/Author 1/kstats.md
Normal file
0
ap_scripts/Author 1/kstats.md
Normal file
0
ap_scripts/Author 1/kstats.uci
Normal file
0
ap_scripts/Author 1/kstats.uci
Normal file
0
ap_scripts/Author 1/listantennas.md
Normal file
0
ap_scripts/Author 1/listantennas.md
Normal file
1
ap_scripts/Author 1/listantennas.sh
Normal file
1
ap_scripts/Author 1/listantennas.sh
Normal file
@@ -0,0 +1 @@
|
||||
#!/bin/sh
|
||||
0
ap_scripts/Author 1/listnoise.md
Normal file
0
ap_scripts/Author 1/listnoise.md
Normal file
2
ap_scripts/Author 1/listnoise.sh
Normal file
2
ap_scripts/Author 1/listnoise.sh
Normal file
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
|
||||
0
ap_scripts/Author 1/resetstats.md
Normal file
0
ap_scripts/Author 1/resetstats.md
Normal file
2
ap_scripts/Author 1/resetstats.sh
Normal file
2
ap_scripts/Author 1/resetstats.sh
Normal file
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
|
||||
1
ap_scripts/README.md
Normal file
1
ap_scripts/README.md
Normal file
@@ -0,0 +1 @@
|
||||
# Repo for scripts
|
||||
40844
docs/index.html
Normal file
40844
docs/index.html
Normal file
File diff suppressed because one or more lines are too long
@@ -9,7 +9,7 @@ fullnameOverride: ""
|
||||
images:
|
||||
owgw:
|
||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owgw
|
||||
tag: v2.7.2
|
||||
tag: master
|
||||
pullPolicy: Always
|
||||
# regcred:
|
||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||
|
||||
@@ -107,6 +107,12 @@ components:
|
||||
type: string
|
||||
minLength: 2
|
||||
maxLength: 2
|
||||
FCC:
|
||||
type: boolean
|
||||
default: false
|
||||
certificateExpiryDate:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
DeviceWithStatus:
|
||||
type: object
|
||||
@@ -202,6 +208,12 @@ components:
|
||||
totalConnectionTime:
|
||||
type: integer
|
||||
format: int64
|
||||
restrictedDevice:
|
||||
type: boolean
|
||||
default: false
|
||||
certificateDate:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
DeviceList:
|
||||
type: object
|
||||
@@ -500,18 +512,20 @@ components:
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- uci
|
||||
- ucode
|
||||
- shell
|
||||
- bundle
|
||||
script:
|
||||
type: string
|
||||
scriptId:
|
||||
type: string
|
||||
format: uuid
|
||||
when:
|
||||
type: integer
|
||||
format: int64
|
||||
default: 0
|
||||
signature:
|
||||
type: string
|
||||
deferred:
|
||||
type: boolean
|
||||
uri:
|
||||
type: string
|
||||
|
||||
FactoryRequest:
|
||||
type: object
|
||||
@@ -921,9 +935,26 @@ components:
|
||||
items:
|
||||
$ref: '#/components/schemas/TagValuePair'
|
||||
|
||||
ExtraSystemConfiguration:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
parameterName:
|
||||
type: string
|
||||
parameterType:
|
||||
type: string
|
||||
enum:
|
||||
- string
|
||||
- integer
|
||||
- boolean
|
||||
- path
|
||||
parameterValue:
|
||||
{}
|
||||
|
||||
#########################################################################################
|
||||
##
|
||||
## End of uCentral system wide values
|
||||
## End of uCentral system-wide values
|
||||
##
|
||||
#########################################################################################
|
||||
BlackDeviceInfo:
|
||||
@@ -1890,6 +1921,12 @@ paths:
|
||||
schema:
|
||||
type: boolean
|
||||
required: false
|
||||
- in: query
|
||||
description: Return the number of matching records.
|
||||
name: countOnly
|
||||
schema:
|
||||
type: boolean
|
||||
required: false
|
||||
|
||||
responses:
|
||||
200:
|
||||
@@ -1899,6 +1936,8 @@ paths:
|
||||
schema:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/StatisticsRecords'
|
||||
- $ref: '#/components/schemas/DeviceCount'
|
||||
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
@@ -2076,6 +2115,11 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
- in: query
|
||||
name: FWsignature
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
requestBody:
|
||||
description: Command details
|
||||
content:
|
||||
@@ -2731,4 +2775,51 @@ paths:
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/systemConfiguration:
|
||||
get:
|
||||
tags:
|
||||
- SystemConfiguration
|
||||
summary: Retrieve system configuration items
|
||||
operationId: getSystemConfiguration
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/ExtraSystemConfiguration'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
put:
|
||||
tags:
|
||||
- SystemConfiguration
|
||||
summary: Set some or all system configuration
|
||||
operationId: setSystemConfiguration
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ExtraSystemConfiguration'
|
||||
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/ExtraSystemConfiguration'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- SystemConfiguration
|
||||
summary: Delete all additional system configuration
|
||||
operationId: deleteSystemConfiguration
|
||||
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/Success'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
@@ -71,27 +71,6 @@ namespace OpenWifi {
|
||||
Valid_ = true;
|
||||
}
|
||||
|
||||
class ThreadedCounter {
|
||||
public:
|
||||
ThreadedCounter(bool T, std::atomic_uint64_t &C) :
|
||||
C_(C),
|
||||
Threaded_(T) {
|
||||
if(Threaded_) {
|
||||
C_++;
|
||||
}
|
||||
}
|
||||
|
||||
~ThreadedCounter() {
|
||||
if(Threaded_ && C_>0) {
|
||||
C_--;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic_uint64_t &C_;
|
||||
bool Threaded_;
|
||||
};
|
||||
|
||||
bool AP_WS_Connection::ValidatedDevice() {
|
||||
if(DeviceValidated_)
|
||||
return true;
|
||||
@@ -99,6 +78,7 @@ namespace OpenWifi {
|
||||
if(!Valid_)
|
||||
return false;
|
||||
|
||||
std::lock_guard Lock(ConnectionMutex_);
|
||||
try {
|
||||
auto SockImpl = dynamic_cast<Poco::Net::WebSocketImpl *>(WS_->impl());
|
||||
auto SS = dynamic_cast<Poco::Net::SecureStreamSocketImpl*>(SockImpl->streamSocketImpl());
|
||||
@@ -155,6 +135,7 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
State_.certificateExpiryDate = PeerCert.expiresOn().timestamp().epochTime();
|
||||
SerialNumber_ = CN_;
|
||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
||||
|
||||
@@ -245,9 +226,9 @@ namespace OpenWifi {
|
||||
|
||||
auto SessionDeleted = AP_WS_Server()->EndSession(State_.sessionId, SerialNumberInt_);
|
||||
if (SessionDeleted) {
|
||||
WebNotificationSingleDevice_t N;
|
||||
GWWebSocketNotifications::SingleDevice_t N;
|
||||
N.content.serialNumber = SerialNumber_;
|
||||
WebSocketClientNotificationDeviceDisconnected(N);
|
||||
GWWebSocketNotifications::DeviceDisconnected(N);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -309,13 +290,13 @@ namespace OpenWifi {
|
||||
bool Sent;
|
||||
|
||||
StorageService()->AddCommand(SerialNumber_, Cmd, Storage::CommandExecutionType::COMMAND_EXECUTED);
|
||||
CommandManager()->PostCommand(CommandManager()->NextRPCId(),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
|
||||
CommandManager()->PostCommand(CommandManager()->Next_RPC_ID(),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
|
||||
|
||||
WebNotificationSingleDeviceConfigurationChange_t Notification;
|
||||
GWWebSocketNotifications::SingleDeviceConfigurationChange_t Notification;
|
||||
Notification.content.serialNumber = D.SerialNumber;
|
||||
Notification.content.oldUUID = UUID;
|
||||
Notification.content.newUUID = UpgradedUUID;
|
||||
WebSocketClientNotificationDeviceConfigurationChange(Notification);
|
||||
GWWebSocketNotifications::DeviceConfigurationChange(Notification);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -324,7 +305,7 @@ namespace OpenWifi {
|
||||
|
||||
void AP_WS_Connection::ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc) {
|
||||
poco_debug(Logger_,fmt::format("RECEIVED-RPC({}): {}.", CId_, Doc->get(uCentralProtocol::ID).toString()));
|
||||
CommandManager()->PostCommandResult(SerialNumber_, *Doc);
|
||||
CommandManager()->PostCommandResult(SerialNumber_, Doc);
|
||||
}
|
||||
|
||||
void AP_WS_Connection::ProcessJSONRPCEvent(Poco::JSON::Object::Ptr &Doc) {
|
||||
@@ -607,7 +588,6 @@ namespace OpenWifi {
|
||||
WS_->sendFrame("", 0,
|
||||
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
|
||||
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
||||
State_.MessageCount++;
|
||||
|
||||
if (KafkaManager()->Enabled()) {
|
||||
Poco::JSON::Object PingObject;
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include "Poco/Net/WebSocket.h"
|
||||
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
|
||||
#include "AP_restrictions.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace OpenWifi {
|
||||
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
||||
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf);
|
||||
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf);
|
||||
bool LookForUpgrade(const uint64_t UUID, uint64_t & UpgradedUUID);
|
||||
bool LookForUpgrade(uint64_t UUID, uint64_t & UpgradedUUID);
|
||||
static bool ExtractBase64CompressedData(const std::string & CompressedData, std::string & UnCompressedData, uint64_t compress_sz);
|
||||
void LogException(const Poco::Exception &E);
|
||||
inline Poco::Logger & Logger() { return Logger_; }
|
||||
@@ -53,6 +53,36 @@ namespace OpenWifi {
|
||||
bool StopWebSocketTelemetry(uint64_t RPCID);
|
||||
bool StopKafkaTelemetry(uint64_t RPCID);
|
||||
|
||||
inline void GetLastStats(std::string &LastStats) const {
|
||||
std::shared_lock G(ConnectionMutex_);
|
||||
LastStats = RawLastStats_;
|
||||
}
|
||||
|
||||
inline void SetLastStats(const std::string &LastStats) {
|
||||
std::unique_lock G(ConnectionMutex_);
|
||||
RawLastStats_ = LastStats;
|
||||
}
|
||||
|
||||
inline void SetLastHealthCheck(const GWObjects::HealthCheck &H) {
|
||||
std::unique_lock G(ConnectionMutex_);
|
||||
RawLastHealthcheck_ = H;
|
||||
}
|
||||
|
||||
inline void GetLastHealthCheck(GWObjects::HealthCheck &H) {
|
||||
std::shared_lock G(ConnectionMutex_);
|
||||
H = RawLastHealthcheck_;
|
||||
}
|
||||
|
||||
inline void GetState(GWObjects::ConnectionState &State) const {
|
||||
std::shared_lock G(ConnectionMutex_);
|
||||
State = State_;
|
||||
}
|
||||
|
||||
inline void GetRestrictions(AP_Restrictions & R) const {
|
||||
std::shared_lock G(ConnectionMutex_);
|
||||
R = Restrictions_;
|
||||
}
|
||||
|
||||
void Process_connect(Poco::JSON::Object::Ptr ParamsObj, const std::string &Serial);
|
||||
void Process_state(Poco::JSON::Object::Ptr ParamsObj);
|
||||
void Process_healthcheck(Poco::JSON::Object::Ptr ParamsObj);
|
||||
@@ -83,11 +113,15 @@ namespace OpenWifi {
|
||||
return true;
|
||||
}
|
||||
|
||||
friend class DeviceRegistry;
|
||||
friend class AP_WS_Server;
|
||||
|
||||
inline AP_Restrictions Restrictions() const {
|
||||
std::shared_lock G(ConnectionMutex_);
|
||||
return Restrictions_;
|
||||
}
|
||||
|
||||
private:
|
||||
// std::recursive_mutex LocalMutex_;
|
||||
mutable std::shared_mutex ConnectionMutex_;
|
||||
std::shared_mutex TelemetryMutex_;
|
||||
Poco::Logger &Logger_;
|
||||
Poco::Net::SocketReactor &Reactor_;
|
||||
@@ -101,22 +135,22 @@ namespace OpenWifi {
|
||||
uint64_t Errors_=0;
|
||||
Poco::Net::IPAddress PeerAddress_;
|
||||
volatile bool TelemetryReporting_ = false;
|
||||
volatile uint64_t TelemetryWebSocketRefCount_ = 0;
|
||||
volatile uint64_t TelemetryKafkaRefCount_ = 0;
|
||||
volatile uint64_t TelemetryWebSocketTimer_ = 0;
|
||||
volatile uint64_t TelemetryKafkaTimer_ = 0 ;
|
||||
volatile uint64_t TelemetryInterval_ = 0;
|
||||
volatile uint64_t TelemetryWebSocketPackets_=0;
|
||||
volatile uint64_t TelemetryKafkaPackets_=0;
|
||||
volatile uint64_t TelemetryWebSocketRefCount_ = 0;
|
||||
volatile uint64_t TelemetryKafkaRefCount_ = 0;
|
||||
volatile uint64_t TelemetryWebSocketTimer_ = 0;
|
||||
volatile uint64_t TelemetryKafkaTimer_ = 0 ;
|
||||
volatile uint64_t TelemetryInterval_ = 0;
|
||||
volatile uint64_t TelemetryWebSocketPackets_=0;
|
||||
volatile uint64_t TelemetryKafkaPackets_=0;
|
||||
GWObjects::ConnectionState State_;
|
||||
std::string LastStats_;
|
||||
GWObjects::HealthCheck LastHealthcheck_;
|
||||
std::string RawLastStats_;
|
||||
GWObjects::HealthCheck RawLastHealthcheck_;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> ConnectionStart_ = std::chrono::high_resolution_clock::now();
|
||||
std::chrono::duration<double, std::milli> ConnectionCompletionTime_{0.0};
|
||||
bool Threaded_=false;
|
||||
std::atomic_flag Dead_=false;
|
||||
std::atomic_bool DeviceValidated_=false;
|
||||
std::atomic_bool Valid_=false;
|
||||
AP_Restrictions Restrictions_;
|
||||
|
||||
static inline std::atomic_uint64_t ConcurrentStartingDevices_=0;
|
||||
|
||||
|
||||
@@ -24,10 +24,7 @@ namespace OpenWifi {
|
||||
ParamsObj->has(uCentralProtocol::CAPABILITIES)) {
|
||||
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
|
||||
auto Firmware = ParamsObj->get(uCentralProtocol::FIRMWARE).toString();
|
||||
auto CapabilitiesString = ParamsObj->get(uCentralProtocol::CAPABILITIES).toString();
|
||||
|
||||
Config::Capabilities Caps(CapabilitiesString);
|
||||
Compatible_ = Caps.Compatible();
|
||||
auto Capabilities = ParamsObj->getObject(uCentralProtocol::CAPABILITIES);
|
||||
|
||||
SerialNumber_ = Serial;
|
||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
||||
@@ -35,6 +32,12 @@ namespace OpenWifi {
|
||||
CommandManager()->ClearQueue(SerialNumberInt_);
|
||||
|
||||
AP_WS_Server()->SetSessionDetails(State_.sessionId,SerialNumberInt_);
|
||||
|
||||
std::lock_guard Lock(ConnectionMutex_);
|
||||
Config::Capabilities Caps(Capabilities);
|
||||
|
||||
Compatible_ = Caps.Compatible();
|
||||
|
||||
State_.UUID = UUID;
|
||||
State_.Firmware = Firmware;
|
||||
State_.PendingUUID = 0;
|
||||
@@ -46,40 +49,52 @@ namespace OpenWifi {
|
||||
IP = IP.substr(7);
|
||||
}
|
||||
|
||||
bool RestrictedDevice = false;
|
||||
if(ParamsObj->has("restricted") && ParamsObj->get("restricted").isBoolean()) {
|
||||
RestrictedDevice = true;
|
||||
if(Capabilities->has("restrictions")) {
|
||||
auto RestrictionObject = Capabilities->getObject("restrictions");
|
||||
Restrictions_.initialize(Logger_, SerialNumber_, RestrictionObject);
|
||||
}
|
||||
}
|
||||
|
||||
State_.locale = FindCountryFromIP()->Get(IP);
|
||||
GWObjects::Device DeviceInfo;
|
||||
auto DeviceExists = StorageService()->GetDevice(SerialNumber_,DeviceInfo);
|
||||
if (Daemon()->AutoProvisioning() && !DeviceExists) {
|
||||
StorageService()->CreateDefaultDevice(SerialNumber_, CapabilitiesString, Firmware,
|
||||
Compatible_, PeerAddress_);
|
||||
StorageService()->CreateDefaultDevice(SerialNumber_, Caps, Firmware, PeerAddress_);
|
||||
} else if (DeviceExists) {
|
||||
StorageService()->UpdateDeviceCapabilities(SerialNumber_, CapabilitiesString,
|
||||
Compatible_);
|
||||
bool Updated = false;
|
||||
StorageService()->UpdateDeviceCapabilities(SerialNumber_, Caps );
|
||||
int Updated{0};
|
||||
if(!Firmware.empty()) {
|
||||
if(Firmware!=DeviceInfo.Firmware) {
|
||||
DeviceInfo.Firmware = Firmware;
|
||||
DeviceInfo.LastFWUpdate = Utils::Now();
|
||||
Updated = true;
|
||||
++Updated;
|
||||
|
||||
WebNotificationSingleDeviceFirmwareChange_t Notification;
|
||||
GWWebSocketNotifications::SingleDeviceFirmwareChange_t Notification;
|
||||
Notification.content.serialNumber = SerialNumber_;
|
||||
Notification.content.newFirmware = Firmware;
|
||||
WebSocketClientNotificationDeviceFirmwareUpdated(Notification);
|
||||
GWWebSocketNotifications::DeviceFirmwareUpdated(Notification);
|
||||
} else if(DeviceInfo.LastFWUpdate==0) {
|
||||
DeviceInfo.LastFWUpdate = Utils::Now();
|
||||
Updated = true;
|
||||
++Updated;
|
||||
}
|
||||
}
|
||||
|
||||
if(DeviceInfo.locale != State_.locale) {
|
||||
DeviceInfo.locale = State_.locale;
|
||||
Updated = true;
|
||||
++Updated;
|
||||
}
|
||||
|
||||
if(Compatible_ != DeviceInfo.DeviceType) {
|
||||
DeviceInfo.DeviceType = Compatible_;
|
||||
Updated = true;
|
||||
++Updated;
|
||||
}
|
||||
|
||||
if(RestrictedDevice != DeviceInfo.restrictedDevice) {
|
||||
DeviceInfo.restrictedDevice = RestrictedDevice;
|
||||
++Updated;
|
||||
}
|
||||
|
||||
if(Updated) {
|
||||
@@ -120,9 +135,9 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
WebNotificationSingleDevice_t Notification;
|
||||
GWWebSocketNotifications::SingleDevice_t Notification;
|
||||
Notification.content.serialNumber = SerialNumber_;
|
||||
WebSocketClientNotificationDeviceConnected(Notification);
|
||||
GWWebSocketNotifications::DeviceConnected(Notification);
|
||||
|
||||
// std::cout << "Serial: " << SerialNumber_ << "Session: " << State_.sessionId << std::endl;
|
||||
|
||||
|
||||
@@ -11,65 +11,64 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void AP_WS_Connection::Process_healthcheck(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
poco_warning(Logger_, fmt::format(
|
||||
"INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
if (ParamsObj->has(uCentralProtocol::UUID) && ParamsObj->has(uCentralProtocol::SANITY) &&
|
||||
ParamsObj->has(uCentralProtocol::DATA)) {
|
||||
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
|
||||
auto Sanity = ParamsObj->get(uCentralProtocol::SANITY);
|
||||
auto CheckData = ParamsObj->get(uCentralProtocol::DATA).toString();
|
||||
if (CheckData.empty())
|
||||
CheckData = uCentralProtocol::EMPTY_JSON_DOC;
|
||||
void AP_WS_Connection::Process_healthcheck(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
poco_warning(Logger_, fmt::format(
|
||||
"INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
if (ParamsObj->has(uCentralProtocol::UUID) && ParamsObj->has(uCentralProtocol::SANITY) &&
|
||||
ParamsObj->has(uCentralProtocol::DATA)) {
|
||||
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
|
||||
auto Sanity = ParamsObj->get(uCentralProtocol::SANITY);
|
||||
auto CheckData = ParamsObj->get(uCentralProtocol::DATA).toString();
|
||||
if (CheckData.empty())
|
||||
CheckData = uCentralProtocol::EMPTY_JSON_DOC;
|
||||
|
||||
std::string request_uuid;
|
||||
if (ParamsObj->has(uCentralProtocol::REQUEST_UUID))
|
||||
request_uuid = ParamsObj->get(uCentralProtocol::REQUEST_UUID).toString();
|
||||
std::string request_uuid;
|
||||
if (ParamsObj->has(uCentralProtocol::REQUEST_UUID))
|
||||
request_uuid = ParamsObj->get(uCentralProtocol::REQUEST_UUID).toString();
|
||||
|
||||
if (request_uuid.empty()) {
|
||||
poco_trace(Logger_,
|
||||
fmt::format("HEALTHCHECK({}): UUID={} Updating.", CId_, UUID));
|
||||
if (request_uuid.empty()) {
|
||||
poco_trace(Logger_,
|
||||
fmt::format("HEALTHCHECK({}): UUID={} Updating.", CId_, UUID));
|
||||
} else {
|
||||
poco_trace(Logger_,
|
||||
fmt::format("HEALTHCHECK({}): UUID={} Updating for CMD={}.", CId_,
|
||||
UUID, request_uuid));
|
||||
}
|
||||
|
||||
uint64_t UpgradedUUID;
|
||||
LookForUpgrade(UUID,UpgradedUUID);
|
||||
State_.UUID = UpgradedUUID;
|
||||
|
||||
GWObjects::HealthCheck Check;
|
||||
|
||||
Check.SerialNumber = SerialNumber_;
|
||||
Check.Recorded = Utils::Now();
|
||||
Check.UUID = UUID;
|
||||
Check.Data = CheckData;
|
||||
Check.Sanity = Sanity;
|
||||
|
||||
StorageService()->AddHealthCheckData(Check);
|
||||
|
||||
if (!request_uuid.empty()) {
|
||||
StorageService()->SetCommandResult(request_uuid, CheckData);
|
||||
}
|
||||
|
||||
SetLastHealthCheck(Check);
|
||||
if (KafkaManager()->Enabled()) {
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
std::ostringstream OS;
|
||||
ParamsObj->set("timestamp", Utils::Now());
|
||||
Stringify.condense(ParamsObj, OS);
|
||||
KafkaManager()->PostMessage(KafkaTopics::HEALTHCHECK, SerialNumber_, OS.str());
|
||||
}
|
||||
} else {
|
||||
poco_trace(Logger_,
|
||||
fmt::format("HEALTHCHECK({}): UUID={} Updating for CMD={}.", CId_,
|
||||
UUID, request_uuid));
|
||||
poco_warning(Logger_, fmt::format("HEALTHCHECK({}): Missing parameter", CId_));
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t UpgradedUUID;
|
||||
LookForUpgrade(UUID,UpgradedUUID);
|
||||
State_.UUID = UpgradedUUID;
|
||||
|
||||
GWObjects::HealthCheck Check;
|
||||
|
||||
Check.SerialNumber = SerialNumber_;
|
||||
Check.Recorded = Utils::Now();
|
||||
Check.UUID = UUID;
|
||||
Check.Data = CheckData;
|
||||
Check.Sanity = Sanity;
|
||||
|
||||
StorageService()->AddHealthCheckData(Check);
|
||||
|
||||
if (!request_uuid.empty()) {
|
||||
StorageService()->SetCommandResult(request_uuid, CheckData);
|
||||
}
|
||||
|
||||
LastHealthcheck_ = Check;
|
||||
if (KafkaManager()->Enabled()) {
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
std::ostringstream OS;
|
||||
ParamsObj->set("timestamp", Utils::Now());
|
||||
Stringify.condense(ParamsObj, OS);
|
||||
KafkaManager()->PostMessage(KafkaTopics::HEALTHCHECK, SerialNumber_, OS.str());
|
||||
}
|
||||
} else {
|
||||
poco_warning(Logger_, fmt::format("HEALTHCHECK({}): Missing parameter", CId_));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -51,7 +51,7 @@ namespace OpenWifi {
|
||||
Poco::JSON::Stringifier::stringify(Params, O);
|
||||
Cmd.Details = O.str();
|
||||
bool Sent;
|
||||
CommandManager()->PostCommand(CommandManager()->NextRPCId(),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
|
||||
CommandManager()->PostCommand(CommandManager()->Next_RPC_ID(),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
|
||||
StorageService()->AddCommand(SerialNumber_, Cmd, Storage::CommandExecutionType::COMMAND_EXECUTED);
|
||||
poco_information(Logger_, fmt::format("RECOVERY({}): Recovery mode received, need for a reboot.", CId_));
|
||||
} else {
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace OpenWifi {
|
||||
uint64_t UpgradedUUID;
|
||||
LookForUpgrade(UUID,UpgradedUUID);
|
||||
State_.UUID = UpgradedUUID;
|
||||
LastStats_ = StateStr;
|
||||
SetLastStats(StateStr);
|
||||
|
||||
GWObjects::Statistics Stats{
|
||||
.SerialNumber = SerialNumber_, .UUID = UUID, .Data = StateStr};
|
||||
@@ -52,7 +52,9 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
StateUtils::ComputeAssociations(StateObj, State_.Associations_2G,
|
||||
State_.Associations_5G);
|
||||
State_.Associations_5G,
|
||||
State_.Associations_6G
|
||||
);
|
||||
|
||||
if (KafkaManager()->Enabled()) {
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
@@ -61,9 +63,9 @@ namespace OpenWifi {
|
||||
KafkaManager()->PostMessage(KafkaTopics::STATE, SerialNumber_, OS.str());
|
||||
}
|
||||
|
||||
WebNotificationSingleDevice_t N;
|
||||
GWWebSocketNotifications::SingleDevice_t N;
|
||||
N.content.serialNumber = SerialNumber_;
|
||||
WebSocketClientNotificationDeviceStatistics(N);
|
||||
GWWebSocketNotifications::DeviceStatistics(N);
|
||||
|
||||
} else {
|
||||
poco_warning(Logger_, fmt::format("STATE({}): Invalid request. Missing serial, uuid, or state", CId_));
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace OpenWifi {
|
||||
State_.websocketPackets = TelemetryWebSocketPackets_;
|
||||
TelemetryStream()->NotifyEndPoint(SerialNumberInt_, SS.str());
|
||||
} else {
|
||||
StopWebSocketTelemetry(CommandManager()->NextRPCId());
|
||||
StopWebSocketTelemetry(CommandManager()->Next_RPC_ID());
|
||||
}
|
||||
}
|
||||
if (TelemetryKafkaRefCount_) {
|
||||
@@ -44,7 +44,7 @@ namespace OpenWifi {
|
||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_TELEMETRY, SerialNumber_,
|
||||
SS.str());
|
||||
} else {
|
||||
StopKafkaTelemetry(CommandManager()->NextRPCId());
|
||||
StopKafkaTelemetry(CommandManager()->Next_RPC_ID());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -53,7 +53,7 @@ namespace OpenWifi {
|
||||
} else {
|
||||
// if we are ignoring telemetry, then close it down on the device.
|
||||
poco_debug(Logger_,fmt::format("TELEMETRY({}): Stopping runaway telemetry.",SerialNumber_));
|
||||
StopTelemetry(CommandManager()->NextRPCId());
|
||||
StopTelemetry(CommandManager()->Next_RPC_ID());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,9 +159,8 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void AP_WS_Server::onGarbageCollecting([[maybe_unused]] Poco::Timer &timer) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
if(Garbage_.size()>0) {
|
||||
std::cout << "Removing " << Garbage_.size() << " old connections." << std::endl;
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
if(!Garbage_.empty()) {
|
||||
Garbage_.clear();
|
||||
}
|
||||
|
||||
@@ -173,20 +172,15 @@ namespace OpenWifi {
|
||||
uint64_t total_connected_time=0;
|
||||
|
||||
auto now = Utils::Now();
|
||||
for (auto connection=SerialNumbers_.begin(); connection!=SerialNumbers_.end();) {
|
||||
|
||||
if(connection->second.second== nullptr) {
|
||||
connection++;
|
||||
for (const auto & connection:SerialNumbers_) {
|
||||
if(connection.second.second == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (connection->second.second->State_.Connected) {
|
||||
if (connection.second.second->State_.Connected) {
|
||||
NumberOfConnectedDevices_++;
|
||||
total_connected_time += (now - connection->second.second->State_.started);
|
||||
connection++;
|
||||
total_connected_time += (now - connection.second.second->State_.started);
|
||||
} else {
|
||||
NumberOfConnectingDevices_++;
|
||||
connection++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -198,11 +192,11 @@ namespace OpenWifi {
|
||||
NumberOfConnectedDevices_, NumberOfConnectingDevices_, AverageDeviceConnectionTime_));
|
||||
}
|
||||
|
||||
WebSocketClientNotificationNumberOfConnection_t Notification;
|
||||
GWWebSocketNotifications::NumberOfConnection_t Notification;
|
||||
Notification.content.numberOfConnectingDevices = NumberOfConnectingDevices_;
|
||||
Notification.content.numberOfDevices = NumberOfConnectedDevices_;
|
||||
Notification.content.averageConnectedTime = AverageDeviceConnectionTime_;
|
||||
WebSocketClientNotificationNumberOfConnections(Notification);
|
||||
GWWebSocketNotifications::NumberOfConnections(Notification);
|
||||
}
|
||||
|
||||
void AP_WS_Server::Stop() {
|
||||
@@ -221,36 +215,49 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
bool AP_WS_Server::GetStatistics(uint64_t SerialNumber, std::string &Statistics) const {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
|
||||
return false;
|
||||
Statistics = Device->second.second->LastStats_;
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
|
||||
return false;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->GetLastStats(Statistics);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AP_WS_Server::GetState(uint64_t SerialNumber, GWObjects::ConnectionState & State) const {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
|
||||
return false;
|
||||
State = Device->second.second->State_;
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
|
||||
return false;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->GetState(State);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AP_WS_Server::GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
|
||||
return false;
|
||||
|
||||
CheckData = Device->second.second->LastHealthcheck_;
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
|
||||
return false;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->GetLastHealthCheck(CheckData);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AP_WS_Server::SetSessionDetails(uint64_t connection_id, uint64_t SerialNumber) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
|
||||
auto Conn = Sessions_.find(connection_id);
|
||||
if(Conn == end(Sessions_))
|
||||
@@ -259,19 +266,19 @@ namespace OpenWifi {
|
||||
auto CurrentSerialNumber = SerialNumbers_.find(SerialNumber);
|
||||
if( (CurrentSerialNumber==SerialNumbers_.end()) ||
|
||||
(CurrentSerialNumber->second.first<connection_id)) {
|
||||
SerialNumbers_[SerialNumber] = std::make_pair(connection_id, Conn->second.first);
|
||||
SerialNumbers_[SerialNumber] = std::make_pair(connection_id, Conn->second);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool AP_WS_Server::EndSession(uint64_t session_id, uint64_t serial_number) {
|
||||
std::unique_lock G(LocalMutex_);
|
||||
std::lock_guard G(WSServerMutex_);
|
||||
|
||||
auto Session = Sessions_.find(session_id);
|
||||
if(Session==end(Sessions_))
|
||||
return false;
|
||||
|
||||
Garbage_.push_back(Session->second.first);
|
||||
Garbage_.push_back(Session->second);
|
||||
|
||||
auto Device = SerialNumbers_.find(serial_number);
|
||||
if (Device == end(SerialNumbers_)) {
|
||||
@@ -289,24 +296,45 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AP_WS_Server::Connected(uint64_t SerialNumber) const {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
|
||||
return false;
|
||||
bool AP_WS_Server::Connected(uint64_t SerialNumber, AP_Restrictions & Restrictions) const {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||
return false;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->GetRestrictions(Restrictions);
|
||||
return DevicePtr->State_.Connected;
|
||||
}
|
||||
|
||||
return Device->second.second->State_.Connected;
|
||||
bool AP_WS_Server::Connected(uint64_t SerialNumber) const {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||
return false;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
return DevicePtr->State_.Connected;
|
||||
}
|
||||
|
||||
bool AP_WS_Server::SendFrame(uint64_t SerialNumber, const std::string & Payload) const {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
|
||||
return false;
|
||||
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
|
||||
return false;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
try {
|
||||
// std::cout << "Device connection pointer: " << (uint64_t) Device->second.second << std::endl;
|
||||
return Device->second.second->Send(Payload);
|
||||
return DevicePtr->Send(Payload);
|
||||
} catch (...) {
|
||||
poco_debug(Logger(),fmt::format(": SendFrame: Could not send data to device '{}'", Utils::IntToSerialNumber(SerialNumber)));
|
||||
}
|
||||
@@ -314,39 +342,56 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void AP_WS_Server::StopWebSocketTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_) || Device->second.second==nullptr)
|
||||
return;
|
||||
Device->second.second->StopWebSocketTelemetry(RPCID);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||
return;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->StopWebSocketTelemetry(RPCID);
|
||||
}
|
||||
|
||||
void AP_WS_Server::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_) || Device->second.second==nullptr)
|
||||
return;
|
||||
Device->second.second->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime);
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||
return;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime);
|
||||
}
|
||||
|
||||
void AP_WS_Server::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
|
||||
return;
|
||||
Device->second.second->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime);
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||
return;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime);
|
||||
}
|
||||
|
||||
void AP_WS_Server::StopKafkaTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
|
||||
return;
|
||||
Device->second.second->StopKafkaTelemetry(RPCID);
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||
return;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->StopKafkaTelemetry(RPCID);
|
||||
}
|
||||
|
||||
void AP_WS_Server::GetTelemetryParameters(uint64_t SerialNumber , bool & TelemetryRunning,
|
||||
@@ -357,29 +402,34 @@ namespace OpenWifi {
|
||||
uint64_t & TelemetryKafkaCount,
|
||||
uint64_t & TelemetryWebSocketPackets,
|
||||
uint64_t & TelemetryKafkaPackets) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_)|| Device->second.second== nullptr)
|
||||
return;
|
||||
Device->second.second->GetTelemetryParameters(TelemetryRunning,
|
||||
TelemetryInterval,
|
||||
TelemetryWebSocketTimer,
|
||||
TelemetryKafkaTimer,
|
||||
TelemetryWebSocketCount,
|
||||
TelemetryKafkaCount,
|
||||
TelemetryWebSocketPackets,
|
||||
TelemetryKafkaPackets);
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||
return;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->GetTelemetryParameters(
|
||||
TelemetryRunning, TelemetryInterval, TelemetryWebSocketTimer, TelemetryKafkaTimer,
|
||||
TelemetryWebSocketCount, TelemetryKafkaCount, TelemetryWebSocketPackets,
|
||||
TelemetryKafkaPackets);
|
||||
}
|
||||
|
||||
bool AP_WS_Server::SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
|
||||
return false;
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
|
||||
return false;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
|
||||
try {
|
||||
return Device->second.second->SendRadiusAccountingData(buffer,size);
|
||||
return DevicePtr->SendRadiusAccountingData(buffer,size);
|
||||
} catch (...) {
|
||||
poco_debug(Logger(),fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'", SerialNumber));
|
||||
}
|
||||
@@ -387,13 +437,18 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
bool AP_WS_Server::SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
|
||||
return false;
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
|
||||
return false;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
|
||||
try {
|
||||
return Device->second.second->SendRadiusAuthenticationData(buffer,size);
|
||||
return DevicePtr->SendRadiusAuthenticationData(buffer,size);
|
||||
} catch (...) {
|
||||
poco_debug(Logger(),fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'", SerialNumber));
|
||||
}
|
||||
@@ -401,13 +456,18 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
bool AP_WS_Server::SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
|
||||
return false;
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
|
||||
return false;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
|
||||
try {
|
||||
return Device->second.second->SendRadiusCoAData(buffer,size);
|
||||
return DevicePtr->SendRadiusCoAData(buffer,size);
|
||||
} catch (...) {
|
||||
poco_debug(Logger(),fmt::format(": SendRadiusCoAData: Could not send data to device '{}'", SerialNumber));
|
||||
}
|
||||
|
||||
@@ -106,16 +106,16 @@ namespace OpenWifi {
|
||||
[[nodiscard]] inline bool Running() const { return Running_; }
|
||||
|
||||
inline void AddConnection(uint64_t session_id, std::shared_ptr<AP_WS_Connection> Connection ) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
Sessions_[session_id] = std::make_pair(std::move(Connection),false);
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
Sessions_[session_id] = std::move(Connection);
|
||||
}
|
||||
|
||||
inline std::shared_ptr<AP_WS_Connection> FindConnection(uint64_t session_id) const {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
|
||||
auto Connection = Sessions_.find(session_id);
|
||||
if(Connection!=end(Sessions_))
|
||||
return Connection->second.first;
|
||||
return Connection->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -134,6 +134,7 @@ namespace OpenWifi {
|
||||
}
|
||||
bool GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const ;
|
||||
|
||||
bool Connected(uint64_t SerialNumber, AP_Restrictions & Restrictions) const ;
|
||||
bool Connected(uint64_t SerialNumber) const ;
|
||||
|
||||
inline bool SendFrame(const std::string & SerialNumber, const std::string & Payload) const {
|
||||
@@ -171,7 +172,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::recursive_mutex LocalMutex_;
|
||||
mutable std::recursive_mutex WSServerMutex_;
|
||||
std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_;
|
||||
std::list<std::unique_ptr<Poco::Net::HTTPServer>> WebServers_;
|
||||
Poco::Net::SocketReactor Reactor_;
|
||||
@@ -183,7 +184,8 @@ namespace OpenWifi {
|
||||
bool SimulatorEnabled_=false;
|
||||
std::unique_ptr<AP_WS_ReactorThreadPool> Reactor_pool_;
|
||||
std::atomic_bool Running_=false;
|
||||
std::map<uint64_t, std::pair<std::shared_ptr<AP_WS_Connection>,bool>> Sessions_;
|
||||
// std::map<uint64_t, std::pair<std::shared_ptr<AP_WS_Connection>,bool>> Sessions_;
|
||||
std::map<std::uint64_t, std::shared_ptr<AP_WS_Connection>> Sessions_;
|
||||
std::map<uint64_t, std::pair<uint64_t,std::shared_ptr<AP_WS_Connection>>> SerialNumbers_;
|
||||
std::atomic_bool AllowSerialNumberMismatch_=true;
|
||||
std::atomic_uint64_t MismatchDepth_=2;
|
||||
|
||||
77
src/AP_restrictions.h
Normal file
77
src/AP_restrictions.h
Normal file
@@ -0,0 +1,77 @@
|
||||
//
|
||||
// Created by stephane bourque on 2022-11-14.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <set>
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/Logger.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
/*
|
||||
{
|
||||
“country”: [
|
||||
“US”, “CA”
|
||||
],
|
||||
“dfs”: true,
|
||||
“ssh”: true,
|
||||
“rtty”: true,
|
||||
“tty”: true,
|
||||
“developer”: true,
|
||||
“sysupgrade”: true,
|
||||
“commands”: true
|
||||
}
|
||||
*/
|
||||
|
||||
namespace OpenWifi {
|
||||
class AP_Restrictions {
|
||||
public:
|
||||
inline bool initialize(Poco::Logger & Logger, const std::string & serialNumber, const Poco::JSON::Object::Ptr &O) {
|
||||
try {
|
||||
dfs_ = O->optValue("dfs",false);
|
||||
ssh_ = O->optValue("ssh",false);
|
||||
rtty_ = O->optValue("rtty",false);
|
||||
tty_ = O->optValue("tty",false);
|
||||
developer_ = O->optValue("developer",false);
|
||||
sysupgrade_ = O->optValue("sysupgrade",false);
|
||||
commands_ = O->optValue("commands",false);
|
||||
if(O->has("country") && O->isArray("country")) {
|
||||
auto Countries = O->getArray("country");
|
||||
for(const auto &country:*Countries) {
|
||||
countries_.insert(Poco::toLower(country.toString()));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} catch (...) {
|
||||
poco_error(Logger,fmt::format("Cannot parse restrictions for device {}", serialNumber));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline auto dfs_not_allowed() const { return dfs_; }
|
||||
[[nodiscard]] inline auto ssh_not_allowed() const { return ssh_; }
|
||||
[[nodiscard]] inline auto rtty_not_allowed() const { return rtty_; }
|
||||
[[nodiscard]] inline auto tty_not_allowed() const { return tty_; }
|
||||
[[nodiscard]] inline auto developer_not_allowed() const { return developer_; }
|
||||
[[nodiscard]] inline auto sysupgrade_not_allowed() const { return sysupgrade_; }
|
||||
[[nodiscard]] inline auto commands_not_allowed() const { return commands_; }
|
||||
[[nodiscard]] inline bool valid_country(const std::string &c) const {
|
||||
if(countries_.empty())
|
||||
return true;
|
||||
return countries_.find(Poco::toLower(c))!=countries_.end();
|
||||
}
|
||||
|
||||
private:
|
||||
std::set<std::string> countries_;
|
||||
bool dfs_ = false;
|
||||
bool ssh_ = false;
|
||||
bool rtty_ = false;
|
||||
bool tty_ = false;
|
||||
bool developer_ = false;
|
||||
bool sysupgrade_ = false;
|
||||
bool commands_ = false;
|
||||
};
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "CentralConfig.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
const std::string PlatformCacheFileName{"/plat_cache.json"};
|
||||
@@ -27,17 +28,17 @@ namespace OpenWifi {
|
||||
return instance;
|
||||
}
|
||||
|
||||
inline void Add(const std::string & DeviceType, const std::string & Platform, const std::string & FullCapabilities) {
|
||||
if(DeviceType.empty() || Platform.empty())
|
||||
inline void Add(const Config::Capabilities &Caps) {
|
||||
if(Caps.Compatible().empty() || Caps.Platform().empty())
|
||||
return;
|
||||
|
||||
std::lock_guard G(Mutex_);
|
||||
if(!PlatformsLoaded_)
|
||||
LoadPlatforms();
|
||||
auto P = Poco::toUpper(Platform);
|
||||
auto Hint = Platforms_.find(DeviceType);
|
||||
auto P = Poco::toUpper(Caps.Platform());
|
||||
auto Hint = Platforms_.find(Caps.Compatible());
|
||||
if(Hint==Platforms_.end()) {
|
||||
Platforms_.insert(std::make_pair(DeviceType,P));
|
||||
Platforms_.insert(std::make_pair(Caps.Compatible(),P));
|
||||
SavePlatforms();
|
||||
} else if(Hint->second != P) {
|
||||
Hint->second = P;
|
||||
@@ -47,12 +48,14 @@ namespace OpenWifi {
|
||||
if(!CapabilitiesLoaded_)
|
||||
LoadCapabilities();
|
||||
|
||||
auto CapHint = Capabilities_.find(DeviceType);
|
||||
auto CapHint = Capabilities_.find(Caps.Compatible());
|
||||
if(CapHint==Capabilities_.end()) {
|
||||
Capabilities_[DeviceType] = nlohmann::json::parse(FullCapabilities);
|
||||
auto C = nlohmann::json::parse(Caps.AsString());
|
||||
C.erase("restrictions");
|
||||
Capabilities_[Caps.Compatible()] = nlohmann::json::parse(Caps.AsString());
|
||||
SaveCapabilities();
|
||||
} else {
|
||||
CapHint->second = nlohmann::json::parse(FullCapabilities);
|
||||
CapHint->second = nlohmann::json::parse(Caps.AsString());
|
||||
SaveCapabilities();
|
||||
}
|
||||
}
|
||||
@@ -150,4 +153,7 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline auto CapabilitiesCache() { return CapabilitiesCache::instance(); };
|
||||
|
||||
}
|
||||
@@ -228,7 +228,7 @@ R"lit(
|
||||
return DefaultConfiguration_;
|
||||
}
|
||||
|
||||
std::string Capabilities::Default() {
|
||||
/* std::string Capabilities::Default() {
|
||||
return std::string(R"lit({"model":{"id":"linksys,ea8300","name":"Linksys EA8300 (Dallas)"},
|
||||
"network":{"lan":{"ifname":"eth0","protocol":"static"},"wan":{"ifname":"eth1","protocol":"dhcp"}},
|
||||
"switch":{"switch0":{"enable":true,"reset":true,"ports":[{"num":0,"device":"eth0","need_tag":false,
|
||||
@@ -242,27 +242,23 @@ R"lit(
|
||||
"platform/soc/a800000.wifi":{"band":["5l"],"ht_capa":6639,"vht_capa":865687986,"htmode":["HT20","HT40","VHT20","VHT40","VHT80"],
|
||||
"tx_ant":3,"rx_ant":3,"channels":[36,40,44,48,52,56,60,64]}}})lit");
|
||||
}
|
||||
*/
|
||||
|
||||
void Capabilities::Parse() {
|
||||
if(Capabilities_.empty())
|
||||
Capabilities_=Default();
|
||||
|
||||
Capabilities::Capabilities(const Poco::JSON::Object::Ptr &Caps) {
|
||||
try {
|
||||
Poco::JSON::Parser parser;
|
||||
|
||||
auto Result = parser.parse(Capabilities_);
|
||||
auto Objects = Result.extract<Poco::JSON::Object::Ptr>();
|
||||
if(Caps->has("compatible"))
|
||||
Compatible_ = Caps->get("compatible").toString();
|
||||
|
||||
if(Objects->has("compatible"))
|
||||
Compatible_ = Objects->get("compatible").toString();
|
||||
if(Caps->has("model"))
|
||||
Model_ = Caps->get("model").toString();
|
||||
|
||||
if(Objects->has("model"))
|
||||
Model_ = Objects->get("model").toString();
|
||||
if(Caps->has("platform"))
|
||||
Platform_ = Caps->get("platform").toString();
|
||||
|
||||
if(Objects->has("platform"))
|
||||
Platform_ = Objects->get("platform").toString();
|
||||
|
||||
Parsed_ = true ;
|
||||
std::ostringstream OS;
|
||||
Caps->stringify(OS);
|
||||
AsString_ = OS.str();
|
||||
}
|
||||
catch ( const Poco::Exception & E )
|
||||
{
|
||||
@@ -270,22 +266,20 @@ R"lit(
|
||||
}
|
||||
}
|
||||
|
||||
const std::string & Capabilities::Compatible() {
|
||||
if(!Parsed_)
|
||||
Parse();
|
||||
const std::string & Capabilities::Compatible() const {
|
||||
return Compatible_;
|
||||
}
|
||||
|
||||
const std::string & Capabilities::Model() {
|
||||
if(!Parsed_)
|
||||
Parse();
|
||||
const std::string & Capabilities::Model() const {
|
||||
return Model_;
|
||||
}
|
||||
|
||||
const std::string & Capabilities::Platform() {
|
||||
if(!Parsed_)
|
||||
Parse();
|
||||
const std::string & Capabilities::Platform() const {
|
||||
return Platform_;
|
||||
}
|
||||
|
||||
const std::string & Capabilities::AsString() const {
|
||||
return AsString_;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -35,29 +35,28 @@ namespace OpenWifi::Config {
|
||||
|
||||
class Capabilities {
|
||||
public:
|
||||
explicit Capabilities(std::string Caps)
|
||||
: Capabilities_(std::move(Caps))
|
||||
{
|
||||
explicit Capabilities(const Poco::JSON::Object::Ptr &Caps);
|
||||
|
||||
}
|
||||
|
||||
Capabilities()
|
||||
/* Capabilities()
|
||||
{
|
||||
Capabilities_ = Default();
|
||||
}
|
||||
|
||||
static std::string Default();
|
||||
|
||||
[[nodiscard]] const std::string & Get() const { return Capabilities_; };
|
||||
[[nodiscard]] const std::string & Compatible();
|
||||
[[nodiscard]] const std::string & Model();
|
||||
[[nodiscard]] const std::string & Platform();
|
||||
*/
|
||||
|
||||
[[nodiscard]] const std::string & Compatible() const;
|
||||
[[nodiscard]] const std::string & Model() const;
|
||||
[[nodiscard]] const std::string & Platform() const;
|
||||
[[nodiscard]] const std::string & AsString() const;
|
||||
|
||||
private:
|
||||
std::string Capabilities_;
|
||||
bool Parsed_=false;
|
||||
std::string Compatible_;
|
||||
std::string Model_;
|
||||
std::string Platform_;
|
||||
std::string AsString_;
|
||||
|
||||
void Parse();
|
||||
};
|
||||
|
||||
@@ -31,25 +31,24 @@ namespace OpenWifi {
|
||||
|
||||
try {
|
||||
if (Resp != nullptr) {
|
||||
const Poco::JSON::Object &Payload = Resp->Payload_;
|
||||
const std::string &SerialNumber = Resp->SerialNumber_;
|
||||
Poco::JSON::Object::Ptr Payload = Resp->Payload_;
|
||||
std::string SerialNumberStr = Utils::IntToSerialNumber(Resp->SerialNumber_);
|
||||
|
||||
std::ostringstream SS;
|
||||
Payload.stringify(SS);
|
||||
Payload->stringify(SS);
|
||||
|
||||
if (!Payload.has(uCentralProtocol::ID)) {
|
||||
poco_error(Logger(), fmt::format("({}): Invalid RPC response.", SerialNumber));
|
||||
if (!Payload->has(uCentralProtocol::ID)) {
|
||||
poco_error(Logger(), fmt::format("({}): Invalid RPC response.", SerialNumberStr));
|
||||
} else {
|
||||
uint64_t ID = Payload.get(uCentralProtocol::ID);
|
||||
poco_debug(Logger(),fmt::format("({}): Processing {} response.", SerialNumber, ID));
|
||||
uint64_t ID = Payload->get(uCentralProtocol::ID);
|
||||
poco_debug(Logger(),fmt::format("({}): Processing {} response.", SerialNumberStr, ID));
|
||||
if (ID > 1) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
auto RPC = OutStandingRequests_.find(ID);
|
||||
if (RPC == OutStandingRequests_.end() ||
|
||||
RPC->second.SerialNumber !=
|
||||
Utils::SerialNumberToInt(Resp->SerialNumber_)) {
|
||||
RPC->second.SerialNumber != Resp->SerialNumber_) {
|
||||
poco_debug(Logger(),
|
||||
fmt::format("({}): RPC {} completed.", SerialNumber, ID));
|
||||
fmt::format("({}): RPC {} completed.", SerialNumberStr, ID));
|
||||
} else {
|
||||
std::chrono::duration<double, std::milli> rpc_execution_time =
|
||||
std::chrono::high_resolution_clock::now() -
|
||||
@@ -61,7 +60,7 @@ namespace OpenWifi {
|
||||
}
|
||||
poco_debug(Logger(),
|
||||
fmt::format("({}): Received RPC answer {}. Command={}",
|
||||
SerialNumber, ID, RPC->second.Command));
|
||||
SerialNumberStr, ID, RPC->second.Command));
|
||||
OutStandingRequests_.erase(ID);
|
||||
}
|
||||
}
|
||||
@@ -206,7 +205,7 @@ namespace OpenWifi {
|
||||
poco_information(MyLogger, fmt::format("{}: Serial={} Command={} Preparing execution.",
|
||||
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
|
||||
auto Params = P.parse(Cmd.Details).extract<Poco::JSON::Object::Ptr>();
|
||||
auto Result = PostCommandDisk(NextRPCId(), Cmd.SerialNumber, Cmd.Command,
|
||||
auto Result = PostCommandDisk(Next_RPC_ID(), Cmd.SerialNumber, Cmd.Command,
|
||||
*Params, Cmd.UUID, Sent);
|
||||
if (Sent) {
|
||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||
|
||||
@@ -31,22 +31,22 @@ namespace OpenWifi {
|
||||
|
||||
class RPCResponseNotification: public Poco::Notification {
|
||||
public:
|
||||
RPCResponseNotification(const std::string &ser,
|
||||
const Poco::JSON::Object &pl) :
|
||||
RPCResponseNotification(std::uint64_t ser,
|
||||
Poco::JSON::Object::Ptr pl) :
|
||||
SerialNumber_(ser),
|
||||
Payload_(pl)
|
||||
Payload_(std::move(pl))
|
||||
{
|
||||
|
||||
}
|
||||
std::string SerialNumber_;
|
||||
Poco::JSON::Object Payload_;
|
||||
std::uint64_t SerialNumber_;
|
||||
Poco::JSON::Object::Ptr Payload_;
|
||||
};
|
||||
|
||||
|
||||
class CommandManager : public SubSystemServer, Poco::Runnable {
|
||||
public:
|
||||
typedef Poco::JSON::Object objtype_t;
|
||||
typedef std::promise<objtype_t> promise_type_t;
|
||||
using objtype_t = Poco::JSON::Object::Ptr;
|
||||
using promise_type_t = std::promise<objtype_t>;
|
||||
|
||||
struct CommandInfo {
|
||||
std::uint64_t Id=0;
|
||||
@@ -58,31 +58,30 @@ namespace OpenWifi {
|
||||
};
|
||||
|
||||
struct RPCResponse {
|
||||
std::string serialNumber;
|
||||
Poco::JSON::Object payload;
|
||||
std::uint64_t serialNumber;
|
||||
Poco::JSON::Object::Ptr payload;
|
||||
|
||||
explicit RPCResponse(const std::string &ser, const Poco::JSON::Object &pl)
|
||||
explicit RPCResponse(std::uint64_t ser, Poco::JSON::Object::Ptr pl)
|
||||
:
|
||||
serialNumber(ser),
|
||||
payload(pl) {
|
||||
payload(std::move(pl)) {
|
||||
}
|
||||
};
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void WakeUp();
|
||||
inline void PostCommandResult(const std::string &SerialNumber, const Poco::JSON::Object &Obj) {
|
||||
// RPCResponseQueue_->Write(RPCResponse{.serialNumber=SerialNumber, .payload = Obj});
|
||||
ResponseQueue_.enqueueNotification(new RPCResponseNotification(SerialNumber,Obj));
|
||||
inline void PostCommandResult(const std::string &SerialNumber, Poco::JSON::Object::Ptr Obj) {
|
||||
ResponseQueue_.enqueueNotification(new RPCResponseNotification(Utils::SerialNumberToInt(SerialNumber),std::move(Obj)));
|
||||
}
|
||||
|
||||
std::shared_ptr<promise_type_t> PostCommandOneWayDisk(uint64_t RPCID,
|
||||
std::shared_ptr<promise_type_t> PostCommandOneWayDisk(uint64_t RPC_ID,
|
||||
const std::string &SerialNumber,
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
bool & Sent) {
|
||||
return PostCommand(RPCID, SerialNumber,
|
||||
return PostCommand(RPC_ID, SerialNumber,
|
||||
Method,
|
||||
Params,
|
||||
UUID,
|
||||
@@ -90,13 +89,13 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
std::shared_ptr<promise_type_t> PostCommandDisk(
|
||||
uint64_t RPCID,
|
||||
uint64_t RPC_ID,
|
||||
const std::string &SerialNumber,
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
bool & Sent) {
|
||||
return PostCommand(RPCID,
|
||||
return PostCommand(RPC_ID,
|
||||
SerialNumber,
|
||||
Method,
|
||||
Params,
|
||||
@@ -105,13 +104,13 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
std::shared_ptr<promise_type_t> PostCommand(
|
||||
uint64_t RPCID,
|
||||
uint64_t RPC_ID,
|
||||
const std::string &SerialNumber,
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
bool & Sent) {
|
||||
return PostCommand(RPCID, SerialNumber,
|
||||
return PostCommand(RPC_ID, SerialNumber,
|
||||
Method,
|
||||
Params,
|
||||
UUID,
|
||||
@@ -120,13 +119,13 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
std::shared_ptr<promise_type_t> PostCommandOneWay(
|
||||
uint64_t RPCID,
|
||||
uint64_t RPC_ID,
|
||||
const std::string &SerialNumber,
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
bool & Sent) {
|
||||
return PostCommand(RPCID,
|
||||
return PostCommand(RPC_ID,
|
||||
SerialNumber,
|
||||
Method,
|
||||
Params,
|
||||
@@ -147,8 +146,7 @@ namespace OpenWifi {
|
||||
inline bool Running() const { return Running_; }
|
||||
void onJanitorTimer(Poco::Timer & timer);
|
||||
void onCommandRunnerTimer(Poco::Timer & timer);
|
||||
void onRPCAnswer(bool& b);
|
||||
inline uint64_t NextRPCId() { return ++Id_; }
|
||||
inline uint64_t Next_RPC_ID() { return ++Id_; }
|
||||
|
||||
void RemovePendingCommand(std::uint64_t Id) {
|
||||
std::unique_lock Lock(LocalMutex_);
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "framework/ConfigurationValidator.h"
|
||||
#include "rttys/RTTYS_server.h"
|
||||
#include "framework/UI_WebSocketClientServer.h"
|
||||
#include "UI_GW_WebSocketNotifications.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class Daemon *Daemon::instance() {
|
||||
@@ -105,6 +106,7 @@ namespace OpenWifi {
|
||||
|
||||
void DaemonPostInitialization(Poco::Util::Application &self) {
|
||||
Daemon()->PostInitialization(self);
|
||||
GWWebSocketNotifications::Register();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -126,34 +126,32 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
// if you pass in an empty UUID, it will just clean the list and not add it.
|
||||
bool FileUploader::AddUUID( const std::string & UUID) {
|
||||
bool FileUploader::AddUUID( const std::string & UUID, std::chrono::seconds WaitTimeInSeconds, const std::string &Type) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
uint64_t now = Utils::Now();
|
||||
|
||||
// remove old stuff...
|
||||
for(auto i=OutStandingUploads_.begin();i!=OutStandingUploads_.end();) {
|
||||
if ((now-i->second) > (60 * 30))
|
||||
i = OutStandingUploads_.erase(i);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
|
||||
if(!UUID.empty())
|
||||
OutStandingUploads_[UUID] = now;
|
||||
|
||||
auto Func=[now](const UploadId &I) -> bool {
|
||||
return (now > I.Expires);
|
||||
};
|
||||
OutStandingUploads_.erase(std::remove_if(OutStandingUploads_.begin(),OutStandingUploads_.end(),Func),OutStandingUploads_.end());
|
||||
OutStandingUploads_.emplace_back(UploadId{UUID, now + WaitTimeInSeconds.count(), Type});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FileUploader::ValidRequest(const std::string &UUID) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
return OutStandingUploads_.find(UUID)!=OutStandingUploads_.end();
|
||||
auto Func = [UUID](const UploadId &P) -> bool {
|
||||
return (P.UUID==UUID);
|
||||
};
|
||||
return std::find_if(OutStandingUploads_.begin(), OutStandingUploads_.end(), Func) != end(OutStandingUploads_);
|
||||
}
|
||||
|
||||
void FileUploader::RemoveRequest(const std::string &UUID) {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
OutStandingUploads_.erase(UUID);
|
||||
auto Func = [UUID](const UploadId &P) -> bool {
|
||||
return (P.UUID==UUID);
|
||||
};
|
||||
OutStandingUploads_.erase(std::remove_if(OutStandingUploads_.begin(),OutStandingUploads_.end(),Func),OutStandingUploads_.end());
|
||||
}
|
||||
|
||||
class FileUploaderPartHandler2 : public Poco::Net::PartHandler {
|
||||
@@ -193,9 +191,10 @@ namespace OpenWifi {
|
||||
class FormRequestHandler: public Poco::Net::HTTPRequestHandler
|
||||
{
|
||||
public:
|
||||
explicit FormRequestHandler(std::string UUID, Poco::Logger & L):
|
||||
explicit FormRequestHandler(std::string UUID, Poco::Logger & L, const std::string &Type):
|
||||
UUID_(std::move(UUID)),
|
||||
Logger_(L)
|
||||
Logger_(L),
|
||||
Type_(Type)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -230,8 +229,8 @@ namespace OpenWifi {
|
||||
Poco::StreamCopier::copyStream(Reader.stream(), FileContent);
|
||||
Answer.set("filename", UUID_);
|
||||
Answer.set("error", 0);
|
||||
poco_debug(Logger(),fmt::format("{}: Trace file uploaded.", UUID_));
|
||||
StorageService()->AttachFileDataToCommand(UUID_, FileContent);
|
||||
poco_debug(Logger(),fmt::format("{}: File uploaded.", UUID_));
|
||||
StorageService()->AttachFileDataToCommand(UUID_, FileContent, Type_);
|
||||
std::ostream &ResponseStream = Response.send();
|
||||
Poco::JSON::Stringifier::stringify(Answer, ResponseStream);
|
||||
return;
|
||||
@@ -267,6 +266,7 @@ namespace OpenWifi {
|
||||
private:
|
||||
std::string UUID_;
|
||||
Poco::Logger & Logger_;
|
||||
std::string Type_;
|
||||
};
|
||||
|
||||
Poco::Net::HTTPRequestHandler *FileUpLoaderRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest & Request) {
|
||||
@@ -285,11 +285,12 @@ namespace OpenWifi {
|
||||
if( UUIDLocation != std::string::npos )
|
||||
{
|
||||
auto UUID = Request.getURI().substr(UUIDLocation+URI_BASE.size());
|
||||
if(FileUploader()->ValidRequest(UUID))
|
||||
|
||||
FileUploader::UploadId E;
|
||||
if(FileUploader()->Find(UUID,E))
|
||||
{
|
||||
// make sure we do not allow anyone else to overwrite our file
|
||||
FileUploader()->RemoveRequest(UUID);
|
||||
return new FormRequestHandler(UUID,Logger());
|
||||
return new FormRequestHandler(UUID,Logger(),E.Type);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -299,6 +300,17 @@ namespace OpenWifi {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool FileUploader::Find(const std::string &UUID, UploadId &V) {
|
||||
std::lock_guard G(Mutex_);
|
||||
for(const auto &E:OutStandingUploads_) {
|
||||
if (E.UUID == UUID) {
|
||||
V = E;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void FileUploader::Stop() {
|
||||
poco_notice(Logger(),"Stopping...");
|
||||
for( const auto & svr : Servers_ )
|
||||
|
||||
@@ -19,11 +19,18 @@ namespace OpenWifi {
|
||||
|
||||
class FileUploader : public SubSystemServer {
|
||||
public:
|
||||
|
||||
struct UploadId {
|
||||
std::string UUID;
|
||||
std::uint64_t Expires;
|
||||
std::string Type;
|
||||
};
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void reinitialize(Poco::Util::Application &self) override;
|
||||
const std::string & FullName();
|
||||
bool AddUUID( const std::string & UUID);
|
||||
bool AddUUID( const std::string & UUID, std::chrono::seconds WaitTimeInSecond, const std::string &Type);
|
||||
bool ValidRequest(const std::string & UUID);
|
||||
void RemoveRequest(const std::string &UUID);
|
||||
const std::string & Path() { return Path_; };
|
||||
@@ -35,12 +42,13 @@ namespace OpenWifi {
|
||||
|
||||
[[nodiscard]] inline uint64_t MaxSize() const { return MaxSize_; }
|
||||
|
||||
bool Find(const std::string &UUID, UploadId &V);
|
||||
private:
|
||||
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> Servers_;
|
||||
std::string FullName_;
|
||||
std::map<std::string,uint64_t> OutStandingUploads_;
|
||||
std::string Path_;
|
||||
uint64_t MaxSize_=10000000;
|
||||
std::string FullName_;
|
||||
std::list<UploadId> OutStandingUploads_;
|
||||
std::string Path_;
|
||||
uint64_t MaxSize_=10000000;
|
||||
|
||||
explicit FileUploader() noexcept:
|
||||
SubSystemServer("FileUploader", "FILE-UPLOAD", "openwifi.fileuploader")
|
||||
@@ -51,10 +59,13 @@ namespace OpenWifi {
|
||||
class FileUpLoaderRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
|
||||
public:
|
||||
explicit FileUpLoaderRequestHandlerFactory(Poco::Logger &L) :
|
||||
Logger_(L){}
|
||||
Logger_(L) {
|
||||
}
|
||||
|
||||
Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &request) override;
|
||||
inline Poco::Logger & Logger() { return Logger_; }
|
||||
inline Poco::Logger & Logger() {
|
||||
return Logger_;
|
||||
}
|
||||
private:
|
||||
Poco::Logger & Logger_;
|
||||
};
|
||||
|
||||
@@ -82,13 +82,13 @@ namespace OpenWifi::RESTAPI_RPC {
|
||||
if (rpc_result == std::future_status::ready) {
|
||||
std::chrono::duration<double, std::milli> rpc_execution_time = std::chrono::high_resolution_clock::now() - rpc_submitted;
|
||||
auto rpc_answer = rpc_future.get();
|
||||
if (!rpc_answer.has(uCentralProtocol::RESULT) || !rpc_answer.isObject(uCentralProtocol::RESULT)) {
|
||||
if (!rpc_answer->has(uCentralProtocol::RESULT) || !rpc_answer->isObject(uCentralProtocol::RESULT)) {
|
||||
SetCommandStatus(Cmd, Request, Response, Handler, Storage::CommandExecutionType::COMMAND_FAILED, Logger);
|
||||
Logger.information(fmt::format("{},{}: Invalid response. Missing result.", Cmd.UUID, RPCID));
|
||||
return;
|
||||
}
|
||||
|
||||
auto ResultFields = rpc_answer.get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
|
||||
auto ResultFields = rpc_answer->get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
|
||||
if (!ResultFields->has(uCentralProtocol::STATUS) || !ResultFields->isObject(uCentralProtocol::STATUS)) {
|
||||
Cmd.executionTime = rpc_execution_time.count();
|
||||
if(Cmd.Command=="ping") {
|
||||
@@ -107,20 +107,20 @@ namespace OpenWifi::RESTAPI_RPC {
|
||||
if (StatusInnerObj->has(uCentralProtocol::TEXT))
|
||||
Cmd.ErrorText = StatusInnerObj->get(uCentralProtocol::TEXT).toString();
|
||||
std::stringstream ResultText;
|
||||
if(rpc_answer.has(uCentralProtocol::RESULT)) {
|
||||
if(rpc_answer->has(uCentralProtocol::RESULT)) {
|
||||
if(Cmd.Command==uCentralProtocol::WIFISCAN) {
|
||||
auto ScanObj = rpc_answer.get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
|
||||
auto ScanObj = rpc_answer->get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
|
||||
ParseWifiScan(ScanObj, ResultText, Logger);
|
||||
} else {
|
||||
Poco::JSON::Stringifier::stringify(
|
||||
rpc_answer.get(uCentralProtocol::RESULT), ResultText);
|
||||
rpc_answer->get(uCentralProtocol::RESULT), ResultText);
|
||||
}
|
||||
} if (rpc_answer.has(uCentralProtocol::RESULT_64)) {
|
||||
} if (rpc_answer->has(uCentralProtocol::RESULT_64)) {
|
||||
uint64_t sz=0;
|
||||
if(rpc_answer.has(uCentralProtocol::RESULT_SZ))
|
||||
sz=rpc_answer.get(uCentralProtocol::RESULT_SZ);
|
||||
if(rpc_answer->has(uCentralProtocol::RESULT_SZ))
|
||||
sz=rpc_answer->get(uCentralProtocol::RESULT_SZ);
|
||||
std::string UnCompressedData;
|
||||
Utils::ExtractBase64CompressedData(rpc_answer.get(uCentralProtocol::RESULT_64).toString(),
|
||||
Utils::ExtractBase64CompressedData(rpc_answer->get(uCentralProtocol::RESULT_64).toString(),
|
||||
UnCompressedData,sz);
|
||||
Poco::JSON::Stringifier::stringify(UnCompressedData, ResultText);
|
||||
}
|
||||
@@ -129,7 +129,7 @@ namespace OpenWifi::RESTAPI_RPC {
|
||||
Cmd.Completed = Utils::Now();
|
||||
Cmd.executionTime = rpc_execution_time.count();
|
||||
|
||||
if (Cmd.ErrorCode && Cmd.Command == uCentralProtocol::TRACE) {
|
||||
if (Cmd.ErrorCode && (Cmd.Command == uCentralProtocol::TRACE || Cmd.Command == uCentralProtocol::SCRIPT)) {
|
||||
Cmd.WaitingForFile = 0;
|
||||
Cmd.AttachDate = Cmd.AttachSize = 0;
|
||||
Cmd.AttachType = "";
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_capabilities_handler::DoGet() {
|
||||
CapabilitiesCache_t Caps = CapabilitiesCache().AllCapabilities();
|
||||
CapabilitiesCache_t Caps = CapabilitiesCache()->AllCapabilities();
|
||||
|
||||
Poco::JSON::Array ObjArr;
|
||||
for(const auto &[deviceType,capabilities]:Caps) {
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_device_commandHandler::CallCanceled(const char * Cmd, const OpenWifi::RESTAPI::Errors::msg &Err, const std::string & Details) {
|
||||
Logger_.warning(fmt::format("{},{}: TID={} Canceled. Error:{} Reason:{} Details={}", Cmd, SerialNumber_, TransactionId_, Err.err_num, Err.err_txt, Details));
|
||||
poco_warning(Logger_,fmt::format("{},{}: TID={} Canceled. Error:{} Reason:{} Details={}", Cmd, SerialNumber_, TransactionId_, Err.err_num, Err.err_txt, Details));
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::DoGet() {
|
||||
@@ -64,16 +64,17 @@ namespace OpenWifi {
|
||||
} else if (Command_ == RESTAPI::Protocol::STATUS) {
|
||||
return GetStatus();
|
||||
} else if (Command_ == RESTAPI::Protocol::RTTY) {
|
||||
if(!AP_WS_Server()->Connected(SerialNumberInt_)) {
|
||||
AP_Restrictions Restrictions;
|
||||
if(!AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) {
|
||||
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected);
|
||||
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
|
||||
}
|
||||
auto UUID = MicroServiceCreateUUID();
|
||||
auto RPC = CommandManager()->NextRPCId();
|
||||
auto RPC = CommandManager()->Next_RPC_ID();
|
||||
poco_debug(Logger_,fmt::format("Command rtty TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
|
||||
TransactionId_, UUID, RPC,
|
||||
Poco::Thread::current()->id()));
|
||||
return Rtty(UUID,RPC,60000ms);
|
||||
return Rtty(UUID,RPC,60000ms, Restrictions);
|
||||
} else {
|
||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
}
|
||||
@@ -113,28 +114,25 @@ namespace OpenWifi {
|
||||
const char * Command;
|
||||
bool AllowParallel=false;
|
||||
bool RequireConnection = true;
|
||||
void (RESTAPI_device_commandHandler::*funPtr)(const std::string &, std::uint64_t, std::chrono::milliseconds );
|
||||
void (RESTAPI_device_commandHandler::*funPtr)(const std::string &, std::uint64_t, std::chrono::milliseconds, const AP_Restrictions &R );
|
||||
std::chrono::milliseconds Timeout=120ms;
|
||||
};
|
||||
|
||||
/*
|
||||
const static std::vector<PostDeviceCommand> PostCommands
|
||||
const std::vector<PostDeviceCommand> PostCommands =
|
||||
{
|
||||
{ RESTAPI::Protocol::PERFORM, false, true, &RESTAPI_device_commandHandler::ExecuteCommand },
|
||||
{ RESTAPI::Protocol::CONFIGURE, false, false, &RESTAPI_device_commandHandler::Configure },
|
||||
{ RESTAPI::Protocol::UPGRADE, false, false, &RESTAPI_device_commandHandler::Upgrade },
|
||||
{ RESTAPI::Protocol::REBOOT, false, true, &RESTAPI_device_commandHandler::Reboot },
|
||||
{ RESTAPI::Protocol::FACTORY, false, false, &RESTAPI_device_commandHandler::Factory },
|
||||
{ RESTAPI::Protocol::LEDS, false, true, &RESTAPI_device_commandHandler::LEDs },
|
||||
{ RESTAPI::Protocol::TRACE, false, true, &RESTAPI_device_commandHandler::Trace },
|
||||
{ RESTAPI::Protocol::REQUEST, false, true, &RESTAPI_device_commandHandler::MakeRequest },
|
||||
{ RESTAPI::Protocol::WIFISCAN, false, true, &RESTAPI_device_commandHandler::WifiScan },
|
||||
{ RESTAPI::Protocol::EVENTQUEUE, false, true, &RESTAPI_device_commandHandler::EventQueue },
|
||||
{ RESTAPI::Protocol::TELEMETRY, false, true, &RESTAPI_device_commandHandler::Telemetry },
|
||||
{ RESTAPI::Protocol::PING, false, true, &RESTAPI_device_commandHandler::Ping },
|
||||
{ RESTAPI::Protocol::SCRIPT, false, true, &RESTAPI_device_commandHandler::Script }
|
||||
};
|
||||
*/
|
||||
{ RESTAPI::Protocol::CONFIGURE, false, false, &RESTAPI_device_commandHandler::Configure, 120000ms },
|
||||
{ RESTAPI::Protocol::UPGRADE, false, false, &RESTAPI_device_commandHandler::Upgrade, 30000ms },
|
||||
{ RESTAPI::Protocol::REBOOT, false, true, &RESTAPI_device_commandHandler::Reboot, 30000ms },
|
||||
{ RESTAPI::Protocol::FACTORY, false, false, &RESTAPI_device_commandHandler::Factory, 30000ms },
|
||||
{ RESTAPI::Protocol::LEDS, false, true, &RESTAPI_device_commandHandler::LEDs, 120000ms },
|
||||
{ RESTAPI::Protocol::TRACE, false, true, &RESTAPI_device_commandHandler::Trace, 300000ms },
|
||||
{ RESTAPI::Protocol::REQUEST, false, true, &RESTAPI_device_commandHandler::MakeRequest, 120000ms },
|
||||
{ RESTAPI::Protocol::WIFISCAN, false, true, &RESTAPI_device_commandHandler::WifiScan, 120000ms },
|
||||
{ RESTAPI::Protocol::EVENTQUEUE, false, true, &RESTAPI_device_commandHandler::EventQueue, 30000ms },
|
||||
{ RESTAPI::Protocol::TELEMETRY, false, true, &RESTAPI_device_commandHandler::Telemetry, 30000ms },
|
||||
{ RESTAPI::Protocol::PING, false, true, &RESTAPI_device_commandHandler::Ping, 60000ms },
|
||||
{ RESTAPI::Protocol::SCRIPT, false, true, &RESTAPI_device_commandHandler::Script, 300000ms }
|
||||
};
|
||||
|
||||
void RESTAPI_device_commandHandler::DoPost() {
|
||||
if(!ValidateParameters()) {
|
||||
@@ -149,27 +147,11 @@ namespace OpenWifi {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
const std::vector<PostDeviceCommand> PostCommands =
|
||||
{
|
||||
{ RESTAPI::Protocol::PERFORM, false, true, &RESTAPI_device_commandHandler::ExecuteCommand, 120000ms },
|
||||
{ RESTAPI::Protocol::CONFIGURE, false, false, &RESTAPI_device_commandHandler::Configure, 120000ms },
|
||||
{ RESTAPI::Protocol::UPGRADE, false, false, &RESTAPI_device_commandHandler::Upgrade, 30000ms },
|
||||
{ RESTAPI::Protocol::REBOOT, false, true, &RESTAPI_device_commandHandler::Reboot, 30000ms },
|
||||
{ RESTAPI::Protocol::FACTORY, false, false, &RESTAPI_device_commandHandler::Factory, 30000ms },
|
||||
{ RESTAPI::Protocol::LEDS, false, true, &RESTAPI_device_commandHandler::LEDs, 120000ms },
|
||||
{ RESTAPI::Protocol::TRACE, false, true, &RESTAPI_device_commandHandler::Trace, 300000ms },
|
||||
{ RESTAPI::Protocol::REQUEST, false, true, &RESTAPI_device_commandHandler::MakeRequest, 120000ms },
|
||||
{ RESTAPI::Protocol::WIFISCAN, false, true, &RESTAPI_device_commandHandler::WifiScan, 120000ms },
|
||||
{ RESTAPI::Protocol::EVENTQUEUE, false, true, &RESTAPI_device_commandHandler::EventQueue, 30000ms },
|
||||
{ RESTAPI::Protocol::TELEMETRY, false, true, &RESTAPI_device_commandHandler::Telemetry, 30000ms },
|
||||
{ RESTAPI::Protocol::PING, false, true, &RESTAPI_device_commandHandler::Ping, 60000ms },
|
||||
{ RESTAPI::Protocol::SCRIPT, false, true, &RESTAPI_device_commandHandler::Script, 300000ms }
|
||||
};
|
||||
|
||||
for(const auto &Command:PostCommands) {
|
||||
if(Command_==Command.Command) {
|
||||
Poco::Thread::current()->setName(fmt::format("{}:{}:{}",Command.Command, TransactionId_,SerialNumber_));
|
||||
if(Command.RequireConnection && !AP_WS_Server()->Connected(SerialNumberInt_)) {
|
||||
AP_Restrictions Restrictions;
|
||||
if(Command.RequireConnection && !AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) {
|
||||
CallCanceled(Command.Command, RESTAPI::Errors::DeviceNotConnected);
|
||||
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
|
||||
}
|
||||
@@ -180,18 +162,18 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::DeviceIsAlreadyBusy, Extra);
|
||||
}
|
||||
auto UUID = MicroServiceCreateUUID();
|
||||
auto RPC = CommandManager()->NextRPCId();
|
||||
auto RPC = CommandManager()->Next_RPC_ID();
|
||||
poco_debug(Logger_,fmt::format("Command {} TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
|
||||
Command.Command, TransactionId_, UUID, RPC,
|
||||
Poco::Thread::current()->id()));
|
||||
return (*this.*Command.funPtr)(UUID,RPC,Command.Timeout);
|
||||
return (*this.*Command.funPtr)(UUID,RPC,Command.Timeout, Restrictions);
|
||||
}
|
||||
}
|
||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::GetCapabilities() {
|
||||
Logger_.information(fmt::format("GET-CAPABILITIES: TID={} user={} serial={}. thr_id={}",
|
||||
poco_information(Logger_,fmt::format("GET-CAPABILITIES: TID={} user={} serial={}. thr_id={}",
|
||||
TransactionId_, Requester(), SerialNumber_,
|
||||
Poco::Thread::current()->id()));
|
||||
GWObjects::Capabilities Caps;
|
||||
@@ -205,7 +187,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::DeleteCapabilities() {
|
||||
Logger_.information(fmt::format("DELETE-CAPABILITIES: TID={} user={} serial={}. thr_id={}",
|
||||
poco_information(Logger_,fmt::format("DELETE-CAPABILITIES: TID={} user={} serial={}. thr_id={}",
|
||||
TransactionId_, Requester(), SerialNumber_,
|
||||
Poco::Thread::current()->id()));
|
||||
if (StorageService()->DeleteDeviceCapabilities(SerialNumber_)) {
|
||||
@@ -215,17 +197,15 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::GetStatistics() {
|
||||
Logger_.information(fmt::format("GET-STATISTICS: TID={} user={} serial={}. thr_id={}",
|
||||
std::string StatsType = QB_.LastOnly ? "LastOnly" : ( QB_.Newest ? "Newest" :
|
||||
( QB_.CountOnly ? "CountOnly" : "Timed"));
|
||||
poco_information(Logger_,fmt::format("GET-STATISTICS: TID={} user={} serial={}. thr_id={}, TYPE={}",
|
||||
TransactionId_, Requester(), SerialNumber_,
|
||||
Poco::Thread::current()->id()));
|
||||
Poco::Thread::current()->id(),StatsType));
|
||||
if (QB_.LastOnly) {
|
||||
std::string Stats;
|
||||
if (AP_WS_Server()->GetStatistics(SerialNumber_, Stats) && !Stats.empty()) {
|
||||
Poco::JSON::Parser P;
|
||||
if (Stats.empty())
|
||||
Stats = uCentralProtocol::EMPTY_JSON_DOC;
|
||||
auto Obj = P.parse(Stats).extract<Poco::JSON::Object::Ptr>();
|
||||
return ReturnObject(*Obj);
|
||||
return ReturnRawJSON(Stats);
|
||||
}
|
||||
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
|
||||
}
|
||||
@@ -234,6 +214,14 @@ namespace OpenWifi {
|
||||
if (QB_.Newest) {
|
||||
StorageService()->GetNewestStatisticsData(SerialNumber_, QB_.Limit, Stats);
|
||||
} else {
|
||||
if(QB_.CountOnly) {
|
||||
std::uint64_t Count = 0 ;
|
||||
StorageService()->GetNumberOfStatisticsDataRecords(SerialNumber_, QB_.StartDate, QB_.EndDate,Count);
|
||||
return ReturnCountOnly(Count);
|
||||
}
|
||||
if(QB_.Limit>100)
|
||||
QB_.Limit=100;
|
||||
|
||||
StorageService()->GetStatisticsData(SerialNumber_, QB_.StartDate, QB_.EndDate,
|
||||
QB_.Offset, QB_.Limit, Stats);
|
||||
}
|
||||
@@ -252,7 +240,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::DeleteStatistics() {
|
||||
Logger_.information(fmt::format("DELETE-STATISTICS: TID={} user={} serial={}. thr_id={}",
|
||||
poco_information(Logger_,fmt::format("DELETE-STATISTICS: TID={} user={} serial={}. thr_id={}",
|
||||
TransactionId_, Requester(), SerialNumber_,
|
||||
Poco::Thread::current()->id()));
|
||||
if (StorageService()->DeleteStatisticsData(SerialNumber_, QB_.StartDate, QB_.EndDate)) {
|
||||
@@ -262,7 +250,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::GetStatus() {
|
||||
Logger_.information(fmt::format("GET-STATUS: TID={} user={} serial={}. thr_id={}",
|
||||
poco_information(Logger_,fmt::format("GET-STATUS: TID={} user={} serial={}. thr_id={}",
|
||||
TransactionId_, Requester(), SerialNumber_,
|
||||
Poco::Thread::current()->id()));
|
||||
GWObjects::ConnectionState State;
|
||||
@@ -280,7 +268,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::GetLogs() {
|
||||
Logger_.information(fmt::format("GET-LOGS: TID={} user={} serial={}. thr_id={}",
|
||||
poco_information(Logger_,fmt::format("GET-LOGS: TID={} user={} serial={}. thr_id={}",
|
||||
TransactionId_, Requester(), SerialNumber_,
|
||||
Poco::Thread::current()->id()));
|
||||
std::vector<GWObjects::DeviceLog> Logs;
|
||||
@@ -304,7 +292,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::DeleteLogs() {
|
||||
Logger_.information(fmt::format("DELETE-LOGS: TID={} user={} serial={}. thr_id={}",
|
||||
poco_information(Logger_,fmt::format("DELETE-LOGS: TID={} user={} serial={}. thr_id={}",
|
||||
TransactionId_, Requester(), SerialNumber_,
|
||||
Poco::Thread::current()->id()));
|
||||
if (StorageService()->DeleteLogData(SerialNumber_, QB_.StartDate, QB_.EndDate,
|
||||
@@ -315,12 +303,10 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::GetChecks() {
|
||||
Logger_.information(fmt::format("GET-HEALTHCHECKS: TID={} user={} serial={}. thr_id={}",
|
||||
poco_information(Logger_,fmt::format("GET-HEALTHCHECKS: TID={} user={} serial={}. thr_id={}",
|
||||
TransactionId_, Requester(), SerialNumber_,
|
||||
Poco::Thread::current()->id()));
|
||||
|
||||
std::vector<GWObjects::HealthCheck> Checks;
|
||||
|
||||
if (QB_.LastOnly) {
|
||||
GWObjects::HealthCheck HC;
|
||||
if (AP_WS_Server()->GetHealthcheck(SerialNumber_, HC)) {
|
||||
@@ -331,6 +317,7 @@ namespace OpenWifi {
|
||||
return NotFound();
|
||||
}
|
||||
} else {
|
||||
std::vector<GWObjects::HealthCheck> Checks;
|
||||
if (QB_.Newest) {
|
||||
StorageService()->GetNewestHealthCheckData(SerialNumber_, QB_.Limit, Checks);
|
||||
} else {
|
||||
@@ -353,7 +340,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::DeleteChecks() {
|
||||
Logger_.information(fmt::format("DELETE-HEALTHCHECKS: TID={} user={} serial={}. thr_id={}",
|
||||
poco_information(Logger_,fmt::format("DELETE-HEALTHCHECKS: TID={} user={} serial={}. thr_id={}",
|
||||
TransactionId_, Requester(), SerialNumber_,
|
||||
Poco::Thread::current()->id()));
|
||||
if (StorageService()->DeleteHealthCheckData(SerialNumber_, QB_.StartDate, QB_.EndDate)) {
|
||||
@@ -362,8 +349,8 @@ namespace OpenWifi {
|
||||
BadRequest(RESTAPI::Errors::NoRecordsDeleted);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Ping(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
Logger_.information(fmt::format("PING({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
void RESTAPI_device_commandHandler::Ping(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
|
||||
poco_information(Logger_,fmt::format("PING({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
const auto &Obj = ParsedBody_;
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
@@ -415,11 +402,15 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::CallCanceled(const char * Cmd, const std::string &UUID, uint64_t RPC, const OpenWifi::RESTAPI::Errors::msg &Err) {
|
||||
Logger_.warning(fmt::format("{}({},{}): Canceled. Error:{} Reason:{}", Cmd, UUID, RPC, Err.err_num, Err.err_txt));
|
||||
poco_warning(Logger_,fmt::format("{}({},{}): Canceled. Error:{} Reason:{}", Cmd, UUID, RPC, Err.err_num, Err.err_txt));
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Script(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
Logger_.information(fmt::format("SCRIPT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
static bool ValidateScriptType(const std::string &t) {
|
||||
return t=="shell" || t=="bundle";
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Script(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
|
||||
poco_information(Logger_,fmt::format("SCRIPT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
if(!Internal_ && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
|
||||
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::ACCESS_DENIED);
|
||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||
@@ -434,9 +425,7 @@ namespace OpenWifi {
|
||||
|
||||
if (SCR.serialNumber.empty() ||
|
||||
SCR.script.empty() ||
|
||||
SCR.type.empty() ||
|
||||
SCR.scriptId.empty() ||
|
||||
(SCR.type!="shell" && SCR.type!="ucode")) {
|
||||
!ValidateScriptType(SCR.type)) {
|
||||
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
@@ -446,6 +435,15 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
GWObjects::Device D;
|
||||
if(!StorageService()->GetDevice(SerialNumber_,D)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if(D.restrictedDevice && SCR.signature.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::DeviceRequiresSignature);
|
||||
}
|
||||
|
||||
uint64_t ap_timeout = SCR.timeout==0 ? 30 : SCR.timeout;
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
@@ -454,10 +452,23 @@ namespace OpenWifi {
|
||||
Cmd.SubmittedBy = Requester();
|
||||
Cmd.Command = uCentralProtocol::SCRIPT;
|
||||
Cmd.RunAt = 0;
|
||||
Cmd.WaitingForFile = SCR.deferred ? 1 : 0;
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::TIMEOUT, ap_timeout);
|
||||
if(SCR.deferred && SCR.uri.empty()) {
|
||||
SCR.uri = FileUploader()->FullName() + CMD_UUID ;
|
||||
}
|
||||
|
||||
if(SCR.deferred) {
|
||||
Params.set(uCentralProtocol::URI, SCR.uri);
|
||||
} else {
|
||||
Params.set(uCentralProtocol::TIMEOUT, ap_timeout);
|
||||
}
|
||||
|
||||
if(!SCR.signature.empty()) {
|
||||
Params.set(uCentralProtocol::SIGNATURE, SCR.signature);
|
||||
}
|
||||
Params.set(uCentralProtocol::TYPE, SCR.type);
|
||||
Params.set(uCentralProtocol::SCRIPT, SCR.script);
|
||||
Params.set(uCentralProtocol::WHEN, SCR.when);
|
||||
@@ -465,12 +476,13 @@ namespace OpenWifi {
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
FileUploader()->AddUUID(CMD_UUID, 15min, "script_result");
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Configure(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
Logger_.information(fmt::format("CONFIGURE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
void RESTAPI_device_commandHandler::Configure(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
|
||||
poco_information(Logger_,fmt::format("CONFIGURE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
@@ -521,8 +533,8 @@ namespace OpenWifi {
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Upgrade(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
Logger_.information(fmt::format("UPGRADE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
void RESTAPI_device_commandHandler::Upgrade(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
|
||||
poco_information(Logger_,fmt::format("UPGRADE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
|
||||
@@ -535,6 +547,17 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
GWObjects::Device DeviceInfo;
|
||||
|
||||
if(!StorageService()->GetDevice(SerialNumber_,DeviceInfo)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
std::string FWSignature = GetParameter("FWsignature","");
|
||||
if(FWSignature.empty() && R.sysupgrade_not_allowed()) {
|
||||
return BadRequest(RESTAPI::Errors::DeviceRequiresSignature);
|
||||
}
|
||||
|
||||
auto URI = GetS(RESTAPI::Protocol::URI, Obj);
|
||||
auto When = GetWhen(Obj);
|
||||
|
||||
@@ -553,6 +576,9 @@ namespace OpenWifi {
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::URI, URI);
|
||||
Params.set(uCentralProtocol::KEEP_REDIRECTOR, KeepRedirector ? 1 : 0);
|
||||
if(!FWSignature.empty()) {
|
||||
Params.set(uCentralProtocol::FWSIGNATURE, FWSignature);
|
||||
}
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
@@ -564,57 +590,8 @@ namespace OpenWifi {
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
|
||||
void RESTAPI_device_commandHandler::ExecuteCommand(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
Logger_.information(fmt::format("EXECUTE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
if (Obj->has(RESTAPI::Protocol::COMMAND) &&
|
||||
Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Obj->has(RESTAPI::Protocol::PAYLOAD)) {
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
CallCanceled("EXECUTE", CMD_UUID, CMD_RPC,RESTAPI::Errors::SerialNumberMismatch);
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
auto Command = GetS(RESTAPI::Protocol::COMMAND, Obj);
|
||||
auto Payload = GetS(RESTAPI::Protocol::PAYLOAD, Obj);
|
||||
auto When = GetWhen(Obj);
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = CMD_UUID;
|
||||
Cmd.SubmittedBy = Requester();
|
||||
Cmd.Command = Command;
|
||||
Cmd.Custom = 1;
|
||||
Cmd.RunAt = When;
|
||||
|
||||
Poco::JSON::Parser parser2;
|
||||
|
||||
Poco::Dynamic::Var result = parser2.parse(Payload);
|
||||
const auto &PayloadObject = result.extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::COMMAND, Command);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
Params.set(uCentralProtocol::PAYLOAD, PayloadObject);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Reboot(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
Logger_.information(fmt::format("REBOOT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
void RESTAPI_device_commandHandler::Reboot(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
|
||||
poco_information(Logger_,fmt::format("REBOOT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
|
||||
@@ -647,8 +624,8 @@ namespace OpenWifi {
|
||||
BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Factory(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
Logger_.information(fmt::format("FACTORY-RESET({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
void RESTAPI_device_commandHandler::Factory(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
|
||||
poco_information(Logger_,fmt::format("FACTORY-RESET({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
if (Obj->has(RESTAPI::Protocol::KEEPREDIRECTOR) &&
|
||||
@@ -687,8 +664,8 @@ namespace OpenWifi {
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::LEDs(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
Logger_.information(fmt::format("LEDS({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
void RESTAPI_device_commandHandler::LEDs(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
|
||||
poco_information(Logger_,fmt::format("LEDS({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
|
||||
@@ -735,8 +712,8 @@ namespace OpenWifi {
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Trace(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
Logger_.information(fmt::format("TRACE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
void RESTAPI_device_commandHandler::Trace(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
|
||||
poco_information(Logger_,fmt::format("TRACE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
|
||||
@@ -782,14 +759,14 @@ namespace OpenWifi {
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
FileUploader()->AddUUID(CMD_UUID);
|
||||
FileUploader()->AddUUID(CMD_UUID, 10min, "trace");
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::WifiScan(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
Logger_.information(fmt::format("WIFISCAN({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
void RESTAPI_device_commandHandler::WifiScan(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
|
||||
poco_information(Logger_,fmt::format("WIFISCAN({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
const auto &Obj = ParsedBody_;
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
@@ -817,6 +794,11 @@ namespace OpenWifi {
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
|
||||
if(R.dfs_not_allowed() && OverrideDFS) {
|
||||
return BadRequest(RESTAPI::Errors::DeviceIsRestricted);
|
||||
}
|
||||
|
||||
Params.set(uCentralProtocol::OVERRIDEDFS, OverrideDFS);
|
||||
Params.set(uCentralProtocol::ACTIVE, ActiveScan);
|
||||
if(ies)
|
||||
@@ -833,8 +815,8 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::EventQueue(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
Logger_.information(fmt::format("EVENT-QUEUE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
void RESTAPI_device_commandHandler::EventQueue(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
|
||||
poco_information(Logger_,fmt::format("EVENT-QUEUE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
@@ -872,8 +854,8 @@ namespace OpenWifi {
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::MakeRequest(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
Logger_.information(fmt::format("FORCE-REQUEST({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
void RESTAPI_device_commandHandler::MakeRequest(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
|
||||
poco_information(Logger_,fmt::format("FORCE-REQUEST({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
@@ -914,17 +896,18 @@ namespace OpenWifi {
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Rtty(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
Logger_.information(fmt::format("RTTY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
void RESTAPI_device_commandHandler::Rtty(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
|
||||
poco_information(Logger_,fmt::format("RTTY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
if(R.rtty_not_allowed()) {
|
||||
return BadRequest(RESTAPI::Errors::DeviceIsRestricted);
|
||||
}
|
||||
|
||||
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
if (MicroServiceConfigGetBool("rtty.enabled", false)) {
|
||||
GWObjects::Device Device;
|
||||
|
||||
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
if (StorageService()->GetDevice(SerialNumber_, Device)) {
|
||||
|
||||
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
GWObjects::RttySessionDetails Rtty{
|
||||
.SerialNumber = SerialNumber_,
|
||||
.Server = MicroServiceConfigGetString("rtty.server", "localhost"),
|
||||
@@ -937,19 +920,13 @@ namespace OpenWifi {
|
||||
.ViewPort = MicroServiceConfigGetInt("rtty.viewport", 5913),
|
||||
.DevicePassword = ""
|
||||
};
|
||||
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
|
||||
if(RTTYS_server()->UseInternal()) {
|
||||
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
Rtty.Token = Utils::ComputeHash(UserInfo_.webtoken.refresh_token_,Utils::Now()).substr(0,RTTY_DEVICE_TOKEN_LENGTH);
|
||||
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
if(!RTTYS_server()->CreateEndPoint(Rtty.ConnectionId, Rtty.Token, Requester(), SerialNumber_)) {
|
||||
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
return BadRequest(RESTAPI::Errors::MaximumRTTYSessionsReached);
|
||||
}
|
||||
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
}
|
||||
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
|
||||
Poco::JSON::Object ReturnedObject;
|
||||
Rtty.to_json(ReturnedObject);
|
||||
@@ -961,7 +938,6 @@ namespace OpenWifi {
|
||||
Cmd.UUID = CMD_UUID;
|
||||
Cmd.Command = uCentralProtocol::RTTY;
|
||||
|
||||
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentralProtocol::METHOD, uCentralProtocol::RTTY);
|
||||
@@ -974,27 +950,22 @@ namespace OpenWifi {
|
||||
Params.set(uCentralProtocol::TIMEOUT, Rtty.TimeOut);
|
||||
Params.set(uCentralProtocol::PASSWORD, Device.DevicePassword);
|
||||
|
||||
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
std::stringstream ParamStream;
|
||||
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
Params.stringify(ParamStream);
|
||||
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
Cmd.Details = ParamStream.str();
|
||||
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
Logger_.information(fmt::format("RTTY: user={} serial={} rttyid={} token={} cmd={}.", Requester(), SerialNumber_, Rtty.ConnectionId, Rtty.Token, CMD_UUID));
|
||||
// poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
poco_information(Logger_,fmt::format("RTTY: user={} serial={} rttyid={} token={} cmd={}.", Requester(), SerialNumber_, Rtty.ConnectionId, Rtty.Token, CMD_UUID));
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, &ReturnedObject, this, Logger_);
|
||||
}
|
||||
return NotFound();
|
||||
}
|
||||
Logger_.information(fmt::format("RTTY: user={} serial={}. Internal error.", Requester(), SerialNumber_));
|
||||
poco_information(Logger_,fmt::format("RTTY: user={} serial={}. Internal error.", Requester(), SerialNumber_));
|
||||
return ReturnStatus(Poco::Net::HTTPResponse::HTTP_SERVICE_UNAVAILABLE);
|
||||
}
|
||||
|
||||
// #define DBG { std::cout << __LINE__ << std::endl; }
|
||||
|
||||
void RESTAPI_device_commandHandler::Telemetry(const std::string &CMD_UUID, uint64_t CMD_RPC, [[maybe_unused]] std::chrono::milliseconds timeout){
|
||||
Logger_.information(fmt::format("TELEMETRY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
void RESTAPI_device_commandHandler::Telemetry(const std::string &CMD_UUID, uint64_t CMD_RPC, [[maybe_unused]] std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R){
|
||||
poco_information(Logger_,fmt::format("TELEMETRY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "AP_restrictions.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_device_commandHandler : public RESTAPIHandler {
|
||||
@@ -32,20 +33,20 @@ namespace OpenWifi {
|
||||
void GetStatus();
|
||||
void GetChecks();
|
||||
void DeleteChecks();
|
||||
void ExecuteCommand(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
|
||||
void Configure(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
|
||||
void Upgrade(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
|
||||
void Reboot(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
|
||||
void Factory(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
|
||||
void LEDs(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
|
||||
void Trace(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
|
||||
void MakeRequest(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
|
||||
void WifiScan(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
|
||||
void EventQueue(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
|
||||
void Rtty(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
|
||||
void Telemetry(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
|
||||
void Ping(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
|
||||
void Script(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout);
|
||||
|
||||
void Configure(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
|
||||
void Upgrade(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
|
||||
void Reboot(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
|
||||
void Factory(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
|
||||
void LEDs(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
|
||||
void Trace(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
|
||||
void MakeRequest(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
|
||||
void WifiScan(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
|
||||
void EventQueue(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
|
||||
void Rtty(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
|
||||
void Telemetry(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
|
||||
void Ping(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
|
||||
void Script(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
|
||||
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/device/{serialNumber}/{command}"}; };
|
||||
void DoGet() final;
|
||||
|
||||
@@ -107,11 +107,6 @@ namespace OpenWifi {
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
|
||||
if (!Utils::ValidSerialNumber(SerialNumber)) {
|
||||
Logger_.warning(fmt::format("CREATE-DEVICE({}): Illegal serial number.", SerialNumber));
|
||||
return BadRequest( RESTAPI::Errors::InvalidSerialNumber);
|
||||
}
|
||||
|
||||
GWObjects::Device Device;
|
||||
if (!Device.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace OpenWifi {
|
||||
std::string ItemList;
|
||||
|
||||
Types::StringVec Fields;
|
||||
StorageService()->GetDeviceDbFieldList(Fields);
|
||||
Storage::GetDeviceDbFieldList(Fields);
|
||||
|
||||
std::set<std::string> FieldNames;
|
||||
for(const auto &field:Fields)
|
||||
@@ -68,7 +68,7 @@ namespace OpenWifi {
|
||||
|
||||
if(GetBoolParameter("orderSpec")) {
|
||||
Types::StringVec Fields;
|
||||
StorageService()->GetDeviceDbFieldList(Fields);
|
||||
Storage::GetDeviceDbFieldList(Fields);
|
||||
std::sort(Fields.begin(),Fields.end());
|
||||
Poco::JSON::Object Answer;
|
||||
RESTAPI_utils::field_to_json(Answer,"list",Fields);
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
#include "RESTAPI/RESTAPI_telemetryWebSocket.h"
|
||||
#include "RESTAPI/RESTAPI_iptocountry_handler.h"
|
||||
#include "RESTAPI/RESTAPI_radiusProxyConfig_handler.h"
|
||||
|
||||
#include "framework/RESTAPI_SystemCommand.h"
|
||||
#include "framework/RESTAPI_WebSocketServer.h"
|
||||
#include "framework/RESTAPI_SystemConfiguration.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -37,6 +39,7 @@ namespace OpenWifi {
|
||||
RESTAPI_ouis,
|
||||
RESTAPI_file,
|
||||
RESTAPI_system_command,
|
||||
RESTAPI_system_configuration,
|
||||
RESTAPI_deviceDashboardHandler,
|
||||
RESTAPI_webSocketServer,
|
||||
RESTAPI_blacklist,
|
||||
|
||||
@@ -50,6 +50,8 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj,"entity", entity);
|
||||
field_to_json(Obj,"modified", modified);
|
||||
field_to_json(Obj,"locale", locale);
|
||||
field_to_json(Obj,"restrictedDevice", restrictedDevice);
|
||||
|
||||
}
|
||||
|
||||
void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
|
||||
@@ -70,6 +72,7 @@ namespace OpenWifi::GWObjects {
|
||||
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);
|
||||
field_to_json(Obj,"associations_6G", (uint64_t) 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -89,6 +92,7 @@ namespace OpenWifi::GWObjects {
|
||||
field_from_json(Obj,"subscriber", subscriber);
|
||||
field_from_json(Obj,"entity", entity);
|
||||
field_from_json(Obj,"locale", locale);
|
||||
field_from_json(Obj,"restrictedDevice", restrictedDevice);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
@@ -199,6 +203,7 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj,"lastContact", LastContact);
|
||||
field_to_json(Obj,"associations_2G", Associations_2G);
|
||||
field_to_json(Obj,"associations_5G", Associations_5G);
|
||||
field_to_json(Obj,"associations_6G", Associations_6G);
|
||||
field_to_json(Obj,"webSocketClients", webSocketClients);
|
||||
field_to_json(Obj,"websocketPackets", websocketPackets);
|
||||
field_to_json(Obj,"kafkaClients", kafkaClients);
|
||||
@@ -208,6 +213,7 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj,"sessionId", sessionId);
|
||||
field_to_json(Obj,"connectionCompletionTime", connectionCompletionTime);
|
||||
field_to_json(Obj,"totalConnectionTime", Utils::Now() - started);
|
||||
field_to_json(Obj,"certificateExpiryDate", certificateExpiryDate);
|
||||
|
||||
switch(VerifiedCertificate) {
|
||||
case NO_CERTIFICATE:
|
||||
@@ -299,8 +305,10 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj,"timeout",timeout);
|
||||
field_to_json(Obj,"type",type);
|
||||
field_to_json(Obj,"script",script);
|
||||
field_to_json(Obj,"scriptId",scriptId);
|
||||
field_to_json(Obj,"when",when);
|
||||
field_to_json(Obj,"signature", signature);
|
||||
field_to_json(Obj,"deferred", deferred);
|
||||
field_to_json(Obj,"uri", uri);
|
||||
}
|
||||
|
||||
bool ScriptRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
@@ -309,8 +317,10 @@ namespace OpenWifi::GWObjects {
|
||||
field_from_json(Obj,"timeout",timeout);
|
||||
field_from_json(Obj,"type",type);
|
||||
field_from_json(Obj,"script",script);
|
||||
field_from_json(Obj,"scriptId",scriptId);
|
||||
field_from_json(Obj,"when",when);
|
||||
field_from_json(Obj,"signature", signature);
|
||||
field_from_json(Obj,"deferred", deferred);
|
||||
field_from_json(Obj,"uri", uri);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
|
||||
@@ -28,19 +28,21 @@ namespace OpenWifi::GWObjects {
|
||||
uint64_t TX = 0, RX = 0;
|
||||
uint64_t Associations_2G=0;
|
||||
uint64_t Associations_5G=0;
|
||||
uint64_t Associations_6G=0;
|
||||
bool Connected = false;
|
||||
uint64_t LastContact=0;
|
||||
std::string Firmware;
|
||||
CertificateValidation VerifiedCertificate = NO_CERTIFICATE;
|
||||
std::string Compatible;
|
||||
uint64_t kafkaClients=0;
|
||||
uint64_t webSocketClients=0;
|
||||
uint64_t kafkaPackets=0;
|
||||
uint64_t websocketPackets=0;
|
||||
std::string locale;
|
||||
uint64_t started=0;
|
||||
uint64_t sessionId=0;
|
||||
double connectionCompletionTime=0.0;
|
||||
std::string Compatible;
|
||||
uint64_t kafkaClients=0;
|
||||
uint64_t webSocketClients=0;
|
||||
uint64_t kafkaPackets=0;
|
||||
uint64_t websocketPackets=0;
|
||||
std::string locale;
|
||||
uint64_t started=0;
|
||||
uint64_t sessionId=0;
|
||||
double connectionCompletionTime=0.0;
|
||||
std::uint64_t certificateExpiryDate=0;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
@@ -68,6 +70,7 @@ namespace OpenWifi::GWObjects {
|
||||
std::string entity;
|
||||
uint64_t modified=0;
|
||||
std::string locale;
|
||||
bool restrictedDevice=false;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
void to_json_with_status(Poco::JSON::Object &Obj) const;
|
||||
@@ -214,12 +217,15 @@ namespace OpenWifi::GWObjects {
|
||||
};
|
||||
|
||||
struct ScriptRequest {
|
||||
uint64_t timeout=30;
|
||||
std::string serialNumber;
|
||||
uint64_t timeout=30;
|
||||
std::string type;
|
||||
std::string script;
|
||||
std::string scriptId;
|
||||
uint64_t when=0;
|
||||
std::uint64_t when;
|
||||
std::string signature;
|
||||
bool deferred;
|
||||
std::string uri;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
@@ -602,6 +602,7 @@ namespace OpenWifi::ProvObjects {
|
||||
field_to_json( Obj, "devClass",devClass);
|
||||
field_to_json( Obj, "locale",locale);
|
||||
field_to_json( Obj, "realMacAddress",realMacAddress);
|
||||
field_to_json( Obj, "doNotAllowOverrides",doNotAllowOverrides);
|
||||
}
|
||||
|
||||
bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
@@ -623,6 +624,7 @@ namespace OpenWifi::ProvObjects {
|
||||
field_from_json( Obj,"devClass",devClass);
|
||||
field_from_json( Obj,"locale",locale);
|
||||
field_from_json( Obj,"realMacAddress",realMacAddress);
|
||||
field_from_json( Obj, "doNotAllowOverrides",doNotAllowOverrides);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
@@ -1195,6 +1197,48 @@ namespace OpenWifi::ProvObjects {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ConfigurationOverride::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"source",source);
|
||||
field_to_json(Obj,"reason",reason);
|
||||
field_to_json(Obj,"parameterName",parameterName);
|
||||
field_to_json(Obj,"parameterType",parameterType);
|
||||
field_to_json(Obj,"parameterValue",parameterValue);
|
||||
field_to_json(Obj,"modified",modified);
|
||||
}
|
||||
|
||||
bool ConfigurationOverride::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"source",source);
|
||||
field_from_json(Obj,"reason",reason);
|
||||
field_from_json(Obj,"parameterName",parameterName);
|
||||
field_from_json(Obj,"parameterType",parameterType);
|
||||
field_from_json(Obj,"parameterValue",parameterValue);
|
||||
field_from_json(Obj,"modified",modified);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ConfigurationOverrideList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj,"serialNumber",serialNumber);
|
||||
field_to_json(Obj,"managementPolicy",managementPolicy);
|
||||
field_to_json(Obj,"overrides",overrides);
|
||||
}
|
||||
|
||||
bool ConfigurationOverrideList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj,"serialNumber",serialNumber);
|
||||
field_from_json(Obj,"managementPolicy",managementPolicy);
|
||||
field_from_json(Obj,"overrides",overrides);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -428,6 +428,7 @@ namespace OpenWifi::ProvObjects {
|
||||
std::string devClass;
|
||||
std::string locale;
|
||||
std::string realMacAddress;
|
||||
bool doNotAllowOverrides=false;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
@@ -693,6 +694,27 @@ namespace OpenWifi::ProvObjects {
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct ConfigurationOverride {
|
||||
std::string source;
|
||||
std::string reason;
|
||||
std::string parameterName;
|
||||
std::string parameterType;
|
||||
std::string parameterValue;
|
||||
std::uint64_t modified;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct ConfigurationOverrideList {
|
||||
std::string serialNumber;
|
||||
Types::UUID_t managementPolicy;
|
||||
std::vector<ConfigurationOverride> overrides;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I);
|
||||
bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I);
|
||||
bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I);
|
||||
|
||||
@@ -619,5 +619,80 @@ namespace OpenWifi::SecurityObjects {
|
||||
field_to_json(Obj,"login",login);
|
||||
field_to_json(Obj,"logout",logout);
|
||||
}
|
||||
|
||||
void ApiKeyAccessRight::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "service", service);
|
||||
field_to_json(Obj, "access", access);
|
||||
}
|
||||
|
||||
bool ApiKeyAccessRight::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "service", service);
|
||||
field_from_json(Obj, "access", access);
|
||||
return true;
|
||||
} catch(...) {
|
||||
std::cout << "Cannot parse: Token" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ApiKeyAccessRightList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "acls", acls);
|
||||
}
|
||||
|
||||
bool ApiKeyAccessRightList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "acls", acls);
|
||||
return true;
|
||||
} catch(...) {
|
||||
std::cout << "Cannot parse: Token" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ApiKeyEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "id", id);
|
||||
field_to_json(Obj, "userUuid", userUuid);
|
||||
field_to_json(Obj, "name", name);
|
||||
field_to_json(Obj, "apiKey", apiKey);
|
||||
field_to_json(Obj, "salt", salt);
|
||||
field_to_json(Obj, "description", description);
|
||||
field_to_json(Obj, "expiresOn", expiresOn);
|
||||
field_to_json(Obj, "rights", rights);
|
||||
field_to_json(Obj, "lastUse", lastUse);
|
||||
}
|
||||
|
||||
bool ApiKeyEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "id", id);
|
||||
field_from_json(Obj, "userUuid", userUuid);
|
||||
field_from_json(Obj, "name", name);
|
||||
field_from_json(Obj, "apiKey", apiKey);
|
||||
field_from_json(Obj, "salt", salt);
|
||||
field_from_json(Obj, "description", description);
|
||||
field_from_json(Obj, "expiresOn", expiresOn);
|
||||
field_from_json(Obj, "rights", rights);
|
||||
field_from_json(Obj, "lastUse", lastUse);
|
||||
return true;
|
||||
} catch(...) {
|
||||
std::cout << "Cannot parse: Token" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ApiKeyEntryList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "apiKeys", apiKeys);
|
||||
}
|
||||
|
||||
bool ApiKeyEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "apiKeys", apiKeys);
|
||||
return true;
|
||||
} catch(...) {
|
||||
std::cout << "Cannot parse: Token" << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -325,5 +325,44 @@ namespace OpenWifi {
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
|
||||
struct ApiKeyAccessRight {
|
||||
std::string service;
|
||||
std::string access;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct ApiKeyAccessRightList {
|
||||
std::vector<ApiKeyAccessRight> acls;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct ApiKeyEntry {
|
||||
Types::UUID_t id;
|
||||
Types::UUID_t userUuid;
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string apiKey;
|
||||
std::string salt;
|
||||
std::uint64_t created;
|
||||
std::uint64_t expiresOn=0;
|
||||
ApiKeyAccessRightList rights;
|
||||
std::uint64_t lastUse=0;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct ApiKeyEntryList {
|
||||
std::vector<ApiKeyEntry> apiKeys;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,13 @@ namespace OpenWifi::StateUtils {
|
||||
return 5;
|
||||
}
|
||||
|
||||
bool ComputeAssociations(const Poco::JSON::Object::Ptr RawObject, uint64_t &Radios_2G,
|
||||
uint64_t &Radios_5G) {
|
||||
bool ComputeAssociations(const Poco::JSON::Object::Ptr & RawObject,
|
||||
uint64_t &Radios_2G,
|
||||
uint64_t &Radios_5G, uint64_t &Radios_6G) {
|
||||
Radios_2G = 0 ;
|
||||
Radios_5G = 0;
|
||||
Radios_6G = 0;
|
||||
|
||||
if(RawObject->isArray("radios") && RawObject->isArray("interfaces")) {
|
||||
auto RA = RawObject->getArray("radios");
|
||||
// map of phy to 2g/5g
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
#include "Poco/JSON/Object.h"
|
||||
|
||||
namespace OpenWifi::StateUtils {
|
||||
bool ComputeAssociations(const Poco::JSON::Object::Ptr RawObject, uint64_t &Radios_2G,
|
||||
uint64_t &Radios_5G);
|
||||
bool ComputeAssociations(const Poco::JSON::Object::Ptr & RawObject, uint64_t &Radios_2G,
|
||||
uint64_t &Radios_5G, uint64_t &Radio_6G);
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "framework/StorageClass.h"
|
||||
#include "RESTObjects//RESTAPI_GWobjects.h"
|
||||
#include "Poco/Net/IPAddress.h"
|
||||
#include "CentralConfig.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -84,6 +85,7 @@ namespace OpenWifi {
|
||||
bool AddStatisticsData(const GWObjects::Statistics & Stats);
|
||||
bool GetStatisticsData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, uint64_t Offset, uint64_t HowMany,
|
||||
std::vector<GWObjects::Statistics> &Stats);
|
||||
bool GetNumberOfStatisticsDataRecords(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, std::uint64_t &Count);
|
||||
bool DeleteStatisticsData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate );
|
||||
bool GetNewestStatisticsData(std::string &SerialNumber, uint64_t HowMany, std::vector<GWObjects::Statistics> &Stats);
|
||||
|
||||
@@ -97,7 +99,7 @@ namespace OpenWifi {
|
||||
bool UpdateDeviceConfiguration(std::string &SerialNumber, std::string &Configuration, uint64_t & NewUUID );
|
||||
|
||||
bool CreateDevice(GWObjects::Device &);
|
||||
bool CreateDefaultDevice(std::string & SerialNumber, std::string & Capabilities, std::string & Firmware, std::string &Compatible,const Poco::Net::IPAddress & IPAddress);
|
||||
bool CreateDefaultDevice(std::string &SerialNumber, const Config::Capabilities &Caps, std::string & Firmware, const Poco::Net::IPAddress & IPAddress);
|
||||
|
||||
bool GetDevice(std::string &SerialNumber, GWObjects::Device &);
|
||||
bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices, const std::string & orderBy="");
|
||||
@@ -111,14 +113,14 @@ namespace OpenWifi {
|
||||
bool GetDeviceFWUpdatePolicy(std::string & SerialNumber, std::string & Policy);
|
||||
bool SetDevicePassword(std::string & SerialNumber, std::string & Password);
|
||||
bool UpdateSerialNumberCache();
|
||||
void GetDeviceDbFieldList( Types::StringVec & Fields);
|
||||
static void GetDeviceDbFieldList( Types::StringVec & Fields);
|
||||
|
||||
bool ExistingConfiguration(std::string &SerialNumber, uint64_t CurrentConfig, std::string &NewConfig, uint64_t &);
|
||||
|
||||
bool UpdateDeviceCapabilities(std::string &SerialNumber, std::string &State, std::string & Compatible);
|
||||
bool UpdateDeviceCapabilities(std::string &SerialNumber, const Config::Capabilities & Capabilities);
|
||||
bool GetDeviceCapabilities(std::string &SerialNumber, GWObjects::Capabilities &);
|
||||
bool DeleteDeviceCapabilities(std::string & SerialNumber);
|
||||
bool CreateDeviceCapabilities(std::string & SerialNumber, std::string & Capabilities);
|
||||
bool CreateDeviceCapabilities(std::string & SerialNumber, const Config::Capabilities & Capabilities);
|
||||
bool InitCapabilitiesCache();
|
||||
|
||||
bool GetLogData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, uint64_t Offset, uint64_t HowMany,
|
||||
@@ -144,9 +146,9 @@ namespace OpenWifi {
|
||||
bool DeleteCommand( std::string &UUID );
|
||||
bool GetReadyToExecuteCommands( uint64_t Offset, uint64_t HowMany, std::vector<GWObjects::CommandDetails> & Commands );
|
||||
bool CommandExecuted(std::string & UUID);
|
||||
bool CommandCompleted(std::string & UUID, const Poco::JSON::Object & ReturnVars, const std::chrono::duration<double, std::milli> & execution_time, bool FullCommand);
|
||||
bool CommandCompleted(std::string & UUID, Poco::JSON::Object::Ptr ReturnVars, const std::chrono::duration<double, std::milli> & execution_time, bool FullCommand);
|
||||
// bool AttachFileToCommand(std::string & UUID);
|
||||
bool AttachFileDataToCommand(std::string & UUID, const std::stringstream &s);
|
||||
bool AttachFileDataToCommand(std::string & UUID, const std::stringstream &s, const std::string &Type);
|
||||
bool CancelWaitFile( std::string & UUID, std::string & ErrorText );
|
||||
// bool GetAttachedFile(std::string & UUID, const std::string & SerialNumber, const std::string & FileName, std::string &Type);
|
||||
bool GetAttachedFileContent(std::string & UUID, const std::string & SerialNumber, std::string & FileContent, std::string &Type);
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace OpenWifi {
|
||||
void TelemetryClient::SendTelemetryShutdown() {
|
||||
poco_information(Logger(),fmt::format("TELEMETRY-SHUTDOWN({}): Closing.",CId_));
|
||||
DeRegister();
|
||||
AP_WS_Server()->StopWebSocketTelemetry(CommandManager()->NextRPCId(), SerialNumber_);
|
||||
AP_WS_Server()->StopWebSocketTelemetry(CommandManager()->Next_RPC_ID(), SerialNumber_);
|
||||
TelemetryStream()->DeRegisterClient(UUID_);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,12 +4,13 @@
|
||||
|
||||
#include "UI_GW_WebSocketNotifications.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
inline void WebNotificationSingleDevice::to_json(Poco::JSON::Object &Obj) const {
|
||||
namespace OpenWifi::GWWebSocketNotifications {
|
||||
|
||||
inline void SingleDevice::to_json(Poco::JSON::Object &Obj) const {
|
||||
RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber);
|
||||
}
|
||||
|
||||
inline bool WebNotificationSingleDevice::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
inline bool SingleDevice::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber);
|
||||
return true;
|
||||
@@ -19,13 +20,13 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void WebNotificationSingleDeviceConfigurationChange::to_json(Poco::JSON::Object &Obj) const {
|
||||
inline void SingleDeviceConfigurationChange::to_json(Poco::JSON::Object &Obj) const {
|
||||
RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber);
|
||||
RESTAPI_utils::field_to_json(Obj,"oldUUID", oldUUID);
|
||||
RESTAPI_utils::field_to_json(Obj,"newUUID", newUUID);
|
||||
}
|
||||
|
||||
inline bool WebNotificationSingleDeviceConfigurationChange::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
inline bool SingleDeviceConfigurationChange::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber);
|
||||
RESTAPI_utils::field_from_json(Obj,"oldUUID", oldUUID);
|
||||
@@ -37,12 +38,12 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void WebNotificationSingleDeviceFirmwareChange::to_json(Poco::JSON::Object &Obj) const {
|
||||
inline void SingleDeviceFirmwareChange::to_json(Poco::JSON::Object &Obj) const {
|
||||
RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber);
|
||||
RESTAPI_utils::field_to_json(Obj,"newFirmware", newFirmware);
|
||||
}
|
||||
|
||||
inline bool WebNotificationSingleDeviceFirmwareChange::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
inline bool SingleDeviceFirmwareChange::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber);
|
||||
RESTAPI_utils::field_from_json(Obj,"newFirmware", newFirmware);
|
||||
@@ -53,13 +54,13 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void WebSocketClientNotificationNumberOfConnection::to_json(Poco::JSON::Object &Obj) const {
|
||||
inline void NumberOfConnection::to_json(Poco::JSON::Object &Obj) const {
|
||||
RESTAPI_utils::field_to_json(Obj,"numberOfDevices", numberOfDevices);
|
||||
RESTAPI_utils::field_to_json(Obj,"averageConnectedTime", averageConnectedTime);
|
||||
RESTAPI_utils::field_to_json(Obj,"numberOfConnectingDevices", numberOfConnectingDevices);
|
||||
}
|
||||
|
||||
inline bool WebSocketClientNotificationNumberOfConnection::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
inline bool NumberOfConnection::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
RESTAPI_utils::field_from_json(Obj,"numberOfDevices", numberOfDevices);
|
||||
RESTAPI_utils::field_from_json(Obj,"averageConnectedTime", averageConnectedTime);
|
||||
@@ -71,64 +72,89 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
void WebSocketClientNotificationNumberOfConnections(WebSocketClientNotificationNumberOfConnection_t &N) {
|
||||
N.type = "device_connections_statistics";
|
||||
UI_WebSocketClientServer()->SendNotification(N);
|
||||
}
|
||||
void WebSocketClientNotificationNumberOfConnections(const std::string & User, WebSocketClientNotificationNumberOfConnection_t &N) {
|
||||
N.type = "device_connections_statistics";
|
||||
UI_WebSocketClientServer()->SendUserNotification(User,N);
|
||||
}
|
||||
|
||||
void WebSocketClientNotificationDeviceConfigurationChange(WebNotificationSingleDeviceConfigurationChange_t &N) {
|
||||
N.type = "device_configuration_upgrade";
|
||||
void NumberOfConnections(NumberOfConnection_t &N) {
|
||||
// N.type = "device_connections_statistics";
|
||||
N.type_id = 1000 ;
|
||||
UI_WebSocketClientServer()->SendNotification(N);
|
||||
}
|
||||
|
||||
void WebSocketClientNotificationDeviceConfigurationChange(const std::string & User, WebNotificationSingleDeviceConfigurationChange_t &N) {
|
||||
N.type = "device_configuration_upgrade";
|
||||
void NumberOfConnections(const std::string & User, NumberOfConnection_t &N) {
|
||||
// N.type = "device_connections_statistics";
|
||||
N.type_id = 1000 ;
|
||||
UI_WebSocketClientServer()->SendUserNotification(User,N);
|
||||
}
|
||||
|
||||
void WebSocketClientNotificationDeviceFirmwareUpdated(WebNotificationSingleDeviceFirmwareChange_t &N) {
|
||||
N.type = "device_firmware_upgrade";
|
||||
void DeviceConfigurationChange(SingleDeviceConfigurationChange_t &N) {
|
||||
// N.type = "device_configuration_upgrade";
|
||||
N.type_id = 2000 ;
|
||||
UI_WebSocketClientServer()->SendNotification(N);
|
||||
}
|
||||
|
||||
void WebSocketClientNotificationDeviceFirmwareUpdated(const std::string & User, WebNotificationSingleDeviceFirmwareChange_t &N){
|
||||
N.type = "device_firmware_upgrade";
|
||||
void DeviceConfigurationChange(const std::string & User, SingleDeviceConfigurationChange_t &N) {
|
||||
// N.type = "device_configuration_upgrade";
|
||||
N.type_id = 2000 ;
|
||||
UI_WebSocketClientServer()->SendUserNotification(User,N);
|
||||
}
|
||||
|
||||
void WebSocketClientNotificationDeviceConnected(WebNotificationSingleDevice_t &N){
|
||||
N.type = "device_connection";
|
||||
void DeviceFirmwareUpdated(SingleDeviceFirmwareChange_t &N) {
|
||||
// N.type = "device_firmware_upgrade";
|
||||
N.type_id = 3000 ;
|
||||
UI_WebSocketClientServer()->SendNotification(N);
|
||||
}
|
||||
|
||||
void WebSocketClientNotificationDeviceConnected(const std::string & User, WebNotificationSingleDevice_t &N){
|
||||
N.type = "device_connection";
|
||||
void DeviceFirmwareUpdated(const std::string & User, SingleDeviceFirmwareChange_t &N){
|
||||
// N.type = "device_firmware_upgrade";
|
||||
N.type_id = 3000 ;
|
||||
UI_WebSocketClientServer()->SendUserNotification(User,N);
|
||||
}
|
||||
|
||||
void WebSocketClientNotificationDeviceDisconnected(const std::string & User, WebNotificationSingleDevice_t &N){
|
||||
N.type = "device_disconnection";
|
||||
UI_WebSocketClientServer()->SendUserNotification(User,N);
|
||||
}
|
||||
|
||||
void WebSocketClientNotificationDeviceDisconnected(WebNotificationSingleDevice_t &N){
|
||||
N.type = "device_disconnection";
|
||||
void DeviceConnected(SingleDevice_t &N){
|
||||
// N.type = "device_connection";
|
||||
N.type_id = 4000 ;
|
||||
UI_WebSocketClientServer()->SendNotification(N);
|
||||
}
|
||||
|
||||
void WebSocketClientNotificationDeviceStatistics(const std::string & User, WebNotificationSingleDevice_t &N){
|
||||
N.type = "device_statistics";
|
||||
void DeviceConnected(const std::string & User, SingleDevice_t &N){
|
||||
// N.type = "device_connection";
|
||||
N.type_id = 4000 ;
|
||||
UI_WebSocketClientServer()->SendUserNotification(User,N);
|
||||
}
|
||||
|
||||
void WebSocketClientNotificationDeviceStatistics(WebNotificationSingleDevice_t &N){
|
||||
N.type = "device_statistics";
|
||||
void DeviceDisconnected(const std::string & User, SingleDevice_t &N){
|
||||
// N.type = "device_disconnection";
|
||||
N.type_id = 5000 ;
|
||||
UI_WebSocketClientServer()->SendUserNotification(User,N);
|
||||
}
|
||||
|
||||
void DeviceDisconnected(SingleDevice_t &N){
|
||||
// N.type = "device_disconnection";
|
||||
N.type_id = 5000 ;
|
||||
UI_WebSocketClientServer()->SendNotification(N);
|
||||
}
|
||||
|
||||
void DeviceStatistics(const std::string & User, SingleDevice_t &N){
|
||||
// N.type = "device_statistics";
|
||||
N.type_id = 6000 ;
|
||||
UI_WebSocketClientServer()->SendUserNotification(User,N);
|
||||
}
|
||||
|
||||
void DeviceStatistics(SingleDevice_t &N){
|
||||
// N.type = "device_statistics";
|
||||
N.type_id = 6000 ;
|
||||
UI_WebSocketClientServer()->SendNotification(N);
|
||||
}
|
||||
|
||||
void Register() {
|
||||
static const UI_WebSocketClientServer::NotificationTypeIdVec Notifications = {
|
||||
{ 1000, "device_connections_statistics" },
|
||||
{ 2000, "device_configuration_upgrade" },
|
||||
{ 3000, "device_firmware_upgrade" },
|
||||
{ 4000, "device_connection" },
|
||||
{ 5000, "device_disconnection" },
|
||||
{ 6000, "device_statistics" }
|
||||
};
|
||||
|
||||
UI_WebSocketClientServer()->RegisterNotifications(Notifications);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,14 +7,15 @@
|
||||
#include "framework/UI_WebSocketClientNotifications.h"
|
||||
#include "framework/UI_WebSocketClientServer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
struct WebNotificationSingleDevice {
|
||||
namespace OpenWifi::GWWebSocketNotifications {
|
||||
|
||||
struct SingleDevice {
|
||||
std::string serialNumber;
|
||||
inline void to_json(Poco::JSON::Object &Obj) const ;
|
||||
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct WebNotificationSingleDeviceConfigurationChange {
|
||||
struct SingleDeviceConfigurationChange {
|
||||
std::string serialNumber;
|
||||
uint64_t oldUUID;
|
||||
uint64_t newUUID;
|
||||
@@ -23,14 +24,14 @@ namespace OpenWifi {
|
||||
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct WebNotificationSingleDeviceFirmwareChange {
|
||||
struct SingleDeviceFirmwareChange {
|
||||
std::string serialNumber;
|
||||
std::string newFirmware;
|
||||
inline void to_json(Poco::JSON::Object &Obj) const ;
|
||||
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct WebSocketClientNotificationNumberOfConnection {
|
||||
struct NumberOfConnection {
|
||||
std::uint64_t numberOfDevices=0;
|
||||
std::uint64_t averageConnectedTime=0;
|
||||
std::uint64_t numberOfConnectingDevices=0;
|
||||
@@ -39,23 +40,25 @@ namespace OpenWifi {
|
||||
inline bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
typedef WebSocketNotification<WebNotificationSingleDevice> WebNotificationSingleDevice_t;
|
||||
typedef WebSocketNotification<WebNotificationSingleDeviceConfigurationChange> WebNotificationSingleDeviceConfigurationChange_t;
|
||||
typedef WebSocketNotification<WebNotificationSingleDeviceFirmwareChange> WebNotificationSingleDeviceFirmwareChange_t;
|
||||
typedef WebSocketNotification<WebSocketClientNotificationNumberOfConnection> WebSocketClientNotificationNumberOfConnection_t;
|
||||
void Register();
|
||||
|
||||
void WebSocketClientNotificationNumberOfConnections(WebSocketClientNotificationNumberOfConnection_t &N);
|
||||
void WebSocketClientNotificationDeviceConfigurationChange(WebNotificationSingleDeviceConfigurationChange_t &N);
|
||||
void WebSocketClientNotificationDeviceFirmwareUpdated(WebNotificationSingleDeviceFirmwareChange_t &);
|
||||
void WebSocketClientNotificationDeviceConnected(WebNotificationSingleDevice_t &N);
|
||||
void WebSocketClientNotificationDeviceDisconnected(WebNotificationSingleDevice_t &N);
|
||||
void WebSocketClientNotificationDeviceStatistics(WebNotificationSingleDevice_t &N);
|
||||
typedef WebSocketNotification<SingleDevice> SingleDevice_t;
|
||||
typedef WebSocketNotification<SingleDeviceConfigurationChange> SingleDeviceConfigurationChange_t;
|
||||
typedef WebSocketNotification<SingleDeviceFirmwareChange> SingleDeviceFirmwareChange_t;
|
||||
typedef WebSocketNotification<NumberOfConnection> NumberOfConnection_t;
|
||||
|
||||
void WebSocketClientNotificationNumberOfConnections(const std::string & User, WebSocketClientNotificationNumberOfConnection_t &N);
|
||||
void WebSocketClientNotificationDeviceConfigurationChange(const std::string & User, WebNotificationSingleDeviceConfigurationChange_t &N);
|
||||
void WebSocketClientNotificationDeviceFirmwareUpdated(const std::string & User, WebNotificationSingleDeviceFirmwareChange_t &);
|
||||
void WebSocketClientNotificationDeviceConnected(const std::string & User, WebNotificationSingleDevice_t &N);
|
||||
void WebSocketClientNotificationDeviceDisconnected(const std::string & User, WebNotificationSingleDevice_t &N);
|
||||
void WebSocketClientNotificationDeviceStatistics(const std::string & User, WebNotificationSingleDevice_t &N);
|
||||
void NumberOfConnections(NumberOfConnection_t &N);
|
||||
void DeviceConfigurationChange(SingleDeviceConfigurationChange_t &N);
|
||||
void DeviceFirmwareUpdated(SingleDeviceFirmwareChange_t &);
|
||||
void DeviceConnected(SingleDevice_t &N);
|
||||
void DeviceDisconnected(SingleDevice_t &N);
|
||||
void DeviceStatistics(SingleDevice_t &N);
|
||||
|
||||
void NumberOfConnections(const std::string & User, NumberOfConnection_t &N);
|
||||
void DeviceConfigurationChange(const std::string & User, SingleDeviceConfigurationChange_t &N);
|
||||
void DeviceFirmwareUpdated(const std::string & User, SingleDeviceFirmwareChange_t &);
|
||||
void DeviceConnected(const std::string & User, SingleDevice_t &N);
|
||||
void DeviceDisconnected(const std::string & User, SingleDevice_t &N);
|
||||
void DeviceStatistics(const std::string & User, SingleDevice_t &N);
|
||||
|
||||
};
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "framework/AuthClient.h"
|
||||
#include "framework/MicroServiceNames.h"
|
||||
#include "framework/OpenAPIRequests.h"
|
||||
#include "framework/utils.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
@@ -18,10 +19,13 @@ namespace OpenWifi {
|
||||
try {
|
||||
Types::StringPairVec QueryData;
|
||||
QueryData.push_back(std::make_pair("token",SessionToken));
|
||||
std::string AlternateURIForLogging = fmt::format("{}?token={}", Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken", Utils::SanitizeToken(SessionToken));
|
||||
OpenAPIRequestGet Req( uSERVICE_SECURITY,
|
||||
Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken",
|
||||
QueryData,
|
||||
10000);
|
||||
10000,
|
||||
AlternateURIForLogging
|
||||
);
|
||||
Poco::JSON::Object::Ptr Response;
|
||||
|
||||
auto StatusCode = Req.Do(Response);
|
||||
@@ -46,7 +50,7 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
poco_error(Logger(),fmt::format("Failed to retrieve token={} for TID={}", SessionToken, TID));
|
||||
poco_error(Logger(),fmt::format("Failed to retrieve token={} for TID={}", Utils::SanitizeToken(SessionToken), TID));
|
||||
}
|
||||
Expired = false;
|
||||
return false;
|
||||
@@ -59,6 +63,7 @@ namespace OpenWifi {
|
||||
if(!User.isNull()) {
|
||||
if(IsTokenExpired(User->webtoken)) {
|
||||
Expired = true;
|
||||
Cache_.remove(SessionToken);
|
||||
return false;
|
||||
}
|
||||
Expired = false;
|
||||
@@ -68,4 +73,57 @@ namespace OpenWifi {
|
||||
return RetrieveTokenInformation(SessionToken, UInfo, TID, Expired, Contacted, Sub);
|
||||
}
|
||||
|
||||
bool AuthClient::RetrieveApiKeyInformation(const std::string & SessionToken,
|
||||
SecurityObjects::UserInfoAndPolicy & UInfo,
|
||||
std::uint64_t TID,
|
||||
bool & Expired, bool & Contacted) {
|
||||
try {
|
||||
Types::StringPairVec QueryData;
|
||||
QueryData.push_back(std::make_pair("apikey",SessionToken));
|
||||
std::string AlternateURIForLogging = fmt::format("/api/v1/validateApiKey?apiKey={}", Utils::SanitizeToken(SessionToken));
|
||||
OpenAPIRequestGet Req( uSERVICE_SECURITY,
|
||||
"/api/v1/validateApiKey" ,
|
||||
QueryData,
|
||||
10000,
|
||||
AlternateURIForLogging);
|
||||
Poco::JSON::Object::Ptr Response;
|
||||
|
||||
auto StatusCode = Req.Do(Response);
|
||||
if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT) {
|
||||
Contacted = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
Contacted = true;
|
||||
if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_OK) {
|
||||
if(Response->has("tokenInfo") && Response->has("userInfo") && Response->has("expiresOn")) {
|
||||
UInfo.from_json(Response);
|
||||
Expired = false;
|
||||
ApiKeyCache_.update(SessionToken, ApiKeyCacheEntry{ .UserInfo = UInfo, .ExpiresOn = Response->get("expiresOn")});
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
poco_error(Logger(),fmt::format("Failed to retrieve api key={} for TID={}", Utils::SanitizeToken(SessionToken), TID));
|
||||
}
|
||||
Expired = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AuthClient::IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy &UInfo,
|
||||
std::uint64_t TID, bool &Expired, bool &Contacted) {
|
||||
auto User = ApiKeyCache_.get(SessionToken);
|
||||
if (!User.isNull()) {
|
||||
if(User->ExpiresOn < Utils::Now()) {
|
||||
Expired = false;
|
||||
UInfo = User->UserInfo;
|
||||
return true;
|
||||
}
|
||||
ApiKeyCache_.remove(SessionToken);
|
||||
}
|
||||
return RetrieveApiKeyInformation(SessionToken, UInfo, TID, Expired, Contacted);
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
@@ -12,6 +12,7 @@
|
||||
namespace OpenWifi {
|
||||
|
||||
class AuthClient : public SubSystemServer {
|
||||
|
||||
public:
|
||||
explicit AuthClient() noexcept:
|
||||
SubSystemServer("Authentication", "AUTH-CLNT", "authentication")
|
||||
@@ -23,7 +24,12 @@ namespace OpenWifi {
|
||||
return instance_;
|
||||
}
|
||||
|
||||
inline int Start() override {
|
||||
struct ApiKeyCacheEntry {
|
||||
OpenWifi::SecurityObjects::UserInfoAndPolicy UserInfo;
|
||||
std::uint64_t ExpiresOn;
|
||||
};
|
||||
|
||||
inline int Start() override {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -36,6 +42,7 @@ namespace OpenWifi {
|
||||
|
||||
inline void RemovedCachedToken(const std::string &Token) {
|
||||
Cache_.remove(Token);
|
||||
ApiKeyCache_.remove(Token);
|
||||
}
|
||||
|
||||
inline static bool IsTokenExpired(const SecurityObjects::WebToken &T) {
|
||||
@@ -46,12 +53,24 @@ namespace OpenWifi {
|
||||
SecurityObjects::UserInfoAndPolicy & UInfo,
|
||||
std::uint64_t TID,
|
||||
bool & Expired, bool & Contacted, bool Sub=false);
|
||||
|
||||
bool RetrieveApiKeyInformation(const std::string & SessionToken,
|
||||
SecurityObjects::UserInfoAndPolicy & UInfo,
|
||||
std::uint64_t TID,
|
||||
bool & Expired, bool & Contacted);
|
||||
|
||||
bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
|
||||
std::uint64_t TID,
|
||||
bool & Expired, bool & Contacted, bool Sub = false);
|
||||
|
||||
bool IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
|
||||
std::uint64_t TID,
|
||||
bool & Expired, bool & Contacted);
|
||||
|
||||
private:
|
||||
|
||||
Poco::ExpireLRUCache<std::string,OpenWifi::SecurityObjects::UserInfoAndPolicy> Cache_{512,1200000 };
|
||||
Poco::ExpireLRUCache<std::string,ApiKeyCacheEntry> ApiKeyCache_{512,1200000 };
|
||||
};
|
||||
|
||||
inline auto AuthClient() { return AuthClient::instance(); }
|
||||
|
||||
@@ -2632,7 +2632,7 @@ static json DefaultUCentralSchema = R"(
|
||||
std::string GitSchema;
|
||||
if(MicroServiceConfigGetBool("ucentral.datamodel.internal",true)) {
|
||||
RootSchema_ = DefaultUCentralSchema;
|
||||
Logger().information("Using uCentral validation from built-in default.");
|
||||
poco_information(Logger(),"Using uCentral validation from built-in default.");
|
||||
Initialized_ = Working_ = true;
|
||||
return;
|
||||
}
|
||||
@@ -2641,7 +2641,7 @@ static json DefaultUCentralSchema = R"(
|
||||
auto GitURI = MicroServiceConfigGetString("ucentral.datamodel.uri",GitUCentralJSONSchemaFile);
|
||||
if(Utils::wgets(GitURI, GitSchema)) {
|
||||
RootSchema_ = json::parse(GitSchema);
|
||||
Logger().information("Using uCentral validation schema from GIT.");
|
||||
poco_information(Logger(),"Using uCentral validation schema from GIT.");
|
||||
} else {
|
||||
std::string FileName{ MicroServiceDataDirectory() + "/ucentral.schema.json" };
|
||||
std::ifstream input(FileName);
|
||||
@@ -2649,11 +2649,11 @@ static json DefaultUCentralSchema = R"(
|
||||
schema_file << input.rdbuf();
|
||||
input.close();
|
||||
RootSchema_ = json::parse(schema_file.str());
|
||||
Logger().information("Using uCentral validation schema from local file.");
|
||||
poco_information(Logger(),"Using uCentral validation schema from local file.");
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
RootSchema_ = DefaultUCentralSchema;
|
||||
Logger().information("Using uCentral validation from built-in default.");
|
||||
poco_information(Logger(),"Using uCentral validation from built-in default.");
|
||||
}
|
||||
Initialized_ = Working_ = true;
|
||||
}
|
||||
@@ -2812,7 +2812,7 @@ static json DefaultUCentralSchema = R"(
|
||||
}
|
||||
|
||||
void ConfigurationValidator::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
||||
Logger().information("Reinitializing.");
|
||||
poco_information(Logger(),"Reinitializing.");
|
||||
Working_ = Initialized_ = false;
|
||||
Init();
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "Poco/FormattingChannel.h"
|
||||
#include "Poco/AsyncChannel.h"
|
||||
#include "Poco/NullChannel.h"
|
||||
#include "Poco/SplitterChannel.h"
|
||||
#include "Poco/Net/HTTPStreamFactory.h"
|
||||
#include "Poco/Net/HTTPSStreamFactory.h"
|
||||
#include "Poco/Net/FTPSStreamFactory.h"
|
||||
@@ -26,7 +27,7 @@
|
||||
#include "framework/RESTAPI_ExtServer.h"
|
||||
#include "framework/RESTAPI_IntServer.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
#include "framework/WebSocketLogger.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -77,7 +78,7 @@ namespace OpenWifi {
|
||||
else
|
||||
SvcList += ", " + Svc.second.Type;
|
||||
}
|
||||
logger().information(fmt::format("Current list of microservices: {}", SvcList));
|
||||
poco_information(logger(),fmt::format("Current list of microservices: {}", SvcList));
|
||||
}
|
||||
} else {
|
||||
poco_error(logger(),fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",Event));
|
||||
@@ -180,8 +181,6 @@ namespace OpenWifi {
|
||||
MyHash_ = Utils::ComputeHash(MyPublicEndPoint_);
|
||||
}
|
||||
|
||||
void MicroServicePostInitialization();
|
||||
|
||||
void MicroService::InitializeLoggingSystem() {
|
||||
static auto initialized = false;
|
||||
|
||||
@@ -192,75 +191,143 @@ namespace OpenWifi {
|
||||
auto LoggingDestination = MicroService::instance().ConfigGetString("logging.type", "file");
|
||||
auto LoggingFormat = MicroService::instance().ConfigGetString("logging.format",
|
||||
"%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t");
|
||||
auto UseAsyncLogs_ = MicroService::instance().ConfigGetBool("logging.asynch",false);
|
||||
auto UseAsyncLogs_ = MicroService::instance().ConfigGetBool("logging.asynch", true);
|
||||
auto DisableWebSocketLogging = MicroService::instance().ConfigGetBool("logging.websocket",false);
|
||||
|
||||
if (LoggingDestination == "null") {
|
||||
Poco::AutoPtr<Poco::NullChannel> DevNull(new Poco::NullChannel);
|
||||
Poco::Logger::root().setChannel(DevNull);
|
||||
} else if (LoggingDestination == "console") {
|
||||
Poco::AutoPtr<Poco::ConsoleChannel> Console(new Poco::ConsoleChannel);
|
||||
if(UseAsyncLogs_) {
|
||||
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Console));
|
||||
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
|
||||
Formatter->setProperty("pattern", LoggingFormat);
|
||||
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
|
||||
new Poco::FormattingChannel(Formatter, Async));
|
||||
Poco::Logger::root().setChannel(FormattingChannel);
|
||||
} else {
|
||||
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
|
||||
Formatter->setProperty("pattern", LoggingFormat);
|
||||
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
|
||||
new Poco::FormattingChannel(Formatter, Console));
|
||||
Poco::Logger::root().setChannel(FormattingChannel);
|
||||
}
|
||||
SetConsoleLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
|
||||
} else if (LoggingDestination == "colorconsole") {
|
||||
Poco::AutoPtr<Poco::ColorConsoleChannel> ColorConsole(new Poco::ColorConsoleChannel);
|
||||
if(UseAsyncLogs_) {
|
||||
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(ColorConsole));
|
||||
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
|
||||
Formatter->setProperty("pattern", LoggingFormat);
|
||||
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
|
||||
new Poco::FormattingChannel(Formatter, Async));
|
||||
Poco::Logger::root().setChannel(FormattingChannel);
|
||||
} else {
|
||||
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
|
||||
Formatter->setProperty("pattern", LoggingFormat);
|
||||
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
|
||||
new Poco::FormattingChannel(Formatter, ColorConsole));
|
||||
Poco::Logger::root().setChannel(FormattingChannel);
|
||||
}
|
||||
SetColorConsoleLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
|
||||
} else if (LoggingDestination == "sql") {
|
||||
//"CREATE TABLE T_POCO_LOG (Source VARCHAR, Name VARCHAR, ProcessId INTEGER, Thread VARCHAR, ThreadId INTEGER, Priority INTEGER, Text VARCHAR, DateTime DATE)"
|
||||
|
||||
SetSQLLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
|
||||
} else if (LoggingDestination == "syslog") {
|
||||
|
||||
SetSyslogLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
|
||||
} else {
|
||||
auto LoggingLocation =
|
||||
MicroService::instance().ConfigPath("logging.path", "$OWCERT_ROOT/logs") + "/log";
|
||||
SetFileLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat, DAEMON_ROOT_ENV_VAR);
|
||||
}
|
||||
|
||||
Poco::AutoPtr<Poco::FileChannel> FileChannel(new Poco::FileChannel);
|
||||
FileChannel->setProperty("rotation", "10 M");
|
||||
FileChannel->setProperty("archive", "timestamp");
|
||||
FileChannel->setProperty("path", LoggingLocation);
|
||||
if(UseAsyncLogs_) {
|
||||
Poco::AutoPtr<Poco::AsyncChannel> Async_File(
|
||||
new Poco::AsyncChannel(FileChannel));
|
||||
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
|
||||
Formatter->setProperty("pattern", LoggingFormat);
|
||||
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
|
||||
new Poco::FormattingChannel(Formatter, Async_File));
|
||||
Poco::Logger::root().setChannel(FormattingChannel);
|
||||
} else {
|
||||
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
|
||||
Formatter->setProperty("pattern", LoggingFormat);
|
||||
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
|
||||
new Poco::FormattingChannel(Formatter, FileChannel));
|
||||
Poco::Logger::root().setChannel(FormattingChannel);
|
||||
}
|
||||
}
|
||||
auto Level = Poco::Logger::parseLevel(MicroService::instance().ConfigGetString("logging.level", "debug"));
|
||||
Poco::Logger::root().setLevel(Level);
|
||||
if(!DisableWebSocketLogging) {
|
||||
static const UI_WebSocketClientServer::NotificationTypeIdVec Notifications = {
|
||||
{1, "log"}};
|
||||
UI_WebSocketClientServer()->RegisterNotifications(Notifications);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MicroService::SetConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) {
|
||||
|
||||
Poco::AutoPtr<Poco::ConsoleChannel> Console(new Poco::ConsoleChannel);
|
||||
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
|
||||
Formatter->setProperty("pattern", FormatterPattern);
|
||||
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, Console));
|
||||
|
||||
if(DisableWebSocketLogging) {
|
||||
if(UseAsync) {
|
||||
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(FormattingChannel));
|
||||
Poco::Logger::root().setChannel(Async);
|
||||
} else {
|
||||
Poco::Logger::root().setChannel(FormattingChannel);
|
||||
}
|
||||
} else {
|
||||
Poco::AutoPtr<WebSocketLogger> WSLogger(new WebSocketLogger);
|
||||
Poco::AutoPtr<Poco::SplitterChannel> Splitter(new Poco::SplitterChannel);
|
||||
Splitter->addChannel(WSLogger);
|
||||
Splitter->addChannel(FormattingChannel);
|
||||
if(UseAsync) {
|
||||
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Splitter));
|
||||
Poco::Logger::root().setChannel(Async);
|
||||
} else {
|
||||
Poco::Logger::root().setChannel(Splitter);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MicroService::SetColorConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) {
|
||||
|
||||
Poco::AutoPtr<Poco::ColorConsoleChannel> Console(new Poco::ColorConsoleChannel);
|
||||
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
|
||||
Formatter->setProperty("pattern", FormatterPattern);
|
||||
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, Console));
|
||||
|
||||
if(DisableWebSocketLogging) {
|
||||
if(UseAsync) {
|
||||
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(FormattingChannel));
|
||||
Poco::Logger::root().setChannel(Async);
|
||||
} else {
|
||||
Poco::Logger::root().setChannel(FormattingChannel);
|
||||
}
|
||||
} else {
|
||||
Poco::AutoPtr<WebSocketLogger> WSLogger(new WebSocketLogger);
|
||||
Poco::AutoPtr<Poco::SplitterChannel> Splitter(new Poco::SplitterChannel);
|
||||
Splitter->addChannel(WSLogger);
|
||||
Splitter->addChannel(FormattingChannel);
|
||||
if(UseAsync) {
|
||||
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Splitter));
|
||||
Poco::Logger::root().setChannel(Async);
|
||||
} else {
|
||||
Poco::Logger::root().setChannel(Splitter);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MicroService::SetSQLLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]] bool DisableWebSocketLogging,[[maybe_unused]] const std::string & FormatterPattern) {
|
||||
//"CREATE TABLE T_POCO_LOG (Source VARCHAR, Name VARCHAR, ProcessId INTEGER, Thread VARCHAR, ThreadId INTEGER, Priority INTEGER, Text VARCHAR, DateTime DATE)"
|
||||
}
|
||||
|
||||
void MicroService::SetSyslogLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]] bool DisableWebSocketLogging,[[maybe_unused]] const std::string & FormatterPattern) {
|
||||
|
||||
}
|
||||
|
||||
void MicroService::SetFileLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern, const std::string & root_env_var) {
|
||||
std::string DefaultLogPath = fmt::format("${}/logs",root_env_var);
|
||||
auto LoggingLocationDir = MicroService::instance().ConfigPath("logging.path", DefaultLogPath);
|
||||
Poco::File LD(LoggingLocationDir);
|
||||
try {
|
||||
if(!LD.exists()) {
|
||||
LD.createDirectory();
|
||||
}
|
||||
} catch(const Poco::Exception &E) {
|
||||
std::cout << "Cannot create " << LD.path() << " Error: " << E.message() << std::endl;
|
||||
}
|
||||
auto LoggingLocationDirFilePattern = LoggingLocationDir + "/log";
|
||||
|
||||
Poco::AutoPtr<Poco::FileChannel> FileChannel(new Poco::FileChannel);
|
||||
FileChannel->setProperty("rotation", "10 M");
|
||||
FileChannel->setProperty("archive", "timestamp");
|
||||
FileChannel->setProperty("purgeCount", "10");
|
||||
FileChannel->setProperty("path", LoggingLocationDirFilePattern);
|
||||
|
||||
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
|
||||
Formatter->setProperty("pattern", FormatterPattern);
|
||||
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, FileChannel));
|
||||
|
||||
if(DisableWebSocketLogging) {
|
||||
if(UseAsync) {
|
||||
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(FormattingChannel));
|
||||
Poco::Logger::root().setChannel(Async);
|
||||
} else {
|
||||
Poco::Logger::root().setChannel(FormattingChannel);
|
||||
}
|
||||
} else {
|
||||
Poco::AutoPtr<WebSocketLogger> WSLogger(new WebSocketLogger);
|
||||
Poco::AutoPtr<Poco::SplitterChannel> Splitter(new Poco::SplitterChannel);
|
||||
Splitter->addChannel(WSLogger);
|
||||
Splitter->addChannel(FormattingChannel);
|
||||
if(UseAsync) {
|
||||
Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Splitter));
|
||||
Poco::Logger::root().setChannel(Async);
|
||||
} else {
|
||||
Poco::Logger::root().setChannel(Splitter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DaemonPostInitialization(Poco::Util::Application &self);
|
||||
|
||||
@@ -590,15 +657,15 @@ namespace OpenWifi {
|
||||
logger.notice(fmt::format("Starting {} version {}.",DAEMON_APP_NAME, Version()));
|
||||
|
||||
if(Poco::Net::Socket::supportsIPv6())
|
||||
logger.information("System supports IPv6.");
|
||||
poco_information(logger,"System supports IPv6.");
|
||||
else
|
||||
logger.information("System does NOT support IPv6.");
|
||||
poco_information(logger,"System does NOT support IPv6.");
|
||||
|
||||
if (config().getBool("application.runAsDaemon", false)) {
|
||||
logger.information("Starting as a daemon.");
|
||||
poco_information(logger,"Starting as a daemon.");
|
||||
}
|
||||
|
||||
logger.information(fmt::format("System ID set to {}",ID_));
|
||||
poco_information(logger,fmt::format("System ID set to {}",ID_));
|
||||
StartSubSystemServers();
|
||||
waitForTerminationRequest();
|
||||
StopSubSystemServers();
|
||||
@@ -630,4 +697,15 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
void MicroService::DeleteOverrideConfiguration() {
|
||||
Poco::File F(DataDir_ + ExtraConfigurationFilename);
|
||||
|
||||
try {
|
||||
if(F.exists())
|
||||
F.remove();
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -55,7 +55,6 @@ namespace OpenWifi {
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "ow_version.h"
|
||||
#include "fmt/core.h"
|
||||
#include "framework/MicroServiceErrorHandler.h"
|
||||
|
||||
#define _OWDEBUG_ std::cout<< __FILE__ <<":" << __LINE__ << std::endl;
|
||||
// #define _OWDEBUG_ Logger().debug(Poco::format("%s: %lu",__FILE__,__LINE__));
|
||||
@@ -82,6 +81,8 @@ namespace OpenWifi {
|
||||
// Logger_ = Poco::Logger::root().get("BASE-SVC");
|
||||
}
|
||||
|
||||
inline static const char * ExtraConfigurationFilename = "/configuration_override.json";
|
||||
|
||||
inline void SaveConfig() { PropConfigurationFile_->save(ConfigFileName_); }
|
||||
inline auto UpdateConfig() { return PropConfigurationFile_; }
|
||||
inline bool NoAPISecurity() const { return NoAPISecurity_; }
|
||||
@@ -152,9 +153,17 @@ namespace OpenWifi {
|
||||
int main(const ArgVec &args) override;
|
||||
void InitializeLoggingSystem();
|
||||
|
||||
void DeleteOverrideConfiguration();
|
||||
|
||||
[[nodiscard]] std::string Sign(Poco::JWT::Token &T, const std::string &Algo);
|
||||
void AddActivity(const std::string &Activity);
|
||||
|
||||
static void SetConsoleLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
|
||||
static void SetColorConsoleLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
|
||||
static void SetSQLLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
|
||||
static void SetSyslogLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
|
||||
static void SetFileLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern, const std::string & root_env_var);
|
||||
|
||||
private:
|
||||
static MicroService * instance_;
|
||||
bool HelpRequested_ = false;
|
||||
|
||||
@@ -167,4 +167,4 @@ namespace OpenWifi {
|
||||
int t_id=0;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
@@ -114,4 +114,8 @@ namespace OpenWifi {
|
||||
std::string MicroServiceGetPublicAPIEndPoint() {
|
||||
return MicroService::instance().GetPublicAPIEndPoint();
|
||||
}
|
||||
|
||||
void MicroServiceDeleteOverrideConfiguration() {
|
||||
return MicroService::instance().DeleteOverrideConfiguration();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,4 +52,5 @@ namespace OpenWifi {
|
||||
std::uint64_t MicroServiceRandom(std::uint64_t Range);
|
||||
std::string MicroServiceSign(Poco::JWT::Token &T, const std::string &Algo);
|
||||
std::string MicroServiceGetPublicAPIEndPoint();
|
||||
void MicroServiceDeleteOverrideConfiguration();
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace OpenWifi {
|
||||
Path,
|
||||
Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
|
||||
poco_debug(Poco::Logger::get("REST-CALLER-GET"),fmt::format(" {}", URI.toString()));
|
||||
poco_debug(Poco::Logger::get("REST-CALLER-GET"), fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
|
||||
|
||||
if(BearerToken.empty()) {
|
||||
Request.add("X-API-KEY", Svc.AccessKey);
|
||||
@@ -91,7 +91,7 @@ namespace OpenWifi {
|
||||
for (const auto &qp : QueryData_)
|
||||
URI.addQueryParameter(qp.first, qp.second);
|
||||
|
||||
poco_debug(Poco::Logger::get("REST-CALLER-PUT"),fmt::format("{}", URI.toString()));
|
||||
poco_debug(Poco::Logger::get("REST-CALLER-PUT"), fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
|
||||
|
||||
std::string Path(URI.getPathAndQuery());
|
||||
|
||||
@@ -170,7 +170,7 @@ namespace OpenWifi {
|
||||
for (const auto &qp : QueryData_)
|
||||
URI.addQueryParameter(qp.first, qp.second);
|
||||
|
||||
poco_debug(Poco::Logger::get("REST-CALLER-POST"),fmt::format(" {}", URI.toString()));
|
||||
poco_debug(Poco::Logger::get("REST-CALLER-POST"),fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
|
||||
|
||||
std::string Path(URI.getPathAndQuery());
|
||||
|
||||
@@ -246,7 +246,7 @@ namespace OpenWifi {
|
||||
for (const auto &qp : QueryData_)
|
||||
URI.addQueryParameter(qp.first, qp.second);
|
||||
|
||||
poco_debug(Poco::Logger::get("REST-CALLER-DELETE"),fmt::format(" {}", URI.toString()));
|
||||
poco_debug(Poco::Logger::get("REST-CALLER-DELETE"),fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
|
||||
|
||||
std::string Path(URI.getPathAndQuery());
|
||||
|
||||
|
||||
@@ -18,17 +18,20 @@ namespace OpenWifi {
|
||||
explicit OpenAPIRequestGet( const std::string & Type,
|
||||
const std::string & EndPoint,
|
||||
const Types::StringPairVec & QueryData,
|
||||
uint64_t msTimeout):
|
||||
uint64_t msTimeout,
|
||||
const std::string &LoggingStr=""):
|
||||
Type_(Type),
|
||||
EndPoint_(EndPoint),
|
||||
QueryData_(QueryData),
|
||||
msTimeout_(msTimeout) {};
|
||||
msTimeout_(msTimeout),
|
||||
LoggingStr_(LoggingStr){};
|
||||
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
|
||||
private:
|
||||
std::string Type_;
|
||||
std::string EndPoint_;
|
||||
Types::StringPairVec QueryData_;
|
||||
uint64_t msTimeout_;
|
||||
std::string LoggingStr_;
|
||||
};
|
||||
|
||||
class OpenAPIRequestPut {
|
||||
@@ -37,12 +40,14 @@ namespace OpenWifi {
|
||||
const std::string & EndPoint,
|
||||
const Types::StringPairVec & QueryData,
|
||||
const Poco::JSON::Object & Body,
|
||||
uint64_t msTimeout):
|
||||
uint64_t msTimeout,
|
||||
const std::string &LoggingStr=""):
|
||||
Type_(Type),
|
||||
EndPoint_(EndPoint),
|
||||
QueryData_(QueryData),
|
||||
msTimeout_(msTimeout),
|
||||
Body_(Body){};
|
||||
Body_(Body),
|
||||
LoggingStr_(LoggingStr){};
|
||||
|
||||
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
|
||||
|
||||
@@ -52,6 +57,7 @@ namespace OpenWifi {
|
||||
Types::StringPairVec QueryData_;
|
||||
uint64_t msTimeout_;
|
||||
Poco::JSON::Object Body_;
|
||||
std::string LoggingStr_;
|
||||
};
|
||||
|
||||
class OpenAPIRequestPost {
|
||||
@@ -60,12 +66,14 @@ namespace OpenWifi {
|
||||
const std::string & EndPoint,
|
||||
const Types::StringPairVec & QueryData,
|
||||
const Poco::JSON::Object & Body,
|
||||
uint64_t msTimeout):
|
||||
uint64_t msTimeout,
|
||||
const std::string &LoggingStr=""):
|
||||
Type_(Type),
|
||||
EndPoint_(EndPoint),
|
||||
QueryData_(QueryData),
|
||||
msTimeout_(msTimeout),
|
||||
Body_(Body){};
|
||||
Body_(Body),
|
||||
LoggingStr_(LoggingStr){};
|
||||
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
|
||||
private:
|
||||
std::string Type_;
|
||||
@@ -73,18 +81,21 @@ namespace OpenWifi {
|
||||
Types::StringPairVec QueryData_;
|
||||
uint64_t msTimeout_;
|
||||
Poco::JSON::Object Body_;
|
||||
std::string LoggingStr_;
|
||||
};
|
||||
|
||||
class OpenAPIRequestDelete {
|
||||
public:
|
||||
explicit OpenAPIRequestDelete( const std::string & Type,
|
||||
const std::string & EndPoint,
|
||||
const Types::StringPairVec & QueryData,
|
||||
uint64_t msTimeout):
|
||||
Type_(Type),
|
||||
EndPoint_(EndPoint),
|
||||
QueryData_(QueryData),
|
||||
msTimeout_(msTimeout){};
|
||||
explicit OpenAPIRequestDelete( const std::string & Type,
|
||||
const std::string & EndPoint,
|
||||
const Types::StringPairVec & QueryData,
|
||||
uint64_t msTimeout,
|
||||
const std::string &LoggingStr=""):
|
||||
Type_(Type),
|
||||
EndPoint_(EndPoint),
|
||||
QueryData_(QueryData),
|
||||
msTimeout_(msTimeout),
|
||||
LoggingStr_(LoggingStr){};
|
||||
Poco::Net::HTTPServerResponse::HTTPStatus Do(const std::string & BearerToken = "");
|
||||
|
||||
private:
|
||||
@@ -93,6 +104,7 @@ namespace OpenWifi {
|
||||
Types::StringPairVec QueryData_;
|
||||
uint64_t msTimeout_;
|
||||
Poco::JSON::Object Body_;
|
||||
std::string LoggingStr_;
|
||||
};
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -30,15 +30,15 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
inline int Start() override {
|
||||
Logger().information("Starting.");
|
||||
poco_information(Logger(),"Starting.");
|
||||
Server_.InitLogging();
|
||||
|
||||
for(const auto & Svr: ConfigServersList_) {
|
||||
|
||||
if(MicroServiceNoAPISecurity()) {
|
||||
Logger().information(fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
|
||||
poco_information(Logger(),fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
|
||||
} else {
|
||||
Logger().information(fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
|
||||
poco_information(Logger(),fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
|
||||
Svr.KeyFile(),Svr.CertFile()));
|
||||
Svr.LogCert(Logger());
|
||||
if (!Svr.RootCA().empty())
|
||||
@@ -64,18 +64,18 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
inline void Stop() override {
|
||||
Logger().information("Stopping...");
|
||||
poco_information(Logger(),"Stopping...");
|
||||
for( const auto & svr : RESTServers_ )
|
||||
svr->stopAll(true);
|
||||
Pool_.stopAll();
|
||||
Pool_.joinAll();
|
||||
RESTServers_.clear();
|
||||
Logger().information("Stopped...");
|
||||
poco_information(Logger(),"Stopped...");
|
||||
}
|
||||
|
||||
inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
|
||||
MicroServiceLoadConfigurationFile();
|
||||
Logger().information("Reinitializing.");
|
||||
poco_information(Logger(),"Reinitializing.");
|
||||
Stop();
|
||||
Start();
|
||||
}
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
#include "framework/AuthClient.h"
|
||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||
|
||||
#if defined(TIP_SECURITY_SERVICE)
|
||||
#include "AuthService.h"
|
||||
#endif
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace OpenWifi {
|
||||
@@ -388,7 +392,7 @@ namespace OpenWifi {
|
||||
std::ostream &Answer = Response->send();
|
||||
Poco::JSON::Stringifier::stringify(ErrorObject, Answer);
|
||||
poco_debug(Logger_,fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}",
|
||||
UserInfo_.userinfo.email,
|
||||
Requester(),
|
||||
Utils::FormatIPv6(Request->clientAddress().toString()),
|
||||
Request->getMethod(),
|
||||
Request->getURI()));
|
||||
@@ -546,6 +550,27 @@ namespace OpenWifi {
|
||||
Poco::JSON::Stringifier::stringify(Object, Answer);
|
||||
}
|
||||
|
||||
inline void ReturnRawJSON(const std::string &json_doc) {
|
||||
PrepareResponse();
|
||||
if(Request!= nullptr) {
|
||||
// can we compress ???
|
||||
auto AcceptedEncoding = Request->find("Accept-Encoding");
|
||||
if(AcceptedEncoding!=Request->end()) {
|
||||
if( AcceptedEncoding->second.find("gzip")!=std::string::npos ||
|
||||
AcceptedEncoding->second.find("compress")!=std::string::npos) {
|
||||
Response->set("Content-Encoding", "gzip");
|
||||
std::ostream &Answer = Response->send();
|
||||
Poco::DeflatingOutputStream deflater(Answer, Poco::DeflatingStreamBuf::STREAM_GZIP);
|
||||
deflater << json_doc;
|
||||
deflater.close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
std::ostream &Answer = Response->send();
|
||||
Answer << json_doc;
|
||||
}
|
||||
|
||||
inline void ReturnCountOnly(uint64_t Count) {
|
||||
Poco::JSON::Object Answer;
|
||||
Answer.set("count", Count);
|
||||
@@ -640,7 +665,8 @@ namespace OpenWifi {
|
||||
};
|
||||
|
||||
#ifdef TIP_SECURITY_SERVICE
|
||||
[[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired , bool Sub );
|
||||
[[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken,
|
||||
SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired , bool Sub );
|
||||
#endif
|
||||
inline bool RESTAPIHandler::IsAuthorized( bool & Expired , [[maybe_unused]] bool & Contacted , bool Sub ) {
|
||||
if(Internal_ && Request->has("X-INTERNAL-NAME")) {
|
||||
@@ -665,7 +691,36 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
return Allowed;
|
||||
} else {
|
||||
} else if(!Internal_ && Request->has("X-API-KEY")) {
|
||||
SessionToken_ = Request->get("X-API-KEY", "");
|
||||
#ifdef TIP_SECURITY_SERVICE
|
||||
std::uint64_t expiresOn;
|
||||
if (AuthService()->IsValidApiKey(SessionToken_, UserInfo_.webtoken, UserInfo_.userinfo, Expired, expiresOn)) {
|
||||
#else
|
||||
if (AuthClient()->IsValidApiKey( SessionToken_, UserInfo_, TransactionId_, Expired, Contacted)) {
|
||||
#endif
|
||||
REST_Requester_ = UserInfo_.userinfo.email;
|
||||
if(Server_.LogIt(Request->getMethod(),true)) {
|
||||
poco_debug(Logger_,fmt::format("X-REQ-ALLOWED({}): APIKEY-ACCESS TID={} User='{}@{}' Method={} Path={}",
|
||||
UserInfo_.userinfo.email,
|
||||
TransactionId_,
|
||||
Utils::FormatIPv6(Request->clientAddress().toString()),
|
||||
Request->clientAddress().toString(),
|
||||
Request->getMethod(),
|
||||
Request->getURI()));
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
if(Server_.LogBadTokens(true)) {
|
||||
poco_debug(Logger_,fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}",
|
||||
Utils::FormatIPv6(Request->clientAddress().toString()),
|
||||
TransactionId_,
|
||||
Request->getMethod(),
|
||||
Request->getURI()));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} else {
|
||||
if (SessionToken_.empty()) {
|
||||
try {
|
||||
Poco::Net::OAuth20Credentials Auth(*Request);
|
||||
|
||||
@@ -30,15 +30,15 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
inline int Start() override {
|
||||
Logger().information("Starting.");
|
||||
poco_information(Logger(),"Starting.");
|
||||
Server_.InitLogging();
|
||||
|
||||
for(const auto & Svr: ConfigServersList_) {
|
||||
|
||||
if(MicroServiceNoAPISecurity()) {
|
||||
Logger().information(fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
|
||||
poco_information(Logger(),fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
|
||||
} else {
|
||||
Logger().information(fmt::format("Starting: {}:{}. Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
|
||||
poco_information(Logger(),fmt::format("Starting: {}:{}. Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
|
||||
Svr.KeyFile(),Svr.CertFile()));
|
||||
Svr.LogCert(Logger());
|
||||
if (!Svr.RootCA().empty())
|
||||
@@ -65,17 +65,17 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
inline void Stop() override {
|
||||
Logger().information("Stopping...");
|
||||
poco_information(Logger(),"Stopping...");
|
||||
for( const auto & svr : RESTServers_ )
|
||||
svr->stopAll(true);
|
||||
Pool_.stopAll();
|
||||
Pool_.joinAll();
|
||||
Logger().information("Stopped...");
|
||||
poco_information(Logger(),"Stopped...");
|
||||
}
|
||||
|
||||
inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
|
||||
MicroServiceLoadConfigurationFile();
|
||||
Logger().information("Reinitializing.");
|
||||
poco_information(Logger(),"Reinitializing.");
|
||||
Stop();
|
||||
Start();
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace OpenWifi {
|
||||
auto Name = GetS(RESTAPI::Protocol::TAG, InnerObj);
|
||||
auto Value = GetS(RESTAPI::Protocol::VALUE, InnerObj);
|
||||
MicroServiceSetSubsystemLogLevel(Name, Value);
|
||||
Logger_.information(
|
||||
poco_information(Logger_,
|
||||
fmt::format("Setting log level for {} at {}", Name, Value));
|
||||
}
|
||||
}
|
||||
|
||||
52
src/framework/RESTAPI_SystemConfiguration.h
Normal file
52
src/framework/RESTAPI_SystemConfiguration.h
Normal file
@@ -0,0 +1,52 @@
|
||||
//
|
||||
// Created by stephane bourque on 2022-10-31.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class RESTAPI_system_configuration : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_system_configuration(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
|
||||
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
|
||||
bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_PUT,
|
||||
Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal) {}
|
||||
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/systemConfiguration"}; }
|
||||
|
||||
inline void DoPost() final {}
|
||||
|
||||
inline void DoGet() final {
|
||||
|
||||
return OK();
|
||||
}
|
||||
|
||||
inline void DoPut() final{
|
||||
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
|
||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
return OK();
|
||||
};
|
||||
|
||||
inline void DoDelete() final{
|
||||
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
|
||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||
}
|
||||
MicroServiceDeleteOverrideConfiguration();
|
||||
return OK();
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -16,7 +16,7 @@ namespace OpenWifi {
|
||||
inline RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{ Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal,false) {}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/ws"};}
|
||||
void DoGet() final {
|
||||
@@ -27,7 +27,7 @@ namespace OpenWifi {
|
||||
{
|
||||
Poco::Net::WebSocket WS(*Request, *Response);
|
||||
auto Id = MicroServiceCreateUUID();
|
||||
UI_WebSocketClientServer()->NewClient(WS,Id,UserInfo_.userinfo.email);
|
||||
UI_WebSocketClientServer()->NewClient(WS,Id,UserInfo_.userinfo.email, TransactionId_);
|
||||
}
|
||||
catch (...) {
|
||||
std::cout << "Cannot create websocket client..." << std::endl;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void onPrivateKeyRequested([[maybe_unused]] const void * pSender,std::string & privateKey) {
|
||||
Logger_.information("Returning key passphrase.");
|
||||
poco_information(Logger_,"Returning key passphrase.");
|
||||
privateKey = Password_;
|
||||
};
|
||||
inline Poco::Logger & Logger() { return Logger_; }
|
||||
@@ -83,7 +83,7 @@ namespace OpenWifi {
|
||||
inline void uninitialize() override {
|
||||
}
|
||||
inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
|
||||
Logger_->L_.information("Reloading of this subsystem is not supported.");
|
||||
poco_information(Logger_->L_,"Reloading of this subsystem is not supported.");
|
||||
}
|
||||
inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override {
|
||||
}
|
||||
|
||||
@@ -10,11 +10,12 @@
|
||||
namespace OpenWifi {
|
||||
|
||||
template<typename ContentStruct>
|
||||
|
||||
struct WebSocketNotification {
|
||||
inline static uint64_t xid = 1;
|
||||
uint64_t notification_id = ++xid;
|
||||
std::string type;
|
||||
ContentStruct content;
|
||||
uint64_t notification_id = ++xid;
|
||||
std::uint64_t type_id=0;
|
||||
ContentStruct content;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
|
||||
@@ -24,7 +25,7 @@ namespace OpenWifi {
|
||||
template<typename ContentStruct>
|
||||
void WebSocketNotification<ContentStruct>::to_json(Poco::JSON::Object &Obj) const {
|
||||
RESTAPI_utils::field_to_json(Obj, "notification_id", notification_id);
|
||||
RESTAPI_utils::field_to_json(Obj, "type", type);
|
||||
RESTAPI_utils::field_to_json(Obj, "type_id", type_id);
|
||||
RESTAPI_utils::field_to_json(Obj, "content", content);
|
||||
}
|
||||
|
||||
@@ -32,8 +33,8 @@ namespace OpenWifi {
|
||||
bool WebSocketNotification<ContentStruct>::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
RESTAPI_utils::field_from_json(Obj, "notification_id", notification_id);
|
||||
RESTAPI_utils::field_from_json(Obj, "content", content);
|
||||
RESTAPI_utils::field_from_json(Obj, "type", type);
|
||||
RESTAPI_utils::field_from_json(Obj, "type_id", type_id);
|
||||
RESTAPI_utils::field_from_json(Obj, "content", content);
|
||||
return true;
|
||||
} catch (...) {
|
||||
|
||||
|
||||
@@ -15,16 +15,20 @@
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
#if defined(TIP_SECURITY_SERVICE)
|
||||
#include "AuthService.h"
|
||||
#endif
|
||||
|
||||
#define DBG { std::cout << __LINE__ << std::endl; }
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void UI_WebSocketClientServer::NewClient(Poco::Net::WebSocket & WS, const std::string &Id, const std::string &UserName ) {
|
||||
void UI_WebSocketClientServer::NewClient(Poco::Net::WebSocket & WS, const std::string &Id, const std::string &UserName, std::uint64_t TID ) {
|
||||
|
||||
std::lock_guard G(Mutex_);
|
||||
std::lock_guard G(LocalMutex_);
|
||||
auto Client = std::make_unique<UI_WebSocketClientInfo>(WS,Id, UserName);
|
||||
auto ClientSocket = Client->WS_->impl()->sockfd();
|
||||
|
||||
TID_ = TID;
|
||||
Client->WS_->setNoDelay(true);
|
||||
Client->WS_->setKeepAlive(true);
|
||||
Client->WS_->setBlocking(false);
|
||||
@@ -39,6 +43,7 @@ namespace OpenWifi {
|
||||
*this, &UI_WebSocketClientServer::OnSocketError));
|
||||
Client->SocketRegistered_ = true;
|
||||
Clients_[ClientSocket] = std::move(Client);
|
||||
UsersConnected_ = Clients_.size();
|
||||
}
|
||||
|
||||
void UI_WebSocketClientServer::SetProcessor( UI_WebSocketClientProcessor * F) {
|
||||
@@ -50,10 +55,28 @@ namespace OpenWifi {
|
||||
{
|
||||
}
|
||||
|
||||
void UI_WebSocketClientServer::EndConnection([[maybe_unused]] std::lock_guard<std::recursive_mutex> &G, ClientList::iterator &Client) {
|
||||
void UI_WebSocketClientServer::run() {
|
||||
Running_ = true;
|
||||
while(Running_) {
|
||||
Poco::Thread::trySleep(2000);
|
||||
|
||||
if(!Running_)
|
||||
break;
|
||||
|
||||
std::lock_guard G(LocalMutex_);
|
||||
for(const auto i:ToBeRemoved_) {
|
||||
// std::cout << "Erasing old WS UI connection..." << std::endl;
|
||||
Clients_.erase(i);
|
||||
}
|
||||
ToBeRemoved_.clear();
|
||||
UsersConnected_ = Clients_.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void UI_WebSocketClientServer::EndConnection(ClientList::iterator Client) {
|
||||
if(Client->second->SocketRegistered_) {
|
||||
Client->second->SocketRegistered_ = false;
|
||||
(*Client->second->WS_).shutdown();
|
||||
Reactor_.removeEventHandler(*Client->second->WS_,
|
||||
Poco::NObserver<UI_WebSocketClientServer,
|
||||
Poco::Net::ReadableNotification>(*this,&UI_WebSocketClientServer::OnSocketReadable));
|
||||
@@ -64,27 +87,17 @@ namespace OpenWifi {
|
||||
Poco::NObserver<UI_WebSocketClientServer,
|
||||
Poco::Net::ErrorNotification>(*this,&UI_WebSocketClientServer::OnSocketError));
|
||||
}
|
||||
Clients_.erase(Client);
|
||||
std::cout << "How many clients: " << Clients_.size() << std::endl;
|
||||
ToBeRemoved_.push_back(Client);
|
||||
}
|
||||
|
||||
void UI_WebSocketClientServer::run() {
|
||||
Running_ = true ;
|
||||
Utils::SetThreadName("ws:uiclnt-svr");
|
||||
while(Running_) {
|
||||
Poco::Thread::trySleep(2000);
|
||||
|
||||
if(!Running_)
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
int UI_WebSocketClientServer::Start() {
|
||||
poco_information(Logger(),"Starting...");
|
||||
GoogleApiKey_ = MicroServiceConfigGetString("google.apikey","");
|
||||
GeoCodeEnabled_ = !GoogleApiKey_.empty();
|
||||
ReactorThread_.start(Reactor_);
|
||||
Thr_.start(*this);
|
||||
ReactorThread_.setName("ws:ui-reactor");
|
||||
CleanerThread_.start(*this);
|
||||
CleanerThread_.setName("ws:ui-cleaner");
|
||||
return 0;
|
||||
};
|
||||
|
||||
@@ -95,45 +108,43 @@ namespace OpenWifi {
|
||||
Reactor_.stop();
|
||||
ReactorThread_.join();
|
||||
Running_ = false;
|
||||
Thr_.wakeUp();
|
||||
Thr_.join();
|
||||
CleanerThread_.wakeUp();
|
||||
CleanerThread_.join();
|
||||
poco_information(Logger(),"Stopped...");
|
||||
}
|
||||
};
|
||||
|
||||
bool UI_WebSocketClientServer::SendToId(const std::string &Id, const std::string &Payload) {
|
||||
std::lock_guard G(Mutex_);
|
||||
|
||||
for(const auto &Client:Clients_) {
|
||||
if(Client.second->Id_==Id)
|
||||
return Client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size());
|
||||
}
|
||||
return false;
|
||||
bool UI_WebSocketClientServer::IsFiltered(std::uint64_t id, const OpenWifi::UI_WebSocketClientInfo &Client) {
|
||||
return std::find(Client.Filter_.begin(), Client.Filter_.end(),id)!=end(Client.Filter_);
|
||||
}
|
||||
|
||||
bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, const std::string &Payload) {
|
||||
bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, std::uint64_t id, const std::string &Payload) {
|
||||
std::lock_guard G(Mutex_);
|
||||
uint64_t Sent=0;
|
||||
|
||||
for(const auto &client:Clients_) {
|
||||
if(client.second->UserName_ == UserName) {
|
||||
for(const auto &Client:Clients_) {
|
||||
if(Client.second->UserName_ == UserName) {
|
||||
try {
|
||||
if (client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size()))
|
||||
Sent++;
|
||||
if(!IsFiltered(id,*Client.second) && Client.second->Authenticated_) {
|
||||
return Client.second->WS_->sendFrame(
|
||||
Payload.c_str(), (int)Payload.size()) == (int)Payload.size();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Sent>0;
|
||||
return false;
|
||||
}
|
||||
|
||||
void UI_WebSocketClientServer::SendToAll(const std::string &Payload) {
|
||||
void UI_WebSocketClientServer::SendToAll(std::uint64_t id, const std::string &Payload) {
|
||||
std::lock_guard G(Mutex_);
|
||||
|
||||
for(const auto &client:Clients_) {
|
||||
for(const auto &Client:Clients_) {
|
||||
try {
|
||||
client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size());
|
||||
if(!IsFiltered(id,*Client.second) && Client.second->Authenticated_)
|
||||
Client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size());
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
@@ -144,12 +155,35 @@ namespace OpenWifi {
|
||||
return Clients_.find(ClientSocket);
|
||||
}
|
||||
|
||||
void UI_WebSocketClientServer::SortNotifications() {
|
||||
struct {
|
||||
bool operator()(const NotificationEntry &A, const NotificationEntry & B) const {
|
||||
return A.id < B.id; };
|
||||
} CompareNotifications;
|
||||
std::sort(NotificationTypes_.begin(), NotificationTypes_.end(), CompareNotifications);
|
||||
|
||||
NotificationTypesJSON_.clear();
|
||||
Poco::JSON::Array AllNotifications;
|
||||
for(const auto ¬ification:NotificationTypes_) {
|
||||
Poco::JSON::Object Notification;
|
||||
Notification.set("id", notification.id);
|
||||
Notification.set("helper", notification.helper);
|
||||
AllNotifications.add(Notification);
|
||||
}
|
||||
NotificationTypesJSON_.set("notificationTypes", AllNotifications);
|
||||
}
|
||||
|
||||
void UI_WebSocketClientServer::RegisterNotifications(const OpenWifi::UI_WebSocketClientServer::NotificationTypeIdVec &Notifications) {
|
||||
std::copy(Notifications.begin(), Notifications.end(), std::back_inserter(NotificationTypes_));
|
||||
SortNotifications();
|
||||
}
|
||||
|
||||
void UI_WebSocketClientServer::OnSocketError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
|
||||
std::lock_guard G(LocalMutex_);
|
||||
auto Client = FindWSClient(G,pNf->socket().impl()->sockfd());
|
||||
auto Client = Clients_.find(pNf->socket().impl()->sockfd());
|
||||
if(Client==end(Clients_))
|
||||
return;
|
||||
EndConnection(G,Client);
|
||||
EndConnection(Client);
|
||||
}
|
||||
|
||||
void UI_WebSocketClientServer::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
||||
@@ -160,7 +194,7 @@ namespace OpenWifi {
|
||||
|
||||
try {
|
||||
|
||||
Client = FindWSClient(G,pNf->socket().impl()->sockfd());
|
||||
Client = Clients_.find(pNf->socket().impl()->sockfd());
|
||||
if( Client == end(Clients_))
|
||||
return;
|
||||
|
||||
@@ -172,7 +206,7 @@ namespace OpenWifi {
|
||||
|
||||
if (n == 0) {
|
||||
poco_debug(Logger(),fmt::format("CLOSE({}): {} UI Client is closing WS connection.", Client->second->Id_, Client->second->UserName_));
|
||||
return EndConnection(G, Client);
|
||||
return EndConnection(Client);
|
||||
}
|
||||
|
||||
switch (Op) {
|
||||
@@ -185,32 +219,56 @@ namespace OpenWifi {
|
||||
} break;
|
||||
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
|
||||
poco_debug(Logger(),fmt::format("CLOSE({}): {} UI Client is closing WS connection.", Client->second->Id_, Client->second->UserName_));
|
||||
return EndConnection(G, Client);
|
||||
return EndConnection(Client);
|
||||
} break;
|
||||
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
|
||||
constexpr const char *DropMessagesCommand = "drop-notifications";
|
||||
IncomingFrame.append(0);
|
||||
if (!Client->second->Authenticated_) {
|
||||
std::string Frame{IncomingFrame.begin()};
|
||||
auto Tokens = Utils::Split(Frame, ':');
|
||||
bool Expired = false, Contacted = false;
|
||||
bool Expired = false;
|
||||
#if not defined(TIP_SECURITY_SERVICE)
|
||||
bool Contacted = false;
|
||||
#endif
|
||||
if (Tokens.size() == 2 &&
|
||||
AuthClient()->IsAuthorized(Tokens[1], Client->second->UserInfo_, 0, Expired, Contacted)) {
|
||||
#if defined(TIP_SECURITY_SERVICE)
|
||||
AuthService()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_, Expired)) {
|
||||
#else
|
||||
AuthClient()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_, Expired, Contacted)) {
|
||||
#endif
|
||||
Client->second->Authenticated_ = true;
|
||||
Client->second->UserName_ = Client->second->UserInfo_.userinfo.email;
|
||||
poco_debug(Logger(),fmt::format("START({}): {} UI Client is starting WS connection.", Client->second->Id_, Client->second->UserName_));
|
||||
std::string S{"Welcome! Bienvenue! Bienvenidos!"};
|
||||
Client->second->WS_->sendFrame(S.c_str(), S.size());
|
||||
auto WelcomeMessage = NotificationTypesJSON_;
|
||||
WelcomeMessage.set("success", "Welcome! Bienvenue! Bienvenidos!");
|
||||
std::ostringstream OS;
|
||||
WelcomeMessage.stringify(OS);
|
||||
Client->second->WS_->sendFrame(OS.str().c_str(), (int) OS.str().size());
|
||||
Client->second->UserName_ = Client->second->UserInfo_.userinfo.email;
|
||||
} else {
|
||||
std::string S{"Invalid token. Closing connection."};
|
||||
Client->second->WS_->sendFrame(S.c_str(), S.size());
|
||||
return EndConnection(G, Client);
|
||||
Poco::JSON::Object WelcomeMessage;
|
||||
WelcomeMessage.set("error", "Invalid token. Closing connection.");
|
||||
std::ostringstream OS;
|
||||
WelcomeMessage.stringify(OS);
|
||||
Client->second->WS_->sendFrame(OS.str().c_str(), (int) OS.str().size());
|
||||
return EndConnection(Client);
|
||||
}
|
||||
|
||||
} else {
|
||||
Poco::JSON::Parser P;
|
||||
auto Obj =
|
||||
P.parse(IncomingFrame.begin()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if(Obj->has(DropMessagesCommand) && Obj->isArray(DropMessagesCommand)) {
|
||||
auto Filters = Obj->getArray(DropMessagesCommand);
|
||||
Client->second->Filter_.clear();
|
||||
for(const auto &Filter:*Filters) {
|
||||
Client->second->Filter_.emplace_back( (std::uint64_t) Filter);
|
||||
}
|
||||
std::sort(begin(Client->second->Filter_),end(Client->second->Filter_));
|
||||
return;
|
||||
}
|
||||
|
||||
std::string Answer;
|
||||
bool CloseConnection=false;
|
||||
if (Processor_ != nullptr) {
|
||||
@@ -223,7 +281,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
if(CloseConnection) {
|
||||
return EndConnection(G, Client);
|
||||
return EndConnection(Client);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
@@ -231,18 +289,16 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
return EndConnection(G, Client);
|
||||
return EndConnection(Client);
|
||||
}
|
||||
}
|
||||
|
||||
void UI_WebSocketClientServer::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
|
||||
ClientList::iterator Client;
|
||||
std::lock_guard G(LocalMutex_);
|
||||
try {
|
||||
Client = FindWSClient(G, pNf->socket().impl()->sockfd());
|
||||
auto Client = Clients_.find(pNf->socket().impl()->sockfd());
|
||||
if (Client == end(Clients_))
|
||||
return;
|
||||
EndConnection(G, Client);
|
||||
EndConnection(Client);
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class UI_WebSocketClient;
|
||||
|
||||
class UI_WebSocketClientProcessor {
|
||||
public:
|
||||
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done ) = 0;
|
||||
@@ -33,6 +31,7 @@ namespace OpenWifi {
|
||||
std::string UserName_;
|
||||
bool Authenticated_ = false;
|
||||
bool SocketRegistered_=false;
|
||||
std::vector<std::uint64_t> Filter_;
|
||||
SecurityObjects::UserInfoAndPolicy UserInfo_;
|
||||
|
||||
UI_WebSocketClientInfo(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &username) {
|
||||
@@ -50,11 +49,15 @@ namespace OpenWifi {
|
||||
return instance_;
|
||||
}
|
||||
|
||||
bool IsAnyoneConnected() {
|
||||
return UsersConnected_;
|
||||
}
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void run() override;
|
||||
Poco::Net::SocketReactor & Reactor() { return Reactor_; }
|
||||
void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName);
|
||||
void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName, std::uint64_t TID);
|
||||
void SetProcessor(UI_WebSocketClientProcessor *F);
|
||||
[[nodiscard]] inline bool GeoCodeEnabled() const { return GeoCodeEnabled_; }
|
||||
[[nodiscard]] inline std::string GoogleApiKey() const { return GoogleApiKey_; }
|
||||
@@ -69,7 +72,7 @@ namespace OpenWifi {
|
||||
std::ostringstream OO;
|
||||
Msg.stringify(OO);
|
||||
|
||||
return SendToUser(userName,OO.str());
|
||||
return SendToUser(userName, Notification.type_id, OO.str());
|
||||
}
|
||||
|
||||
template <typename T> void SendNotification(const WebSocketNotification<T> &Notification) {
|
||||
@@ -79,26 +82,41 @@ namespace OpenWifi {
|
||||
Msg.set("notification",Payload);
|
||||
std::ostringstream OO;
|
||||
Msg.stringify(OO);
|
||||
SendToAll(OO.str());
|
||||
SendToAll(Notification.type_id, OO.str());
|
||||
}
|
||||
|
||||
[[nodiscard]] bool SendToId(const std::string &Id, const std::string &Payload);
|
||||
[[nodiscard]] bool SendToUser(const std::string &userName, const std::string &Payload);
|
||||
void SendToAll(const std::string &Payload);
|
||||
[[nodiscard]] bool SendToUser(const std::string &userName, std::uint64_t id, const std::string &Payload);
|
||||
void SendToAll(std::uint64_t id, const std::string &Payload);
|
||||
|
||||
struct NotificationEntry {
|
||||
std::uint64_t id=0;
|
||||
std::string helper;
|
||||
};
|
||||
|
||||
using ClientList = std::map<int,std::unique_ptr<UI_WebSocketClientInfo>>;
|
||||
using NotificationTypeIdVec = std::vector<NotificationEntry>;
|
||||
|
||||
void RegisterNotifications(const NotificationTypeIdVec & Notifications);
|
||||
bool IsFiltered(std::uint64_t id, const UI_WebSocketClientInfo &Client);
|
||||
|
||||
private:
|
||||
mutable std::atomic_bool Running_ = false;
|
||||
Poco::Thread Thr_;
|
||||
volatile bool Running_ = false;
|
||||
std::atomic_uint64_t UsersConnected_=0;
|
||||
Poco::Net::SocketReactor Reactor_;
|
||||
Poco::Thread ReactorThread_;
|
||||
Poco::Thread CleanerThread_;
|
||||
std::recursive_mutex LocalMutex_;
|
||||
bool GeoCodeEnabled_ = false;
|
||||
std::string GoogleApiKey_;
|
||||
ClientList Clients_;
|
||||
bool GeoCodeEnabled_ = false;
|
||||
std::string GoogleApiKey_;
|
||||
ClientList Clients_;
|
||||
UI_WebSocketClientProcessor *Processor_ = nullptr;
|
||||
NotificationTypeIdVec NotificationTypes_;
|
||||
Poco::JSON::Object NotificationTypesJSON_;
|
||||
std::vector<ClientList::iterator> ToBeRemoved_;
|
||||
std::uint64_t TID_=0;
|
||||
|
||||
UI_WebSocketClientServer() noexcept;
|
||||
void EndConnection(std::lock_guard<std::recursive_mutex> &G, ClientList::iterator & Client);
|
||||
void EndConnection(ClientList::iterator Client);
|
||||
|
||||
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
|
||||
void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf);
|
||||
@@ -106,7 +124,7 @@ namespace OpenWifi {
|
||||
|
||||
ClientList::iterator FindWSClient( std::lock_guard<std::recursive_mutex> &G, int ClientSocket);
|
||||
|
||||
|
||||
void SortNotifications();
|
||||
};
|
||||
|
||||
inline auto UI_WebSocketClientServer() { return UI_WebSocketClientServer::instance(); }
|
||||
|
||||
@@ -5,29 +5,39 @@
|
||||
#pragma once
|
||||
|
||||
#include "framework/SubSystemServer.h"
|
||||
#include "framework/UI_WebSocketClientServer.h"
|
||||
#include "framework/UI_WebSocketClientNotifications.h"
|
||||
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class WebSocketLogger : public Poco::Channel {
|
||||
public:
|
||||
|
||||
inline std::string getProperty( [[maybe_unused]] const std::string &p ) const final {
|
||||
WebSocketLogger() {
|
||||
}
|
||||
|
||||
~WebSocketLogger() {
|
||||
}
|
||||
|
||||
std::string getProperty( [[maybe_unused]] const std::string &p ) const {
|
||||
std::cout << "WS getProperty" << std::endl;
|
||||
return "";
|
||||
}
|
||||
|
||||
inline void close() final {
|
||||
void close() final {
|
||||
}
|
||||
|
||||
inline void open() final {
|
||||
void open() final {
|
||||
}
|
||||
|
||||
inline static std::string to_string(Poco::Message::Priority p) {
|
||||
static std::string to_string(Poco::Message::Priority p) {
|
||||
switch(p) {
|
||||
case Poco::Message::PRIO_INFORMATION: return "information";
|
||||
case Poco::Message::PRIO_CRITICAL: return "critical";
|
||||
case Poco::Message::PRIO_DEBUG: return "debug";
|
||||
case Poco::Message::PRIO_ERROR: return "error";
|
||||
case Poco::Message::PRIO_FATAL: return "level";
|
||||
case Poco::Message::PRIO_FATAL: return "fatal";
|
||||
case Poco::Message::PRIO_NOTICE: return "notice";
|
||||
case Poco::Message::PRIO_TRACE: return "trace";
|
||||
case Poco::Message::PRIO_WARNING: return "warning";
|
||||
@@ -35,55 +45,63 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
inline void log(const Poco::Message &m) final {
|
||||
if(Enabled_) {
|
||||
/*
|
||||
nlohmann::json log_msg;
|
||||
log_msg["msg"] = m.getText();
|
||||
log_msg["level"] = to_string(m.getPriority());
|
||||
log_msg["timestamp"] = Poco::DateTimeFormatter::format(m.getTime(), Poco::DateTimeFormat::ISO8601_FORMAT);
|
||||
log_msg["source"] = m.getSource();
|
||||
log_msg["thread_name"] = m.getThread();
|
||||
log_msg["thread_id"] = m.getTid();
|
||||
struct NotificationLogMessage {
|
||||
std::string msg;
|
||||
std::string level;
|
||||
std::uint64_t timestamp;
|
||||
std::string source;
|
||||
std::string thread_name;
|
||||
std::uint64_t thread_id=0;
|
||||
|
||||
inline void to_json(Poco::JSON::Object &Obj) const {
|
||||
RESTAPI_utils::field_to_json(Obj,"msg", msg);
|
||||
RESTAPI_utils::field_to_json(Obj,"level", level);
|
||||
RESTAPI_utils::field_to_json(Obj,"timestamp", timestamp);
|
||||
RESTAPI_utils::field_to_json(Obj,"source", source);
|
||||
RESTAPI_utils::field_to_json(Obj,"thread_name", thread_name);
|
||||
RESTAPI_utils::field_to_json(Obj,"thread_id", thread_id);
|
||||
}
|
||||
|
||||
inline bool from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
RESTAPI_utils::field_from_json(Obj, "msg", msg);
|
||||
RESTAPI_utils::field_from_json(Obj, "level", level);
|
||||
RESTAPI_utils::field_from_json(Obj, "timestamp", timestamp);
|
||||
RESTAPI_utils::field_from_json(Obj, "source", source);
|
||||
RESTAPI_utils::field_from_json(Obj, "thread_name", thread_name);
|
||||
RESTAPI_utils::field_from_json(Obj, "thread_id", thread_id);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
std::cout << log_msg << std::endl;
|
||||
*/
|
||||
std::lock_guard G(Mutex_);
|
||||
std::vector<uint64_t> Remove;
|
||||
for(const auto &[Id,CallBack]:CallBacks_) {
|
||||
try {
|
||||
CallBack(m);
|
||||
} catch (...) {
|
||||
Remove.push_back(Id);
|
||||
}
|
||||
}
|
||||
for(const auto &i:Remove)
|
||||
CallBacks_.erase(i);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
typedef WebSocketNotification<NotificationLogMessage> WebSocketClientNotificationLogMessage_t;
|
||||
|
||||
void log(const Poco::Message &m) final {
|
||||
if(UI_WebSocketClientServer()->IsAnyoneConnected()) {
|
||||
WebSocketClientNotificationLogMessage_t Msg;
|
||||
Msg.content.msg = m.getText();
|
||||
Msg.content.level = WebSocketLogger::to_string(m.getPriority());
|
||||
Msg.content.timestamp = m.getTime().epochTime();
|
||||
Msg.content.source = m.getSource();
|
||||
Msg.content.thread_name = m.getThread();
|
||||
Msg.content.thread_id = m.getTid();
|
||||
Msg.type_id = 1;
|
||||
UI_WebSocketClientServer()->SendNotification(Msg);
|
||||
}
|
||||
}
|
||||
|
||||
inline void setProperty([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) final {
|
||||
|
||||
void setProperty([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) {
|
||||
std::cout << "WS setProperty" << std::endl;
|
||||
}
|
||||
|
||||
inline static auto instance() {
|
||||
static auto instance_ = new WebSocketLogger;
|
||||
return instance_;
|
||||
}
|
||||
inline void Enable(bool enable) { Enabled_ = enable; }
|
||||
typedef std::function<void(const Poco::Message &M)> logmuxer_callback_func_t;
|
||||
inline void RegisterCallback(const logmuxer_callback_func_t & R, uint64_t &Id) {
|
||||
std::lock_guard G(Mutex_);
|
||||
Id = CallBackId_++;
|
||||
CallBacks_[Id] = R;
|
||||
}
|
||||
private:
|
||||
std::recursive_mutex Mutex_;
|
||||
std::map<uint64_t,logmuxer_callback_func_t> CallBacks_;
|
||||
inline static uint64_t CallBackId_=1;
|
||||
bool Enabled_ = false;
|
||||
};
|
||||
|
||||
inline auto WebSocketLogger() { return WebSocketLogger::instance(); }
|
||||
// inline auto WebSocketLogger() { return WebSocketLogger::instance(); }
|
||||
|
||||
}
|
||||
@@ -219,6 +219,16 @@ namespace OpenWifi::RESTAPI::Errors {
|
||||
|
||||
static const struct msg MaximumRTTYSessionsReached{1144,"Too many RTTY sessions currently active"};
|
||||
static const struct msg DeviceIsAlreadyBusy{1145,"Device is already executing a command. Please try later."};
|
||||
|
||||
static const struct msg DeviceRequiresSignature{1146,"Device requires device signature to be provided."};
|
||||
|
||||
static const struct msg ApiKeyNameAlreadyExists{1147,"API Key name must be unique."};
|
||||
static const struct msg TooManyApiKeys{1148,"Too many API Keys have already been created."};
|
||||
static const struct msg UserMustExist{1149,"User must exist."};
|
||||
static const struct msg ApiKeyNameDoesNotExist{1150,"API Key name does not exist."};
|
||||
static const struct msg ApiKeyDoesNotExist{1150,"API Key does not exist."};
|
||||
|
||||
static const struct msg DeviceIsRestricted{1151,"Device is protected by regulation. This function is not allowed."};
|
||||
}
|
||||
|
||||
|
||||
@@ -433,6 +443,8 @@ namespace OpenWifi::uCentralProtocol {
|
||||
static const char *CHANNELS = "channels";
|
||||
static const char *PASSWORD = "password";
|
||||
static const char *DEVICEUPDATE = "deviceupdate";
|
||||
static const char *FWSIGNATURE = "FWsignature";
|
||||
static const char *SIGNATURE = "signature";
|
||||
|
||||
static const char *SERIALNUMBER = "serialNumber";
|
||||
static const char *COMPATIBLE = "compatible";
|
||||
|
||||
@@ -520,4 +520,15 @@ bool ExtractBase64CompressedData(const std::string &CompressedData,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsAlphaNumeric(const std::string &s) {
|
||||
return std::all_of(s.begin(),s.end(),[](char c) -> bool { return isalnum(c); });
|
||||
}
|
||||
|
||||
std::string SanitizeToken(const std::string &Token) {
|
||||
if(Token.size()>8) {
|
||||
return Token.substr(0,4) + "****" + Token.substr(Token.size()-4,4);
|
||||
}
|
||||
return "*******";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -115,6 +115,8 @@ namespace OpenWifi::Utils {
|
||||
[[nodiscard]] std::string BinaryFileToHexString(const Poco::File &F);
|
||||
[[nodiscard]] std::string SecondsToNiceText(uint64_t Seconds);
|
||||
[[nodiscard]] bool wgets(const std::string &URL, std::string &Response);
|
||||
[[nodiscard]] bool IsAlphaNumeric(const std::string &s);
|
||||
[[nodiscard]] std::string SanitizeToken(const std::string &Token);
|
||||
|
||||
template< typename T >
|
||||
std::string int_to_hex( T i )
|
||||
|
||||
@@ -17,20 +17,21 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
bool Storage::CreateDeviceCapabilities(std::string &SerialNumber, std::string &Capabilities) {
|
||||
bool Storage::CreateDeviceCapabilities(std::string & SerialNumber, const Config::Capabilities & Capabilities) {
|
||||
try {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Statement UpSert(Sess);
|
||||
|
||||
std::string TCaps{Capabilities.AsString()};
|
||||
uint64_t Now = Utils::Now();
|
||||
std::string St{ "insert into Capabilities (SerialNumber, Capabilities, FirstUpdate, LastUpdate) values(?,?,?,?) on conflict (SerialNumber) do "
|
||||
" update set Capabilities=?, LastUpdate=?"};
|
||||
UpSert << ConvertParams(St),
|
||||
Poco::Data::Keywords::use(SerialNumber),
|
||||
Poco::Data::Keywords::use(Capabilities),
|
||||
Poco::Data::Keywords::use(TCaps),
|
||||
Poco::Data::Keywords::use(Now),
|
||||
Poco::Data::Keywords::use(Now),
|
||||
Poco::Data::Keywords::use(Capabilities),
|
||||
Poco::Data::Keywords::use(TCaps),
|
||||
Poco::Data::Keywords::use(Now);
|
||||
UpSert.execute();
|
||||
return true;
|
||||
@@ -41,25 +42,25 @@ bool Storage::CreateDeviceCapabilities(std::string &SerialNumber, std::string &C
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Storage::UpdateDeviceCapabilities(std::string &SerialNumber, std::string & Capabilities, std::string & Compat) {
|
||||
bool Storage::UpdateDeviceCapabilities(std::string &SerialNumber, const Config::Capabilities & Caps) {
|
||||
try {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Statement UpSert(Sess);
|
||||
|
||||
uint64_t Now = Utils::Now();
|
||||
OpenWifi::Config::Capabilities Caps(Capabilities);
|
||||
Compat = Caps.Compatible();
|
||||
if(!Caps.Compatible().empty() && !Caps.Platform().empty())
|
||||
CapabilitiesCache::instance()->Add(Caps.Compatible(), Caps.Platform(), Capabilities);
|
||||
CapabilitiesCache()->Add(Caps);
|
||||
|
||||
std::string TCaps{Caps.AsString()};
|
||||
|
||||
std::string St{"insert into Capabilities (SerialNumber, Capabilities, FirstUpdate, LastUpdate) values(?,?,?,?) on conflict (SerialNumber) do "
|
||||
" update set Capabilities=?, LastUpdate=?"};
|
||||
UpSert << ConvertParams(St),
|
||||
Poco::Data::Keywords::use(SerialNumber),
|
||||
Poco::Data::Keywords::use(Capabilities),
|
||||
Poco::Data::Keywords::use(TCaps),
|
||||
Poco::Data::Keywords::use(Now),
|
||||
Poco::Data::Keywords::use(Now),
|
||||
Poco::Data::Keywords::use(Capabilities),
|
||||
Poco::Data::Keywords::use(TCaps),
|
||||
Poco::Data::Keywords::use(Now);
|
||||
UpSert.execute();
|
||||
return true;
|
||||
|
||||
@@ -508,7 +508,7 @@ typedef Poco::Tuple<
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Storage::CommandCompleted(std::string &UUID, const Poco::JSON::Object & ReturnVars,
|
||||
bool Storage::CommandCompleted(std::string &UUID, Poco::JSON::Object::Ptr ReturnVars,
|
||||
const std::chrono::duration<double, std::milli> & execution_time,
|
||||
bool FullCommand) {
|
||||
try {
|
||||
@@ -519,8 +519,8 @@ typedef Poco::Tuple<
|
||||
uint64_t ErrorCode = 0;
|
||||
std::string ErrorText, ResultStr;
|
||||
|
||||
if (ReturnVars.has("result")) {
|
||||
auto ResultObj = ReturnVars.get("result");
|
||||
if (ReturnVars->has("result")) {
|
||||
auto ResultObj = ReturnVars->get("result");
|
||||
auto ResultFields = ResultObj.extract<Poco::JSON::Object::Ptr>();
|
||||
if (ResultFields->has("status")) {
|
||||
auto StatusObj = ResultFields->get("status");
|
||||
@@ -584,7 +584,7 @@ typedef Poco::Tuple<
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Storage::AttachFileDataToCommand(std::string & UUID, const std::stringstream & FileContent) {
|
||||
bool Storage::AttachFileDataToCommand(std::string & UUID, const std::stringstream & FileContent, const std::string &Type) {
|
||||
try {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
auto Now = Utils::Now();
|
||||
@@ -611,7 +611,7 @@ typedef Poco::Tuple<
|
||||
TheBlob.appendRaw((const unsigned char *)FileContent.str().c_str(),FileContent.str().size());
|
||||
|
||||
Poco::Data::Statement Insert(Sess);
|
||||
std::string FileType{"trace"};
|
||||
std::string FileType{Type};
|
||||
|
||||
std::string St2{
|
||||
"INSERT INTO FileUploads (UUID,Type,Created,FileContent) VALUES(?,?,?,?)"};
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "CentralConfig.h"
|
||||
#include "ConfigurationCache.h"
|
||||
#include "Daemon.h"
|
||||
#include "AP_WS_Server.h"
|
||||
#include "FindCountry.h"
|
||||
#include "OUIServer.h"
|
||||
#include "Poco/Data/RecordSet.h"
|
||||
@@ -48,7 +47,8 @@ namespace OpenWifi {
|
||||
"subscriber, "
|
||||
"entity, "
|
||||
"modified, "
|
||||
"locale"
|
||||
"locale,"
|
||||
"restrictedDevice"
|
||||
};
|
||||
|
||||
const static std::string DB_DeviceUpdateFields{
|
||||
@@ -73,10 +73,11 @@ namespace OpenWifi {
|
||||
"subscriber=?, "
|
||||
"entity=?, "
|
||||
"modified=?, "
|
||||
"locale=? "
|
||||
"locale=?, "
|
||||
"restrictedDevice=?"
|
||||
};
|
||||
|
||||
const static std::string DB_DeviceInsertValues{" VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "};
|
||||
const static std::string DB_DeviceInsertValues{" VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "};
|
||||
|
||||
typedef Poco::Tuple<
|
||||
std::string,
|
||||
@@ -100,7 +101,8 @@ namespace OpenWifi {
|
||||
std::string,
|
||||
std::string,
|
||||
uint64_t,
|
||||
std::string
|
||||
std::string,
|
||||
bool
|
||||
> DeviceRecordTuple;
|
||||
typedef std::vector<DeviceRecordTuple> DeviceRecordList;
|
||||
|
||||
@@ -127,6 +129,7 @@ namespace OpenWifi {
|
||||
D.entity = R.get<19>();
|
||||
D.modified = R.get<20>();
|
||||
D.locale = R.get<21>();
|
||||
D.restrictedDevice = R.get<22>();
|
||||
}
|
||||
|
||||
void ConvertDeviceRecord(const GWObjects::Device &D, DeviceRecordTuple & R) {
|
||||
@@ -152,6 +155,7 @@ namespace OpenWifi {
|
||||
R.set<19>(D.entity);
|
||||
R.set<20>(D.modified);
|
||||
R.set<21>(D.locale);
|
||||
R.set<22>(D.restrictedDevice);
|
||||
}
|
||||
|
||||
bool Storage::GetDeviceCount(uint64_t &Count) {
|
||||
@@ -314,16 +318,15 @@ namespace OpenWifi {
|
||||
|
||||
#define __DBGLOG__ std::cout << __LINE__ << std::endl;
|
||||
|
||||
bool Storage::CreateDefaultDevice(std::string &SerialNumber, std::string &Capabilities, std::string & Firmware, std::string &Compat, const Poco::Net::IPAddress & IPAddress) {
|
||||
bool Storage::CreateDefaultDevice(std::string &SerialNumber, const Config::Capabilities &Caps, std::string & Firmware, const Poco::Net::IPAddress & IPAddress) {
|
||||
|
||||
GWObjects::Device D;
|
||||
poco_information(Logger(),fmt::format("AUTO-CREATION({})", SerialNumber));
|
||||
uint64_t Now = time(nullptr);
|
||||
Config::Capabilities Caps(Capabilities);
|
||||
GWObjects::DefaultConfiguration DefConfig;
|
||||
|
||||
if(!Caps.Platform().empty() && !Caps.Compatible().empty()) {
|
||||
CapabilitiesCache::instance()->Add(Caps.Compatible(), Caps.Platform(), Capabilities);
|
||||
CapabilitiesCache()->Add(Caps);
|
||||
}
|
||||
|
||||
bool Found = false;
|
||||
@@ -339,7 +342,7 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
if (!Found && AP_WS_Server()->UseDefaults() && FindDefaultConfigurationForModel(Compat, DefConfig)) {
|
||||
if (!Found && AP_WS_Server()->UseDefaults() && FindDefaultConfigurationForModel(Caps.Compatible(), DefConfig)) {
|
||||
Config::Config NewConfig(DefConfig.Configuration);
|
||||
NewConfig.SetUUID(Now);
|
||||
D.Configuration = NewConfig.get();
|
||||
@@ -352,14 +355,14 @@ namespace OpenWifi {
|
||||
// We need to insert the country code according to the IP in the radios section...
|
||||
D.locale = InsertRadiosCountyRegulation(D.Configuration, IPAddress);
|
||||
D.SerialNumber = Poco::toLower(SerialNumber);
|
||||
Compat = D.Compatible = Caps.Compatible();
|
||||
D.Compatible = Caps.Compatible();
|
||||
D.DeviceType = Daemon()->IdentifyDevice(D.Compatible);
|
||||
D.MACAddress = Utils::SerialToMAC(SerialNumber);
|
||||
D.Manufacturer = Caps.Model();
|
||||
D.Firmware = Firmware;
|
||||
D.Notes = SecurityObjects::NoteInfoVec { SecurityObjects::NoteInfo{ (uint64_t)Utils::Now(), "", "Auto-provisioned."}};
|
||||
|
||||
CreateDeviceCapabilities(SerialNumber, Capabilities);
|
||||
CreateDeviceCapabilities(SerialNumber, Caps);
|
||||
|
||||
return CreateDevice(D);
|
||||
}
|
||||
@@ -555,7 +558,6 @@ namespace OpenWifi {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Statement Select(Sess);
|
||||
|
||||
|
||||
// std::string st{"SELECT " + DB_DeviceSelectFields + " FROM Devices " + orderBy.empty() ? " ORDER BY SerialNumber ASC " + ComputeRange(From, HowMany)};
|
||||
std::string st = fmt::format("SELECT {} FROM Devices {} {}",
|
||||
DB_DeviceSelectFields,
|
||||
@@ -704,11 +706,6 @@ namespace OpenWifi {
|
||||
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();
|
||||
@@ -766,10 +763,11 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t Associations_2G, Associations_5G;
|
||||
StateUtils::ComputeAssociations(RawObject, Associations_2G, Associations_5G);
|
||||
uint64_t Associations_2G, Associations_5G, Associations_6G;
|
||||
StateUtils::ComputeAssociations(RawObject, Associations_2G, Associations_5G, Associations_6G);
|
||||
UpdateCountedMap(Dashboard.associations, "2G", Associations_2G);
|
||||
UpdateCountedMap(Dashboard.associations, "5G", Associations_5G);
|
||||
UpdateCountedMap(Dashboard.associations, "6G", Associations_6G);
|
||||
}
|
||||
} else {
|
||||
UpdateCountedMap(Dashboard.status, "not connected");
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace OpenWifi {
|
||||
|
||||
bool Storage::AddStatisticsData(const GWObjects::Statistics & Stats) {
|
||||
try {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Session Sess(Pool_->get());
|
||||
Poco::Data::Statement Insert(Sess);
|
||||
|
||||
poco_trace(Logger(),fmt::format("{}: Adding stats. Size={}",Stats.SerialNumber,std::to_string(Stats.Data.size())));
|
||||
@@ -60,11 +60,46 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Storage::GetNumberOfStatisticsDataRecords(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, std::uint64_t &Count) {
|
||||
try {
|
||||
Poco::Data::Session Sess(Pool_->get());
|
||||
Poco::Data::Statement Select(Sess);
|
||||
|
||||
StatsRecordList Records;
|
||||
|
||||
bool DatesIncluded = (FromDate != 0 || ToDate != 0);
|
||||
|
||||
std::string Prefix{"SELECT count(*) FROM Statistics "};
|
||||
std::string StatementStr = SerialNumber.empty()
|
||||
? Prefix + std::string(DatesIncluded ? "WHERE " : "")
|
||||
: Prefix + "WHERE SerialNumber='" + SerialNumber + "'" +
|
||||
std::string(DatesIncluded ? " AND " : "");
|
||||
|
||||
std::string DateSelector;
|
||||
if (FromDate && ToDate) {
|
||||
DateSelector = " Recorded>=" + std::to_string(FromDate) + " AND Recorded<=" + std::to_string(ToDate);
|
||||
} else if (FromDate) {
|
||||
DateSelector = " Recorded>=" + std::to_string(FromDate);
|
||||
} else if (ToDate) {
|
||||
DateSelector = " Recorded<=" + std::to_string(ToDate);
|
||||
}
|
||||
|
||||
Select << StatementStr + DateSelector ,
|
||||
Poco::Data::Keywords::into(Count);
|
||||
Select.execute();
|
||||
return true;
|
||||
}
|
||||
catch (const Poco::Exception &E) {
|
||||
poco_warning(Logger(),fmt::format("{}: Failed with: {}", std::string(__func__), E.displayText()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Storage::GetStatisticsData(std::string &SerialNumber, uint64_t FromDate, uint64_t ToDate, uint64_t Offset,
|
||||
uint64_t HowMany,
|
||||
std::vector<GWObjects::Statistics> &Stats) {
|
||||
try {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Session Sess(Pool_->get());
|
||||
Poco::Data::Statement Select(Sess);
|
||||
|
||||
StatsRecordList Records;
|
||||
@@ -93,7 +128,7 @@ namespace OpenWifi {
|
||||
for (const auto &i: Records) {
|
||||
GWObjects::Statistics R;
|
||||
ConvertStatsRecord(i,R);
|
||||
Stats.push_back(R);
|
||||
Stats.emplace_back(R);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -106,7 +141,7 @@ namespace OpenWifi {
|
||||
bool Storage::GetNewestStatisticsData(std::string &SerialNumber, uint64_t HowMany, std::vector<GWObjects::Statistics> &Stats) {
|
||||
try {
|
||||
StatsRecordList Records;
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Session Sess(Pool_->get());
|
||||
Poco::Data::Statement Select(Sess);
|
||||
|
||||
std::string St{"SELECT " +
|
||||
@@ -120,7 +155,7 @@ namespace OpenWifi {
|
||||
for (const auto &i: Records) {
|
||||
GWObjects::Statistics R;
|
||||
ConvertStatsRecord(i,R);
|
||||
Stats.push_back(R);
|
||||
Stats.emplace_back(R);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -165,7 +200,7 @@ bool Storage::DeleteStatisticsData(std::string &SerialNumber, uint64_t FromDate,
|
||||
|
||||
bool Storage::RemoveStatisticsRecordsOlderThan(uint64_t Date) {
|
||||
try {
|
||||
Poco::Data::Session Sess = Pool_->get();
|
||||
Poco::Data::Session Sess(Pool_->get());
|
||||
Poco::Data::Statement Delete(Sess);
|
||||
|
||||
std::string St1{"delete from Statistics where recorded<?"};
|
||||
|
||||
@@ -107,7 +107,8 @@ namespace OpenWifi {
|
||||
"subscriber VARCHAR(64) , "
|
||||
"entity VARCHAR(64) , "
|
||||
"modified BIGINT,"
|
||||
"locale varchar(32) "
|
||||
"locale varchar(32), "
|
||||
"restrictedDevice BOOLEAN "
|
||||
")", Poco::Data::Keywords::now;
|
||||
Sess << "CREATE INDEX IF NOT EXISTS DeviceOwner ON Devices (Owner ASC)", Poco::Data::Keywords::now;
|
||||
Sess << "CREATE INDEX IF NOT EXISTS DeviceLocation ON Devices (Location ASC)", Poco::Data::Keywords::now;
|
||||
@@ -118,7 +119,8 @@ namespace OpenWifi {
|
||||
"alter table devices add column subscriber varchar(64)",
|
||||
"alter table devices add column entity varchar(64)",
|
||||
"alter table devices add column modified bigint",
|
||||
"alter table devices add column locale varchar(32)"
|
||||
"alter table devices add column locale varchar(32)",
|
||||
"alter table devices add column restrictedDevice boolean",
|
||||
};
|
||||
|
||||
for(const auto &i:Script) {
|
||||
|
||||
16
test_scripts/curl/bundle-test.uc
Normal file
16
test_scripts/curl/bundle-test.uc
Normal file
@@ -0,0 +1,16 @@
|
||||
bundle.wifi();
|
||||
let paths = [
|
||||
[ 'network.wireless', 'status' ],
|
||||
[ 'network.device', 'status' ],
|
||||
[ 'network.interface', 'dump' ],
|
||||
[ 'log', 'read', { stream: false } ],
|
||||
];
|
||||
for (let path in paths)
|
||||
bundle.ubus(path[0], path[1], path[2]);
|
||||
for (let config in [ 'network', 'wireless', 'dhcp', 'firewall', 'system' ])
|
||||
bundle.uci(config);
|
||||
for (let cmd in [ "route", "ifconfig", "logread" ])
|
||||
bundle.shell(cmd);
|
||||
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ browser=""
|
||||
login() {
|
||||
payload="{ \"userId\" : \"$username\" , \"password\" : \"$password\" }"
|
||||
token=$(curl ${FLAGS} -X POST -H "Content-Type: application/json" -d "$payload" "https://${OWSEC}/api/v1/oauth2" | jq -r '.access_token')
|
||||
|
||||
# curl -v -X POST -H "Content-Type: application/json" -d "$payload" "https://${OWSEC}/api/v1/oauth2" | jq -r '.access_token'
|
||||
if [[ "${token}" == "" ]]
|
||||
then
|
||||
echo "Could not login. Please verify the host and username/password."
|
||||
@@ -175,11 +175,11 @@ listdevices() {
|
||||
jq < ${result_file}
|
||||
}
|
||||
|
||||
listdevices() {
|
||||
listdevicesk() {
|
||||
curl ${FLAGS} -X GET "https://${OWGW}/api/v1/devices" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
-H "X-API-KEY: $1" > ${result_file}
|
||||
jq < ${result_file}
|
||||
}
|
||||
|
||||
@@ -651,6 +651,26 @@ telemetry() {
|
||||
fi
|
||||
}
|
||||
|
||||
notifications() {
|
||||
if [[ -z "$1" ]]
|
||||
then
|
||||
timeout=30
|
||||
else
|
||||
timeout=$1
|
||||
fi
|
||||
socket="wss://${OWGW}/api/v1/ws"
|
||||
echo ${socket}
|
||||
if [[ "$(which wscat)" == "" ]]
|
||||
then
|
||||
echo "wscat command not found. Cannot start a websocket session."
|
||||
else
|
||||
wscat \
|
||||
--connect "${socket}" "token:${token}" \
|
||||
--wait $timeout \
|
||||
--execute "token:${token}"
|
||||
fi
|
||||
}
|
||||
|
||||
telemetry_to_kafka() {
|
||||
payload="$(printf '{ "serialNumber": "%s", "interval": 2, "kafka": true, "lifetime": %d, "types": [ "dhcp-snooping", "state", "wifi-frames" ] }' "$1" "$2")"
|
||||
curl ${FLAGS} -X POST "https://${OWGW}/api/v1/device/$1/telemetry" \
|
||||
@@ -662,7 +682,8 @@ telemetry_to_kafka() {
|
||||
}
|
||||
|
||||
runscript() {
|
||||
payload="$(printf '{ "serialNumber": "%s", "type": "%s" , "kafka": true, "timeout": 30, "scriptId": "cli-manual", "script" : "%s" }' "$1" "$2" "$3" )"
|
||||
scriptcontent=$(base64 -i $3)
|
||||
payload="$(printf '{ "serialNumber": "%s", "type": "%s" , "timeout": 30, "script" : "%s" , "when" : 0 }' "$1" "$2" "$scriptcontent" )"
|
||||
curl ${FLAGS} -X POST "https://${OWGW}/api/v1/device/$1/script" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
@@ -730,6 +751,49 @@ connectionstatistics() {
|
||||
jq < ${result_file}
|
||||
}
|
||||
|
||||
testtoken() {
|
||||
login
|
||||
systeminfo
|
||||
logout
|
||||
systeminfo
|
||||
}
|
||||
|
||||
# retreive the stats for a snigle device for the last 7 days
|
||||
stats7() {
|
||||
now=$(date +%s)
|
||||
len=$((7 * 24 * 60 * 60))
|
||||
start=$((now - len))
|
||||
offset=0
|
||||
records=100
|
||||
while [ ${records} == 100 ]
|
||||
do
|
||||
curl ${FLAGS} -X GET "https://${OWGW}/api/v1/device/$1/statistics?startDate=${start}&endDate=${now}&offset=${offset}&limit=100" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
# jq < ${result_file}
|
||||
records=$(jq '.data | length' ${result_file})
|
||||
offset=$((offset + ${records}))
|
||||
echo "Downloaded ${records} records. New offset is ${offset}"
|
||||
if [[ ${records} != 100 ]]
|
||||
then
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
stats7count() {
|
||||
now=$(date +%s)
|
||||
len=$((7 * 24 * 60 * 60))
|
||||
start=$((now - len))
|
||||
curl ${FLAGS} -X GET "https://${OWGW}/api/v1/device/$1/statistics?startDate=${start}&endDate=${now}&countOnly=true" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Authorization: Bearer ${token}" > ${result_file}
|
||||
jq < ${result_file}
|
||||
}
|
||||
|
||||
check_response() {
|
||||
|
||||
if [ -s "$1" ]; then
|
||||
@@ -931,7 +995,8 @@ case "$1" in
|
||||
"getcapabilities") login; getcapabilities "$2" ; logout ;;
|
||||
"deletecapabilities") login; deletecapabilities "$2" ; logout ;;
|
||||
"listdevices") login; listdevices ; logout ;;
|
||||
"deletedevice") login; deletedevice "$2" ; logout ;;
|
||||
"listdevicesk") login; listdevicesk "$2" ; logout ;;
|
||||
"deletedevice") login; deletedevice "$2" ; logout ;;
|
||||
"deleteoui") login; deleteoui "$2" ; logout ;;
|
||||
"createdevice") login; createdevice "$2" "$3" "$4" ; logout ;;
|
||||
"reboot") login; reboot "$2" ; logout ;;
|
||||
@@ -997,6 +1062,10 @@ case "$1" in
|
||||
"deleteradiusconfig") login; deleteradiusconfig ; logout;;
|
||||
"deviceping") login; deviceping $2; logout;;
|
||||
"connectionstatistics") login; connectionstatistics $2; logout;;
|
||||
"notifications") login; notifications "$2"; logout;;
|
||||
"stats7") login; stats7 "$2"; logout;;
|
||||
"stats7count") login; stats7count "$2"; logout;;
|
||||
"testtoken") testtoken;;
|
||||
*) help ;;
|
||||
esac
|
||||
|
||||
|
||||
4
test_scripts/curl/shell-script.sh
Normal file
4
test_scripts/curl/shell-script.sh
Normal file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
|
||||
ls -l /etc/ucentral
|
||||
|
||||
1
test_scripts/curl/temp.json
Normal file
1
test_scripts/curl/temp.json
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user