mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2025-11-02 11:47:47 +00:00
Compare commits
459 Commits
v2.7.1
...
WIFI-12187
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
196afba514 | ||
|
|
0bf22d3406 | ||
|
|
61bb2db3d1 | ||
|
|
9fff261779 | ||
|
|
b627ee7516 | ||
|
|
a2ba11277e | ||
|
|
d1a0f7954b | ||
|
|
74e6264b47 | ||
|
|
ced1522c61 | ||
|
|
426845b192 | ||
|
|
0be833e73c | ||
|
|
64b1c9171c | ||
|
|
ee33bc365e | ||
|
|
bc02666ff0 | ||
|
|
9c4a7a7a27 | ||
|
|
3021e1b20d | ||
|
|
99018fba32 | ||
|
|
84e14c9f80 | ||
|
|
2a375ed98d | ||
|
|
0e9c8ce944 | ||
|
|
2312513a27 | ||
|
|
2d495b070f | ||
|
|
1f1d40e166 | ||
|
|
90e2b2e71f | ||
|
|
08b3d5e316 | ||
|
|
1ac475d48f | ||
|
|
6f874baa54 | ||
|
|
a9ffe80d27 | ||
|
|
83b4f3341e | ||
|
|
801704f065 | ||
|
|
45b25c4e75 | ||
|
|
ea311f70a0 | ||
|
|
e3265c86a5 | ||
|
|
e537259208 | ||
|
|
b9c7990344 | ||
|
|
d5c1cfe2f1 | ||
|
|
1a4f27cbbf | ||
|
|
11ad381534 | ||
|
|
0b548a40f3 | ||
|
|
28e5463196 | ||
|
|
37ea632ac7 | ||
|
|
2f641077e6 | ||
|
|
78318f47c6 | ||
|
|
c83c73a3ae | ||
|
|
6305be8c55 | ||
|
|
4b325ef22c | ||
|
|
a422dff7ae | ||
|
|
271ff4f6c4 | ||
|
|
4cdd275d0b | ||
|
|
9a36e86949 | ||
|
|
fa806ed16c | ||
|
|
57c270973e | ||
|
|
17ebfb24f2 | ||
|
|
26072691ab | ||
|
|
e8b3ea56e0 | ||
|
|
2b1a72b838 | ||
|
|
352afc487a | ||
|
|
6fae29981a | ||
|
|
9569de1b21 | ||
|
|
1a952946b2 | ||
|
|
3b52cf6111 | ||
|
|
74197e2aee | ||
|
|
7152067b09 | ||
|
|
ac3d061eee | ||
|
|
8ee67713bf | ||
|
|
e57cd4fea2 | ||
|
|
5e3a71a6e7 | ||
|
|
a602b8f844 | ||
|
|
89da7d187a | ||
|
|
6c5533aa8b | ||
|
|
66249b258c | ||
|
|
e03512ebf3 | ||
|
|
b152c8477a | ||
|
|
a298c4254b | ||
|
|
b8f04c6d4a | ||
|
|
753dc5c068 | ||
|
|
bf70d6b512 | ||
|
|
760f11ca70 | ||
|
|
2bcd0ccbcb | ||
|
|
0aee258af4 | ||
|
|
9e879f306c | ||
|
|
fb4a4d935a | ||
|
|
282552cdfa | ||
|
|
1d316ff28a | ||
|
|
1da866a7da | ||
|
|
1c628c28fa | ||
|
|
a350b30a9c | ||
|
|
cf6c3f9337 | ||
|
|
2388eac41d | ||
|
|
f0e0f2ba5b | ||
|
|
0c8b9caaf3 | ||
|
|
c0edeb8b23 | ||
|
|
fdcf74788d | ||
|
|
df9c82a4ae | ||
|
|
2963cec1fb | ||
|
|
8053e32c9c | ||
|
|
1750ac5fb5 | ||
|
|
b4d775db0c | ||
|
|
3031483209 | ||
|
|
97b990581d | ||
|
|
98fa4799cc | ||
|
|
95a853fc0e | ||
|
|
7a14cadbf5 | ||
|
|
ab5efcc8c1 | ||
|
|
bb71ff2bad | ||
|
|
c1a2efd32c | ||
|
|
ca4d92fd66 | ||
|
|
efb354031a | ||
|
|
180d01c89d | ||
|
|
f6c1a5e97f | ||
|
|
54e7caafc1 | ||
|
|
e76c97540c | ||
|
|
3f01ef6d5e | ||
|
|
8e118c7f7b | ||
|
|
6dc5622bf2 | ||
|
|
27a9ef01b6 | ||
|
|
9390b9a646 | ||
|
|
871f3c3436 | ||
|
|
a41095a797 | ||
|
|
bb94c9a813 | ||
|
|
fcd991b8d6 | ||
|
|
2df43cfd62 | ||
|
|
014aafbd3d | ||
|
|
d1d058a848 | ||
|
|
d492396182 | ||
|
|
2c710412a1 | ||
|
|
7dcade3d79 | ||
|
|
dc73a2d54b | ||
|
|
6c2bb5b395 | ||
|
|
fccf99cca5 | ||
|
|
0d91dd9a6e | ||
|
|
d84af0f18e | ||
|
|
6b6c9ce0ae | ||
|
|
5a31d6427f | ||
|
|
8b3ff4a560 | ||
|
|
53c81d2c76 | ||
|
|
518bfc0b2c | ||
|
|
c6851819d4 | ||
|
|
d5851753c2 | ||
|
|
379b1446f6 | ||
|
|
6d50ef72b7 | ||
|
|
f0954081c1 | ||
|
|
9653d0affb | ||
|
|
dd626461e8 | ||
|
|
048b33e134 | ||
|
|
eff7a70f6b | ||
|
|
5f73966010 | ||
|
|
911c9ac210 | ||
|
|
f59c369b61 | ||
|
|
526d239fe9 | ||
|
|
939d704460 | ||
|
|
b7e8da5e76 | ||
|
|
c5d68e5397 | ||
|
|
a2bbe71e53 | ||
|
|
1c0cf65145 | ||
|
|
60d41e8569 | ||
|
|
76698476b6 | ||
|
|
4e4ac89401 | ||
|
|
e3e6a27348 | ||
|
|
b419472fd7 | ||
|
|
bd2af4df1d | ||
|
|
bbbb4cd4fe | ||
|
|
445568152c | ||
|
|
ce70ff0f21 | ||
|
|
6dbf16793e | ||
|
|
eba69c8c35 | ||
|
|
ae2e6c5ce6 | ||
|
|
5a2a0cd074 | ||
|
|
9c3a23a8a1 | ||
|
|
b6f0f07bec | ||
|
|
e060e11cd2 | ||
|
|
883245de68 | ||
|
|
9cfc411a51 | ||
|
|
fb3a785227 | ||
|
|
3fe8958323 | ||
|
|
117f0e1637 | ||
|
|
b09b1d5690 | ||
|
|
e073e2b713 | ||
|
|
8343443bd7 | ||
|
|
c5ed66c40c | ||
|
|
de65b2396c | ||
|
|
c85cef57c8 | ||
|
|
6c9bae518a | ||
|
|
7232168037 | ||
|
|
9da06d8384 | ||
|
|
296a4721db | ||
|
|
f2badf7b6d | ||
|
|
766be1aa3c | ||
|
|
4812219e0d | ||
|
|
7b4e39aad2 | ||
|
|
fbff951e22 | ||
|
|
09198d5ec2 | ||
|
|
3666995f7f | ||
|
|
0572674279 | ||
|
|
19f2265161 | ||
|
|
f613449dff | ||
|
|
a1291b1b16 | ||
|
|
39ebc28396 | ||
|
|
6017714363 | ||
|
|
bff7092ce1 | ||
|
|
1741742617 | ||
|
|
b4a6bea1b4 | ||
|
|
57e06b2d2f | ||
|
|
0bc7363dae | ||
|
|
44b2140230 | ||
|
|
49bc934066 | ||
|
|
53d337f462 | ||
|
|
66e7791b95 | ||
|
|
2180c5ff23 | ||
|
|
2f4fa7572e | ||
|
|
5923506237 | ||
|
|
b9600654f8 | ||
|
|
6b0a082ac9 | ||
|
|
c5a108d672 | ||
|
|
23c2925baf | ||
|
|
fa4c72d59c | ||
|
|
d66d901204 | ||
|
|
b09eaf98cc | ||
|
|
7f9bf85958 | ||
|
|
d1d89fcd74 | ||
|
|
bc3f5700d4 | ||
|
|
3a938fd615 | ||
|
|
dc3729aec2 | ||
|
|
dd214ae5d1 | ||
|
|
8f7f8c5736 | ||
|
|
00701a8de4 | ||
|
|
fc41c9aa2f | ||
|
|
a5442eee0d | ||
|
|
9dcf5b5320 | ||
|
|
28b5295a6e | ||
|
|
8261ae34bd | ||
|
|
02baa9329c | ||
|
|
7f01c7b861 | ||
|
|
8d0f0c227a | ||
|
|
c8170bc9f3 | ||
|
|
83003b66b9 | ||
|
|
cbdb15bc32 | ||
|
|
712e15407d | ||
|
|
e424e19d1c | ||
|
|
546d8dee98 | ||
|
|
60b9fc679a | ||
|
|
79a4f24bc2 | ||
|
|
02b8ecf300 | ||
|
|
bdbc5a7a9d | ||
|
|
680fe18bac | ||
|
|
dd08b2e426 | ||
|
|
285b1630ee | ||
|
|
fdcaf9054f | ||
|
|
65b5585797 | ||
|
|
b31fdb202c | ||
|
|
d13d906d11 | ||
|
|
6a403ac916 | ||
|
|
eff54e3202 | ||
|
|
0a7dd7c3f7 | ||
|
|
cf7f962ed1 | ||
|
|
f412df29b5 | ||
|
|
31204bae6a | ||
|
|
a57cf08c00 | ||
|
|
c0171156fa | ||
|
|
a456e95139 | ||
|
|
7f8e2d0f7f | ||
|
|
d80aa68c40 | ||
|
|
81c9090ec9 | ||
|
|
0fa5c46f4b | ||
|
|
d75977140a | ||
|
|
b65440ba4e | ||
|
|
ee15f8b8c2 | ||
|
|
aebf8ba783 | ||
|
|
9f2436b123 | ||
|
|
cd774ea2df | ||
|
|
007f54bc26 | ||
|
|
9c03f3a9e3 | ||
|
|
292365a837 | ||
|
|
1091478e11 | ||
|
|
47b94b3c5a | ||
|
|
7cd62e7b26 | ||
|
|
3397f2407a | ||
|
|
52799659c8 | ||
|
|
86e88942b0 | ||
|
|
11592ebb98 | ||
|
|
83f4bfc53d | ||
|
|
43ed818015 | ||
|
|
fd7f5b991a | ||
|
|
feebcb339a | ||
|
|
0368d4e435 | ||
|
|
a57bad5bb9 | ||
|
|
a0ee1a40d4 | ||
|
|
5c5aa3551b | ||
|
|
bd7daf4072 | ||
|
|
dad844795f | ||
|
|
1ef20f232a | ||
|
|
78deaf8b38 | ||
|
|
41107af0d0 | ||
|
|
a1aec29ffd | ||
|
|
07dc8617a4 | ||
|
|
34cef1ae0a | ||
|
|
144841d88d | ||
|
|
b46a713968 | ||
|
|
4ec7c30e28 | ||
|
|
16c5825e3a | ||
|
|
0f1129e51e | ||
|
|
3e54201be8 | ||
|
|
c34fba4c22 | ||
|
|
625f8c7a2b | ||
|
|
41a4a98c0a | ||
|
|
c858d954a9 | ||
|
|
aa0410edb3 | ||
|
|
97cb61b7cf | ||
|
|
0408d98538 | ||
|
|
69e2f9640e | ||
|
|
efd20dc370 | ||
|
|
7a42598150 | ||
|
|
7a45d96d9a | ||
|
|
468a2553f8 | ||
|
|
a4f7ccdba1 | ||
|
|
a0b47aa4b3 | ||
|
|
ee6dd54ab3 | ||
|
|
518ca7cc9d | ||
|
|
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 | ||
|
|
5744905f5a | ||
|
|
d7c27150d3 | ||
|
|
76a8260f1c | ||
|
|
0d8f43dba2 | ||
|
|
104c07cf6d | ||
|
|
43f244a076 | ||
|
|
e4bc41ed56 | ||
|
|
1c2275537d | ||
|
|
a062ff084e | ||
|
|
7a78cd33eb | ||
|
|
ff2dff5a51 | ||
|
|
d122b86913 | ||
|
|
43e45f7c28 | ||
|
|
ba93725f62 | ||
|
|
c32f0dfb02 | ||
|
|
73dcd49d92 | ||
|
|
56c2640900 | ||
|
|
b33c52616d | ||
|
|
7edc427ea7 | ||
|
|
3c8549b872 | ||
|
|
471b992d2d | ||
|
|
ab2ed7492b | ||
|
|
330cb7552c | ||
|
|
b31fb67eda | ||
|
|
874b8a5510 | ||
|
|
624899b65c | ||
|
|
d0bc6b96c4 | ||
|
|
1781e58189 | ||
|
|
9e536b5235 | ||
|
|
208956d5c6 | ||
|
|
60aba09614 | ||
|
|
da1c3346d1 | ||
|
|
ea4ee0d0f6 | ||
|
|
d940bebb90 | ||
|
|
77c6ce8a1e | ||
|
|
98c761c375 | ||
|
|
7166ad2ce7 | ||
|
|
7f24aee8fa | ||
|
|
8b16c08baa | ||
|
|
f7045d6b40 | ||
|
|
6b64b02192 | ||
|
|
43f37a6e12 | ||
|
|
9fc6d4efee | ||
|
|
ac375e468d | ||
|
|
1c8ce086df | ||
|
|
8b73e4b232 | ||
|
|
7c10d83b6b | ||
|
|
99259cc6c5 | ||
|
|
8062bb8bf7 | ||
|
|
0bb51d2ac0 | ||
|
|
cd9a30be4d | ||
|
|
98fd924bd1 | ||
|
|
20e0fe860f | ||
|
|
10d87dab92 | ||
|
|
cfb7ad21a2 | ||
|
|
cc90306052 | ||
|
|
b8f781b890 | ||
|
|
f4af3da4c2 | ||
|
|
a3f4143a67 | ||
|
|
b8c1a35c3a | ||
|
|
cd9345a54f | ||
|
|
8837b23e79 |
@@ -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
|
||||
|
||||
41
.github/workflows/openapi-pages.yml
vendored
Normal file
41
.github/workflows/openapi-pages.yml
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
name: Update OpenAPI docs on GitHub Pages
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'openapi/**'
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
docsgen:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Generate static HTML page with docs from OpenAPI definition
|
||||
run: |
|
||||
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli:v6.2.1 generate -i https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentralgw/master/openapi/owgw.yaml -g html2 --skip-validate-spec -o /local/
|
||||
|
||||
- name: Update OpenAPI docs
|
||||
run: |
|
||||
mkdir tmp-docs
|
||||
mv index.html tmp-docs/index.html
|
||||
mkdir -p ~/.ssh
|
||||
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
|
||||
echo https://tip-automation:${{ secrets.GIT_PUSH_PAT }}@github.com > ~/.git-credentials
|
||||
git config --global credential.helper store
|
||||
git config --global user.email "tip-automation@telecominfraproject.com"
|
||||
git config --global user.name "TIP Automation User"
|
||||
git pull
|
||||
git checkout gh-pages || git checkout -b gh-pages
|
||||
rm -rf docs
|
||||
mv tmp-docs docs
|
||||
git add docs
|
||||
git commit -m'Update OpenAPI docs for GitHub pages'
|
||||
git push --set-upstream origin gh-pages
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
HELM_REPO_USERNAME: ucentral
|
||||
steps:
|
||||
- name: Checkout uCentral assembly chart repo
|
||||
uses: actions/checkout@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.9.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()
|
||||
@@ -55,7 +55,7 @@ find_package(OpenSSL REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(fmt REQUIRED)
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
find_package(nlohmann_json_schema_validator REQUIRED)
|
||||
# find_package(valijson REQUIRED)
|
||||
|
||||
if(SMALL_BUILD)
|
||||
find_package(Poco REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite)
|
||||
@@ -82,10 +82,53 @@ add_executable( owgw
|
||||
src/framework/orm.h
|
||||
src/framework/StorageClass.h
|
||||
src/framework/MicroServiceErrorHandler.h
|
||||
src/framework/UI_WebSocketClientServer.cpp
|
||||
src/framework/UI_WebSocketClientServer.h
|
||||
src/framework/UI_WebSocketClientNotifications.cpp
|
||||
src/framework/UI_WebSocketClientNotifications.h
|
||||
src/framework/utils.h
|
||||
src/framework/utils.cpp
|
||||
src/framework/AppServiceRegistry.h
|
||||
src/framework/SubSystemServer.cpp
|
||||
src/framework/SubSystemServer.h
|
||||
src/framework/RESTAPI_utils.h
|
||||
src/framework/AuthClient.cpp
|
||||
src/framework/AuthClient.h
|
||||
src/framework/MicroServiceNames.h
|
||||
src/framework/MicroServiceFuncs.h
|
||||
src/framework/OpenAPIRequests.cpp
|
||||
src/framework/OpenAPIRequests.h
|
||||
src/framework/MicroServiceFuncs.cpp
|
||||
src/framework/ALBserver.cpp
|
||||
src/framework/ALBserver.h
|
||||
src/framework/KafkaManager.cpp
|
||||
src/framework/KafkaManager.h
|
||||
src/framework/RESTAPI_RateLimiter.h
|
||||
src/framework/WebSocketLogger.h
|
||||
src/framework/RESTAPI_GenericServerAccounting.h
|
||||
src/framework/CIDR.h
|
||||
src/framework/RESTAPI_Handler.cpp
|
||||
src/framework/RESTAPI_Handler.h
|
||||
src/framework/RESTAPI_ExtServer.h
|
||||
src/framework/RESTAPI_ExtServer.cpp
|
||||
src/framework/RESTAPI_IntServer.cpp
|
||||
src/framework/RESTAPI_IntServer.h
|
||||
src/framework/RESTAPI_SystemCommand.h
|
||||
src/framework/RESTAPI_WebSocketServer.h
|
||||
src/framework/RESTAPI_SystemConfiguration.h
|
||||
src/framework/EventBusManager.cpp
|
||||
src/framework/EventBusManager.h
|
||||
src/framework/RESTAPI_PartHandler.h
|
||||
src/framework/MicroService.cpp
|
||||
src/framework/MicroServiceExtra.h
|
||||
src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp
|
||||
src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h
|
||||
src/RESTObjects/RESTAPI_GWobjects.h src/RESTObjects/RESTAPI_GWobjects.cpp
|
||||
src/RESTObjects/RESTAPI_FMSObjects.h src/RESTObjects/RESTAPI_FMSObjects.cpp
|
||||
src/RESTObjects/RESTAPI_CertObjects.cpp src/RESTObjects/RESTAPI_CertObjects.h
|
||||
src/RESTObjects/RESTAPI_OWLSobjects.cpp src/RESTObjects/RESTAPI_OWLSobjects.h
|
||||
src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h
|
||||
src/RESTObjects/RESTAPI_AnalyticsObjects.cpp src/RESTObjects/RESTAPI_AnalyticsObjects.h
|
||||
src/RESTObjects/RESTAPI_SubObjects.cpp src/RESTObjects/RESTAPI_SubObjects.h
|
||||
src/RESTAPI/RESTAPI_devices_handler.cpp src/RESTAPI/RESTAPI_devices_handler.h
|
||||
src/RESTAPI/RESTAPI_device_handler.cpp src/RESTAPI/RESTAPI_device_handler.h
|
||||
src/RESTAPI/RESTAPI_device_commandHandler.cpp src/RESTAPI/RESTAPI_device_commandHandler.h
|
||||
@@ -109,7 +152,6 @@ add_executable( owgw
|
||||
src/Daemon.cpp src/Daemon.h
|
||||
src/AP_WS_Server.cpp src/AP_WS_Server.h
|
||||
src/StorageService.cpp src/StorageService.h
|
||||
# src/DeviceRegistry.cpp src/DeviceRegistry.h
|
||||
src/CommandManager.cpp src/CommandManager.h
|
||||
src/CentralConfig.cpp src/CentralConfig.h
|
||||
src/FileUploader.cpp src/FileUploader.h
|
||||
@@ -123,17 +165,37 @@ add_executable( owgw
|
||||
src/CapabilitiesCache.h src/FindCountry.h
|
||||
src/rttys/RTTYS_server.cpp
|
||||
src/rttys/RTTYS_server.h
|
||||
src/rttys/RTTYS_device.cpp
|
||||
src/rttys/RTTYS_device.h
|
||||
src/rttys/RTTYS_ClientConnection.cpp
|
||||
src/rttys/RTTYS_ClientConnection.h
|
||||
src/rttys/RTTYS_WebServer.cpp
|
||||
src/rttys/RTTYS_WebServer.h src/RESTAPI/RESTAPI_device_helper.h src/SDKcalls.cpp src/SDKcalls.h src/StateUtils.cpp src/StateUtils.h src/AP_WS_ReactorPool.h src/AP_WS_Connection.h src/AP_WS_Connection.cpp src/TelemetryClient.h src/TelemetryClient.cpp src/RESTAPI/RESTAPI_iptocountry_handler.cpp src/RESTAPI/RESTAPI_iptocountry_handler.h src/framework/ow_constants.h src/GwWebSocketClient.cpp src/GwWebSocketClient.h src/framework/WebSocketClientNotifications.h src/RADIUS_proxy_server.cpp src/RADIUS_proxy_server.h src/RESTAPI/RESTAPI_radiusProxyConfig_handler.cpp src/RESTAPI/RESTAPI_radiusProxyConfig_handler.h src/ParseWifiScan.h src/RADIUS_helpers.h src/VenueBroadcaster.h src/sdks/sdk_prov.h
|
||||
src/rttys/RTTYS_WebServer.h src/RESTAPI/RESTAPI_device_helper.h
|
||||
src/SDKcalls.cpp
|
||||
src/SDKcalls.h
|
||||
src/StateUtils.cpp src/StateUtils.h
|
||||
src/AP_WS_ReactorPool.h
|
||||
src/AP_WS_Connection.h
|
||||
src/AP_WS_Connection.cpp
|
||||
src/TelemetryClient.h src/TelemetryClient.cpp
|
||||
src/RESTAPI/RESTAPI_iptocountry_handler.cpp src/RESTAPI/RESTAPI_iptocountry_handler.h
|
||||
src/framework/ow_constants.h
|
||||
src/GwWebSocketClient.cpp src/GwWebSocketClient.h
|
||||
src/RADIUS_proxy_server.cpp src/RADIUS_proxy_server.h
|
||||
src/RESTAPI/RESTAPI_radiusProxyConfig_handler.cpp src/RESTAPI/RESTAPI_radiusProxyConfig_handler.h
|
||||
src/ParseWifiScan.h
|
||||
src/RADIUS_helpers.h
|
||||
src/VenueBroadcaster.h
|
||||
src/sdks/sdk_prov.h
|
||||
src/AP_WS_Process_connect.cpp
|
||||
src/AP_WS_Process_state.cpp
|
||||
src/AP_WS_Process_healthcheck.cpp
|
||||
src/AP_WS_Process_log.cpp
|
||||
src/AP_WS_Process_crashlog.cpp src/AP_WS_Process_ping.cpp src/AP_WS_Process_cfgpending.cpp src/AP_WS_Process_recovery.cpp src/AP_WS_Process_deviceupdate.cpp src/AP_WS_Process_telemetry.cpp src/AP_WS_Process_venuebroadcast.cpp src/RADSECserver.h)
|
||||
src/AP_WS_Process_crashlog.cpp
|
||||
src/AP_WS_Process_ping.cpp
|
||||
src/AP_WS_Process_cfgpending.cpp
|
||||
src/AP_WS_Process_recovery.cpp
|
||||
src/AP_WS_Process_deviceupdate.cpp
|
||||
src/AP_WS_Process_telemetry.cpp
|
||||
src/AP_WS_Process_venuebroadcast.cpp
|
||||
src/RADSEC_server.h
|
||||
src/UI_GW_WebSocketNotifications.cpp src/UI_GW_WebSocketNotifications.h src/framework/RESTAPI_SystemConfiguration.h src/ScriptManager.cpp src/ScriptManager.h src/RESTAPI/RESTAPI_scripts_handler.cpp src/RESTAPI/RESTAPI_scripts_handler.h src/RESTAPI/RESTAPI_script_handler.cpp src/RESTAPI/RESTAPI_script_handler.h src/storage/storage_scripts.cpp src/storage/storage_scripts.h src/SignatureMgr.cpp src/SignatureMgr.h src/AP_WS_Process_event.cpp src/AP_WS_Process_wifiscan.cpp src/AP_WS_Process_alarm.cpp src/GWKafkaEvents.cpp src/GWKafkaEvents.h)
|
||||
|
||||
if(NOT SMALL_BUILD)
|
||||
|
||||
@@ -151,10 +213,9 @@ if(NOT SMALL_BUILD)
|
||||
target_link_libraries(owgw PUBLIC
|
||||
${MySQL_LIBRARIES} ${ZLIB_LIBRARIES}
|
||||
CppKafka::cppkafka
|
||||
nlohmann_json_schema_validator
|
||||
fmt::fmt
|
||||
)
|
||||
if(UNIX AND NOT APPLE)
|
||||
target_link_libraries(owgw PUBLIC PocoJSON)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
44
Dockerfile
44
Dockerfile
@@ -1,8 +1,7 @@
|
||||
ARG DEBIAN_VERSION=11.5-slim
|
||||
ARG POCO_VERSION=poco-tip-v1
|
||||
ARG FMTLIB_VERSION=9.0.0
|
||||
ARG POCO_VERSION=poco-tip-v2
|
||||
ARG CPPKAFKA_VERSION=tip-v1
|
||||
ARG JSON_VALIDATOR_VERSION=2.1.0
|
||||
ARG VALIJASON_VERSION=tip-v1
|
||||
|
||||
FROM debian:$DEBIAN_VERSION AS build-base
|
||||
|
||||
@@ -10,7 +9,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||
make cmake g++ git \
|
||||
libpq-dev libmariadb-dev libmariadbclient-dev-compat \
|
||||
librdkafka-dev libboost-all-dev libssl-dev \
|
||||
zlib1g-dev nlohmann-json3-dev ca-certificates
|
||||
zlib1g-dev nlohmann-json3-dev ca-certificates libfmt-dev
|
||||
|
||||
FROM build-base AS poco-build
|
||||
|
||||
@@ -26,20 +25,6 @@ RUN cmake ..
|
||||
RUN cmake --build . --config Release -j8
|
||||
RUN cmake --build . --target install
|
||||
|
||||
FROM build-base AS fmtlib-build
|
||||
|
||||
ARG FMTLIB_VERSION
|
||||
|
||||
ADD https://api.github.com/repos/fmtlib/fmt/git/refs/tags/${FMTLIB_VERSION} version.json
|
||||
RUN git clone https://github.com/fmtlib/fmt --branch ${FMTLIB_VERSION} /fmtlib
|
||||
|
||||
WORKDIR /fmtlib
|
||||
RUN mkdir cmake-build
|
||||
WORKDIR cmake-build
|
||||
RUN cmake ..
|
||||
RUN make
|
||||
RUN make install
|
||||
|
||||
FROM build-base AS cppkafka-build
|
||||
|
||||
ARG CPPKAFKA_VERSION
|
||||
@@ -54,19 +39,19 @@ RUN cmake ..
|
||||
RUN cmake --build . --config Release -j8
|
||||
RUN cmake --build . --target install
|
||||
|
||||
FROM build-base AS json-schema-validator-build
|
||||
FROM build-base AS valijson-build
|
||||
|
||||
ARG JSON_VALIDATOR_VERSION
|
||||
ARG VALIJASON_VERSION
|
||||
|
||||
ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/tags/${JSON_VALIDATOR_VERSION} version.json
|
||||
RUN git clone https://github.com/pboettch/json-schema-validator --branch ${JSON_VALIDATOR_VERSION} /json-schema-validator
|
||||
ADD https://api.github.com/repos/AriliaWireless/valijson/git/refs/tags/${VALIJASON_VERSION} version.json
|
||||
RUN git clone https://github.com/AriliaWireless/valijson --branch ${VALIJASON_VERSION} /valijson
|
||||
|
||||
WORKDIR /json-schema-validator
|
||||
WORKDIR /valijson
|
||||
RUN mkdir cmake-build
|
||||
WORKDIR cmake-build
|
||||
RUN cmake ..
|
||||
RUN make
|
||||
RUN make install
|
||||
RUN cmake --build . --config Release -j8
|
||||
RUN cmake --build . --target install
|
||||
|
||||
FROM build-base AS owgw-build
|
||||
|
||||
@@ -79,10 +64,7 @@ COPY --from=poco-build /usr/local/include /usr/local/include
|
||||
COPY --from=poco-build /usr/local/lib /usr/local/lib
|
||||
COPY --from=cppkafka-build /usr/local/include /usr/local/include
|
||||
COPY --from=cppkafka-build /usr/local/lib /usr/local/lib
|
||||
COPY --from=json-schema-validator-build /usr/local/include /usr/local/include
|
||||
COPY --from=json-schema-validator-build /usr/local/lib /usr/local/lib
|
||||
COPY --from=fmtlib-build /usr/local/include /usr/local/include
|
||||
COPY --from=fmtlib-build /usr/local/lib /usr/local/lib
|
||||
COPY --from=valijson-build /usr/local/include /usr/local/include
|
||||
|
||||
WORKDIR /owgw
|
||||
RUN mkdir cmake-build
|
||||
@@ -104,7 +86,7 @@ RUN mkdir -p "$OWGW_ROOT" "$OWGW_CONFIG" && \
|
||||
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||
librdkafka++1 gosu gettext ca-certificates bash jq curl wget \
|
||||
libmariadb-dev-compat libpq5 unixodbc postgresql-client
|
||||
libmariadb-dev-compat libpq5 unixodbc postgresql-client libfmt7 sqlite3
|
||||
|
||||
COPY readiness_check /readiness_check
|
||||
COPY test_scripts/curl/cli /cli
|
||||
@@ -118,7 +100,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>`.
|
||||
|
||||
92
PROTOCOL.md
92
PROTOCOL.md
@@ -89,6 +89,42 @@ Device sends a log message whenever necessary. The controller will log this mess
|
||||
}
|
||||
```
|
||||
|
||||
#### Events Channel
|
||||
Device sends unsolicited events to the controller.
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "event" ,
|
||||
"params" : {
|
||||
"serial" : <serial number> ,
|
||||
"data" : <Optiona/may be empty: JSON Document providing additional information related to this event message>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Alarms Channel
|
||||
Device sends unsolicited alarms to the controller.
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "alarm" ,
|
||||
"params" : {
|
||||
"serial" : <serial number> ,
|
||||
"data" : <Optiona/may be empty: JSON Document providing additional information related to this event message>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Wifiscan Channel
|
||||
Device sends unsolicited wifiscans to the controller.
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "wifiscan" ,
|
||||
"params" : {
|
||||
"serial" : <serial number> ,
|
||||
"data" : <Optiona/may be empty: JSON Document providing additional information related to this wifiscan message>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
##### `severity`
|
||||
The `severity` matches the `syslog` levels. Here are the details:
|
||||
- 0 : LOG_EMERG 0 /* system is unusable */
|
||||
@@ -298,7 +334,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 +355,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.
|
||||
@@ -423,44 +467,6 @@ The device should answer:
|
||||
- 1 : device cannot flash LEDs because it does not have any.
|
||||
- 2 : device rejects the request. `text` should include information as to why.
|
||||
|
||||
#### Controller sends a device specific command
|
||||
Controller sends this command specific to this device. The command is proprietary and must be agreed upon by the device
|
||||
and the controller.
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "perform" ,
|
||||
"params" : {
|
||||
"serial" : <serial number> ,
|
||||
"when" : Optional - <UTC time when to perform this command, 0 mean immediate, this is a suggestion>,
|
||||
"command" : <this is device specific and is TEXT only>,
|
||||
"payload" : <JSON Document: containing additional information about the command>
|
||||
},
|
||||
"id" : <some number>
|
||||
}
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
"status" : {
|
||||
"error" : 0 or an error number,
|
||||
"text" : <description of the error or success>,
|
||||
"when" : <in UTC time in seconds>,
|
||||
"resultCode" : <0 or an appropriate error code>,
|
||||
"resultText" : <any text resulting from the command. This is propietary to each command>
|
||||
}
|
||||
},
|
||||
"id" : <same number>
|
||||
}
|
||||
```
|
||||
##### The device answer
|
||||
The device should answer with teh above message. The `error` value should be interpreted the following way:
|
||||
- 0 : the command was performed as requested and the reults of the command is available in the `resultCode` and `resultText` parameters.
|
||||
- 1 : the command will be performed in the future and `when` shows that time. The `resultCode` and `resultText` dod not contain anything relevant.
|
||||
- 2 : the command cannot be performed as indicated. `resultCode` and `resultText` may contain some indication as to why.
|
||||
|
||||
#### Controller wants the device to perform a trace
|
||||
Controller sends this command when it needs the device to perform a trace (i.e. tcpdump).
|
||||
```json
|
||||
@@ -711,9 +717,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>
|
||||
|
||||
@@ -50,13 +50,13 @@ cmake --build . --config Release
|
||||
sudo cmake --build . --target install
|
||||
|
||||
cd ~
|
||||
git clone https://github.com/pboettch/json-schema-validator.git --branch 2.1.0
|
||||
cd json-schema-validator
|
||||
git clone https://github.com/AriliaWireless/valijson --branch tip-v1
|
||||
cd valijson
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
cmake ..
|
||||
make -j
|
||||
sudo make install
|
||||
cmake --build . --config Release
|
||||
sudo cmake --build . --target install
|
||||
|
||||
git clone https://github.com/fmtlib/fmt --branch 9.0.0 /fmtlib
|
||||
cd fmtlib
|
||||
|
||||
82
RESTRICTED_DEVICES.md
Normal file
82
RESTRICTED_DEVICES.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Restricted devices
|
||||
|
||||
## What is a restricted device?
|
||||
A restricted device is one that because of regulations or a desire for utmost security, requires signatures to access restricted or blocked
|
||||
features. The restriction process is burnt in the device at manufacturing or later by running a specific command on the device. Once a device
|
||||
is restricted, it cannot be unlocked.
|
||||
|
||||
## Current restrictions
|
||||
Restrictions are stored on the AP in a protected partition. They are contained in a file called `restrictions.json`. Here is a sample:
|
||||
```json
|
||||
{
|
||||
"country": [
|
||||
"US", "CA"
|
||||
],
|
||||
"dfs": true,
|
||||
"rtty": true,
|
||||
"tty": true,
|
||||
"developer": true,
|
||||
"sysupgrade": true,
|
||||
"commands": true,
|
||||
"key_info": {
|
||||
"vendor": "dummy",
|
||||
"algo": "static"
|
||||
}
|
||||
}
|
||||
```
|
||||
- country
|
||||
- List of countries where this device may be used
|
||||
- dfs
|
||||
- Disallow DFS Override during wifi-scan. If set to `true`, device will not allow to override DFS channels
|
||||
- rtty
|
||||
- Disallow the use of the RTTY command for this device
|
||||
- tty
|
||||
- Do not allow the AP to accept `tty` connection
|
||||
- developer
|
||||
- Internal use only.
|
||||
- sysupgrade
|
||||
- If set to `true`, only signed firmware upgrade command will be allowed.
|
||||
- commands
|
||||
- If set to `true`, do not allow commands.
|
||||
- key_info
|
||||
- This structure defines how signatures should be generated and verified in a secure system
|
||||
- vendor
|
||||
- An identified that must match the vendor name provided in the controller
|
||||
- algo
|
||||
- The signature algorithm. Here are the supported algorithms
|
||||
- `static`
|
||||
- A test algorithm that always returns and uses a value of `aaaaaaaaaa`. This should never be used in the field.
|
||||
- `dgst-sha256`
|
||||
- The default OpenSSL RSA signature generation and verification. The controller will use the following command to generate the signature
|
||||
```sh
|
||||
openssl dgst -sha256 -sign private-key.pem -out signature.txt myfile
|
||||
```
|
||||
- The AP will be using the following to verify the signature
|
||||
```sh
|
||||
openssl dgst -sha256 -verify public-key.pem -signature signature.txt myfile
|
||||
```
|
||||
|
||||
## Creating signatures on the controller
|
||||
When a device is restricted and a signature is required, the controller can generate the signature
|
||||
for the specified `vendor`. However, on the controlelr side, you must configure the vendors. In
|
||||
order to do so we suggest the following.
|
||||
- Create a directory called `signatures` under your `certs` directory
|
||||
- Copy the public and private keys for each `vendor` name. We suggest naming them accordingly
|
||||
- `vendor`-private-key.pem
|
||||
- `vendor`-public-key.pem
|
||||
- In the `owgw.properties` file, you need to declare these signatures the following way
|
||||
```properties
|
||||
signature.manager.0.key.public = $OWGW_ROOT/certs/signatures/test1-public-key.pem
|
||||
signature.manager.0.key.private = $OWGW_ROOT/certs/signatures/test1-private-key.pem
|
||||
signature.manager.0.vendor = test1
|
||||
|
||||
signature.manager.1.key.public = $OWGW_ROOT/certs/signatures/test2-public-key.pem
|
||||
signature.manager.1.key.private = $OWGW_ROOT/certs/signatures/test2-private-key.pem
|
||||
signature.manager.1.vendor = test2
|
||||
```
|
||||
|
||||
## How do you use the signatures?
|
||||
There is nothing to do really. Now the controller will use the proper key to create the signatures
|
||||
when it sends commands to the AP. It will use the algorithm that the device understands too. This is transparent
|
||||
to the user. The `vendor` name used in the controller configuration must match the `vendor` name provided in the
|
||||
`restrictions.json` file.
|
||||
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
|
||||
@@ -73,6 +73,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
||||
STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"owgw"} \
|
||||
STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"owgw"} \
|
||||
STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \
|
||||
CERTIFICATES_ALLOWMISMATCH=${CERTIFICATES_ALLOWMISMATCH:-"false"} \
|
||||
envsubst < /owgw.properties.tmpl > $OWGW_CONFIG/owgw.properties
|
||||
fi
|
||||
|
||||
|
||||
@@ -230,6 +230,7 @@ configProperties:
|
||||
openwifi.devicetypes.0: AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
|
||||
openwifi.devicetypes.1: SWITCH:edgecore_ecs4100-12ph
|
||||
openwifi.devicetypes.2: IOT:esp32
|
||||
openwifi.certificates.allowmismatch: "false"
|
||||
oui.download.uri: https://standards-oui.ieee.org/oui/oui.txt
|
||||
firmware.autoupdate.policy.default: auto
|
||||
iptocountry.provider: ipinfo
|
||||
|
||||
@@ -49,6 +49,38 @@ components:
|
||||
- IOT
|
||||
- MESH
|
||||
|
||||
DeviceRestrictionsKeyInfo:
|
||||
type: object
|
||||
properties:
|
||||
vendor:
|
||||
type: string
|
||||
algo:
|
||||
type: string
|
||||
|
||||
DeviceRestrictions:
|
||||
type: object
|
||||
properties:
|
||||
dfs:
|
||||
type: boolean
|
||||
ssh:
|
||||
type: boolean
|
||||
rtty:
|
||||
type: boolean
|
||||
tty:
|
||||
type: boolean
|
||||
developer:
|
||||
type: boolean
|
||||
upgrade:
|
||||
type: boolean
|
||||
commands:
|
||||
type: boolean
|
||||
country:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
key_info:
|
||||
$ref: '#/components/schemas/DeviceRestrictionsKeyInfo'
|
||||
|
||||
Device:
|
||||
type: object
|
||||
description: Definition of uCentral device
|
||||
@@ -107,6 +139,19 @@ components:
|
||||
type: string
|
||||
minLength: 2
|
||||
maxLength: 2
|
||||
restrictedDevice:
|
||||
type: boolean
|
||||
default: false
|
||||
certificateExpiryDate:
|
||||
type: integer
|
||||
format: int64
|
||||
pendingConfiguration:
|
||||
type: string
|
||||
pendingConfigurationCmd:
|
||||
type: string
|
||||
format: uuid
|
||||
restrictionDetails:
|
||||
$ref: '#/components/schemas/DeviceRestrictions'
|
||||
|
||||
DeviceWithStatus:
|
||||
type: object
|
||||
@@ -202,6 +247,19 @@ components:
|
||||
totalConnectionTime:
|
||||
type: integer
|
||||
format: int64
|
||||
restrictedDevice:
|
||||
type: boolean
|
||||
default: false
|
||||
certificateDate:
|
||||
type: integer
|
||||
format: int64
|
||||
pendingConfiguration:
|
||||
type: string
|
||||
pendingConfigurationCmd:
|
||||
type: string
|
||||
format: uuid
|
||||
restrictionDetails:
|
||||
$ref: '#/components/schemas/DeviceRestrictions'
|
||||
|
||||
DeviceList:
|
||||
type: object
|
||||
@@ -500,18 +558,69 @@ components:
|
||||
type:
|
||||
type: string
|
||||
enum:
|
||||
- uci
|
||||
- ucode
|
||||
- shell
|
||||
- bundle
|
||||
- diagnostic
|
||||
script:
|
||||
type: string
|
||||
scriptId:
|
||||
type: string
|
||||
format: uuid
|
||||
when:
|
||||
type: integer
|
||||
format: int64
|
||||
default: 0
|
||||
signature:
|
||||
type: string
|
||||
deferred:
|
||||
type: boolean
|
||||
uri:
|
||||
type: string
|
||||
|
||||
ScriptEntry:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
name:
|
||||
type: string
|
||||
description:
|
||||
type: string
|
||||
uri:
|
||||
type: string
|
||||
content:
|
||||
type: string
|
||||
version:
|
||||
type: string
|
||||
type:
|
||||
enum:
|
||||
- shell
|
||||
- bundle
|
||||
created:
|
||||
type: integer
|
||||
modified:
|
||||
type: integer
|
||||
author:
|
||||
type: string
|
||||
restricted:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
deferred:
|
||||
type: boolean
|
||||
default: false
|
||||
timeout:
|
||||
type: integer
|
||||
default: 30
|
||||
defaultUploadURI:
|
||||
type: string
|
||||
|
||||
ScriptEntryList:
|
||||
type: object
|
||||
properties:
|
||||
scripts:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/ScriptEntry'
|
||||
|
||||
FactoryRequest:
|
||||
type: object
|
||||
@@ -921,9 +1030,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 +2016,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 +2031,8 @@ paths:
|
||||
schema:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/StatisticsRecords'
|
||||
- $ref: '#/components/schemas/DeviceCount'
|
||||
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
@@ -2076,6 +2210,11 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
- in: query
|
||||
name: FWsignature
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
requestBody:
|
||||
description: Command details
|
||||
content:
|
||||
@@ -2430,6 +2569,148 @@ paths:
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/scripts:
|
||||
get:
|
||||
tags:
|
||||
- Scripting
|
||||
summary: Returns a list scripts.
|
||||
description: Get a list of scripts.
|
||||
operationId: getScripts
|
||||
parameters:
|
||||
- in: query
|
||||
description: Pagination start (starts at 0. If not specified, 0 is assumed)
|
||||
name: offset
|
||||
schema:
|
||||
type: integer
|
||||
required: false
|
||||
- in: query
|
||||
description: Maximum number of entries to return (if absent, no limit is assumed)
|
||||
name: limit
|
||||
schema:
|
||||
type: integer
|
||||
required: false
|
||||
- in: query
|
||||
description: Filter the results
|
||||
name: filter
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
responses:
|
||||
200:
|
||||
description: List all scripts
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ScriptEntryList'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/script/{uuid}:
|
||||
get:
|
||||
tags:
|
||||
- Scripting
|
||||
summary: Returns a script entry.
|
||||
description: Get a specific script entry.
|
||||
operationId: getScript
|
||||
parameters:
|
||||
- in: path
|
||||
description: The UUID of the script
|
||||
name: uuid
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
description: A script entry
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ScriptEntry'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
post:
|
||||
tags:
|
||||
- Scripting
|
||||
summary: Create a new script.
|
||||
operationId: createScript
|
||||
parameters:
|
||||
- in: path
|
||||
description: The UUID of the script. Must be set to 0 for creation
|
||||
name: uuid
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
requestBody:
|
||||
description: Complet script entry
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ScriptEntry'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/ScriptEntry'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
put:
|
||||
tags:
|
||||
- Scripting
|
||||
summary: Modify a script.
|
||||
operationId: modifyScript
|
||||
parameters:
|
||||
- in: path
|
||||
description: The UUID of the script.
|
||||
name: uuid
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
requestBody:
|
||||
description: Complete script entry. You may only modify the name, description, version, uri, and content
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ScriptEntry'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/ScriptEntry'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- Scripting
|
||||
summary: Delete a script.
|
||||
operationId: deleteScript
|
||||
parameters:
|
||||
- in: path
|
||||
name: uuid
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
responses:
|
||||
204:
|
||||
$ref: '#/components/responses/Success'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
|
||||
|
||||
|
||||
/blacklist:
|
||||
get:
|
||||
tags:
|
||||
@@ -2731,4 +3012,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'
|
||||
|
||||
@@ -75,6 +75,7 @@ openwifi.autoprovisioning = true
|
||||
openwifi.devicetypes.0 = AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
|
||||
openwifi.devicetypes.1 = SWITCH:edgecore_ecs4100-12ph
|
||||
openwifi.devicetypes.2 = IOT:esp32
|
||||
openwifi.certificates.allowmismatch = ${CERTIFICATES_ALLOWMISMATCH}
|
||||
oui.download.uri = https://standards-oui.ieee.org/oui/oui.txt
|
||||
simulatorid = ${SIMULATORID}
|
||||
iptocountry.default = US
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
"weight" : 10,
|
||||
"radsec" : true,
|
||||
"radsecPort" : 2083,
|
||||
"allowSelfSigned" : false,
|
||||
"radsecSecret" : "radsec",
|
||||
"radsecKey" : "LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUR6RnpXeTZlYXg0QVoxTySG9VUURRZ0FFS3BnWVBHMktPTVd2S0w1Z3NMRXpUc09rREg1M3NHaEQyS3RsRXBDTXVnNDNIZlFnTFVpUgpTR1R2S1l0bDFmbmJaU1lnY0RJdncxdjNYRy9hVDhOY2JBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=",
|
||||
"radsecCert" : "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNRVENDQWVpZ0F3SUJBZ0lVY3BKS3pVM0Ba0dBMVVFQmhNQ1ZWTXhFekFSQmdOVkJBb1RDa0oxZEhSdmJuZHZiMlF4SFRBYkJnTlZCQU1URkVKMQpkSFJ2Ym5kdmIyUWdVbUZrYzJWaklFTkJNQjRYRFRJeU1EY3dNekExTWpVeE5Gb1hEVEkzTURVeE9UQTFNalV4Ck5Gb3dkVEVMTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFvVENrSjFkSFJ2Ym5kdmIyUXhOakEwQmdOVkJBTVQKTFdGeWFXeHBZUzVqWWpFd2FtTnVjemgxYlhCbk9HWnBjRFowTUM1dmNtbHZiaTVoY21WaE1USXdMbU52YlRFWgpNQmNHQ2dtU0pvbVQ4aXhrQVFFVENVZHZiMmRzWlRwVlV6QlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VICkEwSUFCQ3FZR0R4dGlqakZyeWkrWUxDeE0wN0RwQXgrZDdCb1E5aXJaUktRakxvT054MzBJQzFJa1Voazd5bUwKWmRYNTIyVW1JSEF5TDhOYjkxeHYyay9EWEd5amdZa3dnWVl3RGdZRFZSMFBBUUgvQkFRREFnZUFNQk1HQTFVZApKUVFNTUFvR0NDc0dBUVVGQndNQ01Bd0dBMVVkRXdFQi93UUNNQUF3T0FZRFZSMFJCREV3TDRJdFlYSnBiR2xoCkxtTmlNVEJxWTI1ek9IVnRjR2M0Wm1sd05uUXdMbTl5YVc5dUxtRnlaV0V4TWpBdVkyOXRNQmNHQTFVZElBUVEKTUE0d0RBWUtLd1lCQkFIdUtnRUJCVEFLQmdncWhrak9QUVFEQWdOSEFEQkVBaUFwTmM1dUNBSkp6KzVyakdqdwpCWGtOdHE3UU83bWU5dUg5bkNsTDZnSVE5Z0lnUHM2VkVKVW5CcEZ0RktXbFF4eWJ1YlBxYnpJNjBPSERHQ0ExCmhXUk1PS1U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K",
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "Poco/Net/SSLException.h"
|
||||
#include "Poco/Net/Context.h"
|
||||
#include "Poco/Base64Decoder.h"
|
||||
|
||||
#include "Poco/Net/WebSocketImpl.h"
|
||||
#include "Poco/zlib.h"
|
||||
|
||||
#include "AP_WS_Server.h"
|
||||
@@ -20,8 +20,17 @@
|
||||
#include "ConfigurationCache.h"
|
||||
#include "StorageService.h"
|
||||
#include "TelemetryStream.h"
|
||||
#include "framework/WebSocketClientNotifications.h"
|
||||
#include "Poco/Net/WebSocketImpl.h"
|
||||
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/utils.h"
|
||||
#include "UI_GW_WebSocketNotifications.h"
|
||||
#include "GWKafkaEvents.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
|
||||
|
||||
#include "RADIUS_proxy_server.h"
|
||||
|
||||
@@ -35,7 +44,7 @@ namespace OpenWifi {
|
||||
|
||||
AP_WS_Connection::AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response,
|
||||
std::uint64_t connection_id,
|
||||
uint64_t connection_id,
|
||||
Poco::Logger &L,
|
||||
Poco::Net::SocketReactor &R)
|
||||
: Logger_(L) ,
|
||||
@@ -65,27 +74,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;
|
||||
@@ -93,6 +81,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());
|
||||
@@ -100,7 +89,7 @@ namespace OpenWifi {
|
||||
PeerAddress_ = SS->peerAddress().host();
|
||||
CId_ = Utils::FormatIPv6(SS->peerAddress().toString());
|
||||
|
||||
State_.started = OpenWifi::Now();
|
||||
State_.started = Utils::Now();
|
||||
|
||||
if (!SS->secure()) {
|
||||
poco_warning(Logger_,fmt::format("TLS-CONNECTION({}): Session={} Connection is NOT secure. Device is not allowed.", CId_, State_.sessionId ));
|
||||
@@ -140,7 +129,10 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CN_.empty() && StorageService()->IsBlackListed(SerialNumber_)) {
|
||||
std::string reason, author;
|
||||
std::uint64_t created;
|
||||
if (!CN_.empty() && StorageService()->IsBlackListed(CN_, reason, author, created)) {
|
||||
DeviceBlacklistedKafkaEvent KE(CN_,Utils::Now(),reason,author,created,CId_);
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("TLS-CONNECTION({}): Session={} Device {} is black listed. Disconnecting.",
|
||||
@@ -149,6 +141,7 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
State_.certificateExpiryDate = PeerCert.expiresOn().timestamp().epochTime();
|
||||
SerialNumber_ = CN_;
|
||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
||||
|
||||
@@ -198,7 +191,7 @@ namespace OpenWifi {
|
||||
Poco::JSON::Object Disconnect;
|
||||
Poco::JSON::Object Details;
|
||||
Details.set(uCentralProtocol::SERIALNUMBER, SerialNumber);
|
||||
Details.set(uCentralProtocol::TIMESTAMP, OpenWifi::Now());
|
||||
Details.set(uCentralProtocol::TIMESTAMP, Utils::Now());
|
||||
Disconnect.set(uCentralProtocol::DISCONNECTION, Details);
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
std::ostringstream OS;
|
||||
@@ -238,8 +231,11 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
auto SessionDeleted = AP_WS_Server()->EndSession(State_.sessionId, SerialNumberInt_);
|
||||
if (SessionDeleted)
|
||||
WebSocketClientNotificationDeviceDisconnected(SerialNumber_);
|
||||
if (SessionDeleted) {
|
||||
GWWebSocketNotifications::SingleDevice_t N;
|
||||
N.content.serialNumber = SerialNumber_;
|
||||
GWWebSocketNotifications::DeviceDisconnected(N);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,7 +276,7 @@ namespace OpenWifi {
|
||||
State_.PendingUUID = D.UUID;
|
||||
GWObjects::CommandDetails Cmd;
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = MicroService::CreateUUID();
|
||||
Cmd.UUID = MicroServiceCreateUUID();
|
||||
Cmd.SubmittedBy = uCentralProtocol::SUBMITTED_BY_SYSTEM;
|
||||
Cmd.Status = uCentralProtocol::PENDING;
|
||||
Cmd.Command = uCentralProtocol::CONFIGURE;
|
||||
@@ -300,9 +296,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(), APCommands::to_apcommand(Cmd.Command.c_str()),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent, false);
|
||||
|
||||
WebSocketClientNotificationDeviceConfigurationChange(D.SerialNumber, UUID, UpgradedUUID);
|
||||
GWWebSocketNotifications::SingleDeviceConfigurationChange_t Notification;
|
||||
Notification.content.serialNumber = D.SerialNumber;
|
||||
Notification.content.oldUUID = UUID;
|
||||
Notification.content.newUUID = UpgradedUUID;
|
||||
GWWebSocketNotifications::DeviceConfigurationChange(Notification);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -311,7 +311,7 @@ namespace OpenWifi {
|
||||
|
||||
void AP_WS_Connection::ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc) {
|
||||
poco_debug(Logger_,fmt::format("RECEIVED-RPC({}): {}.", CId_, Doc->get(uCentralProtocol::ID).toString()));
|
||||
CommandManager()->PostCommandResult(SerialNumber_, *Doc);
|
||||
CommandManager()->PostCommandResult(SerialNumber_, Doc);
|
||||
}
|
||||
|
||||
void AP_WS_Connection::ProcessJSONRPCEvent(Poco::JSON::Object::Ptr &Doc) {
|
||||
@@ -374,7 +374,10 @@ namespace OpenWifi {
|
||||
E.rethrow();
|
||||
}
|
||||
|
||||
if (StorageService()->IsBlackListed(Serial)) {
|
||||
std::string reason, author;
|
||||
std::uint64_t created;
|
||||
if (StorageService()->IsBlackListed(Serial, reason, author, created)) {
|
||||
DeviceBlacklistedKafkaEvent KE(CN_,Utils::Now(),reason,author,created,CId_);
|
||||
Poco::Exception E(
|
||||
fmt::format("BLACKLIST({}): device is blacklisted and not allowed to connect.",
|
||||
Serial),
|
||||
@@ -427,6 +430,18 @@ namespace OpenWifi {
|
||||
Process_venuebroadcast(ParamsObj);
|
||||
} break;
|
||||
|
||||
case uCentralProtocol::Events::ET_EVENT: {
|
||||
Process_event(ParamsObj);
|
||||
} break;
|
||||
|
||||
case uCentralProtocol::Events::ET_ALARM: {
|
||||
Process_alarm(ParamsObj);
|
||||
} break;
|
||||
|
||||
case uCentralProtocol::Events::ET_WIFISCAN: {
|
||||
Process_wifiscan(ParamsObj);
|
||||
} break;
|
||||
|
||||
// this will never be called but some compilers will complain if we do not have a case for
|
||||
// every single values of an enum
|
||||
case uCentralProtocol::Events::ET_UNKNOWN: {
|
||||
@@ -436,18 +451,23 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
bool AP_WS_Connection::StartTelemetry(std::uint64_t RPCID) {
|
||||
bool AP_WS_Connection::StartTelemetry(uint64_t RPCID, const std::vector<std::string> & TelemetryTypes) {
|
||||
poco_information(Logger_, fmt::format("TELEMETRY({}): Starting.", CId_));
|
||||
Poco::JSON::Object StartMessage;
|
||||
StartMessage.set("jsonrpc", "2.0");
|
||||
StartMessage.set("method", "telemetry");
|
||||
Poco::JSON::Object Params;
|
||||
Params.set("serial", SerialNumber_);
|
||||
Params.set("interval", TelemetryInterval_);
|
||||
Params.set("interval", (uint64_t)TelemetryInterval_);
|
||||
Poco::JSON::Array Types;
|
||||
Types.add("wifi-frames");
|
||||
Types.add("dhcp-snooping");
|
||||
Types.add("state");
|
||||
if(TelemetryTypes.empty()) {
|
||||
Types.add("wifi-frames");
|
||||
Types.add("dhcp-snooping");
|
||||
Types.add("state");
|
||||
} else {
|
||||
for(const auto &type:TelemetryTypes)
|
||||
Types.add(type);
|
||||
}
|
||||
Params.set(RESTAPI::Protocol::TYPES, Types);
|
||||
StartMessage.set("id", RPCID);
|
||||
StartMessage.set("params", Params);
|
||||
@@ -457,7 +477,7 @@ namespace OpenWifi {
|
||||
return Send(OS.str());
|
||||
}
|
||||
|
||||
bool AP_WS_Connection::StopTelemetry(std::uint64_t RPCID) {
|
||||
bool AP_WS_Connection::StopTelemetry(uint64_t RPCID) {
|
||||
poco_information(Logger_, fmt::format("TELEMETRY({}): Stopping.", CId_));
|
||||
Poco::JSON::Object StopMessage;
|
||||
StopMessage.set("jsonrpc", "2.0");
|
||||
@@ -480,36 +500,36 @@ namespace OpenWifi {
|
||||
State_.webSocketClients = TelemetryWebSocketRefCount_;
|
||||
}
|
||||
|
||||
bool AP_WS_Connection::SetWebSocketTelemetryReporting(std::uint64_t RPCID, uint64_t Interval,
|
||||
uint64_t LifeTime) {
|
||||
bool AP_WS_Connection::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t Interval,
|
||||
uint64_t LifeTime, const std::vector<std::string> & TelemetryTypes) {
|
||||
std::unique_lock Lock(TelemetryMutex_);
|
||||
TelemetryWebSocketRefCount_++;
|
||||
TelemetryInterval_ = TelemetryInterval_ ? std::min(Interval, TelemetryInterval_) : Interval;
|
||||
auto TelemetryWebSocketTimer = LifeTime + OpenWifi::Now();
|
||||
TelemetryWebSocketTimer_ = std::max(TelemetryWebSocketTimer, TelemetryWebSocketTimer_);
|
||||
TelemetryInterval_ = TelemetryInterval_ ? ( Interval< TelemetryInterval_ ? Interval : TelemetryInterval_) : Interval;
|
||||
auto TelemetryWebSocketTimer = LifeTime + Utils::Now();
|
||||
TelemetryWebSocketTimer_ = TelemetryWebSocketTimer > TelemetryWebSocketTimer_ ? TelemetryWebSocketTimer : TelemetryWebSocketTimer_;
|
||||
UpdateCounts();
|
||||
if (!TelemetryReporting_) {
|
||||
TelemetryReporting_ = true;
|
||||
return StartTelemetry(RPCID);
|
||||
return StartTelemetry(RPCID, TelemetryTypes);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AP_WS_Connection::SetKafkaTelemetryReporting(std::uint64_t RPCID, uint64_t Interval, uint64_t LifeTime) {
|
||||
bool AP_WS_Connection::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t Interval, uint64_t LifeTime, const std::vector<std::string> & TelemetryTypes) {
|
||||
std::unique_lock Lock(TelemetryMutex_);
|
||||
TelemetryKafkaRefCount_++;
|
||||
TelemetryInterval_ = TelemetryInterval_ ? std::min(Interval, TelemetryInterval_) : Interval;
|
||||
auto TelemetryKafkaTimer = LifeTime + OpenWifi::Now();
|
||||
TelemetryKafkaTimer_ = std::max(TelemetryKafkaTimer, TelemetryKafkaTimer_);
|
||||
TelemetryInterval_ = TelemetryInterval_ ? ( Interval<TelemetryInterval_ ? Interval : TelemetryInterval_) : Interval;
|
||||
auto TelemetryKafkaTimer = LifeTime + Utils::Now();
|
||||
TelemetryKafkaTimer_ = TelemetryKafkaTimer > TelemetryKafkaTimer_ ? TelemetryKafkaTimer : TelemetryKafkaTimer_;
|
||||
UpdateCounts();
|
||||
if (!TelemetryReporting_) {
|
||||
TelemetryReporting_ = true;
|
||||
return StartTelemetry(RPCID);
|
||||
return StartTelemetry(RPCID, TelemetryTypes);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AP_WS_Connection::StopWebSocketTelemetry(std::uint64_t RPCID) {
|
||||
bool AP_WS_Connection::StopWebSocketTelemetry(uint64_t RPCID) {
|
||||
std::unique_lock Lock(TelemetryMutex_);
|
||||
if (TelemetryWebSocketRefCount_)
|
||||
TelemetryWebSocketRefCount_--;
|
||||
@@ -521,7 +541,7 @@ namespace OpenWifi {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AP_WS_Connection::StopKafkaTelemetry(std::uint64_t RPCID) {
|
||||
bool AP_WS_Connection::StopKafkaTelemetry(uint64_t RPCID) {
|
||||
std::unique_lock Lock(TelemetryMutex_);
|
||||
if (TelemetryKafkaRefCount_)
|
||||
TelemetryKafkaRefCount_--;
|
||||
@@ -586,7 +606,7 @@ namespace OpenWifi {
|
||||
|
||||
State_.RX += IncomingSize;
|
||||
State_.MessageCount++;
|
||||
State_.LastContact = OpenWifi::Now();
|
||||
State_.LastContact = Utils::Now();
|
||||
|
||||
switch (Op) {
|
||||
case Poco::Net::WebSocket::FRAME_OP_PING: {
|
||||
@@ -594,7 +614,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;
|
||||
@@ -603,7 +622,7 @@ namespace OpenWifi {
|
||||
PingDetails.set(uCentralProtocol::SERIALNUMBER, SerialNumber_);
|
||||
PingDetails.set(uCentralProtocol::COMPATIBLE, Compatible_);
|
||||
PingDetails.set(uCentralProtocol::CONNECTIONIP, CId_);
|
||||
PingDetails.set(uCentralProtocol::TIMESTAMP, OpenWifi::Now());
|
||||
PingDetails.set(uCentralProtocol::TIMESTAMP, Utils::Now());
|
||||
PingDetails.set("locale", State_.locale );
|
||||
PingObject.set(uCentralProtocol::PING, PingDetails);
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class AP_WS_Connection {
|
||||
@@ -24,7 +23,7 @@ namespace OpenWifi {
|
||||
public:
|
||||
explicit AP_WS_Connection( Poco::Net::HTTPServerRequest &request,
|
||||
Poco::Net::HTTPServerResponse &response,
|
||||
std::uint64_t connection_id,
|
||||
uint64_t connection_id,
|
||||
Poco::Logger &L,
|
||||
Poco::Net::SocketReactor &R);
|
||||
~AP_WS_Connection();
|
||||
@@ -44,14 +43,44 @@ 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_; }
|
||||
bool SetWebSocketTelemetryReporting(std::uint64_t RPCID, uint64_t interval, uint64_t TelemetryWebSocketTimer);
|
||||
bool SetKafkaTelemetryReporting(std::uint64_t RPCID, uint64_t interval, uint64_t TelemetryKafkaTimer);
|
||||
bool StopWebSocketTelemetry(std::uint64_t RPCID);
|
||||
bool StopKafkaTelemetry(std::uint64_t RPCID);
|
||||
bool SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t interval, uint64_t TelemetryWebSocketTimer, const std::vector<std::string> & TelemetryTypes);
|
||||
bool SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t interval, uint64_t TelemetryKafkaTimer, const std::vector<std::string> & TelemetryTypes);
|
||||
bool StopWebSocketTelemetry(uint64_t RPCID);
|
||||
bool StopKafkaTelemetry(uint64_t RPCID);
|
||||
|
||||
inline void GetLastStats(std::string &LastStats) const {
|
||||
std::shared_lock G(ConnectionMutex_);
|
||||
LastStats = RawLastStats_;
|
||||
}
|
||||
|
||||
inline void SetLastStats(const std::string &LastStats) {
|
||||
std::unique_lock G(ConnectionMutex_);
|
||||
RawLastStats_ = LastStats;
|
||||
}
|
||||
|
||||
inline void SetLastHealthCheck(const GWObjects::HealthCheck &H) {
|
||||
std::unique_lock G(ConnectionMutex_);
|
||||
RawLastHealthcheck_ = H;
|
||||
}
|
||||
|
||||
inline void GetLastHealthCheck(GWObjects::HealthCheck &H) {
|
||||
std::shared_lock G(ConnectionMutex_);
|
||||
H = RawLastHealthcheck_;
|
||||
}
|
||||
|
||||
inline void GetState(GWObjects::ConnectionState &State) const {
|
||||
std::shared_lock G(ConnectionMutex_);
|
||||
State = State_;
|
||||
}
|
||||
|
||||
inline void GetRestrictions(GWObjects::DeviceRestrictions & R) const {
|
||||
std::shared_lock G(ConnectionMutex_);
|
||||
R = Restrictions_;
|
||||
}
|
||||
|
||||
void Process_connect(Poco::JSON::Object::Ptr ParamsObj, const std::string &Serial);
|
||||
void Process_state(Poco::JSON::Object::Ptr ParamsObj);
|
||||
@@ -64,6 +93,9 @@ namespace OpenWifi {
|
||||
void Process_deviceupdate(Poco::JSON::Object::Ptr ParamsObj, std::string &Serial);
|
||||
void Process_telemetry(Poco::JSON::Object::Ptr ParamsObj);
|
||||
void Process_venuebroadcast(Poco::JSON::Object::Ptr ParamsObj);
|
||||
void Process_event(Poco::JSON::Object::Ptr ParamsObj);
|
||||
void Process_wifiscan(Poco::JSON::Object::Ptr ParamsObj);
|
||||
void Process_alarm(Poco::JSON::Object::Ptr ParamsObj);
|
||||
|
||||
bool ValidatedDevice();
|
||||
|
||||
@@ -83,11 +115,15 @@ namespace OpenWifi {
|
||||
return true;
|
||||
}
|
||||
|
||||
friend class DeviceRegistry;
|
||||
friend class AP_WS_Server;
|
||||
|
||||
inline GWObjects::DeviceRestrictions Restrictions() const {
|
||||
std::shared_lock G(ConnectionMutex_);
|
||||
return Restrictions_;
|
||||
}
|
||||
|
||||
private:
|
||||
// std::recursive_mutex LocalMutex_;
|
||||
mutable std::shared_mutex ConnectionMutex_;
|
||||
std::shared_mutex TelemetryMutex_;
|
||||
Poco::Logger &Logger_;
|
||||
Poco::Net::SocketReactor &Reactor_;
|
||||
@@ -100,28 +136,28 @@ namespace OpenWifi {
|
||||
std::string CN_;
|
||||
uint64_t Errors_=0;
|
||||
Poco::Net::IPAddress PeerAddress_;
|
||||
std::atomic_bool TelemetryReporting_ = false;
|
||||
std::atomic_uint64_t TelemetryWebSocketRefCount_ = 0;
|
||||
std::atomic_uint64_t TelemetryKafkaRefCount_ = 0;
|
||||
uint64_t TelemetryWebSocketTimer_ = 0;
|
||||
uint64_t TelemetryKafkaTimer_ = 0 ;
|
||||
uint64_t TelemetryInterval_ = 0;
|
||||
std::atomic_uint64_t TelemetryWebSocketPackets_=0;
|
||||
std::atomic_uint64_t TelemetryKafkaPackets_=0;
|
||||
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;
|
||||
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;
|
||||
OpenWifi::GWObjects::DeviceRestrictions Restrictions_;
|
||||
|
||||
static inline std::atomic_uint64_t ConcurrentStartingDevices_=0;
|
||||
|
||||
bool StartTelemetry(std::uint64_t RPCID);
|
||||
bool StopTelemetry(std::uint64_t RPCID);
|
||||
bool StartTelemetry(uint64_t RPCID, const std::vector<std::string> & TelemetryTypes);
|
||||
bool StopTelemetry(uint64_t RPCID);
|
||||
void UpdateCounts();
|
||||
};
|
||||
|
||||
|
||||
32
src/AP_WS_Process_alarm.cpp
Normal file
32
src/AP_WS_Process_alarm.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// Created by stephane bourque on 2023-01-22.
|
||||
//
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
#include "fmt/format.h"
|
||||
#include "framework/KafkaManager.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_alarm(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
poco_trace(Logger_, fmt::format("Alarm data received for {}", SerialNumber_));
|
||||
|
||||
if (ParamsObj->has(uCentralProtocol::SERIAL) && ParamsObj->has(uCentralProtocol::DATA)) {
|
||||
if (KafkaManager()->Enabled()) {
|
||||
auto Data = ParamsObj->get(uCentralProtocol::DATA);
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
std::ostringstream OS;
|
||||
Stringify.condense(ParamsObj, OS);
|
||||
KafkaManager()->PostMessage(KafkaTopics::ALERTS, SerialNumber_, OS.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,130 +6,175 @@
|
||||
#include "AP_WS_Server.h"
|
||||
#include "StorageService.h"
|
||||
#include "FindCountry.h"
|
||||
#include "framework/WebSocketClientNotifications.h"
|
||||
#include "Daemon.h"
|
||||
#include "CentralConfig.h"
|
||||
|
||||
#include "CommandManager.h"
|
||||
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
#include "UI_GW_WebSocketNotifications.h"
|
||||
#include <GWKafkaEvents.h>
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void AP_WS_Connection::Process_connect(Poco::JSON::Object::Ptr ParamsObj, const std::string &Serial) {
|
||||
if (ParamsObj->has(uCentralProtocol::UUID) &&
|
||||
ParamsObj->has(uCentralProtocol::FIRMWARE) &&
|
||||
ParamsObj->has(uCentralProtocol::CAPABILITIES)) {
|
||||
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
|
||||
auto Firmware = ParamsObj->get(uCentralProtocol::FIRMWARE).toString();
|
||||
auto CapabilitiesString = ParamsObj->get(uCentralProtocol::CAPABILITIES).toString();
|
||||
|
||||
Config::Capabilities Caps(CapabilitiesString);
|
||||
Compatible_ = Caps.Compatible();
|
||||
|
||||
SerialNumber_ = Serial;
|
||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
||||
|
||||
CommandManager()->ClearQueue(SerialNumberInt_);
|
||||
|
||||
AP_WS_Server()->SetSessionDetails(State_.sessionId,SerialNumberInt_);
|
||||
State_.UUID = UUID;
|
||||
State_.Firmware = Firmware;
|
||||
State_.PendingUUID = 0;
|
||||
State_.Address = Utils::FormatIPv6(WS_->peerAddress().toString());
|
||||
CId_ = SerialNumber_ + "@" + CId_;
|
||||
|
||||
auto IP = PeerAddress_.toString();
|
||||
if(IP.substr(0,7)=="::ffff:") {
|
||||
IP = IP.substr(7);
|
||||
}
|
||||
|
||||
State_.locale = FindCountryFromIP()->Get(IP);
|
||||
GWObjects::Device DeviceInfo;
|
||||
auto DeviceExists = StorageService()->GetDevice(SerialNumber_,DeviceInfo);
|
||||
if (Daemon()->AutoProvisioning() && !DeviceExists) {
|
||||
StorageService()->CreateDefaultDevice(SerialNumber_, CapabilitiesString, Firmware,
|
||||
Compatible_, PeerAddress_);
|
||||
} else if (DeviceExists) {
|
||||
StorageService()->UpdateDeviceCapabilities(SerialNumber_, CapabilitiesString,
|
||||
Compatible_);
|
||||
bool Updated = false;
|
||||
if(!Firmware.empty()) {
|
||||
if(Firmware!=DeviceInfo.Firmware) {
|
||||
DeviceInfo.Firmware = Firmware;
|
||||
DeviceInfo.LastFWUpdate = OpenWifi::Now();
|
||||
Updated = true;
|
||||
WebSocketClientNotificationDeviceFirmwareUpdated(SerialNumber_, Firmware);
|
||||
} else if(DeviceInfo.LastFWUpdate==0) {
|
||||
DeviceInfo.LastFWUpdate = OpenWifi::Now();
|
||||
Updated = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(DeviceInfo.locale != State_.locale) {
|
||||
DeviceInfo.locale = State_.locale;
|
||||
Updated = true;
|
||||
}
|
||||
|
||||
if(Compatible_ != DeviceInfo.DeviceType) {
|
||||
DeviceInfo.DeviceType = Compatible_;
|
||||
Updated = true;
|
||||
}
|
||||
|
||||
if(Updated) {
|
||||
StorageService()->UpdateDevice(DeviceInfo);
|
||||
}
|
||||
uint64_t UpgradedUUID=0;
|
||||
LookForUpgrade(UUID,UpgradedUUID);
|
||||
State_.UUID = UpgradedUUID;
|
||||
}
|
||||
|
||||
State_.Compatible = Compatible_;
|
||||
State_.Connected = true;
|
||||
ConnectionCompletionTime_ = std::chrono::high_resolution_clock::now() - ConnectionStart_;
|
||||
State_.connectionCompletionTime = ConnectionCompletionTime_.count();
|
||||
|
||||
if(State_.VerifiedCertificate == GWObjects::VALID_CERTIFICATE) {
|
||||
if (( Utils::SerialNumberMatch(CN_, SerialNumber_, AP_WS_Server()->MismatchDepth())) ||
|
||||
AP_WS_Server()->IsSimSerialNumber(CN_)) {
|
||||
State_.VerifiedCertificate = GWObjects::VERIFIED;
|
||||
poco_information(Logger_, fmt::format("CONNECT({}): Fully validated and authenticated device. Session={} ConnectionCompletion Time={}",
|
||||
CId_,
|
||||
State_.sessionId,
|
||||
State_.connectionCompletionTime ));
|
||||
} else {
|
||||
State_.VerifiedCertificate = GWObjects::MISMATCH_SERIAL;
|
||||
if(AP_WS_Server()->AllowSerialNumberMismatch()) {
|
||||
poco_information(
|
||||
Logger_, fmt::format("CONNECT({}): Serial number mismatch allowed. CN={} Serial={} Session={} ConnectionCompletion Time={}",
|
||||
CId_, CN_, SerialNumber_, State_.sessionId,
|
||||
State_.connectionCompletionTime));
|
||||
} else {
|
||||
poco_information(
|
||||
Logger_, fmt::format("CONNECT({}): Serial number mismatch disallowed. Device rejected. CN={} Serial={} Session={} ConnectionCompletion Time={}",
|
||||
CId_, CN_, SerialNumber_, State_.sessionId,
|
||||
State_.connectionCompletionTime));
|
||||
return EndConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WebSocketClientNotificationDeviceConnected(SerialNumber_);
|
||||
|
||||
// std::cout << "Serial: " << SerialNumber_ << "Session: " << State_.sessionId << std::endl;
|
||||
|
||||
if (KafkaManager()->Enabled()) {
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
ParamsObj->set(uCentralProtocol::CONNECTIONIP, CId_);
|
||||
ParamsObj->set("locale", State_.locale );
|
||||
ParamsObj->set(uCentralProtocol::TIMESTAMP, OpenWifi::Now());
|
||||
[[maybe_unused]] static void SendKafkaFirmwareUpdate(const std::string &SerialNumber, const std::string &OldFirmware, const std::string &NewFirmware) {
|
||||
if(KafkaManager()->Enabled()) {
|
||||
Poco::JSON::Object EventDetails;
|
||||
EventDetails.set("oldFirmware", OldFirmware);
|
||||
EventDetails.set("newFirmware",NewFirmware);
|
||||
Poco::JSON::Object Event;
|
||||
Event.set("type","device.firmware_change");
|
||||
Event.set("timestamp", Utils::Now());
|
||||
Event.set("payload", EventDetails);
|
||||
std::ostringstream OS;
|
||||
Stringify.condense(ParamsObj, OS);
|
||||
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_, OS.str());
|
||||
Event.stringify(OS);
|
||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, SerialNumber, OS.str());
|
||||
}
|
||||
} else {
|
||||
poco_warning(Logger_,fmt::format("INVALID-PROTOCOL({}): Missing one of uuid, firmware, or capabilities", CId_));
|
||||
Errors_++;
|
||||
}
|
||||
}
|
||||
|
||||
void AP_WS_Connection::Process_connect(Poco::JSON::Object::Ptr ParamsObj, const std::string &Serial) {
|
||||
if (ParamsObj->has(uCentralProtocol::UUID) &&
|
||||
ParamsObj->has(uCentralProtocol::FIRMWARE) &&
|
||||
ParamsObj->has(uCentralProtocol::CAPABILITIES)) {
|
||||
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
|
||||
auto Firmware = ParamsObj->get(uCentralProtocol::FIRMWARE).toString();
|
||||
auto Capabilities = ParamsObj->getObject(uCentralProtocol::CAPABILITIES);
|
||||
|
||||
SerialNumber_ = Serial;
|
||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
||||
|
||||
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;
|
||||
State_.Address = Utils::FormatIPv6(WS_->peerAddress().toString());
|
||||
CId_ = SerialNumber_ + "@" + CId_;
|
||||
|
||||
auto IP = PeerAddress_.toString();
|
||||
if(IP.substr(0,7)=="::ffff:") {
|
||||
IP = IP.substr(7);
|
||||
}
|
||||
|
||||
bool RestrictedDevice = false;
|
||||
if(Capabilities->has("restrictions")){
|
||||
RestrictedDevice = true;
|
||||
Poco::JSON::Object::Ptr RestrictionObject = Capabilities->getObject("restrictions");
|
||||
Restrictions_.from_json(RestrictionObject);
|
||||
}
|
||||
|
||||
State_.locale = FindCountryFromIP()->Get(IP);
|
||||
GWObjects::Device DeviceInfo;
|
||||
auto DeviceExists = StorageService()->GetDevice(SerialNumber_,DeviceInfo);
|
||||
if (Daemon()->AutoProvisioning() && !DeviceExists) {
|
||||
StorageService()->CreateDefaultDevice(SerialNumber_, Caps, Firmware, PeerAddress_);
|
||||
} else if (DeviceExists) {
|
||||
StorageService()->UpdateDeviceCapabilities(SerialNumber_, Caps );
|
||||
int Updated{0};
|
||||
if(!Firmware.empty()) {
|
||||
if(Firmware!=DeviceInfo.Firmware) {
|
||||
DeviceFirmwareChangeKafkaEvent KEvent(SerialNumber_, Utils::Now(),DeviceInfo.Firmware, Firmware );
|
||||
DeviceInfo.Firmware = Firmware;
|
||||
DeviceInfo.LastFWUpdate = Utils::Now();
|
||||
++Updated;
|
||||
|
||||
GWWebSocketNotifications::SingleDeviceFirmwareChange_t Notification;
|
||||
Notification.content.serialNumber = SerialNumber_;
|
||||
Notification.content.newFirmware = Firmware;
|
||||
GWWebSocketNotifications::DeviceFirmwareUpdated(Notification);
|
||||
} else if(DeviceInfo.LastFWUpdate==0) {
|
||||
DeviceInfo.LastFWUpdate = Utils::Now();
|
||||
++Updated;
|
||||
}
|
||||
}
|
||||
|
||||
if(DeviceInfo.locale != State_.locale) {
|
||||
DeviceInfo.locale = State_.locale;
|
||||
++Updated;
|
||||
}
|
||||
|
||||
if(Compatible_ != DeviceInfo.DeviceType) {
|
||||
DeviceInfo.DeviceType = Compatible_;
|
||||
++Updated;
|
||||
}
|
||||
|
||||
if(RestrictedDevice != DeviceInfo.restrictedDevice) {
|
||||
DeviceInfo.restrictedDevice = RestrictedDevice;
|
||||
++Updated;
|
||||
}
|
||||
|
||||
if(Restrictions_ != DeviceInfo.restrictionDetails) {
|
||||
DeviceInfo.restrictionDetails = Restrictions_;
|
||||
++Updated;
|
||||
}
|
||||
|
||||
if(Updated) {
|
||||
StorageService()->UpdateDevice(DeviceInfo);
|
||||
}
|
||||
|
||||
uint64_t UpgradedUUID=0;
|
||||
LookForUpgrade(UUID,UpgradedUUID);
|
||||
State_.UUID = UpgradedUUID;
|
||||
}
|
||||
|
||||
State_.Compatible = Compatible_;
|
||||
State_.Connected = true;
|
||||
ConnectionCompletionTime_ = std::chrono::high_resolution_clock::now() - ConnectionStart_;
|
||||
State_.connectionCompletionTime = ConnectionCompletionTime_.count();
|
||||
|
||||
if(State_.VerifiedCertificate == GWObjects::VALID_CERTIFICATE) {
|
||||
if (( Utils::SerialNumberMatch(CN_, SerialNumber_, (int)AP_WS_Server()->MismatchDepth())) ||
|
||||
AP_WS_Server()->IsSimSerialNumber(CN_)) {
|
||||
State_.VerifiedCertificate = GWObjects::VERIFIED;
|
||||
poco_information(Logger_, fmt::format("CONNECT({}): Fully validated and authenticated device. Session={} ConnectionCompletion Time={}",
|
||||
CId_,
|
||||
State_.sessionId,
|
||||
State_.connectionCompletionTime ));
|
||||
} else {
|
||||
State_.VerifiedCertificate = GWObjects::MISMATCH_SERIAL;
|
||||
if(AP_WS_Server()->AllowSerialNumberMismatch()) {
|
||||
poco_information(
|
||||
Logger_, fmt::format("CONNECT({}): Serial number mismatch allowed. CN={} Serial={} Session={} ConnectionCompletion Time={}",
|
||||
CId_, CN_, SerialNumber_, State_.sessionId,
|
||||
State_.connectionCompletionTime));
|
||||
} else {
|
||||
poco_information(
|
||||
Logger_, fmt::format("CONNECT({}): Serial number mismatch disallowed. Device rejected. CN={} Serial={} Session={}",
|
||||
CId_, CN_, SerialNumber_, State_.sessionId));
|
||||
return EndConnection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GWWebSocketNotifications::SingleDevice_t Notification;
|
||||
Notification.content.serialNumber = SerialNumber_;
|
||||
GWWebSocketNotifications::DeviceConnected(Notification);
|
||||
|
||||
// std::cout << "Serial: " << SerialNumber_ << "Session: " << State_.sessionId << std::endl;
|
||||
|
||||
if (KafkaManager()->Enabled()) {
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
|
||||
ParamsObj->set(uCentralProtocol::CONNECTIONIP, CId_);
|
||||
ParamsObj->set("locale", State_.locale );
|
||||
ParamsObj->set(uCentralProtocol::TIMESTAMP, Utils::Now());
|
||||
std::ostringstream OS;
|
||||
Stringify.condense(ParamsObj, OS);
|
||||
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_, OS.str());
|
||||
}
|
||||
} else {
|
||||
poco_warning(Logger_,fmt::format("INVALID-PROTOCOL({}): Missing one of uuid, firmware, or capabilities", CId_));
|
||||
Errors_++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,6 +5,9 @@
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_crashlog(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (ParamsObj->has(uCentralProtocol::UUID) && ParamsObj->has(uCentralProtocol::LOGLINES)) {
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void AP_WS_Connection::Process_deviceupdate(Poco::JSON::Object::Ptr ParamsObj, std::string &Serial) {
|
||||
|
||||
32
src/AP_WS_Process_event.cpp
Normal file
32
src/AP_WS_Process_event.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// Created by stephane bourque on 2023-01-22.
|
||||
//
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
#include "fmt/format.h"
|
||||
#include "framework/KafkaManager.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_event(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
poco_trace(Logger_, fmt::format("Event data received for {}", SerialNumber_));
|
||||
|
||||
if (ParamsObj->has(uCentralProtocol::SERIAL) && ParamsObj->has(uCentralProtocol::DATA)) {
|
||||
if (KafkaManager()->Enabled()) {
|
||||
auto Data = ParamsObj->get(uCentralProtocol::DATA);
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
std::ostringstream OS;
|
||||
Stringify.condense(ParamsObj, OS);
|
||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, SerialNumber_, OS.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,67 +5,70 @@
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "framework/utils.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void AP_WS_Connection::Process_healthcheck(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
poco_warning(Logger_, fmt::format(
|
||||
"INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
if (ParamsObj->has(uCentralProtocol::UUID) && ParamsObj->has(uCentralProtocol::SANITY) &&
|
||||
ParamsObj->has(uCentralProtocol::DATA)) {
|
||||
uint64_t UUID = ParamsObj->get(uCentralProtocol::UUID);
|
||||
auto Sanity = ParamsObj->get(uCentralProtocol::SANITY);
|
||||
auto CheckData = ParamsObj->get(uCentralProtocol::DATA).toString();
|
||||
if (CheckData.empty())
|
||||
CheckData = uCentralProtocol::EMPTY_JSON_DOC;
|
||||
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 = OpenWifi::Now();
|
||||
Check.UUID = UUID;
|
||||
Check.Data = CheckData;
|
||||
Check.Sanity = Sanity;
|
||||
|
||||
StorageService()->AddHealthCheckData(Check);
|
||||
|
||||
if (!request_uuid.empty()) {
|
||||
StorageService()->SetCommandResult(request_uuid, CheckData);
|
||||
}
|
||||
|
||||
LastHealthcheck_ = Check;
|
||||
if (KafkaManager()->Enabled()) {
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
std::ostringstream OS;
|
||||
ParamsObj->set("timestamp", OpenWifi::Now());
|
||||
Stringify.condense(ParamsObj, OS);
|
||||
KafkaManager()->PostMessage(KafkaTopics::HEALTHCHECK, SerialNumber_, OS.str());
|
||||
}
|
||||
} else {
|
||||
poco_warning(Logger_, fmt::format("HEALTHCHECK({}): Missing parameter", CId_));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -5,6 +5,9 @@
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_log(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
|
||||
@@ -6,6 +6,11 @@
|
||||
#include "StorageService.h"
|
||||
#include "CommandManager.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "fmt/format.h"
|
||||
#include "framework/ow_constants.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_recovery(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (ParamsObj->has(uCentralProtocol::SERIAL) &&
|
||||
@@ -36,7 +41,7 @@ namespace OpenWifi {
|
||||
if (ParamsObj->get(uCentralProtocol::REBOOT).toString() == "true") {
|
||||
GWObjects::CommandDetails Cmd;
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = MicroService::CreateUUID();
|
||||
Cmd.UUID = MicroServiceCreateUUID();
|
||||
Cmd.SubmittedBy = uCentralProtocol::SUBMITTED_BY_SYSTEM;
|
||||
Cmd.Status = uCentralProtocol::PENDING;
|
||||
Cmd.Command = uCentralProtocol::REBOOT;
|
||||
@@ -47,7 +52,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(), APCommands::Commands::reboot, SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent, false);
|
||||
StorageService()->AddCommand(SerialNumber_, Cmd, Storage::CommandExecutionType::COMMAND_EXECUTED);
|
||||
poco_information(Logger_, fmt::format("RECOVERY({}): Recovery mode received, need for a reboot.", CId_));
|
||||
} else {
|
||||
|
||||
@@ -4,9 +4,15 @@
|
||||
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/WebSocketClientNotifications.h"
|
||||
#include "StateUtils.h"
|
||||
|
||||
#include "UI_GW_WebSocketNotifications.h"
|
||||
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_state(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
@@ -35,18 +41,20 @@ namespace OpenWifi {
|
||||
uint64_t UpgradedUUID;
|
||||
LookForUpgrade(UUID,UpgradedUUID);
|
||||
State_.UUID = UpgradedUUID;
|
||||
LastStats_ = StateStr;
|
||||
SetLastStats(StateStr);
|
||||
|
||||
GWObjects::Statistics Stats{
|
||||
.SerialNumber = SerialNumber_, .UUID = UUID, .Data = StateStr};
|
||||
Stats.Recorded = OpenWifi::Now();
|
||||
Stats.Recorded = Utils::Now();
|
||||
StorageService()->AddStatisticsData(Stats);
|
||||
if (!request_uuid.empty()) {
|
||||
StorageService()->SetCommandResult(request_uuid, StateStr);
|
||||
}
|
||||
|
||||
StateUtils::ComputeAssociations(StateObj, State_.Associations_2G,
|
||||
State_.Associations_5G);
|
||||
State_.Associations_5G,
|
||||
State_.Associations_6G
|
||||
);
|
||||
|
||||
if (KafkaManager()->Enabled()) {
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
@@ -55,10 +63,9 @@ namespace OpenWifi {
|
||||
KafkaManager()->PostMessage(KafkaTopics::STATE, SerialNumber_, OS.str());
|
||||
}
|
||||
|
||||
WebSocketNotification<WebNotificationSingleDevice> N;
|
||||
GWWebSocketNotifications::SingleDevice_t N;
|
||||
N.content.serialNumber = SerialNumber_;
|
||||
N.type = "device_statistics";
|
||||
WebSocketClientServer()->SendNotification(N);
|
||||
GWWebSocketNotifications::DeviceStatistics(N);
|
||||
|
||||
} else {
|
||||
poco_warning(Logger_, fmt::format("STATE({}): Invalid request. Missing serial, uuid, or state", CId_));
|
||||
|
||||
@@ -6,6 +6,10 @@
|
||||
#include "TelemetryStream.h"
|
||||
#include "CommandManager.h"
|
||||
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "framework/utils.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_telemetry(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
@@ -14,21 +18,27 @@ namespace OpenWifi {
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
if (TelemetryReporting_) {
|
||||
poco_trace(Logger_,fmt::format("Telemetry data received for {}", SerialNumber_));
|
||||
if (TelemetryReporting_ || ParamsObj->has("adhoc")) {
|
||||
if (ParamsObj->has("data")) {
|
||||
auto Payload = ParamsObj->get("data").extract<Poco::JSON::Object::Ptr>();
|
||||
Payload->set("timestamp", OpenWifi::Now());
|
||||
Payload->set("timestamp", Utils::Now());
|
||||
std::ostringstream SS;
|
||||
Payload->stringify(SS);
|
||||
auto now=OpenWifi::Now();
|
||||
auto now=Utils::Now();
|
||||
if(ParamsObj->has("adhoc")) {
|
||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_TELEMETRY, SerialNumber_,
|
||||
SS.str());
|
||||
return;
|
||||
}
|
||||
if (TelemetryWebSocketRefCount_) {
|
||||
if(now<TelemetryWebSocketTimer_) {
|
||||
// std::cout << SerialNumber_ << ": Updating WebSocket telemetry" << std::endl;
|
||||
TelemetryWebSocketPackets_++;
|
||||
State_.websocketPackets = TelemetryWebSocketPackets_;
|
||||
TelemetryStream()->UpdateEndPoint(SerialNumberInt_, SS.str());
|
||||
TelemetryStream()->NotifyEndPoint(SerialNumberInt_, SS.str());
|
||||
} else {
|
||||
StopWebSocketTelemetry(CommandManager()->NextRPCId());
|
||||
StopWebSocketTelemetry(CommandManager()->Next_RPC_ID());
|
||||
}
|
||||
}
|
||||
if (TelemetryKafkaRefCount_) {
|
||||
@@ -39,7 +49,7 @@ namespace OpenWifi {
|
||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_TELEMETRY, SerialNumber_,
|
||||
SS.str());
|
||||
} else {
|
||||
StopKafkaTelemetry(CommandManager()->NextRPCId());
|
||||
StopKafkaTelemetry(CommandManager()->Next_RPC_ID());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -48,7 +58,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());
|
||||
}
|
||||
}
|
||||
}
|
||||
32
src/AP_WS_Process_wifiscan.cpp
Normal file
32
src/AP_WS_Process_wifiscan.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
//
|
||||
// Created by stephane bourque on 2023-01-22.
|
||||
//
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
#include "fmt/format.h"
|
||||
#include "framework/KafkaManager.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void AP_WS_Connection::Process_wifiscan(Poco::JSON::Object::Ptr ParamsObj) {
|
||||
if (!State_.Connected) {
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("INVALID-PROTOCOL({}): Device '{}' is not following protocol", CId_, CN_));
|
||||
Errors_++;
|
||||
return;
|
||||
}
|
||||
poco_trace(Logger_, fmt::format("Wifiscan data received for {}", SerialNumber_));
|
||||
|
||||
if (ParamsObj->has(uCentralProtocol::SERIAL) && ParamsObj->has(uCentralProtocol::DATA)) {
|
||||
if (KafkaManager()->Enabled()) {
|
||||
auto Data = ParamsObj->get(uCentralProtocol::DATA);
|
||||
Poco::JSON::Stringifier Stringify;
|
||||
std::ostringstream OS;
|
||||
Stringify.condense(ParamsObj, OS);
|
||||
KafkaManager()->PostMessage(KafkaTopics::WIFISCAN, SerialNumber_, OS.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,8 @@
|
||||
#include "Poco/Net/SocketAcceptor.h"
|
||||
#include "Poco/Environment.h"
|
||||
|
||||
#include "framework/utils.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class AP_WS_ReactorThreadPool {
|
||||
public:
|
||||
|
||||
@@ -7,14 +7,18 @@
|
||||
//
|
||||
|
||||
#include "Poco/Net/HTTPHeaderStream.h"
|
||||
#include "Poco/JSON/Array.h"
|
||||
#include "Poco/Net/Context.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
|
||||
#include "AP_WS_Server.h"
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "ConfigurationCache.h"
|
||||
#include "TelemetryStream.h"
|
||||
#include "framework/WebSocketClientNotifications.h"
|
||||
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/utils.h"
|
||||
#include "UI_GW_WebSocketNotifications.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -40,8 +44,8 @@ namespace OpenWifi {
|
||||
|
||||
int AP_WS_Server::Start() {
|
||||
|
||||
AllowSerialNumberMismatch_ = MicroService::instance().ConfigGetBool("openwifi.certificates.allowmismatch",true);
|
||||
MismatchDepth_ = MicroService::instance().ConfigGetInt("openwifi.certificates.mismatchdepth",2);
|
||||
AllowSerialNumberMismatch_ = MicroServiceConfigGetBool("openwifi.certificates.allowmismatch",true);
|
||||
MismatchDepth_ = MicroServiceConfigGetInt("openwifi.certificates.mismatchdepth",2);
|
||||
|
||||
Reactor_pool_ = std::make_unique<AP_WS_ReactorThreadPool>();
|
||||
Reactor_pool_->Start();
|
||||
@@ -72,11 +76,11 @@ namespace OpenWifi {
|
||||
|
||||
auto Context = Poco::AutoPtr<Poco::Net::Context>(new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
|
||||
|
||||
if(!Svr.KeyFilePassword().empty()) {
|
||||
/* if(!Svr.KeyFilePassword().empty()) {
|
||||
auto PassphraseHandler = Poco::SharedPtr<MyPrivateKeyPassphraseHandler>( new MyPrivateKeyPassphraseHandler(Svr.KeyFilePassword(),Logger()));
|
||||
Poco::Net::SSLManager::instance().initializeServer(PassphraseHandler, nullptr,Context);
|
||||
}
|
||||
|
||||
*/
|
||||
Poco::Crypto::X509Certificate Cert(Svr.CertFile());
|
||||
Poco::Crypto::X509Certificate Root(Svr.RootCA());
|
||||
|
||||
@@ -128,7 +132,7 @@ namespace OpenWifi {
|
||||
|
||||
ReactorThread_.start(Reactor_);
|
||||
|
||||
auto ProvString = MicroService::instance().ConfigGetString("autoprovisioning.process","default");
|
||||
auto ProvString = MicroServiceConfigGetString("autoprovisioning.process","default");
|
||||
if(ProvString!="default") {
|
||||
auto Tokens = Poco::StringTokenizer(ProvString, ",");
|
||||
for (const auto &i : Tokens) {
|
||||
@@ -141,48 +145,42 @@ namespace OpenWifi {
|
||||
UseDefaultConfig_ = true;
|
||||
}
|
||||
|
||||
SimulatorId_ = MicroService::instance().ConfigGetString("simulatorid","");
|
||||
SimulatorId_ = MicroServiceConfigGetString("simulatorid","");
|
||||
SimulatorEnabled_ = !SimulatorId_.empty();
|
||||
Utils::SetThreadName(ReactorThread_,"dev:react:head");
|
||||
|
||||
GarbageCollectorCallback_ = std::make_unique<Poco::TimerCallback<AP_WS_Server>>(*this,&AP_WS_Server::onGarbageCollecting);
|
||||
Timer_.setStartInterval(10 * 1000);
|
||||
Timer_.setPeriodicInterval(5 * 1000); // every minute
|
||||
Timer_.start(*GarbageCollectorCallback_, MicroService::instance().TimerPool());
|
||||
Timer_.start(*GarbageCollectorCallback_, MicroServiceTimerPool());
|
||||
|
||||
Running_ = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
static std::uint64_t last_log = OpenWifi::Now();
|
||||
static uint64_t last_log = Utils::Now();
|
||||
|
||||
NumberOfConnectedDevices_ = 0;
|
||||
NumberOfConnectingDevices_ = 0;
|
||||
AverageDeviceConnectionTime_ = 0;
|
||||
std::uint64_t total_connected_time=0;
|
||||
uint64_t total_connected_time=0;
|
||||
|
||||
auto now = OpenWifi::Now();
|
||||
for (auto connection=SerialNumbers_.begin(); connection!=SerialNumbers_.end();) {
|
||||
|
||||
if(connection->second.second== nullptr) {
|
||||
connection++;
|
||||
auto now = Utils::Now();
|
||||
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++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,9 +191,12 @@ namespace OpenWifi {
|
||||
fmt::format("Active AP connections: {} Connecting: {} Average connection time: {} seconds",
|
||||
NumberOfConnectedDevices_, NumberOfConnectingDevices_, AverageDeviceConnectionTime_));
|
||||
}
|
||||
WebSocketClientNotificationNumberOfConnections(NumberOfConnectedDevices_,
|
||||
AverageDeviceConnectionTime_,
|
||||
NumberOfConnectingDevices_);
|
||||
|
||||
GWWebSocketNotifications::NumberOfConnection_t Notification;
|
||||
Notification.content.numberOfConnectingDevices = NumberOfConnectingDevices_;
|
||||
Notification.content.numberOfDevices = NumberOfConnectedDevices_;
|
||||
Notification.content.averageConnectedTime = AverageDeviceConnectionTime_;
|
||||
GWWebSocketNotifications::NumberOfConnections(Notification);
|
||||
}
|
||||
|
||||
void AP_WS_Server::Stop() {
|
||||
@@ -213,37 +214,50 @@ namespace OpenWifi {
|
||||
poco_information(Logger(),"Stopped...");
|
||||
}
|
||||
|
||||
bool AP_WS_Server::GetStatistics(std::uint64_t SerialNumber, std::string &Statistics) const {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
|
||||
return false;
|
||||
Statistics = Device->second.second->LastStats_;
|
||||
bool AP_WS_Server::GetStatistics(uint64_t SerialNumber, std::string &Statistics) const {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == SerialNumbers_.end() || Device->second.second == nullptr) {
|
||||
return false;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->GetLastStats(Statistics);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool AP_WS_Server::GetState(uint64_t SerialNumber, GWObjects::ConnectionState & State) const {
|
||||
std::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(std::uint64_t connection_id, uint64_t SerialNumber) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
void AP_WS_Server::SetSessionDetails(uint64_t connection_id, uint64_t SerialNumber) {
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
|
||||
auto Conn = Sessions_.find(connection_id);
|
||||
if(Conn == end(Sessions_))
|
||||
@@ -252,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(std::uint64_t session_id, std::uint64_t serial_number) {
|
||||
std::unique_lock G(LocalMutex_);
|
||||
bool AP_WS_Server::EndSession(uint64_t session_id, uint64_t serial_number) {
|
||||
std::lock_guard G(WSServerMutex_);
|
||||
|
||||
auto Session = Sessions_.find(session_id);
|
||||
if(Session==end(Sessions_))
|
||||
return false;
|
||||
|
||||
Garbage_.push_back(Session->second.first);
|
||||
Garbage_.push_back(Session->second);
|
||||
|
||||
auto Device = SerialNumbers_.find(serial_number);
|
||||
if (Device == end(SerialNumbers_)) {
|
||||
@@ -282,64 +296,102 @@ 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, GWObjects::DeviceRestrictions & Restrictions) const {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||
return false;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->GetRestrictions(Restrictions);
|
||||
return DevicePtr->State_.Connected;
|
||||
}
|
||||
|
||||
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: " << (std::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)));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AP_WS_Server::StopWebSocketTelemetry(std::uint64_t RPCID, uint64_t SerialNumber) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
void AP_WS_Server::StopWebSocketTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_) || Device->second.second==nullptr)
|
||||
return;
|
||||
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(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_) || Device->second.second==nullptr)
|
||||
return;
|
||||
Device->second.second->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime);
|
||||
void AP_WS_Server::SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime, const std::vector<std::string> & TelemetryTypes) {
|
||||
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, TelemetryTypes);
|
||||
}
|
||||
|
||||
void AP_WS_Server::SetKafkaTelemetryReporting(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
|
||||
return;
|
||||
Device->second.second->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime);
|
||||
void AP_WS_Server::SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime, const std::vector<std::string> & TelemetryTypes) {
|
||||
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, TelemetryTypes);
|
||||
}
|
||||
|
||||
void AP_WS_Server::StopKafkaTelemetry(std::uint64_t RPCID, uint64_t SerialNumber) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
|
||||
return;
|
||||
Device->second.second->StopKafkaTelemetry(RPCID);
|
||||
void AP_WS_Server::StopKafkaTelemetry(uint64_t RPCID, uint64_t SerialNumber) {
|
||||
std::shared_ptr<AP_WS_Connection> DevicePtr;
|
||||
{
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if (Device == end(SerialNumbers_) || Device->second.second == nullptr) {
|
||||
return;
|
||||
}
|
||||
DevicePtr = Device->second.second;
|
||||
}
|
||||
DevicePtr->StopKafkaTelemetry(RPCID);
|
||||
}
|
||||
|
||||
void AP_WS_Server::GetTelemetryParameters(uint64_t SerialNumber , bool & TelemetryRunning,
|
||||
@@ -350,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));
|
||||
}
|
||||
@@ -380,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));
|
||||
}
|
||||
@@ -394,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));
|
||||
}
|
||||
|
||||
@@ -13,22 +13,27 @@
|
||||
#include <array>
|
||||
#include <ctime>
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
#include "Poco/AutoPtr.h"
|
||||
#include "Poco/Net/SocketReactor.h"
|
||||
#include "Poco/Net/ParallelSocketAcceptor.h"
|
||||
#include "Poco/Net/SocketAcceptor.h"
|
||||
#include "Poco/Timer.h"
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||
#include "Poco/Net/HTTPServer.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
|
||||
#include "AP_WS_Connection.h"
|
||||
#include "AP_WS_ReactorPool.h"
|
||||
|
||||
#include "framework/utils.h"
|
||||
#include "framework/SubSystemServer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class AP_WS_RequestHandler : public Poco::Net::HTTPRequestHandler {
|
||||
public:
|
||||
explicit AP_WS_RequestHandler(Poco::Logger &L, std::uint64_t id)
|
||||
explicit AP_WS_RequestHandler(Poco::Logger &L, uint64_t id)
|
||||
: Logger_(L),
|
||||
id_(id){
|
||||
};
|
||||
@@ -37,7 +42,7 @@ namespace OpenWifi {
|
||||
Poco::Net::HTTPServerResponse &response) override;
|
||||
private:
|
||||
Poco::Logger &Logger_;
|
||||
std::uint64_t id_=0;
|
||||
uint64_t id_=0;
|
||||
};
|
||||
|
||||
class AP_WS_RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
|
||||
@@ -58,7 +63,7 @@ namespace OpenWifi {
|
||||
}
|
||||
private:
|
||||
Poco::Logger &Logger_;
|
||||
inline static std::uint64_t id_=1;
|
||||
inline static uint64_t id_=1;
|
||||
};
|
||||
|
||||
class AP_WS_Server : public SubSystemServer {
|
||||
@@ -90,7 +95,7 @@ namespace OpenWifi {
|
||||
return AllowSerialNumberMismatch_;
|
||||
}
|
||||
|
||||
inline std::uint64_t MismatchDepth() const {
|
||||
inline uint64_t MismatchDepth() const {
|
||||
return MismatchDepth_;
|
||||
}
|
||||
|
||||
@@ -100,54 +105,55 @@ namespace OpenWifi {
|
||||
[[nodiscard]] inline Poco::Net::SocketReactor & NextReactor() { return Reactor_pool_->NextReactor(); }
|
||||
[[nodiscard]] inline bool Running() const { return Running_; }
|
||||
|
||||
inline void AddConnection(std::uint64_t session_id, std::shared_ptr<AP_WS_Connection> Connection ) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
Sessions_[session_id] = std::make_pair(std::move(Connection),false);
|
||||
inline void AddConnection(uint64_t session_id, std::shared_ptr<AP_WS_Connection> Connection ) {
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
Sessions_[session_id] = std::move(Connection);
|
||||
}
|
||||
|
||||
inline std::shared_ptr<AP_WS_Connection> FindConnection(std::uint64_t session_id) const {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
inline std::shared_ptr<AP_WS_Connection> FindConnection(uint64_t session_id) const {
|
||||
std::lock_guard Lock(WSServerMutex_);
|
||||
|
||||
auto Connection = Sessions_.find(session_id);
|
||||
if(Connection!=end(Sessions_))
|
||||
return Connection->second.first;
|
||||
return Connection->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline bool GetStatistics(const std::string &SerialNumber, std::string & Statistics) const {
|
||||
return GetStatistics(Utils::SerialNumberToInt(SerialNumber),Statistics);
|
||||
}
|
||||
bool GetStatistics(std::uint64_t SerialNumber, std::string & Statistics) const ;
|
||||
bool GetStatistics(uint64_t SerialNumber, std::string & Statistics) const ;
|
||||
|
||||
inline bool GetState(const std::string & SerialNumber, GWObjects::ConnectionState & State) const {
|
||||
return GetState(Utils::SerialNumberToInt(SerialNumber), State);
|
||||
}
|
||||
bool GetState(std::uint64_t SerialNumber, GWObjects::ConnectionState & State) const;
|
||||
bool GetState(uint64_t SerialNumber, GWObjects::ConnectionState & State) const;
|
||||
|
||||
inline bool GetHealthcheck(const std::string &SerialNumber, GWObjects::HealthCheck & CheckData) const {
|
||||
return GetHealthcheck(Utils::SerialNumberToInt(SerialNumber), CheckData);
|
||||
}
|
||||
bool GetHealthcheck(std::uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const ;
|
||||
bool GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const ;
|
||||
|
||||
bool Connected(uint64_t SerialNumber, GWObjects::DeviceRestrictions & Restrictions) const ;
|
||||
bool Connected(uint64_t SerialNumber) const ;
|
||||
|
||||
inline bool SendFrame(const std::string & SerialNumber, const std::string & Payload) const {
|
||||
return SendFrame(Utils::SerialNumberToInt(SerialNumber), Payload);
|
||||
}
|
||||
|
||||
bool SendFrame(std::uint64_t SerialNumber, const std::string & Payload) const ;
|
||||
bool SendFrame(uint64_t SerialNumber, const std::string & Payload) const ;
|
||||
|
||||
bool SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
|
||||
void SetSessionDetails(std::uint64_t connection_id, uint64_t SerialNumber);
|
||||
bool EndSession(std::uint64_t connection_id, std::uint64_t serial_number);
|
||||
void SetSessionDetails(uint64_t connection_id, uint64_t SerialNumber);
|
||||
bool EndSession(uint64_t connection_id, uint64_t serial_number);
|
||||
|
||||
void SetWebSocketTelemetryReporting(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime);
|
||||
void StopWebSocketTelemetry(std::uint64_t RPCID, uint64_t SerialNumber);
|
||||
void SetKafkaTelemetryReporting(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime);
|
||||
void StopKafkaTelemetry(std::uint64_t RPCID, uint64_t SerialNumber);
|
||||
void SetWebSocketTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime, const std::vector<std::string> & TelemetryTypes);
|
||||
void StopWebSocketTelemetry(uint64_t RPCID, uint64_t SerialNumber);
|
||||
void SetKafkaTelemetryReporting(uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime, const std::vector<std::string> & TelemetryTypes);
|
||||
void StopKafkaTelemetry(uint64_t RPCID, uint64_t SerialNumber);
|
||||
void GetTelemetryParameters(uint64_t SerialNumber , bool & TelemetryRunning,
|
||||
uint64_t & TelemetryInterval,
|
||||
uint64_t & TelemetryWebSocketTimer,
|
||||
@@ -159,14 +165,14 @@ namespace OpenWifi {
|
||||
|
||||
void onGarbageCollecting(Poco::Timer & timer);
|
||||
|
||||
inline void AverageDeviceStatistics( std::uint64_t & Connections, std::uint64_t & AverageConnectionTime, std::uint64_t & NumberOfConnectingDevices) const {
|
||||
inline void AverageDeviceStatistics( uint64_t & Connections, uint64_t & AverageConnectionTime, uint64_t & NumberOfConnectingDevices) const {
|
||||
Connections = NumberOfConnectedDevices_;
|
||||
AverageConnectionTime = AverageDeviceConnectionTime_;
|
||||
NumberOfConnectingDevices = NumberOfConnectingDevices_;
|
||||
}
|
||||
|
||||
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_;
|
||||
@@ -178,8 +184,9 @@ namespace OpenWifi {
|
||||
bool SimulatorEnabled_=false;
|
||||
std::unique_ptr<AP_WS_ReactorThreadPool> Reactor_pool_;
|
||||
std::atomic_bool Running_=false;
|
||||
std::map<std::uint64_t, std::pair<std::shared_ptr<AP_WS_Connection>,bool>> Sessions_;
|
||||
std::map<std::uint64_t, std::pair<std::uint64_t,std::shared_ptr<AP_WS_Connection>>> SerialNumbers_;
|
||||
// std::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;
|
||||
|
||||
|
||||
@@ -4,9 +4,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <fstream>
|
||||
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "CentralConfig.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
const std::string PlatformCacheFileName{"/plat_cache.json"};
|
||||
@@ -22,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;
|
||||
@@ -42,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();
|
||||
}
|
||||
}
|
||||
@@ -92,8 +100,8 @@ namespace OpenWifi {
|
||||
std::atomic_bool CapabilitiesLoaded_=false;
|
||||
std::map<std::string,std::string> Platforms_;
|
||||
CapabilitiesCache_t Capabilities_;
|
||||
std::string PlatformCacheFileName_{ MicroService::instance().DataDir()+PlatformCacheFileName };
|
||||
std::string CapabilitiesCacheFileName_{ MicroService::instance().DataDir()+CapabilitiesCacheFileName };
|
||||
std::string PlatformCacheFileName_{ MicroServiceDataDirectory()+PlatformCacheFileName };
|
||||
std::string CapabilitiesCacheFileName_{ MicroServiceDataDirectory()+CapabilitiesCacheFileName };
|
||||
|
||||
inline void LoadPlatforms() {
|
||||
try {
|
||||
@@ -145,4 +153,7 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline auto CapabilitiesCache() { return CapabilitiesCache::instance(); };
|
||||
|
||||
}
|
||||
@@ -7,8 +7,6 @@
|
||||
//
|
||||
#include <fstream>
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/File.h"
|
||||
@@ -69,11 +67,11 @@ R"lit(
|
||||
"ipv4": {
|
||||
"addressing": "static",
|
||||
"dhcp": {
|
||||
"lease-count": 10000,
|
||||
"lease-count": 100,
|
||||
"lease-first": 10,
|
||||
"lease-time": "6h"
|
||||
},
|
||||
"subnet": "192.168.1.1/16"
|
||||
"subnet": "192.168.1.1/24"
|
||||
},
|
||||
"name": "LAN",
|
||||
"role": "downstream",
|
||||
@@ -230,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,
|
||||
@@ -244,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 )
|
||||
{
|
||||
@@ -272,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();
|
||||
};
|
||||
|
||||
@@ -8,14 +8,16 @@
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
#include "CommandManager.h"
|
||||
#include "AP_WS_Server.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/ow_constants.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -29,39 +31,87 @@ 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);
|
||||
bool NoReply = false;
|
||||
|
||||
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);
|
||||
std::shared_ptr<promise_type_t> TmpRpcEntry;
|
||||
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() -
|
||||
RPC->second.submitted;
|
||||
StorageService()->CommandCompleted(RPC->second.UUID, Payload,
|
||||
rpc_execution_time, true);
|
||||
if (RPC->second.rpc_entry) {
|
||||
RPC->second.rpc_entry->set_value(Payload);
|
||||
}
|
||||
|
||||
poco_debug(Logger(),
|
||||
fmt::format("({}): Received RPC answer {}. Command={}",
|
||||
SerialNumber, ID, RPC->second.Command));
|
||||
OutStandingRequests_.erase(ID);
|
||||
SerialNumberStr, ID, APCommands::to_string(RPC->second.Command)));
|
||||
if(RPC->second.Command==APCommands::Commands::script) {
|
||||
if(RPC->second.State==2) {
|
||||
// look at the payload to see if we should continue or not...
|
||||
if (RPC->second.rpc_entry) {
|
||||
TmpRpcEntry = RPC->second.rpc_entry;
|
||||
}
|
||||
|
||||
// Payload->stringify(std::cout);
|
||||
|
||||
if (Payload->has("result")) {
|
||||
auto Result = Payload->getObject("result");
|
||||
if (Result->has("status")) {
|
||||
auto Status = Result->getObject("status");
|
||||
// Status->stringify(std::cout);
|
||||
std::uint64_t Error = Status->get("error");
|
||||
if(Error==0) {
|
||||
StorageService()->CommandCompleted(RPC->second.UUID, Payload,
|
||||
rpc_execution_time, true);
|
||||
RPC->second.State = 1 ;
|
||||
} else {
|
||||
StorageService()->CommandCompleted(RPC->second.UUID, Payload,
|
||||
rpc_execution_time, true);
|
||||
std::string ErrorTxt = Status->get("result");
|
||||
StorageService()->CancelWaitFile(RPC->second.UUID, ErrorTxt);
|
||||
RPC->second.State = 0 ;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// std::cout << "Bad payload on command result" << std::endl;
|
||||
RPC->second.State=0;
|
||||
}
|
||||
} else {
|
||||
// std::cout << "Completing script 2 phase commit." << std::endl;
|
||||
StorageService()->CommandCompleted(RPC->second.UUID, Payload,
|
||||
rpc_execution_time, true);
|
||||
NoReply = true;
|
||||
RPC->second.State=0;
|
||||
}
|
||||
} else {
|
||||
if(RPC->second.Command!=APCommands::Commands::telemetry) {
|
||||
StorageService()->CommandCompleted(
|
||||
RPC->second.UUID, Payload, rpc_execution_time, true);
|
||||
}
|
||||
if (RPC->second.rpc_entry) {
|
||||
TmpRpcEntry = RPC->second.rpc_entry;
|
||||
}
|
||||
RPC->second.State = 0 ;
|
||||
}
|
||||
|
||||
if(RPC->second.State==0) {
|
||||
OutStandingRequests_.erase(ID);
|
||||
}
|
||||
}
|
||||
if(!NoReply && TmpRpcEntry != nullptr)
|
||||
TmpRpcEntry->set_value(Payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,12 +133,12 @@ namespace OpenWifi {
|
||||
JanitorCallback_ = std::make_unique<Poco::TimerCallback<CommandManager>>(*this,&CommandManager::onJanitorTimer);
|
||||
JanitorTimer_.setStartInterval( 10000 );
|
||||
JanitorTimer_.setPeriodicInterval(10 * 60 * 1000); // 1 hours
|
||||
JanitorTimer_.start(*JanitorCallback_, MicroService::instance().TimerPool());
|
||||
JanitorTimer_.start(*JanitorCallback_, MicroServiceTimerPool());
|
||||
|
||||
CommandRunnerCallback_ = std::make_unique<Poco::TimerCallback<CommandManager>>(*this,&CommandManager::onCommandRunnerTimer);
|
||||
CommandRunnerTimer_.setStartInterval( 10000 );
|
||||
CommandRunnerTimer_.setPeriodicInterval(30 * 1000); // 1 hours
|
||||
CommandRunnerTimer_.start(*CommandRunnerCallback_, MicroService::instance().TimerPool());
|
||||
CommandRunnerTimer_.start(*CommandRunnerCallback_, MicroServiceTimerPool());
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -119,7 +169,7 @@ namespace OpenWifi {
|
||||
if(delta > 10min) {
|
||||
MyLogger.debug(fmt::format("{}: Command={} for {} Timed out.",
|
||||
request->second.UUID,
|
||||
request->second.Command,
|
||||
APCommands::to_string(request->second.Command),
|
||||
Utils::IntToSerialNumber(request->second.SerialNumber)));
|
||||
request = OutStandingRequests_.erase(request);
|
||||
} else {
|
||||
@@ -168,7 +218,7 @@ namespace OpenWifi {
|
||||
if(IsCommandRunning(Cmd.UUID))
|
||||
continue;
|
||||
|
||||
auto now = OpenWifi::Now();
|
||||
auto now = Utils::Now();
|
||||
// 2 hour timeout for commands
|
||||
if ((now - Cmd.Submitted) > (1 * 60 * 60)) {
|
||||
poco_information(
|
||||
@@ -188,14 +238,15 @@ namespace OpenWifi {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string ExecutingCommand, ExecutingUUID;
|
||||
std::string ExecutingUUID;
|
||||
APCommands::Commands ExecutingCommand=APCommands::Commands::unknown;
|
||||
if (CommandRunningForDevice(Utils::SerialNumberToInt(Cmd.SerialNumber),
|
||||
ExecutingUUID, ExecutingCommand)) {
|
||||
poco_trace(
|
||||
MyLogger,
|
||||
fmt::format(
|
||||
"{}: Serial={} Command={} Device is already busy with command {} (Command={})."
|
||||
, Cmd.UUID, Cmd.SerialNumber, Cmd.Command,ExecutingUUID, ExecutingCommand));
|
||||
, Cmd.UUID, Cmd.SerialNumber, Cmd.Command, ExecutingUUID, APCommands::to_string(ExecutingCommand)));
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -204,7 +255,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(), APCommands::to_apcommand(Cmd.Command.c_str()), Cmd.SerialNumber, Cmd.Command,
|
||||
*Params, Cmd.UUID, Sent);
|
||||
if (Sent) {
|
||||
StorageService()->SetCommandExecuted(Cmd.UUID);
|
||||
@@ -239,14 +290,16 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
std::shared_ptr<CommandManager::promise_type_t> CommandManager::PostCommand(
|
||||
uint64_t RPCID,
|
||||
uint64_t RPC_ID,
|
||||
APCommands::Commands Command,
|
||||
const std::string &SerialNumber,
|
||||
const std::string &Command,
|
||||
const std::string &CommandStr,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
bool oneway_rpc,
|
||||
bool disk_only,
|
||||
bool & Sent) {
|
||||
[[maybe_unused]] bool disk_only,
|
||||
bool & Sent,
|
||||
bool rpc) {
|
||||
|
||||
auto SerialNumberInt = Utils::SerialNumberToInt(SerialNumber);
|
||||
Sent=false;
|
||||
@@ -254,31 +307,33 @@ namespace OpenWifi {
|
||||
std::stringstream ToSend;
|
||||
|
||||
CommandInfo Idx;
|
||||
Idx.Id = oneway_rpc ? 1 : RPCID;
|
||||
Idx.Id = oneway_rpc ? 1 : RPC_ID;
|
||||
Idx.SerialNumber = SerialNumberInt;
|
||||
Idx.Command = Command;
|
||||
if(Command == APCommands::Commands::script)
|
||||
Idx.State=2;
|
||||
Idx.UUID = UUID;
|
||||
|
||||
Poco::JSON::Object CompleteRPC;
|
||||
CompleteRPC.set(uCentralProtocol::JSONRPC, uCentralProtocol::JSONRPC_VERSION);
|
||||
CompleteRPC.set(uCentralProtocol::ID, RPCID);
|
||||
CompleteRPC.set(uCentralProtocol::METHOD, Command);
|
||||
CompleteRPC.set(uCentralProtocol::ID, RPC_ID);
|
||||
CompleteRPC.set(uCentralProtocol::METHOD, CommandStr);
|
||||
CompleteRPC.set(uCentralProtocol::PARAMS, Params);
|
||||
Poco::JSON::Stringifier::stringify(CompleteRPC, ToSend);
|
||||
Idx.rpc_entry = disk_only ? nullptr : std::make_shared<CommandManager::promise_type_t>();
|
||||
Idx.rpc_entry = rpc ? std::make_shared<CommandManager::promise_type_t>() : nullptr;
|
||||
|
||||
poco_debug(Logger(), fmt::format("{}: Sending command. ID: {}", UUID, RPCID));
|
||||
poco_debug(Logger(), fmt::format("{}: Sending command {} to {}. ID: {}", UUID, CommandStr, SerialNumber, RPC_ID));
|
||||
if(AP_WS_Server()->SendFrame(SerialNumber, ToSend.str())) {
|
||||
if(!oneway_rpc) {
|
||||
std::lock_guard M(Mutex_);
|
||||
OutStandingRequests_[RPCID] = Idx;
|
||||
OutStandingRequests_[RPC_ID] = Idx;
|
||||
}
|
||||
poco_debug(Logger(), fmt::format("{}: Sent command. ID: {}", UUID, RPCID));
|
||||
poco_debug(Logger(), fmt::format("{}: Sent command. ID: {}", UUID, RPC_ID));
|
||||
Sent=true;
|
||||
return Idx.rpc_entry;
|
||||
}
|
||||
|
||||
poco_warning(Logger(), fmt::format("{}: Failed to send command. ID: {}", UUID, RPCID));
|
||||
poco_warning(Logger(), fmt::format("{}: Failed to send command. ID: {}", UUID, RPC_ID));
|
||||
return nullptr;
|
||||
}
|
||||
} // namespace
|
||||
@@ -15,12 +15,15 @@
|
||||
#include <functional>
|
||||
#include <shared_mutex>
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "Poco/Timer.h"
|
||||
#include "Poco/Notification.h"
|
||||
#include "Poco/NotificationQueue.h"
|
||||
|
||||
#include "framework/SubSystemServer.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
|
||||
@@ -28,108 +31,122 @@ 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;
|
||||
std::uint64_t SerialNumber=0;
|
||||
std::string Command;
|
||||
std::string UUID;
|
||||
std::uint64_t Id=0;
|
||||
std::uint64_t SerialNumber=0;
|
||||
APCommands::Commands Command;
|
||||
std::string UUID;
|
||||
std::uint64_t State=1;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> submitted = std::chrono::high_resolution_clock::now();
|
||||
std::shared_ptr<promise_type_t> rpc_entry;
|
||||
};
|
||||
|
||||
struct RPCResponse {
|
||||
std::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,
|
||||
APCommands::Commands Command,
|
||||
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,
|
||||
Command,
|
||||
SerialNumber,
|
||||
Method,
|
||||
Params,
|
||||
UUID,
|
||||
true, true, Sent );
|
||||
true, true, Sent , false);
|
||||
}
|
||||
|
||||
std::shared_ptr<promise_type_t> PostCommandDisk(
|
||||
uint64_t RPCID,
|
||||
uint64_t RPC_ID,
|
||||
APCommands::Commands Command,
|
||||
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,
|
||||
Command,
|
||||
SerialNumber,
|
||||
Method,
|
||||
Params,
|
||||
UUID,
|
||||
false, true, Sent );
|
||||
false, true, Sent,
|
||||
false );
|
||||
}
|
||||
|
||||
std::shared_ptr<promise_type_t> PostCommand(
|
||||
uint64_t RPCID,
|
||||
uint64_t RPC_ID,
|
||||
APCommands::Commands Command,
|
||||
const std::string &SerialNumber,
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
bool & Sent) {
|
||||
return PostCommand(RPCID, SerialNumber,
|
||||
bool & Sent,
|
||||
bool rpc) {
|
||||
return PostCommand(RPC_ID,
|
||||
Command,
|
||||
SerialNumber,
|
||||
Method,
|
||||
Params,
|
||||
UUID,
|
||||
false,
|
||||
false, Sent );
|
||||
false, Sent,
|
||||
rpc);
|
||||
}
|
||||
|
||||
std::shared_ptr<promise_type_t> PostCommandOneWay(
|
||||
uint64_t RPCID,
|
||||
uint64_t RPC_ID,
|
||||
APCommands::Commands Command,
|
||||
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,
|
||||
Command,
|
||||
SerialNumber,
|
||||
Method,
|
||||
Params,
|
||||
UUID,
|
||||
true,
|
||||
false, Sent );
|
||||
false, Sent,
|
||||
false);
|
||||
}
|
||||
|
||||
bool IsCommandRunning(const std::string &C);
|
||||
@@ -144,15 +161,14 @@ 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_);
|
||||
OutStandingRequests_.erase(Id);
|
||||
}
|
||||
|
||||
inline bool CommandRunningForDevice(std::uint64_t SerialNumber, std::string & uuid, std::string &command) {
|
||||
inline bool CommandRunningForDevice(std::uint64_t SerialNumber, std::string & uuid, APCommands::Commands &command) {
|
||||
std::lock_guard Lock(LocalMutex_);
|
||||
|
||||
for(const auto &[Request,Command]:OutStandingRequests_) {
|
||||
@@ -189,13 +205,15 @@ namespace OpenWifi {
|
||||
|
||||
std::shared_ptr<promise_type_t> PostCommand(
|
||||
uint64_t RPCID,
|
||||
APCommands::Commands Command,
|
||||
const std::string &SerialNumber,
|
||||
const std::string &Method,
|
||||
const Poco::JSON::Object &Params,
|
||||
const std::string &UUID,
|
||||
bool oneway_rpc,
|
||||
bool disk_only,
|
||||
bool & Sent);
|
||||
bool & Sent,
|
||||
bool rpc_call);
|
||||
|
||||
CommandManager() noexcept:
|
||||
SubSystemServer("CommandManager", "CMD-MGR", "command.manager") {
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <mutex>
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class ConfigurationCache {
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/Option.h"
|
||||
#include "Poco/Environment.h"
|
||||
@@ -28,6 +26,10 @@
|
||||
#include "VenueBroadcaster.h"
|
||||
#include "framework/ConfigurationValidator.h"
|
||||
#include "rttys/RTTYS_server.h"
|
||||
#include "framework/UI_WebSocketClientServer.h"
|
||||
#include "UI_GW_WebSocketNotifications.h"
|
||||
#include "ScriptManager.h"
|
||||
#include "SignatureMgr.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class Daemon *Daemon::instance() {
|
||||
@@ -40,10 +42,9 @@ namespace OpenWifi {
|
||||
StorageService(),
|
||||
SerialNumberCache(),
|
||||
ConfigurationValidator(),
|
||||
WebSocketClientServer(),
|
||||
UI_WebSocketClientServer(),
|
||||
OUIServer(),
|
||||
FindCountryFromIP(),
|
||||
// DeviceRegistry(),
|
||||
CommandManager(),
|
||||
FileUploader(),
|
||||
StorageArchiver(),
|
||||
@@ -51,6 +52,8 @@ namespace OpenWifi {
|
||||
RTTYS_server(),
|
||||
RADIUS_proxy_server(),
|
||||
VenueBroadcaster(),
|
||||
ScriptManager(),
|
||||
SignatureManager(),
|
||||
AP_WS_Server()
|
||||
});
|
||||
return &instance;
|
||||
@@ -104,6 +107,11 @@ namespace OpenWifi {
|
||||
}
|
||||
return "AP";
|
||||
}
|
||||
|
||||
void DaemonPostInitialization(Poco::Util::Application &self) {
|
||||
Daemon()->PostInitialization(self);
|
||||
GWWebSocketNotifications::Register();
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
15
src/Daemon.h
15
src/Daemon.h
@@ -14,18 +14,9 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "framework/MicroServiceNames.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/ServerApplication.h"
|
||||
#include "Poco/Util/Option.h"
|
||||
#include "Poco/Util/OptionSet.h"
|
||||
#include "Poco/UUIDGenerator.h"
|
||||
#include "Poco/ErrorHandler.h"
|
||||
#include "Poco/Crypto/RSAKey.h"
|
||||
#include "Poco/Crypto/CipherFactory.h"
|
||||
#include "Poco/Crypto/Cipher.h"
|
||||
|
||||
#include "Dashboard.h"
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
#include "GwWebSocketClient.h"
|
||||
@@ -62,8 +53,6 @@ namespace OpenWifi {
|
||||
};
|
||||
|
||||
inline Daemon * Daemon() { return Daemon::instance(); }
|
||||
inline void DaemonPostInitialization(Poco::Util::Application &self) {
|
||||
Daemon()->PostInitialization(self);
|
||||
}
|
||||
void DaemonPostInitialization(Poco::Util::Application &self);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,16 +4,48 @@
|
||||
|
||||
#include "Dashboard.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void DeviceDashboard::Create() {
|
||||
uint64_t Now = OpenWifi::Now();
|
||||
|
||||
if(LastRun_==0 || (Now-LastRun_)>120) {
|
||||
DB_.reset();
|
||||
StorageService()->AnalyzeCommands(DB_.commands);
|
||||
StorageService()->AnalyzeDevices(DB_);
|
||||
LastRun_ = Now;
|
||||
bool DeviceDashboard::Get(GWObjects::Dashboard &D, Poco::Logger & Logger) {
|
||||
uint64_t Now = Utils::Now();
|
||||
if(!ValidDashboard_ || LastRun_==0 || (Now-LastRun_)>120) {
|
||||
Generate(D, Logger);
|
||||
} else {
|
||||
std::lock_guard G(DataMutex_);
|
||||
D = DB_;
|
||||
}
|
||||
return ValidDashboard_;
|
||||
};
|
||||
|
||||
void DeviceDashboard::Generate(GWObjects::Dashboard &D, Poco::Logger & Logger ) {
|
||||
if (GeneratingDashboard_.load()) {
|
||||
// std::cout << "Trying to generate dashboard but already being generated" << std::endl;
|
||||
while(GeneratingDashboard_.load()) {
|
||||
Poco::Thread::trySleep(100);
|
||||
}
|
||||
std::lock_guard G(DataMutex_);
|
||||
D = DB_;
|
||||
} else {
|
||||
GeneratingDashboard_ = true;
|
||||
ValidDashboard_ = false;
|
||||
try {
|
||||
// std::cout << "Generating dashboard." << std::endl;
|
||||
poco_information(Logger, "DASHBOARD: Generating a new dashboard.");
|
||||
GWObjects::Dashboard NewData;
|
||||
StorageService()->AnalyzeCommands(NewData.commands);
|
||||
StorageService()->AnalyzeDevices(NewData);
|
||||
LastRun_ = Utils::Now();
|
||||
NewData.snapshot = LastRun_;
|
||||
D = NewData;
|
||||
std::lock_guard G(DataMutex_);
|
||||
DB_ = NewData;
|
||||
ValidDashboard_=true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
GeneratingDashboard_ = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,19 +4,24 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "RESTObjects//RESTAPI_GWobjects.h"
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
#include "Poco/Logger.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class DeviceDashboard {
|
||||
public:
|
||||
DeviceDashboard() { DB_.reset(); }
|
||||
void Create();
|
||||
[[nodiscard]] const GWObjects::Dashboard & Report() const { return DB_;}
|
||||
bool Get(GWObjects::Dashboard &D, Poco::Logger & Logger);
|
||||
private:
|
||||
GWObjects::Dashboard DB_;
|
||||
uint64_t LastRun_=0;
|
||||
inline void Reset() { DB_.reset(); }
|
||||
std::mutex DataMutex_;
|
||||
volatile std::atomic_bool GeneratingDashboard_=false;
|
||||
volatile bool ValidDashboard_=false;
|
||||
GWObjects::Dashboard DB_;
|
||||
uint64_t LastRun_=0;
|
||||
|
||||
void Generate(GWObjects::Dashboard &D, Poco::Logger & Logger);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,264 +0,0 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "AP_WS_Server.h"
|
||||
#include "DeviceRegistry.h"
|
||||
#include "CommandManager.h"
|
||||
|
||||
#include "framework/WebSocketClientNotifications.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
int DeviceRegistry::Start() {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
poco_notice(Logger(),"Starting");
|
||||
|
||||
ArchiverCallback_ = std::make_unique<Poco::TimerCallback<DeviceRegistry>>(*this,&DeviceRegistry::onConnectionJanitor);
|
||||
Timer_.setStartInterval(60 * 1000);
|
||||
Timer_.setPeriodicInterval(20 * 1000); // every minute
|
||||
Timer_.start(*ArchiverCallback_, MicroService::instance().TimerPool());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DeviceRegistry::Stop() {
|
||||
poco_notice(Logger(),"Stopping...");
|
||||
std::lock_guard Guard(Mutex_);
|
||||
Timer_.stop();
|
||||
poco_notice(Logger(),"Stopped...");
|
||||
}
|
||||
|
||||
void DeviceRegistry::onConnectionJanitor([[maybe_unused]] Poco::Timer &timer) {
|
||||
|
||||
static std::uint64_t last_log = OpenWifi::Now();
|
||||
|
||||
std::shared_lock Guard(LocalMutex_);
|
||||
|
||||
NumberOfConnectedDevices_ = 0;
|
||||
NumberOfConnectingDevices_ = 0;
|
||||
AverageDeviceConnectionTime_ = 0;
|
||||
std::uint64_t total_connected_time=0;
|
||||
|
||||
auto now = OpenWifi::Now();
|
||||
for (auto connection=SerialNumbers_.begin(); connection!=SerialNumbers_.end();) {
|
||||
|
||||
if(connection->second.second== nullptr) {
|
||||
connection++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (connection->second.second->State_.Connected) {
|
||||
NumberOfConnectedDevices_++;
|
||||
total_connected_time += (now - connection->second.second->State_.started);
|
||||
connection++;
|
||||
} else {
|
||||
NumberOfConnectingDevices_++;
|
||||
connection++;
|
||||
}
|
||||
}
|
||||
|
||||
AverageDeviceConnectionTime_ = (NumberOfConnectedDevices_!=0) ? total_connected_time/NumberOfConnectedDevices_ : 0;
|
||||
if((now-last_log)>120) {
|
||||
last_log = now;
|
||||
poco_information(Logger(),
|
||||
fmt::format("Active AP connections: {} Connecting: {} Average connection time: {} seconds",
|
||||
NumberOfConnectedDevices_, NumberOfConnectingDevices_, AverageDeviceConnectionTime_));
|
||||
}
|
||||
WebSocketClientNotificationNumberOfConnections(NumberOfConnectedDevices_,
|
||||
AverageDeviceConnectionTime_,
|
||||
NumberOfConnectingDevices_);
|
||||
}
|
||||
|
||||
bool DeviceRegistry::GetStatistics(uint64_t SerialNumber, std::string & Statistics) const {
|
||||
std::shared_lock Guard(LocalMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
|
||||
return false;
|
||||
Statistics = Device->second.second->LastStats_;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceRegistry::GetState(uint64_t SerialNumber, GWObjects::ConnectionState & State) const {
|
||||
std::shared_lock Guard(LocalMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
|
||||
return false;
|
||||
State = Device->second.second->State_;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceRegistry::GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const {
|
||||
std::shared_lock Guard(LocalMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device == SerialNumbers_.end() || Device->second.second==nullptr)
|
||||
return false;
|
||||
|
||||
CheckData = Device->second.second->LastHealthcheck_;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DeviceRegistry::EndSession(std::uint64_t connection_id, std::uint64_t serial_number) {
|
||||
|
||||
std::unique_lock G(LocalMutex_);
|
||||
auto Connection = SerialNumbers_.find(serial_number);
|
||||
if (Connection == end(SerialNumbers_)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Connection->second.first != connection_id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SerialNumbers_.erase(Connection);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeviceRegistry::SetSessionDetails(std::uint64_t connection_id, uint64_t SerialNumber) {
|
||||
auto Connection = AP_WS_Server()->FindConnection(connection_id);
|
||||
|
||||
if(Connection== nullptr)
|
||||
return;
|
||||
|
||||
std::unique_lock G(LocalMutex_);
|
||||
auto CurrentSerialNumber = SerialNumbers_.find(SerialNumber);
|
||||
if( (CurrentSerialNumber==SerialNumbers_.end()) ||
|
||||
(CurrentSerialNumber->second.first<connection_id)) {
|
||||
SerialNumbers_[SerialNumber] = std::make_pair(connection_id, Connection);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool DeviceRegistry::Connected(uint64_t SerialNumber) const {
|
||||
std::shared_lock Guard(LocalMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
|
||||
return false;
|
||||
|
||||
return Device->second.second->State_.Connected;
|
||||
}
|
||||
|
||||
bool DeviceRegistry::SendFrame(uint64_t SerialNumber, const std::string & Payload) const {
|
||||
std::shared_lock Guard(LocalMutex_);
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
|
||||
return false;
|
||||
|
||||
try {
|
||||
// std::cout << "Device connection pointer: " << (std::uint64_t) Device->second.second << std::endl;
|
||||
return Device->second.second->Send(Payload);
|
||||
} catch (...) {
|
||||
poco_debug(Logger(),fmt::format(": SendFrame: Could not send data to device '{}'", Utils::IntToSerialNumber(SerialNumber)));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeviceRegistry::StopWebSocketTelemetry(std::uint64_t RPCID, uint64_t SerialNumber) {
|
||||
std::shared_lock Guard(LocalMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_) || Device->second.second==nullptr)
|
||||
return;
|
||||
Device->second.second->StopWebSocketTelemetry(RPCID);
|
||||
}
|
||||
|
||||
void DeviceRegistry::SetWebSocketTelemetryReporting(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
|
||||
std::shared_lock Guard(LocalMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_) || Device->second.second==nullptr)
|
||||
return;
|
||||
Device->second.second->SetWebSocketTelemetryReporting(RPCID, Interval, Lifetime);
|
||||
}
|
||||
|
||||
void DeviceRegistry::SetKafkaTelemetryReporting(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
|
||||
std::shared_lock Guard(LocalMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
|
||||
return;
|
||||
Device->second.second->SetKafkaTelemetryReporting(RPCID, Interval, Lifetime);
|
||||
}
|
||||
|
||||
void DeviceRegistry::StopKafkaTelemetry(std::uint64_t RPCID, uint64_t SerialNumber) {
|
||||
std::shared_lock Guard(LocalMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_) || Device->second.second== nullptr)
|
||||
return;
|
||||
Device->second.second->StopKafkaTelemetry(RPCID);
|
||||
}
|
||||
|
||||
void DeviceRegistry::GetTelemetryParameters(uint64_t SerialNumber , bool & TelemetryRunning,
|
||||
uint64_t & TelemetryInterval,
|
||||
uint64_t & TelemetryWebSocketTimer,
|
||||
uint64_t & TelemetryKafkaTimer,
|
||||
uint64_t & TelemetryWebSocketCount,
|
||||
uint64_t & TelemetryKafkaCount,
|
||||
uint64_t & TelemetryWebSocketPackets,
|
||||
uint64_t & TelemetryKafkaPackets) {
|
||||
std::shared_lock Guard(LocalMutex_);
|
||||
|
||||
auto Device = SerialNumbers_.find(SerialNumber);
|
||||
if(Device==end(SerialNumbers_)|| Device->second.second== nullptr)
|
||||
return;
|
||||
Device->second.second->GetTelemetryParameters(TelemetryRunning,
|
||||
TelemetryInterval,
|
||||
TelemetryWebSocketTimer,
|
||||
TelemetryKafkaTimer,
|
||||
TelemetryWebSocketCount,
|
||||
TelemetryKafkaCount,
|
||||
TelemetryWebSocketPackets,
|
||||
TelemetryKafkaPackets);
|
||||
}
|
||||
|
||||
bool DeviceRegistry::SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
|
||||
std::shared_lock Guard(LocalMutex_);
|
||||
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
|
||||
return false;
|
||||
|
||||
try {
|
||||
return Device->second.second->SendRadiusAccountingData(buffer,size);
|
||||
} catch (...) {
|
||||
poco_debug(Logger(),fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'", SerialNumber));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceRegistry::SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
|
||||
std::shared_lock Guard(LocalMutex_);
|
||||
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
|
||||
return false;
|
||||
|
||||
try {
|
||||
return Device->second.second->SendRadiusAuthenticationData(buffer,size);
|
||||
} catch (...) {
|
||||
poco_debug(Logger(),fmt::format(": SendRadiusAuthenticationData: Could not send data to device '{}'", SerialNumber));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceRegistry::SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
|
||||
std::shared_lock Guard(LocalMutex_);
|
||||
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
|
||||
if(Device==SerialNumbers_.end() || Device->second.second== nullptr)
|
||||
return false;
|
||||
|
||||
try {
|
||||
return Device->second.second->SendRadiusCoAData(buffer,size);
|
||||
} catch (...) {
|
||||
poco_debug(Logger(),fmt::format(": SendRadiusCoAData: Could not send data to device '{}'", SerialNumber));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -1,104 +0,0 @@
|
||||
//
|
||||
// License type: BSD 3-Clause License
|
||||
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
//
|
||||
// Created by Stephane Bourque on 2021-03-04.
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <shared_mutex>
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/Timer.h"
|
||||
#include "RESTObjects//RESTAPI_GWobjects.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class AP_WS_Connection;
|
||||
class DeviceRegistry : public SubSystemServer {
|
||||
public:
|
||||
|
||||
DeviceRegistry() noexcept:
|
||||
SubSystemServer("DeviceRegistry", "DevStatus", "devicestatus") {
|
||||
}
|
||||
|
||||
static auto instance() {
|
||||
static auto instance_ = new DeviceRegistry;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
|
||||
inline bool GetStatistics(const std::string &SerialNumber, std::string & Statistics) const {
|
||||
return GetStatistics(Utils::SerialNumberToInt(SerialNumber),Statistics);
|
||||
}
|
||||
bool GetStatistics(std::uint64_t SerialNumber, std::string & Statistics) const;
|
||||
|
||||
inline bool GetState(const std::string & SerialNumber, GWObjects::ConnectionState & State) const {
|
||||
return GetState(Utils::SerialNumberToInt(SerialNumber), State);
|
||||
}
|
||||
bool GetState(std::uint64_t SerialNumber, GWObjects::ConnectionState & State) const;
|
||||
|
||||
inline bool GetHealthcheck(const std::string &SerialNumber, GWObjects::HealthCheck & CheckData) const {
|
||||
return GetHealthcheck(Utils::SerialNumberToInt(SerialNumber), CheckData);
|
||||
}
|
||||
bool GetHealthcheck(std::uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const ;
|
||||
|
||||
bool Connected(uint64_t SerialNumber) const ;
|
||||
|
||||
inline bool SendFrame(const std::string & SerialNumber, const std::string & Payload) const {
|
||||
return SendFrame(Utils::SerialNumberToInt(SerialNumber), Payload);
|
||||
}
|
||||
|
||||
bool SendFrame(std::uint64_t SerialNumber, const std::string & Payload) const ;
|
||||
|
||||
bool SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
bool SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
|
||||
|
||||
void SetSessionDetails(std::uint64_t connection_id, uint64_t SerialNumber);
|
||||
bool EndSession(std::uint64_t connection_id, std::uint64_t serial_number);
|
||||
|
||||
void SetWebSocketTelemetryReporting(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime);
|
||||
void StopWebSocketTelemetry(std::uint64_t RPCID, uint64_t SerialNumber);
|
||||
void SetKafkaTelemetryReporting(std::uint64_t RPCID, uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime);
|
||||
void StopKafkaTelemetry(std::uint64_t RPCID, uint64_t SerialNumber);
|
||||
void GetTelemetryParameters(uint64_t SerialNumber , bool & TelemetryRunning,
|
||||
uint64_t & TelemetryInterval,
|
||||
uint64_t & TelemetryWebSocketTimer,
|
||||
uint64_t & TelemetryKafkaTimer,
|
||||
uint64_t & TelemetryWebSocketCount,
|
||||
uint64_t & TelemetryKafkaCount,
|
||||
uint64_t & TelemetryWebSocketPackets,
|
||||
uint64_t & TelemetryKafkaPackets);
|
||||
|
||||
void onConnectionJanitor(Poco::Timer & timer);
|
||||
|
||||
inline void AverageDeviceStatistics( std::uint64_t & Connections, std::uint64_t & AverageConnectionTime, std::uint64_t & NumberOfConnectingDevices) const {
|
||||
Connections = NumberOfConnectedDevices_;
|
||||
AverageConnectionTime = AverageDeviceConnectionTime_;
|
||||
NumberOfConnectingDevices = NumberOfConnectingDevices_;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::shared_mutex LocalMutex_;
|
||||
std::map<std::uint64_t, std::pair<std::uint64_t,std::shared_ptr<AP_WS_Connection>>> SerialNumbers_;
|
||||
|
||||
std::unique_ptr<Poco::TimerCallback<DeviceRegistry>> ArchiverCallback_;
|
||||
Poco::Timer Timer_;
|
||||
Poco::Thread ConnectionJanitor_;
|
||||
std::atomic_uint64_t NumberOfConnectedDevices_=0;
|
||||
std::atomic_uint64_t AverageDeviceConnectionTime_=0;
|
||||
std::atomic_uint64_t NumberOfConnectingDevices_=0;
|
||||
|
||||
};
|
||||
|
||||
inline auto DeviceRegistry() { return DeviceRegistry::instance(); }
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -8,8 +8,6 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
#include "Poco/Net/HTTPServerParams.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "Poco/DynamicAny.h"
|
||||
@@ -19,9 +17,16 @@
|
||||
#include "Poco/CountingStream.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/StringTokenizer.h"
|
||||
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/ow_constants.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
#include "FileUploader.h"
|
||||
#include "StorageService.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -30,7 +35,7 @@ namespace OpenWifi {
|
||||
int FileUploader::Start() {
|
||||
poco_notice(Logger(),"Starting.");
|
||||
|
||||
Poco::File UploadsDir(MicroService::instance().ConfigPath("openwifi.fileuploader.path","/tmp"));
|
||||
Poco::File UploadsDir(MicroServiceConfigPath("openwifi.fileuploader.path","/tmp"));
|
||||
Path_ = UploadsDir.path();
|
||||
if(!UploadsDir.exists()) {
|
||||
try {
|
||||
@@ -42,7 +47,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
for(const auto & Svr: ConfigServersList_) {
|
||||
if(MicroService::instance().NoAPISecurity()) {
|
||||
if(MicroServiceNoAPISecurity()) {
|
||||
poco_notice(Logger(), fmt::format("Starting: {}:{}",Svr.Address(),Svr.Port()));
|
||||
|
||||
auto Sock{Svr.CreateSocket(Logger())};
|
||||
@@ -54,7 +59,7 @@ namespace OpenWifi {
|
||||
|
||||
if (FullName_.empty()) {
|
||||
std::string TmpName =
|
||||
MicroService::instance().ConfigGetString("openwifi.fileuploader.uri", "");
|
||||
MicroServiceConfigGetString("openwifi.fileuploader.uri", "");
|
||||
if (TmpName.empty()) {
|
||||
FullName_ =
|
||||
"https://" + Svr.Name() + ":" + std::to_string(Svr.Port()) + URI_BASE;
|
||||
@@ -87,7 +92,7 @@ namespace OpenWifi {
|
||||
|
||||
if (FullName_.empty()) {
|
||||
std::string TmpName =
|
||||
MicroService::instance().ConfigGetString("openwifi.fileuploader.uri", "");
|
||||
MicroServiceConfigGetString("openwifi.fileuploader.uri", "");
|
||||
if (TmpName.empty()) {
|
||||
FullName_ =
|
||||
"https://" + Svr.Name() + ":" + std::to_string(Svr.Port()) + URI_BASE;
|
||||
@@ -104,13 +109,13 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
MaxSize_ = 1000 * MicroService::instance().ConfigGetInt("openwifi.fileuploader.maxsize", 10000);
|
||||
MaxSize_ = 1000 * MicroServiceConfigGetInt("openwifi.fileuploader.maxsize", 10000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FileUploader::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
||||
MicroService::instance().LoadConfigurationFile();
|
||||
MicroServiceLoadConfigurationFile();
|
||||
poco_information(Logger(),"Reinitializing.");
|
||||
Stop();
|
||||
Start();
|
||||
@@ -121,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 = OpenWifi::Now();
|
||||
|
||||
// remove old stuff...
|
||||
for(auto i=OutStandingUploads_.begin();i!=OutStandingUploads_.end();) {
|
||||
if ((now-i->second) > (60 * 30))
|
||||
i = OutStandingUploads_.erase(i);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
|
||||
if(!UUID.empty())
|
||||
OutStandingUploads_[UUID] = now;
|
||||
|
||||
uint64_t now = Utils::Now();
|
||||
auto Func=[now](const UploadId &I) -> bool {
|
||||
return (now > I.Expires);
|
||||
};
|
||||
OutStandingUploads_.erase(std::remove_if(OutStandingUploads_.begin(),OutStandingUploads_.end(),Func),OutStandingUploads_.end());
|
||||
OutStandingUploads_.emplace_back(UploadId{UUID, now + WaitTimeInSeconds.count(), Type});
|
||||
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 {
|
||||
@@ -188,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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -225,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;
|
||||
@@ -262,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) {
|
||||
@@ -280,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
|
||||
{
|
||||
@@ -294,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_ )
|
||||
|
||||
@@ -8,23 +8,29 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
#include "Poco/Net/HTTPRequestHandler.h"
|
||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
|
||||
#include "Poco/Net/HTTPServer.h"
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
|
||||
#include "framework/SubSystemServer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class FileUploader : public SubSystemServer {
|
||||
public:
|
||||
|
||||
struct UploadId {
|
||||
std::string UUID;
|
||||
std::uint64_t Expires;
|
||||
std::string Type;
|
||||
};
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void reinitialize(Poco::Util::Application &self) override;
|
||||
const std::string & FullName();
|
||||
bool AddUUID( const std::string & UUID);
|
||||
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_; };
|
||||
@@ -36,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")
|
||||
@@ -52,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_;
|
||||
};
|
||||
|
||||
@@ -4,9 +4,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
#include "Poco/Net/IPAddress.h"
|
||||
|
||||
#include "framework/SubSystemServer.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
namespace OpenWifi {
|
||||
@@ -24,7 +26,7 @@ namespace OpenWifi {
|
||||
public:
|
||||
static std::string Name() { return "ipinfo"; }
|
||||
inline bool Init() override {
|
||||
Key_ = MicroService::instance().ConfigGetString("iptocountry.ipinfo.token", "");
|
||||
Key_ = MicroServiceConfigGetString("iptocountry.ipinfo.token", "");
|
||||
return !Key_.empty();
|
||||
}
|
||||
|
||||
@@ -56,7 +58,7 @@ namespace OpenWifi {
|
||||
public:
|
||||
static std::string Name() { return "ipdata"; }
|
||||
inline bool Init() override {
|
||||
Key_ = MicroService::instance().ConfigGetString("iptocountry.ipdata.apikey", "");
|
||||
Key_ = MicroServiceConfigGetString("iptocountry.ipdata.apikey", "");
|
||||
return !Key_.empty();
|
||||
}
|
||||
|
||||
@@ -86,7 +88,7 @@ namespace OpenWifi {
|
||||
public:
|
||||
static std::string Name() { return "ip2location"; }
|
||||
inline bool Init() override {
|
||||
Key_ = MicroService::instance().ConfigGetString("iptocountry.ip2location.apikey", "");
|
||||
Key_ = MicroServiceConfigGetString("iptocountry.ip2location.apikey", "");
|
||||
return !Key_.empty();
|
||||
}
|
||||
|
||||
@@ -135,14 +137,14 @@ namespace OpenWifi {
|
||||
|
||||
inline int Start() final {
|
||||
poco_notice(Logger(),"Starting...");
|
||||
ProviderName_ = MicroService::instance().ConfigGetString("iptocountry.provider","");
|
||||
ProviderName_ = MicroServiceConfigGetString("iptocountry.provider","");
|
||||
if(!ProviderName_.empty()) {
|
||||
Provider_ = IPLocationProvider<IPToCountryProvider, IPInfo, IPData, IP2Location>(ProviderName_);
|
||||
if(Provider_!= nullptr) {
|
||||
Enabled_ = Provider_->Init();
|
||||
}
|
||||
}
|
||||
Default_ = MicroService::instance().ConfigGetString("iptocountry.default", "US");
|
||||
Default_ = MicroServiceConfigGetString("iptocountry.default", "US");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
21
src/GWKafkaEvents.cpp
Normal file
21
src/GWKafkaEvents.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
//
|
||||
// Created by stephane bourque on 2023-02-03.
|
||||
//
|
||||
|
||||
#include "GWKafkaEvents.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void GWKafkaEvents::Send() {
|
||||
if(KafkaManager()->Enabled()) {
|
||||
Poco::JSON::Object Event;
|
||||
Event.set("type", type_);
|
||||
Event.set("timestamp", timestamp_);
|
||||
Event.set("payload", payload_);
|
||||
std::ostringstream OS;
|
||||
Event.stringify(OS);
|
||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, serialNumber_, OS.str());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
97
src/GWKafkaEvents.h
Normal file
97
src/GWKafkaEvents.h
Normal file
@@ -0,0 +1,97 @@
|
||||
//
|
||||
// Created by stephane bourque on 2023-02-03.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <Poco/JSON/Object.h>
|
||||
#include <framework/KafkaManager.h>
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class GWKafkaEvents {
|
||||
public:
|
||||
GWKafkaEvents(const std::string &serialNumber, const std::string &type, std::uint64_t timestamp) :
|
||||
serialNumber_(serialNumber),
|
||||
type_(type),
|
||||
timestamp_(timestamp) {
|
||||
}
|
||||
|
||||
inline void SetPayload(Poco::JSON::Object::Ptr payload) {
|
||||
payload_ = std::move(payload);
|
||||
}
|
||||
void Send();
|
||||
|
||||
private:
|
||||
std::string serialNumber_;
|
||||
std::string type_;
|
||||
std::uint64_t timestamp_=0;
|
||||
Poco::JSON::Object::Ptr payload_;
|
||||
};
|
||||
|
||||
class DeviceFirmwareChangeKafkaEvent : public GWKafkaEvents {
|
||||
public:
|
||||
DeviceFirmwareChangeKafkaEvent( const std::string &serialNumber, std::uint64_t timestamp, const std::string &oldFirmware, const std::string &newFirmware) :
|
||||
GWKafkaEvents(serialNumber,"device.firmware_change", timestamp),
|
||||
oldFirmware_(oldFirmware),
|
||||
newFirmware_(newFirmware) {
|
||||
}
|
||||
|
||||
~DeviceFirmwareChangeKafkaEvent() {
|
||||
Poco::JSON::Object::Ptr payload = new Poco::JSON::Object;
|
||||
payload->set("oldFirmware", oldFirmware_);
|
||||
payload->set("newFirmware",newFirmware_);
|
||||
SetPayload(payload);
|
||||
Send();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string oldFirmware_, newFirmware_;
|
||||
};
|
||||
|
||||
class DeviceConfigurationChangeKafkaEvent : public GWKafkaEvents {
|
||||
public:
|
||||
DeviceConfigurationChangeKafkaEvent( const std::string &serialNumber, std::uint64_t timestamp, const std::string config) :
|
||||
GWKafkaEvents(serialNumber,"device.configuration_change", timestamp),
|
||||
config_(config) {
|
||||
}
|
||||
|
||||
~DeviceConfigurationChangeKafkaEvent() {
|
||||
Poco::JSON::Object::Ptr payload = new Poco::JSON::Object;
|
||||
payload->set("configuration", config_);
|
||||
SetPayload(payload);
|
||||
Send();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string config_;
|
||||
};
|
||||
|
||||
class DeviceBlacklistedKafkaEvent : public GWKafkaEvents {
|
||||
public:
|
||||
explicit DeviceBlacklistedKafkaEvent( const std::string &serialNumber, std::uint64_t timestamp, const std::string &reason, const std::string &author, std::uint64_t created, std::string &IP) :
|
||||
GWKafkaEvents(serialNumber,"blacklisted_device", timestamp),
|
||||
reason_(reason), author_(author), created_(created), IP_(IP)
|
||||
{
|
||||
}
|
||||
|
||||
~DeviceBlacklistedKafkaEvent() {
|
||||
Poco::JSON::Object::Ptr payload = new Poco::JSON::Object;
|
||||
payload->set("reason", reason_);
|
||||
payload->set("author", author_);
|
||||
payload->set("created", created_);
|
||||
payload->set("ipaddress", IP_);
|
||||
SetPayload(payload);
|
||||
Send();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string reason_,author_;
|
||||
std::uint64_t created_;
|
||||
std::string IP_;
|
||||
};
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@ namespace OpenWifi {
|
||||
|
||||
GwWebSocketClient::GwWebSocketClient(Poco::Logger &Logger):
|
||||
Logger_(Logger){
|
||||
WebSocketClientServer()->SetProcessor(this);
|
||||
UI_WebSocketClientServer()->SetProcessor(this);
|
||||
}
|
||||
|
||||
GwWebSocketClient::~GwWebSocketClient() {
|
||||
WebSocketClientServer()->SetProcessor(nullptr);
|
||||
UI_WebSocketClientServer()->SetProcessor(nullptr);
|
||||
}
|
||||
|
||||
void GwWebSocketClient::Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done ) {
|
||||
void GwWebSocketClient::Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done, [[maybe_unused]] const SecurityObjects::UserInfo &UserInfo) {
|
||||
try {
|
||||
if (O->has("command")) {
|
||||
auto Command = O->get("command").toString();
|
||||
@@ -60,7 +60,4 @@ namespace OpenWifi {
|
||||
Done = false;
|
||||
Answer = std::string{R"lit({ "error" : "invalid command" })lit"};
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -4,14 +4,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/UI_WebSocketClientServer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class GwWebSocketClient : public WebSocketClientProcessor {
|
||||
class GwWebSocketClient : public UI_WebSocketClientProcessor {
|
||||
public:
|
||||
explicit GwWebSocketClient(Poco::Logger &Logger);
|
||||
virtual ~GwWebSocketClient();
|
||||
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done );
|
||||
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done, const SecurityObjects::UserInfo &UserInfo);
|
||||
void ws_command_serial_number_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
void ws_command_exit( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
void ws_command_invalid( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
|
||||
@@ -11,15 +11,19 @@
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/File.h"
|
||||
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include "OUIServer.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
int OUIServer::Start() {
|
||||
Running_ = true;
|
||||
LatestOUIFileName_ = MicroService::instance().DataDir() + "/newOUIFile.txt";
|
||||
CurrentOUIFileName_ = MicroService::instance().DataDir() + "/current_oui.txt";
|
||||
LatestOUIFileName_ = MicroServiceDataDirectory() + "/newOUIFile.txt";
|
||||
CurrentOUIFileName_ = MicroServiceDataDirectory() + "/current_oui.txt";
|
||||
|
||||
bool Recovered = false;
|
||||
Poco::File OuiFile(CurrentOUIFileName_);
|
||||
@@ -42,7 +46,7 @@ namespace OpenWifi {
|
||||
Timer_.setStartInterval(30 * 1000); // first run in 5 minutes
|
||||
}
|
||||
Timer_.setPeriodicInterval(7 * 24 * 60 * 60 * 1000);
|
||||
Timer_.start(*UpdaterCallBack_, MicroService::instance().TimerPool());
|
||||
Timer_.start(*UpdaterCallBack_, MicroServiceTimerPool());
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -54,7 +58,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
void OUIServer::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
||||
MicroService::instance().LoadConfigurationFile();
|
||||
MicroServiceLoadConfigurationFile();
|
||||
poco_information(Logger(),"Reinitializing.");
|
||||
Stop();
|
||||
Start();
|
||||
@@ -62,15 +66,15 @@ namespace OpenWifi {
|
||||
|
||||
bool OUIServer::GetFile(const std::string &FileName) {
|
||||
try {
|
||||
LastUpdate_ = OpenWifi::Now();
|
||||
poco_information(Logger(), fmt::format("Start: Retrieving OUI file: {}",MicroService::instance().ConfigGetString("oui.download.uri")));
|
||||
LastUpdate_ = Utils::Now();
|
||||
poco_information(Logger(), fmt::format("Start: Retrieving OUI file: {}",MicroServiceConfigGetString("oui.download.uri","")));
|
||||
std::unique_ptr<std::istream> pStr(
|
||||
Poco::URIStreamOpener::defaultOpener().open(MicroService::instance().ConfigGetString("oui.download.uri")));
|
||||
Poco::URIStreamOpener::defaultOpener().open(MicroServiceConfigGetString("oui.download.uri","")));
|
||||
std::ofstream OS;
|
||||
OS.open(FileName);
|
||||
Poco::StreamCopier::copyStream(*pStr, OS);
|
||||
OS.close();
|
||||
poco_information(Logger(), fmt::format("Done: Retrieving OUI file: {}",MicroService::instance().ConfigGetString("oui.download.uri")));
|
||||
poco_information(Logger(), fmt::format("Done: Retrieving OUI file: {}",MicroServiceConfigGetString("oui.download.uri","")));
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
@@ -125,7 +129,7 @@ namespace OpenWifi {
|
||||
// fetch data from server, if not available, just use the file we already have.
|
||||
Poco::File Current(CurrentOUIFileName_);
|
||||
if(Current.exists()) {
|
||||
if((OpenWifi::Now()-Current.getLastModified().epochTime()) < (7*24*60*60)) {
|
||||
if((Utils::Now()-Current.getLastModified().epochTime()) < (7*24*60*60)) {
|
||||
if(!Initialized_) {
|
||||
if(ProcessFile(CurrentOUIFileName_, OUIs_)) {
|
||||
Initialized_ = true;
|
||||
@@ -144,7 +148,7 @@ namespace OpenWifi {
|
||||
if(GetFile(LatestOUIFileName_) && ProcessFile(LatestOUIFileName_, TmpOUIs)) {
|
||||
std::unique_lock G(LocalMutex_);
|
||||
OUIs_ = std::move(TmpOUIs);
|
||||
LastUpdate_ = OpenWifi::Now();
|
||||
LastUpdate_ = Utils::Now();
|
||||
Poco::File F1(CurrentOUIFileName_);
|
||||
if(F1.exists())
|
||||
F1.remove();
|
||||
@@ -153,7 +157,7 @@ namespace OpenWifi {
|
||||
poco_information(Logger(), fmt::format("New OUI file {} downloaded.",LatestOUIFileName_));
|
||||
} else if(OUIs_.empty()) {
|
||||
if(ProcessFile(CurrentOUIFileName_, TmpOUIs)) {
|
||||
LastUpdate_ = OpenWifi::Now();
|
||||
LastUpdate_ = Utils::Now();
|
||||
std::unique_lock G(LocalMutex_);
|
||||
OUIs_ = std::move(TmpOUIs);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
#include <shared_mutex>
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/SubSystemServer.h"
|
||||
|
||||
#include "Poco/Timer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -4,7 +4,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
#include "Poco/HMACEngine.h"
|
||||
#include "Poco/MD5Engine.h"
|
||||
#include "Poco/StringTokenizer.h"
|
||||
#include "Poco/Net/SocketAddress.h"
|
||||
|
||||
namespace OpenWifi::RADIUS {
|
||||
|
||||
@@ -290,6 +292,8 @@ static const struct tok radius_attribute_names[] = {
|
||||
constexpr unsigned char CoA_ACK = 44;
|
||||
constexpr unsigned char CoA_NAK = 45;
|
||||
|
||||
constexpr unsigned char ATTR_MessageAuthenticator = 80;
|
||||
|
||||
inline bool IsAuthentication(unsigned char t) {
|
||||
return (t == RADIUS::Access_Request ||
|
||||
t == RADIUS::Access_Accept ||
|
||||
@@ -329,6 +333,11 @@ static const struct tok radius_attribute_names[] = {
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
inline void MakeRadiusAuthenticator(unsigned char *authenticator) {
|
||||
for(int i=0;i<16;i++)
|
||||
authenticator[i]=std::rand() & 0xff;
|
||||
}
|
||||
|
||||
//
|
||||
// From: https://github.com/Telecominfraproject/wlan-dictionary/blob/main/dictionary.tip
|
||||
//
|
||||
@@ -598,11 +607,16 @@ static const struct tok radius_attribute_names[] = {
|
||||
std::string Result;
|
||||
for(const auto &attribute:Attrs_) {
|
||||
if(attribute.type==33) {
|
||||
const char * SN = (const char *)&P_.attributes[attribute.pos];
|
||||
auto i=0;
|
||||
while(*SN!=':' && i<12) {
|
||||
Result+=*SN++;
|
||||
i++;
|
||||
std::string Attr33;
|
||||
// format is serial:IP:port:interface
|
||||
Attr33.assign((const char *)(const char *)&P_.attributes[attribute.pos],attribute.len-2);
|
||||
auto Parts = Poco::StringTokenizer(Attr33,"|");
|
||||
if(Parts.count()==4) {
|
||||
return Parts[0];
|
||||
}
|
||||
Parts = Poco::StringTokenizer(Attr33,":");
|
||||
if(Parts.count()==4) {
|
||||
return Parts[0];
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
@@ -617,9 +631,16 @@ static const struct tok radius_attribute_names[] = {
|
||||
std::string Attr33;
|
||||
// format is serial:IP:port:interface
|
||||
Attr33.assign((const char *)(const char *)&P_.attributes[attribute.pos],attribute.len-2);
|
||||
auto Parts = Poco::StringTokenizer(Attr33,":");
|
||||
if(Parts.count()==4)
|
||||
return Parts[1]+":"+Parts[2];
|
||||
auto Parts = Poco::StringTokenizer(Attr33,"|");
|
||||
if(Parts.count()==4) {
|
||||
Poco::Net::SocketAddress D(Parts[1],Parts[2]);
|
||||
return D.toString();
|
||||
}
|
||||
Parts = Poco::StringTokenizer(Attr33,":");
|
||||
if(Parts.count()==4) {
|
||||
Poco::Net::SocketAddress D(Parts[1],Parts[2]);
|
||||
return D.toString();
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
}
|
||||
@@ -665,6 +686,44 @@ static const struct tok radius_attribute_names[] = {
|
||||
bool Valid_=false;
|
||||
};
|
||||
|
||||
class RadiusOutputPacket {
|
||||
public:
|
||||
explicit RadiusOutputPacket(const std::string &Secret)
|
||||
: Secret_(Secret) {
|
||||
}
|
||||
|
||||
inline void MakeStatusMessage() {
|
||||
P_.code = RADCMD_STATUS_SER;
|
||||
P_.identifier = std::rand() & 0x00ff;
|
||||
MakeRadiusAuthenticator(P_.authenticator);
|
||||
unsigned char MessageAuthenticator[16]{0};
|
||||
AddAttribute(ATTR_MessageAuthenticator,sizeof(MessageAuthenticator),MessageAuthenticator);
|
||||
P_.rawlen = 1 + 1 + 2 + 16 + 1 + 1 + 16;
|
||||
|
||||
Poco::HMACEngine<Poco::MD5Engine> H(Secret_);
|
||||
H.update((const unsigned char *)&P_, P_.rawlen);
|
||||
auto digest = H.digest();
|
||||
int p = 0;
|
||||
for (const auto &i : digest)
|
||||
P_.attributes[1 + 1 + p++] = i;
|
||||
}
|
||||
|
||||
inline void AddAttribute(unsigned char attr, uint8_t len, const unsigned char * data) {
|
||||
P_.attributes[AttributesLen_++] = attr;
|
||||
P_.attributes[AttributesLen_++] = len;
|
||||
memcpy(&P_.attributes[AttributesLen_],data,len);
|
||||
AttributesLen_+=len;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline const unsigned char * Data() const { return (const unsigned char *) &P_;}
|
||||
[[nodiscard]] inline std::uint16_t Len() const { return P_.rawlen; }
|
||||
|
||||
private:
|
||||
RawRadiusPacket P_;
|
||||
uint16_t AttributesLen_=0;
|
||||
std::string Secret_;
|
||||
};
|
||||
|
||||
inline std::ostream &operator<<(std::ostream &os, RadiusPacket const &P) {
|
||||
os << P.Attrs_ ;
|
||||
return os;
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
// Created by stephane bourque on 2022-05-18.
|
||||
//
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
#include "RADIUS_proxy_server.h"
|
||||
#include "RADIUS_helpers.h"
|
||||
#include "AP_WS_Server.h"
|
||||
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
const int SMALLEST_RADIUS_PACKET = 20+19+4;
|
||||
@@ -14,118 +19,133 @@ namespace OpenWifi {
|
||||
|
||||
int RADIUS_proxy_server::Start() {
|
||||
|
||||
ConfigFilename_ = MicroService::instance().DataDir()+"/radius_pool_config.json";
|
||||
ConfigFilename_ = MicroServiceDataDirectory()+"/radius_pool_config.json";
|
||||
Poco::File Config(ConfigFilename_);
|
||||
|
||||
enabled_ = MicroService::instance().ConfigGetBool("radius.proxy.enable",false);
|
||||
if(!enabled_ && !Config.exists())
|
||||
Enabled_ = MicroServiceConfigGetBool("radius.proxy.enable",false);
|
||||
if(!Enabled_ && !Config.exists()) {
|
||||
StopRADSECServers();
|
||||
return 0;
|
||||
}
|
||||
|
||||
enabled_ = true;
|
||||
poco_notice(Logger(),"Starting...");
|
||||
|
||||
Enabled_ = true;
|
||||
|
||||
Poco::Net::SocketAddress AuthSockAddrV4(Poco::Net::AddressFamily::IPv4,
|
||||
MicroService::instance().ConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
|
||||
AuthenticationSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV4,true);
|
||||
MicroServiceConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
|
||||
AuthenticationSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV4,true,true);
|
||||
Poco::Net::SocketAddress AuthSockAddrV6(Poco::Net::AddressFamily::IPv6,
|
||||
MicroService::instance().ConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
|
||||
AuthenticationSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV6,true);
|
||||
MicroServiceConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
|
||||
AuthenticationSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV6,true,true);
|
||||
|
||||
Poco::Net::SocketAddress AcctSockAddrV4(Poco::Net::AddressFamily::IPv4,
|
||||
MicroService::instance().ConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
|
||||
AccountingSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV4,true);
|
||||
MicroServiceConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
|
||||
AccountingSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV4,true,true);
|
||||
Poco::Net::SocketAddress AcctSockAddrV6(Poco::Net::AddressFamily::IPv6,
|
||||
MicroService::instance().ConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
|
||||
AccountingSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV6,true);
|
||||
MicroServiceConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
|
||||
AccountingSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV6,true,true);
|
||||
|
||||
Poco::Net::SocketAddress CoASockAddrV4(Poco::Net::AddressFamily::IPv4,
|
||||
MicroService::instance().ConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
|
||||
CoASocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV4,true);
|
||||
MicroServiceConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
|
||||
CoASocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV4,true,true);
|
||||
Poco::Net::SocketAddress CoASockAddrV6(Poco::Net::AddressFamily::IPv6,
|
||||
MicroService::instance().ConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
|
||||
CoASocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV6,true);
|
||||
MicroServiceConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
|
||||
CoASocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV6,true,true);
|
||||
|
||||
RadiusReactor_.addEventHandler(*AuthenticationSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
RadiusReactor_.reset();
|
||||
RadiusReactor_ = std::make_unique<Poco::Net::SocketReactor>();
|
||||
RadiusReactor_->addEventHandler(*AuthenticationSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
RadiusReactor_.addEventHandler(*AuthenticationSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
RadiusReactor_->addEventHandler(*AuthenticationSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
|
||||
RadiusReactor_.addEventHandler(*AccountingSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
RadiusReactor_->addEventHandler(*AccountingSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
RadiusReactor_.addEventHandler(*AccountingSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
RadiusReactor_->addEventHandler(*AccountingSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
|
||||
|
||||
RadiusReactor_.addEventHandler(*CoASocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
RadiusReactor_->addEventHandler(*CoASocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnCoASocketReadable));
|
||||
RadiusReactor_.addEventHandler(*CoASocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
RadiusReactor_->addEventHandler(*CoASocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnCoASocketReadable));
|
||||
|
||||
ParseConfig();
|
||||
|
||||
// start RADSEC servers...
|
||||
StartRADSECServers();
|
||||
RadiusReactorThread_.start(RadiusReactor_);
|
||||
|
||||
RadiusReactorThread_.start(*RadiusReactor_);
|
||||
Utils::SetThreadName(RadiusReactorThread_,"rad:reactor");
|
||||
|
||||
running_ = true;
|
||||
Running_ = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::Stop() {
|
||||
poco_information(Logger(),"Stopping...");
|
||||
if(enabled_ && running_) {
|
||||
RadiusReactor_.removeEventHandler(
|
||||
if(Enabled_ && Running_) {
|
||||
poco_information(Logger(),"Stopping...");
|
||||
RadiusReactor_->removeEventHandler(
|
||||
*AuthenticationSocketV4_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
RadiusReactor_.removeEventHandler(
|
||||
RadiusReactor_->removeEventHandler(
|
||||
*AuthenticationSocketV6_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
|
||||
|
||||
RadiusReactor_.removeEventHandler(
|
||||
RadiusReactor_->removeEventHandler(
|
||||
*AccountingSocketV4_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
RadiusReactor_.removeEventHandler(
|
||||
RadiusReactor_->removeEventHandler(
|
||||
*AccountingSocketV6_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
|
||||
|
||||
RadiusReactor_.removeEventHandler(
|
||||
RadiusReactor_->removeEventHandler(
|
||||
*CoASocketV4_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnCoASocketReadable));
|
||||
RadiusReactor_.removeEventHandler(
|
||||
RadiusReactor_->removeEventHandler(
|
||||
*CoASocketV6_,
|
||||
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADIUS_proxy_server::OnCoASocketReadable));
|
||||
|
||||
for(auto &[_,radsec_server]:RADSECservers_)
|
||||
radsec_server->Stop();
|
||||
AuthenticationSocketV4_->close();
|
||||
AuthenticationSocketV6_->close();
|
||||
AccountingSocketV4_->close();
|
||||
AccountingSocketV6_->close();
|
||||
CoASocketV4_->close();
|
||||
CoASocketV6_->close();
|
||||
|
||||
RadiusReactor_.stop();
|
||||
AuthenticationSocketV4_.reset();
|
||||
AuthenticationSocketV6_.reset();
|
||||
AccountingSocketV4_.reset();
|
||||
AccountingSocketV6_.reset();
|
||||
CoASocketV4_.reset();
|
||||
CoASocketV6_.reset();
|
||||
|
||||
StopRADSECServers();
|
||||
RadiusReactor_->stop();
|
||||
RadiusReactorThread_.join();
|
||||
enabled_=false;
|
||||
running_=false;
|
||||
Running_=false;
|
||||
poco_information(Logger(),"Stopped...");
|
||||
}
|
||||
poco_information(Logger(),"Stopped...");
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::StartRADSECServers() {
|
||||
std::lock_guard G(Mutex_);
|
||||
for(const auto &pool:PoolList_.pools) {
|
||||
for(const auto &entry:pool.authConfig.servers) {
|
||||
if(entry.radsec) {
|
||||
StartRADSECServer(entry);
|
||||
RADSECservers_[ Poco::Net::SocketAddress(entry.ip,0) ] = std::make_unique<RADSEC_server>(*RadiusReactor_,entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::StartRADSECServer(const GWObjects::RadiusProxyServerEntry &E) {
|
||||
RADSECservers_[ Poco::Net::SocketAddress(E.ip,0) ] = std::make_unique<RADSECserver>(RadiusReactor_,E);
|
||||
void RADIUS_proxy_server::StopRADSECServers() {
|
||||
std::lock_guard G(Mutex_);
|
||||
RADSECservers_.clear();
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::OnAccountingSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
|
||||
@@ -196,7 +216,7 @@ namespace OpenWifi {
|
||||
|
||||
void RADIUS_proxy_server::SendAccountingData(const std::string &serialNumber, const char *buffer, std::size_t size) {
|
||||
|
||||
if(Pools_.empty() || !enabled_)
|
||||
if(!Continue())
|
||||
return;
|
||||
|
||||
try {
|
||||
@@ -254,7 +274,7 @@ namespace OpenWifi {
|
||||
|
||||
void RADIUS_proxy_server::SendAuthenticationData(const std::string &serialNumber, const char *buffer, std::size_t size) {
|
||||
|
||||
if(Pools_.empty() || !enabled_)
|
||||
if(!Continue())
|
||||
return;
|
||||
|
||||
try {
|
||||
@@ -307,7 +327,7 @@ namespace OpenWifi {
|
||||
|
||||
void RADIUS_proxy_server::SendCoAData(const std::string &serialNumber, const char *buffer, std::size_t size) {
|
||||
|
||||
if(Pools_.empty() || !enabled_)
|
||||
if(!Continue())
|
||||
return;
|
||||
|
||||
try {
|
||||
@@ -377,7 +397,7 @@ namespace OpenWifi {
|
||||
};
|
||||
|
||||
if(setAsDefault && D.useRADSEC)
|
||||
defaultIsRADSEC_ = true;
|
||||
DefaultIsRADSEC_ = true;
|
||||
|
||||
if(S.family()==Poco::Net::IPAddress::IPv4) {
|
||||
TotalV4 += server.weight;
|
||||
@@ -471,26 +491,26 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
if(defaultIsRADSEC_) {
|
||||
if(DefaultIsRADSEC_) {
|
||||
UseRADSEC = true;
|
||||
return (IsV4 ? Pools_[defaultPoolIndex_].AuthV4[0].Addr : Pools_[defaultPoolIndex_].AuthV6[0].Addr );
|
||||
return (IsV4 ? Pools_[DefaultPoolIndex_].AuthV4[0].Addr : Pools_[DefaultPoolIndex_].AuthV6[0].Addr );
|
||||
}
|
||||
|
||||
switch(rtype) {
|
||||
case radius_type::auth: {
|
||||
return ChooseAddress(IsV4 ? Pools_[defaultPoolIndex_].AuthV4
|
||||
: Pools_[defaultPoolIndex_].AuthV6,
|
||||
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].AuthV4
|
||||
: Pools_[DefaultPoolIndex_].AuthV6,
|
||||
RequestedAddress);
|
||||
}
|
||||
case radius_type::acct:
|
||||
default: {
|
||||
return ChooseAddress(IsV4 ? Pools_[defaultPoolIndex_].AcctV4
|
||||
: Pools_[defaultPoolIndex_].AcctV6,
|
||||
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].AcctV4
|
||||
: Pools_[DefaultPoolIndex_].AcctV6,
|
||||
RequestedAddress);
|
||||
}
|
||||
case radius_type::coa: {
|
||||
return ChooseAddress(IsV4 ? Pools_[defaultPoolIndex_].CoaV4
|
||||
: Pools_[defaultPoolIndex_].CoaV6,
|
||||
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].CoaV4
|
||||
: Pools_[DefaultPoolIndex_].CoaV6,
|
||||
RequestedAddress);
|
||||
}
|
||||
}
|
||||
@@ -609,7 +629,6 @@ namespace OpenWifi {
|
||||
|
||||
void RADIUS_proxy_server::SetConfig(const GWObjects::RadiusProxyPoolList &C) {
|
||||
std::lock_guard G(Mutex_);
|
||||
PoolList_ = C;
|
||||
|
||||
Poco::JSON::Object Disk;
|
||||
C.to_json(Disk);
|
||||
@@ -618,17 +637,17 @@ namespace OpenWifi {
|
||||
Disk.stringify(ofs);
|
||||
ofs.close();
|
||||
|
||||
if(!running_) {
|
||||
Start();
|
||||
}
|
||||
|
||||
ParseConfig();
|
||||
Stop();
|
||||
ResetConfig();
|
||||
PoolList_ = C;
|
||||
Start();
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::ResetConfig() {
|
||||
PoolList_.pools.clear();
|
||||
Pools_.clear();
|
||||
defaultPoolIndex_=0;
|
||||
DefaultPoolIndex_=0;
|
||||
DefaultIsRADSEC_=false;
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::DeleteConfig() {
|
||||
@@ -641,8 +660,8 @@ namespace OpenWifi {
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
ResetConfig();
|
||||
Stop();
|
||||
ResetConfig();
|
||||
}
|
||||
|
||||
void RADIUS_proxy_server::GetConfig(GWObjects::RadiusProxyPoolList &C) {
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
|
||||
#include "Poco/Net/DatagramSocket.h"
|
||||
#include "Poco/Net/SocketReactor.h"
|
||||
|
||||
#include "RADSECserver.h"
|
||||
#include "framework/SubSystemServer.h"
|
||||
|
||||
#include "RADSEC_server.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -28,7 +29,7 @@ namespace OpenWifi {
|
||||
|
||||
int Start() final;
|
||||
void Stop() final;
|
||||
inline bool Enabled() const { return enabled_; }
|
||||
inline bool Enabled() const { return Enabled_; }
|
||||
|
||||
void OnAccountingSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
||||
void OnAuthenticationSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
|
||||
@@ -43,7 +44,7 @@ namespace OpenWifi {
|
||||
void GetConfig(GWObjects::RadiusProxyPoolList &C);
|
||||
|
||||
void StartRADSECServers();
|
||||
void StartRADSECServer(const GWObjects::RadiusProxyServerEntry &E);
|
||||
void StopRADSECServers();
|
||||
|
||||
struct Destination {
|
||||
Poco::Net::SocketAddress Addr;
|
||||
@@ -60,6 +61,10 @@ namespace OpenWifi {
|
||||
std::vector<std::string> realms;
|
||||
};
|
||||
|
||||
inline bool Continue() const {
|
||||
return Running_ && Enabled_ && !Pools_.empty();
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV4_;
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV6_;
|
||||
@@ -67,13 +72,13 @@ namespace OpenWifi {
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> AuthenticationSocketV6_;
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> CoASocketV4_;
|
||||
std::unique_ptr<Poco::Net::DatagramSocket> CoASocketV6_;
|
||||
Poco::Net::SocketReactor RadiusReactor_;
|
||||
Poco::Thread RadiusReactorThread_;
|
||||
std::unique_ptr<Poco::Net::SocketReactor> RadiusReactor_;
|
||||
Poco::Thread RadiusReactorThread_;
|
||||
|
||||
GWObjects::RadiusProxyPoolList PoolList_;
|
||||
std::string ConfigFilename_;
|
||||
|
||||
std::map<Poco::Net::SocketAddress, std::unique_ptr<RADSECserver>> RADSECservers_;
|
||||
std::map<Poco::Net::SocketAddress, std::unique_ptr<RADSEC_server>> RADSECservers_;
|
||||
|
||||
struct RadiusPool {
|
||||
std::vector<Destination> AuthV4;
|
||||
@@ -85,10 +90,10 @@ namespace OpenWifi {
|
||||
};
|
||||
|
||||
std::vector<RadiusPool> Pools_;
|
||||
uint defaultPoolIndex_=0;
|
||||
bool enabled_=false;
|
||||
bool defaultIsRADSEC_=false;
|
||||
std::atomic_bool running_=false;
|
||||
uint DefaultPoolIndex_=0;
|
||||
bool Enabled_=false;
|
||||
bool DefaultIsRADSEC_=false;
|
||||
std::atomic_bool Running_=false;
|
||||
|
||||
RADIUS_proxy_server() noexcept:
|
||||
SubSystemServer("RADIUS-PROXY", "RADIUS-PROXY", "radius.proxy")
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
|
||||
#include "Poco/Net/SocketReactor.h"
|
||||
@@ -18,31 +16,60 @@
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/TemporaryFile.h"
|
||||
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include "RADIUS_helpers.h"
|
||||
#include "AP_WS_Server.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class RADSECserver : public Poco::Runnable {
|
||||
class RADSEC_server : public Poco::Runnable {
|
||||
public:
|
||||
RADSECserver(Poco::Net::SocketReactor & R, GWObjects::RadiusProxyServerEntry E) :
|
||||
RADSEC_server(Poco::Net::SocketReactor & R, GWObjects::RadiusProxyServerEntry E) :
|
||||
Reactor_(R),
|
||||
Server_(std::move(E)),
|
||||
Logger_(Poco::Logger::get(fmt::format("RADSEC: {}@{}:{}",
|
||||
Server_.name ,
|
||||
Server_.ip,
|
||||
Server_.port)))
|
||||
{
|
||||
ReconnectorThr_.start(*this);
|
||||
Server_.port))) {
|
||||
Start();
|
||||
}
|
||||
|
||||
~RADSEC_server() {
|
||||
Stop();
|
||||
}
|
||||
|
||||
inline int Start() {
|
||||
ReconnectThread_.start(*this);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void Stop() {
|
||||
TryAgain_ = false;
|
||||
Disconnect();
|
||||
ReconnectThread_.wakeUp();
|
||||
ReconnectThread_.join();
|
||||
}
|
||||
|
||||
inline void run() final {
|
||||
Poco::Thread::trySleep(3000);
|
||||
std::uint64_t LastStatus=0 ;
|
||||
auto RadSecKeepAlive = MicroServiceConfigGetInt("radsec.keepalive",120);
|
||||
while(TryAgain_) {
|
||||
if(!Connected_) {
|
||||
std::unique_lock G(Mutex_);
|
||||
std::lock_guard G(LocalMutex_);
|
||||
LastStatus = Utils::Now() ;
|
||||
Connect();
|
||||
} else if( (Utils::Now() - LastStatus) > RadSecKeepAlive) {
|
||||
RADIUS::RadiusOutputPacket P(Server_.radsecSecret);
|
||||
P.MakeStatusMessage();
|
||||
poco_information(Logger_,"Keep-Alive message.");
|
||||
Socket_->sendBytes(P.Data(), P.Len());
|
||||
LastStatus = Utils::Now();
|
||||
}
|
||||
Poco::Thread::trySleep(1000);
|
||||
Poco::Thread::trySleep(!Connected_ ? 3000 : 10000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,22 +77,23 @@ namespace OpenWifi {
|
||||
try {
|
||||
if (Connected_) {
|
||||
RADIUS::RadiusPacket P(buffer, length);
|
||||
// std::cout << serial_number << " Sending " << P.PacketType() << " " << length << " bytes" << std::endl;
|
||||
int sent_bytes;
|
||||
if (P.VerifyMessageAuthenticator(Server_.radsecSecret)) {
|
||||
poco_debug(Logger_,fmt::format("{}: {} Sending {} bytes", serial_number,
|
||||
P.PacketType(), length));
|
||||
poco_debug(Logger_, fmt::format("{}: {} Sending {} bytes", serial_number,
|
||||
P.PacketType(), length));
|
||||
sent_bytes = Socket_->sendBytes(buffer, length);
|
||||
} else {
|
||||
poco_debug(Logger_,fmt::format("{}: {} Sending {} bytes", serial_number,
|
||||
P.PacketType(), length));
|
||||
poco_debug(Logger_, fmt::format("{}: {} Sending {} bytes", serial_number,
|
||||
P.PacketType(), length));
|
||||
P.ComputeMessageAuthenticator(Server_.radsecSecret);
|
||||
sent_bytes = Socket_->sendBytes(P.Buffer(), length);
|
||||
}
|
||||
return (sent_bytes == length);
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
} catch (...) {
|
||||
|
||||
poco_warning(Logger_,"Exception occurred: while sending data.");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -75,7 +103,7 @@ namespace OpenWifi {
|
||||
|
||||
try {
|
||||
auto NumberOfReceivedBytes = Socket_->receiveBytes(Buffer,sizeof(Buffer));
|
||||
if(NumberOfReceivedBytes>40) {
|
||||
if(NumberOfReceivedBytes>=20) {
|
||||
RADIUS::RadiusPacket P(Buffer,NumberOfReceivedBytes);
|
||||
if (P.IsAuthentication()) {
|
||||
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
||||
@@ -86,9 +114,7 @@ namespace OpenWifi {
|
||||
AP_WS_Server()->SendRadiusAuthenticationData(SerialNumber, Buffer,
|
||||
NumberOfReceivedBytes);
|
||||
} else {
|
||||
poco_debug(Logger_,
|
||||
fmt::format("Invalid AUTH packet received in proxy dropped. No serial number Source={}",
|
||||
Socket_->address().toString()));
|
||||
poco_debug(Logger_, "AUTH packet dropped.");
|
||||
}
|
||||
} else if (P.IsAccounting()) {
|
||||
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
|
||||
@@ -99,53 +125,72 @@ namespace OpenWifi {
|
||||
AP_WS_Server()->SendRadiusAccountingData(SerialNumber, Buffer,
|
||||
NumberOfReceivedBytes);
|
||||
} else {
|
||||
poco_debug(Logger_,
|
||||
fmt::format("Invalid ACCT packet received in proxy dropped. No serial number Source={}",
|
||||
Socket_->address().toString()));
|
||||
poco_debug(Logger_, "ACCT packet dropped.");
|
||||
}
|
||||
} else if (P.IsAuthority()) {
|
||||
auto SerialNumber = P.ExtractSerialNumberTIP();
|
||||
if(!SerialNumber.empty()) {
|
||||
poco_debug(Logger_,
|
||||
fmt::format("{}: {} Received {} bytes.", SerialNumber,
|
||||
P.PacketType(), NumberOfReceivedBytes));
|
||||
AP_WS_Server()->SendRadiusCoAData(SerialNumber, Buffer,
|
||||
NumberOfReceivedBytes);
|
||||
} else {
|
||||
poco_debug(Logger_, "CoA/DM packet dropped.");
|
||||
}
|
||||
} else {
|
||||
poco_warning(Logger_,fmt::format("Unknown packet: Type: {} (type={}) Length={}", P.PacketType(), P.PacketTypeInt(), P.BufferLen()));
|
||||
}
|
||||
} else {
|
||||
poco_warning(Logger_,"Invalid packet received. Resetting the connection.");
|
||||
Disconnect();
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
Disconnect();
|
||||
} catch (...) {
|
||||
Disconnect();
|
||||
poco_warning(Logger_,"Exception occurred. Resetting the connection.");
|
||||
}
|
||||
}
|
||||
|
||||
inline void onError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf) {
|
||||
std::cout << "onError" << std::endl;
|
||||
poco_warning(Logger_,"Socker error. Terminating connection.");
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
inline void onShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf) {
|
||||
std::cout << "onShutdown" << std::endl;
|
||||
poco_warning(Logger_,"Socker socket shutdown. Terminating connection.");
|
||||
Disconnect();
|
||||
}
|
||||
|
||||
inline bool Connect() {
|
||||
if(TryAgain_) {
|
||||
std::lock_guard G(LocalMutex_);
|
||||
|
||||
Poco::TemporaryFile CertFile_(MicroService::instance().DataDir());
|
||||
Poco::TemporaryFile KeyFile_(MicroService::instance().DataDir());
|
||||
std::vector<Poco::TemporaryFile> CaCertFiles_;
|
||||
Poco::TemporaryFile CertFile_(MicroServiceDataDirectory());
|
||||
Poco::TemporaryFile KeyFile_(MicroServiceDataDirectory());
|
||||
std::vector<std::unique_ptr<Poco::TemporaryFile>> CaCertFiles_;
|
||||
|
||||
DecodeFile(CertFile_.path(), Server_.radsecCert);
|
||||
DecodeFile(KeyFile_.path(), Server_.radsecKey);
|
||||
|
||||
for(auto &cert:Server_.radsecCacerts) {
|
||||
CaCertFiles_.emplace_back(Poco::TemporaryFile(MicroService::instance().DataDir()));
|
||||
DecodeFile(CaCertFiles_[CaCertFiles_.size()-1].path(), cert);
|
||||
CaCertFiles_.emplace_back(std::make_unique<Poco::TemporaryFile>(MicroServiceDataDirectory()));
|
||||
DecodeFile(CaCertFiles_[CaCertFiles_.size()-1]->path(), cert);
|
||||
}
|
||||
|
||||
Poco::Net::Context::Ptr SecureContext = Poco::AutoPtr<Poco::Net::Context>(
|
||||
new Poco::Net::Context(Poco::Net::Context::TLS_CLIENT_USE,
|
||||
KeyFile_.path(),
|
||||
CertFile_.path(),""));
|
||||
if(Server_.allowSelfSigned) {
|
||||
SecureContext->setSecurityLevel(Poco::Net::Context::SECURITY_LEVEL_NONE);
|
||||
SecureContext->enableExtendedCertificateVerification(false);
|
||||
}
|
||||
|
||||
for(const auto &ca:CaCertFiles_) {
|
||||
Poco::Crypto::X509Certificate cert(ca.path());
|
||||
Poco::Crypto::X509Certificate cert(ca->path());
|
||||
SecureContext->addCertificateAuthority(cert);
|
||||
}
|
||||
|
||||
@@ -157,7 +202,10 @@ namespace OpenWifi {
|
||||
poco_information(Logger_, "Attempting to connect");
|
||||
Socket_->connect(Destination, Poco::Timespan(100, 0));
|
||||
Socket_->completeHandshake();
|
||||
Socket_->verifyPeerCertificate();
|
||||
|
||||
if(!Server_.allowSelfSigned) {
|
||||
Socket_->verifyPeerCertificate();
|
||||
}
|
||||
|
||||
if(Socket_->havePeerCertificate()) {
|
||||
Peer_Cert_ = std::make_unique<Poco::Crypto::X509Certificate>(Socket_->peerCertificate());
|
||||
@@ -166,21 +214,19 @@ namespace OpenWifi {
|
||||
Socket_->setBlocking(false);
|
||||
Socket_->setNoDelay(true);
|
||||
Socket_->setKeepAlive(true);
|
||||
Socket_->setReceiveTimeout(Poco::Timespan(1 * 60 * 60,0));
|
||||
|
||||
Reactor_.addEventHandler(
|
||||
*Socket_,
|
||||
Poco::NObserver<RADSECserver, Poco::Net::ReadableNotification>(
|
||||
*this, &RADSECserver::onData));
|
||||
Poco::NObserver<RADSEC_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADSEC_server::onData));
|
||||
Reactor_.addEventHandler(
|
||||
*Socket_, Poco::NObserver<RADSECserver, Poco::Net::ErrorNotification>(
|
||||
*this, &RADSECserver::onError));
|
||||
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ErrorNotification>(
|
||||
*this, &RADSEC_server::onError));
|
||||
Reactor_.addEventHandler(
|
||||
*Socket_,
|
||||
Poco::NObserver<RADSECserver, Poco::Net::ShutdownNotification>(
|
||||
*this, &RADSECserver::onShutdown));
|
||||
Socket_->setBlocking(false);
|
||||
Socket_->setNoDelay(true);
|
||||
Socket_->setKeepAlive(true);
|
||||
Poco::NObserver<RADSEC_server, Poco::Net::ShutdownNotification>(
|
||||
*this, &RADSEC_server::onShutdown));
|
||||
|
||||
Connected_ = true;
|
||||
poco_information(Logger_,fmt::format("Connected. CN={}",CommonName()));
|
||||
@@ -200,29 +246,23 @@ namespace OpenWifi {
|
||||
|
||||
inline void Disconnect() {
|
||||
if(Connected_) {
|
||||
std::unique_lock G(Mutex_);
|
||||
std::lock_guard G(LocalMutex_);
|
||||
|
||||
Reactor_.removeEventHandler(
|
||||
*Socket_, Poco::NObserver<RADSECserver, Poco::Net::ReadableNotification>(
|
||||
*this, &RADSECserver::onData));
|
||||
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ReadableNotification>(
|
||||
*this, &RADSEC_server::onData));
|
||||
Reactor_.removeEventHandler(
|
||||
*Socket_, Poco::NObserver<RADSECserver, Poco::Net::ErrorNotification>(
|
||||
*this, &RADSECserver::onError));
|
||||
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ErrorNotification>(
|
||||
*this, &RADSEC_server::onError));
|
||||
Reactor_.removeEventHandler(
|
||||
*Socket_, Poco::NObserver<RADSECserver, Poco::Net::ShutdownNotification>(
|
||||
*this, &RADSECserver::onShutdown));
|
||||
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ShutdownNotification>(
|
||||
*this, &RADSEC_server::onShutdown));
|
||||
Socket_->close();
|
||||
Connected_ = false;
|
||||
}
|
||||
poco_information(Logger_,"Disconnecting.");
|
||||
}
|
||||
|
||||
inline void Stop() {
|
||||
TryAgain_ = false;
|
||||
Disconnect();
|
||||
ReconnectorThr_.wakeUp();
|
||||
ReconnectorThr_.join();
|
||||
}
|
||||
|
||||
static void DecodeFile(const std::string &filename, const std::string &s) {
|
||||
std::ofstream sec_file(filename,std::ios_base::out|std::ios_base::trunc|std::ios_base::binary);
|
||||
std::stringstream is(s);
|
||||
@@ -250,14 +290,14 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_mutex Mutex_;
|
||||
std::recursive_mutex LocalMutex_;
|
||||
Poco::Net::SocketReactor &Reactor_;
|
||||
GWObjects::RadiusProxyServerEntry Server_;
|
||||
Poco::Logger &Logger_;
|
||||
std::atomic_bool Connected_=false;
|
||||
std::atomic_bool TryAgain_=true;
|
||||
std::unique_ptr<Poco::Net::SecureStreamSocket> Socket_;
|
||||
Poco::Thread ReconnectorThr_;
|
||||
Poco::Thread ReconnectThread_;
|
||||
std::unique_ptr<Poco::Crypto::X509Certificate> Peer_Cert_;
|
||||
volatile bool Connected_=false;
|
||||
volatile bool TryAgain_=true;
|
||||
};
|
||||
}
|
||||
@@ -11,7 +11,10 @@
|
||||
#include "AP_WS_Server.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/ow_constants.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "ParseWifiScan.h"
|
||||
#include "framework/utils.h"
|
||||
#include <GWKafkaEvents.h>
|
||||
|
||||
namespace OpenWifi::RESTAPI_RPC {
|
||||
void SetCommandStatus(GWObjects::CommandDetails &Cmd,
|
||||
@@ -32,6 +35,7 @@ namespace OpenWifi::RESTAPI_RPC {
|
||||
}
|
||||
|
||||
void WaitForCommand(uint64_t RPCID,
|
||||
APCommands::Commands Command,
|
||||
bool RetryLater,
|
||||
GWObjects::CommandDetails &Cmd,
|
||||
Poco::JSON::Object & Params,
|
||||
@@ -57,12 +61,12 @@ namespace OpenWifi::RESTAPI_RPC {
|
||||
return SetCommandStatus(Cmd, Request, Response, Handler, Storage::CommandExecutionType::COMMAND_FAILED, Logger);
|
||||
}
|
||||
|
||||
Cmd.Executed = OpenWifi::Now();
|
||||
Cmd.Executed = Utils::Now();
|
||||
|
||||
bool Sent;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> rpc_submitted = std::chrono::high_resolution_clock::now();
|
||||
std::shared_ptr<CommandManager::promise_type_t> rpc_endpoint =
|
||||
CommandManager()->PostCommand(RPCID, Cmd.SerialNumber, Cmd.Command, Params, Cmd.UUID, Sent);
|
||||
CommandManager()->PostCommand(RPCID, Command, Cmd.SerialNumber, Cmd.Command, Params, Cmd.UUID, Sent, true);
|
||||
|
||||
if(RetryLater && (!Sent || rpc_endpoint== nullptr)) {
|
||||
Logger.information(fmt::format("{},{}: Pending completion. Device is not connected.", Cmd.UUID, RPCID));
|
||||
@@ -80,13 +84,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") {
|
||||
@@ -99,40 +103,53 @@ namespace OpenWifi::RESTAPI_RPC {
|
||||
return;
|
||||
}
|
||||
|
||||
//Issue Id : WIFI-12072 : Added Log to print the error message received from AP.
|
||||
std::ostringstream rpcss;
|
||||
ResultFields->stringify(rpcss);
|
||||
nlohmann::json D = nlohmann::json::parse(rpcss.str());
|
||||
Logger.information(fmt::format("Response Received from AP :{} ",rpcss.str() ));
|
||||
|
||||
auto StatusInnerObj = ResultFields->get(uCentralProtocol::STATUS).extract<Poco::JSON::Object::Ptr>();
|
||||
if (StatusInnerObj->has(uCentralProtocol::ERROR))
|
||||
Cmd.ErrorCode = StatusInnerObj->get(uCentralProtocol::ERROR);
|
||||
if (StatusInnerObj->has(uCentralProtocol::TEXT))
|
||||
Cmd.ErrorText = StatusInnerObj->get(uCentralProtocol::TEXT).toString();
|
||||
std::stringstream ResultText;
|
||||
if(rpc_answer.has(uCentralProtocol::RESULT)) {
|
||||
if(rpc_answer->has(uCentralProtocol::RESULT)) {
|
||||
if(Cmd.Command==uCentralProtocol::WIFISCAN) {
|
||||
auto ScanObj = rpc_answer.get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
|
||||
auto ScanObj = rpc_answer->get(uCentralProtocol::RESULT).extract<Poco::JSON::Object::Ptr>();
|
||||
ParseWifiScan(ScanObj, ResultText, Logger);
|
||||
} else {
|
||||
Poco::JSON::Stringifier::stringify(
|
||||
rpc_answer.get(uCentralProtocol::RESULT), ResultText);
|
||||
rpc_answer->get(uCentralProtocol::RESULT), ResultText);
|
||||
}
|
||||
} if (rpc_answer.has(uCentralProtocol::RESULT_64)) {
|
||||
} if (rpc_answer->has(uCentralProtocol::RESULT_64)) {
|
||||
uint64_t sz=0;
|
||||
if(rpc_answer.has(uCentralProtocol::RESULT_SZ))
|
||||
sz=rpc_answer.get(uCentralProtocol::RESULT_SZ);
|
||||
if(rpc_answer->has(uCentralProtocol::RESULT_SZ))
|
||||
sz=rpc_answer->get(uCentralProtocol::RESULT_SZ);
|
||||
std::string UnCompressedData;
|
||||
Utils::ExtractBase64CompressedData(rpc_answer.get(uCentralProtocol::RESULT_64).toString(),
|
||||
Utils::ExtractBase64CompressedData(rpc_answer->get(uCentralProtocol::RESULT_64).toString(),
|
||||
UnCompressedData,sz);
|
||||
Poco::JSON::Stringifier::stringify(UnCompressedData, ResultText);
|
||||
}
|
||||
Cmd.Results = ResultText.str();
|
||||
Cmd.Status = "completed";
|
||||
Cmd.Completed = OpenWifi::Now();
|
||||
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 = "";
|
||||
}
|
||||
|
||||
if(Cmd.ErrorCode==0 && Cmd.Command == uCentralProtocol::CONFIGURE) {
|
||||
// we need to post a kafka event for this.
|
||||
if(Params.has(uCentralProtocol::CONFIG)) {
|
||||
DeviceConfigurationChangeKafkaEvent KEvent(Cmd.SerialNumber,Utils::Now(),Params.get(uCentralProtocol::CONFIG).toString());
|
||||
}
|
||||
}
|
||||
|
||||
// Add the completed command to the database...
|
||||
StorageService()->AddCommand(Cmd.SerialNumber, Cmd, Storage::CommandExecutionType::COMMAND_COMPLETED);
|
||||
|
||||
@@ -156,4 +173,4 @@ namespace OpenWifi::RESTAPI_RPC {
|
||||
return SetCommandStatus(Cmd, Request, Response, Handler, Storage::CommandExecutionType::COMMAND_FAILED, Logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,12 +16,15 @@
|
||||
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
|
||||
namespace OpenWifi::RESTAPI_RPC {
|
||||
|
||||
void WaitForCommand(
|
||||
uint64_t RPCID,
|
||||
APCommands::Commands Command,
|
||||
bool RetryLater,
|
||||
GWObjects::CommandDetails &Cmd,
|
||||
Poco::JSON::Object & Params,
|
||||
|
||||
@@ -6,13 +6,11 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Poco/JSON/Stringifier.h"
|
||||
#include "RESTAPI_blacklist.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/ow_constants.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_blacklist::DoDelete() {
|
||||
@@ -22,6 +20,8 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
poco_debug(Logger(),fmt::format("BLACKLIST-DELETE: {}", SerialNumber));
|
||||
|
||||
GWObjects::BlackListedDevice D;
|
||||
if(!StorageService()->GetBlackListDevice(SerialNumber, D)) {
|
||||
return NotFound();
|
||||
@@ -40,14 +40,12 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
poco_debug(Logger(),fmt::format("BLACKLIST-GET: {}", SerialNumber));
|
||||
GWObjects::BlackListedDevice D;
|
||||
if(!StorageService()->GetBlackListDevice(SerialNumber, D)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
Poco::JSON::Object Answer;
|
||||
D.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
return Object(D);
|
||||
}
|
||||
|
||||
void RESTAPI_blacklist::DoPost() {
|
||||
@@ -62,22 +60,20 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
poco_debug(Logger(),fmt::format("BLACKLIST-POST: {}", D.serialNumber));
|
||||
|
||||
Poco::toLowerInPlace(D.serialNumber);
|
||||
if(StorageService()->IsBlackListed(D.serialNumber)) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberExists);
|
||||
}
|
||||
|
||||
D.author = UserInfo_.userinfo.email;
|
||||
D.created = OpenWifi::Now();
|
||||
D.created = Utils::Now();
|
||||
|
||||
if(StorageService()->AddBlackListDevice(D)) {
|
||||
GWObjects::BlackListedDevice CreatedDevice;
|
||||
|
||||
StorageService()->GetBlackListDevice(D.serialNumber,CreatedDevice);
|
||||
Poco::JSON::Object Answer;
|
||||
|
||||
CreatedDevice.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
return Object(CreatedDevice);
|
||||
}
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
@@ -94,6 +90,8 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
poco_debug(Logger(),fmt::format("BLACKLIST-PUT: {}", SerialNumber));
|
||||
|
||||
GWObjects::BlackListedDevice NewDevice;
|
||||
if(!NewDevice.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
@@ -106,10 +104,7 @@ namespace OpenWifi {
|
||||
GWObjects::BlackListedDevice CreatedDevice;
|
||||
|
||||
StorageService()->GetBlackListDevice(SerialNumber,CreatedDevice);
|
||||
Poco::JSON::Object Answer;
|
||||
|
||||
CreatedDevice.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
return Object(CreatedDevice);
|
||||
}
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_blacklist : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_blacklist(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server , uint64_t TransactionId , bool Internal)
|
||||
RESTAPI_blacklist(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server , uint64_t TransactionId , bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_POST,
|
||||
|
||||
@@ -10,22 +10,16 @@
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_blacklist_list::DoGet() {
|
||||
|
||||
std::vector<GWObjects::BlackListedDevice> Devices;
|
||||
poco_debug(Logger(),fmt::format("BLACKLIST-GET: Device serial number list"));
|
||||
|
||||
Poco::JSON::Array Arr;
|
||||
Poco::JSON::Object Answer;
|
||||
std::vector<GWObjects::BlackListedDevice> Devices;
|
||||
|
||||
if(QB_.CountOnly) {
|
||||
auto Count = StorageService()->GetBlackListDeviceCount();
|
||||
return ReturnCountOnly(Count);
|
||||
} else if(StorageService()->GetBlackListDevices(QB_.Offset, QB_.Limit, Devices)) {
|
||||
for(const auto &i:Devices) {
|
||||
Poco::JSON::Object O;
|
||||
i.to_json(O);
|
||||
Arr.add(O);
|
||||
}
|
||||
return Object("devices",Devices);
|
||||
}
|
||||
Answer.set("devices", Arr);
|
||||
return ReturnObject(Answer);
|
||||
NotFound();
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_blacklist_list : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_blacklist_list(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
|
||||
RESTAPI_blacklist_list(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},
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_capabilities_handler::DoGet() {
|
||||
CapabilitiesCache_t Caps = CapabilitiesCache().AllCapabilities();
|
||||
CapabilitiesCache_t Caps = CapabilitiesCache()->AllCapabilities();
|
||||
|
||||
Poco::JSON::Array ObjArr;
|
||||
for(const auto &[deviceType,capabilities]:Caps) {
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_capabilities_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_capabilities_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
|
||||
RESTAPI_capabilities_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
|
||||
@@ -20,9 +20,7 @@ namespace OpenWifi {
|
||||
|
||||
GWObjects::CommandDetails Command;
|
||||
if (StorageService()->GetCommand(CommandUUID, Command)) {
|
||||
Poco::JSON::Object RetObj;
|
||||
Command.to_json(RetObj);
|
||||
return ReturnObject(RetObj);
|
||||
return Object(Command);
|
||||
}
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_command : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
|
||||
RESTAPI_command(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_DELETE,
|
||||
|
||||
@@ -24,15 +24,7 @@ namespace OpenWifi {
|
||||
StorageService()->GetCommands(SerialNumber, QB_.StartDate, QB_.EndDate, QB_.Offset, QB_.Limit,
|
||||
Commands);
|
||||
}
|
||||
Poco::JSON::Array ArrayObj;
|
||||
for (const auto &i : Commands) {
|
||||
Poco::JSON::Object Obj;
|
||||
i.to_json(Obj);
|
||||
ArrayObj.add(Obj);
|
||||
}
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(RESTAPI::Protocol::COMMANDS, ArrayObj);
|
||||
ReturnObject(RetObj);
|
||||
return Object(RESTAPI::Protocol::COMMANDS, Commands);
|
||||
}
|
||||
|
||||
void RESTAPI_commands::DoDelete() {
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_commands : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_commands(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
|
||||
RESTAPI_commands(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_DELETE,
|
||||
|
||||
@@ -15,15 +15,14 @@
|
||||
#include "framework/ow_constants.h"
|
||||
#include "framework/ConfigurationValidator.h"
|
||||
#include "framework/orm.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_default_configuration::DoGet() {
|
||||
std::string Name = ORM::Escape(GetBinding(RESTAPI::Protocol::NAME, ""));
|
||||
GWObjects::DefaultConfiguration DefConfig;
|
||||
if (StorageService()->GetDefaultConfiguration(Name, DefConfig)) {
|
||||
Poco::JSON::Object Obj;
|
||||
DefConfig.to_json(Obj);
|
||||
return ReturnObject(Obj);
|
||||
return Object(DefConfig);
|
||||
}
|
||||
NotFound();
|
||||
}
|
||||
@@ -61,12 +60,12 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::ModelIDListCannotBeEmpty);
|
||||
}
|
||||
|
||||
std::string Error;
|
||||
if (!ValidateUCentralConfiguration(DefConfig.Configuration, Error)) {
|
||||
std::vector<std::string> Error;
|
||||
if (!ValidateUCentralConfiguration(DefConfig.Configuration, Error, GetBoolParameter("strict",false))) {
|
||||
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||
}
|
||||
|
||||
DefConfig.Created = DefConfig.LastModified = OpenWifi::Now();
|
||||
DefConfig.Created = DefConfig.LastModified = Utils::Now();
|
||||
if (StorageService()->CreateDefaultConfiguration(Name, DefConfig)) {
|
||||
return OK();
|
||||
}
|
||||
@@ -89,14 +88,14 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
if (!NewConfig.Configuration.empty()) {
|
||||
std::string Error;
|
||||
if(!ValidateUCentralConfiguration(NewConfig.Configuration, Error)) {
|
||||
std::vector<std::string> Error;
|
||||
if(!ValidateUCentralConfiguration(NewConfig.Configuration, Error, GetBoolParameter("strict",false))) {
|
||||
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||
}
|
||||
Existing.Configuration = NewConfig.Configuration;
|
||||
}
|
||||
|
||||
Existing.LastModified = OpenWifi::Now();
|
||||
Existing.LastModified = Utils::Now();
|
||||
AssignIfPresent(Obj,"description",Existing.Description);
|
||||
if(Obj->has("modelIds"))
|
||||
Existing.Models = NewConfig.Models;
|
||||
@@ -105,12 +104,9 @@ namespace OpenWifi {
|
||||
GWObjects::DefaultConfiguration ModifiedConfig;
|
||||
|
||||
StorageService()->GetDefaultConfiguration(Name,ModifiedConfig);
|
||||
Poco::JSON::Object Answer;
|
||||
ModifiedConfig.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
return Object(ModifiedConfig);
|
||||
}
|
||||
|
||||
BadRequest(RESTAPI::Errors::RecordNotUpdated);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_default_configuration : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_default_configuration(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
|
||||
RESTAPI_default_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_GET, Poco::Net::HTTPRequest::HTTP_POST,
|
||||
|
||||
@@ -23,16 +23,6 @@ namespace OpenWifi {
|
||||
|
||||
std::vector<GWObjects::DefaultConfiguration> DefConfigs;
|
||||
StorageService()->GetDefaultConfigurations(QB_.Offset, QB_.Limit, DefConfigs);
|
||||
|
||||
Poco::JSON::Array Objects;
|
||||
for (const auto &i : DefConfigs) {
|
||||
Poco::JSON::Object Obj;
|
||||
i.to_json(Obj);
|
||||
Objects.add(Obj);
|
||||
}
|
||||
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(RESTAPI::Protocol::CONFIGURATIONS, Objects);
|
||||
ReturnObject(RetObj);
|
||||
return Object(RESTAPI::Protocol::CONFIGURATIONS, DefConfigs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_default_configurations : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_default_configurations(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
|
||||
RESTAPI_default_configurations(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},
|
||||
|
||||
@@ -8,9 +8,11 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_deviceDashboardHandler::DoGet() {
|
||||
Daemon()->GetDashboard().Create();
|
||||
Poco::JSON::Object Answer;
|
||||
Daemon()->GetDashboard().Report().to_json(Answer);
|
||||
ReturnObject(Answer);
|
||||
poco_information(Logger(),fmt::format("GET-DASHBOARD: {}", Requester()));
|
||||
GWObjects::Dashboard Data;
|
||||
if(Daemon()->GetDashboard().Get(Data, Logger())) {
|
||||
return Object(Data);
|
||||
}
|
||||
return BadRequest(RESTAPI::Errors::InternalError);
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_deviceDashboardHandler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_deviceDashboardHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
|
||||
RESTAPI_deviceDashboardHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{
|
||||
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
|
||||
|
||||
@@ -20,15 +20,22 @@
|
||||
#include "StorageService.h"
|
||||
#include "TelemetryStream.h"
|
||||
#include "CommandManager.h"
|
||||
|
||||
#include "SignatureMgr.h"
|
||||
|
||||
#include "framework/ConfigurationValidator.h"
|
||||
#include "framework/KafkaTopics.h"
|
||||
#include "framework/ow_constants.h"
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
#include "rttys/RTTYS_server.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_device_commandHandler::CallCanceled(const char * Cmd, const OpenWifi::RESTAPI::Errors::msg &Err, const std::string & Details) {
|
||||
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() {
|
||||
@@ -45,32 +52,40 @@ namespace OpenWifi {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
auto Command = APCommands::to_apcommand(Command_.c_str());
|
||||
if(Command==APCommands::Commands::unknown) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
}
|
||||
|
||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
||||
Poco::Thread::current()->setName(fmt::format("{}:{}:{}", Command_, TransactionId_, SerialNumber_));
|
||||
|
||||
if (Command_ == RESTAPI::Protocol::CAPABILITIES){
|
||||
return GetCapabilities();
|
||||
} else if (Command_ == RESTAPI::Protocol::LOGS) {
|
||||
return GetLogs();
|
||||
} else if (Command_ == RESTAPI::Protocol::HEALTHCHECKS) {
|
||||
return GetChecks();
|
||||
} else if (Command_ == RESTAPI::Protocol::STATISTICS) {
|
||||
return GetStatistics();
|
||||
} else if (Command_ == RESTAPI::Protocol::STATUS) {
|
||||
return GetStatus();
|
||||
} else if (Command_ == RESTAPI::Protocol::RTTY) {
|
||||
if(!AP_WS_Server()->Connected(SerialNumberInt_)) {
|
||||
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected);
|
||||
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
|
||||
}
|
||||
auto UUID = MicroService::CreateUUID();
|
||||
auto RPC = CommandManager()->NextRPCId();
|
||||
poco_debug(Logger_,fmt::format("Command rtty TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
|
||||
TransactionId_, UUID, RPC,
|
||||
Poco::Thread::current()->id()));
|
||||
return Rtty(UUID,RPC,60000ms);
|
||||
} else {
|
||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
switch(Command) {
|
||||
case APCommands::Commands::capabilities:
|
||||
return GetCapabilities();
|
||||
case APCommands::Commands::logs:
|
||||
return GetLogs();
|
||||
case APCommands::Commands::healthchecks:
|
||||
return GetChecks();
|
||||
case APCommands::Commands::statistics:
|
||||
return GetStatistics();
|
||||
case APCommands::Commands::status:
|
||||
return GetStatus();
|
||||
case APCommands::Commands::rtty: {
|
||||
GWObjects::DeviceRestrictions Restrictions;
|
||||
if(!AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) {
|
||||
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected);
|
||||
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
|
||||
}
|
||||
auto UUID = MicroServiceCreateUUID();
|
||||
auto RPC = CommandManager()->Next_RPC_ID();
|
||||
poco_debug(Logger_,fmt::format("Command rtty TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
|
||||
TransactionId_, UUID, RPC,
|
||||
Poco::Thread::current()->id()));
|
||||
return Rtty(UUID,RPC,60000ms, Restrictions);
|
||||
};
|
||||
default:
|
||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,48 +103,51 @@ namespace OpenWifi {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
auto Command = APCommands::to_apcommand(Command_.c_str());
|
||||
if(Command==APCommands::Commands::unknown) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
}
|
||||
|
||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
||||
Poco::Thread::current()->setName(fmt::format("{}:{}:{}",Command_, TransactionId_,SerialNumber_));
|
||||
|
||||
if (Command_ == RESTAPI::Protocol::CAPABILITIES) {
|
||||
switch(Command) {
|
||||
case APCommands::Commands::capabilities:
|
||||
return DeleteCapabilities();
|
||||
} else if (Command_ == RESTAPI::Protocol::LOGS){
|
||||
case APCommands::Commands::logs:
|
||||
return DeleteLogs();
|
||||
} else if (Command_ == RESTAPI::Protocol::HEALTHCHECKS){
|
||||
case APCommands::Commands::healthchecks:
|
||||
return DeleteChecks();
|
||||
} else if (Command_ == RESTAPI::Protocol::STATISTICS) {
|
||||
case APCommands::Commands::statistics:
|
||||
return DeleteStatistics();
|
||||
} else {
|
||||
default:
|
||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
}
|
||||
}
|
||||
|
||||
struct PostDeviceCommand {
|
||||
const char * Command;
|
||||
bool AllowParallel=false;
|
||||
bool RequireConnection = true;
|
||||
void (RESTAPI_device_commandHandler::*funPtr)(const std::string &, std::uint64_t, std::chrono::milliseconds );
|
||||
APCommands::Commands Command=APCommands::Commands::unknown;
|
||||
bool AllowParallel=false;
|
||||
bool RequireConnection = true;
|
||||
void (RESTAPI_device_commandHandler::*funPtr)(const std::string &, std::uint64_t, std::chrono::milliseconds, const GWObjects::DeviceRestrictions &Restrictions );
|
||||
std::chrono::milliseconds Timeout=120ms;
|
||||
};
|
||||
|
||||
/*
|
||||
const static std::vector<PostDeviceCommand> PostCommands
|
||||
static 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 }
|
||||
};
|
||||
*/
|
||||
{ APCommands::Commands::configure, false, false, &RESTAPI_device_commandHandler::Configure, 120000ms },
|
||||
{ APCommands::Commands::upgrade, false, false, &RESTAPI_device_commandHandler::Upgrade, 30000ms },
|
||||
{ APCommands::Commands::reboot, false, true, &RESTAPI_device_commandHandler::Reboot, 30000ms },
|
||||
{ APCommands::Commands::factory, false, false, &RESTAPI_device_commandHandler::Factory, 30000ms },
|
||||
{ APCommands::Commands::leds, false, true, &RESTAPI_device_commandHandler::LEDs, 120000ms },
|
||||
{ APCommands::Commands::trace, false, true, &RESTAPI_device_commandHandler::Trace, 300000ms },
|
||||
{ APCommands::Commands::request, false, true, &RESTAPI_device_commandHandler::MakeRequest, 120000ms },
|
||||
{ APCommands::Commands::wifiscan, false, true, &RESTAPI_device_commandHandler::WifiScan, 120000ms },
|
||||
{ APCommands::Commands::eventqueue, false, true, &RESTAPI_device_commandHandler::EventQueue, 30000ms },
|
||||
{ APCommands::Commands::telemetry, false, true, &RESTAPI_device_commandHandler::Telemetry, 30000ms },
|
||||
{ APCommands::Commands::ping, false, true, &RESTAPI_device_commandHandler::Ping, 60000ms },
|
||||
{ APCommands::Commands::script, false, true, &RESTAPI_device_commandHandler::Script, 300000ms }
|
||||
};
|
||||
|
||||
void RESTAPI_device_commandHandler::DoPost() {
|
||||
if(!ValidateParameters()) {
|
||||
@@ -138,55 +156,46 @@ namespace OpenWifi {
|
||||
if(!Utils::NormalizeMac(SerialNumber_)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
auto Command = APCommands::to_apcommand(Command_.c_str());
|
||||
if(Command==APCommands::Commands::unknown) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
}
|
||||
|
||||
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
|
||||
GWObjects::Device TheDevice;
|
||||
if(!StorageService()->GetDevice(SerialNumber_,TheDevice)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
const std::vector<PostDeviceCommand> PostCommands =
|
||||
{
|
||||
{ RESTAPI::Protocol::PERFORM, false, true, &RESTAPI_device_commandHandler::ExecuteCommand, 120000ms },
|
||||
{ RESTAPI::Protocol::CONFIGURE, false, false, &RESTAPI_device_commandHandler::Configure, 120000ms },
|
||||
{ RESTAPI::Protocol::UPGRADE, false, false, &RESTAPI_device_commandHandler::Upgrade, 30000ms },
|
||||
{ RESTAPI::Protocol::REBOOT, false, true, &RESTAPI_device_commandHandler::Reboot, 30000ms },
|
||||
{ RESTAPI::Protocol::FACTORY, false, false, &RESTAPI_device_commandHandler::Factory, 30000ms },
|
||||
{ RESTAPI::Protocol::LEDS, false, true, &RESTAPI_device_commandHandler::LEDs, 120000ms },
|
||||
{ RESTAPI::Protocol::TRACE, false, true, &RESTAPI_device_commandHandler::Trace, 300000ms },
|
||||
{ RESTAPI::Protocol::REQUEST, false, true, &RESTAPI_device_commandHandler::MakeRequest, 120000ms },
|
||||
{ RESTAPI::Protocol::WIFISCAN, false, true, &RESTAPI_device_commandHandler::WifiScan, 120000ms },
|
||||
{ RESTAPI::Protocol::EVENTQUEUE, false, true, &RESTAPI_device_commandHandler::EventQueue, 30000ms },
|
||||
{ RESTAPI::Protocol::TELEMETRY, false, true, &RESTAPI_device_commandHandler::Telemetry, 30000ms },
|
||||
{ RESTAPI::Protocol::PING, false, true, &RESTAPI_device_commandHandler::Ping, 60000ms },
|
||||
{ RESTAPI::Protocol::SCRIPT, false, true, &RESTAPI_device_commandHandler::Script, 300000ms }
|
||||
};
|
||||
|
||||
for(const auto &Command:PostCommands) {
|
||||
if(Command_==Command.Command) {
|
||||
Poco::Thread::current()->setName(fmt::format("{}:{}:{}",Command.Command, TransactionId_,SerialNumber_));
|
||||
if(Command.RequireConnection && !AP_WS_Server()->Connected(SerialNumberInt_)) {
|
||||
CallCanceled(Command.Command, RESTAPI::Errors::DeviceNotConnected);
|
||||
for(const auto &PostCommand:PostCommands) {
|
||||
if(Command==PostCommand.Command) {
|
||||
Poco::Thread::current()->setName(fmt::format("{}:{}:{}",Command_, TransactionId_,SerialNumber_));
|
||||
GWObjects::DeviceRestrictions Restrictions;
|
||||
if(PostCommand.RequireConnection && !AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) {
|
||||
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected);
|
||||
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
|
||||
}
|
||||
std::string Command_UUID, CommandName;
|
||||
if(!Command.AllowParallel && CommandManager()->CommandRunningForDevice(SerialNumberInt_,Command_UUID,CommandName)) {
|
||||
auto Extra = fmt::format("UUID={} Command={}", Command_UUID, CommandName);
|
||||
CallCanceled(Command.Command, RESTAPI::Errors::DeviceIsAlreadyBusy, Extra);
|
||||
std::string Command_UUID;
|
||||
APCommands::Commands CommandName;
|
||||
if(!PostCommand.AllowParallel && CommandManager()->CommandRunningForDevice(SerialNumberInt_,Command_UUID,CommandName)) {
|
||||
auto Extra = fmt::format("UUID={} Command={}", Command_UUID, APCommands::to_string(CommandName));
|
||||
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceIsAlreadyBusy, Extra);
|
||||
return BadRequest(RESTAPI::Errors::DeviceIsAlreadyBusy, Extra);
|
||||
}
|
||||
auto UUID = MicroService::CreateUUID();
|
||||
auto RPC = CommandManager()->NextRPCId();
|
||||
auto UUID = MicroServiceCreateUUID();
|
||||
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,
|
||||
Command_, TransactionId_, UUID, RPC,
|
||||
Poco::Thread::current()->id()));
|
||||
return (*this.*Command.funPtr)(UUID,RPC,Command.Timeout);
|
||||
return (*this.*PostCommand.funPtr)(UUID,RPC,PostCommand.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;
|
||||
@@ -200,7 +209,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_)) {
|
||||
@@ -210,35 +219,45 @@ 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)) {
|
||||
Poco::JSON::Parser P;
|
||||
if (Stats.empty())
|
||||
Stats = uCentralProtocol::EMPTY_JSON_DOC;
|
||||
auto Obj = P.parse(Stats).extract<Poco::JSON::Object::Ptr>();
|
||||
return ReturnObject(*Obj);
|
||||
if (AP_WS_Server()->GetStatistics(SerialNumber_, Stats) && !Stats.empty()) {
|
||||
return ReturnRawJSON(Stats);
|
||||
}
|
||||
return NotFound();
|
||||
if(AP_WS_Server()->Connected(SerialNumberInt_)) {
|
||||
return BadRequest(RESTAPI::Errors::NoDeviceStatisticsYet);
|
||||
}
|
||||
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
|
||||
}
|
||||
|
||||
std::vector<GWObjects::Statistics> Stats;
|
||||
if (QB_.Newest) {
|
||||
StorageService()->GetNewestStatisticsData(SerialNumber_, QB_.Limit, Stats);
|
||||
} else {
|
||||
if(QB_.CountOnly) {
|
||||
std::uint64_t Count = 0 ;
|
||||
StorageService()->GetNumberOfStatisticsDataRecords(SerialNumber_, QB_.StartDate, QB_.EndDate,Count);
|
||||
return ReturnCountOnly(Count);
|
||||
}
|
||||
if(QB_.Limit>100)
|
||||
QB_.Limit=100;
|
||||
|
||||
StorageService()->GetStatisticsData(SerialNumber_, QB_.StartDate, QB_.EndDate,
|
||||
QB_.Offset, QB_.Limit, Stats);
|
||||
}
|
||||
|
||||
Poco::JSON::Array ArrayObj;
|
||||
Poco::JSON::Array::Ptr ArrayObj = Poco::SharedPtr<Poco::JSON::Array>(new Poco::JSON::Array);
|
||||
for (const auto &i : Stats) {
|
||||
Poco::JSON::Object Obj;
|
||||
i.to_json(Obj);
|
||||
ArrayObj.add(Obj);
|
||||
Poco::JSON::Object::Ptr Obj = Poco::SharedPtr<Poco::JSON::Object>(new Poco::JSON::Object);
|
||||
i.to_json(*Obj);
|
||||
ArrayObj->add(Obj);
|
||||
}
|
||||
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set(RESTAPI::Protocol::DATA, ArrayObj);
|
||||
RetObj.set(RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
|
||||
@@ -247,7 +266,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)) {
|
||||
@@ -257,7 +276,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;
|
||||
@@ -275,7 +294,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;
|
||||
@@ -299,7 +318,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,
|
||||
@@ -310,12 +329,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)) {
|
||||
@@ -326,6 +343,7 @@ namespace OpenWifi {
|
||||
return NotFound();
|
||||
}
|
||||
} else {
|
||||
std::vector<GWObjects::HealthCheck> Checks;
|
||||
if (QB_.Newest) {
|
||||
StorageService()->GetNewestHealthCheckData(SerialNumber_, QB_.Limit, Checks);
|
||||
} else {
|
||||
@@ -348,7 +366,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)) {
|
||||
@@ -357,8 +375,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 GWObjects::DeviceRestrictions &Restrictions) {
|
||||
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();
|
||||
@@ -381,7 +399,7 @@ namespace OpenWifi {
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, nullptr, Logger_);
|
||||
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::ping,false,Cmd, Params, *Request, *Response, timeout, nullptr, nullptr, Logger_);
|
||||
|
||||
GWObjects::CommandDetails Cmd2;
|
||||
if(StorageService()->GetCommand(CMD_UUID,Cmd2)) {
|
||||
@@ -410,15 +428,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_));
|
||||
if(!Internal_ && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
|
||||
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::ACCESS_DENIED);
|
||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||
}
|
||||
static bool ValidateScriptType(const std::string &t) {
|
||||
return t=="shell" || t=="bundle";
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Script(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
||||
poco_information(Logger_,fmt::format("SCRIPT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
GWObjects::ScriptRequest SCR;
|
||||
@@ -427,13 +445,25 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if (SCR.serialNumber.empty() ||
|
||||
SCR.script.empty() ||
|
||||
SCR.type.empty() ||
|
||||
SCR.scriptId.empty() ||
|
||||
(SCR.type!="shell" && SCR.type!="ucode")) {
|
||||
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
bool DiagnosticScript = (SCR.type=="diagnostic");
|
||||
if(!SCR.script.empty() && !SCR.scriptId.empty()) {
|
||||
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::InvalidScriptSelection);
|
||||
return UnAuthorized(RESTAPI::Errors::InvalidScriptSelection);
|
||||
}
|
||||
|
||||
if(!Internal_ && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && SCR.scriptId.empty()) {
|
||||
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::ACCESS_DENIED);
|
||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
if (SCR.script.empty() && SCR.scriptId.empty() && !DiagnosticScript) {
|
||||
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::InvalidScriptSelection);
|
||||
return BadRequest(RESTAPI::Errors::InvalidScriptSelection);
|
||||
}
|
||||
|
||||
if(DiagnosticScript && (!SCR.scriptId.empty() || !SCR.script.empty())){
|
||||
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::InvalidScriptSelection);
|
||||
return BadRequest(RESTAPI::Errors::InvalidScriptSelection);
|
||||
}
|
||||
|
||||
if (SerialNumber_ != SCR.serialNumber) {
|
||||
@@ -441,6 +471,50 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
if(!SCR.uri.empty() && !Utils::ValidateURI(SCR.uri)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidURI);
|
||||
}
|
||||
|
||||
GWObjects::Device D;
|
||||
if(!StorageService()->GetDevice(SerialNumber_,D)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if(!SCR.scriptId.empty()) {
|
||||
GWObjects::ScriptEntry Existing;
|
||||
if(!StorageService()->ScriptDB().GetRecord("id",SCR.scriptId,Existing)) {
|
||||
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
// verify the role...
|
||||
if(Existing.restricted.empty() && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
|
||||
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::ACCESS_DENIED);
|
||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
|
||||
if (std::find(Existing.restricted.begin(), Existing.restricted.end(),
|
||||
SecurityObjects::UserTypeToString(UserInfo_.userinfo.userRole)) ==
|
||||
end(Existing.restricted)) {
|
||||
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED);
|
||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||
}
|
||||
}
|
||||
poco_information(Logger_,fmt::format("SCRIPT({},{}): TID={} Name={}", CMD_UUID, CMD_RPC, TransactionId_, Existing.name));
|
||||
SCR.script = Existing.content;
|
||||
SCR.type = Existing.type;
|
||||
if(!ParsedBody_->has("deferred"))
|
||||
SCR.deferred = Existing.deferred;
|
||||
if(!ParsedBody_->has("timeout"))
|
||||
SCR.timeout = Existing.timeout;
|
||||
} else {
|
||||
if(!DiagnosticScript && !ValidateScriptType(SCR.type)) {
|
||||
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t ap_timeout = SCR.timeout==0 ? 30 : SCR.timeout;
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
@@ -449,23 +523,50 @@ 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);
|
||||
}
|
||||
|
||||
if(Restrictions.developer==0 && D.restrictedDevice && SCR.signature.empty()) {
|
||||
SCR.signature = SignatureManager()->Sign(Restrictions, SCR.script);
|
||||
}
|
||||
|
||||
if(Restrictions.developer==0 && D.restrictedDevice && SCR.signature.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::DeviceRequiresSignature);
|
||||
}
|
||||
|
||||
// convert script to base64 ...
|
||||
auto EncodedScript = Utils::base64encode((const unsigned char *)SCR.script.c_str(),SCR.script.size());
|
||||
Params.set(uCentralProtocol::TYPE, SCR.type);
|
||||
Params.set(uCentralProtocol::SCRIPT, SCR.script);
|
||||
if(!DiagnosticScript) {
|
||||
Params.set(uCentralProtocol::SCRIPT, EncodedScript);
|
||||
}
|
||||
Params.set(uCentralProtocol::WHEN, SCR.when);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
FileUploader()->AddUUID(CMD_UUID, 15min, "script_result");
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::script,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 GWObjects::DeviceRestrictions &Restrictions) {
|
||||
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) &&
|
||||
@@ -479,8 +580,8 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
auto Configuration = GetS(RESTAPI::Protocol::CONFIGURATION, Obj,uCentralProtocol::EMPTY_JSON_DOC);
|
||||
std::string Error;
|
||||
if (!ValidateUCentralConfiguration(Configuration, Error)) {
|
||||
std::vector<std::string> Error;
|
||||
if (!ValidateUCentralConfiguration(Configuration, Error, GetBoolParameter("strict",false))) {
|
||||
CallCanceled("CONFIGURE", CMD_UUID, CMD_RPC,RESTAPI::Errors::ConfigBlockInvalid);
|
||||
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||
}
|
||||
@@ -509,15 +610,15 @@ namespace OpenWifi {
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
// AP_WS_Server()->SetPendingUUID(SerialNumber_, NewUUID);
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC,true,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::configure,true,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
}
|
||||
return BadRequest(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Upgrade(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
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 GWObjects::DeviceRestrictions &Restrictions) {
|
||||
poco_information(Logger_,fmt::format("UPGRADE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
|
||||
@@ -530,6 +631,12 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
GWObjects::Device DeviceInfo;
|
||||
if(!StorageService()->GetDevice(SerialNumber_,DeviceInfo)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
std::string FWSignature = GetParameter("FWsignature","");
|
||||
auto URI = GetS(RESTAPI::Protocol::URI, Obj);
|
||||
auto When = GetWhen(Obj);
|
||||
|
||||
@@ -548,68 +655,33 @@ namespace OpenWifi {
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::URI, URI);
|
||||
Params.set(uCentralProtocol::KEEP_REDIRECTOR, KeepRedirector ? 1 : 0);
|
||||
Params.set(uCentralProtocol::WHEN, When);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC,true,Cmd,Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
}
|
||||
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);
|
||||
if(DeviceInfo.restrictionDetails.upgrade && FWSignature.empty()) {
|
||||
Poco::URI uri(URI);
|
||||
FWSignature = SignatureManager()->Sign(DeviceInfo.restrictionDetails,uri);
|
||||
}
|
||||
|
||||
auto Command = GetS(RESTAPI::Protocol::COMMAND, Obj);
|
||||
auto Payload = GetS(RESTAPI::Protocol::PAYLOAD, Obj);
|
||||
auto When = GetWhen(Obj);
|
||||
if(FWSignature.empty() && DeviceInfo.restrictionDetails.upgrade) {
|
||||
return BadRequest(RESTAPI::Errors::DeviceRequiresSignature);
|
||||
}
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
if(!FWSignature.empty()) {
|
||||
Params.set(uCentralProtocol::SIGNATURE, FWSignature);
|
||||
}
|
||||
|
||||
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_);
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::upgrade,true,Cmd,Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Reboot(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
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 GWObjects::DeviceRestrictions &Restrictions) {
|
||||
poco_information(Logger_,fmt::format("REBOOT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
|
||||
@@ -637,13 +709,13 @@ namespace OpenWifi {
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::reboot, false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Factory(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
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 GWObjects::DeviceRestrictions &Restrictions) {
|
||||
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) &&
|
||||
@@ -677,13 +749,13 @@ namespace OpenWifi {
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC,true,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::factory,true,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::LEDs(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
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 GWObjects::DeviceRestrictions &Restrictions) {
|
||||
poco_information(Logger_,fmt::format("LEDS({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
|
||||
@@ -725,13 +797,13 @@ namespace OpenWifi {
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::leds,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Trace(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
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 GWObjects::DeviceRestrictions &Restrictions) {
|
||||
poco_information(Logger_,fmt::format("TRACE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
|
||||
@@ -777,14 +849,14 @@ namespace OpenWifi {
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
FileUploader()->AddUUID(CMD_UUID);
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
FileUploader()->AddUUID(CMD_UUID, 10min, "trace");
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::trace,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 GWObjects::DeviceRestrictions &Restrictions) {
|
||||
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();
|
||||
@@ -812,6 +884,11 @@ namespace OpenWifi {
|
||||
Poco::JSON::Object Params;
|
||||
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
|
||||
if(Restrictions.developer==0 && Restrictions.dfs && OverrideDFS) {
|
||||
return BadRequest(RESTAPI::Errors::DeviceIsRestricted);
|
||||
}
|
||||
|
||||
Params.set(uCentralProtocol::OVERRIDEDFS, OverrideDFS);
|
||||
Params.set(uCentralProtocol::ACTIVE, ActiveScan);
|
||||
if(ies)
|
||||
@@ -822,14 +899,14 @@ namespace OpenWifi {
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::wifiscan,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
if (Cmd.ErrorCode == 0) {
|
||||
KafkaManager()->PostMessage(KafkaTopics::WIFISCAN, SerialNumber_, Cmd.Results);
|
||||
}
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::EventQueue(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout) {
|
||||
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 GWObjects::DeviceRestrictions &Restrictions) {
|
||||
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) &&
|
||||
@@ -857,7 +934,7 @@ namespace OpenWifi {
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::eventqueue,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
|
||||
if(Cmd.ErrorCode==0) {
|
||||
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, SerialNumber_,
|
||||
Cmd.Results);
|
||||
@@ -867,8 +944,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 GWObjects::DeviceRestrictions &Restrictions) {
|
||||
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) &&
|
||||
@@ -904,47 +981,45 @@ namespace OpenWifi {
|
||||
Params.stringify(ParamStream);
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_ );
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::request,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_ );
|
||||
}
|
||||
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_));
|
||||
#define DBGLINE { std::cout << __LINE__ << std::endl; }
|
||||
|
||||
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
if (MicroService::instance().ConfigGetBool("rtty.enabled", false)) {
|
||||
void RESTAPI_device_commandHandler::Rtty(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
||||
poco_information(Logger_,fmt::format("RTTY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
if(Restrictions.developer==0 && Restrictions.rtty) {
|
||||
return BadRequest(RESTAPI::Errors::DeviceIsRestricted);
|
||||
}
|
||||
|
||||
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__ ));
|
||||
static std::uint64_t rtty_sid = 0;
|
||||
rtty_sid += std::rand();
|
||||
GWObjects::RttySessionDetails Rtty{
|
||||
.SerialNumber = SerialNumber_,
|
||||
.Server = MicroService::instance().ConfigGetString("rtty.server", "localhost"),
|
||||
.Port = MicroService::instance().ConfigGetInt("rtty.port", 5912),
|
||||
.Token = MicroService::instance().ConfigGetString("rtty.token", "nothing"),
|
||||
.TimeOut = MicroService::instance().ConfigGetInt("rtty.timeout", 60),
|
||||
.ConnectionId = Utils::ComputeHash(SerialNumber_,OpenWifi::Now()).substr(0,32),
|
||||
.Started = OpenWifi::Now(),
|
||||
.Server = MicroServiceConfigGetString("rtty.server", "localhost"),
|
||||
.Port = MicroServiceConfigGetInt("rtty.port", 5912),
|
||||
.Token = MicroServiceConfigGetString("rtty.token", "nothing"),
|
||||
.TimeOut = MicroServiceConfigGetInt("rtty.timeout", 60),
|
||||
.ConnectionId = Utils::ComputeHash(SerialNumber_,Utils::Now(),rtty_sid).substr(0,RTTY_DEVICE_TOKEN_LENGTH),
|
||||
.Started = Utils::Now(),
|
||||
.CommandUUID = CMD_UUID,
|
||||
.ViewPort = MicroService::instance().ConfigGetInt("rtty.viewport", 5913),
|
||||
.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_,OpenWifi::Now()).substr(0,32);
|
||||
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
Rtty.Token = Utils::ComputeHash(UserInfo_.webtoken.refresh_token_,Utils::Now()).substr(0,RTTY_DEVICE_TOKEN_LENGTH);
|
||||
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);
|
||||
@@ -956,7 +1031,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);
|
||||
@@ -969,30 +1043,27 @@ namespace OpenWifi {
|
||||
Params.set(uCentralProtocol::TIMEOUT, Rtty.TimeOut);
|
||||
Params.set(uCentralProtocol::PASSWORD, Device.DevicePassword);
|
||||
|
||||
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
std::stringstream ParamStream;
|
||||
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
Params.stringify(ParamStream);
|
||||
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
Cmd.Details = ParamStream.str();
|
||||
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
Logger_.information(fmt::format("RTTY: user={} serial={} rttyid={} token={} cmd={}.", Requester(), SerialNumber_, Rtty.ConnectionId, Rtty.Token, CMD_UUID));
|
||||
poco_debug(Logger_,fmt::format("RTTY_DEBUG {} ", __LINE__ ));
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, &ReturnedObject, this, Logger_);
|
||||
poco_information(Logger_,fmt::format("RTTY: user={} serial={} rttyid={} token={} cmd={}.", Requester(), SerialNumber_, Rtty.ConnectionId, Rtty.Token, CMD_UUID));
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::rtty,false,Cmd, Params, *Request, *Response, timeout, &ReturnedObject, this, Logger_);
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
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 GWObjects::DeviceRestrictions &Restrictions){
|
||||
poco_information(Logger_,fmt::format("TELEMETRY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
|
||||
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER) &&
|
||||
Obj->has(RESTAPI::Protocol::INTERVAL) &&
|
||||
Obj->has(RESTAPI::Protocol::TYPES)) {
|
||||
Obj->has(RESTAPI::Protocol::TYPES) &&
|
||||
Obj->isArray(RESTAPI::Protocol::TYPES)) {
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
@@ -1002,10 +1073,9 @@ namespace OpenWifi {
|
||||
|
||||
std::stringstream oooss;
|
||||
Obj->stringify(oooss);
|
||||
// std::cout << "Payload:" << oooss.str() << std::endl;
|
||||
|
||||
uint64_t Lifetime = 60 * 60 ; // 1 hour
|
||||
uint64_t Interval = 5;
|
||||
std::uint64_t Lifetime = 60 * 60 ; // 1 hour
|
||||
std::uint64_t Interval = 5;
|
||||
bool KafkaOnly = false;
|
||||
|
||||
if(Obj->has("kafka")) {
|
||||
@@ -1017,14 +1087,19 @@ namespace OpenWifi {
|
||||
AssignIfPresent(Obj, RESTAPI::Protocol::INTERVAL, Interval);
|
||||
AssignIfPresent(Obj, RESTAPI::Protocol::LIFETIME, Lifetime);
|
||||
|
||||
Poco::JSON::Object Answer;
|
||||
std::vector<std::string> TelemetryTypes;
|
||||
auto Types = Obj->getArray(RESTAPI::Protocol::TYPES);
|
||||
for(const auto &type:*Types) {
|
||||
TelemetryTypes.push_back(type);
|
||||
}
|
||||
|
||||
Poco::JSON::Object Answer;
|
||||
auto IntSerialNumber = Utils::SerialNumberToInt(SerialNumber_);
|
||||
|
||||
if(!StatusOnly) {
|
||||
if (KafkaOnly) {
|
||||
if (Interval) {
|
||||
AP_WS_Server()->SetKafkaTelemetryReporting(CMD_RPC,IntSerialNumber, Interval, Lifetime);
|
||||
AP_WS_Server()->SetKafkaTelemetryReporting(CMD_RPC,IntSerialNumber, Interval, Lifetime,TelemetryTypes);
|
||||
Answer.set("action", "Kafka telemetry started.");
|
||||
Answer.set("uuid", CMD_UUID);
|
||||
} else {
|
||||
@@ -1033,8 +1108,8 @@ namespace OpenWifi {
|
||||
}
|
||||
} else {
|
||||
if (Interval) {
|
||||
AP_WS_Server()->SetWebSocketTelemetryReporting(CMD_RPC,IntSerialNumber, Interval,
|
||||
Lifetime);
|
||||
AP_WS_Server()->SetWebSocketTelemetryReporting(CMD_RPC, IntSerialNumber, Interval,
|
||||
Lifetime,TelemetryTypes);
|
||||
std::string EndPoint;
|
||||
if (TelemetryStream()->CreateEndpoint(Utils::SerialNumberToInt(SerialNumber_), EndPoint, CMD_UUID)) {
|
||||
Answer.set("action", "WebSocket telemetry started.");
|
||||
@@ -1054,7 +1129,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
bool TelemetryRunning;
|
||||
uint64_t TelemetryWebSocketCount, TelemetryKafkaCount, TelemetryInterval,
|
||||
std::uint64_t TelemetryWebSocketCount, TelemetryKafkaCount, TelemetryInterval,
|
||||
TelemetryWebSocketTimer, TelemetryKafkaTimer, TelemetryWebSocketPackets,
|
||||
TelemetryKafkaPackets;
|
||||
AP_WS_Server()->GetTelemetryParameters(IntSerialNumber,TelemetryRunning,
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/ow_constants.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "RESTObjects/RESTAPI_GWobjects.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_device_commandHandler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_device_commandHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
|
||||
RESTAPI_device_commandHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{
|
||||
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
|
||||
@@ -33,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 GWObjects::DeviceRestrictions &R);
|
||||
void Upgrade(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
|
||||
void Reboot(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
|
||||
void Factory(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
|
||||
void LEDs(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
|
||||
void Trace(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
|
||||
void MakeRequest(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
|
||||
void WifiScan(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
|
||||
void EventQueue(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
|
||||
void Rtty(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
|
||||
void Telemetry(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
|
||||
void Ping(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
|
||||
void Script(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
|
||||
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/device/{serialNumber}/{command}"}; };
|
||||
void DoGet() final;
|
||||
|
||||
@@ -9,11 +9,12 @@
|
||||
#include "RESTAPI_device_handler.h"
|
||||
#include "CentralConfig.h"
|
||||
#include "ConfigurationCache.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
#include "framework/ConfigurationValidator.h"
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/ow_constants.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
#include "RESTAPI_device_helper.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
@@ -31,9 +32,7 @@ namespace OpenWifi {
|
||||
CompleteDeviceInfo(Device, Answer);
|
||||
return ReturnObject(Answer);
|
||||
} else {
|
||||
Poco::JSON::Object Obj;
|
||||
Device.to_json(Obj);
|
||||
return ReturnObject(Obj);
|
||||
return Object(Device);
|
||||
}
|
||||
}
|
||||
NotFound();
|
||||
@@ -98,19 +97,14 @@ namespace OpenWifi {
|
||||
}
|
||||
auto Config=Obj->get("configuration").toString();
|
||||
Poco::JSON::Object Answer;
|
||||
std::string Error;
|
||||
auto Res = ValidateUCentralConfiguration(Config, Error);
|
||||
std::vector<std::string> Error;
|
||||
auto Res = ValidateUCentralConfiguration(Config, Error, GetBoolParameter("strict",false));
|
||||
Answer.set("valid",Res);
|
||||
if(!Error.empty())
|
||||
Answer.set("error",Error);
|
||||
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);
|
||||
@@ -124,18 +118,18 @@ namespace OpenWifi {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
std::string Error;
|
||||
if(Device.Configuration.empty() || (!Device.Configuration.empty() && !ValidateUCentralConfiguration(Device.Configuration,Error))) {
|
||||
std::vector<std::string> Error;
|
||||
if(Device.Configuration.empty() || (!Device.Configuration.empty() && !ValidateUCentralConfiguration(Device.Configuration,Error, GetBoolParameter("strict",false)))) {
|
||||
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||
}
|
||||
|
||||
for(auto &i:Device.Notes) {
|
||||
i.createdBy = UserInfo_.userinfo.email;
|
||||
i.created = OpenWifi::Now();
|
||||
i.created = Utils::Now();
|
||||
}
|
||||
|
||||
Config::Config NewConfig(Device.Configuration);
|
||||
Device.UUID = OpenWifi::Now();
|
||||
Device.UUID = Utils::Now();
|
||||
NewConfig.SetUUID(Device.UUID);
|
||||
Device.Configuration = NewConfig.get();
|
||||
|
||||
@@ -143,9 +137,7 @@ namespace OpenWifi {
|
||||
|
||||
if (StorageService()->CreateDevice(Device)) {
|
||||
SetCurrentConfigurationID(SerialNumber, Device.UUID);
|
||||
Poco::JSON::Object DevObj;
|
||||
Device.to_json(DevObj);
|
||||
return ReturnObject(DevObj);
|
||||
return Object(Device);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
@@ -169,12 +161,12 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
if(!NewDevice.Configuration.empty()) {
|
||||
std::string Error;
|
||||
if (!ValidateUCentralConfiguration(NewDevice.Configuration, Error)) {
|
||||
std::vector<std::string> Error;
|
||||
if (!ValidateUCentralConfiguration(NewDevice.Configuration, Error, GetBoolParameter("strict",false))) {
|
||||
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||
}
|
||||
Config::Config NewConfig(NewDevice.Configuration);
|
||||
uint64_t NewConfigUUID = OpenWifi::Now();
|
||||
uint64_t NewConfigUUID = Utils::Now();
|
||||
NewConfig.SetUUID(NewConfigUUID);
|
||||
Existing.Configuration = NewConfig.get();
|
||||
Existing.UUID = NewConfigUUID;
|
||||
@@ -188,16 +180,16 @@ namespace OpenWifi {
|
||||
|
||||
for(auto &i:NewDevice.Notes) {
|
||||
i.createdBy = UserInfo_.userinfo.email;
|
||||
i.created = OpenWifi::Now();
|
||||
i.created = Utils::Now();
|
||||
Existing.Notes.push_back(i);
|
||||
}
|
||||
|
||||
Existing.LastConfigurationChange = OpenWifi::Now();
|
||||
Existing.LastConfigurationChange = Utils::Now();
|
||||
if (StorageService()->UpdateDevice(Existing)) {
|
||||
SetCurrentConfigurationID(SerialNumber, Existing.UUID);
|
||||
Poco::JSON::Object DevObj;
|
||||
NewDevice.to_json(DevObj);
|
||||
return ReturnObject(DevObj);
|
||||
GWObjects::Device UpdatedDevice;
|
||||
StorageService()->GetDevice(SerialNumber, UpdatedDevice);
|
||||
return Object(UpdatedDevice);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
|
||||
@@ -8,14 +8,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Poco/Net/HTTPServerRequest.h"
|
||||
#include "Poco/Net/HTTPServerResponse.h"
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_device_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_device_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
|
||||
RESTAPI_device_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{
|
||||
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
#include "RESTAPI_devices_handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/ow_constants.h"
|
||||
#include "framework/MicroService.h"
|
||||
#include "RESTAPI/RESTAPI_device_helper.h"
|
||||
#include "Poco/StringTokenizer.h"
|
||||
#include "framework/orm.h"
|
||||
@@ -27,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)
|
||||
@@ -69,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);
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_devices_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_devices_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
|
||||
RESTAPI_devices_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
|
||||
@@ -25,7 +25,12 @@ namespace OpenWifi {
|
||||
if (!StorageService()->GetAttachedFileContent(UUID, SerialNumber, FileContent, FileType)) {
|
||||
return NotFound();
|
||||
}
|
||||
SendFileContent(FileContent,"pcap",UUID+".pcap");
|
||||
if(FileType=="pcap")
|
||||
SendFileContent(FileContent,"application/vnd.tcpdump.pcap",UUID+".pcap");
|
||||
else if(FileType=="gzip")
|
||||
SendFileContent(FileContent,"application/gzip",UUID+".tar.gz");
|
||||
else
|
||||
SendFileContent(FileContent,"application/txt",UUID+".txt");
|
||||
}
|
||||
|
||||
void RESTAPI_file::DoDelete() {
|
||||
|
||||
@@ -8,12 +8,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_file : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_file(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
|
||||
RESTAPI_file(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_DELETE,
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_iptocountry_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_iptocountry_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
|
||||
RESTAPI_iptocountry_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_ouis : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_ouis(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
|
||||
RESTAPI_ouis(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,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user