mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2026-03-20 03:41:02 +00:00
Compare commits
62 Commits
WIFI-14521
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1961c26362 | ||
|
|
cae9856fed | ||
|
|
2378bd76bb | ||
|
|
87f7d116a7 | ||
|
|
3e5c96202a | ||
|
|
0914b4908c | ||
|
|
d68c7bdb77 | ||
|
|
d2f2b8df90 | ||
|
|
dfba03bd17 | ||
|
|
b6f0f113e2 | ||
|
|
ac04422302 | ||
|
|
63114641a7 | ||
|
|
691d3399f8 | ||
|
|
6542726ac3 | ||
|
|
4bc753f8b5 | ||
|
|
e3a513fa6a | ||
|
|
b151239a5c | ||
|
|
862dab38d1 | ||
|
|
ee2e9a19c0 | ||
|
|
8b28fa0435 | ||
|
|
aeef70a121 | ||
|
|
42c421ec12 | ||
|
|
98bfb4b24d | ||
|
|
6b64089f55 | ||
|
|
1f6e42b57c | ||
|
|
f857d61377 | ||
|
|
66d580d047 | ||
|
|
567c671c22 | ||
|
|
9e3735ced8 | ||
|
|
18b169e517 | ||
|
|
cab0d8aee6 | ||
|
|
680b6a16e3 | ||
|
|
218694872f | ||
|
|
6ae1eeb2ea | ||
|
|
f537e701a0 | ||
|
|
d4dfb7b620 | ||
|
|
446cbf270f | ||
|
|
06ffee27b1 | ||
|
|
fa3c325bfa | ||
|
|
182a442582 | ||
|
|
3b7a24ea30 | ||
|
|
1c5909613f | ||
|
|
8e5e51a52a | ||
|
|
b4699e9178 | ||
|
|
438309714f | ||
|
|
a9130eeb75 | ||
|
|
33068fca9e | ||
|
|
d329151f6c | ||
|
|
ec846006bb | ||
|
|
bd48079a8d | ||
|
|
242261de0a | ||
|
|
31a4edead5 | ||
|
|
f7b697f219 | ||
|
|
e020da75fc | ||
|
|
89702f56e0 | ||
|
|
0ac97442c0 | ||
|
|
e38b4c8a13 | ||
|
|
9c5bbee834 | ||
|
|
a5d1eebe6d | ||
|
|
ee14f064c8 | ||
|
|
dbf52c1f23 | ||
|
|
1c0556f8bf |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -29,4 +29,6 @@ helm/charts/*
|
||||
!helm/charts/.gitkeep
|
||||
/portal-test/
|
||||
/src/ow_version.h
|
||||
|
||||
.vscode/*
|
||||
# Build dependencies temporary folder
|
||||
.build-deps/
|
||||
|
||||
31
BUILDING.md
31
BUILDING.md
@@ -1,11 +1,36 @@
|
||||
# Building from source
|
||||
In order to build OWGW, you will need to install its dependencies, which includes the following:
|
||||
|
||||
## Quick Build (Recommended - Using Container)
|
||||
The easiest way to build OWGW is using the provided build script that creates a Debian Bookworm container with all dependencies:
|
||||
|
||||
```bash
|
||||
./build-ucentralgw.sh
|
||||
```
|
||||
|
||||
This script will:
|
||||
- Build all dependencies (POCO, cppkafka, valijson) in a Debian Bookworm container
|
||||
- Store dependency builds in `.build-deps/` (gitignored, cached for faster rebuilds)
|
||||
- Build the OWGW binary and place it in `./cmake-build/owgw`
|
||||
- Work entirely within the repository - no system-wide installation needed
|
||||
|
||||
**Requirements:**
|
||||
- Docker installed and running
|
||||
- Git
|
||||
|
||||
**Clean rebuild (if needed):**
|
||||
```bash
|
||||
rm -rf .build-deps/build-cache
|
||||
./build-ucentralgw.sh
|
||||
```
|
||||
|
||||
## Manual Build from Source
|
||||
If you prefer to build manually without Docker, you will need to install the following dependencies:
|
||||
- cmake
|
||||
- boost
|
||||
- POCO 1.10.1 or later
|
||||
- a C++17 compiler
|
||||
- openssl
|
||||
- libpq-dev (PortgreSQL development libraries)
|
||||
- libpq-dev (PostgreSQL development libraries)
|
||||
- mysql-client (MySQL client)
|
||||
- librdkafka
|
||||
- cppkafka
|
||||
@@ -20,7 +45,7 @@ These instructions have proven to work on Ubuntu 20.4.
|
||||
```bash
|
||||
sudo apt install git cmake g++ libssl-dev libmariadb-dev \
|
||||
libpq-dev libaprutil1-dev apache2-dev libboost-all-dev \
|
||||
librdkafka-dev // default-libmysqlclient-dev \
|
||||
librdkafka-dev default-libmysqlclient-dev \
|
||||
nlohmann-json-dev
|
||||
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1 poco
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(owgw VERSION 3.2.1)
|
||||
project(owgw VERSION 4.2.2)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED True)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
ARG DEBIAN_VERSION=11.5-slim
|
||||
ARG POCO_VERSION=poco-tip-v2
|
||||
ARG DEBIAN_VERSION=bookworm
|
||||
ARG POCO_VERSION=poco-tip-v4-tag
|
||||
ARG CPPKAFKA_VERSION=tip-v1
|
||||
ARG VALIJASON_VERSION=tip-v1.0.2
|
||||
ARG APP_NAME=owgw
|
||||
@@ -100,7 +100,7 @@ RUN mkdir -p $APP_ROOT $APP_CONFIG && \
|
||||
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||
librdkafka++1 gosu gettext ca-certificates bash jq curl wget \
|
||||
libmariadb-dev-compat libpq5 unixodbc postgresql-client libfmt7 sqlite3
|
||||
libmariadb-dev-compat libpq5 unixodbc postgresql-client libfmt9 sqlite3
|
||||
|
||||
COPY readiness_check /readiness_check
|
||||
COPY test_scripts/curl/cli /cli
|
||||
|
||||
26
PROTOCOL.md
26
PROTOCOL.md
@@ -880,6 +880,32 @@ The device should answer:
|
||||
}
|
||||
```
|
||||
|
||||
#### Controller wants the device to perform re-enrollment
|
||||
Controller sends this command to trigger re-enrollment, i.e. update of operational certificate. Extreme care must be taken.
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"method" : "reenroll" ,
|
||||
"params" : {
|
||||
"serial" : <serial number>,
|
||||
"when" : Optional - <UTC time when to apply this config, 0 mean immediate, this is a suggestion>
|
||||
},
|
||||
"id" : <some number>
|
||||
}
|
||||
```
|
||||
|
||||
The device should answer:
|
||||
```json
|
||||
{ "jsonrpc" : "2.0" ,
|
||||
"result" : {
|
||||
"serial" : <serial number> ,
|
||||
"status" : {
|
||||
"error" : <0 or the value of $? from the shell running the command, 255 signifies a timeout>,
|
||||
"txt" : <text describing the error or success>
|
||||
},
|
||||
"id" : <same number as request>
|
||||
}
|
||||
```
|
||||
|
||||
#### Controller wants the device to switch to another controller
|
||||
Controller sends this when the device should change the controller it connects to without looking up a new redirector.
|
||||
|
||||
|
||||
243
build-ucentralgw.sh
Executable file
243
build-ucentralgw.sh
Executable file
@@ -0,0 +1,243 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to build wlan-cloud-ucentralgw project in a Debian Bookworm container
|
||||
# Dependencies are built in a temporary folder within the repo
|
||||
|
||||
set -e
|
||||
|
||||
# Configuration
|
||||
POCO_VERSION="poco-tip-v4-tag"
|
||||
CPPKAFKA_VERSION="tip-v1"
|
||||
VALIJSON_VERSION="tip-v1.0.2"
|
||||
DEBIAN_VERSION="bookworm"
|
||||
TEMP_BUILD_DIR=".build-deps"
|
||||
OUTPUT_DIR="./cmake-build"
|
||||
BINARY_NAME="owgw"
|
||||
CONTAINER_NAME="ucentralgw-builder-$$"
|
||||
IMAGE_NAME="ucentralgw-build-env:${DEBIAN_VERSION}"
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
echo -e "${GREEN}=== Building wlan-cloud-ucentralgw in Debian ${DEBIAN_VERSION} container ===${NC}"
|
||||
|
||||
# Check if Docker is available
|
||||
if ! command -v docker >/dev/null 2>&1; then
|
||||
echo -e "${RED}Error: Docker is not installed or not in PATH${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create temporary build directory structure
|
||||
echo -e "${YELLOW}Creating temporary build directory: ${TEMP_BUILD_DIR}${NC}"
|
||||
mkdir -p "${TEMP_BUILD_DIR}"
|
||||
mkdir -p "${OUTPUT_DIR}"
|
||||
|
||||
# Create Dockerfile for build environment
|
||||
echo -e "${YELLOW}Creating build environment Dockerfile...${NC}"
|
||||
cat > "${TEMP_BUILD_DIR}/Dockerfile.build" <<EOF
|
||||
FROM debian:${DEBIAN_VERSION}
|
||||
|
||||
# Install build dependencies
|
||||
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 libfmt-dev
|
||||
|
||||
# Set working directory
|
||||
WORKDIR /build
|
||||
|
||||
# Copy build script into container
|
||||
COPY build-in-container.sh /build/
|
||||
RUN chmod +x /build/build-in-container.sh
|
||||
|
||||
# Entry point
|
||||
ENTRYPOINT ["/build/build-in-container.sh"]
|
||||
EOF
|
||||
|
||||
# Create the build script that runs inside the container
|
||||
echo -e "${YELLOW}Creating in-container build script...${NC}"
|
||||
cat > "${TEMP_BUILD_DIR}/build-in-container.sh" <<'EOFSCRIPT'
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
POCO_VERSION="poco-tip-v4-tag"
|
||||
CPPKAFKA_VERSION="tip-v1"
|
||||
VALIJSON_VERSION="tip-v1.0.2"
|
||||
BUILD_DIR="/build/deps"
|
||||
INSTALL_PREFIX="/build/install"
|
||||
REPO_DIR="/repo"
|
||||
OUTPUT_DIR="/repo/cmake-build"
|
||||
|
||||
# Number of parallel jobs
|
||||
JOBS=$(nproc 2>/dev/null || echo 4)
|
||||
|
||||
echo "=== Building dependencies in container ==="
|
||||
echo "Using ${JOBS} parallel jobs"
|
||||
|
||||
# Function to build a dependency
|
||||
build_dependency() {
|
||||
local name=$1
|
||||
local repo=$2
|
||||
local branch=$3
|
||||
local build_dir="${BUILD_DIR}/${name}"
|
||||
|
||||
echo "Building ${name}..."
|
||||
|
||||
if [ ! -d "${build_dir}" ]; then
|
||||
echo "Cloning ${name} from ${repo} (branch: ${branch})"
|
||||
git clone --depth 1 --branch "${branch}" "${repo}" "${build_dir}"
|
||||
fi
|
||||
|
||||
mkdir -p "${build_dir}/cmake-build"
|
||||
cd "${build_dir}/cmake-build"
|
||||
|
||||
echo "Configuring ${name}..."
|
||||
if [ "${name}" = "poco" ]; then
|
||||
# POCO needs special configuration to enable all required components
|
||||
cmake -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" \
|
||||
-DENABLE_JSON=ON \
|
||||
-DENABLE_CRYPTO=ON \
|
||||
-DENABLE_JWT=ON \
|
||||
-DENABLE_NET=ON \
|
||||
-DENABLE_NETSSL=ON \
|
||||
-DENABLE_UTIL=ON \
|
||||
-DENABLE_DATA=ON \
|
||||
-DENABLE_DATA_SQLITE=ON \
|
||||
-DENABLE_DATA_POSTGRESQL=ON \
|
||||
-DENABLE_DATA_MYSQL=ON \
|
||||
..
|
||||
else
|
||||
cmake -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" ..
|
||||
fi
|
||||
|
||||
echo "Building ${name}..."
|
||||
cmake --build . --config Release -j${JOBS}
|
||||
|
||||
echo "Installing ${name}..."
|
||||
cmake --build . --target install
|
||||
|
||||
# For POCO, create symlinks if needed and show what was installed
|
||||
if [ "${name}" = "poco" ]; then
|
||||
echo "POCO libraries installed:"
|
||||
find "${INSTALL_PREFIX}/lib" -name "libPoco*" -type f || true
|
||||
|
||||
# Run ldconfig to update library cache
|
||||
cd "${INSTALL_PREFIX}/lib"
|
||||
|
||||
# Create missing symlinks if needed
|
||||
for lib in libPocoJSON.so libPocoCrypto.so libPocoNet.so libPocoNetSSL.so libPocoUtil.so libPocoFoundation.so libPocoData.so libPocoDataSQLite.so libPocoDataPostgreSQL.so libPocoDataMySQL.so libPocoJWT.so; do
|
||||
if [ ! -e "${lib}" ]; then
|
||||
# Find versioned library and create symlink
|
||||
versioned=$(find . -maxdepth 1 -name "${lib}.*" | head -n 1)
|
||||
if [ -n "$versioned" ]; then
|
||||
echo "Creating symlink: ${lib} -> ${versioned}"
|
||||
ln -sf "$(basename ${versioned})" "${lib}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
echo "${name} built successfully"
|
||||
}
|
||||
|
||||
# Create directories
|
||||
mkdir -p "${BUILD_DIR}"
|
||||
mkdir -p "${INSTALL_PREFIX}"
|
||||
|
||||
# Build POCO
|
||||
build_dependency \
|
||||
"poco" \
|
||||
"https://github.com/Telecominfraproject/wlan-cloud-lib-poco" \
|
||||
"${POCO_VERSION}"
|
||||
|
||||
# Build cppkafka
|
||||
build_dependency \
|
||||
"cppkafka" \
|
||||
"https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka" \
|
||||
"${CPPKAFKA_VERSION}"
|
||||
|
||||
# Build valijson
|
||||
build_dependency \
|
||||
"valijson" \
|
||||
"https://github.com/Telecominfraproject/wlan-cloud-lib-valijson" \
|
||||
"${VALIJSON_VERSION}"
|
||||
|
||||
# Build the main application
|
||||
echo "=== Building owgw ==="
|
||||
|
||||
cd "${REPO_DIR}"
|
||||
|
||||
# Configure git to trust the repository directory (needed for mounted volumes)
|
||||
git config --global --add safe.directory /repo
|
||||
|
||||
# Clean the build directory to avoid CMake cache conflicts
|
||||
if [ -d "${OUTPUT_DIR}" ]; then
|
||||
echo "Cleaning existing build directory..."
|
||||
rm -rf "${OUTPUT_DIR}"
|
||||
fi
|
||||
|
||||
mkdir -p "${OUTPUT_DIR}"
|
||||
cd "${OUTPUT_DIR}"
|
||||
|
||||
echo "Configuring owgw..."
|
||||
export CMAKE_PREFIX_PATH="${INSTALL_PREFIX}"
|
||||
export PKG_CONFIG_PATH="${INSTALL_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}"
|
||||
export LD_LIBRARY_PATH="${INSTALL_PREFIX}/lib:${LD_LIBRARY_PATH}"
|
||||
|
||||
# Debug: show what libraries are available
|
||||
echo "Installed libraries in ${INSTALL_PREFIX}/lib:"
|
||||
ls -la "${INSTALL_PREFIX}/lib" || true
|
||||
|
||||
cmake \
|
||||
-DCMAKE_PREFIX_PATH="${INSTALL_PREFIX}" \
|
||||
-DCMAKE_LIBRARY_PATH="${INSTALL_PREFIX}/lib" \
|
||||
-DPoco_DIR="${INSTALL_PREFIX}/lib/cmake/Poco" \
|
||||
-DCppKafka_DIR="${INSTALL_PREFIX}/lib/cmake/CppKafka" \
|
||||
..
|
||||
|
||||
echo "Building owgw..."
|
||||
echo "Library search paths:"
|
||||
echo " LD_LIBRARY_PATH=${LD_LIBRARY_PATH}"
|
||||
echo " CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}"
|
||||
|
||||
# Build with explicit library path
|
||||
LIBRARY_PATH="${INSTALL_PREFIX}/lib:${LIBRARY_PATH}" \
|
||||
cmake --build . --config Release -j${JOBS}
|
||||
|
||||
echo "=== Build completed successfully ==="
|
||||
EOFSCRIPT
|
||||
|
||||
# Build the Docker image
|
||||
echo -e "${YELLOW}Building Docker image (this may take a while on first run)...${NC}"
|
||||
docker build \
|
||||
-t "${IMAGE_NAME}" \
|
||||
-f "${TEMP_BUILD_DIR}/Dockerfile.build" \
|
||||
"${TEMP_BUILD_DIR}"
|
||||
|
||||
# Run the build in the container
|
||||
echo -e "${YELLOW}Running build in container...${NC}"
|
||||
docker run --rm \
|
||||
--name "${CONTAINER_NAME}" \
|
||||
-v "$(pwd):/repo" \
|
||||
-v "$(pwd)/${TEMP_BUILD_DIR}/build-cache:/build/deps" \
|
||||
"${IMAGE_NAME}"
|
||||
|
||||
echo -e "${GREEN}=== Build completed successfully! ===${NC}"
|
||||
echo -e "${GREEN}Binary location: ${OUTPUT_DIR}/${BINARY_NAME}${NC}"
|
||||
echo ""
|
||||
echo "To run the binary, you'll need the dependencies installed or use the container."
|
||||
echo ""
|
||||
echo "To clean up build dependencies:"
|
||||
echo -e "${YELLOW} rm -rf ${TEMP_BUILD_DIR}${NC}"
|
||||
echo ""
|
||||
echo "To remove the Docker image:"
|
||||
echo -e "${YELLOW} docker rmi ${IMAGE_NAME}${NC}"
|
||||
echo ""
|
||||
echo "Note: The temporary build directory (${TEMP_BUILD_DIR}) is excluded from git."
|
||||
|
||||
exit 0
|
||||
@@ -14,6 +14,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
||||
WEBSOCKET_HOST_CAS=${WEBSOCKET_HOST_CAS:-"\${APP_ROOT}/certs/cas"} \
|
||||
WEBSOCKET_HOST_PORT=${WEBSOCKET_HOST_PORT:-"15002"} \
|
||||
WEBSOCKET_HOST_KEY_PASSWORD=${WEBSOCKET_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
WEBSOCKET_HOST_SECURITY=${WEBSOCKET_HOST_SECURITY:-"strict"} \
|
||||
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\${APP_ROOT}/certs/restapi-ca.pem"} \
|
||||
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16002"} \
|
||||
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\${APP_ROOT}/certs/restapi-cert.pem"} \
|
||||
@@ -32,6 +33,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
||||
FILEUPLOADER_HOST_KEY_PASSWORD=${FILEUPLOADER_HOST_KEY_PASSWORD:-"mypassword"} \
|
||||
FILEUPLOADER_PATH=${FILEUPLOADER_PATH:-"\${APP_ROOT}/uploads"} \
|
||||
FILEUPLOADER_URI=${FILEUPLOADER_URI:-"https://localhost:16003"} \
|
||||
FILEUPLOADER_MAXSIZE=${FILEUPLOADER_MAXSIZE:-"10000"} \
|
||||
SERVICE_KEY=${SERVICE_KEY:-"\${APP_ROOT}/certs/restapi-key.pem"} \
|
||||
SERVICE_KEY_PASSWORD=${SERVICE_KEY_PASSWORD:-"mypassword"} \
|
||||
SYSTEM_DATA=${SYSTEM_DATA:-"\${APP_ROOT}/data"} \
|
||||
@@ -76,6 +78,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
||||
CERTIFICATES_ALLOWMISMATCH=${CERTIFICATES_ALLOWMISMATCH:-"false"} \
|
||||
IPINFO_DEFAULT_COUNTRY=${IPINFO_DEFAULT_COUNTRY:-"US"} \
|
||||
DEVICE_SESSION_TIMEOUT=${DEVICE_SESSION_TIMEOUT:-"600"} \
|
||||
LOGGING_LEVEL=${LOGGING_LEVEL:-"information"} \
|
||||
envsubst < /"${APP_NAME}".properties.tmpl > "${APP_CONFIG}"/"${APP_NAME}".properties
|
||||
fi
|
||||
|
||||
|
||||
@@ -1576,6 +1576,15 @@ components:
|
||||
format: base64
|
||||
description: This is a base64 encoded string of the certificate bundle (the current bundle .tar.gz file from the PKI portal)
|
||||
|
||||
ReenrollRequest:
|
||||
type: object
|
||||
properties:
|
||||
serialNumber:
|
||||
type: string
|
||||
when:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
PowerCycleRequest:
|
||||
type: object
|
||||
properties:
|
||||
@@ -1600,6 +1609,74 @@ components:
|
||||
maximum: 60000
|
||||
description: off time in milliseconds
|
||||
|
||||
PackageGetResponse:
|
||||
type: object
|
||||
properties:
|
||||
serial:
|
||||
type: string
|
||||
status:
|
||||
type: object
|
||||
properties:
|
||||
package:
|
||||
type: string
|
||||
text:
|
||||
type: string
|
||||
uuid:
|
||||
type: number
|
||||
|
||||
|
||||
PackageInstallRequest:
|
||||
type: object
|
||||
properties:
|
||||
serialNumber:
|
||||
type: string
|
||||
packages:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
url:
|
||||
type: string
|
||||
|
||||
PackageInstallResponse:
|
||||
type: object
|
||||
properties:
|
||||
serial:
|
||||
type: string
|
||||
status:
|
||||
type: object
|
||||
properties:
|
||||
error:
|
||||
type: number
|
||||
packages:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
result:
|
||||
type: string
|
||||
text:
|
||||
type: string
|
||||
uuid:
|
||||
type: number
|
||||
|
||||
PackageRemoveRequest:
|
||||
type: object
|
||||
properties:
|
||||
serialNumber:
|
||||
type: string
|
||||
packages:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
|
||||
paths:
|
||||
/devices:
|
||||
get:
|
||||
@@ -3056,6 +3133,32 @@ paths:
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/device/{serialNumber}/reenroll:
|
||||
post:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Reenroll operational certificate for the device.
|
||||
operationId: reenrollCertificate
|
||||
parameters:
|
||||
- in: path
|
||||
name: serialNumber
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
requestBody:
|
||||
description: Reenroll operational certificate for the device
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ReenrollRequest'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/Success'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/device/{serialNumber}/powercycle:
|
||||
post:
|
||||
tags:
|
||||
@@ -3084,6 +3187,98 @@ paths:
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/device/{serialNumber}/package:
|
||||
get:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Get package installed on the remote device.
|
||||
operationId: getDevicePackages
|
||||
parameters:
|
||||
- in: path
|
||||
name: serialNumber
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
- in: query
|
||||
name: pkgName
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
description: The name or identifier of the package to retrieve.
|
||||
responses:
|
||||
200:
|
||||
description: Successful command execution
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PackageGetResponse'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
post:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Install IPK files to remote device.
|
||||
operationId: postDevicePackages
|
||||
parameters:
|
||||
- in: path
|
||||
name: serialNumber
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
requestBody:
|
||||
description: Packages to be installed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PackageInstallRequest'
|
||||
responses:
|
||||
200:
|
||||
description: Successful command execution
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PackageInstallResponse'
|
||||
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- Commands
|
||||
summary: Remove install packages from remote device.
|
||||
operationId: deleteDevicePackages
|
||||
parameters:
|
||||
- in: path
|
||||
name: serialNumber
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
requestBody:
|
||||
description: Packages to be removed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PackageRemoveRequest'
|
||||
responses:
|
||||
200:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PackageInstallResponse'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/ouis:
|
||||
get:
|
||||
tags:
|
||||
|
||||
@@ -12,7 +12,7 @@ ucentral.websocket.host.0.clientcas = ${WEBSOCKET_HOST_CLIENTCAS}
|
||||
ucentral.websocket.host.0.cas = ${WEBSOCKET_HOST_CAS}
|
||||
ucentral.websocket.host.0.address = *
|
||||
ucentral.websocket.host.0.port = ${WEBSOCKET_HOST_PORT}
|
||||
ucentral.websocket.host.0.security = strict
|
||||
ucentral.websocket.host.0.security = ${WEBSOCKET_HOST_SECURITY}
|
||||
ucentral.websocket.host.0.key.password = ${WEBSOCKET_HOST_KEY_PASSWORD}
|
||||
ucentral.websocket.maxreactors = 20
|
||||
|
||||
@@ -52,7 +52,8 @@ openwifi.fileuploader.host.0.cert = ${FILEUPLOADER_HOST_CERT}
|
||||
openwifi.fileuploader.host.0.key = ${FILEUPLOADER_HOST_KEY}
|
||||
openwifi.fileuploader.host.0.key.password = ${FILEUPLOADER_HOST_KEY_PASSWORD}
|
||||
openwifi.fileuploader.path = ${FILEUPLOADER_PATH}
|
||||
openwifi.fileuploader.maxsize = 10000
|
||||
# maxsize in KB
|
||||
openwifi.fileuploader.maxsize = ${FILEUPLOADER_MAXSIZE}
|
||||
openwifi.fileuploader.uri = ${FILEUPLOADER_URI}
|
||||
|
||||
#
|
||||
@@ -182,4 +183,4 @@ archiver.db.3.keep = 7
|
||||
########################################################################
|
||||
logging.type = console
|
||||
logging.path = $OWGW_ROOT/logs
|
||||
logging.level = information
|
||||
logging.level = ${LOGGING_LEVEL}
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <Poco/Net/Context.h>
|
||||
#include <Poco/Net/HTTPServerRequestImpl.h>
|
||||
#include <Poco/Net/HTTPServerResponseImpl.h>
|
||||
#include <Poco/JSON/JSONException.h>
|
||||
#include <Poco/Net/NetException.h>
|
||||
#include <Poco/Net/SSLException.h>
|
||||
#include <Poco/Net/SecureStreamSocketImpl.h>
|
||||
@@ -39,7 +40,7 @@ namespace OpenWifi {
|
||||
Poco::Net::HTTPServerResponse &response,
|
||||
uint64_t session_id, Poco::Logger &L,
|
||||
std::pair<std::shared_ptr<Poco::Net::SocketReactor>, std::shared_ptr<LockedDbSession>> R)
|
||||
: Logger_(L) {
|
||||
: Logger_(L), IncomingFrame_(0) {
|
||||
|
||||
Reactor_ = R.first;
|
||||
DbSession_ = R.second;
|
||||
@@ -54,6 +55,7 @@ namespace OpenWifi {
|
||||
WS_->setNoDelay(false);
|
||||
WS_->setKeepAlive(true);
|
||||
WS_->setBlocking(false);
|
||||
IncomingFrame_.resize(0);
|
||||
uuid_ = MicroServiceRandom(std::numeric_limits<std::uint64_t>::max()-1);
|
||||
|
||||
AP_WS_Server()->IncrementConnectionCount();
|
||||
@@ -213,6 +215,7 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
State_.certificateExpiryDate = PeerCert.expiresOn().timestamp().epochTime();
|
||||
State_.certificateIssuerName = PeerCert.issuerName();
|
||||
|
||||
poco_trace(Logger_,
|
||||
fmt::format("TLS-CONNECTION({}): Session={} CN={} Completed. (t={})", CId_,
|
||||
@@ -599,36 +602,95 @@ namespace OpenWifi {
|
||||
EndConnection();
|
||||
}
|
||||
|
||||
void AP_WS_Connection::ProcessIncomingFrame() {
|
||||
Poco::Buffer<char> IncomingFrame(0);
|
||||
void AP_WS_Connection::ProcessWSFinalPayload() {
|
||||
auto IncomingSize = IncomingFrame_.size();
|
||||
|
||||
if (IncomingSize == 0) {
|
||||
poco_debug(Logger_,
|
||||
fmt::format("ProcessWSFrame({}): Final Acc. Frame received but empty",
|
||||
CId_));
|
||||
return;
|
||||
}
|
||||
IncomingFrame_.append(0);
|
||||
|
||||
poco_trace(Logger_,
|
||||
fmt::format("ProcessWSFrame({}): Final Acc. Frame received (len={}, Msg={}",
|
||||
CId_, IncomingSize, IncomingFrame_.begin()));
|
||||
|
||||
Poco::JSON::Parser parser;
|
||||
auto ParsedMessage = parser.parse(IncomingFrame_.begin());
|
||||
auto IncomingJSON = ParsedMessage.extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (IncomingJSON->has(uCentralProtocol::JSONRPC)) {
|
||||
if (IncomingJSON->has(uCentralProtocol::METHOD) &&
|
||||
IncomingJSON->has(uCentralProtocol::PARAMS)) {
|
||||
ProcessJSONRPCEvent(IncomingJSON);
|
||||
} else if (IncomingJSON->has(uCentralProtocol::RESULT) &&
|
||||
IncomingJSON->has(uCentralProtocol::ID)) {
|
||||
poco_trace(Logger_, fmt::format("RPC-RESULT({}): payload: {}", CId_,
|
||||
IncomingFrame_.begin()));
|
||||
ProcessJSONRPCResult(IncomingJSON);
|
||||
} else {
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("INVALID-PAYLOAD({}): Payload is not JSON-RPC 2.0: {}",
|
||||
CId_, IncomingFrame_.begin()));
|
||||
}
|
||||
} else if (IncomingJSON->has(uCentralProtocol::RADIUS)) {
|
||||
ProcessIncomingRadiusData(IncomingJSON);
|
||||
} else {
|
||||
std::ostringstream iS;
|
||||
IncomingJSON->stringify(iS);
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("FRAME({}): illegal transaction header, missing 'jsonrpc': {}",
|
||||
CId_, iS.str()));
|
||||
Errors_++;
|
||||
}
|
||||
IncomingFrame_.clear();
|
||||
IncomingFrame_.resize(0);
|
||||
}
|
||||
|
||||
void AP_WS_Connection::ProcessIncomingFrame() {
|
||||
Poco::Buffer<char> CurrentFrame(0);
|
||||
bool KillConnection = false;
|
||||
int flags = 0;
|
||||
int IncomingSize = 0;
|
||||
|
||||
bool KillConnection=false;
|
||||
try {
|
||||
int Op, flags;
|
||||
auto IncomingSize = WS_->receiveFrame(IncomingFrame, flags);
|
||||
IncomingSize = WS_->receiveFrame(CurrentFrame, flags);
|
||||
int Op;
|
||||
|
||||
Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
||||
|
||||
if (IncomingSize == 0 && flags == 0 && Op == 0) {
|
||||
if (IncomingSize < 0 && flags == 0) {
|
||||
poco_trace(Logger_,
|
||||
fmt::format("EMPTY({}): Non-blocking try-again empty frame (len={}, flags={})",
|
||||
CId_, IncomingSize, flags));
|
||||
} else if (IncomingSize == 0 && flags == 0) {
|
||||
poco_information(Logger_,
|
||||
fmt::format("DISCONNECT({}): device has disconnected. Session={}",
|
||||
CId_, State_.sessionId));
|
||||
return EndConnection();
|
||||
}
|
||||
|
||||
IncomingFrame.append(0);
|
||||
|
||||
State_.RX += IncomingSize;
|
||||
AP_WS_Server()->AddRX(IncomingSize);
|
||||
if (IncomingSize > 0) {
|
||||
State_.RX += IncomingSize;
|
||||
AP_WS_Server()->AddRX(IncomingSize);
|
||||
IncomingFrame_.append(CurrentFrame);
|
||||
}
|
||||
State_.MessageCount++;
|
||||
State_.LastContact = Utils::Now();
|
||||
poco_trace(Logger_,
|
||||
fmt::format("FRAME({}): Frame rx (op={} len={}, flags={}, acc.len={})",
|
||||
CId_, Op, IncomingSize, flags, IncomingFrame_.size()));
|
||||
|
||||
switch (Op) {
|
||||
case Poco::Net::WebSocket::FRAME_OP_PING: {
|
||||
poco_trace(Logger_, fmt::format("WS-PING({}): received. PONG sent back.", CId_));
|
||||
poco_trace(Logger_, fmt::format("PING({}): received. PONG sent back.", CId_));
|
||||
WS_->sendFrame("", 0,
|
||||
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
|
||||
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
||||
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
||||
|
||||
if (KafkaManager()->Enabled()) {
|
||||
Poco::JSON::Object PingObject;
|
||||
@@ -642,49 +704,32 @@ namespace OpenWifi {
|
||||
PingDetails.set("locale", State_.locale);
|
||||
PingObject.set(uCentralProtocol::PING, PingDetails);
|
||||
poco_trace(Logger_,fmt::format("Sending PING for {}", SerialNumber_));
|
||||
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_,PingObject);
|
||||
KafkaManager()->PostMessage(KafkaTopics::CONNECTION, SerialNumber_,
|
||||
PingObject);
|
||||
}
|
||||
return;
|
||||
} break;
|
||||
|
||||
case Poco::Net::WebSocket::FRAME_OP_PONG: {
|
||||
poco_trace(Logger_, fmt::format("PONG({}): received and ignored.", CId_));
|
||||
return;
|
||||
} break;
|
||||
|
||||
case Poco::Net::WebSocket::FRAME_OP_CONT: {
|
||||
poco_trace(Logger_, fmt::format("CONTINUATION({}): registered.", CId_));
|
||||
} break;
|
||||
|
||||
case Poco::Net::WebSocket::FRAME_OP_BINARY: {
|
||||
poco_trace(Logger_, fmt::format("BINARY({}): Invalid frame type.", CId_));
|
||||
KillConnection=true;
|
||||
return;
|
||||
} break;
|
||||
|
||||
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
|
||||
poco_trace(Logger_,
|
||||
fmt::format("FRAME({}): Frame received (length={}, flags={}). Msg={}",
|
||||
CId_, IncomingSize, flags, IncomingFrame.begin()));
|
||||
|
||||
Poco::JSON::Parser parser;
|
||||
auto ParsedMessage = parser.parse(IncomingFrame.begin());
|
||||
auto IncomingJSON = ParsedMessage.extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (IncomingJSON->has(uCentralProtocol::JSONRPC)) {
|
||||
if (IncomingJSON->has(uCentralProtocol::METHOD) &&
|
||||
IncomingJSON->has(uCentralProtocol::PARAMS)) {
|
||||
ProcessJSONRPCEvent(IncomingJSON);
|
||||
} else if (IncomingJSON->has(uCentralProtocol::RESULT) &&
|
||||
IncomingJSON->has(uCentralProtocol::ID)) {
|
||||
poco_trace(Logger_, fmt::format("RPC-RESULT({}): payload: {}", CId_,
|
||||
IncomingFrame.begin()));
|
||||
ProcessJSONRPCResult(IncomingJSON);
|
||||
} else {
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("INVALID-PAYLOAD({}): Payload is not JSON-RPC 2.0: {}",
|
||||
CId_, IncomingFrame.begin()));
|
||||
}
|
||||
} else if (IncomingJSON->has(uCentralProtocol::RADIUS)) {
|
||||
ProcessIncomingRadiusData(IncomingJSON);
|
||||
} else {
|
||||
std::ostringstream iS;
|
||||
IncomingJSON->stringify(iS);
|
||||
poco_warning(
|
||||
Logger_,
|
||||
fmt::format("FRAME({}): illegal transaction header, missing 'jsonrpc': {}",
|
||||
CId_, iS.str()));
|
||||
Errors_++;
|
||||
}
|
||||
fmt::format("TEXT({}): Frame received (len={}, flags={}). Msg={}",
|
||||
CId_, IncomingSize, flags,
|
||||
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin()));
|
||||
} break;
|
||||
|
||||
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
|
||||
@@ -700,25 +745,31 @@ namespace OpenWifi {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for final frame and process accumulated payload
|
||||
if (!KillConnection && (flags & Poco::Net::WebSocket::FRAME_FLAG_FIN) != 0) {
|
||||
ProcessWSFinalPayload();
|
||||
}
|
||||
|
||||
} catch (const Poco::Net::ConnectionResetException &E) {
|
||||
poco_warning(Logger_,
|
||||
fmt::format("ConnectionResetException({}): Text:{} Payload:{} Session:{}",
|
||||
CId_, E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
|
||||
State_.sessionId));
|
||||
KillConnection=true;
|
||||
} catch (const Poco::JSON::JSONException &E) {
|
||||
poco_warning(Logger_,
|
||||
fmt::format("JSONException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||
E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
|
||||
State_.sessionId));
|
||||
KillConnection=true;
|
||||
} catch (const Poco::Net::WebSocketException &E) {
|
||||
poco_warning(Logger_,
|
||||
fmt::format("WebSocketException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||
E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
|
||||
State_.sessionId));
|
||||
KillConnection=true;
|
||||
} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) {
|
||||
@@ -727,42 +778,42 @@ namespace OpenWifi {
|
||||
fmt::format(
|
||||
"SSLConnectionUnexpectedlyClosedException({}): Text:{} Payload:{} Session:{}",
|
||||
CId_, E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
|
||||
State_.sessionId));
|
||||
KillConnection=true;
|
||||
} catch (const Poco::Net::SSLException &E) {
|
||||
poco_warning(Logger_,
|
||||
fmt::format("SSLException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||
E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
|
||||
State_.sessionId));
|
||||
KillConnection=true;
|
||||
} catch (const Poco::Net::NetException &E) {
|
||||
poco_warning(Logger_,
|
||||
fmt::format("NetException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||
E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
|
||||
State_.sessionId));
|
||||
KillConnection=true;
|
||||
} catch (const Poco::IOException &E) {
|
||||
poco_warning(Logger_,
|
||||
fmt::format("IOException({}): Text:{} Payload:{} Session:{}", CId_,
|
||||
E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
|
||||
State_.sessionId));
|
||||
KillConnection=true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
poco_warning(Logger_,
|
||||
fmt::format("Exception({}): Text:{} Payload:{} Session:{}", CId_,
|
||||
E.displayText(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
|
||||
State_.sessionId));
|
||||
KillConnection=true;
|
||||
} catch (const std::exception &E) {
|
||||
poco_warning(Logger_,
|
||||
fmt::format("std::exception({}): Text:{} Payload:{} Session:{}", CId_,
|
||||
E.what(),
|
||||
IncomingFrame.begin() == nullptr ? "" : IncomingFrame.begin(),
|
||||
CurrentFrame.begin() == nullptr ? "" : CurrentFrame.begin(),
|
||||
State_.sessionId));
|
||||
KillConnection=true;
|
||||
} catch (...) {
|
||||
@@ -775,7 +826,9 @@ namespace OpenWifi {
|
||||
if (!KillConnection && Errors_ < 10)
|
||||
return;
|
||||
|
||||
poco_warning(Logger_, fmt::format("DISCONNECTING({}): ConnectionException: {} Errors: {}", CId_, KillConnection, Errors_ ));
|
||||
poco_warning(Logger_,
|
||||
fmt::format("DISCONNECTING({}): ConnectionException: {} Errors: {}",
|
||||
CId_, KillConnection, Errors_ ));
|
||||
EndConnection();
|
||||
}
|
||||
|
||||
@@ -920,4 +973,4 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
namespace OpenWifi {
|
||||
|
||||
class AP_WS_Connection {
|
||||
static constexpr int BufSize = 256000;
|
||||
static constexpr int BufSize = 512000;
|
||||
|
||||
public:
|
||||
explicit AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
|
||||
@@ -33,6 +33,7 @@ namespace OpenWifi {
|
||||
void EndConnection();
|
||||
void ProcessJSONRPCEvent(Poco::JSON::Object::Ptr &Doc);
|
||||
void ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc);
|
||||
void ProcessWSFinalPayload();
|
||||
void ProcessIncomingFrame();
|
||||
void ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc);
|
||||
|
||||
@@ -145,6 +146,7 @@ namespace OpenWifi {
|
||||
std::uint64_t uuid_=0;
|
||||
bool Simulated_=false;
|
||||
std::atomic_uint64_t LastContact_=0;
|
||||
Poco::Buffer<char> IncomingFrame_;
|
||||
|
||||
static inline std::atomic_uint64_t ConcurrentStartingDevices_ = 0;
|
||||
|
||||
@@ -175,4 +177,4 @@ namespace OpenWifi {
|
||||
|
||||
};
|
||||
|
||||
} // namespace OpenWifi
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -105,7 +105,7 @@ namespace OpenWifi {
|
||||
Restrictions_.developer = Capabilities->getValue<bool>("developer");
|
||||
}
|
||||
|
||||
if(Capabilities->has("secure-rtty")) {
|
||||
if (Capabilities->has("secure-rtty")) {
|
||||
RTTYMustBeSecure_ = Capabilities->getValue<bool>("secure-rtty");
|
||||
}
|
||||
|
||||
|
||||
@@ -120,7 +120,6 @@ namespace OpenWifi {
|
||||
P.verificationDepth = 9;
|
||||
P.loadDefaultCAs = Svr.RootCA().empty();
|
||||
P.cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
|
||||
P.dhUse2048Bits = true;
|
||||
P.caLocation = Svr.Cas();
|
||||
|
||||
auto Context = Poco::AutoPtr<Poco::Net::Context>(
|
||||
@@ -795,4 +794,4 @@ namespace OpenWifi {
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -315,4 +315,4 @@ namespace OpenWifi {
|
||||
poco_notice(Logger(), "Stopped...");
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -91,6 +91,31 @@ namespace OpenWifi {
|
||||
TransactionId_, UUID, RPC, Poco::Thread::current()->id()));
|
||||
return Rtty(UUID, RPC, 60000ms, Restrictions);
|
||||
};
|
||||
case APCommands::Commands::package:{
|
||||
GWObjects::DeviceRestrictions Restrictions;
|
||||
std::string pkg_name = "";
|
||||
if (!AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) {
|
||||
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected);
|
||||
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
|
||||
}
|
||||
Poco::URI uri(Request->getURI());
|
||||
for (const auto ¶m : uri.getQueryParameters()) {
|
||||
if (param.first == "pkgName") {
|
||||
pkg_name = param.second;
|
||||
}
|
||||
}
|
||||
if (pkg_name.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
auto UUID = MicroServiceCreateUUID();
|
||||
auto RPC = CommandManager()->Next_RPC_ID();
|
||||
poco_debug(
|
||||
Logger_,
|
||||
fmt::format(
|
||||
"Command Package TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
|
||||
TransactionId_, UUID, RPC, Poco::Thread::current()->id()));
|
||||
return GetPackages(UUID, RPC, pkg_name, 300000ms, Restrictions);
|
||||
}
|
||||
default:
|
||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
}
|
||||
@@ -128,6 +153,21 @@ namespace OpenWifi {
|
||||
return DeleteChecks();
|
||||
case APCommands::Commands::statistics:
|
||||
return DeleteStatistics();
|
||||
case APCommands::Commands::package: {
|
||||
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 DeletePackages(UUID, RPC, 300000ms, Restrictions);
|
||||
}
|
||||
default:
|
||||
return BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
}
|
||||
@@ -170,7 +210,8 @@ namespace OpenWifi {
|
||||
{APCommands::Commands::powercycle, false, true, &RESTAPI_device_commandHandler::PowerCycle, 60000ms},
|
||||
{APCommands::Commands::fixedconfig, false, true, &RESTAPI_device_commandHandler::FixedConfig, 120000ms},
|
||||
{APCommands::Commands::cablediagnostics, false, true, &RESTAPI_device_commandHandler::CableDiagnostics, 120000ms},
|
||||
|
||||
{APCommands::Commands::reenroll, false, true, &RESTAPI_device_commandHandler::ReEnroll, 120000ms},
|
||||
{APCommands::Commands::package, false, true, &RESTAPI_device_commandHandler::PackageInstall, 120000ms},
|
||||
};
|
||||
|
||||
void RESTAPI_device_commandHandler::DoPost() {
|
||||
@@ -408,6 +449,210 @@ namespace OpenWifi {
|
||||
BadRequest(RESTAPI::Errors::NoRecordsDeleted);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::GetPackages(const std::string &CMD_UUID, uint64_t CMD_RPC,
|
||||
const std::string pkg_name,
|
||||
[[maybe_unused]] std::chrono::milliseconds timeout,
|
||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
||||
poco_debug(Logger_, fmt::format("GET-PACKAGES: TID={}, user={} serial={}. thr_id={}",
|
||||
TransactionId_, Requester(), SerialNumber_,
|
||||
Poco::Thread::current()->id()));
|
||||
|
||||
if (IsDeviceSimulated(SerialNumber_)) {
|
||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
||||
}
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
Params.set(uCentralProtocol::OPERATION, "list");
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::PACKAGE, pkg_name);
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = CMD_UUID;
|
||||
Cmd.SubmittedBy = Requester();
|
||||
Cmd.Command = uCentralProtocol::PACKAGE;
|
||||
Cmd.RunAt = 0;
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::package, false, Cmd, Params,
|
||||
*Request, *Response, timeout, nullptr, nullptr, Logger_);
|
||||
|
||||
Poco::JSON::Object O, P;
|
||||
Cmd.to_json(O);
|
||||
|
||||
Poco::Dynamic::Var resultsVar = O.get("results");
|
||||
Poco::JSON::Object::Ptr resultsObj = resultsVar.extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
return ReturnObject(*resultsObj);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::PackageInstall(
|
||||
const std::string &CMD_UUID, uint64_t CMD_RPC,
|
||||
[[maybe_unused]] std::chrono::milliseconds timeout,
|
||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
||||
|
||||
if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT &&
|
||||
UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) {
|
||||
CallCanceled("INSTALLPACKAGE", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED);
|
||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
poco_debug(Logger_, fmt::format("INSTALL-PACKAGES({},{}): TID={} user={} serial={}", CMD_UUID,
|
||||
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
if (IsDeviceSimulated(SerialNumber_)) {
|
||||
CallCanceled("INSTALL-PACKAGES", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported);
|
||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
||||
}
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
if (!Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
CallCanceled("INSTALL-PACKAGES", CMD_UUID, CMD_RPC, RESTAPI::Errors::SerialNumberMismatch);
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
std::ostringstream os;
|
||||
ParsedBody_->stringify(os);
|
||||
|
||||
poco_information(Logger_, fmt::format("INSTALL_OBJECT: {} for device {}", os.str(), SerialNumber_));
|
||||
|
||||
GWObjects::PackageInstall PI;
|
||||
if (!PI.from_json(ParsedBody_)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
Poco::JSON::Array::Ptr ArrayObj = Poco::SharedPtr<Poco::JSON::Array>(new Poco::JSON::Array);
|
||||
for (const auto &i : PI.pkgs) {
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
Poco::SharedPtr<Poco::JSON::Object>(new Poco::JSON::Object);
|
||||
i.to_json(*Obj);
|
||||
ArrayObj->add(Obj);
|
||||
}
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
Params.set(uCentralProtocol::OPERATION, "install");
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::PACKAGES, ArrayObj);
|
||||
|
||||
std::ostringstream os2;
|
||||
Params.stringify(os2);
|
||||
|
||||
poco_information(Logger_, fmt::format("INSTALL_OBJECT2: {} for device {}", os2.str(), SerialNumber_));
|
||||
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = CMD_UUID;
|
||||
Cmd.SubmittedBy = Requester();
|
||||
Cmd.Command = uCentralProtocol::PACKAGE;
|
||||
Cmd.RunAt = 0;
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::package, false, Cmd, Params,
|
||||
*Request, *Response, timeout, nullptr, nullptr, Logger_);
|
||||
|
||||
Poco::JSON::Object O, P;
|
||||
Cmd.to_json(O);
|
||||
|
||||
Poco::Dynamic::Var resultsVar = O.get("results");
|
||||
Poco::JSON::Object::Ptr resultsObj = resultsVar.extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
return ReturnObject(*resultsObj);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::DeletePackages(
|
||||
const std::string &CMD_UUID, uint64_t CMD_RPC,
|
||||
[[maybe_unused]] std::chrono::milliseconds timeout,
|
||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
||||
|
||||
if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT &&
|
||||
UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) {
|
||||
CallCanceled("DELETE-PACKAGES", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED);
|
||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
poco_debug(Logger_, fmt::format("DELETE-PACKAGES({},{}): TID={} user={} serial={}", CMD_UUID,
|
||||
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
if (IsDeviceSimulated(SerialNumber_)) {
|
||||
CallCanceled("DELETE-PACKAGES", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported);
|
||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
||||
}
|
||||
|
||||
const auto &Obj = ParsedBody_;
|
||||
if (!Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString();
|
||||
if (SerialNumber_ != SNum) {
|
||||
CallCanceled("DELETE-PACKAGES", CMD_UUID, CMD_RPC, RESTAPI::Errors::SerialNumberMismatch);
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
std::ostringstream os;
|
||||
ParsedBody_->stringify(os);
|
||||
|
||||
poco_information(Logger_, fmt::format("DELETE_OBJECT: {} for device {}", os.str(), SerialNumber_));
|
||||
|
||||
GWObjects::PackageRemove PR;
|
||||
if (!PR.from_json(ParsedBody_)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
Poco::JSON::Array::Ptr ArrayObj = Poco::SharedPtr<Poco::JSON::Array>(new Poco::JSON::Array);
|
||||
for (const auto &i : PR.pkgs) {
|
||||
Poco::JSON::Object::Ptr Obj =
|
||||
Poco::SharedPtr<Poco::JSON::Object>(new Poco::JSON::Object);
|
||||
i.to_json(*Obj);
|
||||
ArrayObj->add(Obj);
|
||||
}
|
||||
|
||||
Poco::JSON::Object Params;
|
||||
Params.set(uCentralProtocol::OPERATION, "delete");
|
||||
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
|
||||
Params.set(uCentralProtocol::PACKAGES, ArrayObj);
|
||||
|
||||
std::ostringstream os2;
|
||||
Params.stringify(os2);
|
||||
|
||||
poco_information(Logger_, fmt::format("DELETE_OBJECT2: {} for device {}", os2.str(), SerialNumber_));
|
||||
|
||||
|
||||
std::stringstream ParamStream;
|
||||
Params.stringify(ParamStream);
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.UUID = CMD_UUID;
|
||||
Cmd.SubmittedBy = Requester();
|
||||
Cmd.Command = uCentralProtocol::PACKAGE;
|
||||
Cmd.RunAt = 0;
|
||||
Cmd.Details = ParamStream.str();
|
||||
|
||||
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::package, false, Cmd, Params,
|
||||
*Request, *Response, timeout, nullptr, nullptr, Logger_);
|
||||
|
||||
Poco::JSON::Object O, P;
|
||||
Cmd.to_json(O);
|
||||
|
||||
Poco::Dynamic::Var resultsVar = O.get("results");
|
||||
Poco::JSON::Object::Ptr resultsObj = resultsVar.extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
return ReturnObject(*resultsObj);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::Ping(
|
||||
const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout,
|
||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
||||
@@ -1651,4 +1896,45 @@ namespace OpenWifi {
|
||||
*ParsedBody_, *Request, *Response, timeout, nullptr, this,
|
||||
Logger_);
|
||||
}
|
||||
|
||||
void RESTAPI_device_commandHandler::ReEnroll(
|
||||
const std::string &CMD_UUID, uint64_t CMD_RPC,
|
||||
[[maybe_unused]] std::chrono::milliseconds timeout,
|
||||
[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) {
|
||||
|
||||
if(UserInfo_.userinfo.userRole != SecurityObjects::ROOT &&
|
||||
UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) {
|
||||
CallCanceled("REENROLL", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED);
|
||||
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||
}
|
||||
|
||||
poco_debug(Logger_, fmt::format("REENROLL({},{}): TID={} user={} serial={}", CMD_UUID,
|
||||
CMD_RPC, TransactionId_, Requester(), SerialNumber_));
|
||||
|
||||
if(IsDeviceSimulated(SerialNumber_)) {
|
||||
CallCanceled("REENROLL", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported);
|
||||
return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported);
|
||||
}
|
||||
|
||||
GWObjects::ReEnroll PR;
|
||||
if(!PR.from_json(ParsedBody_)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
GWObjects::CommandDetails Cmd;
|
||||
Cmd.SerialNumber = SerialNumber_;
|
||||
Cmd.SubmittedBy = Requester();
|
||||
Cmd.UUID = CMD_UUID;
|
||||
Cmd.Command = uCentralProtocol::REENROLL;
|
||||
std::ostringstream os;
|
||||
ParsedBody_->stringify(os);
|
||||
Cmd.Details = os.str();
|
||||
Cmd.RunAt = PR.when;
|
||||
Cmd.ErrorCode = 0;
|
||||
Cmd.WaitingForFile = 0;
|
||||
|
||||
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::reenroll, false, Cmd,
|
||||
*ParsedBody_, *Request, *Response, timeout, nullptr, this,
|
||||
Logger_);
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -33,6 +33,13 @@ namespace OpenWifi {
|
||||
void GetStatus();
|
||||
void GetChecks();
|
||||
void DeleteChecks();
|
||||
void GetPackages(const std::string &UUID, uint64_t RPC,
|
||||
std::string pkg_name,
|
||||
std::chrono::milliseconds timeout,
|
||||
const GWObjects::DeviceRestrictions &R);
|
||||
void DeletePackages(const std::string &UUID, uint64_t RPC,
|
||||
std::chrono::milliseconds timeout,
|
||||
const GWObjects::DeviceRestrictions &R);
|
||||
|
||||
bool IsDeviceSimulated(std::string &Serial);
|
||||
|
||||
@@ -74,6 +81,10 @@ namespace OpenWifi {
|
||||
const GWObjects::DeviceRestrictions &R);
|
||||
void CableDiagnostics(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
||||
const GWObjects::DeviceRestrictions &R);
|
||||
void ReEnroll(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout,
|
||||
const GWObjects::DeviceRestrictions &R);
|
||||
void PackageInstall(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}"};
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
#include "Daemon.h"
|
||||
#ifdef TIP_GATEWAY_SERVICE
|
||||
#include "AP_WS_Server.h"
|
||||
#include "StorageService.h"
|
||||
#include "CapabilitiesCache.h"
|
||||
#include "RADIUSSessionTracker.h"
|
||||
#include "StorageService.h"
|
||||
#endif
|
||||
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
@@ -31,7 +31,8 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj, "serialNumber", SerialNumber);
|
||||
#ifdef TIP_GATEWAY_SERVICE
|
||||
field_to_json(Obj, "deviceType", StorageService()->GetPlatform(SerialNumber));
|
||||
field_to_json(Obj, "blackListed", StorageService()->IsBlackListed(Utils::MACToInt(SerialNumber)));
|
||||
field_to_json(Obj, "blackListed",
|
||||
StorageService()->IsBlackListed(Utils::MACToInt(SerialNumber)));
|
||||
#endif
|
||||
field_to_json(Obj, "macAddress", MACAddress);
|
||||
field_to_json(Obj, "manufacturer", Manufacturer);
|
||||
@@ -70,12 +71,12 @@ namespace OpenWifi::GWObjects {
|
||||
#ifdef TIP_GATEWAY_SERVICE
|
||||
ConnectionState ConState;
|
||||
#ifdef USE_MEDUSA_CLIENT
|
||||
auto Res = GS()->GetState(SerialNumber);
|
||||
if (Res.has_value()) {
|
||||
Res.value().to_json(SerialNumber,Obj);
|
||||
auto Res = GS()->GetState(SerialNumber);
|
||||
if (Res.has_value()) {
|
||||
Res.value().to_json(SerialNumber, Obj);
|
||||
#else
|
||||
if (AP_WS_Server()->GetState(SerialNumber, ConState)) {
|
||||
ConState.to_json(SerialNumber,Obj);
|
||||
if (AP_WS_Server()->GetState(SerialNumber, ConState)) {
|
||||
ConState.to_json(SerialNumber, Obj);
|
||||
#endif
|
||||
} else {
|
||||
field_to_json(Obj, "ipAddress", "");
|
||||
@@ -172,17 +173,16 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj, "recorded", Recorded);
|
||||
}
|
||||
|
||||
bool HealthCheck::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "UUID", UUID);
|
||||
field_from_json(Obj, "sanity", Sanity);
|
||||
field_from_json(Obj, "recorded", Recorded);
|
||||
return true;
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool HealthCheck::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "UUID", UUID);
|
||||
field_from_json(Obj, "sanity", Sanity);
|
||||
field_from_json(Obj, "recorded", Recorded);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DefaultFirmware::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "deviceType", deviceType);
|
||||
@@ -275,7 +275,8 @@ namespace OpenWifi::GWObjects {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ConnectionState::to_json([[maybe_unused]] const std::string &SerialNumber, Poco::JSON::Object &Obj) {
|
||||
void ConnectionState::to_json([[maybe_unused]] const std::string &SerialNumber,
|
||||
Poco::JSON::Object &Obj) {
|
||||
field_to_json(Obj, "ipAddress", Address);
|
||||
field_to_json(Obj, "txBytes", TX);
|
||||
field_to_json(Obj, "rxBytes", RX);
|
||||
@@ -297,14 +298,15 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj, "connectionCompletionTime", connectionCompletionTime);
|
||||
field_to_json(Obj, "totalConnectionTime", Utils::Now() - started);
|
||||
field_to_json(Obj, "certificateExpiryDate", certificateExpiryDate);
|
||||
field_to_json(Obj, "certificateIssuerName", certificateIssuerName);
|
||||
field_to_json(Obj, "connectReason", connectReason);
|
||||
field_to_json(Obj, "uptime", uptime);
|
||||
field_to_json(Obj, "compatible", Compatible);
|
||||
field_to_json(Obj, "compatible", Compatible);
|
||||
|
||||
#ifdef TIP_GATEWAY_SERVICE
|
||||
hasRADIUSSessions = RADIUSSessionTracker()->HasSessions(SerialNumber);
|
||||
#endif
|
||||
field_to_json(Obj, "hasRADIUSSessions", hasRADIUSSessions );
|
||||
field_to_json(Obj, "hasRADIUSSessions", hasRADIUSSessions);
|
||||
field_to_json(Obj, "hasGPS", hasGPS);
|
||||
field_to_json(Obj, "sanity", sanity);
|
||||
field_to_json(Obj, "memoryUsed", memoryUsed);
|
||||
@@ -334,44 +336,45 @@ namespace OpenWifi::GWObjects {
|
||||
}
|
||||
}
|
||||
|
||||
bool ConnectionState::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "compatible", Compatible);
|
||||
field_from_json(Obj, "ipAddress", Address);
|
||||
field_from_json(Obj, "txBytes", TX);
|
||||
field_from_json(Obj, "rxBytes", RX);
|
||||
field_from_json(Obj, "messageCount", MessageCount);
|
||||
field_from_json(Obj, "UUID", UUID);
|
||||
field_from_json(Obj, "connected", Connected);
|
||||
field_from_json(Obj, "firmware", Firmware);
|
||||
field_from_json(Obj, "lastContact", LastContact);
|
||||
field_from_json(Obj, "associations_2G", Associations_2G);
|
||||
field_from_json(Obj, "associations_5G", Associations_5G);
|
||||
field_from_json(Obj, "associations_6G", Associations_6G);
|
||||
field_from_json(Obj, "webSocketClients", webSocketClients);
|
||||
field_from_json(Obj, "websocketPackets", websocketPackets);
|
||||
field_from_json(Obj, "kafkaClients", kafkaClients);
|
||||
field_from_json(Obj, "kafkaPackets", kafkaPackets);
|
||||
field_from_json(Obj, "locale", locale);
|
||||
field_from_json(Obj, "started", started);
|
||||
field_from_json(Obj, "sessionId", sessionId);
|
||||
field_from_json(Obj, "connectionCompletionTime", connectionCompletionTime);
|
||||
field_from_json(Obj, "totalConnectionTime", totalConnectionTime);
|
||||
field_from_json(Obj, "certificateExpiryDate", certificateExpiryDate);
|
||||
field_from_json(Obj, "connectReason", connectReason);
|
||||
field_from_json(Obj, "uptime", uptime);
|
||||
field_from_json(Obj, "hasRADIUSSessions", hasRADIUSSessions );
|
||||
field_from_json(Obj, "hasGPS", hasGPS);
|
||||
field_from_json(Obj, "sanity", sanity);
|
||||
field_from_json(Obj, "memoryUsed", memoryUsed);
|
||||
field_from_json(Obj, "sanity", sanity);
|
||||
field_from_json(Obj, "load", load);
|
||||
field_from_json(Obj, "temperature", temperature);
|
||||
return true;
|
||||
} catch(const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool ConnectionState::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "compatible", Compatible);
|
||||
field_from_json(Obj, "ipAddress", Address);
|
||||
field_from_json(Obj, "txBytes", TX);
|
||||
field_from_json(Obj, "rxBytes", RX);
|
||||
field_from_json(Obj, "messageCount", MessageCount);
|
||||
field_from_json(Obj, "UUID", UUID);
|
||||
field_from_json(Obj, "connected", Connected);
|
||||
field_from_json(Obj, "firmware", Firmware);
|
||||
field_from_json(Obj, "lastContact", LastContact);
|
||||
field_from_json(Obj, "associations_2G", Associations_2G);
|
||||
field_from_json(Obj, "associations_5G", Associations_5G);
|
||||
field_from_json(Obj, "associations_6G", Associations_6G);
|
||||
field_from_json(Obj, "webSocketClients", webSocketClients);
|
||||
field_from_json(Obj, "websocketPackets", websocketPackets);
|
||||
field_from_json(Obj, "kafkaClients", kafkaClients);
|
||||
field_from_json(Obj, "kafkaPackets", kafkaPackets);
|
||||
field_from_json(Obj, "locale", locale);
|
||||
field_from_json(Obj, "started", started);
|
||||
field_from_json(Obj, "sessionId", sessionId);
|
||||
field_from_json(Obj, "connectionCompletionTime", connectionCompletionTime);
|
||||
field_from_json(Obj, "totalConnectionTime", totalConnectionTime);
|
||||
field_from_json(Obj, "certificateExpiryDate", certificateExpiryDate);
|
||||
field_from_json(Obj, "certificateIssuerName", certificateIssuerName);
|
||||
field_from_json(Obj, "connectReason", connectReason);
|
||||
field_from_json(Obj, "uptime", uptime);
|
||||
field_from_json(Obj, "hasRADIUSSessions", hasRADIUSSessions);
|
||||
field_from_json(Obj, "hasGPS", hasGPS);
|
||||
field_from_json(Obj, "sanity", sanity);
|
||||
field_from_json(Obj, "memoryUsed", memoryUsed);
|
||||
field_from_json(Obj, "sanity", sanity);
|
||||
field_from_json(Obj, "load", load);
|
||||
field_from_json(Obj, "temperature", temperature);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeviceConnectionStatistics::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "averageConnectionTime", averageConnectionTime);
|
||||
@@ -819,4 +822,103 @@ namespace OpenWifi::GWObjects {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ReEnroll::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "serial", serialNumber);
|
||||
field_from_json(Obj, "when", when);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PackageInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "name", name);
|
||||
field_from_json(Obj, "version", version);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void PackageInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "name", name);
|
||||
field_to_json(Obj, "version", version);
|
||||
}
|
||||
|
||||
void PackageList::to_json(Poco::JSON::Object &Obj) const {
|
||||
Obj.set("serialNumber", serialNumber);
|
||||
|
||||
Poco::JSON::Array packageJsonArray;
|
||||
for (const auto &pkg : packageArray) {
|
||||
Poco::JSON::Object pkgObj;
|
||||
pkg.to_json(pkgObj);
|
||||
packageJsonArray.add(pkgObj);
|
||||
}
|
||||
Obj.set("packageArray", packageJsonArray);
|
||||
|
||||
Obj.set("FirstUpdate", Poco::UInt64(FirstUpdate));
|
||||
Obj.set("LastUpdate", Poco::UInt64(LastUpdate));
|
||||
}
|
||||
|
||||
bool ToBeInstalled::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "name", name);
|
||||
field_from_json(Obj, "url", url);
|
||||
|
||||
Poco::URI uri(url);
|
||||
std::string scheme = uri.getScheme();
|
||||
if (scheme != "http" && scheme != "https") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ToBeInstalled::to_json(Poco::JSON::Object &Obj) const {
|
||||
Obj.set("name", name);
|
||||
Obj.set("url", url);
|
||||
}
|
||||
|
||||
bool PackageInstall::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "serialNumber", serialNumber);
|
||||
field_from_json(Obj, "when", when);
|
||||
field_from_json(Obj, "packages", pkgs);
|
||||
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ToBeRemoved::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "name", name);
|
||||
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ToBeRemoved::to_json(Poco::JSON::Object &Obj) const {
|
||||
Obj.set("name", name);
|
||||
}
|
||||
|
||||
bool PackageRemove::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "serialNumber", serialNumber);
|
||||
field_from_json(Obj, "packages", pkgs);
|
||||
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace OpenWifi::GWObjects
|
||||
|
||||
@@ -42,6 +42,7 @@ namespace OpenWifi::GWObjects {
|
||||
uint64_t sessionId = 0;
|
||||
double connectionCompletionTime = 0.0;
|
||||
std::uint64_t certificateExpiryDate = 0;
|
||||
std::string certificateIssuerName;
|
||||
std::uint64_t hasRADIUSSessions = 0;
|
||||
bool hasGPS = false;
|
||||
std::uint64_t sanity=0;
|
||||
@@ -545,6 +546,57 @@ namespace OpenWifi::GWObjects {
|
||||
std::uint64_t when;
|
||||
std::vector<std::string> ports;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct ReEnroll {
|
||||
std::string serialNumber;
|
||||
std::uint64_t when;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
struct PackageInfo {
|
||||
std::string name;
|
||||
std::string version;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
struct PackageList {
|
||||
std::string serialNumber;
|
||||
std::vector<PackageInfo> packageArray;
|
||||
uint64_t FirstUpdate = 0;
|
||||
uint64_t LastUpdate = 0;
|
||||
std::string packageStringArray;
|
||||
|
||||
bool from_json(const Poco::JSON::Array::Ptr &Obj);
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
struct ToBeInstalled {
|
||||
std::string name;
|
||||
std::string url;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
struct PackageInstall {
|
||||
std::string serialNumber;
|
||||
std::uint64_t when;
|
||||
std::vector<ToBeInstalled> pkgs;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
struct ToBeRemoved {
|
||||
std::string name;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
struct PackageRemove {
|
||||
std::string serialNumber;
|
||||
std::uint64_t when;
|
||||
std::vector<ToBeRemoved> pkgs;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
} // namespace OpenWifi::GWObjects
|
||||
|
||||
@@ -120,14 +120,16 @@ namespace OpenWifi {
|
||||
Poco::Buffer<char> IncomingFrame(0);
|
||||
|
||||
try {
|
||||
int Op, flags;
|
||||
int IncomingSize;
|
||||
int Op, flags, IncomingSize;
|
||||
|
||||
IncomingSize = WS_->receiveFrame(IncomingFrame, flags);
|
||||
Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
||||
|
||||
if (IncomingSize == 0 && flags == 0 && Op == 0) {
|
||||
poco_information(
|
||||
Logger(),
|
||||
if (IncomingSize == -1) {
|
||||
poco_trace(Logger(),
|
||||
fmt::format("TELEMETRY-EMPTY({}): Empty frame, non-blocking try-again.", CId_));
|
||||
} else if (IncomingSize == 0 && flags == 0 && Op == 0) {
|
||||
poco_information(Logger(),
|
||||
fmt::format("TELEMETRY-DISCONNECT({}): device has disconnected.", CId_));
|
||||
MustDisconnect = true;
|
||||
} else {
|
||||
@@ -136,12 +138,14 @@ namespace OpenWifi {
|
||||
fmt::format("TELEMETRY-WS-PING({}): received. PONG sent back.", CId_));
|
||||
WS_->sendFrame("", 0,
|
||||
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
|
||||
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
||||
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
||||
} else if (Op == Poco::Net::WebSocket::FRAME_OP_CLOSE) {
|
||||
poco_information(
|
||||
Logger(),
|
||||
poco_information(Logger(),
|
||||
fmt::format("TELEMETRY-DISCONNECT({}): device wants to disconnect.", CId_));
|
||||
MustDisconnect = true;
|
||||
} else if (Op == Poco::Net::WebSocket::FRAME_OP_CONT) {
|
||||
poco_information(Logger(),
|
||||
fmt::format("TELEMETRY-CONT({}): rx {} bytes.", CId_, IncomingSize));
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
@@ -154,4 +158,4 @@ namespace OpenWifi {
|
||||
SendTelemetryShutdown();
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -276,7 +276,8 @@ static std::string DefaultAPSchema = R"foo(
|
||||
"sae-mixed",
|
||||
"wpa3",
|
||||
"wpa3-192",
|
||||
"wpa3-mixed"
|
||||
"wpa3-mixed",
|
||||
"mpsk-radius"
|
||||
],
|
||||
"examples": [
|
||||
"psk2"
|
||||
@@ -376,21 +377,18 @@ static std::string DefaultAPSchema = R"foo(
|
||||
"properties": {
|
||||
"port-mirror": {
|
||||
"description": "Enable mirror of traffic from multiple minotor ports to a single analysis port.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"monitor-ports": {
|
||||
"description": "The list of ports that we want to mirror.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"analysis-port": {
|
||||
"description": "The port that mirror'ed packets should be sent to.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"monitor-ports": {
|
||||
"description": "The list of ports that we want to mirror.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"analysis-port": {
|
||||
"description": "The port that mirror'ed packets should be sent to.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -552,7 +550,8 @@ static std::string DefaultAPSchema = R"foo(
|
||||
"5G",
|
||||
"5G-lower",
|
||||
"5G-upper",
|
||||
"6G"
|
||||
"6G",
|
||||
"HaLow"
|
||||
]
|
||||
},
|
||||
"bandwidth": {
|
||||
@@ -569,7 +568,7 @@ static std::string DefaultAPSchema = R"foo(
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"maximum": 196,
|
||||
"maximum": 233,
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
@@ -583,7 +582,7 @@ static std::string DefaultAPSchema = R"foo(
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"maximum": 196,
|
||||
"maximum": 233,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
@@ -625,6 +624,10 @@ static std::string DefaultAPSchema = R"foo(
|
||||
],
|
||||
"default": 80
|
||||
},
|
||||
"enable": {
|
||||
"description": "Specifies radio is enabled/disabled.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"require-mode": {
|
||||
"description": "Stations that do no fulfill these HT modes will be rejected.",
|
||||
"type": "string",
|
||||
@@ -2309,7 +2312,8 @@ static std::string DefaultAPSchema = R"foo(
|
||||
"5G",
|
||||
"5G-lower",
|
||||
"5G-upper",
|
||||
"6G"
|
||||
"6G",
|
||||
"HaLow"
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -2413,6 +2417,11 @@ static std::string DefaultAPSchema = R"foo(
|
||||
"encryption": {
|
||||
"$ref": "#/$defs/interface.ssid.encryption"
|
||||
},
|
||||
"enhanced-mpsk": {
|
||||
"description": "Optionally disable MPSK",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"multi-psk": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -3742,7 +3751,8 @@ static std::string DefaultAPSchema = R"foo(
|
||||
"5G",
|
||||
"5G-lower",
|
||||
"5G-upper",
|
||||
"6G"
|
||||
"6G",
|
||||
"HaLow"
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -3777,7 +3787,7 @@ static std::string DefaultAPSchema = R"foo(
|
||||
"enum": [
|
||||
"polled",
|
||||
"final",
|
||||
"raw-data"
|
||||
"raw"
|
||||
],
|
||||
"default": "final"
|
||||
},
|
||||
@@ -3952,8 +3962,10 @@ static std::string DefaultAPSchema = R"foo(
|
||||
"inactive-deauth",
|
||||
"key-mismatch",
|
||||
"beacon-report",
|
||||
"radar-detected"
|
||||
]
|
||||
"radar-detected",
|
||||
"ft-finish",
|
||||
"sta-authorized"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4441,7 +4453,8 @@ static std::string DefaultSWITCHSchema = R"foo(
|
||||
"sae-mixed",
|
||||
"wpa3",
|
||||
"wpa3-192",
|
||||
"wpa3-mixed"
|
||||
"wpa3-mixed",
|
||||
"mpsk-radius"
|
||||
],
|
||||
"examples": [
|
||||
"psk2"
|
||||
@@ -4656,21 +4669,18 @@ static std::string DefaultSWITCHSchema = R"foo(
|
||||
"properties": {
|
||||
"port-mirror": {
|
||||
"description": "Enable mirror of traffic from multiple minotor ports to a single analysis port.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"monitor-ports": {
|
||||
"description": "The list of ports that we want to mirror.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"analysis-port": {
|
||||
"description": "The port that mirror'ed packets should be sent to.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"monitor-ports": {
|
||||
"description": "The list of ports that we want to mirror.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"analysis-port": {
|
||||
"description": "The port that mirror'ed packets should be sent to.",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4890,7 +4900,8 @@ static std::string DefaultSWITCHSchema = R"foo(
|
||||
"5G",
|
||||
"5G-lower",
|
||||
"5G-upper",
|
||||
"6G"
|
||||
"6G",
|
||||
"HaLow"
|
||||
]
|
||||
},
|
||||
"bandwidth": {
|
||||
@@ -4905,7 +4916,7 @@ static std::string DefaultSWITCHSchema = R"foo(
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "integer",
|
||||
"maximum": 196,
|
||||
"maximum": 233,
|
||||
"minimum": 1
|
||||
},
|
||||
{
|
||||
@@ -4918,7 +4929,7 @@ static std::string DefaultSWITCHSchema = R"foo(
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"maximum": 196,
|
||||
"maximum": 233,
|
||||
"minimum": 1
|
||||
}
|
||||
},
|
||||
@@ -4956,6 +4967,10 @@ static std::string DefaultSWITCHSchema = R"foo(
|
||||
],
|
||||
"default": 80
|
||||
},
|
||||
"enable": {
|
||||
"description": "Specifies radio is enabled/disabled.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"require-mode": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@@ -6528,7 +6543,8 @@ static std::string DefaultSWITCHSchema = R"foo(
|
||||
"5G",
|
||||
"5G-lower",
|
||||
"5G-upper",
|
||||
"6G"
|
||||
"6G",
|
||||
"HaLow"
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -6618,6 +6634,11 @@ static std::string DefaultSWITCHSchema = R"foo(
|
||||
"encryption": {
|
||||
"$ref": "#/$defs/interface.ssid.encryption"
|
||||
},
|
||||
"enhanced-mpsk": {
|
||||
"description": "Optionally disable MPSK",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"multi-psk": {
|
||||
"anyOf": [
|
||||
{
|
||||
@@ -7751,7 +7772,8 @@ static std::string DefaultSWITCHSchema = R"foo(
|
||||
"5G",
|
||||
"5G-lower",
|
||||
"5G-upper",
|
||||
"6G"
|
||||
"6G",
|
||||
"HaLow"
|
||||
]
|
||||
}
|
||||
},
|
||||
@@ -7920,7 +7942,9 @@ static std::string DefaultSWITCHSchema = R"foo(
|
||||
"inactive-deauth",
|
||||
"key-mismatch",
|
||||
"beacon-report",
|
||||
"radar-detected"
|
||||
"radar-detected",
|
||||
"ft-finish",
|
||||
"sta-authorized"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -845,4 +845,4 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <vector>
|
||||
#include <optional>
|
||||
|
||||
// This must be defined for poco_debug and poco_trace macros to function.
|
||||
|
||||
@@ -40,6 +41,7 @@ namespace OpenWifi {
|
||||
#include "Poco/Util/OptionSet.h"
|
||||
#include "Poco/Util/PropertyFileConfiguration.h"
|
||||
#include "Poco/Util/ServerApplication.h"
|
||||
#include "Poco/ThreadPool.h"
|
||||
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <optional>
|
||||
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ namespace OpenWifi {
|
||||
P.verificationDepth = 9;
|
||||
P.loadDefaultCAs = root_ca_.empty();
|
||||
P.cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
|
||||
P.dhUse2048Bits = true;
|
||||
P.caLocation = cas_;
|
||||
// P.securityLevel =
|
||||
|
||||
@@ -344,4 +343,4 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -210,10 +210,16 @@ namespace OpenWifi {
|
||||
n = Client->second->WS_->receiveFrame(IncomingFrame, flags);
|
||||
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
||||
|
||||
if (n == -1) {
|
||||
poco_warning(Logger(),
|
||||
fmt::format("UI-EMPTY({}): {} Empty Frame flags {}.",
|
||||
Client->second->Id_, Client->second->UserName_, flags));
|
||||
return;
|
||||
}
|
||||
if (n == 0) {
|
||||
poco_debug(Logger(),
|
||||
fmt::format("CLOSE({}): {} UI Client is closing WS connection.",
|
||||
Client->second->Id_, Client->second->UserName_));
|
||||
fmt::format("CLOSE({}): {} UI Client is closing WS connection.",
|
||||
Client->second->Id_, Client->second->UserName_));
|
||||
return EndConnection(Client);
|
||||
}
|
||||
|
||||
@@ -221,7 +227,7 @@ namespace OpenWifi {
|
||||
case Poco::Net::WebSocket::FRAME_OP_PING: {
|
||||
Client->second->WS_->sendFrame("", 0,
|
||||
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
|
||||
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
||||
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
||||
} break;
|
||||
case Poco::Net::WebSocket::FRAME_OP_PONG: {
|
||||
} break;
|
||||
@@ -231,6 +237,11 @@ namespace OpenWifi {
|
||||
Client->second->Id_, Client->second->UserName_));
|
||||
return EndConnection(Client);
|
||||
} break;
|
||||
case Poco::Net::WebSocket::FRAME_OP_CONT: {
|
||||
poco_warning(Logger(),
|
||||
fmt::format("CONT({}): {} Unexpected CONT Frame - Ignoring.",
|
||||
Client->second->Id_, Client->second->UserName_));
|
||||
} break;
|
||||
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
|
||||
constexpr const char *DropMessagesCommand = "drop-notifications";
|
||||
IncomingFrame.append(0);
|
||||
@@ -319,4 +330,4 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -433,6 +433,10 @@ namespace OpenWifi::RESTAPI::Errors {
|
||||
|
||||
static const struct msg InvalidRRMAction { 1192, "Invalid RRM Action." };
|
||||
|
||||
static const struct msg InvalidPackageURL { 1193, "Invalid URL, must start with http:// or https://." };
|
||||
static const struct msg FailedToDownload { 1194, "Failed to download package." };
|
||||
static const struct msg FailedToDecompress { 1195, "Failed to decompress package data."};
|
||||
|
||||
static const struct msg SimulationDoesNotExist {
|
||||
7000, "Simulation Instance ID does not exist."
|
||||
};
|
||||
@@ -550,6 +554,10 @@ namespace OpenWifi::RESTAPI::Protocol {
|
||||
static const char *DEBUG = "debug";
|
||||
static const char *SCRIPT = "script";
|
||||
static const char *TIMEOUT = "timeout";
|
||||
static const char *PACKAGE = "package";
|
||||
static const char *PACKAGES = "packages";
|
||||
static const char *PACKAGEINST = "packageInstall";
|
||||
static const char *PACKAGEDEL = "packageDelete";
|
||||
|
||||
static const char *NEWPASSWORD = "newPassword";
|
||||
static const char *USERS = "users";
|
||||
@@ -583,6 +591,7 @@ namespace OpenWifi::RESTAPI::Protocol {
|
||||
|
||||
static const char *FIXEDCONFIG = "fixedconfig";
|
||||
static const char *CABLEDIAGNOSTICS = "cable-diagnostics";
|
||||
static const char *REENROLL = "reenroll";
|
||||
} // namespace OpenWifi::RESTAPI::Protocol
|
||||
|
||||
namespace OpenWifi::uCentralProtocol {
|
||||
@@ -668,6 +677,9 @@ namespace OpenWifi::uCentralProtocol {
|
||||
static const char *SIGNATURE = "signature";
|
||||
static const char *INFO = "info";
|
||||
static const char *DATE = "date";
|
||||
static const char *PACKAGE = "package";
|
||||
static const char *PACKAGES = "packages";
|
||||
static const char *CATEGORY = "category";
|
||||
|
||||
static const char *SERIALNUMBER = "serialNumber";
|
||||
static const char *COMPATIBLE = "compatible";
|
||||
@@ -698,7 +710,9 @@ namespace OpenWifi::uCentralProtocol {
|
||||
|
||||
static const char *FIXEDCONFIG = "fixedconfig";
|
||||
static const char *CABLEDIAGNOSTICS = "cable-diagnostics";
|
||||
static const char *REENROLL = "reenroll";
|
||||
|
||||
static const char *OPERATION = "op";
|
||||
} // namespace OpenWifi::uCentralProtocol
|
||||
|
||||
namespace OpenWifi::uCentralProtocol::Events {
|
||||
@@ -733,7 +747,7 @@ namespace OpenWifi::uCentralProtocol::Events {
|
||||
ET_EVENT,
|
||||
ET_WIFISCAN,
|
||||
ET_ALARM,
|
||||
ET_REBOOTLOG
|
||||
ET_REBOOTLOG,
|
||||
};
|
||||
|
||||
inline EVENT_MSG EventFromString(const std::string &Method) {
|
||||
@@ -797,6 +811,8 @@ namespace OpenWifi::APCommands {
|
||||
powercycle,
|
||||
fixedconfig,
|
||||
cablediagnostics,
|
||||
reenroll,
|
||||
package,
|
||||
unknown
|
||||
};
|
||||
|
||||
@@ -812,7 +828,8 @@ namespace OpenWifi::APCommands {
|
||||
RESTAPI::Protocol::PING, RESTAPI::Protocol::SCRIPT,
|
||||
RESTAPI::Protocol::RRM, RESTAPI::Protocol::CERTUPDATE,
|
||||
RESTAPI::Protocol::TRANSFER, RESTAPI::Protocol::POWERCYCLE,
|
||||
RESTAPI::Protocol::FIXEDCONFIG, RESTAPI::Protocol::CABLEDIAGNOSTICS
|
||||
RESTAPI::Protocol::FIXEDCONFIG, RESTAPI::Protocol::CABLEDIAGNOSTICS,
|
||||
RESTAPI::Protocol::REENROLL, RESTAPI::Protocol::PACKAGE
|
||||
};
|
||||
|
||||
inline const char *to_string(Commands Cmd) { return uCentralAPCommands[(uint8_t)Cmd]; }
|
||||
|
||||
@@ -888,78 +888,15 @@ namespace OpenWifi::Utils {
|
||||
return password;
|
||||
}
|
||||
|
||||
// Function to query NAPTR records for a domain and return them in a vector
|
||||
std::vector<NAPTRRecord> getNAPTRRecords(const std::string& domain) {
|
||||
std::vector<NAPTRRecord> naptrRecords;
|
||||
|
||||
unsigned char buf[4096];
|
||||
ns_msg handle;
|
||||
ns_initparse(buf, NS_PACKETSZ, &handle);
|
||||
|
||||
// Query NAPTR records for the given domain
|
||||
int response = res_query(domain.c_str(), ns_c_in, ns_t_naptr, buf, sizeof(buf));
|
||||
if (response < 0) {
|
||||
return naptrRecords;
|
||||
}
|
||||
|
||||
if(ns_initparse(buf, response, &handle) < 0) {
|
||||
return naptrRecords;
|
||||
}
|
||||
|
||||
// Iterate through the DNS response and extract NAPTR records
|
||||
int count = ns_msg_count(handle, ns_s_an);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
ns_rr rr;
|
||||
if (ns_parserr(&handle, ns_s_an, i, &rr) == 0) {
|
||||
char rdata[256];
|
||||
ns_sprintrr(&handle, &rr, nullptr, nullptr, rdata, sizeof(rdata));
|
||||
NAPTRRecord record;
|
||||
std::istringstream os(rdata);
|
||||
os >> record.name >> record.ttl >> record.rclass >> record.rtype >> record.order >> record.preference >> record.flags
|
||||
>> record.service >> record.regexp >> record.replacement;
|
||||
naptrRecords.push_back(record);
|
||||
}
|
||||
}
|
||||
|
||||
return naptrRecords;
|
||||
}
|
||||
/*
|
||||
Note that these 2 functions aren't used. They have been removed due to this deprecation warning:
|
||||
// Function to query NAPTR records for a domain and return them in a vector
|
||||
#47 3.825 /owgw/src/framework/utils.cpp: In function 'std::vector<OpenWifi::Utils::NAPTRRecord> OpenWifi::Utils::getNAPTRRecords(const std::string&)':
|
||||
#47 3.825 /owgw/src/framework/utils.cpp:915:28: warning: 'int ns_sprintrr(const ns_msg*, const ns_rr*, const char*, const char*, char*, size_t)' is deprecated [-Wdeprecated-declarations]
|
||||
|
||||
std::vector<SrvRecord> getSRVRecords(const std::string& domain) {
|
||||
std::vector<SrvRecord> srvRecords;
|
||||
|
||||
// Buffer to hold the DNS response
|
||||
unsigned char buf[4096];
|
||||
ns_msg handle;
|
||||
ns_initparse(buf, NS_PACKETSZ, &handle);
|
||||
|
||||
// Query NAPTR records for the given domain
|
||||
int response = res_query(domain.c_str(), ns_c_in, ns_t_srv, buf, sizeof(buf));
|
||||
if (response < 0) {
|
||||
std::cerr << "DNS query failed for " << domain << ": " << hstrerror(h_errno) << std::endl;
|
||||
return srvRecords;
|
||||
}
|
||||
|
||||
if(ns_initparse(buf, response, &handle) < 0) {
|
||||
return srvRecords;
|
||||
}
|
||||
|
||||
// Iterate through the DNS response and extract NAPTR records
|
||||
int count = ns_msg_count(handle, ns_s_an);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
ns_rr rr;
|
||||
if (ns_parserr(&handle, ns_s_an, i, &rr) == 0) {
|
||||
char rdata[256];
|
||||
ns_sprintrr(&handle, &rr, nullptr, nullptr, rdata, sizeof(rdata));
|
||||
SrvRecord record;
|
||||
std::istringstream os(rdata);
|
||||
os >> record.name >> record.ttl >> record.rclass >> record.rtype >> record.pref >> record.weight >>
|
||||
record.port >> record.srvname ;
|
||||
srvRecords.push_back(record);
|
||||
}
|
||||
}
|
||||
|
||||
return srvRecords;
|
||||
}
|
||||
|
||||
#47 3.833 /owgw/src/framework/utils.cpp: In function 'std::vector<OpenWifi::Utils::SrvRecord> OpenWifi::Utils::getSRVRecords(const std::string&)':
|
||||
#47 3.833 /owgw/src/framework/utils.cpp:952:28: warning: 'int ns_sprintrr(const ns_msg*, const ns_rr*, const char*, const char*, char*, size_t)' is deprecated [-Wdeprecated-declarations]
|
||||
*/
|
||||
|
||||
} // namespace OpenWifi::Utils
|
||||
|
||||
@@ -298,8 +298,10 @@ namespace OpenWifi::Utils {
|
||||
std::string replacement;
|
||||
};
|
||||
|
||||
// Function to query NAPTR records for a domain and return them in a vector
|
||||
std::vector<NAPTRRecord> getNAPTRRecords(const std::string& domain);
|
||||
// removed due to deprecation: see utils.cpp
|
||||
// Function to query NAPTR records for a domain and return them in a vector
|
||||
//std::vector<NAPTRRecord> getNAPTRRecords(const std::string& domain);
|
||||
|
||||
struct SrvRecord {
|
||||
std::string name;
|
||||
std::string ttl;
|
||||
@@ -311,7 +313,8 @@ namespace OpenWifi::Utils {
|
||||
std::string srvname;
|
||||
};
|
||||
|
||||
std::vector<SrvRecord> getSRVRecords(const std::string& domain);
|
||||
// removed due to deprecation: see utils.cpp
|
||||
// std::vector<SrvRecord> getSRVRecords(const std::string& domain);
|
||||
|
||||
struct HostNameServerResult{
|
||||
std::string Hostname;
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
#include "Poco/NObserver.h"
|
||||
#include <Poco/Net/Context.h>
|
||||
#include "Poco/Net/SocketNotification.h"
|
||||
#include "Poco/Net/NetException.h"
|
||||
#include "Poco/Net/WebSocketImpl.h"
|
||||
@@ -71,6 +72,7 @@ namespace OpenWifi {
|
||||
const auto &RootCas =
|
||||
MicroServiceConfigPath("ucentral.websocket.host.0.rootca", "");
|
||||
const auto &Cas = MicroServiceConfigPath("ucentral.websocket.host.0.cas", "");
|
||||
const auto &ClientCasFile = MicroServiceConfigPath("ucentral.websocket.host.0.clientcas", "");
|
||||
|
||||
Poco::Net::Context::Params P;
|
||||
|
||||
@@ -86,6 +88,7 @@ namespace OpenWifi {
|
||||
Poco::Crypto::X509Certificate Cert(CertFileName);
|
||||
Poco::Crypto::X509Certificate Root(RootCaFileName);
|
||||
Poco::Crypto::X509Certificate Issuing(IssuerFileName);
|
||||
std::vector<Poco::Crypto::X509Certificate> ClientCasCerts;
|
||||
Poco::Crypto::RSAKey Key("", KeyFileName, KeyPassword);
|
||||
|
||||
DeviceSecureContext->useCertificate(Cert);
|
||||
@@ -93,7 +96,11 @@ namespace OpenWifi {
|
||||
DeviceSecureContext->addCertificateAuthority(Root);
|
||||
DeviceSecureContext->addChainCertificate(Issuing);
|
||||
DeviceSecureContext->addCertificateAuthority(Issuing);
|
||||
DeviceSecureContext->addCertificateAuthority(Root);
|
||||
ClientCasCerts = Poco::Net::X509Certificate::readPEM(ClientCasFile);
|
||||
for (const auto &cert : ClientCasCerts) {
|
||||
DeviceSecureContext->addChainCertificate(cert);
|
||||
DeviceSecureContext->addCertificateAuthority(cert);
|
||||
}
|
||||
DeviceSecureContext->enableSessionCache(true);
|
||||
DeviceSecureContext->setSessionCacheSize(0);
|
||||
DeviceSecureContext->setSessionTimeout(120);
|
||||
@@ -573,14 +580,16 @@ namespace OpenWifi {
|
||||
try {
|
||||
Client = Clients_.find(pNf->socket().impl()->sockfd());
|
||||
if (Client == end(Clients_)) {
|
||||
poco_warning(Logger(), fmt::format("Cannot find client socket: {}",
|
||||
pNf->socket().impl()->sockfd()));
|
||||
poco_warning(Logger(),
|
||||
fmt::format("Cannot find client socket: {}",
|
||||
pNf->socket().impl()->sockfd()));
|
||||
return;
|
||||
}
|
||||
Connection = Client->second;
|
||||
if(Connection->WSSocket_==nullptr || Connection->WSSocket_->impl()==nullptr) {
|
||||
poco_warning(Logger(), fmt::format("WebSocket is no valid: {}",
|
||||
Connection->SerialNumber_));
|
||||
poco_warning(Logger(),
|
||||
fmt::format("WebSocket is not valid: {}",
|
||||
Connection->SerialNumber_));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -589,15 +598,25 @@ namespace OpenWifi {
|
||||
|
||||
auto ReceivedBytes = Connection->WSSocket_->receiveFrame(FrameBuffer, sizeof(FrameBuffer), flags);
|
||||
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
||||
|
||||
if (ReceivedBytes == -1) {
|
||||
poco_trace(Logger(),
|
||||
fmt::format("WS-EMPTY{}: Non-blocking try-again empty Frame: flags {}",
|
||||
Connection->SerialNumber_, flags));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (Op) {
|
||||
|
||||
case Poco::Net::WebSocket::FRAME_OP_PING: {
|
||||
Connection->WSSocket_->sendFrame("", 0,
|
||||
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
|
||||
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
||||
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
|
||||
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
||||
} break;
|
||||
|
||||
case Poco::Net::WebSocket::FRAME_OP_PONG: {
|
||||
} break;
|
||||
|
||||
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
|
||||
if (ReceivedBytes == 0) {
|
||||
EndConnection(Connection,__func__,__LINE__);
|
||||
@@ -624,19 +643,29 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case Poco::Net::WebSocket::FRAME_OP_BINARY: {
|
||||
if (ReceivedBytes == 0) {
|
||||
EndConnection(Connection,__func__,__LINE__);
|
||||
return;
|
||||
} else {
|
||||
poco_trace(Logger(),
|
||||
fmt::format("Sending {} key strokes to device.", ReceivedBytes));
|
||||
fmt::format("Sending {} key strokes to device.", ReceivedBytes));
|
||||
if (!RTTYS_server().KeyStrokes(Connection, FrameBuffer, ReceivedBytes)) {
|
||||
EndConnection(Connection,__func__,__LINE__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
case Poco::Net::WebSocket::FRAME_OP_CONT: {
|
||||
// may have to handle this, but not sure whether it's a continuation for text or
|
||||
// binary, seems to be a hole in the protocol.
|
||||
poco_warning(Logger(),
|
||||
fmt::format("CONT Frame {} received, ignoring for now.",
|
||||
ReceivedBytes));
|
||||
}
|
||||
|
||||
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
|
||||
EndConnection(Connection,__func__,__LINE__);
|
||||
return;
|
||||
@@ -682,8 +711,8 @@ namespace OpenWifi {
|
||||
if (Connection->WSSocket_ != nullptr && Connection->WSSocket_->impl()!= nullptr) {
|
||||
try {
|
||||
Connection->WSSocket_->sendFrame(Buf, len,
|
||||
Poco::Net::WebSocket::FRAME_FLAG_FIN |
|
||||
Poco::Net::WebSocket::FRAME_OP_BINARY);
|
||||
(int) Poco::Net::WebSocket::FRAME_FLAG_FIN |
|
||||
(int) Poco::Net::WebSocket::FRAME_OP_BINARY);
|
||||
return;
|
||||
} catch (...) {
|
||||
poco_error(Logger(), "SendData shutdown.");
|
||||
@@ -985,8 +1014,9 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
bool RTTYS_server::SendToClient(Poco::Net::WebSocket &WebSocket, const u_char *Buf, int len) {
|
||||
WebSocket.sendFrame(
|
||||
Buf, len, Poco::Net::WebSocket::FRAME_FLAG_FIN | Poco::Net::WebSocket::FRAME_OP_BINARY);
|
||||
WebSocket.sendFrame(Buf, len,
|
||||
(int) Poco::Net::WebSocket::FRAME_FLAG_FIN |
|
||||
(int) Poco::Net::WebSocket::FRAME_OP_BINARY);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1117,4 +1147,4 @@ namespace OpenWifi {
|
||||
RTTYS_EndPoint::~RTTYS_EndPoint() {
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -664,12 +664,14 @@ namespace OpenWifi {
|
||||
Insert.execute();
|
||||
Sess.commit();
|
||||
} else {
|
||||
poco_warning(Logger(), fmt::format("File {} is too large.", UUID));
|
||||
poco_warning(Logger(),
|
||||
fmt::format("File {} is too large ({} >= {} max bytes).",
|
||||
UUID, Size, FileUploader()->MaxSize()));
|
||||
}
|
||||
|
||||
// update CommandList here to ensure that file us uploaded
|
||||
Sess.begin();
|
||||
Poco::Data::Statement Statement(Sess);
|
||||
Sess.begin();
|
||||
Poco::Data::Statement Statement(Sess);
|
||||
std::string StatementStr;
|
||||
StatementStr =
|
||||
"UPDATE CommandList SET WaitingForFile=?, AttachDate=?, AttachSize=? WHERE UUID=?";
|
||||
|
||||
@@ -202,15 +202,14 @@ namespace OpenWifi {
|
||||
|
||||
std::string st;
|
||||
std::string whereClause = "";
|
||||
if(!platform.empty()) {
|
||||
if (!platform.empty()) {
|
||||
if (includeProvisioned == false) {
|
||||
|
||||
whereClause = fmt::format("WHERE entity='' and venue='' and DeviceType='" + platform + "'");
|
||||
//whereClause = fmt::format("WHERE entity='' and venue='' and DeviceType='" + platform + "'");
|
||||
whereClause = fmt::format("WHERE entity='' and venue='' and DeviceType='{}'", platform);
|
||||
} else {
|
||||
whereClause = fmt::format("WHERE DeviceType='" + platform + "'");
|
||||
//whereClause = fmt::format("WHERE DeviceType='" + platform + "'");
|
||||
whereClause = fmt::format("WHERE DeviceType='{}'", platform);
|
||||
}
|
||||
|
||||
|
||||
//st = "SELECT SerialNumber From Devices WHERE DeviceType='" + platform + "' ";
|
||||
} else {
|
||||
if (includeProvisioned == false) {
|
||||
@@ -218,7 +217,7 @@ namespace OpenWifi {
|
||||
}
|
||||
//st = "SELECT SerialNumber From Devices ";
|
||||
}
|
||||
|
||||
|
||||
st = fmt::format("SELECT SerialNumber From Devices {}", whereClause);
|
||||
|
||||
if (orderBy.empty())
|
||||
@@ -896,9 +895,9 @@ namespace OpenWifi {
|
||||
if (includeProvisioned == false) {
|
||||
whereClause = fmt::format("WHERE DeviceType='{}' and entity='' and venue=''",platform);
|
||||
} else {
|
||||
whereClause = fmt::format("WHERE DeviceType='{}'", platform);
|
||||
whereClause = fmt::format("WHERE DeviceType='{}'", platform);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
st =
|
||||
@@ -907,7 +906,7 @@ namespace OpenWifi {
|
||||
ComputeRange(From, HowMany));
|
||||
|
||||
//Logger().information(fmt::format(" GetDevices st is {} ", st));
|
||||
|
||||
|
||||
Select << ConvertParams(st), Poco::Data::Keywords::into(Records);
|
||||
Select.execute();
|
||||
|
||||
|
||||
@@ -49,8 +49,7 @@ namespace OpenWifi {
|
||||
"Data TEXT, "
|
||||
"Recorded BIGINT, "
|
||||
"INDEX StatSerial0 (SerialNumber)), ",
|
||||
"INDEX StatSerial (SerialNumber ASC, Recorded ASC))",
|
||||
Poco::Data::Keywords::now;
|
||||
"INDEX StatSerial (SerialNumber ASC, Recorded ASC))", Poco::Data::Keywords::now;
|
||||
}
|
||||
return 0;
|
||||
} catch (const Poco::Exception &E) {
|
||||
@@ -154,8 +153,7 @@ namespace OpenWifi {
|
||||
"alter table devices add column lastRecordedContact bigint",
|
||||
"alter table devices add column simulated boolean",
|
||||
"alter table devices add column certificateExpiryDate bigint",
|
||||
"alter table devices add column connectReason TEXT"
|
||||
};
|
||||
"alter table devices add column connectReason TEXT"};
|
||||
|
||||
for (const auto &i : Script) {
|
||||
try {
|
||||
@@ -279,9 +277,7 @@ namespace OpenWifi {
|
||||
Poco::Data::Keywords::now;
|
||||
}
|
||||
|
||||
std::vector<std::string> Script{
|
||||
"alter table DefaultConfigs add column Platform text"
|
||||
};
|
||||
std::vector<std::string> Script{"alter table DefaultConfigs add column Platform text"};
|
||||
|
||||
for (const auto &i : Script) {
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user