mirror of
				https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
				synced 2025-11-04 04:37:46 +00:00 
			
		
		
		
	Compare commits
	
		
			67 Commits
		
	
	
		
			dev-micros
			...
			v2.0.0-RC1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					6ab5ccd904 | ||
| 
						 | 
					840481f0d0 | ||
| 
						 | 
					f7e450a66e | ||
| 
						 | 
					2d8f925115 | ||
| 
						 | 
					3988f6c38c | ||
| 
						 | 
					4d1ebd398a | ||
| 
						 | 
					2790fb0de1 | ||
| 
						 | 
					02c40835f5 | ||
| 
						 | 
					4c75a2cd71 | ||
| 
						 | 
					d0df73fa86 | ||
| 
						 | 
					660570df44 | ||
| 
						 | 
					5f8f4137b0 | ||
| 
						 | 
					de164d30dd | ||
| 
						 | 
					a69c51afd3 | ||
| 
						 | 
					161ddd281e | ||
| 
						 | 
					5e36935f3b | ||
| 
						 | 
					91dd93fcd5 | ||
| 
						 | 
					12152a6a6e | ||
| 
						 | 
					326b33ce63 | ||
| 
						 | 
					9effac0c6e | ||
| 
						 | 
					4bc8788df2 | ||
| 
						 | 
					e8cfcbb507 | ||
| 
						 | 
					44f427fcc7 | ||
| 
						 | 
					487e043e4f | ||
| 
						 | 
					6d294e6add | ||
| 
						 | 
					d39fe0b07c | ||
| 
						 | 
					64719877f3 | ||
| 
						 | 
					127e455fe5 | ||
| 
						 | 
					e7b625d058 | ||
| 
						 | 
					fdccb31482 | ||
| 
						 | 
					fc1daade6e | ||
| 
						 | 
					99e937614b | ||
| 
						 | 
					f341598056 | ||
| 
						 | 
					0f6ec15fa2 | ||
| 
						 | 
					34a04b406c | ||
| 
						 | 
					a2ae90a7cb | ||
| 
						 | 
					52e252576a | ||
| 
						 | 
					9345c4892d | ||
| 
						 | 
					89c325190a | ||
| 
						 | 
					add35585e0 | ||
| 
						 | 
					b8fe3e41fa | ||
| 
						 | 
					bb4effa518 | ||
| 
						 | 
					997f2c4787 | ||
| 
						 | 
					56f0a3f46a | ||
| 
						 | 
					ff911cb478 | ||
| 
						 | 
					f31aa8711e | ||
| 
						 | 
					523bbbcb84 | ||
| 
						 | 
					0010a5fc02 | ||
| 
						 | 
					8a440cfcd8 | ||
| 
						 | 
					3ebd5426f4 | ||
| 
						 | 
					46b3cad88b | ||
| 
						 | 
					e756a7c1cd | ||
| 
						 | 
					8e216417f7 | ||
| 
						 | 
					3a7a386a87 | ||
| 
						 | 
					ebc6af17b3 | ||
| 
						 | 
					c3d17499b1 | ||
| 
						 | 
					01473a337b | ||
| 
						 | 
					4e9dfe53d5 | ||
| 
						 | 
					39a6daecf5 | ||
| 
						 | 
					897dc735d1 | ||
| 
						 | 
					8c406c57e0 | ||
| 
						 | 
					923386a06f | ||
| 
						 | 
					ca52d187ca | ||
| 
						 | 
					925285b7db | ||
| 
						 | 
					f8fd154dd8 | ||
| 
						 | 
					8b0586b122 | ||
| 
						 | 
					4d119fabd5 | 
							
								
								
									
										106
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										106
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							@@ -7,11 +7,12 @@ on:
 | 
				
			|||||||
      - '**.md'
 | 
					      - '**.md'
 | 
				
			||||||
    branches:
 | 
					    branches:
 | 
				
			||||||
      - master
 | 
					      - master
 | 
				
			||||||
      - dev-microservice
 | 
					      - 'release/*'
 | 
				
			||||||
 | 
					    tags:
 | 
				
			||||||
 | 
					      - 'v*'
 | 
				
			||||||
  pull_request:
 | 
					  pull_request:
 | 
				
			||||||
    branches:
 | 
					    branches:
 | 
				
			||||||
      - master
 | 
					      - master
 | 
				
			||||||
      - dev-microservice
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
defaults:
 | 
					defaults:
 | 
				
			||||||
  run:
 | 
					  run:
 | 
				
			||||||
@@ -26,87 +27,102 @@ jobs:
 | 
				
			|||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
    - uses: actions/checkout@v2
 | 
					    - uses: actions/checkout@v2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    - name: build Docker image
 | 
					    - name: Build Docker image
 | 
				
			||||||
      run: docker build -t wlan-cloud-ucentralgw:${{ github.sha }} .
 | 
					      run: docker build -t wlan-cloud-ucentralgw:${{ github.sha }} .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    - name: log into Docker registry
 | 
					    - name: Tag Docker image
 | 
				
			||||||
 | 
					      run: |
 | 
				
			||||||
 | 
					        TAGS="${{ github.sha }}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if [[ ${GITHUB_REF} == "refs/heads/"* ]]
 | 
				
			||||||
 | 
					        then
 | 
				
			||||||
 | 
					          CURRENT_TAG=$(echo ${GITHUB_REF#refs/heads/} | tr '/' '-')
 | 
				
			||||||
 | 
					          TAGS="$TAGS $CURRENT_TAG"
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					          if [[ ${GITHUB_REF} == "refs/tags/"* ]]
 | 
				
			||||||
 | 
					          then
 | 
				
			||||||
 | 
					            CURRENT_TAG=$(echo ${GITHUB_REF#refs/tags/} | tr '/' '-')
 | 
				
			||||||
 | 
					            TAGS="$TAGS $CURRENT_TAG"
 | 
				
			||||||
 | 
					          else # PR build
 | 
				
			||||||
 | 
					            CURRENT_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
 | 
				
			||||||
 | 
					            TAGS="$TAGS $CURRENT_TAG"
 | 
				
			||||||
 | 
					          fi
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        echo "Result tags: $TAGS"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for tag in $TAGS; do
 | 
				
			||||||
 | 
					          docker tag wlan-cloud-ucentralgw:${{ github.sha }} ${{ env.DOCKER_REGISTRY_URL }}/ucentralgw:$tag
 | 
				
			||||||
 | 
					        done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - name: Log into Docker registry
 | 
				
			||||||
 | 
					      if: startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/pull/') || github.ref == 'refs/heads/master'
 | 
				
			||||||
      uses: docker/login-action@v1
 | 
					      uses: docker/login-action@v1
 | 
				
			||||||
      with:
 | 
					      with:
 | 
				
			||||||
        registry: ${{ env.DOCKER_REGISTRY_URL }}
 | 
					        registry: ${{ env.DOCKER_REGISTRY_URL }}
 | 
				
			||||||
        username: ${{ env.DOCKER_REGISTRY_USERNAME }}
 | 
					        username: ${{ env.DOCKER_REGISTRY_USERNAME }}
 | 
				
			||||||
        password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
 | 
					        password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    - name: push Docker image
 | 
					    - name: Push Docker images
 | 
				
			||||||
 | 
					      if: startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/pull/') || github.ref == 'refs/heads/master'
 | 
				
			||||||
      run: |
 | 
					      run: |
 | 
				
			||||||
        TAGS="${{ github.sha }}"
 | 
					        docker images | grep ${{ env.DOCKER_REGISTRY_URL }}/ucentralgw | awk -F ' ' '{print $1":"$2}' | xargs -I {} docker push {}
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if [ ${GITHUB_REF} == "refs/heads/master" ]
 | 
					 | 
				
			||||||
        then
 | 
					 | 
				
			||||||
          TAGS="$TAGS ${GITHUB_REF#refs/heads/}"
 | 
					 | 
				
			||||||
        else # PR build
 | 
					 | 
				
			||||||
          CURRENT_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
 | 
					 | 
				
			||||||
          TAGS="$TAGS $CURRENT_TAG"
 | 
					 | 
				
			||||||
        fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        echo "Pushing tags $TAGS"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for tag in $TAGS; do
 | 
					 | 
				
			||||||
          docker tag wlan-cloud-ucentralgw:${{ github.sha }} ${{ env.DOCKER_REGISTRY_URL }}/ucentralgw:$tag
 | 
					 | 
				
			||||||
          docker push ${{ env.DOCKER_REGISTRY_URL }}/ucentralgw:$tag
 | 
					 | 
				
			||||||
        done
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  docker-compose:
 | 
					  docker-compose:
 | 
				
			||||||
 | 
					    if: startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/pull/') || github.ref == 'refs/heads/master'
 | 
				
			||||||
    runs-on: ubuntu-20.04
 | 
					    runs-on: ubuntu-20.04
 | 
				
			||||||
    needs: docker
 | 
					    needs: docker
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
    - name: Check out repository
 | 
					    - name: Check out wlan-cloud-ucentral-deploy repository
 | 
				
			||||||
      uses: actions/checkout@v2
 | 
					      uses: actions/checkout@v2
 | 
				
			||||||
 | 
					      with:
 | 
				
			||||||
    - name: Create certificate and key files from Github secrets
 | 
					        repository: Telecominfraproject/wlan-cloud-ucentral-deploy
 | 
				
			||||||
      env:
 | 
					        path: wlan-cloud-ucentral-deploy
 | 
				
			||||||
        DIGICERT_TIP_WILDCARD_CERT: ${{ secrets.DIGICERT_TIP_WILDCARD_CERT }}
 | 
					 | 
				
			||||||
        DIGICERT_TIP_WILDCARD_KEY: ${{ secrets.DIGICERT_TIP_WILDCARD_KEY }}
 | 
					 | 
				
			||||||
      run: |
 | 
					 | 
				
			||||||
        cat certificates/issuer.pem certificates/root.pem > docker-compose/ucentral-data/certs/restapi-ca.pem
 | 
					 | 
				
			||||||
        echo "$DIGICERT_TIP_WILDCARD_CERT" > docker-compose/ucentral-data/certs/websocket-cert.pem
 | 
					 | 
				
			||||||
        echo "$DIGICERT_TIP_WILDCARD_CERT" > docker-compose/ucentral-data/certs/restapi-cert.pem
 | 
					 | 
				
			||||||
        echo "$DIGICERT_TIP_WILDCARD_KEY" > docker-compose/ucentral-data/certs/websocket-key.pem
 | 
					 | 
				
			||||||
        echo "$DIGICERT_TIP_WILDCARD_KEY" > docker-compose/ucentral-data/certs/restapi-key.pem
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    - name: Instantiate Docker Compose deployment
 | 
					    - name: Instantiate Docker Compose deployment
 | 
				
			||||||
      working-directory: ./docker-compose
 | 
					      working-directory: ./wlan-cloud-ucentral-deploy/docker-compose
 | 
				
			||||||
      env:
 | 
					      env:
 | 
				
			||||||
        UCENTRALGW_TAG: ${{ github.sha }}
 | 
					        UCENTRALGW_TAG: ${{ github.sha }}
 | 
				
			||||||
      run: |
 | 
					      run: |
 | 
				
			||||||
        docker-compose up -d
 | 
					        docker-compose up -d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    - name: Wait for uCentralGW to be alive and kicking
 | 
					    - name: Wait for uCentralSec to be alive and kicking
 | 
				
			||||||
      run: |
 | 
					      run: |
 | 
				
			||||||
        n=0
 | 
					        n=0
 | 
				
			||||||
        until [ "$n" -ge 3 ]
 | 
					        until [ "$n" -ge 3 ]
 | 
				
			||||||
        do
 | 
					        do
 | 
				
			||||||
          curl -s 127.0.0.1:15015 && break
 | 
					          curl -s 127.0.0.1:16102 && break
 | 
				
			||||||
          n=$((n+1)) 
 | 
					          n=$((n+1))
 | 
				
			||||||
          if [ "$n" -eq 3]; then        
 | 
					          if [ "$n" -eq 3]; then
 | 
				
			||||||
            exit 1
 | 
					            exit 1
 | 
				
			||||||
          else
 | 
					          else
 | 
				
			||||||
            sleep 3
 | 
					            sleep 3
 | 
				
			||||||
          fi
 | 
					          fi
 | 
				
			||||||
        done
 | 
					        done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    - name: Check functionality of uCentralGW
 | 
					    - name: Add self-signed certificates to system trust store of containers
 | 
				
			||||||
      env:
 | 
					      working-directory: ./wlan-cloud-ucentral-deploy/docker-compose
 | 
				
			||||||
        UCENTRALGW: "ucentral.cicd.lab.wlan.tip.build:16001"
 | 
					 | 
				
			||||||
        FLAGS: "-s --cacert docker-compose/ucentral-data/certs/restapi-ca.pem --resolve ucentral.cicd.lab.wlan.tip.build:16001:127.0.0.1"
 | 
					 | 
				
			||||||
      run: |
 | 
					      run: |
 | 
				
			||||||
        ./test_scripts/curl/cli listdevices
 | 
					        ./add-ca-cert.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - name: Check out wlan-cloud-ucentralgw repository
 | 
				
			||||||
 | 
					      uses: actions/checkout@v2
 | 
				
			||||||
 | 
					      with:
 | 
				
			||||||
 | 
					        path: wlan-cloud-ucentralgw
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - name: Check functionality of microservices
 | 
				
			||||||
 | 
					      env:
 | 
				
			||||||
 | 
					        UCENTRALSEC: "ucentral.wlan.local:16001"
 | 
				
			||||||
 | 
					        FLAGS: "-s --cacert ./wlan-cloud-ucentral-deploy/docker-compose/certs/restapi-ca.pem --resolve ucentral.wlan.local:16001:127.0.0.1"
 | 
				
			||||||
 | 
					      run: |
 | 
				
			||||||
 | 
					        ./wlan-cloud-ucentralgw/test_scripts/curl/cli listdevices
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    - name: Display information about running containers and log ucentralgw output
 | 
					    - name: Display information about running containers and log ucentralgw output
 | 
				
			||||||
      working-directory: ./docker-compose
 | 
					      working-directory: ./wlan-cloud-ucentral-deploy/docker-compose
 | 
				
			||||||
      if: always()
 | 
					      if: always()
 | 
				
			||||||
      run: |
 | 
					      run: |
 | 
				
			||||||
        docker-compose ps -a
 | 
					        docker-compose ps -a
 | 
				
			||||||
        docker-compose logs 
 | 
					        docker-compose logs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # disable until repo is public
 | 
					    # disable until repo is public
 | 
				
			||||||
    #- name: export Docker image
 | 
					    #- name: export Docker image
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								.github/workflows/cleanup.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflows/cleanup.yml
									
									
									
									
										vendored
									
									
								
							@@ -4,7 +4,6 @@ on:
 | 
				
			|||||||
  pull_request:
 | 
					  pull_request:
 | 
				
			||||||
    branches:
 | 
					    branches:
 | 
				
			||||||
      - master
 | 
					      - master
 | 
				
			||||||
      - dev-microservice
 | 
					 | 
				
			||||||
    types: [ closed ]
 | 
					    types: [ closed ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
defaults:
 | 
					defaults:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
cmake_minimum_required(VERSION 3.13)
 | 
					cmake_minimum_required(VERSION 3.13)
 | 
				
			||||||
project(ucentralgw VERSION 0.4.0)
 | 
					project(ucentralgw VERSION 2.0.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(CMAKE_CXX_STANDARD 17)
 | 
					set(CMAKE_CXX_STANDARD 17)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -45,8 +45,7 @@ else()
 | 
				
			|||||||
    find_package(CppKafka REQUIRED)
 | 
					    find_package(CppKafka REQUIRED)
 | 
				
			||||||
    find_package(PostgreSQL REQUIRED)
 | 
					    find_package(PostgreSQL REQUIRED)
 | 
				
			||||||
    find_package(MySQL REQUIRED)
 | 
					    find_package(MySQL REQUIRED)
 | 
				
			||||||
    find_package(ODBC REQUIRED)
 | 
					    find_package(Poco REQUIRED COMPONENTS JSON Crypto JWT Net Util NetSSL Data DataSQLite DataPostgreSQL DataMySQL)
 | 
				
			||||||
    find_package(Poco REQUIRED COMPONENTS JSON Crypto JWT Net Util NetSSL Data DataSQLite DataPostgreSQL DataMySQL DataODBC)
 | 
					 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
include_directories(/usr/local/include  /usr/local/opt/openssl/include src include/kafka /usr/local/opt/mysql-client/include)
 | 
					include_directories(/usr/local/include  /usr/local/opt/openssl/include src include/kafka /usr/local/opt/mysql-client/include)
 | 
				
			||||||
@@ -64,7 +63,7 @@ add_executable( ucentralgw
 | 
				
			|||||||
                src/RESTAPI_device_handler.cpp src/RESTAPI_device_handler.h
 | 
					                src/RESTAPI_device_handler.cpp src/RESTAPI_device_handler.h
 | 
				
			||||||
                src/RESTAPI_handler.cpp src/RESTAPI_handler.h
 | 
					                src/RESTAPI_handler.cpp src/RESTAPI_handler.h
 | 
				
			||||||
                src/RESTAPI_device_commandHandler.cpp src/RESTAPI_device_commandHandler.h
 | 
					                src/RESTAPI_device_commandHandler.cpp src/RESTAPI_device_commandHandler.h
 | 
				
			||||||
        src/RESTAPI_GWobjects.h src/RESTAPI_GWobjects.cpp
 | 
					                src/RESTAPI_GWobjects.h src/RESTAPI_GWobjects.cpp
 | 
				
			||||||
                src/CentralConfig.cpp src/CentralConfig.h
 | 
					                src/CentralConfig.cpp src/CentralConfig.h
 | 
				
			||||||
                src/RESTAPI_default_configuration.cpp
 | 
					                src/RESTAPI_default_configuration.cpp
 | 
				
			||||||
                src/RESTAPI_InternalServer.cpp src/RESTAPI_InternalServer.h
 | 
					                src/RESTAPI_InternalServer.cpp src/RESTAPI_InternalServer.h
 | 
				
			||||||
@@ -80,15 +79,15 @@ add_executable( ucentralgw
 | 
				
			|||||||
                src/Utils.h src/Utils.cpp src/storage_blacklist.cpp
 | 
					                src/Utils.h src/Utils.cpp src/storage_blacklist.cpp
 | 
				
			||||||
                src/storage_command.cpp src/storage_healthcheck.cpp src/storage_statistics.cpp src/storage_logs.cpp
 | 
					                src/storage_command.cpp src/storage_healthcheck.cpp src/storage_statistics.cpp src/storage_logs.cpp
 | 
				
			||||||
                src/storage_device.cpp src/storage_capabilities.cpp src/storage_defconfig.cpp src/storage_sqlite.cpp
 | 
					                src/storage_device.cpp src/storage_capabilities.cpp src/storage_defconfig.cpp src/storage_sqlite.cpp
 | 
				
			||||||
                src/storage_mysql.cpp src/storage_pgql.cpp src/storage_odbc.cpp src/storage_tables.cpp src/RESTAPI_callback.cpp
 | 
					                src/storage_mysql.cpp src/storage_pgql.cpp src/storage_tables.cpp
 | 
				
			||||||
                src/RESTAPI_callback.h src/CallbackManager.cpp src/CallbackManager.h
 | 
					 | 
				
			||||||
                src/StateProcessor.cpp src/StateProcessor.h
 | 
					                src/StateProcessor.cpp src/StateProcessor.h
 | 
				
			||||||
                src/storage_lifetime_stats.cpp src/uCentralProtocol.h src/RESTAPI_protocol.h
 | 
					                src/storage_lifetime_stats.cpp src/uCentralProtocol.h src/RESTAPI_protocol.h
 | 
				
			||||||
                src/ALBHealthCheckServer.h src/Kafka_topics.h src/uCentralTypes.h
 | 
					                src/ALBHealthCheckServer.h src/Kafka_topics.h src/uCentralTypes.h
 | 
				
			||||||
                src/OUIServer.cpp src/OUIServer.h
 | 
					                src/OUIServer.cpp src/OUIServer.h
 | 
				
			||||||
                src/RESTAPI_ouis.cpp src/RESTAPI_ouis.h
 | 
					                src/RESTAPI_ouis.cpp src/RESTAPI_ouis.h
 | 
				
			||||||
                src/MicroService.cpp src/MicroService.h
 | 
					                src/MicroService.cpp src/MicroService.h
 | 
				
			||||||
                src/RESTAPI_RPC.cpp src/RESTAPI_RPC.h src/AuthClient.cpp src/AuthClient.h src/OpenAPIRequest.cpp src/OpenAPIRequest.h src/RESTAPI_utils.h src/RESTAPI_utils.cpp src/StorageArchiver.cpp src/StorageArchiver.h)
 | 
					                src/RESTAPI_RPC.cpp src/RESTAPI_RPC.h src/AuthClient.cpp src/AuthClient.h src/OpenAPIRequest.cpp src/OpenAPIRequest.h
 | 
				
			||||||
 | 
					                src/RESTAPI_utils.h src/RESTAPI_utils.cpp src/StorageArchiver.cpp src/StorageArchiver.h src/Dashboard.cpp src/Dashboard.h src/RESTAPI_deviceDashboardHandler.cpp src/RESTAPI_deviceDashboardHandler.h)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(NOT SMALL_BUILD)
 | 
					if(NOT SMALL_BUILD)
 | 
				
			||||||
    target_sources(ucentralgw PUBLIC src/KafkaManager.cpp src/KafkaManager.h)
 | 
					    target_sources(ucentralgw PUBLIC src/KafkaManager.cpp src/KafkaManager.h)
 | 
				
			||||||
@@ -102,7 +101,7 @@ target_link_libraries(ucentralgw PUBLIC
 | 
				
			|||||||
                        ${Poco_LIBRARIES} ${Boost_LIBRARIES} ${ZLIB_LIBRARIES})
 | 
					                        ${Poco_LIBRARIES} ${Boost_LIBRARIES} ${ZLIB_LIBRARIES})
 | 
				
			||||||
if(NOT SMALL_BUILD)
 | 
					if(NOT SMALL_BUILD)
 | 
				
			||||||
    target_link_libraries(ucentralgw PUBLIC
 | 
					    target_link_libraries(ucentralgw PUBLIC
 | 
				
			||||||
            ${MySQL_LIBRARIES} ${ODBC_LIBRARIES} ${ZLIB_LIBRARIES}
 | 
					            ${MySQL_LIBRARIES} ${ZLIB_LIBRARIES}
 | 
				
			||||||
            CppKafka::cppkafka
 | 
					            CppKafka::cppkafka
 | 
				
			||||||
             )
 | 
					             )
 | 
				
			||||||
    if(UNIX AND NOT APPLE)
 | 
					    if(UNIX AND NOT APPLE)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										39
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										39
									
								
								Dockerfile
									
									
									
									
									
								
							@@ -1,13 +1,13 @@
 | 
				
			|||||||
FROM alpine AS builder
 | 
					FROM alpine AS builder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN apk update && \
 | 
					RUN apk add --update --no-cache \
 | 
				
			||||||
    apk add --no-cache openssl openssh && \
 | 
					    openssl openssh \
 | 
				
			||||||
    apk add --no-cache ncurses-libs && \
 | 
					    ncurses-libs \
 | 
				
			||||||
    apk add --no-cache bash util-linux coreutils curl && \
 | 
					    bash util-linux coreutils curl \
 | 
				
			||||||
    apk add --no-cache make cmake gcc g++ libstdc++ libgcc git zlib-dev yaml-cpp-dev && \
 | 
					    make cmake gcc g++ libstdc++ libgcc git zlib-dev yaml-cpp-dev \
 | 
				
			||||||
    apk add --no-cache openssl-dev boost-dev unixodbc-dev postgresql-dev mariadb-dev && \
 | 
					    openssl-dev boost-dev unixodbc-dev postgresql-dev mariadb-dev \
 | 
				
			||||||
    apk add --no-cache apache2-utils yaml-dev apr-util-dev && \
 | 
					    apache2-utils yaml-dev apr-util-dev \
 | 
				
			||||||
    apk add --no-cache lua-dev librdkafka-dev
 | 
					    lua-dev librdkafka-dev
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN git clone https://github.com/stephb9959/poco /poco
 | 
					RUN git clone https://github.com/stephb9959/poco /poco
 | 
				
			||||||
RUN git clone https://github.com/stephb9959/cppkafka /cppkafka
 | 
					RUN git clone https://github.com/stephb9959/cppkafka /cppkafka
 | 
				
			||||||
@@ -26,7 +26,7 @@ RUN cmake ..
 | 
				
			|||||||
RUN cmake --build . --config Release -j8
 | 
					RUN cmake --build . --config Release -j8
 | 
				
			||||||
RUN cmake --build . --target install
 | 
					RUN cmake --build . --target install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ADD CMakeLists.txt /ucentralgw/
 | 
					ADD CMakeLists.txt build /ucentralgw/
 | 
				
			||||||
ADD cmake /ucentralgw/cmake
 | 
					ADD cmake /ucentralgw/cmake
 | 
				
			||||||
ADD src /ucentralgw/src
 | 
					ADD src /ucentralgw/src
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -38,18 +38,23 @@ RUN cmake --build . --config Release -j8
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
FROM alpine
 | 
					FROM alpine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENV UCENTRALGW_USER=ucentralgw \
 | 
				
			||||||
 | 
					    UCENTRALGW_ROOT=/ucentralgw-data \
 | 
				
			||||||
 | 
					    UCENTRALGW_CONFIG=/ucentralgw-data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN addgroup -S "$UCENTRALGW_USER" && \
 | 
				
			||||||
 | 
					    adduser -S -G "$UCENTRALGW_USER" "$UCENTRALGW_USER"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN mkdir /ucentral
 | 
					RUN mkdir /ucentral
 | 
				
			||||||
RUN mkdir /ucentralgw-data
 | 
					RUN mkdir -p "$UCENTRALGW_ROOT" "$UCENTRALGW_CONFIG"
 | 
				
			||||||
RUN apk add --update --no-cache librdkafka mariadb-connector-c libpq unixodbc
 | 
					RUN apk add --update --no-cache librdkafka mariadb-connector-c libpq unixodbc su-exec
 | 
				
			||||||
 | 
					
 | 
				
			||||||
COPY --from=builder /ucentralgw/cmake-build/ucentralgw /ucentral/ucentralgw
 | 
					COPY --from=builder /ucentralgw/cmake-build/ucentralgw /ucentral/ucentralgw
 | 
				
			||||||
COPY --from=builder /cppkafka/cmake-build/src/lib/* /lib/
 | 
					COPY --from=builder /cppkafka/cmake-build/src/lib/* /lib/
 | 
				
			||||||
COPY --from=builder /poco/cmake-build/lib/* /lib/
 | 
					COPY --from=builder /poco/cmake-build/lib/* /lib/
 | 
				
			||||||
 | 
					COPY docker-entrypoint.sh /
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXPOSE 15002
 | 
					EXPOSE 15002 16002 16003 17002 16102
 | 
				
			||||||
EXPOSE 16002
 | 
					 | 
				
			||||||
EXPOSE 16003
 | 
					 | 
				
			||||||
EXPOSE 17002
 | 
					 | 
				
			||||||
EXPOSE 16102
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENTRYPOINT /ucentral/ucentralgw
 | 
					ENTRYPOINT ["/docker-entrypoint.sh"]
 | 
				
			||||||
 | 
					CMD ["/ucentral/ucentralgw"]
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								README.md
									
									
									
									
									
								
							@@ -498,24 +498,6 @@ you must use `$<varname>`. The path for the logs for the service must exist prio
 | 
				
			|||||||
service. The path is defined under `logging.channels.c2.path`. Only `path names` support the use of 
 | 
					service. The path is defined under `logging.channels.c2.path`. Only `path names` support the use of 
 | 
				
			||||||
environment variables. Here is a sample configuration:
 | 
					environment variables. Here is a sample configuration:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Docker Compose
 | 
					 | 
				
			||||||
The repository also contains a Docker Compose file, which you can use to instantiate a complete deployment of the uCentral microservices and related components for local development purposes. To spin up a local development environment:
 | 
					 | 
				
			||||||
1. Switch into the project directory with `cd docker-compose/`.
 | 
					 | 
				
			||||||
2. This repository contains a gateway certificate signed by TIP and a self-signed certificate for the REST API and other components which are used by default in the Compose deployment. The certificates are valid for the `*.wlan.local` domain and the Docker Compose uCentral microservice configs use `ucentral.wlan.local` as a hostname, so make sure you add an entry in your hosts file (or in your local DNS solution) which points to `127.0.0.1`.
 | 
					 | 
				
			||||||
3. If you have your own certificates and want to use the deployment for anything other than local development copy your certs into the `certs/` directory and reference them in the appropriate sections of the microservice configuration files. Make sure to also adapt the sections which reference the hostname. For more information on certificates please see the [certificates section](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw#certificates) of this README and/or [CERTIFICATES.md](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/CERTIFICATES.md).  
 | 
					 | 
				
			||||||
4. Docker Compose pulls the microservice images from the JFrog repository. If you want to change the image tag or some of the image versions which are used for the other services, have a look into the `.env` file. You'll also find service specific `.env` files in this directory. Edit them if you want to change database passwords (highly recommended!) or other configuration data. Don't forget to adapt your changes in the application configuration files.
 | 
					 | 
				
			||||||
5. Open `docker-compose/ucentralgw-data/ucentral.properties` to change [authentication data](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw#default-username-and-password) for uCentralGW (again highly recommended!).
 | 
					 | 
				
			||||||
6. Spin up the deployment with `docker-compose up -d`.
 | 
					 | 
				
			||||||
7. Navigate to the UI which listens to `127.0.0.1` and login with your uCentralGW authentication data.
 | 
					 | 
				
			||||||
8. To use the [curl test script](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/TEST_CURL.md) to talk to the API set the following environment variables: 
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
export UCENTRALSEC="ucentral.wlan.local:16001"
 | 
					 | 
				
			||||||
export FLAGS="-s --cacert docker-compose/ucentral-data/certs/restapi-ca.pem" 
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
The `--cacert` option is necessary since the REST API certificates are self-signed. Omit the option if you provide your own signed certificates.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
PS: The Docker Compose deployment creates five local volumes to persist mostly database data and data for Zookeeper and Kafka. If you want re-create the deployment and remove all persistent application and database data just delete the volumes with `docker volume rm $(docker volume ls -qf name=ucentral)` after you stopped the services with `docker-compose down`.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## uCentral communication protocol
 | 
					## uCentral communication protocol
 | 
				
			||||||
The communication protocol between the device and the controller is detailed in this [document](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/PROTOCOL.md).
 | 
					The communication protocol between the device and the controller is detailed in this [document](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/PROTOCOL.md).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -84,8 +84,9 @@
 | 
				
			|||||||
				<Option type="1"/>
 | 
									<Option type="1"/>
 | 
				
			||||||
				<Option compiler="gcc"/>
 | 
									<Option compiler="gcc"/>
 | 
				
			||||||
				<Compiler>
 | 
									<Compiler>
 | 
				
			||||||
					<Add option="-DAPP_VERSION="0.4.0""/>
 | 
										<Add option="-DAPP_VERSION="0.7.0""/>
 | 
				
			||||||
					<Add option="-DBUILD_NUMBER="61""/>
 | 
										<Add option="-DBUILD_NUMBER="120""/>
 | 
				
			||||||
 | 
										<Add option="-DTIP_GATEWAY_SERVICE="1""/>
 | 
				
			||||||
					<Add option="-D_DEBUG"/>
 | 
										<Add option="-D_DEBUG"/>
 | 
				
			||||||
					<Add option="-DPOCO_ENABLE_CPP14"/>
 | 
										<Add option="-DPOCO_ENABLE_CPP14"/>
 | 
				
			||||||
					<Add option="-DPOCO_ENABLE_CPP11"/>
 | 
										<Add option="-DPOCO_ENABLE_CPP11"/>
 | 
				
			||||||
@@ -98,6 +99,7 @@
 | 
				
			|||||||
					<Add option="-DBOOST_ALL_NO_LIB"/>
 | 
										<Add option="-DBOOST_ALL_NO_LIB"/>
 | 
				
			||||||
					<Add directory="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src"/>
 | 
										<Add directory="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src"/>
 | 
				
			||||||
					<Add directory="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/include/kafka"/>
 | 
										<Add directory="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/include/kafka"/>
 | 
				
			||||||
 | 
										<Add directory="/usr/local/opt/mysql-client/include"/>
 | 
				
			||||||
					<Add directory="/usr/local/include"/>
 | 
										<Add directory="/usr/local/include"/>
 | 
				
			||||||
					<Add directory="/usr/local/opt/openssl/include"/>
 | 
										<Add directory="/usr/local/opt/openssl/include"/>
 | 
				
			||||||
					<Add directory="/usr/local/opt/mysql-client/include/mysql"/>
 | 
										<Add directory="/usr/local/opt/mysql-client/include/mysql"/>
 | 
				
			||||||
@@ -121,8 +123,9 @@
 | 
				
			|||||||
				<Option type="1"/>
 | 
									<Option type="1"/>
 | 
				
			||||||
				<Option compiler="gcc"/>
 | 
									<Option compiler="gcc"/>
 | 
				
			||||||
				<Compiler>
 | 
									<Compiler>
 | 
				
			||||||
					<Add option="-DAPP_VERSION="0.4.0""/>
 | 
										<Add option="-DAPP_VERSION="0.7.0""/>
 | 
				
			||||||
					<Add option="-DBUILD_NUMBER="61""/>
 | 
										<Add option="-DBUILD_NUMBER="120""/>
 | 
				
			||||||
 | 
										<Add option="-DTIP_GATEWAY_SERVICE="1""/>
 | 
				
			||||||
					<Add option="-D_DEBUG"/>
 | 
										<Add option="-D_DEBUG"/>
 | 
				
			||||||
					<Add option="-DPOCO_ENABLE_CPP14"/>
 | 
										<Add option="-DPOCO_ENABLE_CPP14"/>
 | 
				
			||||||
					<Add option="-DPOCO_ENABLE_CPP11"/>
 | 
										<Add option="-DPOCO_ENABLE_CPP11"/>
 | 
				
			||||||
@@ -135,6 +138,7 @@
 | 
				
			|||||||
					<Add option="-DBOOST_ALL_NO_LIB"/>
 | 
										<Add option="-DBOOST_ALL_NO_LIB"/>
 | 
				
			||||||
					<Add directory="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src"/>
 | 
										<Add directory="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src"/>
 | 
				
			||||||
					<Add directory="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/include/kafka"/>
 | 
										<Add directory="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/include/kafka"/>
 | 
				
			||||||
 | 
										<Add directory="/usr/local/opt/mysql-client/include"/>
 | 
				
			||||||
					<Add directory="/usr/local/include"/>
 | 
										<Add directory="/usr/local/include"/>
 | 
				
			||||||
					<Add directory="/usr/local/opt/openssl/include"/>
 | 
										<Add directory="/usr/local/opt/openssl/include"/>
 | 
				
			||||||
					<Add directory="/usr/local/opt/mysql-client/include/mysql"/>
 | 
										<Add directory="/usr/local/opt/mysql-client/include/mysql"/>
 | 
				
			||||||
@@ -155,16 +159,106 @@
 | 
				
			|||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/build">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/build">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/ALBHealthCheckServer.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/AuthClient.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/AuthClient.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/CentralConfig.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/CentralConfig.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/CommandChannel.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/CommandChannel.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/CommandManager.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/CommandManager.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/Daemon.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/Daemon.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/DeviceRegistry.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/DeviceRegistry.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/FileUploader.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/FileUploader.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/KafkaManager.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/KafkaManager.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/Kafka_topics.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/MicroService.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/MicroService.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/OUIServer.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/OUIServer.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/OpenAPIRequest.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/OpenAPIRequest.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_BlackList.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_BlackList.cpp">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_BlackList.h">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_BlackList.h">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_callback.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_GWobjects.cpp">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_callback.h">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_GWobjects.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_InternalServer.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_InternalServer.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_RPC.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_RPC.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_SecurityObjects.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_SecurityObjects.h">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_command.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_command.cpp">
 | 
				
			||||||
@@ -221,16 +315,13 @@
 | 
				
			|||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_handler.h">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_handler.h">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_oauth2Handler.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_ouis.cpp">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_oauth2Handler.h">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_ouis.h">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_objects.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_protocol.h">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_objects.h">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_server.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_server.cpp">
 | 
				
			||||||
@@ -245,16 +336,46 @@
 | 
				
			|||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_system_command.h">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_system_command.h">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_unknownRequestHandler.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_utils.cpp">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_unknownRequestHandler.h">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/RESTAPI_utils.h">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/kafka_service.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/StateProcessor.cpp">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/kafka_service.h">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/StateProcessor.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/StorageArchiver.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/StorageArchiver.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/StorageService.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/StorageService.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/SubSystemServer.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/SubSystemServer.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/Utils.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/Utils.h">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/WebSocketServer.cpp">
 | 
				
			||||||
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
 | 
							</Unit>
 | 
				
			||||||
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/WebSocketServer.h">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_blacklist.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_blacklist.cpp">
 | 
				
			||||||
@@ -272,13 +393,10 @@
 | 
				
			|||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_device.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_device.cpp">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_firmware_updates.cpp">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_healthcheck.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_healthcheck.cpp">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_identity.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_lifetime_stats.cpp">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_logs.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_logs.cpp">
 | 
				
			||||||
@@ -287,9 +405,6 @@
 | 
				
			|||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_mysql.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_mysql.cpp">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_odbc.cpp">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_pgql.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_pgql.cpp">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
@@ -302,82 +417,10 @@
 | 
				
			|||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_tables.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/storage_tables.cpp">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uAuthService.cpp">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCentralProtocol.h">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uAuthService.h">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCentralTypes.h">
 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCallbackManager.cpp">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCallbackManager.h">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCentral.cpp">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCentral.h">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCentralConfig.cpp">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCentralConfig.h">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCentralWebSocketServer.cpp">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCentralWebSocketServer.h">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCommandChannel.cpp">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCommandChannel.h">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCommandManager.cpp">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uCommandManager.h">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uDeviceRegistry.cpp">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uDeviceRegistry.h">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uFileUploader.cpp">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uFileUploader.h">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uFirmwareManager.cpp">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uFirmwareManager.h">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uStorageService.cpp">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uStorageService.h">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uSubSystemServer.cpp">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uSubSystemServer.h">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uUtils.cpp">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/src/uUtils.h">
 | 
					 | 
				
			||||||
			<Option target="ucentralgw"/>
 | 
								<Option target="ucentralgw"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/CMakeLists.txt">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/CMakeLists.txt">
 | 
				
			||||||
@@ -440,12 +483,6 @@
 | 
				
			|||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoCryptoConfigVersion.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoCryptoConfigVersion.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoCryptoTargets-debug.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoCryptoTargets-release.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoCryptoTargets-relwithdebinfo.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoCryptoTargets-relwithdebinfo.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
@@ -464,48 +501,18 @@
 | 
				
			|||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataMySQLConfigVersion.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataMySQLConfigVersion.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataMySQLTargets-debug.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataMySQLTargets-release.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataMySQLTargets-relwithdebinfo.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataMySQLTargets-relwithdebinfo.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataMySQLTargets.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataMySQLTargets.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataODBCConfig.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataODBCConfigVersion.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataODBCTargets-debug.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataODBCTargets-release.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataODBCTargets-relwithdebinfo.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataODBCTargets.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataPostgreSQLConfig.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataPostgreSQLConfig.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataPostgreSQLConfigVersion.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataPostgreSQLConfigVersion.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataPostgreSQLTargets-debug.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataPostgreSQLTargets-release.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataPostgreSQLTargets-relwithdebinfo.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataPostgreSQLTargets-relwithdebinfo.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
@@ -518,24 +525,12 @@
 | 
				
			|||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataSQLiteConfigVersion.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataSQLiteConfigVersion.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataSQLiteTargets-debug.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataSQLiteTargets-release.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataSQLiteTargets-relwithdebinfo.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataSQLiteTargets-relwithdebinfo.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataSQLiteTargets.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataSQLiteTargets.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataTargets-debug.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataTargets-release.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataTargets-relwithdebinfo.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoDataTargets-relwithdebinfo.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
@@ -548,12 +543,6 @@
 | 
				
			|||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoFoundationConfigVersion.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoFoundationConfigVersion.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoFoundationTargets-debug.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoFoundationTargets-release.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoFoundationTargets-relwithdebinfo.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoFoundationTargets-relwithdebinfo.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
@@ -566,12 +555,6 @@
 | 
				
			|||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJSONConfigVersion.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJSONConfigVersion.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJSONTargets-debug.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJSONTargets-release.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJSONTargets-relwithdebinfo.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJSONTargets-relwithdebinfo.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
@@ -584,12 +567,6 @@
 | 
				
			|||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJWTConfigVersion.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJWTConfigVersion.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJWTTargets-debug.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJWTTargets-release.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJWTTargets-relwithdebinfo.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoJWTTargets-relwithdebinfo.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
@@ -608,24 +585,12 @@
 | 
				
			|||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetSSLConfigVersion.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetSSLConfigVersion.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetSSLTargets-debug.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetSSLTargets-release.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetSSLTargets-relwithdebinfo.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetSSLTargets-relwithdebinfo.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetSSLTargets.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetSSLTargets.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetTargets-debug.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetTargets-release.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetTargets-relwithdebinfo.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoNetTargets-relwithdebinfo.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
@@ -638,12 +603,6 @@
 | 
				
			|||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoUtilConfigVersion.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoUtilConfigVersion.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoUtilTargets-debug.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoUtilTargets-release.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoUtilTargets-relwithdebinfo.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoUtilTargets-relwithdebinfo.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
@@ -656,12 +615,6 @@
 | 
				
			|||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoXMLConfigVersion.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoXMLConfigVersion.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoXMLTargets-debug.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoXMLTargets-release.cmake">
 | 
					 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
					 | 
				
			||||||
		</Unit>
 | 
					 | 
				
			||||||
		<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoXMLTargets-relwithdebinfo.cmake">
 | 
							<Unit filename="/Users/stephb/Desktop/Dropbox/clion/wlan-cloud-ucentralgw/../../../../../../usr/local/lib/cmake/Poco/PocoXMLTargets-relwithdebinfo.cmake">
 | 
				
			||||||
			<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
								<Option virtualFolder="CMake Files\..\..\..\..\..\..\usr\local\lib\cmake\Poco\"/>
 | 
				
			||||||
		</Unit>
 | 
							</Unit>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +0,0 @@
 | 
				
			|||||||
COMPOSE_PROJECT_NAME=ucentral
 | 
					 | 
				
			||||||
POSTGRES_TAG=latest
 | 
					 | 
				
			||||||
MYSQL_TAG=latest
 | 
					 | 
				
			||||||
UCENTRALGW_TAG=master
 | 
					 | 
				
			||||||
UCENTRALGWUI_TAG=main
 | 
					 | 
				
			||||||
UCENTRALSEC_TAG=main
 | 
					 | 
				
			||||||
RTTYS_TAG=3.6.0
 | 
					 | 
				
			||||||
KAFKA_TAG=latest
 | 
					 | 
				
			||||||
ZOOKEEPER_TAG=latest
 | 
					 | 
				
			||||||
@@ -1,2 +0,0 @@
 | 
				
			|||||||
KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181
 | 
					 | 
				
			||||||
ALLOW_PLAINTEXT_LISTENER=yes
 | 
					 | 
				
			||||||
@@ -1,4 +0,0 @@
 | 
				
			|||||||
MYSQL_ROOT_PASSWORD=root
 | 
					 | 
				
			||||||
MYSQL_USER=rttys
 | 
					 | 
				
			||||||
MYSQL_PASSWORD=rttys
 | 
					 | 
				
			||||||
MYSQL_DATABASE=rttys
 | 
					 | 
				
			||||||
@@ -1,5 +0,0 @@
 | 
				
			|||||||
POSTGRES_PASSWORD=ucentralgw
 | 
					 | 
				
			||||||
POSTGRES_USER=ucentralgw
 | 
					 | 
				
			||||||
UCENTRALSEC_DB=ucentralsec
 | 
					 | 
				
			||||||
UCENTRALSEC_DB_USER=ucentralsec
 | 
					 | 
				
			||||||
UCENTRALSEC_DB_PASSWORD=ucentralsec
 | 
					 | 
				
			||||||
@@ -1,2 +0,0 @@
 | 
				
			|||||||
UCENTRALGW_ROOT=/ucentralgw-data
 | 
					 | 
				
			||||||
UCENTRALGW_CONFIG=/ucentralgw-data
 | 
					 | 
				
			||||||
@@ -1,2 +0,0 @@
 | 
				
			|||||||
DEFAULT_UCENTRALSEC_URL=https://ucentral.wlan.local:16001
 | 
					 | 
				
			||||||
ALLOW_UCENTRALSEC_CHANGE=false
 | 
					 | 
				
			||||||
@@ -1,2 +0,0 @@
 | 
				
			|||||||
UCENTRALSEC_ROOT=/ucentralsec-data
 | 
					 | 
				
			||||||
UCENTRALSEC_CONFIG=/ucentralsec-data
 | 
					 | 
				
			||||||
@@ -1,10 +0,0 @@
 | 
				
			|||||||
#!/usr/bin/env bash
 | 
					 | 
				
			||||||
set -e
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
SERVICES="ucentralgw.wlan.local ucentralsec.wlan.local"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
for i in $SERVICES; do
 | 
					 | 
				
			||||||
    docker-compose exec $i apk add ca-certificates
 | 
					 | 
				
			||||||
    docker cp certs/restapi-ca.pem ucentral_$i\_1:/usr/local/share/ca-certificates/
 | 
					 | 
				
			||||||
    docker-compose exec $i update-ca-certificates
 | 
					 | 
				
			||||||
done
 | 
					 | 
				
			||||||
							
								
								
									
										3
									
								
								docker-compose/certs/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								docker-compose/certs/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +0,0 @@
 | 
				
			|||||||
*
 | 
					 | 
				
			||||||
!.gitignore
 | 
					 | 
				
			||||||
!cas/
 | 
					 | 
				
			||||||
							
								
								
									
										2
									
								
								docker-compose/certs/cas/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								docker-compose/certs/cas/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +0,0 @@
 | 
				
			|||||||
*
 | 
					 | 
				
			||||||
!.gitignore
 | 
					 | 
				
			||||||
@@ -1,18 +0,0 @@
 | 
				
			|||||||
-----BEGIN CERTIFICATE-----
 | 
					 | 
				
			||||||
MIIC4DCCAcgCCQC7oc+4dT4WlTANBgkqhkiG9w0BAQsFADAyMQswCQYDVQQGEwJD
 | 
					 | 
				
			||||||
QTEMMAoGA1UECgwDVElQMRUwEwYDVQQDDAwqLndsYW4ubG9jYWwwHhcNMjEwNzA3
 | 
					 | 
				
			||||||
MDkyOTAxWhcNMzEwNzA1MDkyOTAxWjAyMQswCQYDVQQGEwJDQTEMMAoGA1UECgwD
 | 
					 | 
				
			||||||
VElQMRUwEwYDVQQDDAwqLndsYW4ubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IB
 | 
					 | 
				
			||||||
DwAwggEKAoIBAQD67KEKKHj1xyj0Sc+/WSFeXluhp+76V/8njnGcTus8IsaHWeAj
 | 
					 | 
				
			||||||
O1T1/PnqNMNP3CSgCpAZRn7Eom33HH89pC7iIE5t3aGrFzxZ6AxFgECUCkby1j9D
 | 
					 | 
				
			||||||
j7PawapJ7XNqT4P4ZGEGOWlLGE9oUpF2pr3B3jBwmV9t9d/Zp8na23K7rnsr5kNn
 | 
					 | 
				
			||||||
RXp6iPNPpynppNQFBwzsovyhu9tzk/zz3gohSY9f6oyNNaKcZwN/yrG4B8FnRfa7
 | 
					 | 
				
			||||||
WFNvkPi5zAjJ3oEXMp+Im2/SvSqzptYwZhplb14ILZ5ClkSwAslG8FiOAzXr887r
 | 
					 | 
				
			||||||
hgEPzqP6SNIOwy/B/AMOFQl6wPvXBwz9eNW1AgMBAAEwDQYJKoZIhvcNAQELBQAD
 | 
					 | 
				
			||||||
ggEBAA8Oa8jannqNRdqOuY460Pum1B61kGmf2OK2ZiMaddlxqL3ZBdXPqF02hwSd
 | 
					 | 
				
			||||||
q6uxCVP5NgvqSm+pTHaDcODJiCBrMmGQqHT82LuoCyk1BMqH/PYm+kfazPhKF31x
 | 
					 | 
				
			||||||
Me7E47DQzk4tMyV28HBCHH6UicQ05ryT1yBfmj8JmYNx9ezmJcanu0/eyI2Lv8Ar
 | 
					 | 
				
			||||||
Y7mrgblfOUnsif2w/aUaOsoY1t6/ThgTBc3BTMtUXXAcMiPLu4mSdN6nCm75Qp5q
 | 
					 | 
				
			||||||
4zl/SNPjLnmtpHhLDtr4swf6vZw0RG7ECCf6Av8lv8mJG6g53YM8jfe0EzLqbAFf
 | 
					 | 
				
			||||||
iSuQbt5n6lMWVgv+FKwXjwAda+Q=
 | 
					 | 
				
			||||||
-----END CERTIFICATE-----
 | 
					 | 
				
			||||||
@@ -1,18 +0,0 @@
 | 
				
			|||||||
-----BEGIN CERTIFICATE-----
 | 
					 | 
				
			||||||
MIIC4DCCAcgCCQC7oc+4dT4WlTANBgkqhkiG9w0BAQsFADAyMQswCQYDVQQGEwJD
 | 
					 | 
				
			||||||
QTEMMAoGA1UECgwDVElQMRUwEwYDVQQDDAwqLndsYW4ubG9jYWwwHhcNMjEwNzA3
 | 
					 | 
				
			||||||
MDkyOTAxWhcNMzEwNzA1MDkyOTAxWjAyMQswCQYDVQQGEwJDQTEMMAoGA1UECgwD
 | 
					 | 
				
			||||||
VElQMRUwEwYDVQQDDAwqLndsYW4ubG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IB
 | 
					 | 
				
			||||||
DwAwggEKAoIBAQD67KEKKHj1xyj0Sc+/WSFeXluhp+76V/8njnGcTus8IsaHWeAj
 | 
					 | 
				
			||||||
O1T1/PnqNMNP3CSgCpAZRn7Eom33HH89pC7iIE5t3aGrFzxZ6AxFgECUCkby1j9D
 | 
					 | 
				
			||||||
j7PawapJ7XNqT4P4ZGEGOWlLGE9oUpF2pr3B3jBwmV9t9d/Zp8na23K7rnsr5kNn
 | 
					 | 
				
			||||||
RXp6iPNPpynppNQFBwzsovyhu9tzk/zz3gohSY9f6oyNNaKcZwN/yrG4B8FnRfa7
 | 
					 | 
				
			||||||
WFNvkPi5zAjJ3oEXMp+Im2/SvSqzptYwZhplb14ILZ5ClkSwAslG8FiOAzXr887r
 | 
					 | 
				
			||||||
hgEPzqP6SNIOwy/B/AMOFQl6wPvXBwz9eNW1AgMBAAEwDQYJKoZIhvcNAQELBQAD
 | 
					 | 
				
			||||||
ggEBAA8Oa8jannqNRdqOuY460Pum1B61kGmf2OK2ZiMaddlxqL3ZBdXPqF02hwSd
 | 
					 | 
				
			||||||
q6uxCVP5NgvqSm+pTHaDcODJiCBrMmGQqHT82LuoCyk1BMqH/PYm+kfazPhKF31x
 | 
					 | 
				
			||||||
Me7E47DQzk4tMyV28HBCHH6UicQ05ryT1yBfmj8JmYNx9ezmJcanu0/eyI2Lv8Ar
 | 
					 | 
				
			||||||
Y7mrgblfOUnsif2w/aUaOsoY1t6/ThgTBc3BTMtUXXAcMiPLu4mSdN6nCm75Qp5q
 | 
					 | 
				
			||||||
4zl/SNPjLnmtpHhLDtr4swf6vZw0RG7ECCf6Av8lv8mJG6g53YM8jfe0EzLqbAFf
 | 
					 | 
				
			||||||
iSuQbt5n6lMWVgv+FKwXjwAda+Q=
 | 
					 | 
				
			||||||
-----END CERTIFICATE-----
 | 
					 | 
				
			||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
-----BEGIN PRIVATE KEY-----
 | 
					 | 
				
			||||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD67KEKKHj1xyj0
 | 
					 | 
				
			||||||
Sc+/WSFeXluhp+76V/8njnGcTus8IsaHWeAjO1T1/PnqNMNP3CSgCpAZRn7Eom33
 | 
					 | 
				
			||||||
HH89pC7iIE5t3aGrFzxZ6AxFgECUCkby1j9Dj7PawapJ7XNqT4P4ZGEGOWlLGE9o
 | 
					 | 
				
			||||||
UpF2pr3B3jBwmV9t9d/Zp8na23K7rnsr5kNnRXp6iPNPpynppNQFBwzsovyhu9tz
 | 
					 | 
				
			||||||
k/zz3gohSY9f6oyNNaKcZwN/yrG4B8FnRfa7WFNvkPi5zAjJ3oEXMp+Im2/SvSqz
 | 
					 | 
				
			||||||
ptYwZhplb14ILZ5ClkSwAslG8FiOAzXr887rhgEPzqP6SNIOwy/B/AMOFQl6wPvX
 | 
					 | 
				
			||||||
Bwz9eNW1AgMBAAECggEAZdJT3u1heEqjAc5Z8QnYEpUzlbuxrAC9V23kCEu2BScP
 | 
					 | 
				
			||||||
bKk53NIcvd00BKf4gZWRfygKJVeH5X8MJHR55aeUJsp5SPfgvK6nHMye/iz3B5vM
 | 
					 | 
				
			||||||
AoqSDXZow2JHGcyzQvaVVNxWytHNOl3ZCzpGMOGkquDgwzBZmyNk/Muri5X1TtbH
 | 
					 | 
				
			||||||
DgeYdht2YiHqHdGWsLNU1vZAgzlwD8fXg65XOmNehjWnowhpNRCgpcDeJCtEuNzt
 | 
					 | 
				
			||||||
6iXFWffjO6YTbVnoM5xhLROjLv6gYP4wxsQSZc/NGz9Jow7VxlYZg9wCE75bduFn
 | 
					 | 
				
			||||||
7D5O4OgVgPgYbyCutpB/o4PMNURb4V/5p2OAEgLX2QKBgQD+kHYRAaawRbaY4jGf
 | 
					 | 
				
			||||||
isj0oh2C/Z99Mqf/nnpPwmUwrhpmnQ+pRdWBw940tPrEpVoOcCPWQ5hO1zUET18d
 | 
					 | 
				
			||||||
xQqs3zd6lEhJogmMqkjOT670YBEX/wyALd3M5F3HT/K2aixL1XaCCpAl97JB9RyB
 | 
					 | 
				
			||||||
zGIr5c+mIOVK/uYrlFO28thXzwKBgQD8VumZIYZpWeE7pTyCg0PcDYlNATA/VKoD
 | 
					 | 
				
			||||||
9YrGqEEHGgFNJEWj8Xj8aqBzaPoUk+eGp7NfSoOchVM+Bf3ktWy5doZCmNuxlOyq
 | 
					 | 
				
			||||||
Ix5yrB2jyYceaSf2nxHqlD2VhKB/YJx0yTU1UkB5dG4nYnqiUg7c5JeQOVzwFKm1
 | 
					 | 
				
			||||||
t6/Hk/cXOwKBgGT+yWjL3+cVcXFMZGWouTudSdobZ3hTbaWTqXEVbfIXUPAfJgSB
 | 
					 | 
				
			||||||
aUi3feQpXUhBVe5efUlXvgihhy4zk0gLUcXuNWOTiu5ztBgzwvjfUkkwB/geP0Zn
 | 
					 | 
				
			||||||
bBULEU2vIVtP2k0n3oGPUUtO71ENvwacIOLLpUuCx5WudYEasu/lfwGvAoGBAOiE
 | 
					 | 
				
			||||||
manuF3HaTU3tu20z0YLiwkK/tpqUxDjzuBXIEmudzdcsdjNUHbzR79mIwO/XPf95
 | 
					 | 
				
			||||||
ZjKHcfD3dbXwRXzKpE3dZmfVfJMM/GrmA3d9G67B04z1Lsr01siGIp004cOd3W1L
 | 
					 | 
				
			||||||
vojMqvZ/j8Ug3InX/TQUO4i9IuNi1uLISOQpdwTjAoGAG33swIFnH/mz7ubu8wfE
 | 
					 | 
				
			||||||
9nwe8NNf56kbFBG2FMuHvo8GYj0sqylwtZnh4TCwlTzqUO8e6oFdK8Ot6z7H9Fa3
 | 
					 | 
				
			||||||
vnDD2WRwEFydRP5fbW5eFmGbzLfHlzUY+Do81qrUMF47LEN94X7yaXdb/vNW57lp
 | 
					 | 
				
			||||||
K9hGF1Bdk8089Knm3l1Fc4w=
 | 
					 | 
				
			||||||
-----END PRIVATE KEY-----
 | 
					 | 
				
			||||||
@@ -1,27 +0,0 @@
 | 
				
			|||||||
-----BEGIN CERTIFICATE-----
 | 
					 | 
				
			||||||
MIIEgDCCA2igAwIBAgIUaKVB2xg9gr/sS6FvzMex0xSbEzswDQYJKoZIhvcNAQEL
 | 
					 | 
				
			||||||
BQAwbDELMAkGA1UEBhMCVVMxJDAiBgNVBAoTG1RlbGVjb20gSW5mcmEgUHJvamVj
 | 
					 | 
				
			||||||
dCwgSW5jLjEMMAoGA1UECxMDVElQMSkwJwYDVQQDEyBUZWxlY29tIEluZnJhIFBy
 | 
					 | 
				
			||||||
b2plY3QgSXNzdWluZyBDQTAeFw0yMTA3MDgxMDQ5MTVaFw0yNTA3MDgxMDQ5MTVa
 | 
					 | 
				
			||||||
MDIxCzAJBgNVBAYTAlVTMQwwCgYDVQQKEwNUSVAxFTATBgNVBAMMDCoud2xhbi5s
 | 
					 | 
				
			||||||
b2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL2rlMfV7/Si2Svx
 | 
					 | 
				
			||||||
J1YOEz6KJLvey995/0MkQvAG0RM6TpFwgUNnpYFFozcWME8MGSxws+6hOzDoMmHC
 | 
					 | 
				
			||||||
pgpP/KZ/Fyu9iUdzTxsJMyMxIW9sYbBMkQgBmvjkBlXDk5NfHh+yJBVxb7JlJ6vJ
 | 
					 | 
				
			||||||
oT7EJMzgKpYpFnO+bddalUVsDp3qQIjSvJIxl77vwgZQUJx0qCm17VTBhyM2RTJ3
 | 
					 | 
				
			||||||
jtr7kcWDm3jyyTVUvlM9g3DM9g0hUPMN0R5PP2HuqDdtYoY51krsm2mmVIYYnyAN
 | 
					 | 
				
			||||||
BDawmwYnZJfcC4gFzZJ5wK5NFjSKmd1mYp0damlSh0/uHxPyd4rm2QhUCQH92yKM
 | 
					 | 
				
			||||||
+9qYU70CAwEAAaOCAVIwggFOMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFM0mIZuE
 | 
					 | 
				
			||||||
6aly7ZKXl0KWjprcO9/uMB8GA1UdIwQYMBaAFLMbVLjgR6s98ziA5Dzl/QBhbdHo
 | 
					 | 
				
			||||||
MA4GA1UdDwEB/wQEAwIFoDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDATCBhgYIKwYB
 | 
					 | 
				
			||||||
BQUHAQEEejB4MCgGCCsGAQUFBzABhhxodHRwOi8vb2NzcC5vbmUuZGlnaWNlcnQu
 | 
					 | 
				
			||||||
Y29tMEwGCCsGAQUFBzAChkBodHRwOi8vY2FjZXJ0cy5vbmUuZGlnaWNlcnQuY29t
 | 
					 | 
				
			||||||
L1RlbGVjb21JbmZyYVByb2plY3RJc3N1aW5nQ0EuY3J0ME0GA1UdHwRGMEQwQqBA
 | 
					 | 
				
			||||||
oD6GPGh0dHA6Ly9jcmwub25lLmRpZ2ljZXJ0LmNvbS9UZWxlY29tSW5mcmFQcm9q
 | 
					 | 
				
			||||||
ZWN0SXNzdWluZ0NBLmNybDANBgkqhkiG9w0BAQsFAAOCAQEAAyb7X9qW0z0QJrl2
 | 
					 | 
				
			||||||
oAalMCh/gSJy5oER3L7iu/pnP3GREbr6bh6+1/MAf2bgnN2CUOKQHbozB7yCkM6V
 | 
					 | 
				
			||||||
8m5RnL4ePKVP5yIrbs48uM5Hl14QFLU4ZtFao6js0haoWWEgMo3sfbeyfOU0ScyW
 | 
					 | 
				
			||||||
ET5zfbDub3gUbWYmlz6hyV5aJoznaFjJTNP7SRQ9CHMTMHh3wAPfVlvG2TdcwwbM
 | 
					 | 
				
			||||||
ZKkdAHpl1NwRxyiBPJfkejGWrY3ZAs10te7u9Lsc9yZZKL8SU9J/mrO9tM5HLeUr
 | 
					 | 
				
			||||||
nCJN4RI7RyTuDw4LdMZW1Ju5QBXoZL9mj4KXIbUkDwryhbAxdQ1OnwD4O/avMChk
 | 
					 | 
				
			||||||
TNJzIw==
 | 
					 | 
				
			||||||
-----END CERTIFICATE-----
 | 
					 | 
				
			||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
-----BEGIN PRIVATE KEY-----
 | 
					 | 
				
			||||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC9q5TH1e/0otkr
 | 
					 | 
				
			||||||
8SdWDhM+iiS73svfef9DJELwBtETOk6RcIFDZ6WBRaM3FjBPDBkscLPuoTsw6DJh
 | 
					 | 
				
			||||||
wqYKT/ymfxcrvYlHc08bCTMjMSFvbGGwTJEIAZr45AZVw5OTXx4fsiQVcW+yZSer
 | 
					 | 
				
			||||||
yaE+xCTM4CqWKRZzvm3XWpVFbA6d6kCI0rySMZe+78IGUFCcdKgpte1UwYcjNkUy
 | 
					 | 
				
			||||||
d47a+5HFg5t48sk1VL5TPYNwzPYNIVDzDdEeTz9h7qg3bWKGOdZK7JtpplSGGJ8g
 | 
					 | 
				
			||||||
DQQ2sJsGJ2SX3AuIBc2SecCuTRY0ipndZmKdHWppUodP7h8T8neK5tkIVAkB/dsi
 | 
					 | 
				
			||||||
jPvamFO9AgMBAAECggEBAJgYoaRmcJfShyhvp8WgX9pE2RQ2o3I/2Gy1BWCJdtte
 | 
					 | 
				
			||||||
ZGbIuz+cO+IgP7QK/Q5Ge2Fht0hizp53dP9kIdYfMlEplSEkSpObahIaHIHaAh/h
 | 
					 | 
				
			||||||
36yKmbq73tQ7tsDLpuoE2pk8Nydi4dlCuL9PXxiAHaqVEFF9/V0vldGd+BnFfyst
 | 
					 | 
				
			||||||
retXgockCH+fqddM5Kp+H0bmjXzLke/b8T9KsdSBz7lg1Z67kmMrHLe14Q4Hgmr/
 | 
					 | 
				
			||||||
pFBkGGWKTFn48OXfncrv+oQAGED7r9c5UEdpOB6SBDxuddfzgkw9urnpKrYC/KOs
 | 
					 | 
				
			||||||
HLBTaGew73O81BsbaZlUiVxTdewrmFk2nG6UIPoGaxkCgYEA7IYOjIfNJOEPIWYP
 | 
					 | 
				
			||||||
zj4eipTy6zFk4L7tX3wX4wsor93rz8ArlF8sgNoyUhbKm6H++ZfVezLs2jcjJJ8Q
 | 
					 | 
				
			||||||
sXLwQ6L/D8aVb6AOVeC1WYJu5+wXIDX0H+1318a5+3bKVPn+hktJGEgCBvplVRnh
 | 
					 | 
				
			||||||
yzpQ+2v1SBp9qEzoSl1sV6gm1tsCgYEAzUnZcjUhHvoXLXJ1lfagCC6QsmjqzpJv
 | 
					 | 
				
			||||||
VdTKJlDuZ0qQGC6Ts+wKfM3MoiOsXW0pByC5lWwE43c/KU8J358j3OSSNafIFeD1
 | 
					 | 
				
			||||||
cxtYzJlMgnw5Y2Zt9tj+QW/1BOMdOftnPSOnsk6rpdCBMW6a2tYubJjbAuge+a2O
 | 
					 | 
				
			||||||
939XGnV0R0cCgYEA0bvmNtNNJAC2LAWWymnnJzgBWHFKZMipMNyXSethPuHo8yYS
 | 
					 | 
				
			||||||
/tSOYAwcRxKSwwMZWDY9RavYv3/ZF+Y9JT0otLFav6B2bq9dRuWlqiOxONLvhs6R
 | 
					 | 
				
			||||||
Faa7eIlt7gBeVpAAFRG5VWC0+38aUCZNRKsHmIsYy8FB3/Winh7NrcUb+7UCgYBi
 | 
					 | 
				
			||||||
egCTZqUixPmFVZjOfWY7Rosm6mlo+pnp5I+sXbpfVkdVMlKsRpipUdfOF6rBjnHV
 | 
					 | 
				
			||||||
937PDOgzbaqg2Ed2PFLpzcPNdVToGefkdcPdMdSf65Nj+WjatzEQlvJEi+YjQFQ/
 | 
					 | 
				
			||||||
4fC5+j8g5apz2gjy3Teb5J96/3qMbxNb6nwQNzO2VQKBgHyHUJOrhvv9+vs7v8nu
 | 
					 | 
				
			||||||
9DgV0b5eNO0g6Q4Ji7oqs24PssPQRA4gMtwmPT8Ha+wWGVzQt2U5LmjsLlrqAO6O
 | 
					 | 
				
			||||||
+Fa3c63sgmt672A8BJ3PL8LI8E2keZiH6rwADSUFp3TZoU2SHamw5NEruNRMIF1R
 | 
					 | 
				
			||||||
0LMsuAs2KEdnwAth2ZmUF2+S
 | 
					 | 
				
			||||||
-----END PRIVATE KEY-----
 | 
					 | 
				
			||||||
@@ -1,120 +0,0 @@
 | 
				
			|||||||
version: '3'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
volumes:
 | 
					 | 
				
			||||||
  postgresql_data:
 | 
					 | 
				
			||||||
    driver: local
 | 
					 | 
				
			||||||
  mysql_data:
 | 
					 | 
				
			||||||
    driver: local
 | 
					 | 
				
			||||||
  zookeeper_data:
 | 
					 | 
				
			||||||
    driver: local
 | 
					 | 
				
			||||||
  zookeeper_datalog:
 | 
					 | 
				
			||||||
    driver: local
 | 
					 | 
				
			||||||
  kafka_data:
 | 
					 | 
				
			||||||
    driver: local
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
services:
 | 
					 | 
				
			||||||
  postgresql:
 | 
					 | 
				
			||||||
    image: "postgres:${POSTGRES_TAG}"
 | 
					 | 
				
			||||||
    env_file:
 | 
					 | 
				
			||||||
      - .env_postgresql
 | 
					 | 
				
			||||||
    restart: unless-stopped
 | 
					 | 
				
			||||||
    volumes:
 | 
					 | 
				
			||||||
      - postgresql_data:/var/lib/postgresql/data
 | 
					 | 
				
			||||||
      - ./init-ucentralsec-db.sh:/docker-entrypoint-initdb.d/init-ucentralsec-db.sh
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  mysql:
 | 
					 | 
				
			||||||
    image: "mysql:${MYSQL_TAG}"
 | 
					 | 
				
			||||||
    env_file:
 | 
					 | 
				
			||||||
      - .env_mysql
 | 
					 | 
				
			||||||
    restart: unless-stopped
 | 
					 | 
				
			||||||
    command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
 | 
					 | 
				
			||||||
    volumes:
 | 
					 | 
				
			||||||
      - mysql_data:/var/lib/mysql
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ucentralgw.wlan.local:
 | 
					 | 
				
			||||||
    image: "tip-tip-wlan-cloud-ucentral.jfrog.io/ucentralgw:${UCENTRALGW_TAG}"
 | 
					 | 
				
			||||||
    env_file:
 | 
					 | 
				
			||||||
      - .env_ucentralgw
 | 
					 | 
				
			||||||
    depends_on: 
 | 
					 | 
				
			||||||
      - postgresql
 | 
					 | 
				
			||||||
      - kafka
 | 
					 | 
				
			||||||
      - rttys
 | 
					 | 
				
			||||||
    restart: unless-stopped
 | 
					 | 
				
			||||||
    ports:
 | 
					 | 
				
			||||||
      - "127.0.0.1:15002:15002"
 | 
					 | 
				
			||||||
      - "127.0.0.1:16002:16002"
 | 
					 | 
				
			||||||
      - "127.0.0.1:16003:16003"
 | 
					 | 
				
			||||||
      - "127.0.0.1:16102:16102"
 | 
					 | 
				
			||||||
    volumes:
 | 
					 | 
				
			||||||
      - ./ucentralgw-data:/ucentralgw-data
 | 
					 | 
				
			||||||
      - ./certs:/ucentralgw-data/certs
 | 
					 | 
				
			||||||
      - ../certificates/root.pem:/ucentralgw-data/certs/root.pem
 | 
					 | 
				
			||||||
      - ../certificates/issuer.pem:/ucentralgw-data/certs/issuer.pem
 | 
					 | 
				
			||||||
      - ../certificates/clientcas.pem:/ucentralgw-data/certs/clientcas.pem
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ucentralgw-ui:
 | 
					 | 
				
			||||||
    image: "tip-tip-wlan-cloud-ucentral.jfrog.io/ucentralgw-ui:${UCENTRALGWUI_TAG}"
 | 
					 | 
				
			||||||
    env_file:
 | 
					 | 
				
			||||||
      - .env_ucentralgw-ui
 | 
					 | 
				
			||||||
    depends_on:
 | 
					 | 
				
			||||||
      - ucentralgw.wlan.local
 | 
					 | 
				
			||||||
    restart: unless-stopped
 | 
					 | 
				
			||||||
    ports:
 | 
					 | 
				
			||||||
      - "127.0.0.1:80:80"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ucentralsec.wlan.local:
 | 
					 | 
				
			||||||
    image: "tip-tip-wlan-cloud-ucentral.jfrog.io/ucentralsec:${UCENTRALSEC_TAG}"
 | 
					 | 
				
			||||||
    env_file:
 | 
					 | 
				
			||||||
      - .env_ucentralsec
 | 
					 | 
				
			||||||
    depends_on: 
 | 
					 | 
				
			||||||
      - postgresql
 | 
					 | 
				
			||||||
      - kafka
 | 
					 | 
				
			||||||
      - rttys
 | 
					 | 
				
			||||||
      - ucentralgw.wlan.local
 | 
					 | 
				
			||||||
    restart: unless-stopped
 | 
					 | 
				
			||||||
    ports:
 | 
					 | 
				
			||||||
      - "127.0.0.1:16001:16001"
 | 
					 | 
				
			||||||
      - "127.0.0.1:16101:16101"
 | 
					 | 
				
			||||||
    volumes:
 | 
					 | 
				
			||||||
      - ./ucentralsec-data:/ucentralsec-data
 | 
					 | 
				
			||||||
      - ./certs:/ucentralsec-data/certs
 | 
					 | 
				
			||||||
      - ../certificates/root.pem:/ucentralsec-data/certs/root.pem
 | 
					 | 
				
			||||||
      - ../certificates/issuer.pem:/ucentralsec-data/certs/issuer.pem
 | 
					 | 
				
			||||||
      - ../certificates/clientcas.pem:/ucentralsec-data/certs/clientcas.pem
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  ucentralgw-ui:
 | 
					 | 
				
			||||||
    image: "tip-tip-wlan-cloud-ucentral.jfrog.io/ucentralgw-ui:${UCENTRALGWUI_TAG}"
 | 
					 | 
				
			||||||
    env_file:
 | 
					 | 
				
			||||||
      - .env_ucentralgw-ui
 | 
					 | 
				
			||||||
    depends_on:
 | 
					 | 
				
			||||||
      - ucentralgw
 | 
					 | 
				
			||||||
    restart: unless-stopped
 | 
					 | 
				
			||||||
    ports:
 | 
					 | 
				
			||||||
      - "127.0.0.1:80:80"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  rttys:
 | 
					 | 
				
			||||||
    image: "tip-tip-wlan-cloud-ucentral.jfrog.io/rttys:${RTTYS_TAG}"
 | 
					 | 
				
			||||||
    depends_on: 
 | 
					 | 
				
			||||||
      - mysql
 | 
					 | 
				
			||||||
    restart: unless-stopped
 | 
					 | 
				
			||||||
    volumes:
 | 
					 | 
				
			||||||
      - ./certs/restapi-cert.pem:/etc/rttys/restapi-cert.pem
 | 
					 | 
				
			||||||
      - ./certs/restapi-key.pem:/etc/rttys/restapi-key.pem
 | 
					 | 
				
			||||||
      - ./rttys/rttys.conf:/rttys/rttys.conf
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  zookeeper:
 | 
					 | 
				
			||||||
    image: "zookeeper:${ZOOKEEPER_TAG}"
 | 
					 | 
				
			||||||
    restart: unless-stopped
 | 
					 | 
				
			||||||
    volumes:
 | 
					 | 
				
			||||||
      - zookeeper_data:/data
 | 
					 | 
				
			||||||
      - zookeeper_datalog:/datalog
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  kafka:
 | 
					 | 
				
			||||||
    image: "docker.io/bitnami/kafka:${KAFKA_TAG}"
 | 
					 | 
				
			||||||
    env_file:
 | 
					 | 
				
			||||||
      - .env_kafka
 | 
					 | 
				
			||||||
    restart: unless-stopped
 | 
					 | 
				
			||||||
    depends_on:
 | 
					 | 
				
			||||||
      - zookeeper
 | 
					 | 
				
			||||||
    volumes:
 | 
					 | 
				
			||||||
      - kafka_data:/bitnami/kafka
 | 
					 | 
				
			||||||
@@ -1,8 +0,0 @@
 | 
				
			|||||||
#!/bin/bash
 | 
					 | 
				
			||||||
set -e
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
 | 
					 | 
				
			||||||
    CREATE USER $UCENTRALSEC_DB_USER WITH ENCRYPTED PASSWORD '$UCENTRALSEC_DB_PASSWORD';
 | 
					 | 
				
			||||||
    CREATE DATABASE $UCENTRALSEC_DB;
 | 
					 | 
				
			||||||
    GRANT ALL PRIVILEGES ON DATABASE $UCENTRALSEC_DB TO $UCENTRALSEC_DB_USER;
 | 
					 | 
				
			||||||
EOSQL
 | 
					 | 
				
			||||||
@@ -1,18 +0,0 @@
 | 
				
			|||||||
addr-dev: :5912
 | 
					 | 
				
			||||||
addr-user: :5913
 | 
					 | 
				
			||||||
#addr-web: :5914
 | 
					 | 
				
			||||||
#web-redir-url:# Auth for http
 | 
					 | 
				
			||||||
http-username: rttys
 | 
					 | 
				
			||||||
http-password: rttys
 | 
					 | 
				
			||||||
ssl-cert: /etc/rttys/restapi-cert.pem
 | 
					 | 
				
			||||||
ssl-key: /etc/rttys/restapi-key.pem
 | 
					 | 
				
			||||||
token: 96181c567b4d0d98c50f127230068fa8
 | 
					 | 
				
			||||||
# font-size: 16
 | 
					 | 
				
			||||||
# No login required to connect device.
 | 
					 | 
				
			||||||
# Values can be device IDs separated by spaces,
 | 
					 | 
				
			||||||
# or a "*" indicates that all devices do not require login
 | 
					 | 
				
			||||||
# http://localhost:5913/connect/rtty1
 | 
					 | 
				
			||||||
white-list: "*"
 | 
					 | 
				
			||||||
#white-list: rtty1 rtty2
 | 
					 | 
				
			||||||
# mysql database source
 | 
					 | 
				
			||||||
db: rttys:rttys@tcp(mysql)/rttys
 | 
					 | 
				
			||||||
@@ -1,181 +0,0 @@
 | 
				
			|||||||
#
 | 
					 | 
				
			||||||
# uCentral protocol server for devices. This is where you point
 | 
					 | 
				
			||||||
# all your devices. You can replace the * for address by the specific
 | 
					 | 
				
			||||||
# address of one of your interfaces
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
ucentral.websocket.host.0.backlog = 500
 | 
					 | 
				
			||||||
ucentral.websocket.host.0.rootca = $UCENTRALGW_ROOT/certs/root.pem
 | 
					 | 
				
			||||||
ucentral.websocket.host.0.issuer = $UCENTRALGW_ROOT/certs/issuer.pem
 | 
					 | 
				
			||||||
ucentral.websocket.host.0.cert = $UCENTRALGW_ROOT/certs/websocket-cert.pem
 | 
					 | 
				
			||||||
ucentral.websocket.host.0.key = $UCENTRALGW_ROOT/certs/websocket-key.pem
 | 
					 | 
				
			||||||
ucentral.websocket.host.0.clientcas = $UCENTRALGW_ROOT/certs/clientcas.pem
 | 
					 | 
				
			||||||
ucentral.websocket.host.0.cas = $UCENTRALGW_ROOT/certs/cas
 | 
					 | 
				
			||||||
ucentral.websocket.host.0.address = *
 | 
					 | 
				
			||||||
ucentral.websocket.host.0.port = 15002
 | 
					 | 
				
			||||||
ucentral.websocket.host.0.security = strict
 | 
					 | 
				
			||||||
ucentral.websocket.host.0.key.password = mypassword
 | 
					 | 
				
			||||||
ucentral.websocket.maxreactors = 20
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# REST API access
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.backlog = 100
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.security = relaxed
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.rootca = $UCENTRALGW_ROOT/certs/restapi-ca.pem
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.address = *
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.port = 16002
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.cert = $UCENTRALGW_ROOT/certs/restapi-cert.pem
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.key.password = mypassword
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.backlog = 100
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.security = relaxed
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.rootca = $UCENTRALGW_ROOT/certs/restapi-ca.pem
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.address = *
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.port = 17002
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.cert = $UCENTRALGW_ROOT/certs/restapi-cert.pem
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.key.password = mypassword
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Used to upload files to the service.
 | 
					 | 
				
			||||||
# You should replace the 'name' vaalue with the IP address of your gateway or an FQDN
 | 
					 | 
				
			||||||
# that your devices can reach
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
ucentral.fileuploader.host.0.backlog = 100
 | 
					 | 
				
			||||||
ucentral.fileuploader.host.0.rootca = $UCENTRALGW_ROOT/certs/restapi-ca.pem
 | 
					 | 
				
			||||||
ucentral.fileuploader.host.0.security = relaxed
 | 
					 | 
				
			||||||
ucentral.fileuploader.host.0.address = *
 | 
					 | 
				
			||||||
ucentral.fileuploader.host.0.name = ucentral.wlan.local
 | 
					 | 
				
			||||||
ucentral.fileuploader.host.0.port = 16003
 | 
					 | 
				
			||||||
ucentral.fileuploader.host.0.cert = $UCENTRALGW_ROOT/certs/restapi-cert.pem
 | 
					 | 
				
			||||||
ucentral.fileuploader.host.0.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
 | 
					 | 
				
			||||||
ucentral.fileuploader.host.0.key.password = mypassword
 | 
					 | 
				
			||||||
ucentral.fileuploader.path = $UCENTRALGW_ROOT/uploads
 | 
					 | 
				
			||||||
ucentral.fileuploader.maxsize = 10000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Generic section that all microservices must have
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
ucentral.service.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
 | 
					 | 
				
			||||||
ucentral.system.data = $UCENTRALGW_ROOT/data
 | 
					 | 
				
			||||||
ucentral.system.debug = true
 | 
					 | 
				
			||||||
ucentral.system.uri.private = https://ucentralgw.wlan.local:17002
 | 
					 | 
				
			||||||
ucentral.system.uri.public = https://ucentral.wlan.local:16002
 | 
					 | 
				
			||||||
ucentral.system.commandchannel = /tmp/app.ucentralgw
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Gateway Microservice Specific Section
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
ucentral.autoprovisioning = true
 | 
					 | 
				
			||||||
ucentral.devicetypes.0 = AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
 | 
					 | 
				
			||||||
ucentral.devicetypes.1 = SWITCH:edgecore_ecs4100-12ph
 | 
					 | 
				
			||||||
ucentral.devicetypes.2 = IOT:esp32
 | 
					 | 
				
			||||||
oui.download.uri = https://linuxnet.ca/ieee/oui.txt
 | 
					 | 
				
			||||||
firmware.autoupdate.policy.default = auto
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# rtty
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
rtty.enabled = true
 | 
					 | 
				
			||||||
rtty.server = rttys
 | 
					 | 
				
			||||||
rtty.port = 5912
 | 
					 | 
				
			||||||
rtty.token = 96181c567b4d0d98c50f127230068fa8
 | 
					 | 
				
			||||||
rtty.timeout = 60
 | 
					 | 
				
			||||||
rtty.viewport = 5913
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#############################
 | 
					 | 
				
			||||||
# Generic information for all micro services
 | 
					 | 
				
			||||||
#############################
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# NLB Support
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
alb.enable = true
 | 
					 | 
				
			||||||
alb.port = 16102
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
oui.download.uri = https://linuxnet.ca/ieee/oui.txt
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Kafka
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
ucentral.kafka.group.id = gateway
 | 
					 | 
				
			||||||
ucentral.kafka.client.id = gateway1
 | 
					 | 
				
			||||||
ucentral.kafka.enable = true
 | 
					 | 
				
			||||||
# ucentral.kafka.brokerlist = a1.arilia.com:9092
 | 
					 | 
				
			||||||
ucentral.kafka.brokerlist = kafka:9092
 | 
					 | 
				
			||||||
ucentral.kafka.auto.commit = false
 | 
					 | 
				
			||||||
ucentral.kafka.queue.buffering.max.ms = 50
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# This section select which form of persistence you need
 | 
					 | 
				
			||||||
# Only one selected at a time. If you select multiple, this service will die if a horrible
 | 
					 | 
				
			||||||
# death and might make your beer flat.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
#storage.type = sqlite
 | 
					 | 
				
			||||||
storage.type = postgresql
 | 
					 | 
				
			||||||
#storage.type = mysql
 | 
					 | 
				
			||||||
#storage.type = odbc
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
storage.type.sqlite.db = devices.db
 | 
					 | 
				
			||||||
storage.type.sqlite.idletime = 120
 | 
					 | 
				
			||||||
storage.type.sqlite.maxsessions = 128
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
storage.type.postgresql.maxsessions = 64
 | 
					 | 
				
			||||||
storage.type.postgresql.idletime = 60
 | 
					 | 
				
			||||||
storage.type.postgresql.host = postgresql
 | 
					 | 
				
			||||||
storage.type.postgresql.username = ucentralgw
 | 
					 | 
				
			||||||
storage.type.postgresql.password = ucentralgw
 | 
					 | 
				
			||||||
storage.type.postgresql.database = ucentralgw
 | 
					 | 
				
			||||||
storage.type.postgresql.port = 5432
 | 
					 | 
				
			||||||
storage.type.postgresql.connectiontimeout = 60
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
storage.type.mysql.maxsessions = 64
 | 
					 | 
				
			||||||
storage.type.mysql.idletime = 60
 | 
					 | 
				
			||||||
storage.type.mysql.host = localhost
 | 
					 | 
				
			||||||
storage.type.mysql.username = stephb
 | 
					 | 
				
			||||||
storage.type.mysql.password = snoopy99
 | 
					 | 
				
			||||||
storage.type.mysql.database = ucentral
 | 
					 | 
				
			||||||
storage.type.mysql.port = 3306
 | 
					 | 
				
			||||||
storage.type.mysql.connectiontimeout = 60
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
########################################################################
 | 
					 | 
				
			||||||
########################################################################
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Logging: please leave as is for now.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
########################################################################
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
logging.formatters.f1.class = PatternFormatter
 | 
					 | 
				
			||||||
logging.formatters.f1.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t
 | 
					 | 
				
			||||||
logging.formatters.f1.times = UTC
 | 
					 | 
				
			||||||
logging.channels.c1.class = ConsoleChannel
 | 
					 | 
				
			||||||
logging.channels.c1.formatter = f1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# This is where the logs will be written. This path MUST exist
 | 
					 | 
				
			||||||
logging.channels.c2.class = FileChannel
 | 
					 | 
				
			||||||
logging.channels.c2.path = $UCENTRALGW_ROOT/logs/log
 | 
					 | 
				
			||||||
logging.channels.c2.formatter.class = PatternFormatter
 | 
					 | 
				
			||||||
logging.channels.c2.formatter.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t
 | 
					 | 
				
			||||||
logging.channels.c2.rotation = 20 M
 | 
					 | 
				
			||||||
logging.channels.c2.archive = timestamp
 | 
					 | 
				
			||||||
logging.channels.c2.purgeCount = 20
 | 
					 | 
				
			||||||
logging.channels.c3.class = ConsoleChannel
 | 
					 | 
				
			||||||
logging.channels.c3.pattern = %s: [%p] %t
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# External Channel
 | 
					 | 
				
			||||||
logging.loggers.root.channel = c1
 | 
					 | 
				
			||||||
logging.loggers.root.level = debug
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Inline Channel with PatternFormatter
 | 
					 | 
				
			||||||
# logging.loggers.l1.name = logger1
 | 
					 | 
				
			||||||
# logging.loggers.l1.channel.class = ConsoleChannel
 | 
					 | 
				
			||||||
# logging.loggers.l1.channel.pattern = %s: [%p] %t
 | 
					 | 
				
			||||||
# logging.loggers.l1.level = information
 | 
					 | 
				
			||||||
# SplitterChannel
 | 
					 | 
				
			||||||
# logging.channels.splitter.class = SplitterChannel
 | 
					 | 
				
			||||||
# logging.channels.splitter.channels = l1,l2
 | 
					 | 
				
			||||||
# logging.loggers.l2.name = logger2
 | 
					 | 
				
			||||||
# logging.loggers.l2.channel = splitter
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,145 +0,0 @@
 | 
				
			|||||||
#
 | 
					 | 
				
			||||||
# uCentral protocol server for devices. This is where you point
 | 
					 | 
				
			||||||
# all your devices. You can replace the * for address by the specific
 | 
					 | 
				
			||||||
# address of one of your interfaces
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# REST API access
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.backlog = 100
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.security = relaxed
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.rootca = $UCENTRALSEC_ROOT/certs/restapi-ca.pem
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.address = *
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.port = 16001
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.cert = $UCENTRALSEC_ROOT/certs/restapi-cert.pem
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.key = $UCENTRALSEC_ROOT/certs/restapi-key.pem
 | 
					 | 
				
			||||||
ucentral.restapi.host.0.key.password = mypassword
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.backlog = 100
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.security = relaxed
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.rootca = $UCENTRALSEC_ROOT/certs/restapi-ca.pem
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.address = *
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.port = 17001
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.cert = $UCENTRALSEC_ROOT/certs/restapi-cert.pem
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.key = $UCENTRALSEC_ROOT/certs/restapi-key.pem
 | 
					 | 
				
			||||||
ucentral.internal.restapi.host.0.key.password = mypassword
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Generic section that all microservices must have
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
authentication.enabled = true
 | 
					 | 
				
			||||||
authentication.default.username = tip@ucentral.com
 | 
					 | 
				
			||||||
authentication.default.password = 13268b7daa751240369d125e79c873bd8dd3bef7981bdfd38ea03dbb1fbe7dcf
 | 
					 | 
				
			||||||
authentication.default.access = master
 | 
					 | 
				
			||||||
authentication.service.type = internal
 | 
					 | 
				
			||||||
ucentral.system.data = $UCENTRALSEC_ROOT/data
 | 
					 | 
				
			||||||
ucentral.system.debug = true
 | 
					 | 
				
			||||||
ucentral.system.uri.private = https://ucentralsec.wlan.local:17001
 | 
					 | 
				
			||||||
ucentral.system.uri.public = https://ucentral.wlan.local:16001
 | 
					 | 
				
			||||||
ucentral.system.commandchannel = /tmp/app.ucentralsec
 | 
					 | 
				
			||||||
ucentral.service.key = $UCENTRALSEC_ROOT/certs/restapi-key.pem
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Security Microservice Specific Section
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
mailer.hostname = smtp.gmail.com
 | 
					 | 
				
			||||||
mailer.username = no-reply@arilia.com
 | 
					 | 
				
			||||||
mailer.password = **************************
 | 
					 | 
				
			||||||
mailer.loginmethod = login
 | 
					 | 
				
			||||||
mailer.port = 587
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#############################
 | 
					 | 
				
			||||||
# Generic information for all micro services
 | 
					 | 
				
			||||||
#############################
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# NLB Support
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
alb.enable = true
 | 
					 | 
				
			||||||
alb.port = 16101
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Kafka
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
ucentral.kafka.group.id = security
 | 
					 | 
				
			||||||
ucentral.kafka.client.id = security1
 | 
					 | 
				
			||||||
ucentral.kafka.enable = true
 | 
					 | 
				
			||||||
# ucentral.kafka.brokerlist = a1.arilia.com:9092
 | 
					 | 
				
			||||||
ucentral.kafka.brokerlist = kafka:9092
 | 
					 | 
				
			||||||
ucentral.kafka.auto.commit = false
 | 
					 | 
				
			||||||
ucentral.kafka.queue.buffering.max.ms = 50
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# This section select which form of persistence you need
 | 
					 | 
				
			||||||
# Only one selected at a time. If you select multiple, this service will die if a horrible
 | 
					 | 
				
			||||||
# death and might make your beer flat.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
#storage.type = sqlite
 | 
					 | 
				
			||||||
storage.type = postgresql
 | 
					 | 
				
			||||||
#storage.type = mysql
 | 
					 | 
				
			||||||
#storage.type = odbc
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
storage.type.sqlite.db = security.db
 | 
					 | 
				
			||||||
storage.type.sqlite.idletime = 120
 | 
					 | 
				
			||||||
storage.type.sqlite.maxsessions = 128
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
storage.type.postgresql.maxsessions = 64
 | 
					 | 
				
			||||||
storage.type.postgresql.idletime = 60
 | 
					 | 
				
			||||||
storage.type.postgresql.host = postgresql
 | 
					 | 
				
			||||||
storage.type.postgresql.username = ucentralsec
 | 
					 | 
				
			||||||
storage.type.postgresql.password = ucentralsec
 | 
					 | 
				
			||||||
storage.type.postgresql.database = ucentralsec
 | 
					 | 
				
			||||||
storage.type.postgresql.port = 5432
 | 
					 | 
				
			||||||
storage.type.postgresql.connectiontimeout = 60
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
storage.type.mysql.maxsessions = 64
 | 
					 | 
				
			||||||
storage.type.mysql.idletime = 60
 | 
					 | 
				
			||||||
storage.type.mysql.host = localhost
 | 
					 | 
				
			||||||
storage.type.mysql.username = stephb
 | 
					 | 
				
			||||||
storage.type.mysql.password = snoopy99
 | 
					 | 
				
			||||||
storage.type.mysql.database = ucentral
 | 
					 | 
				
			||||||
storage.type.mysql.port = 3306
 | 
					 | 
				
			||||||
storage.type.mysql.connectiontimeout = 60
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
########################################################################
 | 
					 | 
				
			||||||
########################################################################
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
# Logging: please leave as is for now.
 | 
					 | 
				
			||||||
#
 | 
					 | 
				
			||||||
########################################################################
 | 
					 | 
				
			||||||
logging.formatters.f1.class = PatternFormatter
 | 
					 | 
				
			||||||
logging.formatters.f1.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t
 | 
					 | 
				
			||||||
logging.formatters.f1.times = UTC
 | 
					 | 
				
			||||||
logging.channels.c1.class = ConsoleChannel
 | 
					 | 
				
			||||||
logging.channels.c1.formatter = f1
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# This is where the logs will be written. This path MUST exist
 | 
					 | 
				
			||||||
logging.channels.c2.class = FileChannel
 | 
					 | 
				
			||||||
logging.channels.c2.path = $UCENTRALSEC_ROOT/logs/log
 | 
					 | 
				
			||||||
logging.channels.c2.formatter.class = PatternFormatter
 | 
					 | 
				
			||||||
logging.channels.c2.formatter.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t
 | 
					 | 
				
			||||||
logging.channels.c2.rotation = 20 M
 | 
					 | 
				
			||||||
logging.channels.c2.archive = timestamp
 | 
					 | 
				
			||||||
logging.channels.c2.purgeCount = 20
 | 
					 | 
				
			||||||
logging.channels.c3.class = ConsoleChannel
 | 
					 | 
				
			||||||
logging.channels.c3.pattern = %s: [%p] %t
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# External Channel
 | 
					 | 
				
			||||||
logging.loggers.root.channel = c1
 | 
					 | 
				
			||||||
logging.loggers.root.level = debug
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Inline Channel with PatternFormatter
 | 
					 | 
				
			||||||
# logging.loggers.l1.name = logger1
 | 
					 | 
				
			||||||
# logging.loggers.l1.channel.class = ConsoleChannel
 | 
					 | 
				
			||||||
# logging.loggers.l1.channel.pattern = %s: [%p] %t
 | 
					 | 
				
			||||||
# logging.loggers.l1.level = information
 | 
					 | 
				
			||||||
# SplitterChannel
 | 
					 | 
				
			||||||
# logging.channels.splitter.class = SplitterChannel
 | 
					 | 
				
			||||||
# logging.channels.splitter.channels = l1,l2
 | 
					 | 
				
			||||||
# logging.loggers.l2.name = logger2
 | 
					 | 
				
			||||||
# logging.loggers.l2.channel = splitter
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
							
								
								
									
										11
									
								
								docker-entrypoint.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										11
									
								
								docker-entrypoint.sh
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					set -e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ "$1" = '/ucentral/ucentralgw' -a "$(id -u)" = '0' ]; then
 | 
				
			||||||
 | 
					    if [ "$RUN_CHOWN" = 'true' ]; then
 | 
				
			||||||
 | 
					      chown -R "$UCENTRALGW_USER": "$UCENTRALGW_ROOT" "$UCENTRALGW_CONFIG"
 | 
				
			||||||
 | 
					    fi
 | 
				
			||||||
 | 
					    exec su-exec "$UCENTRALGW_USER" "$@"
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exec "$@"
 | 
				
			||||||
							
								
								
									
										104
									
								
								helm/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								helm/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
				
			|||||||
 | 
					# ucentralgw
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This Helm chart helps to deploy uCentralGW to the Kubernetes clusters. It is mainly used in [assembly chart](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/main/chart) as uCentralGW requires other services as dependencies that are considered in that Helm chart. This chart is purposed to define deployment logic close to the application code itself and define default values that could be overriden during deployment.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## TL;DR;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					$ helm install .
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Introduction
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This chart bootstraps an ucentralgw on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Installing the Chart
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Currently this chart is not assembled in charts archives, so [helm-git](https://github.com/aslafy-z/helm-git) is required for remote the installation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To install the chart with the release name `my-release`:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					$ helm install --name my-release git+https://github.com/Telecominfraproject/wlan-cloud-ucentralgw@helm?ref=master
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The command deploys ucentralgw on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> **Tip**: List all releases using `helm list`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Uninstalling the Chart
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To uninstall/delete the `my-release` deployment:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					$ helm delete my-release
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The command removes all the Kubernetes components associated with the chart and deletes the release.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Configuration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The following table lists the configurable parameters of the chart and their default values. If Default value is not listed in the table, please refer to the [Values](values.yaml) files for details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					| Parameter | Type | Description | Default |
 | 
				
			||||||
 | 
					|-----------|------|-------------|---------|
 | 
				
			||||||
 | 
					| replicaCount | number | Amount of replicas to be deployed | `1` |
 | 
				
			||||||
 | 
					| strategyType | string | Application deployment strategy | `'Recreate'` |
 | 
				
			||||||
 | 
					| nameOverride | string | Override to be used for application deployment |  |
 | 
				
			||||||
 | 
					| fullnameOverride | string | Override to be used for application deployment (has priority over nameOverride) |  |
 | 
				
			||||||
 | 
					| images.ucentralgw.repository | string | Docker image repository |  |
 | 
				
			||||||
 | 
					| images.ucentralgw.tag | string | Docker image tag | `'master'` |
 | 
				
			||||||
 | 
					| images.ucentralgw.pullPolicy | string | Docker image pull policy | `'Always'` |
 | 
				
			||||||
 | 
					| services.ucentralgw.type | string | uCentralGW service type | `'LoadBalancer'` |
 | 
				
			||||||
 | 
					| services.ucentralgw.ports.websocket.servicePort | number | Websocket endpoint port to be exposed on service | `15002` |
 | 
				
			||||||
 | 
					| services.ucentralgw.ports.websocket.targetPort | number | Websocket endpoint port to be targeted by service | `15002` |
 | 
				
			||||||
 | 
					| services.ucentralgw.ports.websocket.protocol | string | Websocket endpoint protocol | `'TCP'` |
 | 
				
			||||||
 | 
					| services.ucentralgw.ports.restapi.servicePort | number | REST API endpoint port to be exposed on service | `16002` |
 | 
				
			||||||
 | 
					| services.ucentralgw.ports.restapi.targetPort | number | REST API endpoint port to be targeted by service | `16002` |
 | 
				
			||||||
 | 
					| services.ucentralgw.ports.restapi.protocol | string | REST API endpoint protocol | `'TCP'` |
 | 
				
			||||||
 | 
					| services.ucentralgw.ports.restapiinternal.servicePort | string | Internal REST API endpoint port to be exposed on service | `17002` |
 | 
				
			||||||
 | 
					| services.ucentralgw.ports.restapiinternal.targetPort | number | Internal REST API endpoint port to be targeted by service | `17002` |
 | 
				
			||||||
 | 
					| services.ucentralgw.ports.restapiinternal.protocol | string | Internal REST API endpoint protocol | `'TCP'` |
 | 
				
			||||||
 | 
					| services.ucentralgw.ports.fileuploader.servicePort | string | Fileuploader endpoint port to be exposed on service | `16003` |
 | 
				
			||||||
 | 
					| services.ucentralgw.ports.fileuploader.targetPort | number | Fileuploader endpoint port to be targeted by service | `16003` |
 | 
				
			||||||
 | 
					| services.ucentralgw.ports.fileuploader.protocol | string | Fileuploader endpoint protocol | `'TCP'` |
 | 
				
			||||||
 | 
					| checks.ucentralgw.liveness.httpGet.path | string | Liveness check path to be used | `'/'` |
 | 
				
			||||||
 | 
					| checks.ucentralgw.liveness.httpGet.port | number | Liveness check port to be used (should be pointint to ALB endpoint) | `16102` |
 | 
				
			||||||
 | 
					| checks.ucentralgw.readiness.httpGet.path | string | Readiness check path to be used | `'/'` |
 | 
				
			||||||
 | 
					| checks.ucentralgw.readiness.httpGet.port | number | Readiness check port to be used (should be pointint to ALB endpoint) | `16102` |
 | 
				
			||||||
 | 
					| ingresses.restapi.enabled | boolean | Defines if REST API endpoint should be exposed via Ingress controller | `False` |
 | 
				
			||||||
 | 
					| ingresses.restapi.hosts | array | List of hosts for exposed REST API |  |
 | 
				
			||||||
 | 
					| ingresses.restapi.paths | array | List of paths to be exposed for REST API |  |
 | 
				
			||||||
 | 
					| ingresses.fileuploader.enabled | boolean | Defines if Fileuploader endpoint should be exposed via Ingress controller | `False` |
 | 
				
			||||||
 | 
					| ingresses.fileuploader.hosts | array | List of hosts for exposed Fileuploader |  |
 | 
				
			||||||
 | 
					| ingresses.fileuploader.paths | array | List of paths for exposed Fileuploader |  |
 | 
				
			||||||
 | 
					| volumes.ucentralgw | array | Defines list of volumes to be attached to uCentralGW |  |
 | 
				
			||||||
 | 
					| persistence.enabled | boolean | Defines if uCentralGW requires Persistent Volume (required for permanent files storage and SQLite DB if enabled) | `True` |
 | 
				
			||||||
 | 
					| persistence.accessModes | array | Defines PV access modes |  |
 | 
				
			||||||
 | 
					| persistence.size | string | Defines PV size | `'10Gi'` |
 | 
				
			||||||
 | 
					| public_env_variables | hash | Defines list of environment variables to be passed to uCentralGW | |
 | 
				
			||||||
 | 
					| configProperties | hash | Configuration properties that should be passed to the application in `ucentralgw.properties`. May be passed by key in set (i.e. `configProperties."rtty\.token"`) | |
 | 
				
			||||||
 | 
					| certs | hash | Defines files (keys and certificates) that should be passed to uCentralGW (PEM format is adviced to be used) (see `volumes.ucentralgw` on where it is mounted) |  |
 | 
				
			||||||
 | 
					| certsCAs | hash | Defines files with CAs that should be passed to uCentralGW (see `volumes.ucentralgw` on where it is mounted) |  |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					$ helm install --name my-release \
 | 
				
			||||||
 | 
					  --set replicaCount=1 \
 | 
				
			||||||
 | 
					    .
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above command sets that only 1 instance of your app should be running
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```bash
 | 
				
			||||||
 | 
					$ helm install --name my-release -f values.yaml .
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					> **Tip**: You can use the default [values.yaml](values.yaml) as a base for customization.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -8,7 +8,7 @@ fullnameOverride: ""
 | 
				
			|||||||
images:
 | 
					images:
 | 
				
			||||||
  ucentralgw:
 | 
					  ucentralgw:
 | 
				
			||||||
    repository: tip-tip-wlan-cloud-ucentral.jfrog.io/ucentralgw
 | 
					    repository: tip-tip-wlan-cloud-ucentral.jfrog.io/ucentralgw
 | 
				
			||||||
    tag: master
 | 
					    tag: v2.0.0-RC1
 | 
				
			||||||
    pullPolicy: Always
 | 
					    pullPolicy: Always
 | 
				
			||||||
#    regcred:
 | 
					#    regcred:
 | 
				
			||||||
#      registry: tip-tip-wlan-cloud-ucentral.jfrog.io
 | 
					#      registry: tip-tip-wlan-cloud-ucentral.jfrog.io
 | 
				
			||||||
@@ -232,7 +232,7 @@ configProperties:
 | 
				
			|||||||
  logging.channels.c1.class: ConsoleChannel
 | 
					  logging.channels.c1.class: ConsoleChannel
 | 
				
			||||||
  logging.channels.c1.formatter: f1
 | 
					  logging.channels.c1.formatter: f1
 | 
				
			||||||
  logging.channels.c2.class: FileChannel
 | 
					  logging.channels.c2.class: FileChannel
 | 
				
			||||||
  logging.channels.c2.path: /dev/stdout
 | 
					  logging.channels.c2.path: /tmp/log_ucentralgw
 | 
				
			||||||
  logging.channels.c2.formatter.class: PatternFormatter
 | 
					  logging.channels.c2.formatter.class: PatternFormatter
 | 
				
			||||||
  logging.channels.c2.formatter.pattern: "%Y-%m-%d %H:%M:%S %s: [%p] %t"
 | 
					  logging.channels.c2.formatter.pattern: "%Y-%m-%d %H:%M:%S %s: [%p] %t"
 | 
				
			||||||
  logging.channels.c2.rotation: "20 M"
 | 
					  logging.channels.c2.rotation: "20 M"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ openapi: 3.0.1
 | 
				
			|||||||
info:
 | 
					info:
 | 
				
			||||||
  title: uCentral gateway API
 | 
					  title: uCentral gateway API
 | 
				
			||||||
  description: A process to manage configuration for devices.
 | 
					  description: A process to manage configuration for devices.
 | 
				
			||||||
  version: 0.0.8
 | 
					  version: 2.0.0
 | 
				
			||||||
  license:
 | 
					  license:
 | 
				
			||||||
    name: BSD3
 | 
					    name: BSD3
 | 
				
			||||||
    url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
 | 
					    url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
 | 
				
			||||||
@@ -581,6 +581,36 @@ components:
 | 
				
			|||||||
          items:
 | 
					          items:
 | 
				
			||||||
            $ref: '#/components/schemas/CommandInfo'
 | 
					            $ref: '#/components/schemas/CommandInfo'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DeviceDashboard:
 | 
				
			||||||
 | 
					      type: object
 | 
				
			||||||
 | 
					      properties:
 | 
				
			||||||
 | 
					        commands:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/TagIntPairList'
 | 
				
			||||||
 | 
					        upTimes:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/TagIntPairList'
 | 
				
			||||||
 | 
					        memoryUsed:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/TagIntPairList'
 | 
				
			||||||
 | 
					        load1:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/TagIntPairList'
 | 
				
			||||||
 | 
					        load5:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/TagIntPairList'
 | 
				
			||||||
 | 
					        load15:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/TagIntPairList'
 | 
				
			||||||
 | 
					        vendors:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/TagIntPairList'
 | 
				
			||||||
 | 
					        status:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/TagIntPairList'
 | 
				
			||||||
 | 
					        type:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/TagIntPairList'
 | 
				
			||||||
 | 
					        deviceType:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/TagIntPairList'
 | 
				
			||||||
 | 
					        healths:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/TagIntPairList'
 | 
				
			||||||
 | 
					        certificates:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/TagIntPairList'
 | 
				
			||||||
 | 
					        lastContact:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/TagIntPairList'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #########################################################################################
 | 
					    #########################################################################################
 | 
				
			||||||
    ##
 | 
					    ##
 | 
				
			||||||
    ## These are endpoints that all services in the uCentral stack must provide
 | 
					    ## These are endpoints that all services in the uCentral stack must provide
 | 
				
			||||||
@@ -616,6 +646,23 @@ components:
 | 
				
			|||||||
          items:
 | 
					          items:
 | 
				
			||||||
            $ref: '#/components/schemas/TagValuePair'
 | 
					            $ref: '#/components/schemas/TagValuePair'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TagIntPair:
 | 
				
			||||||
 | 
					      type: object
 | 
				
			||||||
 | 
					      properties:
 | 
				
			||||||
 | 
					        tag:
 | 
				
			||||||
 | 
					          type: string
 | 
				
			||||||
 | 
					        value:
 | 
				
			||||||
 | 
					          type: integer
 | 
				
			||||||
 | 
					          format: int64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    TagIntPairList:
 | 
				
			||||||
 | 
					      type: object
 | 
				
			||||||
 | 
					      properties:
 | 
				
			||||||
 | 
					        tagList:
 | 
				
			||||||
 | 
					          type: array
 | 
				
			||||||
 | 
					          items:
 | 
				
			||||||
 | 
					            $ref: '#/components/schemas/TagIntPair'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SystemCommandDetails:
 | 
					    SystemCommandDetails:
 | 
				
			||||||
      type: object
 | 
					      type: object
 | 
				
			||||||
      properties:
 | 
					      properties:
 | 
				
			||||||
@@ -1993,6 +2040,20 @@ paths:
 | 
				
			|||||||
        404:
 | 
					        404:
 | 
				
			||||||
          $ref: '#/components/responses/NotFound'
 | 
					          $ref: '#/components/responses/NotFound'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  /deviceDashboard:
 | 
				
			||||||
 | 
					    get:
 | 
				
			||||||
 | 
					      tags:
 | 
				
			||||||
 | 
					        - Dashboards
 | 
				
			||||||
 | 
					      summary: Get the last version of the dashboard
 | 
				
			||||||
 | 
					      operationId: getDeviceDashboard
 | 
				
			||||||
 | 
					      responses:
 | 
				
			||||||
 | 
					        200:
 | 
				
			||||||
 | 
					          $ref: '#/components/schemas/DeviceDashboard'
 | 
				
			||||||
 | 
					        403:
 | 
				
			||||||
 | 
					          $ref: '#/components/responses/Unauthorized'
 | 
				
			||||||
 | 
					        404:
 | 
				
			||||||
 | 
					          $ref: '#/components/responses/NotFound'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  #########################################################################################
 | 
					  #########################################################################################
 | 
				
			||||||
  ##
 | 
					  ##
 | 
				
			||||||
  ## These are endpoints that all services in the uCentral stack must provide
 | 
					  ## These are endpoints that all services in the uCentral stack must provide
 | 
				
			||||||
@@ -2022,53 +2083,30 @@ paths:
 | 
				
			|||||||
          $ref: '#/components/responses/Unauthorized'
 | 
					          $ref: '#/components/responses/Unauthorized'
 | 
				
			||||||
        404:
 | 
					        404:
 | 
				
			||||||
          $ref: '#/components/responses/NotFound'
 | 
					          $ref: '#/components/responses/NotFound'
 | 
				
			||||||
 | 
					    get:
 | 
				
			||||||
  /callbackChannel:
 | 
					 | 
				
			||||||
    post:
 | 
					 | 
				
			||||||
      tags:
 | 
					      tags:
 | 
				
			||||||
        - Callback
 | 
					        - System Commands
 | 
				
			||||||
      summary: Generic callback hook
 | 
					      summary: Retrieve different values from the running service.
 | 
				
			||||||
      operationId: postCallback
 | 
					      operationId: getSystemCommand
 | 
				
			||||||
      parameters:
 | 
					      parameters:
 | 
				
			||||||
        - in: query
 | 
					        - in: query
 | 
				
			||||||
          name: subscribe
 | 
					          description: Get a value
 | 
				
			||||||
          schema:
 | 
					          name: command
 | 
				
			||||||
            type: boolean
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: uri
 | 
					 | 
				
			||||||
          schema:
 | 
					          schema:
 | 
				
			||||||
            type: string
 | 
					            type: string
 | 
				
			||||||
            format: uri
 | 
					            enum:
 | 
				
			||||||
        - in: query
 | 
					              - version
 | 
				
			||||||
          name: key
 | 
					              - times
 | 
				
			||||||
          schema:
 | 
					          required: true
 | 
				
			||||||
            type: string
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: topics
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: string
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: id
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: string
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: topic
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: string
 | 
					 | 
				
			||||||
      requestBody:
 | 
					 | 
				
			||||||
        description: A generic JSONDocument, may be empty too {}
 | 
					 | 
				
			||||||
        required: true
 | 
					 | 
				
			||||||
        content:
 | 
					 | 
				
			||||||
          application/json:
 | 
					 | 
				
			||||||
            schema:
 | 
					 | 
				
			||||||
              $ref: '#/components/schemas/AnyPayload'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
      responses:
 | 
					      responses:
 | 
				
			||||||
        200:
 | 
					        200:
 | 
				
			||||||
          $ref: '#/components/responses/Success'
 | 
					          description: Successfull command execution
 | 
				
			||||||
 | 
					          content:
 | 
				
			||||||
 | 
					            application/json:
 | 
				
			||||||
 | 
					              schema:
 | 
				
			||||||
 | 
					                $ref: '#/components/schemas/TagValuePair'
 | 
				
			||||||
        403:
 | 
					        403:
 | 
				
			||||||
          $ref: '#/components/responses/Unauthorized'
 | 
					          $ref: '#/components/responses/Unauthorized'
 | 
				
			||||||
        404:
 | 
					        404:
 | 
				
			||||||
          $ref: '#/components/responses/NotFound'
 | 
					          $ref: '#/components/responses/NotFound'
 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,170 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
//	License type: BSD 3-Clause License
 | 
					 | 
				
			||||||
//	License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	Created by Stephane Bourque on 2021-03-04.
 | 
					 | 
				
			||||||
//	Arilia Wireless Inc.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "CallbackManager.h"
 | 
					 | 
				
			||||||
#include "Daemon.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPClientSession.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPSClientSession.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPRequest.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPResponse.h"
 | 
					 | 
				
			||||||
#include "Poco/URI.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace uCentral {
 | 
					 | 
				
			||||||
	class CallbackManager *CallbackManager::instance_ = nullptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	CallbackManager::CallbackManager() noexcept:
 | 
					 | 
				
			||||||
	  SubSystemServer("CallbackManager", "CBACK-MGR", "ucentral.callback")
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int CallbackManager::Start() {
 | 
					 | 
				
			||||||
		Logger_.notice("Starting...");
 | 
					 | 
				
			||||||
		Mgr_.start(*this);
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool CallbackManager::InitHosts() {
 | 
					 | 
				
			||||||
		// get all the hosts we are registering with and register ourselves...
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if(Daemon()->ConfigGetString("ucentral.callback.enable","false") == "false") {
 | 
					 | 
				
			||||||
			Logger_.information("CALLBACK system disabled.");
 | 
					 | 
				
			||||||
			return false;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		MyIDCallbackId_ = Daemon()->ConfigGetString("ucentral.callback.id","");
 | 
					 | 
				
			||||||
		if(MyIDCallbackId_.empty()) {
 | 
					 | 
				
			||||||
			Logger_.information("CALLBACK system disabled. No CallbackID present in ucentral.callback.id");
 | 
					 | 
				
			||||||
			return false;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		//	now get all the hosts we need to register with...
 | 
					 | 
				
			||||||
		auto Index = 0 ;
 | 
					 | 
				
			||||||
		while(true) {
 | 
					 | 
				
			||||||
			std::string root = "ucentral.callback." + std::to_string(Index);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			auto Local = Daemon()->ConfigGetString(root + ".local","");
 | 
					 | 
				
			||||||
			auto Remote = Daemon()->ConfigGetString(root + ".remote","");
 | 
					 | 
				
			||||||
			auto LocalKey = Daemon()->ConfigGetString(root + ".localkey","");
 | 
					 | 
				
			||||||
			auto RemoteKey = Daemon()->ConfigGetString(root + ".localkey","");
 | 
					 | 
				
			||||||
			auto Topics = Daemon()->ConfigGetString(root + ".topics","");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if(Local.empty() || Remote.empty() || LocalKey.empty() || Topics.empty() || RemoteKey.empty())
 | 
					 | 
				
			||||||
				break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			CallbackHost H{
 | 
					 | 
				
			||||||
				.Local = "https://" + Local + "/api/v1/callbackChannel",
 | 
					 | 
				
			||||||
				.LocalKey = LocalKey,
 | 
					 | 
				
			||||||
				.Remote = "https://" + Remote + "/api/v1/callbackChannel",
 | 
					 | 
				
			||||||
				.RemoteKey = RemoteKey,
 | 
					 | 
				
			||||||
				.Topics = Topics,
 | 
					 | 
				
			||||||
				.LastContact = 0,
 | 
					 | 
				
			||||||
				.NextContact = 0,
 | 
					 | 
				
			||||||
				.Registered = false
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
			Hosts_.push_back(H);
 | 
					 | 
				
			||||||
			Index++;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return true;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool DoRequest(Poco::Net::HTTPSClientSession& Session, Poco::Net::HTTPRequest& Request, Poco::Net::HTTPResponse& Response)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		std::string Content{R"lit({ "comment" : "registration from uCentralGW" })lit"};
 | 
					 | 
				
			||||||
		std::stringstream Body(Content);
 | 
					 | 
				
			||||||
		Request.setContentType("application/json");
 | 
					 | 
				
			||||||
		Request.setContentLength(Content.length());
 | 
					 | 
				
			||||||
		std::ostream& OS = Session.sendRequest(Request);
 | 
					 | 
				
			||||||
		Poco::StreamCopier::copyStream(Body, OS);
 | 
					 | 
				
			||||||
		Session.receiveResponse(Response);
 | 
					 | 
				
			||||||
		return (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool CallbackManager::RegisterHosts() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if(MyIDCallbackId_.empty())
 | 
					 | 
				
			||||||
			return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for(auto &i:Hosts_) {
 | 
					 | 
				
			||||||
			if(!i.Registered || (time(nullptr)-i.LastContact)>300) {
 | 
					 | 
				
			||||||
				Poco::URI Uri(i.Remote);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				Uri.addQueryParameter("subscribe", "true");
 | 
					 | 
				
			||||||
				Uri.addQueryParameter("uri", i.Local);
 | 
					 | 
				
			||||||
				Uri.addQueryParameter("topics", i.Topics);
 | 
					 | 
				
			||||||
				Uri.addQueryParameter("key", i.LocalKey);
 | 
					 | 
				
			||||||
				Uri.addQueryParameter("id", MyIDCallbackId_);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				Poco::Net::HTTPSClientSession Session(Uri.getHost(), Uri.getPort());
 | 
					 | 
				
			||||||
				Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST,
 | 
					 | 
				
			||||||
											   Uri.getPathAndQuery(),
 | 
					 | 
				
			||||||
											   Poco::Net::HTTPMessage::HTTP_1_1);
 | 
					 | 
				
			||||||
				Request.add("X-API-KEY", i.RemoteKey);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				Poco::Net::HTTPResponse Response;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				i.LastContact = time(nullptr);
 | 
					 | 
				
			||||||
				i.Registered = DoRequest(Session, Request, Response);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return true;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void CallbackManager::run() {
 | 
					 | 
				
			||||||
		Running_ = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		uint64_t LastContact = time(nullptr);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		InitHosts();
 | 
					 | 
				
			||||||
		RegisterHosts();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		while(Running_) {
 | 
					 | 
				
			||||||
			if((time(nullptr) - LastContact) >300) {
 | 
					 | 
				
			||||||
				RegisterHosts();
 | 
					 | 
				
			||||||
				LastContact = time(nullptr);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if(Calls_.empty()) {
 | 
					 | 
				
			||||||
				Poco::Thread::sleep(2000);
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				CallBackMessage E;
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					SubMutexGuard Guard(Mutex_);
 | 
					 | 
				
			||||||
					E = Calls_.front();
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				std::cout << "Call: " << E.Message << " JSON:" << E.JSONDoc << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				{
 | 
					 | 
				
			||||||
					SubMutexGuard Guard(Mutex_);
 | 
					 | 
				
			||||||
					Calls_.pop();
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void CallbackManager::Stop() {
 | 
					 | 
				
			||||||
		SubMutexGuard Guard(Mutex_);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		Logger_.notice("Stopping...");
 | 
					 | 
				
			||||||
		Running_ = false ;
 | 
					 | 
				
			||||||
		Mgr_.join();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool CallbackManager::AddMessage(const CallBackMessage &Msg) {
 | 
					 | 
				
			||||||
		SubMutexGuard Guard(Mutex_);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		Calls_.push(Msg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return true;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}  // end of namespace
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,65 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
//	License type: BSD 3-Clause License
 | 
					 | 
				
			||||||
//	License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	Created by Stephane Bourque on 2021-03-04.
 | 
					 | 
				
			||||||
//	Arilia Wireless Inc.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef UCENTRALGW_CALLBACKMANAGER_H
 | 
					 | 
				
			||||||
#define UCENTRALGW_CALLBACKMANAGER_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <queue>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "SubSystemServer.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace uCentral {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	class CallbackManager : public SubSystemServer, Poco::Runnable {
 | 
					 | 
				
			||||||
	  public:
 | 
					 | 
				
			||||||
		struct CallBackMessage {
 | 
					 | 
				
			||||||
			std::string Message;
 | 
					 | 
				
			||||||
			std::string JSONDoc;
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		struct CallbackHost {
 | 
					 | 
				
			||||||
			std::string Local;
 | 
					 | 
				
			||||||
			std::string LocalKey;
 | 
					 | 
				
			||||||
			std::string Remote;
 | 
					 | 
				
			||||||
			std::string RemoteKey;
 | 
					 | 
				
			||||||
			std::string Topics;
 | 
					 | 
				
			||||||
			uint64_t 	LastContact;
 | 
					 | 
				
			||||||
			uint64_t 	NextContact;
 | 
					 | 
				
			||||||
			bool 		Registered;
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		static CallbackManager *instance() {
 | 
					 | 
				
			||||||
			if (instance_ == nullptr) {
 | 
					 | 
				
			||||||
				instance_ = new CallbackManager;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			return instance_;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		void run() override;
 | 
					 | 
				
			||||||
		int Start() override;
 | 
					 | 
				
			||||||
		void Stop() override;
 | 
					 | 
				
			||||||
		bool AddMessage(const CallBackMessage &Msg);
 | 
					 | 
				
			||||||
		bool InitHosts();
 | 
					 | 
				
			||||||
		bool RegisterHosts();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	  private:
 | 
					 | 
				
			||||||
		static CallbackManager *instance_;
 | 
					 | 
				
			||||||
		Poco::Thread Mgr_;
 | 
					 | 
				
			||||||
		std::atomic_bool Running_ = false;
 | 
					 | 
				
			||||||
		std::queue<CallBackMessage> Calls_;
 | 
					 | 
				
			||||||
		std::string MyIDCallbackId_;
 | 
					 | 
				
			||||||
		std::vector<CallbackHost> Hosts_;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		CallbackManager() noexcept;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	inline CallbackManager * CallbackManager() { return CallbackManager::instance(); }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // end of namespace
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif // UCENTRALGW_CALLBACKMANAGER_H
 | 
					 | 
				
			||||||
@@ -18,8 +18,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "Poco/JSON/Parser.h"
 | 
					#include "Poco/JSON/Parser.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DBG		std::cout << __LINE__ << "   " __FILE__ << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class CommandManager * CommandManager::instance_ = nullptr;
 | 
					    class CommandManager * CommandManager::instance_ = nullptr;
 | 
				
			||||||
@@ -95,8 +93,6 @@ namespace uCentral {
 | 
				
			|||||||
		std::stringstream ToSend;
 | 
							std::stringstream ToSend;
 | 
				
			||||||
		Poco::JSON::Stringifier::stringify(CompleteRPC, ToSend);
 | 
							Poco::JSON::Stringifier::stringify(CompleteRPC, ToSend);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::cout << "Count: " << Promise.use_count() << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		OutStandingRequests_[Id_] = std::make_pair(std::move(Promise),UUID);
 | 
							OutStandingRequests_[Id_] = std::make_pair(std::move(Promise),UUID);
 | 
				
			||||||
		Age_[Id_] = time(nullptr);
 | 
							Age_[Id_] = time(nullptr);
 | 
				
			||||||
		Id_++;
 | 
							Id_++;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "Daemon.h"
 | 
					#include "Daemon.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "CallbackManager.h"
 | 
					 | 
				
			||||||
#include "CommandChannel.h"
 | 
					#include "CommandChannel.h"
 | 
				
			||||||
#include "CommandManager.h"
 | 
					#include "CommandManager.h"
 | 
				
			||||||
#include "DeviceRegistry.h"
 | 
					#include "DeviceRegistry.h"
 | 
				
			||||||
@@ -51,7 +50,6 @@ namespace uCentral {
 | 
				
			|||||||
									   FileUploader(),
 | 
														   FileUploader(),
 | 
				
			||||||
									   OUIServer(),
 | 
														   OUIServer(),
 | 
				
			||||||
									   CommandChannel(),
 | 
														   CommandChannel(),
 | 
				
			||||||
									   CallbackManager(),
 | 
					 | 
				
			||||||
									   StorageArchiver(),
 | 
														   StorageArchiver(),
 | 
				
			||||||
								   });
 | 
													   });
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,6 +25,7 @@
 | 
				
			|||||||
#include "Poco/Crypto/CipherFactory.h"
 | 
					#include "Poco/Crypto/CipherFactory.h"
 | 
				
			||||||
#include "Poco/Crypto/Cipher.h"
 | 
					#include "Poco/Crypto/Cipher.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Dashboard.h"
 | 
				
			||||||
#include "MicroService.h"
 | 
					#include "MicroService.h"
 | 
				
			||||||
#include "uCentralTypes.h"
 | 
					#include "uCentralTypes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -50,10 +51,13 @@ namespace uCentral {
 | 
				
			|||||||
			[[nodiscard]] std::string IdentifyDevice(const std::string & Compatible) const;
 | 
								[[nodiscard]] std::string IdentifyDevice(const std::string & Compatible) const;
 | 
				
			||||||
			void initialize(Poco::Util::Application &self);
 | 
								void initialize(Poco::Util::Application &self);
 | 
				
			||||||
			static Daemon *instance();
 | 
								static Daemon *instance();
 | 
				
			||||||
 | 
								inline DeviceDashboard	& GetDashboard() { return DB_; }
 | 
				
			||||||
	  	private:
 | 
						  	private:
 | 
				
			||||||
			static Daemon 				*instance_;
 | 
								static Daemon 				*instance_;
 | 
				
			||||||
			bool                        AutoProvisioning_ = false;
 | 
								bool                        AutoProvisioning_ = false;
 | 
				
			||||||
			Types::StringMapStringSet   DeviceTypeIdentifications_;
 | 
								Types::StringMapStringSet   DeviceTypeIdentifications_;
 | 
				
			||||||
 | 
								DeviceDashboard				DB_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline Daemon * Daemon() { return Daemon::instance(); }
 | 
						inline Daemon * Daemon() { return Daemon::instance(); }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										20
									
								
								src/Dashboard.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/Dashboard.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					// Created by stephane bourque on 2021-07-21.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Dashboard.h"
 | 
				
			||||||
 | 
					#include "DeviceRegistry.h"
 | 
				
			||||||
 | 
					#include "StorageService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace uCentral {
 | 
				
			||||||
 | 
						void DeviceDashboard::Create() {
 | 
				
			||||||
 | 
							uint64_t Now = std::time(nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(LastRun_==0 || (Now-LastRun_)>120) {
 | 
				
			||||||
 | 
								DB_.reset();
 | 
				
			||||||
 | 
								Storage()->AnalyzeCommands(DB_.commands);
 | 
				
			||||||
 | 
								DeviceRegistry()->AnalyzeRegistry(DB_);
 | 
				
			||||||
 | 
								LastRun_ = Now;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										23
									
								
								src/Dashboard.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/Dashboard.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					// Created by stephane bourque on 2021-07-21.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef UCENTRALGW_DASHBOARD_H
 | 
				
			||||||
 | 
					#define UCENTRALGW_DASHBOARD_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "uCentralTypes.h"
 | 
				
			||||||
 | 
					#include "RESTAPI_GWobjects.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace uCentral {
 | 
				
			||||||
 | 
						class DeviceDashboard {
 | 
				
			||||||
 | 
						  public:
 | 
				
			||||||
 | 
								void Create();
 | 
				
			||||||
 | 
								const GWObjects::Dashboard & Report() const { return DB_;}
 | 
				
			||||||
 | 
								inline void Reset() { LastRun_=0; DB_.reset(); }
 | 
				
			||||||
 | 
						  private:
 | 
				
			||||||
 | 
								GWObjects::Dashboard 	DB_;
 | 
				
			||||||
 | 
								uint64_t 				LastRun_=0;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // UCENTRALGW_DASHBOARD_H
 | 
				
			||||||
@@ -12,6 +12,9 @@
 | 
				
			|||||||
#include "WebSocketServer.h"
 | 
					#include "WebSocketServer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "DeviceRegistry.h"
 | 
					#include "DeviceRegistry.h"
 | 
				
			||||||
 | 
					#include "OUIServer.h"
 | 
				
			||||||
 | 
					#include "Poco/JSON/Object.h"
 | 
				
			||||||
 | 
					#include "Poco/JSON/Parser.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
    class DeviceRegistry *DeviceRegistry::instance_ = nullptr;
 | 
					    class DeviceRegistry *DeviceRegistry::instance_ = nullptr;
 | 
				
			||||||
@@ -78,7 +81,7 @@ namespace uCentral {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool DeviceRegistry::GetHealthcheck(const std::string &SerialNumber, std::string & CheckData) {
 | 
						bool DeviceRegistry::GetHealthcheck(const std::string &SerialNumber, GWObjects::HealthCheck & CheckData) {
 | 
				
			||||||
		SubMutexGuard		Guard(Mutex_);
 | 
							SubMutexGuard		Guard(Mutex_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto Device = Devices_.find(SerialNumber);
 | 
							auto Device = Devices_.find(SerialNumber);
 | 
				
			||||||
@@ -89,7 +92,7 @@ namespace uCentral {
 | 
				
			|||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void DeviceRegistry::SetHealthcheck(const std::string &SerialNumber, const std::string &CheckData) {
 | 
						void DeviceRegistry::SetHealthcheck(const std::string &SerialNumber, const GWObjects::HealthCheck & CheckData) {
 | 
				
			||||||
		SubMutexGuard		Guard(Mutex_);
 | 
							SubMutexGuard		Guard(Mutex_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto Device = Devices_.find(SerialNumber);
 | 
							auto Device = Devices_.find(SerialNumber);
 | 
				
			||||||
@@ -152,7 +155,6 @@ namespace uCentral {
 | 
				
			|||||||
            Device->second->Conn_.Address = "";
 | 
					            Device->second->Conn_.Address = "";
 | 
				
			||||||
            Device->second->WSConn_ = nullptr;
 | 
					            Device->second->WSConn_ = nullptr;
 | 
				
			||||||
            Device->second->Conn_.Connected = false;
 | 
					            Device->second->Conn_.Connected = false;
 | 
				
			||||||
            Device->second->Conn_.LastContact = time(nullptr);
 | 
					 | 
				
			||||||
			Device->second->Conn_.VerifiedCertificate = GWObjects::NO_CERTIFICATE;
 | 
								Device->second->Conn_.VerifiedCertificate = GWObjects::NO_CERTIFICATE;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -177,26 +179,103 @@ namespace uCentral {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*	bool Service::SendCommand(uCentral::Objects::CommandDetails & Cmd)
 | 
						std::string ComputeCertificateTag( GWObjects::CertificateValidation V) {
 | 
				
			||||||
    {
 | 
							switch(V) {
 | 
				
			||||||
 | 
							case GWObjects::NO_CERTIFICATE: return "no certificate";
 | 
				
			||||||
 | 
							case GWObjects::VALID_CERTIFICATE: return "non TIP certificate";
 | 
				
			||||||
 | 
							case GWObjects::MISMATCH_SERIAL: return "serial mismatch";
 | 
				
			||||||
 | 
							case GWObjects::VERIFIED: return "verified";
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return "unknown";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						const uint64_t SECONDS_MONTH = 30*24*60*60;
 | 
				
			||||||
 | 
						const uint64_t SECONDS_WEEK = 7*24*60*60;
 | 
				
			||||||
 | 
						const uint64_t SECONDS_DAY = 1*24*60*60;
 | 
				
			||||||
 | 
						const uint64_t SECONDS_HOUR = 1*24*60*60;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string ComputeUpLastContactTag(uint64_t T1) {
 | 
				
			||||||
 | 
							uint64_t T = T1 - std::time(nullptr);
 | 
				
			||||||
 | 
							if( T>SECONDS_MONTH) return ">month";
 | 
				
			||||||
 | 
							if( T>SECONDS_WEEK) return ">week";
 | 
				
			||||||
 | 
							if( T>SECONDS_DAY) return ">day";
 | 
				
			||||||
 | 
							if( T>SECONDS_HOUR) return ">hour";
 | 
				
			||||||
 | 
							return "now";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string ComputeSanityTag(uint64_t T) {
 | 
				
			||||||
 | 
							if( T==100) return "100%";
 | 
				
			||||||
 | 
							if( T>90) return ">90%";
 | 
				
			||||||
 | 
							if( T>60) return ">60%";
 | 
				
			||||||
 | 
							return "<60%%>";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string ComputeUpTimeTag(uint64_t T) {
 | 
				
			||||||
 | 
							if( T>SECONDS_MONTH) return ">month";
 | 
				
			||||||
 | 
							if( T>SECONDS_WEEK) return ">week";
 | 
				
			||||||
 | 
							if( T>SECONDS_DAY) return ">day";
 | 
				
			||||||
 | 
							if( T>SECONDS_HOUR) return ">hour";
 | 
				
			||||||
 | 
							return "now";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string ComputeLoadTag(uint64_t T) {
 | 
				
			||||||
 | 
							float V=100.0*((float)T/65536.0);
 | 
				
			||||||
 | 
							if(V<5.0) return "< 5%";
 | 
				
			||||||
 | 
							if(V<25.0) return "< 25%";
 | 
				
			||||||
 | 
							if(V<50.0) return "< 50%";
 | 
				
			||||||
 | 
							if(V<75.0) return "< 75%";
 | 
				
			||||||
 | 
							return ">75%";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						std::string ComputeFreeMemoryTag(uint64_t Free, uint64_t Total) {
 | 
				
			||||||
 | 
							float V = 100.0 * ((float)Free/(float(Total)));
 | 
				
			||||||
 | 
							if(V<5.0) return "< 5%";
 | 
				
			||||||
 | 
							if(V<25.0) return "< 25%";
 | 
				
			||||||
 | 
							if(V<50.0) return "< 50%";
 | 
				
			||||||
 | 
							if(V<75.0) return "< 75%";
 | 
				
			||||||
 | 
							return ">75%";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool DeviceRegistry::AnalyzeRegistry(GWObjects::Dashboard &D) {
 | 
				
			||||||
		SubMutexGuard		Guard(Mutex_);
 | 
							SubMutexGuard		Guard(Mutex_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auto Device = Devices_.find(Cmd.SerialNumber);
 | 
							for(auto const &[SerialNumber,Connection]:Devices_) {
 | 
				
			||||||
 | 
								Types::UpdateCountedMap(D.status, Connection->Conn_.Connected ? "connected" : "not connected");
 | 
				
			||||||
 | 
								Types::UpdateCountedMap(D.vendors, OUIServer()->GetManufacturer(SerialNumber));
 | 
				
			||||||
 | 
								Types::UpdateCountedMap(D.certificates, ComputeCertificateTag(Connection->Conn_.VerifiedCertificate));
 | 
				
			||||||
 | 
								Types::UpdateCountedMap(D.lastContact, ComputeUpLastContactTag(Connection->Conn_.LastContact));
 | 
				
			||||||
 | 
								Types::UpdateCountedMap(D.healths, ComputeSanityTag(Connection->LastHealthcheck.Sanity));
 | 
				
			||||||
 | 
								Types::UpdateCountedMap(D.deviceType, Connection->Conn_.Compatible);
 | 
				
			||||||
 | 
								if(!Connection->LastStats.empty()) {
 | 
				
			||||||
 | 
									Poco::JSON::Parser	P;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									auto RawObject = P.parse(Connection->LastStats).extract<Poco::JSON::Object::Ptr>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									if(RawObject->has("unit")) {
 | 
				
			||||||
 | 
										auto Unit = RawObject->getObject("unit");
 | 
				
			||||||
 | 
										if (Unit->has("uptime")) {
 | 
				
			||||||
 | 
											Types::UpdateCountedMap(D.upTimes, ComputeUpTimeTag(Unit->get("uptime")));
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (Unit->has("memory")) {
 | 
				
			||||||
 | 
											auto Memory = Unit->getObject("memory");
 | 
				
			||||||
 | 
											uint64_t Free = Memory->get("free");
 | 
				
			||||||
 | 
											uint64_t Total = Memory->get("total");
 | 
				
			||||||
 | 
											Types::UpdateCountedMap(D.memoryUsed, ComputeFreeMemoryTag(Free, Total));
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										if (Unit->has("load")) {
 | 
				
			||||||
 | 
											auto Load = Unit->getArray("load");
 | 
				
			||||||
 | 
											Types::UpdateCountedMap(D.load1,
 | 
				
			||||||
 | 
																	ComputeLoadTag(Load->getElement<uint64_t>(0)));
 | 
				
			||||||
 | 
											Types::UpdateCountedMap(D.load5,
 | 
				
			||||||
 | 
																	ComputeLoadTag(Load->getElement<uint64_t>(1)));
 | 
				
			||||||
 | 
											Types::UpdateCountedMap(D.load15,
 | 
				
			||||||
 | 
																	ComputeLoadTag(Load->getElement<uint64_t>(2)));
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            if (Device != Devices_.end()) {
 | 
					 | 
				
			||||||
                if (Device->second->Conn_.Connected) {
 | 
					 | 
				
			||||||
                    if (Device->second->WSConn_ != nullptr) {
 | 
					 | 
				
			||||||
                        auto *WSConn = static_cast<uCentral::WebSocket::WSConnection *>(Device->second->WSConn_);
 | 
					 | 
				
			||||||
                        WSConn->SendCommand(Cmd);
 | 
					 | 
				
			||||||
                        return true;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } catch(...) {
 | 
					 | 
				
			||||||
            Logger_.error(Poco::format("COMMAND(%s): Cannot send command %s.",Cmd.SerialNumber, Cmd.Command));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
}  // namespace
 | 
					}  // namespace
 | 
				
			||||||
@@ -25,7 +25,7 @@ namespace uCentral {
 | 
				
			|||||||
			WSConnection 				*WSConn_;
 | 
								WSConnection 				*WSConn_;
 | 
				
			||||||
			GWObjects::ConnectionState 	Conn_;
 | 
								GWObjects::ConnectionState 	Conn_;
 | 
				
			||||||
			std::string        			LastStats;
 | 
								std::string        			LastStats;
 | 
				
			||||||
			std::string 				LastHealthcheck;
 | 
								GWObjects::HealthCheck		LastHealthcheck;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static DeviceRegistry *instance() {
 | 
					        static DeviceRegistry *instance() {
 | 
				
			||||||
@@ -41,8 +41,8 @@ namespace uCentral {
 | 
				
			|||||||
		void SetStatistics(const std::string &SerialNumber, const std::string &stats);
 | 
							void SetStatistics(const std::string &SerialNumber, const std::string &stats);
 | 
				
			||||||
		bool GetState(const std::string & SerialNumber, GWObjects::ConnectionState & State);
 | 
							bool GetState(const std::string & SerialNumber, GWObjects::ConnectionState & State);
 | 
				
			||||||
		void SetState(const std::string & SerialNumber, GWObjects::ConnectionState & State);
 | 
							void SetState(const std::string & SerialNumber, GWObjects::ConnectionState & State);
 | 
				
			||||||
		bool GetHealthcheck(const std::string &SerialNumber, std::string & Statistics);
 | 
							bool GetHealthcheck(const std::string &SerialNumber, GWObjects::HealthCheck & CheckData);
 | 
				
			||||||
		void SetHealthcheck(const std::string &SerialNumber, const std::string &stats);
 | 
							void SetHealthcheck(const std::string &SerialNumber, const GWObjects::HealthCheck &H);
 | 
				
			||||||
		GWObjects::ConnectionState * Register(const std::string & SerialNumber, WSConnection *);
 | 
							GWObjects::ConnectionState * Register(const std::string & SerialNumber, WSConnection *);
 | 
				
			||||||
		void UnRegister(const std::string & SerialNumber, WSConnection *);
 | 
							void UnRegister(const std::string & SerialNumber, WSConnection *);
 | 
				
			||||||
		bool SendCommand(GWObjects::CommandDetails & Command);
 | 
							bool SendCommand(GWObjects::CommandDetails & Command);
 | 
				
			||||||
@@ -50,6 +50,8 @@ namespace uCentral {
 | 
				
			|||||||
		bool SendFrame(const std::string & SerialNumber, const std::string & Payload);
 | 
							bool SendFrame(const std::string & SerialNumber, const std::string & Payload);
 | 
				
			||||||
		void SetPendingUUID(const std::string & SerialNumber, uint64_t PendingUUID);
 | 
							void SetPendingUUID(const std::string & SerialNumber, uint64_t PendingUUID);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bool AnalyzeRegistry(GWObjects::Dashboard &D);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		static DeviceRegistry                          *instance_;
 | 
							static DeviceRegistry                          *instance_;
 | 
				
			||||||
		std::map<std::string,std::unique_ptr<ConnectionEntry>>   Devices_;
 | 
							std::map<std::string,std::unique_ptr<ConnectionEntry>>   Devices_;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,12 +29,6 @@
 | 
				
			|||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
    class FileUploader *FileUploader::instance_ = nullptr;
 | 
					    class FileUploader *FileUploader::instance_ = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	FileUploader::FileUploader() noexcept:
 | 
					 | 
				
			||||||
		SubSystemServer("FileUploader", "FILE-UPLOAD", "ucentral.fileuploader")
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
		SubMutexGuard		Guard(Mutex_);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    static const std::string URI_BASE{"/v1/upload/"};
 | 
					    static const std::string URI_BASE{"/v1/upload/"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int FileUploader::Start() {
 | 
					    int FileUploader::Start() {
 | 
				
			||||||
@@ -107,10 +101,10 @@ namespace uCentral {
 | 
				
			|||||||
        OutStandingUploads_.erase(UUID);
 | 
					        OutStandingUploads_.erase(UUID);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class MyPartHandler: public Poco::Net::PartHandler
 | 
					    class FileUploaderPartHandler: public Poco::Net::PartHandler
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        MyPartHandler(std::string UUID, Poco::Logger & Logger):
 | 
							FileUploaderPartHandler(std::string UUID, Poco::Logger & Logger):
 | 
				
			||||||
            UUID_(std::move(UUID)),
 | 
					            UUID_(std::move(UUID)),
 | 
				
			||||||
            Logger_(Logger)
 | 
					            Logger_(Logger)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -127,16 +121,15 @@ namespace uCentral {
 | 
				
			|||||||
                Name_ = Parameters.get("name", "(unnamed)");
 | 
					                Name_ = Parameters.get("name", "(unnamed)");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Poco::CountingInputStream InputStream(Stream);
 | 
								Poco::TemporaryFile 		TmpFile;
 | 
				
			||||||
            std::string TmpFileName = FileUploader()->Path() + "/" + UUID_ + ".upload.start" ;
 | 
					 | 
				
			||||||
            std::string FinalFileName = FileUploader()->Path() + "/" + UUID_ ;
 | 
					            std::string FinalFileName = FileUploader()->Path() + "/" + UUID_ ;
 | 
				
			||||||
 | 
					            Logger_.information(Poco::format("FILE-UPLOADER: uploading trace for %s",UUID_));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Logger_.information(Poco::format("FILE-UPLOADER: uploading %s",TmpFileName));
 | 
								Poco::CountingInputStream 	InputStream(Stream);
 | 
				
			||||||
 | 
					            std::ofstream OutputStream(TmpFile.path(), std::ofstream::out);
 | 
				
			||||||
            std::ofstream OutputStream(TmpFileName, std::ofstream::out);
 | 
					 | 
				
			||||||
            Poco::StreamCopier::copyStream(InputStream, OutputStream);
 | 
					            Poco::StreamCopier::copyStream(InputStream, OutputStream);
 | 
				
			||||||
            Length_ = InputStream.chars();
 | 
					            Length_ = InputStream.chars();
 | 
				
			||||||
            rename(TmpFileName.c_str(),FinalFileName.c_str());
 | 
					            rename(TmpFile.path().c_str(),FinalFileName.c_str());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [[nodiscard]] uint64_t Length() const { return Length_; }
 | 
					        [[nodiscard]] uint64_t Length() const { return Length_; }
 | 
				
			||||||
@@ -153,7 +146,6 @@ namespace uCentral {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class FormRequestHandler: public Poco::Net::HTTPRequestHandler
 | 
					    class FormRequestHandler: public Poco::Net::HTTPRequestHandler
 | 
				
			||||||
        /// Return a HTML document with the current date and time.
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        explicit FormRequestHandler(std::string UUID, Poco::Logger & L):
 | 
					        explicit FormRequestHandler(std::string UUID, Poco::Logger & L):
 | 
				
			||||||
@@ -165,62 +157,26 @@ namespace uCentral {
 | 
				
			|||||||
        void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override
 | 
					        void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                MyPartHandler partHandler(UUID_,Logger_);
 | 
									FileUploaderPartHandler partHandler(UUID_,Logger_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Poco::Net::HTMLForm form(Request, Request.stream(), partHandler);
 | 
					                Poco::Net::HTMLForm form(Request, Request.stream(), partHandler);
 | 
				
			||||||
                Response.setChunkedTransferEncoding(true);
 | 
					 | 
				
			||||||
                Response.setContentType("text/html");
 | 
					 | 
				
			||||||
                std::ostream &ResponseStream = Response.send();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                ResponseStream <<
 | 
									Response.setChunkedTransferEncoding(true);
 | 
				
			||||||
                     "<html>\n"
 | 
					                Response.setContentType("application/json");
 | 
				
			||||||
                     "<head>\n"
 | 
					 | 
				
			||||||
                     "<title>POCO Form Server Sample</title>\n"
 | 
					 | 
				
			||||||
                     "</head>\n"
 | 
					 | 
				
			||||||
                     "<body>\n"
 | 
					 | 
				
			||||||
                     "<h1>POCO Form Server Sample</h1>\n"
 | 
					 | 
				
			||||||
                     "<h2>GET Form</h2>\n"
 | 
					 | 
				
			||||||
                     "<form method=\"GET\" action=\"/form\">\n"
 | 
					 | 
				
			||||||
                     "<input type=\"text\" name=\"text\" size=\"31\">\n"
 | 
					 | 
				
			||||||
                     "<input type=\"submit\" value=\"GET\">\n"
 | 
					 | 
				
			||||||
                     "</form>\n"
 | 
					 | 
				
			||||||
                     "<h2>POST Form</h2>\n"
 | 
					 | 
				
			||||||
                     "<form method=\"POST\" action=\"/form\">\n"
 | 
					 | 
				
			||||||
                     "<input type=\"text\" name=\"text\" size=\"31\">\n"
 | 
					 | 
				
			||||||
                     "<input type=\"submit\" value=\"POST\">\n"
 | 
					 | 
				
			||||||
                     "</form>\n"
 | 
					 | 
				
			||||||
                     "<h2>File Upload</h2>\n"
 | 
					 | 
				
			||||||
                     "<form method=\"POST\" action=\"/form\" enctype=\"multipart/form-data\">\n"
 | 
					 | 
				
			||||||
                     "<input type=\"file\" name=\"file\" size=\"31\"> \n"
 | 
					 | 
				
			||||||
                     "<input type=\"submit\" value=\"Upload\">\n"
 | 
					 | 
				
			||||||
                     "</form>\n";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                ResponseStream << "<h2>Request</h2><p>\n";
 | 
					 | 
				
			||||||
                ResponseStream << "Method: " << Request.getMethod() << "<br>\n";
 | 
					 | 
				
			||||||
                ResponseStream << "URI: " << Request.getURI() << "<br>\n";
 | 
					 | 
				
			||||||
                for (auto & i:Request) {
 | 
					 | 
				
			||||||
                    ResponseStream << i.first << ": " << i.second << "<br>\n";
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                ResponseStream << "</p>";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (!form.empty()) {
 | 
					 | 
				
			||||||
                    ResponseStream << "<h2>Form</h2><p>\n";
 | 
					 | 
				
			||||||
                    for (const auto & i:form)
 | 
					 | 
				
			||||||
                        ResponseStream << i.first << ": " << i.second << "<br>\n";
 | 
					 | 
				
			||||||
                    ResponseStream << "</p>";
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									Poco::JSON::Object	Answer;
 | 
				
			||||||
                if (!partHandler.Name().empty()) {
 | 
					                if (!partHandler.Name().empty()) {
 | 
				
			||||||
                    ResponseStream << "<h2>Upload</h2><p>\n";
 | 
										Answer.set("filename", UUID_);
 | 
				
			||||||
                    ResponseStream << "Name: " << partHandler.Name() << "<br>\n";
 | 
										Answer.set("error", 0);
 | 
				
			||||||
                    ResponseStream << "Type: " << partHandler.ContentType() << "<br>\n";
 | 
										Storage()->AttachFileToCommand(UUID_);
 | 
				
			||||||
                    ResponseStream << "Size: " << partHandler.Length() << "<br>\n";
 | 
									} else {
 | 
				
			||||||
                    ResponseStream << "</p>";
 | 
										Answer.set("filename", UUID_);
 | 
				
			||||||
                }
 | 
										Answer.set("error", 13);
 | 
				
			||||||
                ResponseStream << "</body>\n";
 | 
										Answer.set("errorText", "File could not be uploaded");
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
				Storage()->AttachFileToCommand(UUID_);
 | 
									std::ostream &ResponseStream = Response.send();
 | 
				
			||||||
 | 
									Poco::JSON::Stringifier::stringify(Answer, ResponseStream);
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            catch( const Poco::Exception & E )
 | 
					            catch( const Poco::Exception & E )
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,6 +15,7 @@
 | 
				
			|||||||
#include "Poco/Net/HTTPRequestHandler.h"
 | 
					#include "Poco/Net/HTTPRequestHandler.h"
 | 
				
			||||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
 | 
					#include "Poco/Net/HTTPRequestHandlerFactory.h"
 | 
				
			||||||
#include "Poco/Net/HTTPServerRequest.h"
 | 
					#include "Poco/Net/HTTPServerRequest.h"
 | 
				
			||||||
 | 
					#include "RESTAPI_handler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -43,7 +44,11 @@ namespace uCentral {
 | 
				
			|||||||
        std::map<std::string,uint64_t>  OutStandingUploads_;
 | 
					        std::map<std::string,uint64_t>  OutStandingUploads_;
 | 
				
			||||||
        std::string                     Path_;
 | 
					        std::string                     Path_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		FileUploader() noexcept;
 | 
							explicit FileUploader() noexcept:
 | 
				
			||||||
 | 
								SubSystemServer("FileUploader", "FILE-UPLOAD", "ucentral.fileuploader")
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								SubMutexGuard		Guard(Mutex_);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class FileUpLoaderRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
 | 
					    class FileUpLoaderRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,7 +61,7 @@ namespace uCentral {
 | 
				
			|||||||
		SystemInfoWrapper_ = 	R"lit({ "system" : { "id" : )lit" +
 | 
							SystemInfoWrapper_ = 	R"lit({ "system" : { "id" : )lit" +
 | 
				
			||||||
								  	std::to_string(Daemon()->ID()) +
 | 
													  	std::to_string(Daemon()->ID()) +
 | 
				
			||||||
									R"lit( , "host" : ")lit" + Daemon()->PrivateEndPoint() +
 | 
														R"lit( , "host" : ")lit" + Daemon()->PrivateEndPoint() +
 | 
				
			||||||
									R"lit(" } , "payload" : ")lit" ;
 | 
														R"lit(" } , "payload" : )lit" ;
 | 
				
			||||||
		cppkafka::Producer	Producer(Config);
 | 
							cppkafka::Producer	Producer(Config);
 | 
				
			||||||
		ProducerRunning_ = true;
 | 
							ProducerRunning_ = true;
 | 
				
			||||||
		while(ProducerRunning_) {
 | 
							while(ProducerRunning_) {
 | 
				
			||||||
@@ -87,6 +87,13 @@ namespace uCentral {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void KafkaManager::PartitionAssignment(const cppkafka::TopicPartitionList& partitions) {
 | 
				
			||||||
 | 
							Logger_.information(Poco::format("Partition assigned: %Lu...",(uint64_t )partitions.front().get_partition()));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						void KafkaManager::PartitionRevocation(const cppkafka::TopicPartitionList& partitions) {
 | 
				
			||||||
 | 
							Logger_.information(Poco::format("Partition revocation: %Lu...",(uint64_t )partitions.front().get_partition()));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void KafkaManager::ConsumerThr() {
 | 
						void KafkaManager::ConsumerThr() {
 | 
				
			||||||
		cppkafka::Configuration Config({
 | 
							cppkafka::Configuration Config({
 | 
				
			||||||
										   { "client.id", Daemon()->ConfigGetString("ucentral.kafka.client.id") },
 | 
															   { "client.id", Daemon()->ConfigGetString("ucentral.kafka.client.id") },
 | 
				
			||||||
@@ -105,14 +112,23 @@ namespace uCentral {
 | 
				
			|||||||
		Config.set_default_topic_configuration(topic_config);
 | 
							Config.set_default_topic_configuration(topic_config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		cppkafka::Consumer Consumer(Config);
 | 
							cppkafka::Consumer Consumer(Config);
 | 
				
			||||||
		Consumer.set_assignment_callback([this](const cppkafka::TopicPartitionList& partitions) {
 | 
							Consumer.set_assignment_callback([this](cppkafka::TopicPartitionList& partitions) {
 | 
				
			||||||
		  	Logger_.information(Poco::format("Partition assigned: %Lu...",(uint64_t )partitions.front().get_partition()));
 | 
								if(!partitions.empty()) {
 | 
				
			||||||
 | 
									Logger_.information(Poco::format("Partition assigned: %Lu...",
 | 
				
			||||||
 | 
																	 (uint64_t)partitions.front().get_partition()));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
		Consumer.set_revocation_callback([this](const cppkafka::TopicPartitionList& partitions) {
 | 
							Consumer.set_revocation_callback([this](const cppkafka::TopicPartitionList& partitions) {
 | 
				
			||||||
		  	Logger_.information(Poco::format("Partition revocation: %Lu...",(uint64_t )partitions.front().get_partition()));
 | 
								if(!partitions.empty()) {
 | 
				
			||||||
 | 
									Logger_.information(Poco::format("Partition revocation: %Lu...",
 | 
				
			||||||
 | 
																	 (uint64_t)partitions.front().get_partition()));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Types::StringVec    Topics;
 | 
					        bool AutoCommit = Daemon()->ConfigGetBool("ucentral.kafka.auto.commit",false);
 | 
				
			||||||
 | 
					        auto BatchSize = Daemon()->ConfigGetInt("ucentral.kafka.consumer.batchsize",20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Types::StringVec    Topics;
 | 
				
			||||||
		for(const auto &i:Notifiers_)
 | 
							for(const auto &i:Notifiers_)
 | 
				
			||||||
			Topics.push_back(i.first);
 | 
								Topics.push_back(i.first);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -121,28 +137,31 @@ namespace uCentral {
 | 
				
			|||||||
		ConsumerRunning_ = true;
 | 
							ConsumerRunning_ = true;
 | 
				
			||||||
		while(ConsumerRunning_) {
 | 
							while(ConsumerRunning_) {
 | 
				
			||||||
			try {
 | 
								try {
 | 
				
			||||||
				cppkafka::Message Msg = Consumer.poll(std::chrono::milliseconds(200));
 | 
									std::vector<cppkafka::Message> MsgVec = Consumer.poll_batch(BatchSize, std::chrono::milliseconds(200));
 | 
				
			||||||
				if (!Msg)
 | 
									for(auto const &Msg:MsgVec) {
 | 
				
			||||||
					continue;
 | 
					                    if (!Msg)
 | 
				
			||||||
				if (Msg.get_error()) {
 | 
					                        continue;
 | 
				
			||||||
					if (!Msg.is_eof()) {
 | 
					                    if (Msg.get_error()) {
 | 
				
			||||||
						Logger_.error(Poco::format("Error: %s", Msg.get_error().to_string()));
 | 
					                        if (!Msg.is_eof()) {
 | 
				
			||||||
					}
 | 
					                            Logger_.error(Poco::format("Error: %s", Msg.get_error().to_string()));
 | 
				
			||||||
					Consumer.commit(Msg);
 | 
					                        }if(!AutoCommit)
 | 
				
			||||||
					continue;
 | 
					                            Consumer.async_commit(Msg);
 | 
				
			||||||
				}
 | 
					                        continue;
 | 
				
			||||||
				SubMutexGuard G(ConsumerMutex_);
 | 
					                    }
 | 
				
			||||||
				auto It = Notifiers_.find(Msg.get_topic());
 | 
					                    SubMutexGuard G(ConsumerMutex_);
 | 
				
			||||||
				if (It != Notifiers_.end()) {
 | 
					                    auto It = Notifiers_.find(Msg.get_topic());
 | 
				
			||||||
					Types::TopicNotifyFunctionList &FL = It->second;
 | 
					                    if (It != Notifiers_.end()) {
 | 
				
			||||||
					std::string Key{Msg.get_key()};
 | 
					                        Types::TopicNotifyFunctionList &FL = It->second;
 | 
				
			||||||
					std::string Payload{Msg.get_payload()};
 | 
					                        std::string Key{Msg.get_key()};
 | 
				
			||||||
					for (auto &F : FL) {
 | 
					                        std::string Payload{Msg.get_payload()};
 | 
				
			||||||
						std::thread T(F.first, Key, Payload);
 | 
					                        for (auto &F : FL) {
 | 
				
			||||||
						T.detach();
 | 
					                            std::thread T(F.first, Key, Payload);
 | 
				
			||||||
					}
 | 
					                            T.detach();
 | 
				
			||||||
				}
 | 
					                        }
 | 
				
			||||||
				Consumer.commit(Msg);
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (!AutoCommit)
 | 
				
			||||||
 | 
					                        Consumer.async_commit(Msg);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
			} catch (const cppkafka::HandleException &E) {
 | 
								} catch (const cppkafka::HandleException &E) {
 | 
				
			||||||
				Logger_.warning(Poco::format("Caught a Kafka exception (consumer): %s",std::string{E.what()}));
 | 
									Logger_.warning(Poco::format("Caught a Kafka exception (consumer): %s",std::string{E.what()}));
 | 
				
			||||||
			} catch (const Poco::Exception &E) {
 | 
								} catch (const Poco::Exception &E) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,6 +47,8 @@ namespace uCentral {
 | 
				
			|||||||
		int RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction & F);
 | 
							int RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction & F);
 | 
				
			||||||
		void UnregisterTopicWatcher(const std::string &Topic, int FunctionId);
 | 
							void UnregisterTopicWatcher(const std::string &Topic, int FunctionId);
 | 
				
			||||||
		void WakeUp();
 | 
							void WakeUp();
 | 
				
			||||||
 | 
							void PartitionAssignment(const cppkafka::TopicPartitionList& partitions);
 | 
				
			||||||
 | 
							void PartitionRevocation(const cppkafka::TopicPartitionList& partitions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		static KafkaManager 			*instance_;
 | 
							static KafkaManager 			*instance_;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -140,11 +140,6 @@ namespace uCentral {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void MicroService::initialize(Poco::Util::Application &self) {
 | 
						void MicroService::initialize(Poco::Util::Application &self) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
		std::string V{APP_VERSION};
 | 
					 | 
				
			||||||
		std::string B{BUILD_NUMBER};
 | 
					 | 
				
			||||||
		Version_ =  V + "(" + B +  ")";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// add the default services
 | 
							// add the default services
 | 
				
			||||||
		SubSystems_.push_back(KafkaManager());
 | 
							SubSystems_.push_back(KafkaManager());
 | 
				
			||||||
		SubSystems_.push_back(ALBHealthCheckServer());
 | 
							SubSystems_.push_back(ALBHealthCheckServer());
 | 
				
			||||||
@@ -187,7 +182,8 @@ namespace uCentral {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		std::string KeyFile = ConfigPath("ucentral.service.key");
 | 
							std::string KeyFile = ConfigPath("ucentral.service.key");
 | 
				
			||||||
		AppKey_ = Poco::SharedPtr<Poco::Crypto::RSAKey>(new Poco::Crypto::RSAKey("", KeyFile, ""));
 | 
							std::string KeyFilePassword = ConfigPath("ucentral.service.key.password" , "" );
 | 
				
			||||||
 | 
							AppKey_ = Poco::SharedPtr<Poco::Crypto::RSAKey>(new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword));
 | 
				
			||||||
		Cipher_ = CipherFactory_.createCipher(*AppKey_);
 | 
							Cipher_ = CipherFactory_.createCipher(*AppKey_);
 | 
				
			||||||
		ID_ = Utils::GetSystemId();
 | 
							ID_ = Utils::GetSystemId();
 | 
				
			||||||
		if(!DebugMode_)
 | 
							if(!DebugMode_)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,8 @@ namespace uCentral {
 | 
				
			|||||||
	static const std::string uSERVICE_SECURITY{"ucentralsec"};
 | 
						static const std::string uSERVICE_SECURITY{"ucentralsec"};
 | 
				
			||||||
	static const std::string uSERVICE_GATEWAY{"ucentralgw"};
 | 
						static const std::string uSERVICE_GATEWAY{"ucentralgw"};
 | 
				
			||||||
	static const std::string uSERVICE_FIRMWARE{ "ucentralfws"};
 | 
						static const std::string uSERVICE_FIRMWARE{ "ucentralfws"};
 | 
				
			||||||
 | 
					    static const std::string uSERVICE_TOPOLOGY{ "ucentraltopo"};
 | 
				
			||||||
 | 
					    static const std::string uSERVICE_PROVISIONING{ "ucentralprov"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class MyErrorHandler : public Poco::ErrorHandler {
 | 
						class MyErrorHandler : public Poco::ErrorHandler {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
@@ -79,7 +81,11 @@ namespace uCentral {
 | 
				
			|||||||
			DAEMON_CONFIG_ENV_VAR(std::move(ConfigVar)),
 | 
								DAEMON_CONFIG_ENV_VAR(std::move(ConfigVar)),
 | 
				
			||||||
			DAEMON_APP_NAME(std::move(AppName)),
 | 
								DAEMON_APP_NAME(std::move(AppName)),
 | 
				
			||||||
			DAEMON_BUS_TIMER(BusTimer),
 | 
								DAEMON_BUS_TIMER(BusTimer),
 | 
				
			||||||
			SubSystems_(std::move(Subsystems)) {}
 | 
								SubSystems_(std::move(Subsystems)) {
 | 
				
			||||||
 | 
								std::string V{APP_VERSION};
 | 
				
			||||||
 | 
								std::string B{BUILD_NUMBER};
 | 
				
			||||||
 | 
								Version_ =  V + "(" + B +  ")";
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		int main(const ArgVec &args) override;
 | 
							int main(const ArgVec &args) override;
 | 
				
			||||||
		void initialize(Application &self) override;
 | 
							void initialize(Application &self) override;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,12 +14,13 @@
 | 
				
			|||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
	class RESTAPI_BlackList : public RESTAPIHandler {
 | 
						class RESTAPI_BlackList : public RESTAPIHandler {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		RESTAPI_BlackList(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
 | 
							RESTAPI_BlackList(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
 | 
				
			||||||
			: RESTAPIHandler(bindings, L,
 | 
								: RESTAPIHandler(bindings, L,
 | 
				
			||||||
							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
 | 
												 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
													  Poco::Net::HTTPRequest::HTTP_POST,
 | 
																		  Poco::Net::HTTPRequest::HTTP_POST,
 | 
				
			||||||
													  Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
																		  Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
				
			||||||
													  Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
 | 
																		  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
 | 
												 							Internal) {}
 | 
				
			||||||
		void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
							void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
				
			||||||
						   Poco::Net::HTTPServerResponse &response) override;
 | 
											   Poco::Net::HTTPServerResponse &response) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -203,5 +203,34 @@ namespace uCentral::GWObjects {
 | 
				
			|||||||
		field_to_json(Obj,"password",DevicePassword);
 | 
							field_to_json(Obj,"password",DevicePassword);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void Dashboard::to_json(Poco::JSON::Object &Obj) const {
 | 
				
			||||||
 | 
							field_to_json(Obj,"commands",commands);
 | 
				
			||||||
 | 
							field_to_json(Obj,"upTimes",upTimes);
 | 
				
			||||||
 | 
							field_to_json(Obj,"memoryUsed",memoryUsed);
 | 
				
			||||||
 | 
							field_to_json(Obj,"load1",load1);
 | 
				
			||||||
 | 
							field_to_json(Obj,"load5",load5);
 | 
				
			||||||
 | 
							field_to_json(Obj,"load15",load15);
 | 
				
			||||||
 | 
							field_to_json(Obj,"vendors",vendors);
 | 
				
			||||||
 | 
							field_to_json(Obj,"status",status);
 | 
				
			||||||
 | 
							field_to_json(Obj,"deviceType",deviceType);
 | 
				
			||||||
 | 
							field_to_json(Obj,"healths",healths);
 | 
				
			||||||
 | 
							field_to_json(Obj,"certificates",certificates);
 | 
				
			||||||
 | 
							field_to_json(Obj,"lastContact",lastContact);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void Dashboard::reset()  {
 | 
				
			||||||
 | 
							commands.clear();
 | 
				
			||||||
 | 
							upTimes.clear();
 | 
				
			||||||
 | 
							memoryUsed.clear();
 | 
				
			||||||
 | 
							load1.clear();
 | 
				
			||||||
 | 
							load5.clear();
 | 
				
			||||||
 | 
							load15.clear();
 | 
				
			||||||
 | 
							vendors.clear();
 | 
				
			||||||
 | 
							status.clear();
 | 
				
			||||||
 | 
							deviceType.clear();
 | 
				
			||||||
 | 
							healths.clear();
 | 
				
			||||||
 | 
							certificates.clear();
 | 
				
			||||||
 | 
							lastContact.clear();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,7 @@ namespace uCentral::GWObjects {
 | 
				
			|||||||
		uint64_t LastContact=0;
 | 
							uint64_t LastContact=0;
 | 
				
			||||||
		std::string Firmware;
 | 
							std::string Firmware;
 | 
				
			||||||
		CertificateValidation VerifiedCertificate = NO_CERTIFICATE;
 | 
							CertificateValidation VerifiedCertificate = NO_CERTIFICATE;
 | 
				
			||||||
 | 
							std::string Compatible;
 | 
				
			||||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
							void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -156,6 +157,23 @@ namespace uCentral::GWObjects {
 | 
				
			|||||||
		std::string DevicePassword;
 | 
							std::string DevicePassword;
 | 
				
			||||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
							void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct Dashboard {
 | 
				
			||||||
 | 
							Types::CountedMap commands;
 | 
				
			||||||
 | 
							Types::CountedMap upTimes;
 | 
				
			||||||
 | 
							Types::CountedMap memoryUsed;
 | 
				
			||||||
 | 
							Types::CountedMap load1;
 | 
				
			||||||
 | 
							Types::CountedMap load5;
 | 
				
			||||||
 | 
							Types::CountedMap load15;
 | 
				
			||||||
 | 
							Types::CountedMap vendors;
 | 
				
			||||||
 | 
							Types::CountedMap status;
 | 
				
			||||||
 | 
							Types::CountedMap deviceType;
 | 
				
			||||||
 | 
							Types::CountedMap healths;
 | 
				
			||||||
 | 
							Types::CountedMap certificates;
 | 
				
			||||||
 | 
							Types::CountedMap lastContact;
 | 
				
			||||||
 | 
							void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
 | 
							void reset();
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif //UCENTRAL_RESTAPI_OBJECTS_H
 | 
					#endif //UCENTRAL_RESTAPI_OBJECTS_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,6 @@
 | 
				
			|||||||
#include "Poco/URI.h"
 | 
					#include "Poco/URI.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "RESTAPI_BlackList.h"
 | 
					#include "RESTAPI_BlackList.h"
 | 
				
			||||||
#include "RESTAPI_callback.h"
 | 
					 | 
				
			||||||
#include "RESTAPI_command.h"
 | 
					#include "RESTAPI_command.h"
 | 
				
			||||||
#include "RESTAPI_commands.h"
 | 
					#include "RESTAPI_commands.h"
 | 
				
			||||||
#include "RESTAPI_default_configuration.h"
 | 
					#include "RESTAPI_default_configuration.h"
 | 
				
			||||||
@@ -16,7 +15,6 @@
 | 
				
			|||||||
#include "RESTAPI_device_handler.h"
 | 
					#include "RESTAPI_device_handler.h"
 | 
				
			||||||
#include "RESTAPI_devices_handler.h"
 | 
					#include "RESTAPI_devices_handler.h"
 | 
				
			||||||
#include "RESTAPI_file.h"
 | 
					#include "RESTAPI_file.h"
 | 
				
			||||||
#include "RESTAPI_system_command.h"
 | 
					 | 
				
			||||||
#include "RESTAPI_ouis.h"
 | 
					#include "RESTAPI_ouis.h"
 | 
				
			||||||
#include "Utils.h"
 | 
					#include "Utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -67,7 +65,7 @@ namespace uCentral {
 | 
				
			|||||||
        const auto & Path = uri.getPath();
 | 
					        const auto & Path = uri.getPath();
 | 
				
			||||||
        RESTAPIHandler::BindingMap Bindings;
 | 
					        RESTAPIHandler::BindingMap Bindings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return RESTAPI_Router<
 | 
							return RESTAPI_Router_I<
 | 
				
			||||||
			RESTAPI_devices_handler,
 | 
								RESTAPI_devices_handler,
 | 
				
			||||||
			RESTAPI_device_handler,
 | 
								RESTAPI_device_handler,
 | 
				
			||||||
			RESTAPI_device_commandHandler,
 | 
								RESTAPI_device_commandHandler,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,12 +26,12 @@ namespace uCentral::SecurityObjects {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ResourceAccessType ResourceAccessTypeFromString(const std::string &s) {
 | 
						ResourceAccessType ResourceAccessTypeFromString(const std::string &s) {
 | 
				
			||||||
		if(s=="READ") return READ;
 | 
							if(!Poco::icompare(s,"READ")) return READ;
 | 
				
			||||||
		if(s=="MODIFY") return MODIFY;
 | 
							if(!Poco::icompare(s,"MODIFY")) return MODIFY;
 | 
				
			||||||
		if(s=="DELETE") return DELETE;
 | 
							if(!Poco::icompare(s,"DELETE")) return DELETE;
 | 
				
			||||||
		if(s=="CREATE") return CREATE;
 | 
							if(!Poco::icompare(s,"CREATE")) return CREATE;
 | 
				
			||||||
		if(s=="TEST") return TEST;
 | 
							if(!Poco::icompare(s,"TEST")) return TEST;
 | 
				
			||||||
		if(s=="MOVE") return MOVE;
 | 
							if(!Poco::icompare(s,"MOVE")) return MOVE;
 | 
				
			||||||
		return NONE;
 | 
							return NONE;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -48,17 +48,17 @@ namespace uCentral::SecurityObjects {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    USER_ROLE UserTypeFromString(const std::string &U) {
 | 
					    USER_ROLE UserTypeFromString(const std::string &U) {
 | 
				
			||||||
        if (U=="root")
 | 
					        if (!Poco::icompare(U,"root"))
 | 
				
			||||||
            return ROOT;
 | 
					            return ROOT;
 | 
				
			||||||
        else if (U=="admin")
 | 
					        else if (!Poco::icompare(U,"admin"))
 | 
				
			||||||
            return ADMIN;
 | 
					            return ADMIN;
 | 
				
			||||||
        else if (U=="subscriber")
 | 
					        else if (!Poco::icompare(U,"subscriber"))
 | 
				
			||||||
            return SUBSCRIBER;
 | 
					            return SUBSCRIBER;
 | 
				
			||||||
        else if (U=="csr")
 | 
					        else if (!Poco::icompare(U,"csr"))
 | 
				
			||||||
            return CSR;
 | 
					            return CSR;
 | 
				
			||||||
        else if (U=="system")
 | 
					        else if (!Poco::icompare(U, "system"))
 | 
				
			||||||
            return SYSTEM;
 | 
					            return SYSTEM;
 | 
				
			||||||
        else if (U=="special")
 | 
					        else if (!Poco::icompare(U, "special"))
 | 
				
			||||||
            return SPECIAL;
 | 
					            return SPECIAL;
 | 
				
			||||||
        return UNKNOWN;
 | 
					        return UNKNOWN;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -71,6 +71,7 @@ namespace uCentral::SecurityObjects {
 | 
				
			|||||||
            case CSR: return "csr";
 | 
					            case CSR: return "csr";
 | 
				
			||||||
            case SYSTEM: return "system";
 | 
					            case SYSTEM: return "system";
 | 
				
			||||||
            case SPECIAL: return "special";
 | 
					            case SPECIAL: return "special";
 | 
				
			||||||
 | 
					            case ADMIN: return "admin";
 | 
				
			||||||
            default: return "unknown";
 | 
					            default: return "unknown";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,16 +41,6 @@ namespace uCentral::SecurityObjects {
 | 
				
			|||||||
		bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
							bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enum AUTH_ERROR {
 | 
					 | 
				
			||||||
        SUCCESS,
 | 
					 | 
				
			||||||
        PASSWORD_CHANGE_REQUIRED,
 | 
					 | 
				
			||||||
        PASSWORD_DOES_NOT_MATCH,
 | 
					 | 
				
			||||||
        PASSWORD_ALREADY_USED,
 | 
					 | 
				
			||||||
        USERNAME_PENDING_VERIFICATION,
 | 
					 | 
				
			||||||
        PASSWORD_INVALID,
 | 
					 | 
				
			||||||
        INTERNAL_ERROR
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    enum USER_ROLE {
 | 
					    enum USER_ROLE {
 | 
				
			||||||
        UNKNOWN, ROOT, ADMIN, SUBSCRIBER, CSR, SYSTEM, SPECIAL
 | 
					        UNKNOWN, ROOT, ADMIN, SUBSCRIBER, CSR, SYSTEM, SPECIAL
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,66 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
//	License type: BSD 3-Clause License
 | 
					 | 
				
			||||||
//	License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	Created by Stephane Bourque on 2021-03-04.
 | 
					 | 
				
			||||||
//	Arilia Wireless Inc.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI_callback.h"
 | 
					 | 
				
			||||||
#include "Poco/JSON/Object.h"
 | 
					 | 
				
			||||||
#include "Poco/JSON/Parser.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI_protocol.h"
 | 
					 | 
				
			||||||
#include "StorageService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace uCentral {
 | 
					 | 
				
			||||||
void RESTAPI_callback::handleRequest(Poco::Net::HTTPServerRequest &Request,
 | 
					 | 
				
			||||||
									 Poco::Net::HTTPServerResponse &Response) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!ContinueProcessing(Request, Response))
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!ValidateAPIKey(Request, Response))
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ParseParameters(Request);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	try {
 | 
					 | 
				
			||||||
		if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST)
 | 
					 | 
				
			||||||
			DoPost(Request, Response);
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	} catch (const Poco::Exception &E) {
 | 
					 | 
				
			||||||
		Logger_.error(Poco::format("%s: failed with %s", std::string(__func__), E.displayText()));
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	BadRequest(Request, Response);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void RESTAPI_callback::DoPost(Poco::Net::HTTPServerRequest &Request,
 | 
					 | 
				
			||||||
							  Poco::Net::HTTPServerResponse &Response) {
 | 
					 | 
				
			||||||
	try {
 | 
					 | 
				
			||||||
		Poco::JSON::Parser parser;
 | 
					 | 
				
			||||||
		Poco::JSON::Object::Ptr Obj =
 | 
					 | 
				
			||||||
			parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
 | 
					 | 
				
			||||||
		Poco::DynamicStruct ds = *Obj;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		auto Topic = GetParameter(uCentral::RESTAPI::Protocol::TOPIC, "");
 | 
					 | 
				
			||||||
		if (Topic == "ucentralfws") {
 | 
					 | 
				
			||||||
			if (ds.contains(uCentral::RESTAPI::Protocol::FIRMWARES) &&
 | 
					 | 
				
			||||||
				ds[uCentral::RESTAPI::Protocol::FIRMWARES].isArray()) {
 | 
					 | 
				
			||||||
				std::cout << "Proper manifest received..." << std::endl;
 | 
					 | 
				
			||||||
				Logger_.information("New manifest...");
 | 
					 | 
				
			||||||
				OK(Request, Response);
 | 
					 | 
				
			||||||
				return;
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				std::cout << __LINE__ << std::endl;
 | 
					 | 
				
			||||||
				Logger_.information("Bad manifest. JSON does not contain firmwares");
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			Logger_.information("Missing topic in callback.");
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} catch (const Poco::Exception &E) {
 | 
					 | 
				
			||||||
		Logger_.log(E);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	BadRequest(Request, Response);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
//	License type: BSD 3-Clause License
 | 
					 | 
				
			||||||
//	License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	Created by Stephane Bourque on 2021-03-04.
 | 
					 | 
				
			||||||
//	Arilia Wireless Inc.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef UCENTRALGW_RESTAPI_CALLBACK_H
 | 
					 | 
				
			||||||
#define UCENTRALGW_RESTAPI_CALLBACK_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI_handler.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace uCentral {
 | 
					 | 
				
			||||||
class RESTAPI_callback : public RESTAPIHandler {
 | 
					 | 
				
			||||||
  public:
 | 
					 | 
				
			||||||
	RESTAPI_callback(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
 | 
					 | 
				
			||||||
		: RESTAPIHandler(bindings, L,
 | 
					 | 
				
			||||||
						 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
 | 
					 | 
				
			||||||
												  Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
 | 
					 | 
				
			||||||
	void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
					 | 
				
			||||||
					   Poco::Net::HTTPServerResponse &response) override;
 | 
					 | 
				
			||||||
	void DoPost(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response);
 | 
					 | 
				
			||||||
	static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/callbackChannel"};}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif // UCENTRALGW_RESTAPI_CALLBACK_H
 | 
					 | 
				
			||||||
@@ -14,11 +14,12 @@
 | 
				
			|||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
class RESTAPI_command : public RESTAPIHandler {
 | 
					class RESTAPI_command : public RESTAPIHandler {
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
	RESTAPI_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
 | 
						RESTAPI_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
 | 
				
			||||||
		: RESTAPIHandler(bindings, L,
 | 
							: RESTAPIHandler(bindings, L,
 | 
				
			||||||
						 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
 | 
											 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
												  Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
																	  Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
				
			||||||
												  Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
 | 
																	  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
 | 
											 Internal) {}
 | 
				
			||||||
	void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
						void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
				
			||||||
					   Poco::Net::HTTPServerResponse &response) override;
 | 
										   Poco::Net::HTTPServerResponse &response) override;
 | 
				
			||||||
	static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/command/{commandUUID}"};}
 | 
						static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/command/{commandUUID}"};}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,11 +14,12 @@
 | 
				
			|||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
class RESTAPI_commands : public RESTAPIHandler {
 | 
					class RESTAPI_commands : public RESTAPIHandler {
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
	RESTAPI_commands(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
 | 
						RESTAPI_commands(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
 | 
				
			||||||
		: RESTAPIHandler(bindings, L,
 | 
							: RESTAPIHandler(bindings, L,
 | 
				
			||||||
						 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
 | 
											 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
												  Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
																	  Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
				
			||||||
												  Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
 | 
																	  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
 | 
											 Internal) {}
 | 
				
			||||||
	void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
						void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
				
			||||||
					   Poco::Net::HTTPServerResponse &response) override;
 | 
										   Poco::Net::HTTPServerResponse &response) override;
 | 
				
			||||||
	static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/commands"};}
 | 
						static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/commands"};}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,12 +14,13 @@
 | 
				
			|||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
class RESTAPI_default_configuration : public RESTAPIHandler {
 | 
					class RESTAPI_default_configuration : public RESTAPIHandler {
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
	RESTAPI_default_configuration(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
 | 
						RESTAPI_default_configuration(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
 | 
				
			||||||
		: RESTAPIHandler(bindings, L,
 | 
							: RESTAPIHandler(bindings, L,
 | 
				
			||||||
						 std::vector<std::string>{
 | 
											 std::vector<std::string>{
 | 
				
			||||||
							 Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
 | 
												 Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
 | 
				
			||||||
							 Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
												 Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
				
			||||||
							 Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
 | 
												 Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
 | 
											 Internal) {}
 | 
				
			||||||
	void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
						void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
				
			||||||
					   Poco::Net::HTTPServerResponse &response) override;
 | 
										   Poco::Net::HTTPServerResponse &response) override;
 | 
				
			||||||
	static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/default_configuration/{name}"};}
 | 
						static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/default_configuration/{name}"};}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,10 +14,11 @@
 | 
				
			|||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
class RESTAPI_default_configurations : public RESTAPIHandler {
 | 
					class RESTAPI_default_configurations : public RESTAPIHandler {
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
	RESTAPI_default_configurations(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
 | 
						RESTAPI_default_configurations(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
 | 
				
			||||||
		: RESTAPIHandler(bindings, L,
 | 
							: RESTAPIHandler(bindings, L,
 | 
				
			||||||
						 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
 | 
											 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
												  Poco::Net::HTTPRequest::HTTP_OPTIONS}){};
 | 
																	  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
 | 
											 Internal){};
 | 
				
			||||||
	void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
						void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
				
			||||||
					   Poco::Net::HTTPServerResponse &response) override;
 | 
										   Poco::Net::HTTPServerResponse &response) override;
 | 
				
			||||||
	static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/default_configurations"};}
 | 
						static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/default_configurations"};}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										31
									
								
								src/RESTAPI_deviceDashboardHandler.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/RESTAPI_deviceDashboardHandler.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					// Created by stephane bourque on 2021-07-21.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "RESTAPI_deviceDashboardHandler.h"
 | 
				
			||||||
 | 
					#include "Daemon.h"
 | 
				
			||||||
 | 
					#include "Dashboard.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace uCentral {
 | 
				
			||||||
 | 
						void RESTAPI_deviceDashboardHandler::handleRequest(Poco::Net::HTTPServerRequest &Request,
 | 
				
			||||||
 | 
																		   Poco::Net::HTTPServerResponse &Response) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!ContinueProcessing(Request, Response))
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!IsAuthorized(Request, Response))
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_GET) {
 | 
				
			||||||
 | 
								DoGet(Request, Response);
 | 
				
			||||||
 | 
								BadRequest(Request, Response);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void RESTAPI_deviceDashboardHandler::DoGet(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
 | 
				
			||||||
 | 
							Daemon()->GetDashboard().Create();
 | 
				
			||||||
 | 
							Poco::JSON::Object	Answer;
 | 
				
			||||||
 | 
							Daemon()->GetDashboard().Report().to_json(Answer);
 | 
				
			||||||
 | 
							ReturnObject(Request, Answer, Response);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										26
									
								
								src/RESTAPI_deviceDashboardHandler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								src/RESTAPI_deviceDashboardHandler.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					// Created by stephane bourque on 2021-07-21.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef UCENTRALGW_RESTAPI_DEVICEDASHBOARDHANDLER_H
 | 
				
			||||||
 | 
					#define UCENTRALGW_RESTAPI_DEVICEDASHBOARDHANDLER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "RESTAPI_handler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace uCentral {
 | 
				
			||||||
 | 
					class RESTAPI_deviceDashboardHandler : public RESTAPIHandler {
 | 
				
			||||||
 | 
					  public:
 | 
				
			||||||
 | 
						RESTAPI_deviceDashboardHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
 | 
				
			||||||
 | 
							: RESTAPIHandler(bindings, L,
 | 
				
			||||||
 | 
											 std::vector<std::string>{
 | 
				
			||||||
 | 
												 Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
 | 
				
			||||||
 | 
												 Poco::Net::HTTPRequest::HTTP_OPTIONS}, Internal) {}
 | 
				
			||||||
 | 
						void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
				
			||||||
 | 
										   Poco::Net::HTTPServerResponse &response) override;
 | 
				
			||||||
 | 
						static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/deviceDashboard"};}
 | 
				
			||||||
 | 
						void DoGet(Poco::Net::HTTPServerRequest &Request,
 | 
				
			||||||
 | 
								   Poco::Net::HTTPServerResponse &Response);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // UCENTRALGW_RESTAPI_DEVICEDASHBOARDHANDLER_H
 | 
				
			||||||
@@ -405,13 +405,11 @@ void RESTAPI_device_commandHandler::GetChecks(Poco::Net::HTTPServerRequest &Requ
 | 
				
			|||||||
		std::vector<GWObjects::HealthCheck> Checks;
 | 
							std::vector<GWObjects::HealthCheck> Checks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (QB_.LastOnly) {
 | 
							if (QB_.LastOnly) {
 | 
				
			||||||
			std::string Healthcheck;
 | 
								GWObjects::HealthCheck	HC;
 | 
				
			||||||
			if (DeviceRegistry()->GetHealthcheck(SerialNumber_, Healthcheck)) {
 | 
								if (DeviceRegistry()->GetHealthcheck(SerialNumber_, HC)) {
 | 
				
			||||||
				Poco::JSON::Parser P;
 | 
									Poco::JSON::Object	Answer;
 | 
				
			||||||
				if (Healthcheck.empty())
 | 
									HC.to_json(Answer);
 | 
				
			||||||
					Healthcheck = uCentral::uCentralProtocol::EMPTY_JSON_DOC;
 | 
									ReturnObject(Request, Answer, Response);
 | 
				
			||||||
				auto Obj = P.parse(Healthcheck).extract<Poco::JSON::Object::Ptr>();
 | 
					 | 
				
			||||||
				ReturnObject(Request, *Obj, Response);
 | 
					 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				NotFound(Request, Response);
 | 
									NotFound(Request, Response);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,12 +14,13 @@
 | 
				
			|||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
class RESTAPI_device_commandHandler : public RESTAPIHandler {
 | 
					class RESTAPI_device_commandHandler : public RESTAPIHandler {
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
	RESTAPI_device_commandHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
 | 
						RESTAPI_device_commandHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
 | 
				
			||||||
		: RESTAPIHandler(bindings, L,
 | 
							: RESTAPIHandler(bindings, L,
 | 
				
			||||||
						 std::vector<std::string>{
 | 
											 std::vector<std::string>{
 | 
				
			||||||
							 Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
 | 
												 Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
 | 
				
			||||||
							 Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
												 Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
				
			||||||
							 Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
 | 
												 Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
 | 
											 Internal) {}
 | 
				
			||||||
	void handleRequest(Poco::Net::HTTPServerRequest &Request,
 | 
						void handleRequest(Poco::Net::HTTPServerRequest &Request,
 | 
				
			||||||
					   Poco::Net::HTTPServerResponse &Response) override;
 | 
										   Poco::Net::HTTPServerResponse &Response) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,12 +17,13 @@
 | 
				
			|||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
class RESTAPI_device_handler : public RESTAPIHandler {
 | 
					class RESTAPI_device_handler : public RESTAPIHandler {
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
	RESTAPI_device_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
 | 
						RESTAPI_device_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
 | 
				
			||||||
		: RESTAPIHandler(bindings, L,
 | 
							: RESTAPIHandler(bindings, L,
 | 
				
			||||||
						 std::vector<std::string>{
 | 
											 std::vector<std::string>{
 | 
				
			||||||
							 Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
 | 
												 Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
 | 
				
			||||||
							 Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
												 Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
				
			||||||
							 Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
 | 
												 Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
 | 
											 Internal) {}
 | 
				
			||||||
	void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
						void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
				
			||||||
					   Poco::Net::HTTPServerResponse &response) override;
 | 
										   Poco::Net::HTTPServerResponse &response) override;
 | 
				
			||||||
	static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/device/{serialNumber}"}; };
 | 
						static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/device/{serialNumber}"}; };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,10 +14,11 @@
 | 
				
			|||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
	class RESTAPI_devices_handler : public RESTAPIHandler {
 | 
						class RESTAPI_devices_handler : public RESTAPIHandler {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		RESTAPI_devices_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
 | 
							RESTAPI_devices_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
 | 
				
			||||||
			: RESTAPIHandler(bindings, L,
 | 
								: RESTAPIHandler(bindings, L,
 | 
				
			||||||
							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
 | 
												 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
													  Poco::Net::HTTPRequest::HTTP_OPTIONS}){};
 | 
																		  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
 | 
												 Internal){};
 | 
				
			||||||
		void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
							void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
				
			||||||
						   Poco::Net::HTTPServerResponse &response) override;
 | 
											   Poco::Net::HTTPServerResponse &response) override;
 | 
				
			||||||
		static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/devices"}; };
 | 
							static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/devices"}; };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,11 +14,12 @@
 | 
				
			|||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
	class RESTAPI_file : public RESTAPIHandler {
 | 
						class RESTAPI_file : public RESTAPIHandler {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		RESTAPI_file(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
 | 
							RESTAPI_file(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
 | 
				
			||||||
			: RESTAPIHandler(bindings, L,
 | 
								: RESTAPIHandler(bindings, L,
 | 
				
			||||||
							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
 | 
												 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
													  Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
																		  Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
				
			||||||
													  Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
 | 
																		  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
 | 
												 Internal) {}
 | 
				
			||||||
		void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
							void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
				
			||||||
						   Poco::Net::HTTPServerResponse &response) override;
 | 
											   Poco::Net::HTTPServerResponse &response) override;
 | 
				
			||||||
		static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/file/{uuid}"};}
 | 
							static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/file/{uuid}"};}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,6 +25,7 @@
 | 
				
			|||||||
#include "RESTAPI_handler.h"
 | 
					#include "RESTAPI_handler.h"
 | 
				
			||||||
#include "RESTAPI_protocol.h"
 | 
					#include "RESTAPI_protocol.h"
 | 
				
			||||||
#include "Utils.h"
 | 
					#include "Utils.h"
 | 
				
			||||||
 | 
					#include "Daemon.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -246,18 +247,33 @@ namespace uCentral {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void RESTAPIHandler::SendFile(Poco::File & File, Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
 | 
					    void RESTAPIHandler::SendFile(Poco::File & File, Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
 | 
				
			||||||
        Response.set("Content-Type",Utils::FindMediaType(File));
 | 
					 | 
				
			||||||
        Poco::Path  P(File.path());
 | 
					        Poco::Path  P(File.path());
 | 
				
			||||||
        Response.set("Content-Disposition", "attachment; filename=" + P.getBaseName()  );
 | 
					        auto MT = Utils::FindMediaType(File);
 | 
				
			||||||
        Response.set("Content-Transfer-Encoding","binary");
 | 
					        if(MT.Encoding==Utils::BINARY) {
 | 
				
			||||||
 | 
					            Response.set("Content-Transfer-Encoding","binary");
 | 
				
			||||||
 | 
					            Response.set("Accept-Ranges", "bytes");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Response.set("Cache-Control", "private");
 | 
				
			||||||
 | 
					        Response.set("Pragma", "private");
 | 
				
			||||||
 | 
					        Response.set("Expires", "Mon, 26 Jul 2027 05:00:00 GMT");
 | 
				
			||||||
 | 
					        AddCORS(Request, Response);
 | 
				
			||||||
 | 
					        Response.sendFile(File.path(),MT.ContentType);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void RESTAPIHandler::SendFile(Poco::TemporaryFile &TempAvatar, const std::string &Type, const std::string & Name, Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
 | 
				
			||||||
 | 
					        auto MT = Utils::FindMediaType(Name);
 | 
				
			||||||
 | 
					        if(MT.Encoding==Utils::BINARY) {
 | 
				
			||||||
 | 
					            Response.set("Content-Transfer-Encoding","binary");
 | 
				
			||||||
 | 
					            Response.set("Accept-Ranges", "bytes");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Response.set("Content-Disposition", "attachment; filename=" + Name );
 | 
				
			||||||
        Response.set("Accept-Ranges", "bytes");
 | 
					        Response.set("Accept-Ranges", "bytes");
 | 
				
			||||||
        Response.set("Cache-Control", "private");
 | 
					        Response.set("Cache-Control", "private");
 | 
				
			||||||
        Response.set("Pragma", "private");
 | 
					        Response.set("Pragma", "private");
 | 
				
			||||||
        Response.set("Expires", "Mon, 26 Jul 2027 05:00:00 GMT");
 | 
					        Response.set("Expires", "Mon, 26 Jul 2027 05:00:00 GMT");
 | 
				
			||||||
        Response.set("Content-Length", std::to_string(File.getSize()));
 | 
					 | 
				
			||||||
        AddCORS(Request, Response);
 | 
					        AddCORS(Request, Response);
 | 
				
			||||||
        Response.sendFile(File.path(),Utils::FindMediaType(File));
 | 
					        Response.sendFile(TempAvatar.path(),MT.ContentType);
 | 
				
			||||||
    }
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void RESTAPIHandler::SendHTMLFileBack(Poco::File & File,
 | 
					    void RESTAPIHandler::SendHTMLFileBack(Poco::File & File,
 | 
				
			||||||
                          Poco::Net::HTTPServerRequest &Request,
 | 
					                          Poco::Net::HTTPServerRequest &Request,
 | 
				
			||||||
@@ -291,10 +307,6 @@ namespace uCentral {
 | 
				
			|||||||
	bool RESTAPIHandler::ContinueProcessing(Poco::Net::HTTPServerRequest &Request,
 | 
						bool RESTAPIHandler::ContinueProcessing(Poco::Net::HTTPServerRequest &Request,
 | 
				
			||||||
											Poco::Net::HTTPServerResponse &Response) {
 | 
																Poco::Net::HTTPServerResponse &Response) {
 | 
				
			||||||
		if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) {
 | 
							if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) {
 | 
				
			||||||
			/*		std::cout << "REQUEST:" << std::endl;
 | 
					 | 
				
			||||||
					for(const auto &[f,s]:Request)
 | 
					 | 
				
			||||||
						std::cout << "First: " << f << " second:" << s << std::endl;
 | 
					 | 
				
			||||||
			*/
 | 
					 | 
				
			||||||
			ProcessOptions(Request, Response);
 | 
								ProcessOptions(Request, Response);
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		} else if (std::find(Methods_.begin(), Methods_.end(), Request.getMethod()) == Methods_.end()) {
 | 
							} else if (std::find(Methods_.begin(), Methods_.end(), Request.getMethod()) == Methods_.end()) {
 | 
				
			||||||
@@ -307,45 +319,34 @@ namespace uCentral {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	bool RESTAPIHandler::IsAuthorized(Poco::Net::HTTPServerRequest &Request,
 | 
						bool RESTAPIHandler::IsAuthorized(Poco::Net::HTTPServerRequest &Request,
 | 
				
			||||||
									  Poco::Net::HTTPServerResponse &Response) {
 | 
														  Poco::Net::HTTPServerResponse &Response) {
 | 
				
			||||||
		if(SessionToken_.empty()) {
 | 
						    if(Internal_) {
 | 
				
			||||||
			try {
 | 
						        return Daemon()->IsValidAPIKEY(Request);
 | 
				
			||||||
				Poco::Net::OAuth20Credentials Auth(Request);
 | 
						    } else {
 | 
				
			||||||
 | 
					            if (SessionToken_.empty()) {
 | 
				
			||||||
 | 
					                try {
 | 
				
			||||||
 | 
					                    Poco::Net::OAuth20Credentials Auth(Request);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (Auth.getScheme() == "Bearer") {
 | 
					                    if (Auth.getScheme() == "Bearer") {
 | 
				
			||||||
					SessionToken_ = Auth.getBearerToken();
 | 
					                        SessionToken_ = Auth.getBearerToken();
 | 
				
			||||||
				}
 | 
					                    }
 | 
				
			||||||
			} catch(const Poco::Exception &E) {
 | 
					                } catch (const Poco::Exception &E) {
 | 
				
			||||||
				Logger_.log(E);
 | 
					                    Logger_.log(E);
 | 
				
			||||||
			}
 | 
					                }
 | 
				
			||||||
		}
 | 
					            }
 | 
				
			||||||
#ifdef	TIP_SECURITY_SERVICE
 | 
					#ifdef    TIP_SECURITY_SERVICE
 | 
				
			||||||
		if (AuthService()->IsAuthorized(Request, SessionToken_, UserInfo_)) {
 | 
					            if (AuthService()->IsAuthorized(Request, SessionToken_, UserInfo_)) {
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
		if (AuthClient()->IsAuthorized(Request, SessionToken_, UserInfo_)) {
 | 
					            if (AuthClient()->IsAuthorized(Request, SessionToken_, UserInfo_)) {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
			return true;
 | 
					                return true;
 | 
				
			||||||
		} else {
 | 
					            } else {
 | 
				
			||||||
			UnAuthorized(Request, Response);
 | 
					                UnAuthorized(Request, Response);
 | 
				
			||||||
		}
 | 
					            }
 | 
				
			||||||
		return false;
 | 
					            return false;
 | 
				
			||||||
	}
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool RESTAPIHandler::IsAuthorized(Poco::Net::HTTPServerRequest &Request,
 | 
					 | 
				
			||||||
									  Poco::Net::HTTPServerResponse &Response, std::string &UserName) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef	TIP_SECURITY_SERVICE
 | 
					 | 
				
			||||||
		if (AuthService()->IsAuthorized(Request, SessionToken_, UserInfo_)) {
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
		if (AuthClient()->IsAuthorized(Request, SessionToken_, UserInfo_)) {
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
			UserName = UserInfo_.webtoken.username_;
 | 
					 | 
				
			||||||
			return true;
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			UnAuthorized(Request, Response);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
	bool RESTAPIHandler::ValidateAPIKey(Poco::Net::HTTPServerRequest &Request,
 | 
						bool RESTAPIHandler::ValidateAPIKey(Poco::Net::HTTPServerRequest &Request,
 | 
				
			||||||
										Poco::Net::HTTPServerResponse &Response) {
 | 
															Poco::Net::HTTPServerResponse &Response) {
 | 
				
			||||||
		auto Key = Request.get("X-API-KEY", "");
 | 
							auto Key = Request.get("X-API-KEY", "");
 | 
				
			||||||
@@ -355,7 +356,7 @@ namespace uCentral {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
	void RESTAPIHandler::ReturnObject(Poco::Net::HTTPServerRequest &Request, Poco::JSON::Object &Object,
 | 
						void RESTAPIHandler::ReturnObject(Poco::Net::HTTPServerRequest &Request, Poco::JSON::Object &Object,
 | 
				
			||||||
									  Poco::Net::HTTPServerResponse &Response) {
 | 
														  Poco::Net::HTTPServerResponse &Response) {
 | 
				
			||||||
		PrepareResponse(Request, Response);
 | 
							PrepareResponse(Request, Response);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,6 +19,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "Poco/Logger.h"
 | 
					#include "Poco/Logger.h"
 | 
				
			||||||
#include "Poco/File.h"
 | 
					#include "Poco/File.h"
 | 
				
			||||||
 | 
					#include "Poco/TemporaryFile.h"
 | 
				
			||||||
#include "Poco/JSON/Object.h"
 | 
					#include "Poco/JSON/Object.h"
 | 
				
			||||||
#include "Poco/CountingStream.h"
 | 
					#include "Poco/CountingStream.h"
 | 
				
			||||||
#include "Poco/NullStream.h"
 | 
					#include "Poco/NullStream.h"
 | 
				
			||||||
@@ -90,8 +91,8 @@ namespace uCentral {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		typedef std::map<std::string, std::string> BindingMap;
 | 
							typedef std::map<std::string, std::string> BindingMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		RESTAPIHandler(BindingMap map, Poco::Logger &l, std::vector<std::string> Methods)
 | 
							RESTAPIHandler(BindingMap map, Poco::Logger &l, std::vector<std::string> Methods, bool Internal=false)
 | 
				
			||||||
			: Bindings_(std::move(map)), Logger_(l), Methods_(std::move(Methods)) {}
 | 
								: Bindings_(std::move(map)), Logger_(l), Methods_(std::move(Methods)), Internal_(Internal) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static bool ParseBindings(const std::string & Request, const std::list<const char *> & EndPoints, BindingMap &Keys);
 | 
							static bool ParseBindings(const std::string & Request, const std::list<const char *> & EndPoints, BindingMap &Keys);
 | 
				
			||||||
		void PrintBindings();
 | 
							void PrintBindings();
 | 
				
			||||||
@@ -110,10 +111,8 @@ namespace uCentral {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		bool IsAuthorized(Poco::Net::HTTPServerRequest &Request,
 | 
							bool IsAuthorized(Poco::Net::HTTPServerRequest &Request,
 | 
				
			||||||
						  Poco::Net::HTTPServerResponse &Response);
 | 
											  Poco::Net::HTTPServerResponse &Response);
 | 
				
			||||||
		bool IsAuthorized(Poco::Net::HTTPServerRequest &Request,
 | 
					/*		bool ValidateAPIKey(Poco::Net::HTTPServerRequest &Request,
 | 
				
			||||||
						  Poco::Net::HTTPServerResponse &Response, std::string &UserName);
 | 
												Poco::Net::HTTPServerResponse &Response); */
 | 
				
			||||||
		bool ValidateAPIKey(Poco::Net::HTTPServerRequest &Request,
 | 
					 | 
				
			||||||
							Poco::Net::HTTPServerResponse &Response);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		uint64_t GetParameter(const std::string &Name, uint64_t Default);
 | 
							uint64_t GetParameter(const std::string &Name, uint64_t Default);
 | 
				
			||||||
		std::string GetParameter(const std::string &Name, const std::string &Default);
 | 
							std::string GetParameter(const std::string &Name, const std::string &Default);
 | 
				
			||||||
@@ -136,6 +135,7 @@ namespace uCentral {
 | 
				
			|||||||
                              Poco::Net::HTTPServerRequest &Request,
 | 
					                              Poco::Net::HTTPServerRequest &Request,
 | 
				
			||||||
                              Poco::Net::HTTPServerResponse &Response ,
 | 
					                              Poco::Net::HTTPServerResponse &Response ,
 | 
				
			||||||
                              const Types::StringPairVec & FormVars);
 | 
					                              const Types::StringPairVec & FormVars);
 | 
				
			||||||
 | 
					        void SendFile(Poco::TemporaryFile &TempAvatar, const std::string &Type, const std::string & Name, Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void SendFile(Poco::File & File, Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response);
 | 
					        void SendFile(Poco::File & File, Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -155,6 +155,7 @@ namespace uCentral {
 | 
				
			|||||||
		SecurityObjects::UserInfoAndPolicy 	UserInfo_;
 | 
							SecurityObjects::UserInfoAndPolicy 	UserInfo_;
 | 
				
			||||||
		std::vector<std::string> 	Methods_;
 | 
							std::vector<std::string> 	Methods_;
 | 
				
			||||||
		QueryBlock					QB_;
 | 
							QueryBlock					QB_;
 | 
				
			||||||
 | 
							bool                        Internal_=false;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class RESTAPI_UnknownRequestHandler : public RESTAPIHandler {
 | 
						class RESTAPI_UnknownRequestHandler : public RESTAPIHandler {
 | 
				
			||||||
@@ -181,10 +182,10 @@ namespace uCentral {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template<typename T, typename... Args>
 | 
						template<typename T, typename... Args>
 | 
				
			||||||
	RESTAPIHandler * RESTAPI_Router(const std::string & RequestedPath, RESTAPIHandler::BindingMap &Bindings, Poco::Logger & Logger) {
 | 
						RESTAPIHandler * RESTAPI_Router(const std::string & RequestedPath, RESTAPIHandler::BindingMap &Bindings, Poco::Logger & Logger ) {
 | 
				
			||||||
		static_assert(test_has_PathName_method((T*)nullptr), "Class must have a static PathName() method.");
 | 
							static_assert(test_has_PathName_method((T*)nullptr), "Class must have a static PathName() method.");
 | 
				
			||||||
		if(RESTAPIHandler::ParseBindings(RequestedPath,T::PathName(),Bindings)) {
 | 
							if(RESTAPIHandler::ParseBindings(RequestedPath,T::PathName(),Bindings)) {
 | 
				
			||||||
			return new T(Bindings, Logger);
 | 
								return new T(Bindings, Logger, false);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if constexpr (sizeof...(Args) == 0) {
 | 
							if constexpr (sizeof...(Args) == 0) {
 | 
				
			||||||
@@ -194,6 +195,21 @@ namespace uCentral {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename T, typename... Args>
 | 
				
			||||||
 | 
					    RESTAPIHandler * RESTAPI_Router_I(const std::string & RequestedPath, RESTAPIHandler::BindingMap &Bindings, Poco::Logger & Logger) {
 | 
				
			||||||
 | 
					        static_assert(test_has_PathName_method((T*)nullptr), "Class must have a static PathName() method.");
 | 
				
			||||||
 | 
					        if(RESTAPIHandler::ParseBindings(RequestedPath,T::PathName(),Bindings)) {
 | 
				
			||||||
 | 
					            return new T(Bindings, Logger, true);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if constexpr (sizeof...(Args) == 0) {
 | 
				
			||||||
 | 
					            return new RESTAPI_UnknownRequestHandler(Bindings,Logger);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return RESTAPI_Router_I<Args...>(RequestedPath, Bindings, Logger);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif //UCENTRAL_RESTAPI_HANDLER_H
 | 
					#endif //UCENTRAL_RESTAPI_HANDLER_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,11 +10,11 @@
 | 
				
			|||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
	class RESTAPI_ouis : public RESTAPIHandler {
 | 
						class RESTAPI_ouis : public RESTAPIHandler {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		RESTAPI_ouis(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
 | 
							RESTAPI_ouis(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
 | 
				
			||||||
			: RESTAPIHandler(bindings, L,
 | 
								: RESTAPIHandler(bindings, L,
 | 
				
			||||||
							 std::vector<std::string>{
 | 
												 std::vector<std::string>{
 | 
				
			||||||
								 Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
 | 
													 Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
 | 
				
			||||||
								 Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
 | 
													 Poco::Net::HTTPRequest::HTTP_OPTIONS}, Internal) {}
 | 
				
			||||||
		void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
							void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
				
			||||||
						   Poco::Net::HTTPServerResponse &response) override;
 | 
											   Poco::Net::HTTPServerResponse &response) override;
 | 
				
			||||||
		static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/ouis"};}
 | 
							static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/ouis"};}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -72,9 +72,7 @@ namespace uCentral::RESTAPI::Protocol {
 | 
				
			|||||||
	static const char * REASON = "reason";
 | 
						static const char * REASON = "reason";
 | 
				
			||||||
	static const char * FILEUUID = "uuid";
 | 
						static const char * FILEUUID = "uuid";
 | 
				
			||||||
	static const char * USERID = "userId";
 | 
						static const char * USERID = "userId";
 | 
				
			||||||
    static const char * USERS = "users";
 | 
					 | 
				
			||||||
	static const char * PASSWORD = "password";
 | 
						static const char * PASSWORD = "password";
 | 
				
			||||||
    static const char * NEWPASSWORD = "newPassword";
 | 
					 | 
				
			||||||
	static const char * TOKEN = "token";
 | 
						static const char * TOKEN = "token";
 | 
				
			||||||
	static const char * SETLOGLEVEL = "setloglevel";
 | 
						static const char * SETLOGLEVEL = "setloglevel";
 | 
				
			||||||
	static const char * GETLOGLEVELS = "getloglevels";
 | 
						static const char * GETLOGLEVELS = "getloglevels";
 | 
				
			||||||
@@ -89,6 +87,42 @@ namespace uCentral::RESTAPI::Protocol {
 | 
				
			|||||||
	static const char * LIST = "list";
 | 
						static const char * LIST = "list";
 | 
				
			||||||
	static const char * TAG = "tag";
 | 
						static const char * TAG = "tag";
 | 
				
			||||||
	static const char * TAGLIST = "tagList";
 | 
						static const char * TAGLIST = "tagList";
 | 
				
			||||||
 | 
					    static const char * DESCRIPTION = "description";
 | 
				
			||||||
 | 
					    static const char * NOTES = "notes";
 | 
				
			||||||
 | 
					    static const char * DEVICETYPE = "deviceType";
 | 
				
			||||||
 | 
					    static const char * REVISION = "revision";
 | 
				
			||||||
 | 
					    static const char * AGES = "ages";
 | 
				
			||||||
 | 
					    static const char * REVISIONS = "revisions";
 | 
				
			||||||
 | 
					    static const char * DEVICETYPES = "deviceTypes";
 | 
				
			||||||
 | 
					    static const char * LATESTONLY = "latestOnly";
 | 
				
			||||||
 | 
					    static const char * IDONLY = "idOnly";
 | 
				
			||||||
 | 
					    static const char * REVISIONSET = "revisionSet";
 | 
				
			||||||
 | 
					    static const char * DEVICESET = "deviceSet";
 | 
				
			||||||
 | 
					    static const char * HISTORY = "history";
 | 
				
			||||||
 | 
					    static const char * ID = "id";
 | 
				
			||||||
 | 
					    static const char * VERSION = "version";
 | 
				
			||||||
 | 
					    static const char * TIMES = "times";
 | 
				
			||||||
 | 
					    static const char * UPTIME = "uptime";
 | 
				
			||||||
 | 
					    static const char * START = "start";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static const char * NEWPASSWORD = "newPassword";
 | 
				
			||||||
 | 
					    static const char * USERS = "users";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static const char * ERRORTEXT = "errorText";
 | 
				
			||||||
 | 
					    static const char * ERRORCODE = "errorCode";
 | 
				
			||||||
 | 
					    static const char * AVATARID = "avatarId";
 | 
				
			||||||
 | 
					    static const char * UNNAMED = "(unnamed)";
 | 
				
			||||||
 | 
					    static const char * UNSPECIFIED = "(unspecified)";
 | 
				
			||||||
 | 
					    static const char * CONTENTDISPOSITION = "Content-Disposition";
 | 
				
			||||||
 | 
					    static const char * CONTENTTYPE = "Content-Type";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static const char * REQUIREMENTS = "requirements";
 | 
				
			||||||
 | 
					    static const char * PASSWORDPATTERN = "passwordPattern";
 | 
				
			||||||
 | 
					    static const char * ACCESSPOLICY = "accessPolicy";
 | 
				
			||||||
 | 
					    static const char * PASSWORDPOLICY = "passwordPolicy";
 | 
				
			||||||
 | 
					    static const char * FORGOTPASSWORD = "forgotPassword";
 | 
				
			||||||
 | 
					    static const char * ME = "me";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // UCENTRALGW_RESTAPI_PROTOCOL_H
 | 
					#endif // UCENTRALGW_RESTAPI_PROTOCOL_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,6 @@
 | 
				
			|||||||
#include "Poco/URI.h"
 | 
					#include "Poco/URI.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "RESTAPI_BlackList.h"
 | 
					#include "RESTAPI_BlackList.h"
 | 
				
			||||||
#include "RESTAPI_callback.h"
 | 
					 | 
				
			||||||
#include "RESTAPI_command.h"
 | 
					#include "RESTAPI_command.h"
 | 
				
			||||||
#include "RESTAPI_commands.h"
 | 
					#include "RESTAPI_commands.h"
 | 
				
			||||||
#include "RESTAPI_default_configuration.h"
 | 
					#include "RESTAPI_default_configuration.h"
 | 
				
			||||||
@@ -22,6 +21,7 @@
 | 
				
			|||||||
#include "RESTAPI_file.h"
 | 
					#include "RESTAPI_file.h"
 | 
				
			||||||
#include "RESTAPI_system_command.h"
 | 
					#include "RESTAPI_system_command.h"
 | 
				
			||||||
#include "RESTAPI_ouis.h"
 | 
					#include "RESTAPI_ouis.h"
 | 
				
			||||||
 | 
					#include "RESTAPI_deviceDashboardHandler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Utils.h"
 | 
					#include "Utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -84,8 +84,8 @@ namespace uCentral {
 | 
				
			|||||||
							  	RESTAPI_ouis,
 | 
												  	RESTAPI_ouis,
 | 
				
			||||||
								RESTAPI_file,
 | 
													RESTAPI_file,
 | 
				
			||||||
								RESTAPI_system_command,
 | 
													RESTAPI_system_command,
 | 
				
			||||||
								RESTAPI_BlackList,
 | 
													RESTAPI_deviceDashboardHandler,
 | 
				
			||||||
								RESTAPI_callback>(Path,Bindings,Logger_);
 | 
													RESTAPI_BlackList>(Path,Bindings,Logger_);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace
 | 
					}  // namespace
 | 
				
			||||||
@@ -13,40 +13,6 @@
 | 
				
			|||||||
#include "Daemon.h"
 | 
					#include "Daemon.h"
 | 
				
			||||||
#include "RESTAPI_protocol.h"
 | 
					#include "RESTAPI_protocol.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SystemCommandDetails:
 | 
					 | 
				
			||||||
      type: object
 | 
					 | 
				
			||||||
      properties:
 | 
					 | 
				
			||||||
        command:
 | 
					 | 
				
			||||||
          type: string
 | 
					 | 
				
			||||||
          enum:
 | 
					 | 
				
			||||||
            - setloglevel
 | 
					 | 
				
			||||||
            - getloglevel
 | 
					 | 
				
			||||||
            - stats
 | 
					 | 
				
			||||||
        parameters:
 | 
					 | 
				
			||||||
          type: array
 | 
					 | 
				
			||||||
          items:
 | 
					 | 
				
			||||||
            properties:
 | 
					 | 
				
			||||||
              name:
 | 
					 | 
				
			||||||
                type: string
 | 
					 | 
				
			||||||
              value:
 | 
					 | 
				
			||||||
                type: string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    SystemCommandResults:
 | 
					 | 
				
			||||||
      type: object
 | 
					 | 
				
			||||||
      properties:
 | 
					 | 
				
			||||||
        command:
 | 
					 | 
				
			||||||
          type: string
 | 
					 | 
				
			||||||
        result:
 | 
					 | 
				
			||||||
          type: integer
 | 
					 | 
				
			||||||
        resultTxt:
 | 
					 | 
				
			||||||
          type: array
 | 
					 | 
				
			||||||
          items:
 | 
					 | 
				
			||||||
            type: string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
	void RESTAPI_system_command::handleRequest(Poco::Net::HTTPServerRequest &Request,
 | 
						void RESTAPI_system_command::handleRequest(Poco::Net::HTTPServerRequest &Request,
 | 
				
			||||||
											   Poco::Net::HTTPServerResponse &Response) {
 | 
																   Poco::Net::HTTPServerResponse &Response) {
 | 
				
			||||||
@@ -57,70 +23,110 @@ namespace uCentral {
 | 
				
			|||||||
		if (!IsAuthorized(Request, Response))
 | 
							if (!IsAuthorized(Request, Response))
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST)
 | 
				
			||||||
 | 
								DoPost(Request, Response);
 | 
				
			||||||
 | 
							else if(Request.getMethod()==Poco::Net::HTTPRequest::HTTP_GET)
 | 
				
			||||||
 | 
								DoGet(Request, Response);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							BadRequest(Request, Response);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void RESTAPI_system_command::DoPost(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
				if (Request.getMethod() == Poco::Net::HTTPRequest::HTTP_POST) {
 | 
								Poco::JSON::Parser parser;
 | 
				
			||||||
				Poco::JSON::Parser parser;
 | 
								auto Obj = parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
 | 
				
			||||||
				auto Obj = parser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (Obj->has(uCentral::RESTAPI::Protocol::COMMAND)) {
 | 
								if (Obj->has(uCentral::RESTAPI::Protocol::COMMAND)) {
 | 
				
			||||||
					auto Command = Poco::toLower(Obj->get(uCentral::RESTAPI::Protocol::COMMAND).toString());
 | 
									auto Command = Poco::toLower(Obj->get(uCentral::RESTAPI::Protocol::COMMAND).toString());
 | 
				
			||||||
					if (Command == uCentral::RESTAPI::Protocol::SETLOGLEVEL) {
 | 
									if (Command == uCentral::RESTAPI::Protocol::SETLOGLEVEL) {
 | 
				
			||||||
						if (Obj->has(uCentral::RESTAPI::Protocol::PARAMETERS) &&
 | 
										if (Obj->has(uCentral::RESTAPI::Protocol::PARAMETERS) &&
 | 
				
			||||||
							Obj->isArray(uCentral::RESTAPI::Protocol::PARAMETERS)) {
 | 
											Obj->isArray(uCentral::RESTAPI::Protocol::PARAMETERS)) {
 | 
				
			||||||
							auto ParametersBlock = Obj->getArray(uCentral::RESTAPI::Protocol::PARAMETERS);
 | 
											auto ParametersBlock = Obj->getArray(uCentral::RESTAPI::Protocol::PARAMETERS);
 | 
				
			||||||
							for (const auto &i:*ParametersBlock) {
 | 
											for (const auto &i:*ParametersBlock) {
 | 
				
			||||||
								Poco::JSON::Parser pp;
 | 
												Poco::JSON::Parser pp;
 | 
				
			||||||
								auto InnerObj = pp.parse(i).extract<Poco::JSON::Object::Ptr>();
 | 
												auto InnerObj = pp.parse(i).extract<Poco::JSON::Object::Ptr>();
 | 
				
			||||||
								if (InnerObj->has(uCentral::RESTAPI::Protocol::TAG) &&
 | 
												if (InnerObj->has(uCentral::RESTAPI::Protocol::TAG) &&
 | 
				
			||||||
									InnerObj->has(uCentral::RESTAPI::Protocol::VALUE)) {
 | 
													InnerObj->has(uCentral::RESTAPI::Protocol::VALUE)) {
 | 
				
			||||||
									auto Name = GetS(uCentral::RESTAPI::Protocol::TAG, InnerObj);
 | 
													auto Name = GetS(uCentral::RESTAPI::Protocol::TAG, InnerObj);
 | 
				
			||||||
									auto Value = GetS(uCentral::RESTAPI::Protocol::VALUE, InnerObj);
 | 
													auto Value = GetS(uCentral::RESTAPI::Protocol::VALUE, InnerObj);
 | 
				
			||||||
									Daemon()->SetSubsystemLogLevel(Name, Value);
 | 
													Daemon()->SetSubsystemLogLevel(Name, Value);
 | 
				
			||||||
									Logger_.information(Poco::format("Setting log level for %s at %s", Name, Value));
 | 
													Logger_.information(Poco::format("Setting log level for %s at %s", Name, Value));
 | 
				
			||||||
								}
 | 
					 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
							OK(Request, Response);
 | 
					 | 
				
			||||||
							return;
 | 
					 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					} else if (Command == uCentral::RESTAPI::Protocol::GETLOGLEVELS) {
 | 
											OK(Request, Response);
 | 
				
			||||||
						auto CurrentLogLevels = Daemon()->GetLogLevels();
 | 
					 | 
				
			||||||
						Poco::JSON::Object	Result;
 | 
					 | 
				
			||||||
						Poco::JSON::Array	Array;
 | 
					 | 
				
			||||||
						for(auto &[Name,Level]:CurrentLogLevels) {
 | 
					 | 
				
			||||||
							Poco::JSON::Object	Pair;
 | 
					 | 
				
			||||||
							Pair.set( uCentral::RESTAPI::Protocol::TAG,Name);
 | 
					 | 
				
			||||||
							Pair.set(uCentral::RESTAPI::Protocol::VALUE,Level);
 | 
					 | 
				
			||||||
							Array.add(Pair);
 | 
					 | 
				
			||||||
						}
 | 
					 | 
				
			||||||
						Result.set(uCentral::RESTAPI::Protocol::TAGLIST,Array);
 | 
					 | 
				
			||||||
						ReturnObject(Request,Result,Response);
 | 
					 | 
				
			||||||
						return;
 | 
											return;
 | 
				
			||||||
					} else if (Command == uCentral::RESTAPI::Protocol::GETLOGLEVELNAMES) {
 | 
					 | 
				
			||||||
						Poco::JSON::Object	Result;
 | 
					 | 
				
			||||||
						Poco::JSON::Array	LevelNamesArray;
 | 
					 | 
				
			||||||
						const Types::StringVec & LevelNames = Daemon()->GetLogLevelNames();
 | 
					 | 
				
			||||||
						for(const auto &i:LevelNames)
 | 
					 | 
				
			||||||
							LevelNamesArray.add(i);
 | 
					 | 
				
			||||||
						Result.set(uCentral::RESTAPI::Protocol::LIST,LevelNamesArray);
 | 
					 | 
				
			||||||
						ReturnObject(Request,Result,Response);
 | 
					 | 
				
			||||||
						return;
 | 
					 | 
				
			||||||
					} else if (Command == uCentral::RESTAPI::Protocol::GETSUBSYSTEMNAMES) {
 | 
					 | 
				
			||||||
						Poco::JSON::Object	Result;
 | 
					 | 
				
			||||||
						Poco::JSON::Array	LevelNamesArray;
 | 
					 | 
				
			||||||
						const Types::StringVec & SubSystemNames = Daemon()->GetSubSystems();
 | 
					 | 
				
			||||||
						for(const auto &i:SubSystemNames)
 | 
					 | 
				
			||||||
							LevelNamesArray.add(i);
 | 
					 | 
				
			||||||
						Result.set(uCentral::RESTAPI::Protocol::LIST,LevelNamesArray);
 | 
					 | 
				
			||||||
						ReturnObject(Request,Result,Response);
 | 
					 | 
				
			||||||
						return;
 | 
					 | 
				
			||||||
					} else if (Command == uCentral::RESTAPI::Protocol::STATS) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
 | 
									} else if (Command == uCentral::RESTAPI::Protocol::GETLOGLEVELS) {
 | 
				
			||||||
 | 
										auto CurrentLogLevels = Daemon()->GetLogLevels();
 | 
				
			||||||
 | 
										Poco::JSON::Object	Result;
 | 
				
			||||||
 | 
										Poco::JSON::Array	Array;
 | 
				
			||||||
 | 
										for(auto &[Name,Level]:CurrentLogLevels) {
 | 
				
			||||||
 | 
											Poco::JSON::Object	Pair;
 | 
				
			||||||
 | 
											Pair.set( uCentral::RESTAPI::Protocol::TAG,Name);
 | 
				
			||||||
 | 
											Pair.set(uCentral::RESTAPI::Protocol::VALUE,Level);
 | 
				
			||||||
 | 
											Array.add(Pair);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										Result.set(uCentral::RESTAPI::Protocol::TAGLIST,Array);
 | 
				
			||||||
 | 
										ReturnObject(Request,Result,Response);
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									} else if (Command == uCentral::RESTAPI::Protocol::GETLOGLEVELNAMES) {
 | 
				
			||||||
 | 
										Poco::JSON::Object	Result;
 | 
				
			||||||
 | 
										Poco::JSON::Array	LevelNamesArray;
 | 
				
			||||||
 | 
										const Types::StringVec & LevelNames = Daemon()->GetLogLevelNames();
 | 
				
			||||||
 | 
										for(const auto &i:LevelNames)
 | 
				
			||||||
 | 
											LevelNamesArray.add(i);
 | 
				
			||||||
 | 
										Result.set(uCentral::RESTAPI::Protocol::LIST,LevelNamesArray);
 | 
				
			||||||
 | 
										ReturnObject(Request,Result,Response);
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									} else if (Command == uCentral::RESTAPI::Protocol::GETSUBSYSTEMNAMES) {
 | 
				
			||||||
 | 
										Poco::JSON::Object	Result;
 | 
				
			||||||
 | 
										Poco::JSON::Array	LevelNamesArray;
 | 
				
			||||||
 | 
										const Types::StringVec & SubSystemNames = Daemon()->GetSubSystems();
 | 
				
			||||||
 | 
										for(const auto &i:SubSystemNames)
 | 
				
			||||||
 | 
											LevelNamesArray.add(i);
 | 
				
			||||||
 | 
										Result.set(uCentral::RESTAPI::Protocol::LIST,LevelNamesArray);
 | 
				
			||||||
 | 
										ReturnObject(Request,Result,Response);
 | 
				
			||||||
 | 
										return;
 | 
				
			||||||
 | 
									} else if (Command == uCentral::RESTAPI::Protocol::STATS) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							} catch(const Poco::Exception &E) {
 | 
				
			||||||
 | 
								Logger_.log(E);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							BadRequest(Request, Response);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void RESTAPI_system_command::DoGet(Poco::Net::HTTPServerRequest &Request, Poco::Net::HTTPServerResponse &Response) {
 | 
				
			||||||
 | 
							try {
 | 
				
			||||||
 | 
								ParseParameters(Request);
 | 
				
			||||||
 | 
								auto Command = GetParameter(RESTAPI::Protocol::COMMAND, "");
 | 
				
			||||||
 | 
								if (!Poco::icompare(Command, RESTAPI::Protocol::VERSION)) {
 | 
				
			||||||
 | 
									Poco::JSON::Object Answer;
 | 
				
			||||||
 | 
									Answer.set(RESTAPI::Protocol::TAG, RESTAPI::Protocol::VERSION);
 | 
				
			||||||
 | 
									Answer.set(RESTAPI::Protocol::VALUE, Daemon()->Version());
 | 
				
			||||||
 | 
									ReturnObject(Request, Answer, Response);
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (!Poco::icompare(Command, RESTAPI::Protocol::TIMES)) {
 | 
				
			||||||
 | 
									Poco::JSON::Array	Array;
 | 
				
			||||||
 | 
									Poco::JSON::Object 	Answer;
 | 
				
			||||||
 | 
									Poco::JSON::Object	UpTimeObj;
 | 
				
			||||||
 | 
									UpTimeObj.set(RESTAPI::Protocol::TAG,RESTAPI::Protocol::UPTIME);
 | 
				
			||||||
 | 
									UpTimeObj.set(RESTAPI::Protocol::VALUE, Daemon()->uptime().totalSeconds());
 | 
				
			||||||
 | 
									Poco::JSON::Object	StartObj;
 | 
				
			||||||
 | 
									StartObj.set(RESTAPI::Protocol::TAG,RESTAPI::Protocol::START);
 | 
				
			||||||
 | 
									StartObj.set(RESTAPI::Protocol::VALUE, Daemon()->startTime().epochTime());
 | 
				
			||||||
 | 
									Array.add(UpTimeObj);
 | 
				
			||||||
 | 
									Array.add(StartObj);
 | 
				
			||||||
 | 
									Answer.set(RESTAPI::Protocol::TIMES, Array);
 | 
				
			||||||
 | 
									ReturnObject(Request, Answer, Response);
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		} catch (const Poco::Exception &E) {
 | 
							} catch (const Poco::Exception &E) {
 | 
				
			||||||
			Logger_.log(E);
 | 
								Logger_.log(E);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		BadRequest(Request, Response);
 | 
							BadRequest(Request, Response);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -14,13 +14,19 @@
 | 
				
			|||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
class RESTAPI_system_command : public RESTAPIHandler {
 | 
					class RESTAPI_system_command : public RESTAPIHandler {
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
	RESTAPI_system_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L)
 | 
						RESTAPI_system_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, bool Internal)
 | 
				
			||||||
		: RESTAPIHandler(bindings, L,
 | 
							: RESTAPIHandler(bindings, L,
 | 
				
			||||||
						 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
 | 
											 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
 | 
				
			||||||
												  Poco::Net::HTTPRequest::HTTP_OPTIONS}) {}
 | 
																			  Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
 | 
																			  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
 | 
											 Internal) {}
 | 
				
			||||||
	void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
						void handleRequest(Poco::Net::HTTPServerRequest &request,
 | 
				
			||||||
					   Poco::Net::HTTPServerResponse &response) override;
 | 
										   Poco::Net::HTTPServerResponse &response) override;
 | 
				
			||||||
	static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/system"};}
 | 
						static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/system"};}
 | 
				
			||||||
};
 | 
						void DoGet(Poco::Net::HTTPServerRequest &Request,
 | 
				
			||||||
 | 
								   Poco::Net::HTTPServerResponse &Response);
 | 
				
			||||||
 | 
						void DoPost(Poco::Net::HTTPServerRequest &Request,
 | 
				
			||||||
 | 
									Poco::Net::HTTPServerResponse &Response);
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif // UCENTRALGW_RESTAPI_SYSTEM_COMMAND_H
 | 
					#endif // UCENTRALGW_RESTAPI_SYSTEM_COMMAND_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "Poco/JSON/Object.h"
 | 
					#include "Poco/JSON/Object.h"
 | 
				
			||||||
#include "Poco/JSON/Parser.h"
 | 
					#include "Poco/JSON/Parser.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/HTTPServerRequest.h"
 | 
				
			||||||
#include "uCentralTypes.h"
 | 
					#include "uCentralTypes.h"
 | 
				
			||||||
#include "Utils.h"
 | 
					#include "Utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -38,7 +39,19 @@ namespace uCentral::RESTAPI_utils {
 | 
				
			|||||||
		Obj.set(Field,A);
 | 
							Obj.set(Field,A);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template<typename T> void field_to_json(Poco::JSON::Object &Obj,
 | 
					    inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::CountedMap &M) {
 | 
				
			||||||
 | 
					        Poco::JSON::Array	A;
 | 
				
			||||||
 | 
					        for(const auto &[Key,Value]:M) {
 | 
				
			||||||
 | 
					            Poco::JSON::Object  O;
 | 
				
			||||||
 | 
					            O.set("tag",Key);
 | 
				
			||||||
 | 
					            O.set("value", Value);
 | 
				
			||||||
 | 
					            A.add(O);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Obj.set(Field,A);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<typename T> void field_to_json(Poco::JSON::Object &Obj,
 | 
				
			||||||
					   						const char *Field,
 | 
										   						const char *Field,
 | 
				
			||||||
					   						const T &V,
 | 
										   						const T &V,
 | 
				
			||||||
											std::function<std::string(const T &)> F) {
 | 
																std::function<std::string(const T &)> F) {
 | 
				
			||||||
@@ -191,6 +204,13 @@ namespace uCentral::RESTAPI_utils {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return Result;
 | 
							return Result;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    template<class T> bool from_request(T & Obj, Poco::Net::HTTPServerRequest &Request) {
 | 
				
			||||||
 | 
					        Poco::JSON::Parser IncomingParser;
 | 
				
			||||||
 | 
					        auto RawObject = IncomingParser.parse(Request.stream()).extract<Poco::JSON::Object::Ptr>();
 | 
				
			||||||
 | 
					        Obj.from_json(RawObject);
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // UCENTRALGW_RESTAPI_UTILS_H
 | 
					#endif // UCENTRALGW_RESTAPI_UTILS_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,8 +56,6 @@ namespace uCentral {
 | 
				
			|||||||
            Setup_PostgreSQL();
 | 
					            Setup_PostgreSQL();
 | 
				
			||||||
        } else if (DBType == "mysql") {
 | 
					        } else if (DBType == "mysql") {
 | 
				
			||||||
            Setup_MySQL();
 | 
					            Setup_MySQL();
 | 
				
			||||||
        } else if (DBType == "odbc") {
 | 
					 | 
				
			||||||
            Setup_ODBC();
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Create_Tables();
 | 
							Create_Tables();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,6 @@
 | 
				
			|||||||
#ifndef SMALL_BUILD
 | 
					#ifndef SMALL_BUILD
 | 
				
			||||||
#include "Poco/Data/PostgreSQL/Connector.h"
 | 
					#include "Poco/Data/PostgreSQL/Connector.h"
 | 
				
			||||||
#include "Poco/Data/MySQL/Connector.h"
 | 
					#include "Poco/Data/MySQL/Connector.h"
 | 
				
			||||||
#include "Poco/Data/ODBC/Connector.h"
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "RESTAPI_GWobjects.h"
 | 
					#include "RESTAPI_GWobjects.h"
 | 
				
			||||||
@@ -30,8 +29,7 @@ namespace uCentral {
 | 
				
			|||||||
		enum StorageType {
 | 
							enum StorageType {
 | 
				
			||||||
			sqlite,
 | 
								sqlite,
 | 
				
			||||||
			pgsql,
 | 
								pgsql,
 | 
				
			||||||
			mysql,
 | 
								mysql
 | 
				
			||||||
			odbc
 | 
					 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		enum CommandExecutionType {
 | 
							enum CommandExecutionType {
 | 
				
			||||||
@@ -65,7 +63,7 @@ namespace uCentral {
 | 
				
			|||||||
		bool UpdateDeviceConfiguration(std::string &SerialNumber, std::string &Configuration, uint64_t & NewUUID );
 | 
							bool UpdateDeviceConfiguration(std::string &SerialNumber, std::string &Configuration, uint64_t & NewUUID );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool CreateDevice(GWObjects::Device &);
 | 
							bool CreateDevice(GWObjects::Device &);
 | 
				
			||||||
		bool CreateDefaultDevice(const std::string & SerialNumber, const std::string & Capabilities, std::string & Firmware);
 | 
							bool CreateDefaultDevice(const std::string & SerialNumber, const std::string & Capabilities, std::string & Firmware, std::string &Compatible);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool GetDevice(std::string &SerialNumber, GWObjects::Device &);
 | 
							bool GetDevice(std::string &SerialNumber, GWObjects::Device &);
 | 
				
			||||||
		bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices);
 | 
							bool GetDevices(uint64_t From, uint64_t HowMany, std::vector<GWObjects::Device> &Devices);
 | 
				
			||||||
@@ -86,7 +84,7 @@ namespace uCentral {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		bool ExistingConfiguration(std::string &SerialNumber, uint64_t CurrentConfig, std::string &NewConfig, uint64_t &);
 | 
							bool ExistingConfiguration(std::string &SerialNumber, uint64_t CurrentConfig, std::string &NewConfig, uint64_t &);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool UpdateDeviceCapabilities(std::string &SerialNumber, std::string &State);
 | 
							bool UpdateDeviceCapabilities(std::string &SerialNumber, std::string &State, std::string & Compatible);
 | 
				
			||||||
		bool GetDeviceCapabilities(std::string &SerialNumber, GWObjects::Capabilities &);
 | 
							bool GetDeviceCapabilities(std::string &SerialNumber, GWObjects::Capabilities &);
 | 
				
			||||||
		bool DeleteDeviceCapabilities(std::string & SerialNumber);
 | 
							bool DeleteDeviceCapabilities(std::string & SerialNumber);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -145,6 +143,8 @@ namespace uCentral {
 | 
				
			|||||||
		int Create_FileUploads();
 | 
							int Create_FileUploads();
 | 
				
			||||||
		int Create_LifetimeStats();
 | 
							int Create_LifetimeStats();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							bool AnalyzeCommands(Types::CountedMap &R);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		int 	Start() override;
 | 
							int 	Start() override;
 | 
				
			||||||
		void 	Stop() override;
 | 
							void 	Stop() override;
 | 
				
			||||||
		int 	Setup_SQLite();
 | 
							int 	Setup_SQLite();
 | 
				
			||||||
@@ -153,7 +153,6 @@ namespace uCentral {
 | 
				
			|||||||
#ifndef SMALL_BUILD
 | 
					#ifndef SMALL_BUILD
 | 
				
			||||||
		int 	Setup_MySQL();
 | 
							int 	Setup_MySQL();
 | 
				
			||||||
		int 	Setup_PostgreSQL();
 | 
							int 	Setup_PostgreSQL();
 | 
				
			||||||
		int 	Setup_ODBC();
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
@@ -164,7 +163,6 @@ namespace uCentral {
 | 
				
			|||||||
#ifndef SMALL_BUILD
 | 
					#ifndef SMALL_BUILD
 | 
				
			||||||
		std::unique_ptr<Poco::Data::PostgreSQL::Connector>  PostgresConn_= nullptr;
 | 
							std::unique_ptr<Poco::Data::PostgreSQL::Connector>  PostgresConn_= nullptr;
 | 
				
			||||||
		std::unique_ptr<Poco::Data::MySQL::Connector>       MySQLConn_= nullptr;
 | 
							std::unique_ptr<Poco::Data::MySQL::Connector>       MySQLConn_= nullptr;
 | 
				
			||||||
		std::unique_ptr<Poco::Data::ODBC::Connector>        ODBCConn_= nullptr;
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Storage() noexcept;
 | 
							Storage() noexcept;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -117,7 +117,7 @@ Poco::Net::SecureServerSocket PropertiesFileServerEntry::CreateSecureSocket(Poco
 | 
				
			|||||||
	auto Context = Poco::AutoPtr<Poco::Net::Context>(new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
 | 
						auto Context = Poco::AutoPtr<Poco::Net::Context>(new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if(!key_file_password_.empty()) {
 | 
						if(!key_file_password_.empty()) {
 | 
				
			||||||
		auto PassphraseHandler = Poco::SharedPtr<MyPrivateKeyPassphraseHandler>( new MyPrivateKeyPassphraseHandler(KeyFilePassword(),L));
 | 
							auto PassphraseHandler = Poco::SharedPtr<MyPrivateKeyPassphraseHandler>( new MyPrivateKeyPassphraseHandler(key_file_password_,L));
 | 
				
			||||||
		Poco::Net::SSLManager::instance().initializeServer(PassphraseHandler, nullptr,Context);
 | 
							Poco::Net::SSLManager::instance().initializeServer(PassphraseHandler, nullptr,Context);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -142,7 +142,7 @@ Poco::Net::SecureServerSocket PropertiesFileServerEntry::CreateSecureSocket(Poco
 | 
				
			|||||||
			Context->addCertificateAuthority(Issuing);
 | 
								Context->addCertificateAuthority(Issuing);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Poco::Crypto::RSAKey Key("", key_file_, "");
 | 
							Poco::Crypto::RSAKey Key("", key_file_, key_file_password_);
 | 
				
			||||||
		Context->usePrivateKey(Key);
 | 
							Context->usePrivateKey(Key);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		SSL_CTX *SSLCtx = Context->sslContext();
 | 
							SSL_CTX *SSLCtx = Context->sslContext();
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										117
									
								
								src/Utils.cpp
									
									
									
									
									
								
							
							
						
						
									
										117
									
								
								src/Utils.cpp
									
									
									
									
									
								
							@@ -9,6 +9,8 @@
 | 
				
			|||||||
#include <fstream>
 | 
					#include <fstream>
 | 
				
			||||||
#include <cstdlib>
 | 
					#include <cstdlib>
 | 
				
			||||||
#include <regex>
 | 
					#include <regex>
 | 
				
			||||||
 | 
					#include <random>
 | 
				
			||||||
 | 
					#include <chrono>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Utils.h"
 | 
					#include "Utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -363,8 +365,11 @@ namespace uCentral::Utils {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint64_t InitializeSystemId() {
 | 
						uint64_t InitializeSystemId() {
 | 
				
			||||||
		std::srand(std::time(nullptr));
 | 
							std::random_device	RDev;
 | 
				
			||||||
		auto S = GetDefaultMacAsInt64() ^ std::rand();
 | 
							std::srand(RDev());
 | 
				
			||||||
 | 
							std::chrono::high_resolution_clock	Clock;
 | 
				
			||||||
 | 
							auto Now = Clock.now().time_since_epoch().count();
 | 
				
			||||||
 | 
							auto S = (GetDefaultMacAsInt64() + std::rand() + Now)  ;
 | 
				
			||||||
		SaveSystemId(S);
 | 
							SaveSystemId(S);
 | 
				
			||||||
		std::cout << "ID: " << S << std::endl;
 | 
							std::cout << "ID: " << S << std::endl;
 | 
				
			||||||
		return S;
 | 
							return S;
 | 
				
			||||||
@@ -420,26 +425,31 @@ namespace uCentral::Utils {
 | 
				
			|||||||
	    }
 | 
						    }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::string FindMediaType(const Poco::File &F) {
 | 
					    MediaTypeEncoding FindMediaType(const Poco::File &F) {
 | 
				
			||||||
	    Poco::Path  P(F.path());
 | 
						    const auto E = Poco::Path(F.path()).getExtension();
 | 
				
			||||||
	    const auto E = P.getExtension();
 | 
					 | 
				
			||||||
	    if(E=="png")
 | 
						    if(E=="png")
 | 
				
			||||||
	        return "image/png";
 | 
						        return MediaTypeEncoding{   .Encoding = BINARY,
 | 
				
			||||||
 | 
					                                        .ContentType = "image/png" };
 | 
				
			||||||
	    if(E=="gif")
 | 
						    if(E=="gif")
 | 
				
			||||||
            return "image/gif";
 | 
					            return MediaTypeEncoding{   .Encoding = BINARY,
 | 
				
			||||||
        if(E=="jpeg")
 | 
					                                        .ContentType = "image/gif" };
 | 
				
			||||||
            return "image/jpeg";
 | 
					        if(E=="jpeg" || E=="jpg")
 | 
				
			||||||
        if(E=="jpg")
 | 
					            return MediaTypeEncoding{   .Encoding = BINARY,
 | 
				
			||||||
            return "image/jpeg";
 | 
					                                        .ContentType = "image/jpeg" };
 | 
				
			||||||
        if(E=="svg")
 | 
					        if(E=="svg" || E=="svgz")
 | 
				
			||||||
            return "image/svg";
 | 
					            return MediaTypeEncoding{   .Encoding = PLAIN,
 | 
				
			||||||
 | 
					                                        .ContentType = "image/svg+xml" };
 | 
				
			||||||
        if(E=="html")
 | 
					        if(E=="html")
 | 
				
			||||||
            return "text/html";
 | 
					            return MediaTypeEncoding{   .Encoding = PLAIN,
 | 
				
			||||||
 | 
					                                        .ContentType = "text/html" };
 | 
				
			||||||
        if(E=="css")
 | 
					        if(E=="css")
 | 
				
			||||||
            return "text/css";
 | 
					            return MediaTypeEncoding{   .Encoding = PLAIN,
 | 
				
			||||||
 | 
					                                        .ContentType = "text/css" };
 | 
				
			||||||
        if(E=="js")
 | 
					        if(E=="js")
 | 
				
			||||||
            return "application/javascript";
 | 
					            return MediaTypeEncoding{   .Encoding = PLAIN,
 | 
				
			||||||
        return "application/octet-stream";
 | 
					                                        .ContentType = "application/javascript" };
 | 
				
			||||||
 | 
					        return MediaTypeEncoding{       .Encoding = BINARY,
 | 
				
			||||||
 | 
					                                        .ContentType = "application/octet-stream" };
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::string BinaryFileToHexString(const Poco::File &F) {
 | 
						std::string BinaryFileToHexString(const Poco::File &F) {
 | 
				
			||||||
@@ -466,6 +476,79 @@ namespace uCentral::Utils {
 | 
				
			|||||||
        return Result;
 | 
					        return Result;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string SecondsToNiceText(uint64_t Seconds) {
 | 
				
			||||||
 | 
						    std::string Result;
 | 
				
			||||||
 | 
						    int Days = Seconds / (24*60*60);
 | 
				
			||||||
 | 
						    Seconds -= Days * (24*60*60);
 | 
				
			||||||
 | 
						    int Hours= Seconds / (60*60);
 | 
				
			||||||
 | 
						    Seconds -= Hours * (60*60);
 | 
				
			||||||
 | 
						    int Minutes = Seconds / 60;
 | 
				
			||||||
 | 
						    Seconds -= Minutes * 60;
 | 
				
			||||||
 | 
						    Result = std::to_string(Days) +" days, " + std::to_string(Hours) + ":" + std::to_string(Minutes) + ":" + std::to_string(Seconds);
 | 
				
			||||||
 | 
						    return Result;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static bool cidr_match(const in_addr &addr, const in_addr &net, uint8_t bits) {
 | 
				
			||||||
 | 
							if (bits == 0) {
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return !((addr.s_addr ^ net.s_addr) & htonl(0xFFFFFFFFu << (32 - bits)));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static bool cidr6_match(const in6_addr &address, const in6_addr &network, uint8_t bits) {
 | 
				
			||||||
 | 
					#ifdef __linux__
 | 
				
			||||||
 | 
							const uint32_t *a = address.s6_addr32;
 | 
				
			||||||
 | 
							const uint32_t *n = network.s6_addr32;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
							const uint32_t *a = address.__u6_addr.__u6_addr32;
 | 
				
			||||||
 | 
							const uint32_t *n = network.__u6_addr.__u6_addr32;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
							int bits_whole, bits_incomplete;
 | 
				
			||||||
 | 
							bits_whole = bits >> 5;         // number of whole u32
 | 
				
			||||||
 | 
							bits_incomplete = bits & 0x1F;  // number of bits in incomplete u32
 | 
				
			||||||
 | 
							if (bits_whole) {
 | 
				
			||||||
 | 
								if (memcmp(a, n, bits_whole << 2)!=0) {
 | 
				
			||||||
 | 
									return false;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (bits_incomplete) {
 | 
				
			||||||
 | 
								uint32_t mask = htonl((0xFFFFFFFFu) << (32 - bits_incomplete));
 | 
				
			||||||
 | 
								if ((a[bits_whole] ^ n[bits_whole]) & mask) {
 | 
				
			||||||
 | 
									return false;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						static bool ConvertStringToLong(const char *S, unsigned long &L) {
 | 
				
			||||||
 | 
							char *end;
 | 
				
			||||||
 | 
							L = std::strtol(S,&end,10);
 | 
				
			||||||
 | 
							return end != S;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool IPinRange(const std::string &Range, const Poco::Net::IPAddress &IP) {
 | 
				
			||||||
 | 
							Poco::StringTokenizer	TimeTokens(Range,"/",Poco::StringTokenizer::TOK_TRIM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							Poco::Net::IPAddress	RangeIP;
 | 
				
			||||||
 | 
							if(Poco::Net::IPAddress::tryParse(TimeTokens[0],RangeIP)) {
 | 
				
			||||||
 | 
								if(TimeTokens.count()==2) {
 | 
				
			||||||
 | 
									if (RangeIP.family() == Poco::Net::IPAddress::IPv4) {
 | 
				
			||||||
 | 
										unsigned long MaskLength;
 | 
				
			||||||
 | 
										if (ConvertStringToLong(TimeTokens[1].c_str(), MaskLength)) {
 | 
				
			||||||
 | 
											return cidr_match(*static_cast<const in_addr *>(RangeIP.addr()),
 | 
				
			||||||
 | 
															  *static_cast<const in_addr *>(IP.addr()), MaskLength);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									} else if (RangeIP.family() == Poco::Net::IPAddress::IPv6) {
 | 
				
			||||||
 | 
										unsigned long MaskLength;
 | 
				
			||||||
 | 
										if (ConvertStringToLong(TimeTokens[1].c_str(), MaskLength)) {
 | 
				
			||||||
 | 
											return cidr6_match(*static_cast<const in6_addr *>(RangeIP.addr()),
 | 
				
			||||||
 | 
															   *static_cast<const in6_addr *>(IP.addr()), MaskLength);
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										17
									
								
								src/Utils.h
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								src/Utils.h
									
									
									
									
									
								
							@@ -13,6 +13,7 @@
 | 
				
			|||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/Net/NetworkInterface.h"
 | 
					#include "Poco/Net/NetworkInterface.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/IPAddress.h"
 | 
				
			||||||
#include "Poco/String.h"
 | 
					#include "Poco/String.h"
 | 
				
			||||||
#include "Poco/File.h"
 | 
					#include "Poco/File.h"
 | 
				
			||||||
#include "uCentralTypes.h"
 | 
					#include "uCentralTypes.h"
 | 
				
			||||||
@@ -21,6 +22,16 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace uCentral::Utils {
 | 
					namespace uCentral::Utils {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    enum MediaTypeEncodings {
 | 
				
			||||||
 | 
					        PLAIN,
 | 
				
			||||||
 | 
					        BINARY,
 | 
				
			||||||
 | 
					        BASE64
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    struct MediaTypeEncoding {
 | 
				
			||||||
 | 
					        MediaTypeEncodings  Encoding=PLAIN;
 | 
				
			||||||
 | 
					        std::string         ContentType;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] std::vector<std::string> Split(const std::string &List, char Delimiter=',');
 | 
						[[nodiscard]] std::vector<std::string> Split(const std::string &List, char Delimiter=',');
 | 
				
			||||||
	[[nodiscard]] std::string FormatIPv6(const std::string & I );
 | 
						[[nodiscard]] std::string FormatIPv6(const std::string & I );
 | 
				
			||||||
	inline void padTo(std::string& str, size_t num, char paddingChar = '\0') {
 | 
						inline void padTo(std::string& str, size_t num, char paddingChar = '\0') {
 | 
				
			||||||
@@ -56,7 +67,11 @@ namespace uCentral::Utils {
 | 
				
			|||||||
	[[nodiscard]] std::string LoadFile( const Poco::File & F);
 | 
						[[nodiscard]] std::string LoadFile( const Poco::File & F);
 | 
				
			||||||
    void ReplaceVariables( std::string & Content , const Types::StringPairVec & P);
 | 
					    void ReplaceVariables( std::string & Content , const Types::StringPairVec & P);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [[nodiscard]] std::string FindMediaType(const Poco::File &F);
 | 
					    [[nodiscard]] MediaTypeEncoding FindMediaType(const Poco::File &F);
 | 
				
			||||||
    [[nodiscard]] std::string BinaryFileToHexString( const Poco::File &F);
 | 
					    [[nodiscard]] std::string BinaryFileToHexString( const Poco::File &F);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [[nodiscard]] std::string SecondsToNiceText(uint64_t Seconds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] bool IPinRange(const std::string &Range, const Poco::Net::IPAddress &IP);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif // UCENTRALGW_UTILS_H
 | 
					#endif // UCENTRALGW_UTILS_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -201,7 +201,20 @@ namespace uCentral {
 | 
				
			|||||||
            (*WS_).close();
 | 
					            (*WS_).close();
 | 
				
			||||||
            Registered_ = false ;
 | 
					            Registered_ = false ;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					
 | 
				
			||||||
 | 
							if(KafkaManager()->Enabled() && !SerialNumber_.empty()) {
 | 
				
			||||||
 | 
								Poco::JSON::Object	Disconnect;
 | 
				
			||||||
 | 
								Poco::JSON::Object	Details;
 | 
				
			||||||
 | 
								Details.set(uCentralProtocol::SERIALNUMBER, SerialNumber_);
 | 
				
			||||||
 | 
								Details.set(uCentralProtocol::TIMESTAMP,std::time(nullptr));
 | 
				
			||||||
 | 
								Disconnect.set(uCentralProtocol::DISCONNECTION,Details);
 | 
				
			||||||
 | 
								Poco::JSON::Stringifier		Stringify;
 | 
				
			||||||
 | 
								std::ostringstream OS;
 | 
				
			||||||
 | 
								Stringify.condense(Disconnect,OS);
 | 
				
			||||||
 | 
								KafkaManager()->PostMessage(uCentral::KafkaTopics::CONNECTION, SerialNumber_, OS.str());
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool WSConnection::LookForUpgrade(uint64_t UUID) {
 | 
					    bool WSConnection::LookForUpgrade(uint64_t UUID) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -357,14 +370,16 @@ namespace uCentral {
 | 
				
			|||||||
						}
 | 
											}
 | 
				
			||||||
						Conn_->VerifiedCertificate = CertValidation_;
 | 
											Conn_->VerifiedCertificate = CertValidation_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
											std::string Compatible;
 | 
				
			||||||
						if (Daemon()->AutoProvisioning() && !Storage()->DeviceExists(SerialNumber_)) {
 | 
											if (Daemon()->AutoProvisioning() && !Storage()->DeviceExists(SerialNumber_)) {
 | 
				
			||||||
							Storage()->CreateDefaultDevice(SerialNumber_, Capabilities, Firmware);
 | 
												Storage()->CreateDefaultDevice(SerialNumber_, Capabilities, Firmware, Compatible_);
 | 
				
			||||||
						} else if (Storage()->DeviceExists(SerialNumber_)) {
 | 
											} else if (Storage()->DeviceExists(SerialNumber_)) {
 | 
				
			||||||
							Storage()->UpdateDeviceCapabilities(SerialNumber_, Capabilities);
 | 
												Storage()->UpdateDeviceCapabilities(SerialNumber_, Capabilities, Compatible_);
 | 
				
			||||||
							if(!Firmware.empty()) {
 | 
												if(!Firmware.empty()) {
 | 
				
			||||||
								Storage()->SetConnectInfo(SerialNumber_, Firmware );
 | 
													Storage()->SetConnectInfo(SerialNumber_, Firmware );
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
 | 
											Conn_->Compatible = Compatible_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						StatsProcessor_ = std::make_unique<uCentral::StateProcessor>();
 | 
											StatsProcessor_ = std::make_unique<uCentral::StateProcessor>();
 | 
				
			||||||
						StatsProcessor_->Initialize(Serial);
 | 
											StatsProcessor_->Initialize(Serial);
 | 
				
			||||||
@@ -457,7 +472,7 @@ namespace uCentral {
 | 
				
			|||||||
							Storage()->SetCommandResult(request_uuid, CheckData);
 | 
												Storage()->SetCommandResult(request_uuid, CheckData);
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						DeviceRegistry()->SetHealthcheck(Serial, CheckData);
 | 
											DeviceRegistry()->SetHealthcheck(Serial, Check);
 | 
				
			||||||
						if(KafkaManager()->Enabled()) {
 | 
											if(KafkaManager()->Enabled()) {
 | 
				
			||||||
							Poco::JSON::Stringifier		Stringify;
 | 
												Poco::JSON::Stringifier		Stringify;
 | 
				
			||||||
							std::ostringstream OS;
 | 
												std::ostringstream OS;
 | 
				
			||||||
@@ -656,9 +671,24 @@ namespace uCentral {
 | 
				
			|||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                switch (Op) {
 | 
					                switch (Op) {
 | 
				
			||||||
                    case Poco::Net::WebSocket::FRAME_OP_PING: {
 | 
					                    case Poco::Net::WebSocket::FRAME_OP_PING: {
 | 
				
			||||||
                        Logger_.debug(Poco::format("WS-PING(%s): received. PONG sent back.", CId_));
 | 
												Logger_.debug(Poco::format("WS-PING(%s): received. PONG sent back.", CId_));
 | 
				
			||||||
                        WS_->sendFrame("", 0,(int)Poco::Net::WebSocket::FRAME_OP_PONG | (int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
 | 
												WS_->sendFrame("", 0,
 | 
				
			||||||
                        }
 | 
															   (int)Poco::Net::WebSocket::FRAME_OP_PONG |
 | 
				
			||||||
 | 
																   (int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
 | 
				
			||||||
 | 
												if (KafkaManager()->Enabled() && Conn_) {
 | 
				
			||||||
 | 
													Poco::JSON::Object PingObject;
 | 
				
			||||||
 | 
													Poco::JSON::Object PingDetails;
 | 
				
			||||||
 | 
													PingDetails.set(uCentralProtocol::FIRMWARE, Conn_->Firmware);
 | 
				
			||||||
 | 
													PingDetails.set(uCentralProtocol::SERIALNUMBER, SerialNumber_);
 | 
				
			||||||
 | 
													PingDetails.set(uCentralProtocol::COMPATIBLE, Compatible_);
 | 
				
			||||||
 | 
													PingObject.set(uCentralProtocol::PING,PingDetails);
 | 
				
			||||||
 | 
													Poco::JSON::Stringifier Stringify;
 | 
				
			||||||
 | 
													std::ostringstream OS;
 | 
				
			||||||
 | 
													Stringify.condense(PingObject, OS);
 | 
				
			||||||
 | 
													KafkaManager()->PostMessage(uCentral::KafkaTopics::CONNECTION, SerialNumber_,
 | 
				
			||||||
 | 
																				OS.str());
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    case Poco::Net::WebSocket::FRAME_OP_PONG: {
 | 
					                    case Poco::Net::WebSocket::FRAME_OP_PONG: {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -172,6 +172,7 @@ namespace uCentral {
 | 
				
			|||||||
        Poco::Net::StreamSocket       		Socket_;
 | 
					        Poco::Net::StreamSocket       		Socket_;
 | 
				
			||||||
        std::unique_ptr<Poco::Net::WebSocket> WS_;
 | 
					        std::unique_ptr<Poco::Net::WebSocket> WS_;
 | 
				
			||||||
        std::string                         SerialNumber_;
 | 
					        std::string                         SerialNumber_;
 | 
				
			||||||
 | 
							std::string 						Compatible_;
 | 
				
			||||||
		GWObjects::ConnectionState 	* Conn_ = nullptr;
 | 
							GWObjects::ConnectionState 	* Conn_ = nullptr;
 | 
				
			||||||
        bool                                Registered_ = false ;
 | 
					        bool                                Registered_ = false ;
 | 
				
			||||||
		std::string 						CId_;
 | 
							std::string 						CId_;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace uCentral {
 | 
					namespace uCentral {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool Storage::UpdateDeviceCapabilities(std::string &SerialNumber, std::string & Capabilities) {
 | 
						bool Storage::UpdateDeviceCapabilities(std::string &SerialNumber, std::string & Capabilities, std::string & Compat) {
 | 
				
			||||||
		// std::lock_guard<std::mutex> guard(Mutex_);
 | 
							// std::lock_guard<std::mutex> guard(Mutex_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
@@ -33,7 +33,7 @@ namespace uCentral {
 | 
				
			|||||||
			Poco::DynamicStruct ds = *Obj;
 | 
								Poco::DynamicStruct ds = *Obj;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if(ds.contains("compatible")) {
 | 
								if(ds.contains("compatible")) {
 | 
				
			||||||
				Compatible= ds["compatible"].toString();
 | 
									Compat = Compatible = ds["compatible"].toString();
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				//	Maybe this is an old firmware
 | 
									//	Maybe this is an old firmware
 | 
				
			||||||
				auto TmpCompatible = ds["model"]["id"].toString();
 | 
									auto TmpCompatible = ds["model"]["id"].toString();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "Poco/File.h"
 | 
					#include "Poco/File.h"
 | 
				
			||||||
#include "Poco/Data/LOBStream.h"
 | 
					#include "Poco/Data/LOBStream.h"
 | 
				
			||||||
 | 
					#include "Poco/Data/RecordSet.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Daemon.h"
 | 
					#include "Daemon.h"
 | 
				
			||||||
#include "DeviceRegistry.h"
 | 
					#include "DeviceRegistry.h"
 | 
				
			||||||
@@ -786,4 +787,28 @@ namespace uCentral {
 | 
				
			|||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bool Storage::AnalyzeCommands(Types::CountedMap &R) {
 | 
				
			||||||
 | 
							try {
 | 
				
			||||||
 | 
								Poco::Data::Session     Sess = Pool_->get();
 | 
				
			||||||
 | 
								Poco::Data::Statement   Select(Sess);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Select << "SELECT Command from CommandList";
 | 
				
			||||||
 | 
								Select.execute();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Poco::Data::RecordSet   RSet(Select);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								bool More = RSet.moveFirst();
 | 
				
			||||||
 | 
								while(More) {
 | 
				
			||||||
 | 
									auto Command = RSet[0].convert<std::string>();
 | 
				
			||||||
 | 
									if(!Command.empty())
 | 
				
			||||||
 | 
										Types::UpdateCountedMap(R,Command);
 | 
				
			||||||
 | 
									More = RSet.moveNext();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							} catch(const Poco::Exception &E) {
 | 
				
			||||||
 | 
								Logger_.log(E);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -182,7 +182,7 @@ namespace uCentral {
 | 
				
			|||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool Storage::CreateDefaultDevice(const std::string &SerialNumber, const std::string &Capabilities, std::string & Firmware) {
 | 
						bool Storage::CreateDefaultDevice(const std::string &SerialNumber, const std::string &Capabilities, std::string & Firmware, std::string &Compat) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		GWObjects::Device D;
 | 
							GWObjects::Device D;
 | 
				
			||||||
		Logger_.information(Poco::format("AUTO-CREATION(%s)", SerialNumber));
 | 
							Logger_.information(Poco::format("AUTO-CREATION(%s)", SerialNumber));
 | 
				
			||||||
@@ -202,7 +202,7 @@ namespace uCentral {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		D.SerialNumber = Poco::toLower(SerialNumber);
 | 
							D.SerialNumber = Poco::toLower(SerialNumber);
 | 
				
			||||||
		D.Compatible = Caps.Compatible();
 | 
							Compat = D.Compatible = Caps.Compatible();
 | 
				
			||||||
		D.DeviceType = Daemon()->IdentifyDevice(D.Compatible);
 | 
							D.DeviceType = Daemon()->IdentifyDevice(D.Compatible);
 | 
				
			||||||
		D.MACAddress = Utils::SerialToMAC(SerialNumber);
 | 
							D.MACAddress = Utils::SerialToMAC(SerialNumber);
 | 
				
			||||||
		D.Manufacturer = Caps.Model();
 | 
							D.Manufacturer = Caps.Model();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "StateProcessor.h"
 | 
					#include "StateProcessor.h"
 | 
				
			||||||
#include "StorageService.h"
 | 
					#include "StorageService.h"
 | 
				
			||||||
 | 
					#include "Poco/Data/RecordSet.h"
 | 
				
			||||||
 | 
					#include "Poco/JSON/Object.h"
 | 
				
			||||||
 | 
					#include "Poco/JSON/Parser.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
	Sess << "CREATE TABLE IF NOT EXISTS LifetimeStats ("
 | 
						Sess << "CREATE TABLE IF NOT EXISTS LifetimeStats ("
 | 
				
			||||||
@@ -98,4 +101,5 @@ namespace uCentral {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,47 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
//	License type: BSD 3-Clause License
 | 
					 | 
				
			||||||
//	License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
//	Created by Stephane Bourque on 2021-03-04.
 | 
					 | 
				
			||||||
//	Arilia Wireless Inc.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "Daemon.h"
 | 
					 | 
				
			||||||
#include "StorageService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace uCentral {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef SMALL_BUILD
 | 
					 | 
				
			||||||
	int Service::Setup_ODBC() { uCentral::instance()->exit(Poco::Util::Application::EXIT_CONFIG);}
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
	int Storage::Setup_ODBC() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		dbType_ = odbc ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		Logger_.notice("ODBC Storage enabled.");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		auto NumSessions = Daemon()->ConfigGetInt("storage.type.postgresql.maxsessions", 64);
 | 
					 | 
				
			||||||
		auto IdleTime = Daemon()->ConfigGetInt("storage.type.postgresql.idletime", 60);
 | 
					 | 
				
			||||||
		auto Host = Daemon()->ConfigGetString("storage.type.postgresql.host");
 | 
					 | 
				
			||||||
		auto Username = Daemon()->ConfigGetString("storage.type.postgresql.username");
 | 
					 | 
				
			||||||
		auto Password = Daemon()->ConfigGetString("storage.type.postgresql.password");
 | 
					 | 
				
			||||||
		auto Database = Daemon()->ConfigGetString("storage.type.postgresql.database");
 | 
					 | 
				
			||||||
		auto Port = Daemon()->ConfigGetString("storage.type.postgresql.port");
 | 
					 | 
				
			||||||
		auto ConnectionTimeout = Daemon()->ConfigGetString("storage.type.postgresql.connectiontimeout");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		std::string ConnectionStr =
 | 
					 | 
				
			||||||
			"host=" + Host +
 | 
					 | 
				
			||||||
			" user=" + Username +
 | 
					 | 
				
			||||||
			" password=" + Password +
 | 
					 | 
				
			||||||
			" dbname=" + Database +
 | 
					 | 
				
			||||||
			" port=" + Port +
 | 
					 | 
				
			||||||
			" connect_timeout=" + ConnectionTimeout;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		ODBCConn_ = std::make_unique<Poco::Data::ODBC::Connector>();
 | 
					 | 
				
			||||||
		ODBCConn_->registerConnector();
 | 
					 | 
				
			||||||
		Pool_ = std::make_unique<Poco::Data::SessionPool>(ODBCConn_->name(), ConnectionStr, 4, NumSessions, IdleTime);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -82,6 +82,13 @@ namespace uCentral::uCentralProtocol {
 | 
				
			|||||||
	static const char * PASSWORD = "password";
 | 
						static const char * PASSWORD = "password";
 | 
				
			||||||
	static const char * DEVICEUPDATE = "deviceupdate";
 | 
						static const char * DEVICEUPDATE = "deviceupdate";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static const char * SERIALNUMBER = "serialNumber";
 | 
				
			||||||
 | 
					    static const char * COMPATIBLE = "compatible";
 | 
				
			||||||
 | 
					    static const char * DISCONNECTION = "disconnection";
 | 
				
			||||||
 | 
					    static const char * TIMESTAMP = "timestamp";
 | 
				
			||||||
 | 
					    static const char * SYSTEM = "system";
 | 
				
			||||||
 | 
					    static const char * HOST = "host";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enum EVENT_MSG {
 | 
						enum EVENT_MSG {
 | 
				
			||||||
			ET_UNKNOWN,
 | 
								ET_UNKNOWN,
 | 
				
			||||||
			ET_CONNECT,
 | 
								ET_CONNECT,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,15 +13,28 @@
 | 
				
			|||||||
#include <functional>
 | 
					#include <functional>
 | 
				
			||||||
#include <list>
 | 
					#include <list>
 | 
				
			||||||
#include <utility>
 | 
					#include <utility>
 | 
				
			||||||
 | 
					#include <queue>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace uCentral::Types {
 | 
					namespace uCentral::Types {
 | 
				
			||||||
	typedef std::vector<std::pair<std::string,std::string>>	StringPairVec;
 | 
					    typedef std::pair<std::string,std::string>              StringPair;
 | 
				
			||||||
 | 
						typedef std::vector<StringPair>	                        StringPairVec;
 | 
				
			||||||
 | 
					    typedef std::queue<StringPair>	                        StringPairQueue;
 | 
				
			||||||
	typedef std::vector<std::string>						StringVec;
 | 
						typedef std::vector<std::string>						StringVec;
 | 
				
			||||||
 | 
						typedef std::set<std::string>                           StringSet;
 | 
				
			||||||
	typedef std::vector<SubSystemServer*>					SubSystemVec;
 | 
						typedef std::vector<SubSystemServer*>					SubSystemVec;
 | 
				
			||||||
	typedef std::map<std::string,std::set<std::string>>		StringMapStringSet;
 | 
						typedef std::map<std::string,std::set<std::string>>		StringMapStringSet;
 | 
				
			||||||
	typedef std::function<void(std::string, std::string)>   TopicNotifyFunction;
 | 
						typedef std::function<void(std::string, std::string)>   TopicNotifyFunction;
 | 
				
			||||||
	typedef std::list<std::pair<TopicNotifyFunction,int>>   TopicNotifyFunctionList;
 | 
						typedef std::list<std::pair<TopicNotifyFunction,int>>   TopicNotifyFunctionList;
 | 
				
			||||||
	typedef std::map<std::string, TopicNotifyFunctionList>  NotifyTable;
 | 
						typedef std::map<std::string, TopicNotifyFunctionList>  NotifyTable;
 | 
				
			||||||
 | 
					    typedef std::map<std::string,uint64_t>                  CountedMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    inline void UpdateCountedMap(CountedMap &M, const std::string &S ) {
 | 
				
			||||||
 | 
					        auto it = M.find(S);
 | 
				
			||||||
 | 
					        if(it==M.end())
 | 
				
			||||||
 | 
					            M[S]=1;
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            it->second += 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // UCENTRALGW_UCENTRALTYPES_H
 | 
					#endif // UCENTRALGW_UCENTRALTYPES_H
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										103
									
								
								test_scripts/curl/ExpressWiFi.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								test_scripts/curl/ExpressWiFi.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,103 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
						"uuid": 2,
 | 
				
			||||||
 | 
						"radios": [
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"band": "5G",
 | 
				
			||||||
 | 
								"channel": "auto",
 | 
				
			||||||
 | 
								"channel-mode": "HE",
 | 
				
			||||||
 | 
								"channel-width": 80,
 | 
				
			||||||
 | 
								"country": "CA"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"band": "2G",
 | 
				
			||||||
 | 
								"channel": "auto",
 | 
				
			||||||
 | 
								"channel-mode": "HE",
 | 
				
			||||||
 | 
								"channel-width": 20,
 | 
				
			||||||
 | 
								"country": "CA"
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"interfaces": [
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"name": "WAN",
 | 
				
			||||||
 | 
								"role": "upstream",
 | 
				
			||||||
 | 
								"services": [ "lldp" ],
 | 
				
			||||||
 | 
								"ethernet": [
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										"select-ports": [
 | 
				
			||||||
 | 
											"WAN*"
 | 
				
			||||||
 | 
										]
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								],
 | 
				
			||||||
 | 
								"ipv4": {
 | 
				
			||||||
 | 
									"addressing": "dynamic"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"name": "LAN",
 | 
				
			||||||
 | 
								"role": "downstream",
 | 
				
			||||||
 | 
								"services": [ "ssh", "lldp", "open-flow"],
 | 
				
			||||||
 | 
								"ethernet": [
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										"select-ports": [
 | 
				
			||||||
 | 
											"LAN*"
 | 
				
			||||||
 | 
										]
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								],
 | 
				
			||||||
 | 
								"ipv4": {
 | 
				
			||||||
 | 
									"addressing": "static",
 | 
				
			||||||
 | 
									"subnet": "192.168.1.1/24",
 | 
				
			||||||
 | 
									"dhcp": {
 | 
				
			||||||
 | 
										"lease-first": 10,
 | 
				
			||||||
 | 
										"lease-count": 100,
 | 
				
			||||||
 | 
										"lease-time": "6h"
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
								"ssids": [
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										"name": "ExpressWiFi",
 | 
				
			||||||
 | 
										"wifi-bands": [
 | 
				
			||||||
 | 
											"5G", "2G"
 | 
				
			||||||
 | 
										],
 | 
				
			||||||
 | 
										"bss-mode": "ap"
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						"metrics": {
 | 
				
			||||||
 | 
							"statistics": {
 | 
				
			||||||
 | 
								"interval": 120,
 | 
				
			||||||
 | 
								"types": [ "ssids", "lldp", "clients" ]
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"health": {
 | 
				
			||||||
 | 
								"interval": 120
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"wifi-frames": {
 | 
				
			||||||
 | 
								"filters": [ "probe",
 | 
				
			||||||
 | 
									"auth",
 | 
				
			||||||
 | 
									"assoc",
 | 
				
			||||||
 | 
									"disassoc",
 | 
				
			||||||
 | 
									"deauth",
 | 
				
			||||||
 | 
									"local-deauth",
 | 
				
			||||||
 | 
									"inactive-deauth",
 | 
				
			||||||
 | 
									"key-mismatch",
 | 
				
			||||||
 | 
									"beacon-report",
 | 
				
			||||||
 | 
									"radar-detected"]
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"dhcp-snooping": {
 | 
				
			||||||
 | 
								"filters": [ "ack", "discover", "offer", "request", "solicit", "reply", "renew" ]
 | 
				
			||||||
 | 
							}      
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						"services": {
 | 
				
			||||||
 | 
							"lldp": {
 | 
				
			||||||
 | 
								"describe": "uCentral",
 | 
				
			||||||
 | 
								"location": "universe"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"ssh": {
 | 
				
			||||||
 | 
								"port": 22
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"open-flow": {
 | 
				
			||||||
 | 
								"controller": "18.130.73.35"
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										121
									
								
								test_scripts/curl/basic-metrics_nat-SSID.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								test_scripts/curl/basic-metrics_nat-SSID.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
						"uuid": 2,
 | 
				
			||||||
 | 
						"radios": [
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"band": "5G",
 | 
				
			||||||
 | 
								"channel": "auto",
 | 
				
			||||||
 | 
								"channel-mode": "VHT",
 | 
				
			||||||
 | 
								"channel-width": 80,
 | 
				
			||||||
 | 
								"country": "CA"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"band": "2G",
 | 
				
			||||||
 | 
								"channel": "auto",
 | 
				
			||||||
 | 
								"channel-mode": "HE",
 | 
				
			||||||
 | 
								"channel-width": 20,
 | 
				
			||||||
 | 
								"country": "CA"
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"interfaces": [
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"name": "WAN",
 | 
				
			||||||
 | 
								"role": "upstream",
 | 
				
			||||||
 | 
								"services": [ "lldp", "dhcp-snooping" ],
 | 
				
			||||||
 | 
								"ethernet": [
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										"select-ports": [
 | 
				
			||||||
 | 
											"WAN*"
 | 
				
			||||||
 | 
										]
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								],
 | 
				
			||||||
 | 
								"ipv4": {
 | 
				
			||||||
 | 
									"addressing": "dynamic"
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								"name": "LAN",
 | 
				
			||||||
 | 
								"role": "downstream",
 | 
				
			||||||
 | 
								"services": [ "ssh", "lldp", "dhcp-snooping" ],
 | 
				
			||||||
 | 
								"ethernet": [
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										"select-ports": [
 | 
				
			||||||
 | 
											"LAN*"
 | 
				
			||||||
 | 
										]
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								],
 | 
				
			||||||
 | 
								"ipv4": {
 | 
				
			||||||
 | 
									"addressing": "static",
 | 
				
			||||||
 | 
									"subnet": "192.168.1.1/24",
 | 
				
			||||||
 | 
									"dhcp": {
 | 
				
			||||||
 | 
										"lease-first": 10,
 | 
				
			||||||
 | 
										"lease-count": 100,
 | 
				
			||||||
 | 
										"lease-time": "6h"
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
					            "ssids": [
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										"name": "OpenWifi_2GHz",
 | 
				
			||||||
 | 
					                    "role": "downstream",
 | 
				
			||||||
 | 
					                    "services": [ "wifi-frames"],                    
 | 
				
			||||||
 | 
										"wifi-bands": [
 | 
				
			||||||
 | 
											"2G"
 | 
				
			||||||
 | 
										],
 | 
				
			||||||
 | 
										"bss-mode": "ap",
 | 
				
			||||||
 | 
										"encryption": {
 | 
				
			||||||
 | 
											"proto": "psk2",
 | 
				
			||||||
 | 
											"key": "OpenWifi",
 | 
				
			||||||
 | 
											"ieee80211w": "optional"
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										"name": "OpenWifi_5GHz",
 | 
				
			||||||
 | 
					                    "role": "downstream",
 | 
				
			||||||
 | 
					                    "services": [ "wifi-frames"],                      
 | 
				
			||||||
 | 
										"wifi-bands": [
 | 
				
			||||||
 | 
											"5G"
 | 
				
			||||||
 | 
										],
 | 
				
			||||||
 | 
										"bss-mode": "ap",
 | 
				
			||||||
 | 
										"encryption": {
 | 
				
			||||||
 | 
											"proto": "psk2",
 | 
				
			||||||
 | 
											"key": "OpenWifi",
 | 
				
			||||||
 | 
											"ieee80211w": "optional"
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}				
 | 
				
			||||||
 | 
								]
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						],
 | 
				
			||||||
 | 
						"metrics": {
 | 
				
			||||||
 | 
							"statistics": {
 | 
				
			||||||
 | 
								"interval": 60,
 | 
				
			||||||
 | 
								"types": [ "ssids", "lldp", "clients" ]
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"health": {
 | 
				
			||||||
 | 
								"interval": 120
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"wifi-frames": {
 | 
				
			||||||
 | 
								"filters": [ "probe",
 | 
				
			||||||
 | 
									"auth",
 | 
				
			||||||
 | 
									"assoc",
 | 
				
			||||||
 | 
									"disassoc",
 | 
				
			||||||
 | 
									"deauth",
 | 
				
			||||||
 | 
									"local-deauth",
 | 
				
			||||||
 | 
									"inactive-deauth",
 | 
				
			||||||
 | 
									"key-mismatch",
 | 
				
			||||||
 | 
									"beacon-report",
 | 
				
			||||||
 | 
									"radar-detected"]
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"dhcp-snooping": {
 | 
				
			||||||
 | 
								"filters": [ "ack", "discover", "offer", "request", "solicit", "reply", "renew" ]
 | 
				
			||||||
 | 
							}        
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						"services": {      
 | 
				
			||||||
 | 
							"lldp": {
 | 
				
			||||||
 | 
								"describe": "TIP OpenWiFi",
 | 
				
			||||||
 | 
								"location": "QA"
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"ssh": {
 | 
				
			||||||
 | 
								"port": 22
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -498,6 +498,28 @@ ouilookup() {
 | 
				
			|||||||
	jq < ${result_file}
 | 
						jq < ${result_file}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					dashboard() {
 | 
				
			||||||
 | 
						curl  ${FLAGS} -X GET "https://${UCENTRALGW}/api/v1/deviceDashboard" \
 | 
				
			||||||
 | 
					        -H "accept: application/json" \
 | 
				
			||||||
 | 
					        -H "Authorization: Bearer ${token}" > ${result_file}
 | 
				
			||||||
 | 
						jq < ${result_file}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gwversion() {
 | 
				
			||||||
 | 
						curl  ${FLAGS} -X GET "https://${UCENTRALGW}/api/v1/system?command=version" \
 | 
				
			||||||
 | 
					        -H "accept: application/json" \
 | 
				
			||||||
 | 
					        -H "Authorization: Bearer ${token}" > ${result_file}
 | 
				
			||||||
 | 
						jq < ${result_file}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					gwtimes() {
 | 
				
			||||||
 | 
						curl  ${FLAGS} -X GET "https://${UCENTRALGW}/api/v1/system?command=times" \
 | 
				
			||||||
 | 
					        -H "accept: application/json" \
 | 
				
			||||||
 | 
					        -H "Authorization: Bearer ${token}" > ${result_file}
 | 
				
			||||||
 | 
						jq < ${result_file}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
help() {
 | 
					help() {
 | 
				
			||||||
  echo
 | 
					  echo
 | 
				
			||||||
  echo "getdevice <serial>                Get the device JSON document."
 | 
					  echo "getdevice <serial>                Get the device JSON document."
 | 
				
			||||||
@@ -578,7 +600,9 @@ help() {
 | 
				
			|||||||
  echo
 | 
					  echo
 | 
				
			||||||
  echo "ouilookup <serial> 				  Lookup an OUI"
 | 
					  echo "ouilookup <serial> 				  Lookup an OUI"
 | 
				
			||||||
  echo
 | 
					  echo
 | 
				
			||||||
  echo
 | 
					  echo "dashboard 				  		  Get the dashboard document"
 | 
				
			||||||
 | 
					  echo "gwtimes							  Get the uptime and start time of the service."
 | 
				
			||||||
 | 
					  echo "gwversion						  Get the service version."
 | 
				
			||||||
  echo "To pass additional flags to the CURL command, create an environment variable called FLAGS and git ve the values you"
 | 
					  echo "To pass additional flags to the CURL command, create an environment variable called FLAGS and git ve the values you"
 | 
				
			||||||
  echo "want. For example, for force all call to use IPv6, set FLAGS=\"-6\", for verbose mode and IPv6, set FLAGS=\"-6 -v\""
 | 
					  echo "want. For example, for force all call to use IPv6, set FLAGS=\"-6\", for verbose mode and IPv6, set FLAGS=\"-6 -v\""
 | 
				
			||||||
  echo
 | 
					  echo
 | 
				
			||||||
@@ -638,6 +662,9 @@ case "$1" in
 | 
				
			|||||||
  "getloglevelnames") login; getloglevelnames; logout ;;
 | 
					  "getloglevelnames") login; getloglevelnames; logout ;;
 | 
				
			||||||
  "getsubsystemnames") login; getsubsystemnames; logout ;;
 | 
					  "getsubsystemnames") login; getsubsystemnames; logout ;;
 | 
				
			||||||
  "ouilookup") login; ouilookup "$2"; logout;;
 | 
					  "ouilookup") login; ouilookup "$2"; logout;;
 | 
				
			||||||
 | 
					  "dashboard") login; dashboard ; logout;;
 | 
				
			||||||
 | 
					  "gwversion") login; gwversion ; logout;;
 | 
				
			||||||
 | 
					  "gwtimes") login; gwtimes ; logout;;
 | 
				
			||||||
  "addnote") login; addnote "$2" "$3"; logout;;
 | 
					  "addnote") login; addnote "$2" "$3"; logout;;
 | 
				
			||||||
  *) help ;;
 | 
					  *) help ;;
 | 
				
			||||||
esac
 | 
					esac
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,6 +58,7 @@ ucentral.fileuploader.maxsize = 10000
 | 
				
			|||||||
# Generic section that all microservices must have
 | 
					# Generic section that all microservices must have
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
ucentral.service.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
 | 
					ucentral.service.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
 | 
				
			||||||
 | 
					ucentral.service.key.password = mypassword
 | 
				
			||||||
ucentral.system.data = $UCENTRALGW_ROOT/data
 | 
					ucentral.system.data = $UCENTRALGW_ROOT/data
 | 
				
			||||||
ucentral.system.debug = true
 | 
					ucentral.system.debug = true
 | 
				
			||||||
#ucentral.system.uri.private = https://localhost:17002
 | 
					#ucentral.system.uri.private = https://localhost:17002
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,6 +58,7 @@ ucentral.fileuploader.maxsize = 10000
 | 
				
			|||||||
# Generic section that all microservices must have
 | 
					# Generic section that all microservices must have
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
ucentral.service.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
 | 
					ucentral.service.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
 | 
				
			||||||
 | 
					ucentral.service.key.password = mypassword
 | 
				
			||||||
ucentral.system.data = $UCENTRALGW_ROOT/data
 | 
					ucentral.system.data = $UCENTRALGW_ROOT/data
 | 
				
			||||||
ucentral.system.debug = true
 | 
					ucentral.system.debug = true
 | 
				
			||||||
ucentral.system.uri.private = https://localhost:17002
 | 
					ucentral.system.uri.private = https://localhost:17002
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -58,6 +58,7 @@ ucentral.fileuploader.maxsize = 10000
 | 
				
			|||||||
# Generic section that all microservices must have
 | 
					# Generic section that all microservices must have
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
ucentral.service.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
 | 
					ucentral.service.key = $UCENTRALGW_ROOT/certs/restapi-key.pem
 | 
				
			||||||
 | 
					ucentral.service.key.password = mypassword
 | 
				
			||||||
ucentral.system.data = $UCENTRALGW_ROOT/data
 | 
					ucentral.system.data = $UCENTRALGW_ROOT/data
 | 
				
			||||||
ucentral.system.debug = true
 | 
					ucentral.system.debug = true
 | 
				
			||||||
ucentral.system.uri.private = https://localhost:17002
 | 
					ucentral.system.uri.private = https://localhost:17002
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										45
									
								
								ucentralgw.service
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								ucentralgw.service
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					[Unit]
 | 
				
			||||||
 | 
					Description=OpenWiFi uCentral Gateway Service
 | 
				
			||||||
 | 
					After=network-online.target docker.service
 | 
				
			||||||
 | 
					Wants=network-online.target
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[Service]
 | 
				
			||||||
 | 
					Type=simple
 | 
				
			||||||
 | 
					# the default is not to use systemd for cgroups because the delegate issues still
 | 
				
			||||||
 | 
					# exists and systemd currently does not support the cgroup feature set required
 | 
				
			||||||
 | 
					# for containers run by docker
 | 
				
			||||||
 | 
					Environment="UCENTRALGW_ROOT=/home/admin/dev/wlan-cloud-ucentralgw"
 | 
				
			||||||
 | 
					ExecStart=/home/admin/dev/wlan-cloud-ucentralgw/cmake-build/ucentralgw
 | 
				
			||||||
 | 
					WorkingDirectory=/home/admin/dev/wlan-cloud-ucentralgw
 | 
				
			||||||
 | 
					ExecReload=/bin/kill -s HUP $MAINPID
 | 
				
			||||||
 | 
					User=admin
 | 
				
			||||||
 | 
					TimeoutSec=0
 | 
				
			||||||
 | 
					RestartSec=2
 | 
				
			||||||
 | 
					Restart=always
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
 | 
				
			||||||
 | 
					# Both the old, and new location are accepted by systemd 229 and up, so using the old location
 | 
				
			||||||
 | 
					# to make them work for either version of systemd.
 | 
				
			||||||
 | 
					StartLimitBurst=3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Note that StartLimitInterval was renamed to StartLimitIntervalSec in systemd 230.
 | 
				
			||||||
 | 
					# Both the old, and new name are accepted by systemd 230 and up, so using the old name to make
 | 
				
			||||||
 | 
					# this option work for either version of systemd.
 | 
				
			||||||
 | 
					# StartLimitInterval=60s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Having non-zero Limit*s causes performance problems due to accounting overhead
 | 
				
			||||||
 | 
					# in the kernel. We recommend using cgroups to do container-local accounting.
 | 
				
			||||||
 | 
					LimitNOFILE=infinity
 | 
				
			||||||
 | 
					LimitNPROC=infinity
 | 
				
			||||||
 | 
					LimitCORE=infinity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Comment TasksMax if your systemd version does not support it.
 | 
				
			||||||
 | 
					# Only systemd 226 and above support this option.
 | 
				
			||||||
 | 
					TasksMax=infinity
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# set delegate yes so that systemd does not reset the cgroups of docker containers
 | 
				
			||||||
 | 
					Delegate=yes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# kill only the docker process, not all processes in the cgroup
 | 
				
			||||||
 | 
					KillMode=process
 | 
				
			||||||
 | 
					OOMScoreAdjust=-500
 | 
				
			||||||
		Reference in New Issue
	
	Block a user