Compare commits
	
		
			146 Commits
		
	
	
		
			v2.7.0
			...
			release/v3
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | bd80f9b2f9 | ||
|   | 0d2368f47c | ||
|   | e777a8da4f | ||
|   | 73dbd2f36a | ||
|   | 06ad21c5fb | ||
|   | cd177040fe | ||
|   | 23cf3042b3 | ||
|   | 1f02c9fec4 | ||
|   | 7ba9b43b56 | ||
|   | 0178b5e5d0 | ||
|   | c020e702df | ||
|   | 7e72cc7ac7 | ||
|   | a283f31d7f | ||
|   | 13d2d39aed | ||
|   | 7d5c130d5c | ||
|   | bc4da0aaeb | ||
|   | bf3a689249 | ||
|   | dea5bb96e5 | ||
|   | 381006b9f5 | ||
|   | 92bc511ec5 | ||
|   | 73686f8a6c | ||
|   | 48b8705fc6 | ||
|   | 0ba38c8736 | ||
|   | b018dc70ef | ||
|   | 42d44b056e | ||
|   | 7d9d5b4d15 | ||
|   | 7fc77e529b | ||
|   | e8986d84b4 | ||
|   | f54fd2b411 | ||
|   | 86f3754c7e | ||
|   | 260927a3eb | ||
|   | bb571ad11a | ||
|   | bd0fbfd6d2 | ||
|   | 33ba7b2323 | ||
|   | 28cbc79890 | ||
|   | 0137d8ee66 | ||
|   | 1ca77de37e | ||
|   | bd5ae332bd | ||
|   | 28dcf0085c | ||
|   | f1a687f6e1 | ||
|   | d2bae99b3c | ||
|   | 180d8d1502 | ||
|   | bd7eca32f4 | ||
|   | 43658550df | ||
|   | c113fc24c5 | ||
|   | 5ddbd0bad3 | ||
|   | 8d030ff51b | ||
|   | 388e5d9aee | ||
|   | a1ea461b68 | ||
|   | a77ef768e3 | ||
|   | 24e275743e | ||
|   | 3366b933bf | ||
|   | 6cd1c9a0f6 | ||
|   | cb8c526b9b | ||
|   | f95ed7624b | ||
|   | ddfa040d4e | ||
|   | fa379befe4 | ||
|   | 9100a023b0 | ||
|   | 071e6ab86e | ||
|   | 383343a2e5 | ||
|   | efb2623613 | ||
|   | a7d8517291 | ||
|   | 7bf98b96de | ||
|   | 40d2458f38 | ||
|   | 62f98adc83 | ||
|   | 96da7500a6 | ||
|   | 13556889e6 | ||
|   | 43fc8f7f09 | ||
|   | bfdec30974 | ||
|   | ae2cbb9971 | ||
|   | 6f0c8b550c | ||
|   | 64e6a6f70a | ||
|   | c67367ec4d | ||
|   | fe3c5d7c4a | ||
|   | 3c8d8697e0 | ||
|   | 7b0c61ff5e | ||
|   | 2255988b4c | ||
|   | 106c9353fc | ||
|   | 6c7fc8e310 | ||
|   | e151b45d51 | ||
|   | 1584ff1ebe | ||
|   | 82ccb08d6b | ||
|   | 82b184a79f | ||
|   | 71c37edde7 | ||
|   | 0c8fa44935 | ||
|   | 32714f95b6 | ||
|   | 13cbf8c603 | ||
|   | 48c95c3101 | ||
|   | 857055750f | ||
|   | 96b22ef09b | ||
|   | acff9afff2 | ||
|   | 1e250be2cd | ||
|   | 93a8624645 | ||
|   | b9bf57e1f2 | ||
|   | f203622299 | ||
|   | 698282658c | ||
|   | 5baacac9bf | ||
|   | 8ca4531c99 | ||
|   | a6e0cd453b | ||
|   | 5e39f63fd2 | ||
|   | 9b081c6924 | ||
|   | be2150d845 | ||
|   | 2d6f1879f5 | ||
|   | e870a381a8 | ||
|   | 0cc0d0204e | ||
|   | 498e55f933 | ||
|   | a9b3cb9821 | ||
|   | 29736da681 | ||
|   | 28f890002b | ||
|   | 0ec0a4fd95 | ||
|   | 6dce398ddc | ||
|   | eca0e8883a | ||
|   | 43cc667a59 | ||
|   | a084230cbd | ||
|   | 59c5ed51c0 | ||
|   | 1128fd3c23 | ||
|   | ee4f1fac93 | ||
|   | a1a600de77 | ||
|   | 9d64c2dabd | ||
|   | 4f6c9728ef | ||
|   | 167933e422 | ||
|   | f661bb579a | ||
|   | 1e14eb1611 | ||
|   | dae57a7492 | ||
|   | d30014372b | ||
|   | a9f37ae30d | ||
|   | 23bc11f26e | ||
|   | caa25f0a1e | ||
|   | b86e80be6d | ||
|   | 880a14b651 | ||
|   | fa5d1b982a | ||
|   | e803885d24 | ||
|   | 17b7e1de59 | ||
|   | 15d7ae635c | ||
|   | 244423132e | ||
|   | ad149a8e40 | ||
|   | 59020f8809 | ||
|   | 4c5dbea4fb | ||
|   | 8fa42ab75d | ||
|   | ad1d7301a1 | ||
|   | 6ad2f0ba1b | ||
|   | aad7cf752a | ||
|   | ff8fa5e625 | ||
|   | 6e38083912 | ||
|   | 98509fdab7 | ||
|   | 2bbaf44e88 | 
							
								
								
									
										178
									
								
								.clang-format
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,178 @@ | |||||||
|  | --- | ||||||
|  | Language:        Cpp | ||||||
|  | # BasedOnStyle:  LLVM | ||||||
|  | AccessModifierOffset: -2 | ||||||
|  | AlignAfterOpenBracket: Align | ||||||
|  | AlignArrayOfStructures: None | ||||||
|  | AlignConsecutiveMacros: None | ||||||
|  | AlignConsecutiveAssignments: None | ||||||
|  | AlignConsecutiveBitFields: None | ||||||
|  | AlignConsecutiveDeclarations: None | ||||||
|  | AlignEscapedNewlines: Right | ||||||
|  | AlignOperands:   Align | ||||||
|  | AlignTrailingComments: true | ||||||
|  | AllowAllArgumentsOnNextLine: true | ||||||
|  | AllowAllConstructorInitializersOnNextLine: true | ||||||
|  | AllowAllParametersOfDeclarationOnNextLine: true | ||||||
|  | AllowShortEnumsOnASingleLine: true | ||||||
|  | AllowShortBlocksOnASingleLine: Never | ||||||
|  | AllowShortCaseLabelsOnASingleLine: false | ||||||
|  | AllowShortFunctionsOnASingleLine: All | ||||||
|  | AllowShortLambdasOnASingleLine: All | ||||||
|  | AllowShortIfStatementsOnASingleLine: Never | ||||||
|  | AllowShortLoopsOnASingleLine: false | ||||||
|  | AlwaysBreakAfterDefinitionReturnType: None | ||||||
|  | AlwaysBreakAfterReturnType: None | ||||||
|  | AlwaysBreakBeforeMultilineStrings: false | ||||||
|  | AlwaysBreakTemplateDeclarations: MultiLine | ||||||
|  | AttributeMacros: | ||||||
|  |   - __capability | ||||||
|  | BinPackArguments: true | ||||||
|  | BinPackParameters: true | ||||||
|  | BraceWrapping: | ||||||
|  |   AfterCaseLabel:  false | ||||||
|  |   AfterClass:      false | ||||||
|  |   AfterControlStatement: Never | ||||||
|  |   AfterEnum:       false | ||||||
|  |   AfterFunction:   false | ||||||
|  |   AfterNamespace:  false | ||||||
|  |   AfterObjCDeclaration: false | ||||||
|  |   AfterStruct:     false | ||||||
|  |   AfterUnion:      false | ||||||
|  |   AfterExternBlock: false | ||||||
|  |   BeforeCatch:     false | ||||||
|  |   BeforeElse:      false | ||||||
|  |   BeforeLambdaBody: false | ||||||
|  |   BeforeWhile:     false | ||||||
|  |   IndentBraces:    false | ||||||
|  |   SplitEmptyFunction: true | ||||||
|  |   SplitEmptyRecord: true | ||||||
|  |   SplitEmptyNamespace: true | ||||||
|  | BreakBeforeBinaryOperators: None | ||||||
|  | BreakBeforeConceptDeclarations: true | ||||||
|  | BreakBeforeBraces: Attach | ||||||
|  | BreakBeforeInheritanceComma: false | ||||||
|  | BreakInheritanceList: BeforeColon | ||||||
|  | BreakBeforeTernaryOperators: true | ||||||
|  | BreakConstructorInitializersBeforeComma: false | ||||||
|  | BreakConstructorInitializers: BeforeColon | ||||||
|  | BreakAfterJavaFieldAnnotations: false | ||||||
|  | BreakStringLiterals: true | ||||||
|  | ColumnLimit:     100 | ||||||
|  | CommentPragmas:  '^ IWYU pragma:' | ||||||
|  | CompactNamespaces: false | ||||||
|  | ConstructorInitializerAllOnOneLineOrOnePerLine: false | ||||||
|  | ConstructorInitializerIndentWidth: 4 | ||||||
|  | ContinuationIndentWidth: 4 | ||||||
|  | Cpp11BracedListStyle: true | ||||||
|  | DeriveLineEnding: true | ||||||
|  | DerivePointerAlignment: false | ||||||
|  | DisableFormat:   false | ||||||
|  | EmptyLineAfterAccessModifier: Never | ||||||
|  | EmptyLineBeforeAccessModifier: LogicalBlock | ||||||
|  | ExperimentalAutoDetectBinPacking: false | ||||||
|  | FixNamespaceComments: true | ||||||
|  | ForEachMacros: | ||||||
|  |   - foreach | ||||||
|  |   - Q_FOREACH | ||||||
|  |   - BOOST_FOREACH | ||||||
|  | IfMacros: | ||||||
|  |   - KJ_IF_MAYBE | ||||||
|  | IncludeBlocks:   Preserve | ||||||
|  | IncludeCategories: | ||||||
|  |   - Regex:           '^"(llvm|llvm-c|clang|clang-c)/' | ||||||
|  |     Priority:        2 | ||||||
|  |     SortPriority:    0 | ||||||
|  |     CaseSensitive:   false | ||||||
|  |   - Regex:           '^(<|"(gtest|gmock|isl|json)/)' | ||||||
|  |     Priority:        3 | ||||||
|  |     SortPriority:    0 | ||||||
|  |     CaseSensitive:   false | ||||||
|  |   - Regex:           '.*' | ||||||
|  |     Priority:        1 | ||||||
|  |     SortPriority:    0 | ||||||
|  |     CaseSensitive:   false | ||||||
|  | IncludeIsMainRegex: '(Test)?$' | ||||||
|  | IncludeIsMainSourceRegex: '' | ||||||
|  | IndentAccessModifiers: false | ||||||
|  | IndentCaseLabels: false | ||||||
|  | IndentCaseBlocks: false | ||||||
|  | IndentGotoLabels: true | ||||||
|  | IndentPPDirectives: None | ||||||
|  | IndentExternBlock: AfterExternBlock | ||||||
|  | IndentRequires:  false | ||||||
|  | IndentWidth:     4 | ||||||
|  | IndentWrappedFunctionNames: false | ||||||
|  | InsertTrailingCommas: None | ||||||
|  | JavaScriptQuotes: Leave | ||||||
|  | JavaScriptWrapImports: true | ||||||
|  | KeepEmptyLinesAtTheStartOfBlocks: true | ||||||
|  | LambdaBodyIndentation: Signature | ||||||
|  | MacroBlockBegin: '' | ||||||
|  | MacroBlockEnd:   '' | ||||||
|  | MaxEmptyLinesToKeep: 1 | ||||||
|  | NamespaceIndentation: All | ||||||
|  | ObjCBinPackProtocolList: Auto | ||||||
|  | ObjCBlockIndentWidth: 2 | ||||||
|  | ObjCBreakBeforeNestedBlockParam: true | ||||||
|  | ObjCSpaceAfterProperty: false | ||||||
|  | ObjCSpaceBeforeProtocolList: true | ||||||
|  | PenaltyBreakAssignment: 2 | ||||||
|  | PenaltyBreakBeforeFirstCallParameter: 19 | ||||||
|  | PenaltyBreakComment: 300 | ||||||
|  | PenaltyBreakFirstLessLess: 120 | ||||||
|  | PenaltyBreakString: 1000 | ||||||
|  | PenaltyBreakTemplateDeclaration: 10 | ||||||
|  | PenaltyExcessCharacter: 1000000 | ||||||
|  | PenaltyReturnTypeOnItsOwnLine: 60 | ||||||
|  | PenaltyIndentedWhitespace: 0 | ||||||
|  | PointerAlignment: Right | ||||||
|  | PPIndentWidth:   -1 | ||||||
|  | ReferenceAlignment: Pointer | ||||||
|  | ReflowComments:  true | ||||||
|  | ShortNamespaceLines: 1 | ||||||
|  | SortIncludes:    CaseSensitive | ||||||
|  | SortJavaStaticImport: Before | ||||||
|  | SortUsingDeclarations: true | ||||||
|  | SpaceAfterCStyleCast: false | ||||||
|  | SpaceAfterLogicalNot: false | ||||||
|  | SpaceAfterTemplateKeyword: true | ||||||
|  | SpaceBeforeAssignmentOperators: true | ||||||
|  | SpaceBeforeCaseColon: false | ||||||
|  | SpaceBeforeCpp11BracedList: false | ||||||
|  | SpaceBeforeCtorInitializerColon: true | ||||||
|  | SpaceBeforeInheritanceColon: true | ||||||
|  | SpaceBeforeParens: ControlStatements | ||||||
|  | SpaceAroundPointerQualifiers: Default | ||||||
|  | SpaceBeforeRangeBasedForLoopColon: true | ||||||
|  | SpaceInEmptyBlock: false | ||||||
|  | SpaceInEmptyParentheses: false | ||||||
|  | SpacesBeforeTrailingComments: 1 | ||||||
|  | SpacesInAngles:  Never | ||||||
|  | SpacesInConditionalStatement: false | ||||||
|  | SpacesInContainerLiterals: true | ||||||
|  | SpacesInCStyleCastParentheses: false | ||||||
|  | SpacesInLineCommentPrefix: | ||||||
|  |   Minimum:         1 | ||||||
|  |   Maximum:         -1 | ||||||
|  | SpacesInParentheses: false | ||||||
|  | SpacesInSquareBrackets: false | ||||||
|  | SpaceBeforeSquareBrackets: false | ||||||
|  | BitFieldColonSpacing: Both | ||||||
|  | Standard:        Latest | ||||||
|  | StatementAttributeLikeMacros: | ||||||
|  |   - Q_EMIT | ||||||
|  | StatementMacros: | ||||||
|  |   - Q_UNUSED | ||||||
|  |   - QT_REQUIRE_VERSION | ||||||
|  | TabWidth:        4 | ||||||
|  | UseCRLF:         false | ||||||
|  | UseTab:          Always | ||||||
|  | WhitespaceSensitiveMacros: | ||||||
|  |   - STRINGIZE | ||||||
|  |   - PP_STRINGIZE | ||||||
|  |   - BOOST_PP_STRINGIZE | ||||||
|  |   - NS_SWIFT_NAME | ||||||
|  |   - CF_SWIFT_NAME | ||||||
|  | ... | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -27,7 +27,7 @@ jobs: | |||||||
|       DOCKER_REGISTRY_USERNAME: ucentral |       DOCKER_REGISTRY_USERNAME: ucentral | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout actions repo |     - name: Checkout actions repo | ||||||
|       uses: actions/checkout@v2 |       uses: actions/checkout@v3 | ||||||
|       with: |       with: | ||||||
|         repository: Telecominfraproject/.github |         repository: Telecominfraproject/.github | ||||||
|         path: github |         path: github | ||||||
| @@ -58,11 +58,11 @@ jobs: | |||||||
|     - name: Get base branch name and set as output |     - name: Get base branch name and set as output | ||||||
|       id: get_base_branch |       id: get_base_branch | ||||||
|       run: | |       run: | | ||||||
|         echo ::set-output name=branch::$(echo ${GITHUB_BASE_REF##*/}) |         echo "branch=$(echo ${GITHUB_BASE_REF##*/})" >> $GITHUB_OUTPUT | ||||||
|         echo ::set-output name=owgw_branch::$(echo ${GITHUB_BASE_REF##*/} | sed 's/main/master/g') |         echo "owgw_branch=$(echo ${GITHUB_BASE_REF##*/} | sed 's/main/master/g')" >> $GITHUB_OUTPUT | ||||||
|  |  | ||||||
|     - name: Checkout actions repo |     - name: Checkout actions repo | ||||||
|       uses: actions/checkout@v2 |       uses: actions/checkout@v3 | ||||||
|       with: |       with: | ||||||
|         repository: Telecominfraproject/.github |         repository: Telecominfraproject/.github | ||||||
|         path: github |         path: github | ||||||
| @@ -87,7 +87,7 @@ jobs: | |||||||
|       - docker |       - docker | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout actions repo |     - name: Checkout actions repo | ||||||
|       uses: actions/checkout@v2 |       uses: actions/checkout@v3 | ||||||
|       with: |       with: | ||||||
|         repository: Telecominfraproject/.github |         repository: Telecominfraproject/.github | ||||||
|         path: github |         path: github | ||||||
|   | |||||||
							
								
								
									
										41
									
								
								.github/workflows/openapi-pages.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,41 @@ | |||||||
|  | name: Update OpenAPI docs on GitHub Pages | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     paths: | ||||||
|  |       - 'openapi/**' | ||||||
|  |     branches: | ||||||
|  |       - main | ||||||
|  |   workflow_dispatch: | ||||||
|  |  | ||||||
|  | defaults: | ||||||
|  |   run: | ||||||
|  |     shell: bash | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   docsgen: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v3 | ||||||
|  |  | ||||||
|  |       - name: Generate static HTML page with docs from OpenAPI definition | ||||||
|  |         run: | | ||||||
|  |           docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli:v6.2.1 generate -i https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentralfms/main/openapi/owfms.yaml -g html2 --skip-validate-spec -o /local/ | ||||||
|  |  | ||||||
|  |       - name: Update OpenAPI docs | ||||||
|  |         run: | | ||||||
|  |           mkdir tmp-docs | ||||||
|  |           mv index.html tmp-docs/index.html | ||||||
|  |           mkdir -p ~/.ssh | ||||||
|  |           ssh-keyscan -H github.com >> ~/.ssh/known_hosts | ||||||
|  |           echo https://tip-automation:${{ secrets.GIT_PUSH_PAT }}@github.com > ~/.git-credentials | ||||||
|  |           git config --global credential.helper store | ||||||
|  |           git config --global user.email "tip-automation@telecominfraproject.com" | ||||||
|  |           git config --global user.name "TIP Automation User" | ||||||
|  |           git pull | ||||||
|  |           git checkout gh-pages || git checkout -b gh-pages | ||||||
|  |           rm -rf docs | ||||||
|  |           mv tmp-docs docs | ||||||
|  |           git add docs | ||||||
|  |           git commit -m'Update OpenAPI docs for GitHub pages' | ||||||
|  |           git push --set-upstream origin gh-pages | ||||||
							
								
								
									
										121
									
								
								BUILDING.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,121 @@ | |||||||
|  | # Building from source | ||||||
|  | In order to build OWFMS, you will need to install its dependencies, which includes the following: | ||||||
|  | - cmake | ||||||
|  | - boost | ||||||
|  | - POCO 1.10.1 or later | ||||||
|  | - a C++17 compiler | ||||||
|  | - openssl | ||||||
|  | - libpq-dev (PortgreSQL development libraries) | ||||||
|  | - mysql-client (MySQL client) | ||||||
|  | - librdkafka | ||||||
|  | - cppkafka | ||||||
|  |  | ||||||
|  | Building is a 2 part process. The first part is to build a local copy of the framework tailored to your environment. This | ||||||
|  | framework is [Poco](https://github.com/pocoproject/poco). The version used in this project has a couple of fixes | ||||||
|  | from the master copy needed for cmake. Please use the version of this [Poco fix](https://github.com/Telecominfraproject/wlan-cloud-lib-poco). Building | ||||||
|  | Poco may take several minutes depending on the platform you are building on. | ||||||
|  |  | ||||||
|  | ## Ubuntu | ||||||
|  | These instructions have proven to work on Ubuntu 20.4. | ||||||
|  | ```bash | ||||||
|  | sudo apt install git cmake g++ libssl-dev libmariabd-dev unixodbc-dev | ||||||
|  | sudo apt install libpq-dev libaprutil1-dev apache2-dev libboost-all-dev | ||||||
|  | sudo apt install librdkafka-dev liblua5.3-dev | ||||||
|  |  | ||||||
|  | git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1 poco | ||||||
|  | cd poco | ||||||
|  | mkdir cmake-build | ||||||
|  | cd cmake-build | ||||||
|  | cmake .. | ||||||
|  | cmake --build . --config Release | ||||||
|  | sudo cmake --build . --target install | ||||||
|  | cd ../.. | ||||||
|  |  | ||||||
|  | git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch tip-v1 cppkafka | ||||||
|  | cd cppkafka | ||||||
|  | mkdir cmake-build | ||||||
|  | cd cmake-build | ||||||
|  | cmake .. | ||||||
|  | cmake --build . --config Release | ||||||
|  | sudo cmake --build . --target install | ||||||
|  | cd ../.. | ||||||
|  |  | ||||||
|  | git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralgw | ||||||
|  | cd wlan-cloud-ucentralgw | ||||||
|  | mkdir cmake-build | ||||||
|  | cd cmake-build | ||||||
|  | cmake .. | ||||||
|  | make | ||||||
|  | cd ../.. | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Fedora | ||||||
|  | The following instructions have proven to work on Fedora 33 | ||||||
|  | ```bash | ||||||
|  | sudo yum install cmake g++ openssl-devel unixODBC-devel mysql-devel mysql apr-util-devel boost boost-devel | ||||||
|  | sudo yum install yaml-cpp-devel lua-devel | ||||||
|  | sudo dnf install postgresql.x86_64 librdkafka-devel | ||||||
|  | sudo dnf install postgresql-devel | ||||||
|  |  | ||||||
|  | git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1 poco | ||||||
|  | cd poco | ||||||
|  | mkdir cmake-build | ||||||
|  | cd cmake-build | ||||||
|  | cmake .. | ||||||
|  | cmake --build . --config Release | ||||||
|  | sudo cmake --build . --target install | ||||||
|  | cd ../.. | ||||||
|  |  | ||||||
|  | git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch tip-v1 cppkafka | ||||||
|  | cd cppkafka | ||||||
|  | mkdir cmake-build | ||||||
|  | cd cmake-build | ||||||
|  | cmake .. | ||||||
|  | cmake --build . --config Release | ||||||
|  | sudo cmake --build . --target install | ||||||
|  | cd ../.. | ||||||
|  |  | ||||||
|  | git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralfms | ||||||
|  | cd wlan-cloud-ucentralfms | ||||||
|  | mkdir cmake-build | ||||||
|  | cd cmake-build | ||||||
|  | cmake .. | ||||||
|  | make | ||||||
|  | cd ../.. | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Mac OSX Build | ||||||
|  | The following instructions have proven to work on OSX Big Sur. You need to install [Homebrew](https://brew.sh/). You must also have installed [XCode for OS X](https://www.freecodecamp.org/news/how-to-download-and-install-xcode/). | ||||||
|  | ```bash | ||||||
|  | brew install \ | ||||||
|  |     openssl cmake libpq mysql-client \ | ||||||
|  |     apr apr-util boost yaml-cpp postgresql \ | ||||||
|  |     unixodbc librdkafka | ||||||
|  |  | ||||||
|  | git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1 poco | ||||||
|  | cd poco | ||||||
|  | mkdir cmake-build | ||||||
|  | cd cmake-build | ||||||
|  | cmake .. | ||||||
|  | cmake --build . --config Release -j | ||||||
|  | sudo cmake --build . --target install | ||||||
|  | cd ../.. | ||||||
|  |  | ||||||
|  | git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch tip-v1 cppkafka | ||||||
|  | cd cppkafka | ||||||
|  | mkdir cmake-build | ||||||
|  | cd cmake-build | ||||||
|  | cmake .. | ||||||
|  | cmake --build . --config Release | ||||||
|  | sudo cmake --build . --target install | ||||||
|  | cd ../.. | ||||||
|  |  | ||||||
|  | git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralfms | ||||||
|  | cd wlan-cloud-ucentralfms | ||||||
|  | mkdir cmake-build | ||||||
|  | cd cmake-build | ||||||
|  | cmake .. | ||||||
|  | make -j | ||||||
|  | cd ../.. | ||||||
|  | ``` | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| cmake_minimum_required(VERSION 3.13) | cmake_minimum_required(VERSION 3.13) | ||||||
| project(owfms VERSION 2.7.0) | project(owfms VERSION 3.2.0) | ||||||
|  |  | ||||||
| set(CMAKE_CXX_STANDARD 17) | set(CMAKE_CXX_STANDARD 17) | ||||||
|  |  | ||||||
| @@ -27,12 +27,12 @@ endif() | |||||||
|  |  | ||||||
| find_package(Git QUIET) | find_package(Git QUIET) | ||||||
| if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") | if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") | ||||||
|     execute_process(COMMAND ${GIT_EXECUTABLE} describe --always --tags |     execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD | ||||||
|             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} |             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} | ||||||
|             RESULT_VARIABLE GIT_RESULT |             RESULT_VARIABLE GIT_RESULT | ||||||
|             OUTPUT_VARIABLE GIT_HASH) |             OUTPUT_VARIABLE GIT_HASH) | ||||||
|     if(NOT GIT_RESULT EQUAL "0") |     if(NOT GIT_RESULT EQUAL "0") | ||||||
|         message(FATAL_ERROR "git describe --always --tags failed with ${GIT_RESULT}") |         message(FATAL_ERROR "git rev-parse --short HEAD failed with ${GIT_RESULT}") | ||||||
|     endif() |     endif() | ||||||
|     string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}") |     string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}") | ||||||
| endif() | endif() | ||||||
| @@ -42,8 +42,10 @@ endif() | |||||||
|  |  | ||||||
| find_package(OpenSSL    REQUIRED) | find_package(OpenSSL    REQUIRED) | ||||||
| find_package(fmt        REQUIRED) | find_package(fmt        REQUIRED) | ||||||
|  | find_package(ZLIB       REQUIRED) | ||||||
| find_package(Poco       REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite) | find_package(Poco       REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite) | ||||||
| find_package(AWSSDK     REQUIRED COMPONENTS s3) | find_package(AWSSDK     REQUIRED COMPONENTS s3) | ||||||
|  | find_package(ZLIB       REQUIRED) | ||||||
|  |  | ||||||
| if(SMALL_BUILD) | if(SMALL_BUILD) | ||||||
|     find_package(Poco REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite) |     find_package(Poco REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite) | ||||||
| @@ -59,7 +61,7 @@ include_directories(/usr/local/include  /usr/local/opt/openssl/include src inclu | |||||||
| configure_file(src/ow_version.h.in ${PROJECT_SOURCE_DIR}/src/ow_version.h @ONLY) | configure_file(src/ow_version.h.in ${PROJECT_SOURCE_DIR}/src/ow_version.h @ONLY) | ||||||
|  |  | ||||||
| add_compile_options(-Wall -Wextra) | add_compile_options(-Wall -Wextra) | ||||||
| add_definitions(-DPOCO_LOG_DEBUG="1") | add_definitions(-DPOCO_LOG_DEBUG="1" -DBOOST_NO_CXX98_FUNCTION_BASE=1) | ||||||
|  |  | ||||||
| if(ASAN) | if(ASAN) | ||||||
|     add_compile_options(-fsanitize=address) |     add_compile_options(-fsanitize=address) | ||||||
| @@ -75,14 +77,55 @@ add_executable( owfms | |||||||
|         src/framework/OpenWifiTypes.h |         src/framework/OpenWifiTypes.h | ||||||
|         src/framework/orm.h |         src/framework/orm.h | ||||||
|         src/framework/StorageClass.h |         src/framework/StorageClass.h | ||||||
|         src/framework/ow_constants.h |  | ||||||
|         src/framework/MicroServiceErrorHandler.h |  | ||||||
|         src/framework/WebSocketClientNotifications.h |  | ||||||
|         src/framework/MicroServiceErrorHandler.h |         src/framework/MicroServiceErrorHandler.h | ||||||
|  |         src/framework/UI_WebSocketClientServer.cpp | ||||||
|  |         src/framework/UI_WebSocketClientServer.h | ||||||
|  |         src/framework/UI_WebSocketClientNotifications.cpp | ||||||
|  |         src/framework/UI_WebSocketClientNotifications.h | ||||||
|  |         src/framework/utils.h | ||||||
|  |         src/framework/utils.cpp | ||||||
|  |         src/framework/AppServiceRegistry.h | ||||||
|  |         src/framework/SubSystemServer.cpp | ||||||
|  |         src/framework/SubSystemServer.h | ||||||
|  |         src/framework/RESTAPI_utils.h | ||||||
|  |         src/framework/AuthClient.cpp | ||||||
|  |         src/framework/AuthClient.h | ||||||
|  |         src/framework/MicroServiceNames.h | ||||||
|  |         src/framework/MicroServiceFuncs.h | ||||||
|  |         src/framework/OpenAPIRequests.cpp | ||||||
|  |         src/framework/OpenAPIRequests.h | ||||||
|  |         src/framework/MicroServiceFuncs.cpp | ||||||
|  |         src/framework/ALBserver.cpp | ||||||
|  |         src/framework/ALBserver.h | ||||||
|  |         src/framework/KafkaManager.cpp | ||||||
|  |         src/framework/KafkaManager.h | ||||||
|  |         src/framework/RESTAPI_RateLimiter.h | ||||||
|  |         src/framework/WebSocketLogger.h | ||||||
|  |         src/framework/RESTAPI_GenericServerAccounting.h | ||||||
|  |         src/framework/RESTAPI_SystemConfiguration.h | ||||||
|  |         src/framework/CIDR.h | ||||||
|  |         src/framework/RESTAPI_Handler.cpp | ||||||
|  |         src/framework/RESTAPI_Handler.h | ||||||
|  |         src/framework/RESTAPI_ExtServer.h | ||||||
|  |         src/framework/RESTAPI_ExtServer.cpp | ||||||
|  |         src/framework/RESTAPI_IntServer.cpp | ||||||
|  |         src/framework/RESTAPI_IntServer.h | ||||||
|  |         src/framework/RESTAPI_SystemCommand.h | ||||||
|  |         src/framework/RESTAPI_WebSocketServer.h | ||||||
|  |         src/framework/EventBusManager.cpp | ||||||
|  |         src/framework/EventBusManager.h | ||||||
|  |         src/framework/RESTAPI_PartHandler.h | ||||||
|  |         src/framework/MicroService.cpp | ||||||
|  |         src/framework/MicroServiceExtra.h | ||||||
|  |         src/framework/default_device_types.h | ||||||
|         src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp |         src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp | ||||||
|         src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h |  | ||||||
|         src/RESTObjects/RESTAPI_GWobjects.h src/RESTObjects/RESTAPI_GWobjects.cpp |         src/RESTObjects/RESTAPI_GWobjects.h src/RESTObjects/RESTAPI_GWobjects.cpp | ||||||
|         src/RESTObjects/RESTAPI_FMSObjects.h src/RESTObjects/RESTAPI_FMSObjects.cpp |         src/RESTObjects/RESTAPI_FMSObjects.h src/RESTObjects/RESTAPI_FMSObjects.cpp | ||||||
|  |         src/RESTObjects/RESTAPI_CertObjects.cpp src/RESTObjects/RESTAPI_CertObjects.h | ||||||
|  |         src/RESTObjects/RESTAPI_OWLSobjects.cpp src/RESTObjects/RESTAPI_OWLSobjects.h | ||||||
|  |         src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h | ||||||
|  |         src/RESTObjects/RESTAPI_AnalyticsObjects.cpp src/RESTObjects/RESTAPI_AnalyticsObjects.h | ||||||
|  |         src/RESTObjects/RESTAPI_SubObjects.cpp src/RESTObjects/RESTAPI_SubObjects.h | ||||||
|         src/RESTAPI/RESTAPI_firmwaresHandler.cpp src/RESTAPI/RESTAPI_firmwaresHandler.h |         src/RESTAPI/RESTAPI_firmwaresHandler.cpp src/RESTAPI/RESTAPI_firmwaresHandler.h | ||||||
|         src/RESTAPI/RESTAPI_firmwareHandler.cpp src/RESTAPI/RESTAPI_firmwareHandler.h |         src/RESTAPI/RESTAPI_firmwareHandler.cpp src/RESTAPI/RESTAPI_firmwareHandler.h | ||||||
|         src/RESTAPI/RESTAPI_historyHandler.cpp src/RESTAPI/RESTAPI_historyHandler.h |         src/RESTAPI/RESTAPI_historyHandler.cpp src/RESTAPI/RESTAPI_historyHandler.h | ||||||
| @@ -95,7 +138,6 @@ add_executable( owfms | |||||||
|         src/Daemon.cpp src/Daemon.h |         src/Daemon.cpp src/Daemon.h | ||||||
|         src/StorageService.cpp src/StorageService.h |         src/StorageService.cpp src/StorageService.h | ||||||
|         src/ManifestCreator.cpp src/ManifestCreator.h |         src/ManifestCreator.cpp src/ManifestCreator.h | ||||||
|         src/framework/MicroService.h |  | ||||||
|         src/NewConnectionHandler.cpp src/NewConnectionHandler.h |         src/NewConnectionHandler.cpp src/NewConnectionHandler.h | ||||||
|         src/LatestFirmwareCache.cpp src/LatestFirmwareCache.h |         src/LatestFirmwareCache.cpp src/LatestFirmwareCache.h | ||||||
|         src/DeviceCache.cpp src/DeviceCache.h |         src/DeviceCache.cpp src/DeviceCache.h | ||||||
| @@ -105,7 +147,9 @@ add_executable( owfms | |||||||
|         src/NewCommandHandler.cpp src/NewCommandHandler.h |         src/NewCommandHandler.cpp src/NewCommandHandler.h | ||||||
|         src/storage/orm_history.cpp src/storage/orm_history.h |         src/storage/orm_history.cpp src/storage/orm_history.h | ||||||
|         src/storage/orm_firmwares.cpp src/storage/orm_firmwares.h |         src/storage/orm_firmwares.cpp src/storage/orm_firmwares.h | ||||||
|         src/storage/orm_deviceInfo.cpp src/storage/orm_deviceInfo.h src/RESTAPI/RESTAPI_deviceInformation_handler.cpp src/RESTAPI/RESTAPI_deviceInformation_handler.h) |         src/storage/orm_deviceInfo.cpp src/storage/orm_deviceInfo.h | ||||||
|  |         src/RESTAPI/RESTAPI_deviceInformation_handler.cpp | ||||||
|  |         src/RESTAPI/RESTAPI_deviceInformation_handler.h) | ||||||
|  |  | ||||||
| target_link_libraries( owfms PUBLIC | target_link_libraries( owfms PUBLIC | ||||||
|         ${Poco_LIBRARIES} |         ${Poco_LIBRARIES} | ||||||
| @@ -113,6 +157,7 @@ target_link_libraries( owfms PUBLIC | |||||||
|         ${ZLIB_LIBRARIES} |         ${ZLIB_LIBRARIES} | ||||||
|         ${AWSSDK_LINK_LIBRARIES} |         ${AWSSDK_LINK_LIBRARIES} | ||||||
|         fmt::fmt |         fmt::fmt | ||||||
|  |         resolv | ||||||
|         CppKafka::cppkafka |         CppKafka::cppkafka | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										250
									
								
								CONFIGURATION.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,250 @@ | |||||||
|  | # OWFMS Configuration | ||||||
|  | Here is the list of parameters you can configure in the `owfms.properties` file. | ||||||
|  |  | ||||||
|  | ## OWFMS Specific Parameters | ||||||
|  | ### OWFMS behaviour | ||||||
|  | ```properties | ||||||
|  | firmwaredb.refresh = 86400 | ||||||
|  | firmwaredb.maxage = 90 | ||||||
|  | autoupdater.enabled = true | ||||||
|  | ``` | ||||||
|  | #### firmwaredb.refresh | ||||||
|  | How often to refresh the FMS DB, in seconds. Should never be less than 6 hours. It does take 10-20 minutes to  | ||||||
|  | create a refresh. The default is 24 hours.  | ||||||
|  |  | ||||||
|  | #### firmwaredb.maxage | ||||||
|  | The maximum age of firmware kept in the DB (in days). Do not go more than 6 months. The default is 3 months. | ||||||
|  |  | ||||||
|  | #### autoupdater.enabled | ||||||
|  | The determins if the FMS autoupdates its database. You should leave this to `true`. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ### S3 information | ||||||
|  | The actual data for all the firmware is kept in a TIP bucket. The following parameters allow you to change the bucket. | ||||||
|  | You should never need to do this unless you need to implement your own FMS server. | ||||||
|  |  | ||||||
|  | ```properties | ||||||
|  | s3.bucketname = ucentral-ap-firmware | ||||||
|  | s3.region = us-east-1 | ||||||
|  | s3.secret = ******************************************* | ||||||
|  | s3.key =  ******************************************* | ||||||
|  | s3.retry = 60 | ||||||
|  | s3.bucket.uri = ucentral-ap-firmware.s3.amazonaws.com | ||||||
|  | s3.endpoint.https = true | ||||||
|  | s3.endpointOverride = "" | ||||||
|  | s3.useVirtualAdressing = true | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### s3.bucketname | ||||||
|  | The S3 bucket name. | ||||||
|  | #### s3.region | ||||||
|  | The region for this bucket. | ||||||
|  | #### s3.secret | ||||||
|  | The AWS secret for access to this S3 bucket | ||||||
|  | #### s3.key | ||||||
|  | The AWS key for access for this S3 bucket | ||||||
|  | #### s3.retry = 60 | ||||||
|  | The AWS retry window in seconds. | ||||||
|  | #### s3.bucket.uri = ucentral-ap-firmware.s3.amazonaws.com | ||||||
|  | The URI to the S3 bucket | ||||||
|  | #### s3.endpointOverride = "" | ||||||
|  | The Endpoint Address to override if you using a different provider that not AWS. | ||||||
|  | #### s3.endpoint.https = true | ||||||
|  | The Endpoint Method if you using a HTTP endpoint | ||||||
|  | #### s3.useVirtualAdressing = true | ||||||
|  | In a virtual-hosted–style URI, the bucket name is part of the domain name in the URL. (Not supported by all providers) | ||||||
|  |  | ||||||
|  | ## Generic OpenWiFi SDK parameters | ||||||
|  | ### REST API External parameters | ||||||
|  | These are the parameters required for the configuration of the external facing REST API server | ||||||
|  | ```properties | ||||||
|  | openwifi.restapi.host.0.backlog = 100 | ||||||
|  | openwifi.restapi.host.0.security = relaxed | ||||||
|  | openwifi.restapi.host.0.rootca = $OWFMS_ROOT/certs/restapi-ca.pem | ||||||
|  | openwifi.restapi.host.0.address = * | ||||||
|  | openwifi.restapi.host.0.port = 16004 | ||||||
|  | openwifi.restapi.host.0.cert = $OWFMS_ROOT/certs/restapi-cert.pem | ||||||
|  | openwifi.restapi.host.0.key = $OWFMS_ROOT/certs/restapi-key.pem | ||||||
|  | openwifi.restapi.host.0.key.password = mypassword | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### openwifi.restapi.host.0.backlog | ||||||
|  | This is the number of concurrent REST API calls that maybe be kept in the backlog for processing. That's a good rule of thumb. Never go above 500. | ||||||
|  | #### openwifi.restapi.host.0.rootca | ||||||
|  | This is the root file of your own certificate CA in `pem` format. | ||||||
|  | #### openwifi.restapi.host.0.cert | ||||||
|  | This is your own server certificate in `pem` format.. | ||||||
|  | #### openwifi.restapi.host.0.key | ||||||
|  | This is the private key associated with your own certificate in `pem` format. | ||||||
|  | #### openwifi.restapi.host.0.address | ||||||
|  | Leve this a `*` in the case you want to bind to all interfaces on your gateway host or select the address of a single interface. | ||||||
|  | #### openwifi.restapi.host.0.port | ||||||
|  | The port on which the REST API server is listening. By default, this is 16002. | ||||||
|  | #### openwifi.restapi.host.0.security | ||||||
|  | Leave this as `relaxed` for now for devices. | ||||||
|  | #### openwifi.restapi.host.0.key.password | ||||||
|  | If you key file uses a password, please enter it here. | ||||||
|  |  | ||||||
|  | ### REST API Intra microservice parameters | ||||||
|  | The following parameters describe the configuration for the inter-microservice HTTP server. You may use the same certificate/key | ||||||
|  | you are using for your extenral server or another certificate. | ||||||
|  | ```properties | ||||||
|  | openwifi.internal.restapi.host.0.backlog = 100 | ||||||
|  | openwifi.internal.restapi.host.0.security = relaxed | ||||||
|  | openwifi.internal.restapi.host.0.rootca = $OWFMS_ROOT/certs/restapi-ca.pem | ||||||
|  | openwifi.internal.restapi.host.0.address = * | ||||||
|  | openwifi.internal.restapi.host.0.port = 17004 | ||||||
|  | openwifi.internal.restapi.host.0.cert = $OWFMS_ROOT/certs/restapi-cert.pem | ||||||
|  | openwifi.internal.restapi.host.0.key = $OWFMS_ROOT/certs/restapi-key.pem | ||||||
|  | openwifi.internal.restapi.host.0.key.password = mypassword | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### openwifi.internal.host.0.backlog | ||||||
|  | This is the number of concurrent REST API calls that maybe be kept in the backlog for processing. That's a good rule of thumb. Never go above 500. | ||||||
|  | #### openwifi.internal.host.0.rootca | ||||||
|  | This is the root file of your own certificate CA in `pem` format. | ||||||
|  | #### openwifi.internal.host.0.cert | ||||||
|  | This is your own server certificate in `pem` format.. | ||||||
|  | #### openwifi.internal.host.0.key | ||||||
|  | This is the private key associated with your own certificate in `pem` format. | ||||||
|  | #### openwifi.internal.host.0.address | ||||||
|  | Leve this a `*` in the case you want to bind to all interfaces on your gateway host or select the address of a single interface. | ||||||
|  | #### openwifi.internal.host.0.port | ||||||
|  | The port on which the REST API server is listening. By default, this is 17002. | ||||||
|  | #### openwifi.internal.host.0.security | ||||||
|  | Leave this as `relaxed` for now for devices. | ||||||
|  | #### openwifi.internal.host.0.key.password | ||||||
|  | If you key file uses a password, please enter it here. | ||||||
|  |  | ||||||
|  | ### Microservice information | ||||||
|  | These are different Microservie parameters. Following is a brief explanation. | ||||||
|  | ```properties | ||||||
|  | openwifi.service.key = $OWFMS_ROOT/certs/restapi-key.pem | ||||||
|  | openwifi.service.key.password = mypassword | ||||||
|  | openwifi.system.data = $OWFMS_ROOT/data | ||||||
|  | openwifi.system.uri.private = https://localhost:17004 | ||||||
|  | openwifi.system.uri.public = https://ucentral.dpaas.arilia.com:16002 | ||||||
|  | openwifi.system.uri.ui = https://ucentral-ui.arilia.com | ||||||
|  | openwifi.security.restapi.disable = false | ||||||
|  | openwifi.system.commandchannel = /tmp/app.ucentralfms | ||||||
|  | openwifi.autoprovisioning = true | ||||||
|  | ``` | ||||||
|  | #### openwifi.service.key | ||||||
|  | From time to time, the microservice must encrypt information. This is the key it should use. You may use the | ||||||
|  | same keey as you RESTAPI or your server. | ||||||
|  | #### openwifi.service.key.password | ||||||
|  | The password for the `openwifi.service.key` | ||||||
|  | #### openwifi.system.data | ||||||
|  | The location of system data. This path must exist. | ||||||
|  | #### openwifi.system.uri.private | ||||||
|  | The URI to reach the controller on the internal port. | ||||||
|  | #### openwifi.system.uri.public | ||||||
|  | The URI to reach the controller from the outside world. | ||||||
|  | #### openwifi.system.uri.ui | ||||||
|  | The URI of the UI to manage this service | ||||||
|  | #### openwifi.security.restapi.disable | ||||||
|  | This allows to disable security for internal and external API calls. This should only be used if the controller | ||||||
|  | sits behind an application load balancer that will actually do TLS. Setting this to `true` disables security. | ||||||
|  | #### openwifi.system.commandchannel | ||||||
|  | The UNIX socket command channel used by this service. | ||||||
|  | #### openwifi.autoprovisioning | ||||||
|  | Allow unknown devices to be provisioned by the system. | ||||||
|  |  | ||||||
|  | ### ALB Support | ||||||
|  | In order to support an application load balancer health check verification, your need to provide the following parameters. | ||||||
|  | ```properties | ||||||
|  | alb.enable = true | ||||||
|  | alb.port = 16104 | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Kafka | ||||||
|  | The controller use Kafka, like all the other microservices. You must configure the kafka section in order for the | ||||||
|  | system to work. | ||||||
|  | ```properties | ||||||
|  | openwifi.kafka.group.id = firmware | ||||||
|  | openwifi.kafka.client.id = firmware1 | ||||||
|  | openwifi.kafka.enable = true | ||||||
|  | openwifi.kafka.brokerlist = my_Kafka.example.com:9092 | ||||||
|  | openwifi.kafka.auto.commit = false | ||||||
|  | openwifi.kafka.queue.buffering.max.ms = 50 | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### openwifi.kafka.group.id | ||||||
|  | The group ID is a single word that should identify the type of service tuning. In the case `firmware` | ||||||
|  | ### openwifi.kafka.client.id | ||||||
|  | The client ID is a single service within that group ID. Each participant must have a unique client ID. | ||||||
|  | ### openwifi.kafka.enable | ||||||
|  | Kafka should always be enabled. | ||||||
|  | ### openwifi.kafka.brokerlist | ||||||
|  | The list of servers where your Kafka server is running. Comma separated. | ||||||
|  | ### openwifi.kafka.auto.commit | ||||||
|  | Auto commit flag in Kafka. Leave as `false`. | ||||||
|  | ### openwifi.kafka.queue.buffering.max.ms | ||||||
|  | Kafka buffering. Leave as `50`. | ||||||
|  | ### Kafka security | ||||||
|  | If you intend to use SSL, you should look into Kafka Connect and specify the certificates below. | ||||||
|  | ```properties | ||||||
|  | penwifi.kafka.ssl.ca.location = | ||||||
|  | openwifi.kafka.ssl.certificate.location = | ||||||
|  | openwifi.kafka.ssl.key.location = | ||||||
|  | openwifi.kafka.ssl.key.password = | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### DB Type | ||||||
|  | The controller supports 3 types of Database. SQLite should only be used for sites with less than 100 APs or for testing in the lab. | ||||||
|  | In order to select which database to use, you must set the `storage.type` value to sqlite, postgresql, or mysql. | ||||||
|  |  | ||||||
|  | ```properties | ||||||
|  | storage.type = sqlite | ||||||
|  | #storage.type = postgresql | ||||||
|  | #storage.type = mysql | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Storage SQLite parameters | ||||||
|  | Additional parameters to set for SQLite. The only important one is `storage.type.sqlite.db` which is the database name on disk. | ||||||
|  | ```properties | ||||||
|  | storage.type.sqlite.db = firmware.db | ||||||
|  | storage.type.sqlite.idletime = 120 | ||||||
|  | storage.type.sqlite.maxsessions = 128 | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Storage Postgres | ||||||
|  | Additional parameters to set if you select Postgres for your database. You must specify `host`, `username`, `password`, | ||||||
|  | `database`, and `port`. | ||||||
|  | ```properties | ||||||
|  | storage.type.postgresql.maxsessions = 64 | ||||||
|  | storage.type.postgresql.idletime = 60 | ||||||
|  | storage.type.postgresql.host = localhost | ||||||
|  | storage.type.postgresql.username = firmware | ||||||
|  | storage.type.postgresql.password = firmware | ||||||
|  | storage.type.postgresql.database = firmware | ||||||
|  | storage.type.postgresql.port = 5432 | ||||||
|  | storage.type.postgresql.connectiontimeout = 60 | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Storage MySQL/MariaDB | ||||||
|  | Additional parameters to set if you select mysql for your database. You must specify `host`, `username`, `password`, | ||||||
|  | `database`, and `port`. | ||||||
|  | ```properties | ||||||
|  | storage.type.mysql.maxsessions = 64 | ||||||
|  | storage.type.mysql.idletime = 60 | ||||||
|  | storage.type.mysql.host = localhost | ||||||
|  | storage.type.postgresql.username = firmware | ||||||
|  | storage.type.postgresql.password = firmware | ||||||
|  | storage.type.postgresql.database = firmware | ||||||
|  | storage.type.mysql.port = 3306 | ||||||
|  | storage.type.mysql.connectiontimeout = 60 | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Logging Parameters | ||||||
|  | The microservice provides extensive logging. If you would like to keep logging on disk, set the `logging.type = file`. If you only want | ||||||
|  | console logging, `set logging.type = console`. When selecting file, `logging.path` must exist. `logging.level` sets the | ||||||
|  | basic logging level for the entire controller. `logging.websocket` disables WebSocket logging. | ||||||
|  |  | ||||||
|  | ```properties | ||||||
|  | logging.type = file | ||||||
|  | logging.path = $OWFMS_ROOT/logs | ||||||
|  | logging.level = information | ||||||
|  | logging.asynch = true | ||||||
|  | logging.websocket = false | ||||||
|  | ``` | ||||||
							
								
								
									
										38
									
								
								CONTRIBUTING.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,38 @@ | |||||||
|  | # How to Contribute | ||||||
|  |  | ||||||
|  | We'd love to accept your patches and contributions to this project. There are | ||||||
|  | just a few small guidelines you need to follow. | ||||||
|  |  | ||||||
|  | ## Version of C++ | ||||||
|  | This project is based on the C++17 standard and compiles as-is on most platforms  | ||||||
|  | using either clang or g++. Do not use C++21 or C++23 features for now. Some core  | ||||||
|  | libraries used in this project do not support C++21 or C++23 yet. | ||||||
|  |  | ||||||
|  | ## Variable Naming | ||||||
|  | Naming of pretty much anything uses Pascal naming. Longer explicit names using casing.  | ||||||
|  | Member variable naming adds a `_` at the end of the vars. Try to | ||||||
|  | keep this standard going. Sometimes you must override a base class function and then of course | ||||||
|  | you need to follow the base class. | ||||||
|  |  | ||||||
|  | ## This is a cmake project | ||||||
|  | This is a cmake project, and you need to adhere to the cmake rules. If you need | ||||||
|  | to add a package to the CMakeList, you need to ensure that the package is available | ||||||
|  | on all required platforms and compiles. Remember that this project runs on Linux, OS X,  | ||||||
|  | and the Raspberry PI. | ||||||
|  |  | ||||||
|  | ## Licensed packages | ||||||
|  | When adding a package, you must also state the licensing for the package. MIT, BSD, Apache licenses | ||||||
|  | are acceptable. No commercial licenses are allowed.  | ||||||
|  |  | ||||||
|  | ## clang formatting | ||||||
|  | Please format your code using the included `.clang-format` file included in the project. | ||||||
|  |  | ||||||
|  | ```bash | ||||||
|  | clang-format -i --style=<project root>/.clang-format myfile.cpp | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ## Pull Requests | ||||||
|  | All submissions, including submissions by project members, require review. We | ||||||
|  | accept GitHub pull requests. Please create a branch with the Jira name for addressing the issue you are fixing or the  | ||||||
|  | feature you are implementing. | ||||||
|  | Create a pull-request from the branch into master.  | ||||||
							
								
								
									
										135
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						| @@ -1,24 +1,23 @@ | |||||||
| ARG DEBIAN_VERSION=11.4-slim | ARG DEBIAN_VERSION=11.5-slim | ||||||
| ARG POCO_VERSION=poco-tip-v1 | ARG POCO_VERSION=poco-tip-v2 | ||||||
| ARG FMTLIB_VERSION=9.0.0 |  | ||||||
| ARG CPPKAFKA_VERSION=tip-v1 | ARG CPPKAFKA_VERSION=tip-v1 | ||||||
| ARG JSON_VALIDATOR_VERSION=2.1.0 | ARG VALIJASON_VERSION=tip-v1 | ||||||
| ARG AWS_SDK_VERSION=1.9.315 | ARG APP_NAME=owfms | ||||||
|  | ARG APP_HOME_DIR=/openwifi | ||||||
|  |  | ||||||
| FROM debian:$DEBIAN_VERSION AS build-base | FROM debian:$DEBIAN_VERSION AS build-base | ||||||
|  |  | ||||||
| RUN apt-get update && apt-get install --no-install-recommends -y \ | RUN apt-get update && apt-get install --no-install-recommends -y \ | ||||||
|     make cmake g++ git \ |     make cmake g++ git curl zip unzip pkg-config \ | ||||||
|     libpq-dev libmariadb-dev libmariadbclient-dev-compat \ |     libpq-dev libmariadb-dev libmariadbclient-dev-compat \ | ||||||
|     librdkafka-dev libboost-all-dev libssl-dev \ |     librdkafka-dev libboost-all-dev libssl-dev \ | ||||||
|     zlib1g-dev nlohmann-json3-dev ca-certificates libcurl4-openssl-dev |     zlib1g-dev ca-certificates libcurl4-openssl-dev libfmt-dev | ||||||
|  |  | ||||||
| FROM build-base AS poco-build | FROM build-base AS poco-build | ||||||
|  |  | ||||||
| ARG POCO_VERSION | ARG POCO_VERSION | ||||||
|  | ADD https://api.github.com/repos/Telecominfraproject/wlan-cloud-lib-poco/git/refs/tags/${POCO_VERSION} version.json | ||||||
| ADD https://api.github.com/repos/AriliaWireless/poco/git/refs/tags/${POCO_VERSION} version.json | RUN git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch ${POCO_VERSION} /poco | ||||||
| RUN git clone https://github.com/AriliaWireless/poco --branch ${POCO_VERSION} /poco |  | ||||||
|  |  | ||||||
| WORKDIR /poco | WORKDIR /poco | ||||||
| RUN mkdir cmake-build | RUN mkdir cmake-build | ||||||
| @@ -27,26 +26,12 @@ RUN cmake .. | |||||||
| RUN cmake --build . --config Release -j8 | RUN cmake --build . --config Release -j8 | ||||||
| RUN cmake --build . --target install | RUN cmake --build . --target install | ||||||
|  |  | ||||||
| FROM build-base AS fmtlib-build |  | ||||||
|  |  | ||||||
| ARG FMTLIB_VERSION |  | ||||||
|  |  | ||||||
| ADD https://api.github.com/repos/fmtlib/fmt/git/refs/tags/${FMTLIB_VERSION} version.json |  | ||||||
| RUN git clone https://github.com/fmtlib/fmt --branch ${FMTLIB_VERSION} /fmtlib |  | ||||||
|  |  | ||||||
| WORKDIR /fmtlib |  | ||||||
| RUN mkdir cmake-build |  | ||||||
| WORKDIR cmake-build |  | ||||||
| RUN cmake .. |  | ||||||
| RUN make |  | ||||||
| RUN make install |  | ||||||
|  |  | ||||||
| FROM build-base AS cppkafka-build | FROM build-base AS cppkafka-build | ||||||
|  |  | ||||||
| ARG CPPKAFKA_VERSION | ARG CPPKAFKA_VERSION | ||||||
|  |  | ||||||
| ADD https://api.github.com/repos/AriliaWireless/cppkafka/git/refs/tags/${CPPKAFKA_VERSION} version.json | ADD https://api.github.com/repos/Telecominfraproject/wlan-cloud-lib-cppkafka/git/refs/tags/${CPPKAFKA_VERSION} version.json | ||||||
| RUN git clone https://github.com/AriliaWireless/cppkafka --branch ${CPPKAFKA_VERSION} /cppkafka | RUN git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch ${CPPKAFKA_VERSION} /cppkafka | ||||||
|  |  | ||||||
| WORKDIR /cppkafka | WORKDIR /cppkafka | ||||||
| RUN mkdir cmake-build | RUN mkdir cmake-build | ||||||
| @@ -55,99 +40,73 @@ RUN cmake .. | |||||||
| RUN cmake --build . --config Release -j8 | RUN cmake --build . --config Release -j8 | ||||||
| RUN cmake --build . --target install | RUN cmake --build . --target install | ||||||
|  |  | ||||||
| FROM build-base AS json-schema-validator-build | FROM build-base AS app-build | ||||||
|  |  | ||||||
| ARG JSON_VALIDATOR_VERSION | ARG APP_NAME | ||||||
|  |  | ||||||
| ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/tags/${JSON_VALIDATOR_VERSION} version.json | ADD CMakeLists.txt build /${APP_NAME}/ | ||||||
| RUN git clone https://github.com/pboettch/json-schema-validator --branch ${JSON_VALIDATOR_VERSION} /json-schema-validator | ADD overlays /${APP_NAME}/overlays | ||||||
|  | ADD cmake /${APP_NAME}/cmake | ||||||
|  | ADD src /${APP_NAME}/src | ||||||
|  | ADD .git /${APP_NAME}/.git | ||||||
|  | ARG VCPKG_VERSION=2022.11.14 | ||||||
|  |  | ||||||
| WORKDIR /json-schema-validator | RUN git clone --depth 1 --branch ${VCPKG_VERSION} https://github.com/microsoft/vcpkg && \ | ||||||
| RUN mkdir cmake-build |     ./vcpkg/bootstrap-vcpkg.sh && \ | ||||||
| WORKDIR cmake-build |     mkdir /vcpkg/custom-triplets && \ | ||||||
| RUN cmake .. |     cp /vcpkg/triplets/x64-linux.cmake /vcpkg/custom-triplets/x64-linux.cmake && \ | ||||||
| RUN make |     sed -i 's/set(VCPKG_LIBRARY.*/set(VCPKG_LIBRARY_LINKAGE dynamic)/g' /vcpkg/custom-triplets/x64-linux.cmake && \ | ||||||
| RUN make install |     ./vcpkg/vcpkg install aws-sdk-cpp[s3]:x64-linux json-schema-validator:x64-linux --overlay-triplets=/vcpkg/custom-triplets --overlay-ports=/owfms/overlays | ||||||
|  |  | ||||||
| FROM build-base AS aws-sdk-cpp-build |  | ||||||
|  |  | ||||||
| ARG AWS_SDK_VERSION |  | ||||||
|  |  | ||||||
| ADD https://api.github.com/repos/aws/aws-sdk-cpp/git/refs/tags/${AWS_SDK_VERSION} version.json |  | ||||||
| RUN git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp --branch ${AWS_SDK_VERSION} /aws-sdk-cpp |  | ||||||
|  |  | ||||||
| WORKDIR /aws-sdk-cpp |  | ||||||
| RUN mkdir cmake-build |  | ||||||
| WORKDIR cmake-build |  | ||||||
| RUN cmake .. -DBUILD_ONLY="sns;s3" \ |  | ||||||
|              -DCMAKE_BUILD_TYPE=Release \ |  | ||||||
|              -DUSE_OPENSSL=ON \ |  | ||||||
|              -DCPP_STANDARD=17 \ |  | ||||||
|              -DBUILD_SHARED_LIBS=ON \ |  | ||||||
|              -DCMAKE_CXX_FLAGS="-Wno-error=stringop-overflow -Wno-error=uninitialized" \ |  | ||||||
|              -DAUTORUN_UNIT_TESTS=OFF |  | ||||||
| RUN cmake --build . --config Release -j8 |  | ||||||
| RUN cmake --build . --target install |  | ||||||
|  |  | ||||||
| FROM build-base AS owfms-build |  | ||||||
|  |  | ||||||
| ADD CMakeLists.txt build /owfms/ |  | ||||||
| ADD cmake /owfms/cmake |  | ||||||
| ADD src /owfms/src |  | ||||||
| ADD .git /owfms/.git |  | ||||||
|  |  | ||||||
| COPY --from=poco-build /usr/local/include /usr/local/include | COPY --from=poco-build /usr/local/include /usr/local/include | ||||||
| COPY --from=poco-build /usr/local/lib /usr/local/lib | COPY --from=poco-build /usr/local/lib /usr/local/lib | ||||||
| COPY --from=cppkafka-build /usr/local/include /usr/local/include | COPY --from=cppkafka-build /usr/local/include /usr/local/include | ||||||
| COPY --from=cppkafka-build /usr/local/lib /usr/local/lib | COPY --from=cppkafka-build /usr/local/lib /usr/local/lib | ||||||
| COPY --from=json-schema-validator-build /usr/local/include /usr/local/include |  | ||||||
| COPY --from=json-schema-validator-build /usr/local/lib /usr/local/lib |  | ||||||
| COPY --from=aws-sdk-cpp-build /usr/local/include /usr/local/include |  | ||||||
| COPY --from=aws-sdk-cpp-build /usr/local/lib /usr/local/lib |  | ||||||
| COPY --from=fmtlib-build /usr/local/include /usr/local/include |  | ||||||
| COPY --from=fmtlib-build /usr/local/lib /usr/local/lib |  | ||||||
|  |  | ||||||
| WORKDIR /owfms | WORKDIR /${APP_NAME} | ||||||
| RUN mkdir cmake-build | RUN mkdir cmake-build | ||||||
| WORKDIR /owfms/cmake-build | WORKDIR /${APP_NAME}/cmake-build | ||||||
| RUN cmake .. | RUN cmake -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake .. | ||||||
| RUN cmake --build . --config Release -j8 | RUN cmake --build . --config Release -j8 | ||||||
|  |  | ||||||
| FROM debian:$DEBIAN_VERSION | FROM debian:$DEBIAN_VERSION | ||||||
|  |  | ||||||
| ENV OWFMS_USER=owfms \ | ARG APP_NAME | ||||||
|     OWFMS_ROOT=/owfms-data \ | ARG APP_HOME_DIR | ||||||
|     OWFMS_CONFIG=/owfms-data |  | ||||||
|  |  | ||||||
| RUN useradd "$OWFMS_USER" | ENV APP_NAME=$APP_NAME \ | ||||||
|  |     APP_USER=$APP_NAME \ | ||||||
|  |     APP_ROOT=/$APP_NAME-data \ | ||||||
|  |     APP_CONFIG=/$APP_NAME-data \ | ||||||
|  |     APP_HOME_DIR=$APP_HOME_DIR | ||||||
|  |  | ||||||
| RUN mkdir /openwifi | RUN useradd $APP_USER | ||||||
| RUN mkdir -p "$OWFMS_ROOT" "$OWFMS_CONFIG" && \ |  | ||||||
|     chown "$OWFMS_USER": "$OWFMS_ROOT" "$OWFMS_CONFIG" | RUN mkdir $APP_HOME_DIR | ||||||
|  | RUN mkdir -p "$APP_ROOT" "$APP_CONFIG" && \ | ||||||
|  |     chown "$APP_USER": "$APP_ROOT" "$APP_CONFIG" | ||||||
|  |  | ||||||
| RUN apt-get update && apt-get install --no-install-recommends -y \ | RUN apt-get update && apt-get install --no-install-recommends -y \ | ||||||
|     librdkafka++1 gosu gettext ca-certificates bash jq curl wget \ |     librdkafka++1 gosu gettext ca-certificates bash jq curl wget \ | ||||||
|     libmariadb-dev-compat libpq5 unixodbc postgresql-client |     libmariadb-dev-compat libpq5 postgresql-client libfmt7 sqlite3 | ||||||
|  |  | ||||||
| COPY readiness_check /readiness_check | COPY readiness_check /readiness_check | ||||||
| COPY test_scripts/curl/cli /cli | COPY test_scripts/curl/cli /cli | ||||||
|  |  | ||||||
| COPY owfms.properties.tmpl / | COPY $APP_NAME.properties.tmpl / | ||||||
| COPY docker-entrypoint.sh / | COPY docker-entrypoint.sh / | ||||||
| COPY wait-for-postgres.sh / | COPY wait-for-postgres.sh / | ||||||
| RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \ | RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \ | ||||||
|     -O /usr/local/share/ca-certificates/restapi-ca-selfsigned.crt |     -O /usr/local/share/ca-certificates/restapi-ca-selfsigned.crt | ||||||
|  |  | ||||||
| COPY --from=owfms-build /owfms/cmake-build/owfms /openwifi/owfms | COPY --from=app-build /$APP_NAME/cmake-build/$APP_NAME $APP_HOME_DIR/$APP_NAME | ||||||
| COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib | COPY --from=app-build /vcpkg/installed/x64-linux/lib/ /usr/local/lib/ | ||||||
| COPY --from=poco-build /poco/cmake-build/lib/* /usr/local/lib | COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/ /usr/local/lib/ | ||||||
| COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-cpp-sdk-core.so /usr/local/lib | COPY --from=poco-build /poco/cmake-build/lib/ /usr/local/lib/ | ||||||
| COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib |  | ||||||
| COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib |  | ||||||
|  |  | ||||||
| RUN ldconfig | RUN ldconfig | ||||||
|  |  | ||||||
| EXPOSE 16004 17004 16104 | EXPOSE 16004 17004 16104 | ||||||
|  |  | ||||||
| ENTRYPOINT ["/docker-entrypoint.sh"] | ENTRYPOINT ["/docker-entrypoint.sh"] | ||||||
| CMD ["/openwifi/owfms"] | CMD ${APP_HOME_DIR}/${APP_NAME} | ||||||
|   | |||||||
							
								
								
									
										252
									
								
								README.md
									
									
									
									
									
								
							
							
						
						| @@ -1,3 +1,7 @@ | |||||||
|  | <p align="center"> | ||||||
|  |     <img src="images/project/logo.svg" width="200"/> | ||||||
|  | </p> | ||||||
|  |  | ||||||
| # uCentralFMS | # uCentralFMS | ||||||
|  |  | ||||||
| ## What is this? | ## What is this? | ||||||
| @@ -5,215 +9,87 @@ The uCentralFMS is a micro-service part of the OpenWiFi ecosystem. uCentralFMS i | |||||||
| to facilitate the task of upgrade and maintaining the proper firmware for all the devices  | to facilitate the task of upgrade and maintaining the proper firmware for all the devices  | ||||||
| used in your OpenWiFi solution. You may either [build it](#building) or use the [Docker version](#docker). | used in your OpenWiFi solution. You may either [build it](#building) or use the [Docker version](#docker). | ||||||
|  |  | ||||||
|  | ## OpenAPI | ||||||
|  | You may get static page with OpenAPI docs generated from the definition on [GitHub Page](https://telecominfraproject.github.io/wlan-cloud-ucentralfms/). | ||||||
|  | Also, you may use [Swagger UI](https://petstore.swagger.io/#/) with OpenAPI definition file raw link (i.e. [latest version file](https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentralfms/main/openapi/owfms.yaml)) to get interactive docs page. | ||||||
|  |  | ||||||
| ## Building | ## Building | ||||||
| In order to build the uCentralFMS, you will need to install its dependencies, which includes the following: | To build the microservice from source, please follow the instructions in [here](./BUILDING.md) | ||||||
| - cmake |  | ||||||
| - boost |  | ||||||
| - POCO 1.10.1 or later |  | ||||||
| - a C++17 compiler |  | ||||||
| - openssl |  | ||||||
| - libpq-dev (PortgreSQL development libraries) |  | ||||||
| - mysql-client (MySQL client) |  | ||||||
| - librdkafka |  | ||||||
| - cppkafka |  | ||||||
|  |  | ||||||
| Building is a 2 part process. The first part is to build a local copy of the framework tailored to your environment. This | ## Docker | ||||||
| framework is [Poco](https://github.com/pocoproject/poco). The version used in this project has a couple of fixes | To use the CLoudSDK deployment please follow [here](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy) | ||||||
| from the master copy needed for cmake. Please use the version of this [Poco fix](https://github.com/stephb9959/poco). Building |  | ||||||
| Poco may take several minutes depending on the platform you are building on. |  | ||||||
|  |  | ||||||
| ### Ubuntu |  | ||||||
| These instructions have proven to work on Ubuntu 20.4. |  | ||||||
| ``` |  | ||||||
| sudo apt install git cmake g++ libssl-dev libmariabd-dev unixodbc-dev  |  | ||||||
| sudo apt install libpq-dev libaprutil1-dev apache2-dev libboost-all-dev |  | ||||||
| sudo apt install librdkafka-dev liblua5.3-dev |  | ||||||
|  |  | ||||||
| git clone https://github.com/stephb9959/poco |  | ||||||
| cd poco |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| cmake --build . --config Release |  | ||||||
| sudo cmake --build . --target install |  | ||||||
|  |  | ||||||
| git clone https://github.com/stephb9959/cppkafka |  | ||||||
| cd cppkafka |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| cmake --build . --config Release |  | ||||||
| sudo cmake --build . --target install |  | ||||||
|  |  | ||||||
| cd ~ |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralgw |  | ||||||
| cd wlan-cloud-ucentralgw |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| make |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### Fedora |  | ||||||
| The following instructions have proven to work on Fedora 33 |  | ||||||
| ``` |  | ||||||
| sudo yum install cmake g++ openssl-devel unixODBC-devel mysql-devel mysql apr-util-devel boost boost-devel |  | ||||||
| sudo yum install yaml-cpp-devel lua-devel  |  | ||||||
| sudo dnf install postgresql.x86_64 librdkafka-devel |  | ||||||
| sudo dnf install postgresql-devel |  | ||||||
|  |  | ||||||
| git clone https://github.com/stephb9959/poco |  | ||||||
| cd poco |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| cmake --build . --config Release |  | ||||||
| sudo cmake --build . --target install |  | ||||||
|  |  | ||||||
| git clone https://github.com/stephb9959/cppkafka |  | ||||||
| cd cppkafka |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| cmake --build . --config Release |  | ||||||
| sudo cmake --build . --target install |  | ||||||
|  |  | ||||||
| cd ~ |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralfms |  | ||||||
| cd wlan-cloud-ucentralfms |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| make |  | ||||||
|  |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### OSX Build |  | ||||||
| The following instructions have proven to work on OSX Big Sur. You need to install [Homebrew](https://brew.sh/). You must also have installed [XCode for OS X](https://www.freecodecamp.org/news/how-to-download-and-install-xcode/). |  | ||||||
| ``` |  | ||||||
| brew install openssl |  | ||||||
| brew install cmake |  | ||||||
| brew install libpq |  | ||||||
| brew install mysql-client |  | ||||||
| brew install apr |  | ||||||
| brew install apr-util |  | ||||||
| brew install boost |  | ||||||
| brew install yaml-cpp |  | ||||||
| brew install postgresql |  | ||||||
| brew install unixodbc |  | ||||||
| brew install librdkafka |  | ||||||
|  |  | ||||||
| git clone https://github.com/stephb9959/poco |  | ||||||
| cd poco |  | ||||||
| mkdir cmake-build  |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| cmake --build . --config Release -j |  | ||||||
| sudo cmake --build . --target install |  | ||||||
|  |  | ||||||
| git clone https://github.com/stephb9959/cppkafka |  | ||||||
| cd cppkafka |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| cmake --build . --config Release |  | ||||||
| sudo cmake --build . --target install |  | ||||||
|  |  | ||||||
| cd ~ |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralfms |  | ||||||
| cd wlan-cloud-ucentralfms |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| make -j |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### After completing the build |  | ||||||
| After completing the build, you can remove the Poco source as it is no longer needed. |  | ||||||
|  |  | ||||||
| #### Expected directory layout | #### Expected directory layout | ||||||
| From the directory where your cloned source is, you will need to create the `certs`, `logs`, and `data`. | From the directory where your cloned source is, you will need to create the `certs`, `logs`, and `uploads` directories. | ||||||
| ```shell | ```bash | ||||||
| mkdir certs | mkdir certs | ||||||
|  | mkdir certs/cas | ||||||
| mkdir logs | mkdir logs | ||||||
| mkdir data | mkdir uploads | ||||||
|  | ``` | ||||||
|  | You should now have the following: | ||||||
|  | ```text | ||||||
|  | --+-- certs | ||||||
|  |   |   +--- cas | ||||||
|  |   +-- cmake | ||||||
|  |   +-- cmake-build | ||||||
|  |   +-- logs | ||||||
|  |   +-- src | ||||||
|  |   +-- test_scripts | ||||||
|  |   +-- openapi | ||||||
|  |   +-- uploads | ||||||
|  |   +-- owsec.properties | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### Certificates | ### Certificate | ||||||
| Love'em of hate'em, we gotta use'em. So we tried to make this as easy as possible for you. | The OWFMS uses a certificate to provide security for the REST API Certificate to secure the Northbound API. | ||||||
|  |  | ||||||
| #### The `certs` directory | #### The `certs` directory | ||||||
| For all deployments, you will need the following `certs` directory, populated with the proper files. | For all deployments, you will need the following `certs` directory, populated with the proper files. | ||||||
|  |  | ||||||
| ```asm | ```text | ||||||
| certs ---+---  | certs ---+--- restapi-ca.pem | ||||||
|          +--- restapi-ca.pem |  | ||||||
|          +--- restapi-cert.pem |          +--- restapi-cert.pem | ||||||
|          +--- restapi-key.pem |          +--- restapi-key.pem | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| ### Configuration | ## Firewall Considerations | ||||||
| The configuration is kep in the file `owfms.properties`. This is a text file read by the service at startup time. | | Port  | Description                                   | Configurable | | ||||||
|  | |:------|:----------------------------------------------|:------------:| | ||||||
|  | | 16003 | Default port for REST API Access to the OWFMS |     yes      | | ||||||
|  |  | ||||||
| #### Basic configuration | ### Environment variables | ||||||
| You must set the environment variables: | The following environment variables should be set from the root directory of the service. They tell the OWGW process where to find | ||||||
| - OWFMS_ROOT: represents where the root of the installation is for this service. | the configuration and the root directory. | ||||||
| - OWFMS_CONFIG: represents the path where the configuration is kept. | ```bash | ||||||
|  | export OWGW_ROOT=`pwd` | ||||||
| #### The file section | export OWGW_CONFIG=`pwd` | ||||||
| #### RESTAPI |  | ||||||
| ```json |  | ||||||
| openwifi.restapi.host.0.backlog = 100 |  | ||||||
| openwifi.restapi.host.0.security = relaxed |  | ||||||
| openwifi.restapi.host.0.rootca = $OWFMS_ROOT/certs/restapi-ca.pem |  | ||||||
| openwifi.restapi.host.0.address = * |  | ||||||
| openwifi.restapi.host.0.port = 16004 |  | ||||||
| openwifi.restapi.host.0.cert = $OWFMS_ROOT/certs/restapi-cert.pem |  | ||||||
| openwifi.restapi.host.0.key = $OWFMS_ROOT/certs/restapi-key.pem |  | ||||||
| openwifi.restapi.host.0.key.password = mypassword |  | ||||||
| ``` | ``` | ||||||
| Of importance are the `.port` which should point to the port used. | You can run the shell script `set_env.sh` from the microservice root. | ||||||
|  |  | ||||||
| #### Internal microservice interface | ### OWFMS Service Configuration | ||||||
| ```json | The configuration is kept in a file called `owfms.properties`. To understand the content of this file, | ||||||
| openwifi.internal.restapi.host.0.backlog = 100 | please look [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralfms/blob/main/CONFIGURATION.md) | ||||||
| openwifi.internal.restapi.host.0.security = relaxed |  | ||||||
| openwifi.internal.restapi.host.0.rootca = $OWFMS_ROOT/certs/restapi-ca.pem |  | ||||||
| openwifi.internal.restapi.host.0.address = * |  | ||||||
| openwifi.internal.restapi.host.0.port = 17004 |  | ||||||
| openwifi.internal.restapi.host.0.cert = $OWFMS_ROOT/certs/restapi-cert.pem |  | ||||||
| openwifi.internal.restapi.host.0.key = $OWFMS_ROOT/certs/restapi-key.pem |  | ||||||
| openwifi.internal.restapi.host.0.key.password = mypassword |  | ||||||
| ``` |  | ||||||
| You can leave all the default values for this one.  |  | ||||||
|  |  | ||||||
| #### System values | ## Kafka topics | ||||||
| In the following values, you need to change `.uri.public` and `uri.ui`. The `.uri.public` must point to an externally available FQDN to access the service. The `.uri.ui` must point to web server running  | Toe read more about Kafka, follow the [document](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/KAFKA.md) | ||||||
| the UI for the service. `firmwaredb.refresh` tells the service how often to refresh the firmware database in seconds. `firmwaredb.maxage` tells the service how old you |  | ||||||
| want to accept release for. This value is in days. |  | ||||||
|  |  | ||||||
| ```json | ## Contributions | ||||||
| openwifi.service.key = $OWFMS_ROOT/certs/restapi-key.pem | We need more contributors. Should you wish to contribute, | ||||||
| openwifi.service.key.password = mypassword | please follow the [contributions](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/CONTRIBUTING.md) document. | ||||||
| openwifi.system.data = $OWFMS_ROOT/data |  | ||||||
| openwifi.system.debug = false |  | ||||||
| openwifi.system.uri.private = https://localhost:17004 |  | ||||||
| openwifi.system.uri.public = https://ucentral.dpaas.arilia.com:16004 |  | ||||||
| openwifi.system.commandchannel = /tmp/app.owfms |  | ||||||
| openwifi.system.uri.ui = ucentral-ui.arilia.com |  | ||||||
| firmwaredb.refresh = 1800 |  | ||||||
| firmwaredb.maxage = 90 |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| #### S3 configuration | ## Pull Requests | ||||||
| The service mua read the information about firmware from an Amazon S3 Bucket. You need to replace `s3.secret` and `s3.key` with your own.  | Please create a branch with the Jira addressing the issue you are fixing or the feature you are implementing. | ||||||
|  | Create a pull-request from the branch into master. | ||||||
|  |  | ||||||
| ```json | ## Additional OWSDK Microservices | ||||||
| s3.bucketname = ucentral-ap-firmware | Here is a list of additional OWSDK microservices | ||||||
| s3.region = us-east-1 | | Name | Description | Link | OpenAPI | | ||||||
| s3.secret = ******************************************* | | :--- | :--- | :---: | :---: | | ||||||
| s3.key =  ******************************************* | | OWSEC | Security Service | [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralsec) | [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml) | | ||||||
| s3.retry = 60 | | OWGW | Controller Service | [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw) | [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/openapi/owgw.yaml) | | ||||||
| s3.bucket.uri = ucentral-ap-firmware.s3.amazonaws.com | | OWFMS | Firmware Management Service | [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralfms) | [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralfms/blob/main/openapi/owfms.yaml) | | ||||||
|  | | OWPROV | Provisioning Service | [here](https://github.com/Telecominfraproject/wlan-cloud-owprov) | [here](https://github.com/Telecominfraproject/wlan-cloud-owprov/blob/main/openapi/owprov.yaml) | | ||||||
|  | | OWANALYTICS | Analytics Service | [here](https://github.com/Telecominfraproject/wlan-cloud-analytics) | [here](https://github.com/Telecominfraproject/wlan-cloud-analytics/blob/main/openapi/owanalytics.yaml) | | ||||||
|  | | OWSUB | Subscriber Service | [here](https://github.com/Telecominfraproject/wlan-cloud-userportal) | [here](https://github.com/Telecominfraproject/wlan-cloud-userportal/blob/main/openapi/userportal.yaml) | | ||||||
|  |  | ||||||
| ``` |  | ||||||
| @@ -23,6 +23,11 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then | |||||||
|   SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16004"} \ |   SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16004"} \ | ||||||
|   SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \ |   SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \ | ||||||
|   SECURITY_RESTAPI_DISABLE=${SECURITY_RESTAPI_DISABLE:-"false"} \ |   SECURITY_RESTAPI_DISABLE=${SECURITY_RESTAPI_DISABLE:-"false"} \ | ||||||
|  |   FIRMWAREDB_REFRESH=${FIRMWAREDB_REFRESH:-"86400"} \ | ||||||
|  |   FIRMWAREDB_MAXAGE=${FIRMWAREDB_MAXAGE:-"90"} \ | ||||||
|  |   S3_VIRTUAL_ADRESSING=${S3_VIRTUAL_ADRESSING:-"true"} \ | ||||||
|  |   S3_HTTPS=${S3_HTTPS:-"true"} \ | ||||||
|  |   S3_ENDPOINT=${S3_ENDPOINT:-""} \ | ||||||
|   S3_BUCKETNAME=${S3_BUCKETNAME:-"ucentral-ap-firmware"} \ |   S3_BUCKETNAME=${S3_BUCKETNAME:-"ucentral-ap-firmware"} \ | ||||||
|   S3_REGION=${S3_REGION:-"us-east-1"} \ |   S3_REGION=${S3_REGION:-"us-east-1"} \ | ||||||
|   S3_SECRET=${S3_SECRET:-"*******************************************"} \ |   S3_SECRET=${S3_SECRET:-"*******************************************"} \ | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ fullnameOverride: "" | |||||||
| images: | images: | ||||||
|   owfms: |   owfms: | ||||||
|     repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owfms |     repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owfms | ||||||
|     tag: main |     tag: v3.2.0 | ||||||
|     pullPolicy: Always |     pullPolicy: Always | ||||||
| #    regcred: | #    regcred: | ||||||
| #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | ||||||
| @@ -143,11 +143,14 @@ configProperties: | |||||||
|   openwifi.internal.restapi.host.0.cert: $OWFMS_ROOT/certs/restapi-cert.pem |   openwifi.internal.restapi.host.0.cert: $OWFMS_ROOT/certs/restapi-cert.pem | ||||||
|   openwifi.internal.restapi.host.0.key: $OWFMS_ROOT/certs/restapi-key.pem |   openwifi.internal.restapi.host.0.key: $OWFMS_ROOT/certs/restapi-key.pem | ||||||
|   # Firmware Microservice Specific Section |   # Firmware Microservice Specific Section | ||||||
|  |   s3.endpointOverride: "" | ||||||
|  |   s3.useVirtualAdressing: true | ||||||
|  |   s3.endpoint.https: true | ||||||
|   s3.bucketname: ucentral-ap-firmware |   s3.bucketname: ucentral-ap-firmware | ||||||
|   s3.region: us-east-1 |   s3.region: us-east-1 | ||||||
|   s3.retry: 60 |   s3.retry: 60 | ||||||
|   s3.bucket.uri: ucentral-ap-firmware.s3.amazonaws.com |   s3.bucket.uri: ucentral-ap-firmware.s3.amazonaws.com | ||||||
|   firmwaredb.refresh: 1800 |   firmwaredb.refresh: 86400 | ||||||
|   # ALB |   # ALB | ||||||
|   alb.enable: "true" |   alb.enable: "true" | ||||||
|   alb.port: 16104 |   alb.port: 16104 | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								images/device_types/cig_wf160d.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 104 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/cig_wf188.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 80 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/cig_wf188n.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 80 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/cig_wf194c.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 75 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/cig_wf194c4.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 75 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/cig_wf808.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 218 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/cig_wf809.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 158 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/edgecore_eap101.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 140 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/edgecore_eap102.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 121 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/edgecore_ecs4100-12ph.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 44 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/edgecore_ecw5211.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 192 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/edgecore_ecw5410.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 197 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/edgecore_oap100.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 50 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/edgecore_spw2ac1200-lan-poe.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 59 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/edgecore_spw2ac1200.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 59 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/edgecore_ssw2ac2600.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 51 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/hfcl_ion4.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 72 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/hfcl_ion4.yml.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 72 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/indio_um-305ac.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 34 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/linksys_e8450-ubi.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 98 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/linksys_ea6350-v4.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 89 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/linksys_ea6350.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 89 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/linksys_ea8300.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 204 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/tp-link_ec420-g1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 159 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/tplink_ec420.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 159 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/tplink_ex227.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 103 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/tplink_ex228.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 103 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/tplink_ex447.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 103 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/wallys_dr40x9.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 59 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/wallys_dr6018.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 80 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/device_types/wallys_dr6018_v4.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 80 KiB | 
							
								
								
									
										
											BIN
										
									
								
								images/project/logo.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 4.8 KiB | 
							
								
								
									
										165
									
								
								images/project/logo.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,165 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <!-- Generator: Adobe Illustrator 24.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> | ||||||
|  | <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" | ||||||
|  | 	 viewBox="0 0 141.5 185.6" style="enable-background:new 0 0 141.5 185.6;" xml:space="preserve"> | ||||||
|  | <style type="text/css"> | ||||||
|  | 	.st0{fill:#414141;} | ||||||
|  | 	.st1{fill:#FFFFFF;} | ||||||
|  | 	.st2{fill:#FED206;} | ||||||
|  | 	.st3{fill:#EB6F53;} | ||||||
|  | 	.st4{fill:#3BA9B6;} | ||||||
|  | </style> | ||||||
|  | <g> | ||||||
|  | 	<g> | ||||||
|  | 		<path class="st0" d="M120.7,183.9H21.5c-10.8,0-19.5-8.7-19.5-19.5V20.5c0-10.8,8.7-19.5,19.5-19.5h99.2 | ||||||
|  | 			c10.8,0,19.5,8.7,19.5,19.5v143.9C140.2,175.2,131.5,183.9,120.7,183.9z"/> | ||||||
|  | 		<g> | ||||||
|  | 			<g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M46.3,166.2v-3.4h-1.2v-0.6h3.1v0.6H47v3.4H46.3z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M49,166.2v-4h2.7v0.6h-2v1h2v0.6h-2v1.1h2v0.6H49z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M52.6,166.2v-4h0.7v3.4h1.8v0.6H52.6z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M55.7,166.2v-4h2.7v0.6h-2v1h2v0.6h-2v1.1h2v0.6H55.7z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M59.1,164.2c0-1.2,0.9-2.1,2.1-2.1c0.8,0,1.3,0.4,1.6,0.9l-0.6,0.3c-0.2-0.3-0.6-0.6-1-0.6 | ||||||
|  | 						c-0.8,0-1.4,0.6-1.4,1.4c0,0.8,0.6,1.4,1.4,1.4c0.4,0,0.8-0.3,1-0.6l0.6,0.3c-0.3,0.5-0.8,0.9-1.6,0.9 | ||||||
|  | 						C60,166.3,59.1,165.5,59.1,164.2z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M63.2,164.2c0-1.2,0.8-2.1,2-2.1c1.2,0,2,0.9,2,2.1c0,1.2-0.8,2.1-2,2.1C64,166.3,63.2,165.4,63.2,164.2z | ||||||
|  | 						 M66.5,164.2c0-0.8-0.5-1.4-1.3-1.4c-0.8,0-1.3,0.6-1.3,1.4c0,0.8,0.5,1.4,1.3,1.4C66,165.7,66.5,165,66.5,164.2z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M71.3,166.2v-3.1l-1.2,3.1h-0.3l-1.2-3.1v3.1h-0.7v-4h1l1.1,2.7l1.1-2.7h1v4H71.3z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M75.7,166.2v-4h0.7v4H75.7z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M80.4,166.2l-2.1-2.8v2.8h-0.7v-4h0.7l2,2.8v-2.8h0.7v4H80.4z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M82.3,166.2v-4H85v0.6h-2v1h2v0.6h-2v1.7H82.3z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M87.9,166.2l-0.9-1.5h-0.7v1.5h-0.7v-4h1.7c0.8,0,1.3,0.5,1.3,1.2c0,0.7-0.5,1.1-0.9,1.2l1,1.6H87.9z | ||||||
|  | 						 M88,163.5c0-0.4-0.3-0.6-0.7-0.6h-1v1.3h1C87.7,164.1,88,163.9,88,163.5z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M92.4,166.2l-0.3-0.8h-1.8l-0.3,0.8h-0.8l1.6-4h0.9l1.6,4H92.4z M91.2,162.9l-0.7,1.9h1.4L91.2,162.9z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M95.8,166.2v-4h1.5c0.8,0,1.2,0.5,1.2,1.2c0,0.6-0.4,1.2-1.2,1.2h-1.2v1.7H95.8z M98.2,163.4 | ||||||
|  | 						c0-0.5-0.3-0.9-0.9-0.9h-1.1v1.7h1.1C97.8,164.3,98.2,163.9,98.2,163.4z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M101.5,166.2l-1.1-1.6h-0.9v1.6h-0.3v-4h1.5c0.7,0,1.2,0.4,1.2,1.2c0,0.7-0.5,1.1-1.1,1.1l1.2,1.7H101.5z | ||||||
|  | 						 M101.6,163.4c0-0.5-0.4-0.9-0.9-0.9h-1.1v1.7h1.1C101.2,164.3,101.6,163.9,101.6,163.4z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M102.8,164.2c0-1.2,0.8-2.1,1.9-2.1c1.2,0,1.9,0.9,1.9,2.1c0,1.2-0.8,2.1-1.9,2.1 | ||||||
|  | 						C103.6,166.3,102.8,165.4,102.8,164.2z M106.3,164.2c0-1-0.6-1.7-1.6-1.7c-1,0-1.6,0.7-1.6,1.7c0,1,0.6,1.7,1.6,1.7 | ||||||
|  | 						C105.7,166,106.3,165.2,106.3,164.2z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M106.9,165.8l0.2-0.3c0.2,0.2,0.4,0.4,0.8,0.4c0.5,0,0.9-0.4,0.9-0.9v-2.8h0.3v2.8c0,0.8-0.5,1.2-1.2,1.2 | ||||||
|  | 						C107.5,166.3,107.2,166.1,106.9,165.8z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M110.4,166.2v-4h2.5v0.3h-2.2v1.5h2.1v0.3h-2.1v1.6h2.2v0.3H110.4z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M113.5,164.2c0-1.2,0.9-2.1,2-2.1c0.6,0,1.1,0.3,1.5,0.7l-0.3,0.2c-0.3-0.3-0.7-0.6-1.2-0.6 | ||||||
|  | 						c-0.9,0-1.7,0.7-1.7,1.7c0,1,0.7,1.7,1.7,1.7c0.5,0,0.9-0.2,1.2-0.6l0.3,0.2c-0.4,0.4-0.8,0.7-1.5,0.7 | ||||||
|  | 						C114.4,166.3,113.5,165.5,113.5,164.2z"/> | ||||||
|  | 				</g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st1" d="M118.7,166.2v-3.7h-1.3v-0.3h2.9v0.3H119v3.7H118.7z"/> | ||||||
|  | 				</g> | ||||||
|  | 			</g> | ||||||
|  | 			<g> | ||||||
|  | 				<polygon class="st1" points="26.3,163.8 31.6,158.5 36.9,163.8 37.7,163.8 31.6,157.6 25.5,163.8 				"/> | ||||||
|  | 				<polygon class="st1" points="36.9,164.7 31.6,170 26.3,164.7 25.5,164.7 31.6,170.8 37.7,164.7 				"/> | ||||||
|  | 				<polygon class="st1" points="31,163.8 36.3,158.5 41.6,163.8 42.5,163.8 36.3,157.6 30.2,163.8 				"/> | ||||||
|  | 				<polygon class="st1" points="41.6,164.7 36.3,170 31,164.7 30.2,164.7 36.3,170.8 42.5,164.7 				"/> | ||||||
|  | 			</g> | ||||||
|  | 		</g> | ||||||
|  | 		<g> | ||||||
|  | 			<path class="st1" d="M33.2,100.7c-4.6,0-8.3,3.7-8.3,8.3s3.7,8.3,8.3,8.3s8.3-3.7,8.3-8.3S37.8,100.7,33.2,100.7z"/> | ||||||
|  | 		</g> | ||||||
|  | 		<g> | ||||||
|  | 			<g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st2" d="M33.2,35.2c40.7,0,73.8,33.1,73.8,73.8c0,0.7,0,1.4,0,2.1c0,1.7,0.6,3.3,1.7,4.6c1.2,1.2,2.8,1.9,4.5,2 | ||||||
|  | 						l0.2,0c3.5,0,6.3-2.7,6.4-6.2c0-0.8,0-1.7,0-2.5c0-47.7-38.8-86.6-86.6-86.6c-0.8,0-1.7,0-2.5,0c-1.7,0-3.3,0.8-4.5,2 | ||||||
|  | 						c-1.2,1.2-1.8,2.9-1.7,4.6c0.1,3.5,3,6.3,6.6,6.2C31.8,35.2,32.5,35.2,33.2,35.2z"/> | ||||||
|  | 				</g> | ||||||
|  | 			</g> | ||||||
|  | 		</g> | ||||||
|  | 		<g> | ||||||
|  | 			<g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st3" d="M33.2,60.5c26.7,0,48.5,21.7,48.5,48.5c0,0.6,0,1.3,0,2c-0.1,1.7,0.5,3.3,1.7,4.6c1.2,1.3,2.7,2,4.4,2.1 | ||||||
|  | 						c1.7,0.1,3.3-0.5,4.6-1.7c1.2-1.2,2-2.7,2-4.4c0-0.9,0.1-1.8,0.1-2.6c0-33.8-27.5-61.2-61.2-61.2c-0.8,0-1.6,0-2.6,0.1 | ||||||
|  | 						c-1.7,0.1-3.3,0.8-4.4,2.1c-1.2,1.3-1.8,2.9-1.7,4.6s0.8,3.3,2.1,4.4c1.3,1.2,2.9,1.8,4.6,1.7C31.9,60.5,32.6,60.5,33.2,60.5z" | ||||||
|  | 						/> | ||||||
|  | 				</g> | ||||||
|  | 			</g> | ||||||
|  | 		</g> | ||||||
|  | 		<g> | ||||||
|  | 			<g> | ||||||
|  | 				<g> | ||||||
|  | 					<path class="st4" d="M33.2,86.7c12.3,0,22.3,10,22.3,22.3c0,0.5,0,1.1-0.1,1.8c-0.3,3.5,2.3,6.6,5.8,6.9 | ||||||
|  | 						c3.5,0.3,6.6-2.3,6.9-5.8c0.1-1,0.1-1.9,0.1-2.8c0-19.3-15.7-35.1-35.1-35.1c-0.9,0-1.8,0-2.8,0.1c-1.7,0.1-3.2,0.9-4.3,2.2 | ||||||
|  | 						c-1.1,1.3-1.6,2.9-1.5,4.6c0.1,1.7,0.9,3.2,2.2,4.3c1.3,1.1,2.9,1.6,4.6,1.5C32.1,86.7,32.7,86.7,33.2,86.7z"/> | ||||||
|  | 				</g> | ||||||
|  | 			</g> | ||||||
|  | 		</g> | ||||||
|  | 	</g> | ||||||
|  | 	<g> | ||||||
|  | 		<path class="st1" d="M35.8,130.4c1.1,0.6,2.1,1.5,2.7,2.6c0.7,1.1,1,2.3,1,3.7s-0.3,2.6-1,3.7c-0.7,1.1-1.6,2-2.7,2.6 | ||||||
|  | 			c-1.1,0.6-2.4,1-3.8,1s-2.7-0.3-3.8-1c-1.1-0.6-2.1-1.5-2.7-2.6c-0.7-1.1-1-2.3-1-3.7c0-1.3,0.3-2.6,1-3.7c0.7-1.1,1.6-2,2.7-2.6 | ||||||
|  | 			c1.1-0.6,2.4-0.9,3.8-0.9C33.4,129.5,34.7,129.8,35.8,130.4z M29.9,132.9c-0.7,0.4-1.2,0.9-1.6,1.6s-0.6,1.4-0.6,2.2 | ||||||
|  | 			c0,0.8,0.2,1.6,0.6,2.3c0.4,0.7,0.9,1.2,1.6,1.6c0.7,0.4,1.4,0.6,2.1,0.6c0.8,0,1.5-0.2,2.1-0.6c0.6-0.4,1.2-0.9,1.5-1.6 | ||||||
|  | 			c0.4-0.7,0.6-1.4,0.6-2.3c0-0.8-0.2-1.6-0.6-2.2s-0.9-1.2-1.5-1.6c-0.6-0.4-1.4-0.6-2.1-0.6C31.3,132.3,30.6,132.5,29.9,132.9z"/> | ||||||
|  | 		<path class="st1" d="M50.6,133.6c0.8,0.5,1.4,1.1,1.8,2c0.4,0.8,0.6,1.8,0.6,2.9c0,1.1-0.2,2-0.6,2.8c-0.4,0.8-1,1.5-1.8,1.9 | ||||||
|  | 			c-0.8,0.5-1.6,0.7-2.6,0.7c-0.7,0-1.4-0.1-2-0.4s-1.1-0.7-1.5-1.2v5.4h-3.1V133h3.1v1.6c0.4-0.5,0.9-1,1.4-1.2s1.2-0.4,2-0.4 | ||||||
|  | 			C48.9,132.9,49.8,133.1,50.6,133.6z M49.1,140.5c0.5-0.6,0.7-1.3,0.7-2.2c0-0.9-0.2-1.6-0.7-2.1c-0.5-0.6-1.1-0.8-1.9-0.8 | ||||||
|  | 			s-1.4,0.3-1.9,0.8c-0.5,0.6-0.8,1.3-0.8,2.1c0,0.9,0.2,1.6,0.8,2.2s1.1,0.8,1.9,0.8S48.6,141,49.1,140.5z"/> | ||||||
|  | 		<path class="st1" d="M63.4,134.4c0.9,1,1.4,2.4,1.4,4.2c0,0.3,0,0.6,0,0.7H57c0.2,0.7,0.5,1.2,1,1.6c0.5,0.4,1.1,0.6,1.8,0.6 | ||||||
|  | 			c0.5,0,1-0.1,1.5-0.3s0.9-0.5,1.3-0.9l1.6,1.6c-0.5,0.6-1.2,1.1-2,1.4c-0.8,0.3-1.6,0.5-2.6,0.5c-1.1,0-2.1-0.2-3-0.7 | ||||||
|  | 			s-1.5-1.1-2-1.9c-0.5-0.8-0.7-1.8-0.7-2.9c0-1.1,0.2-2.1,0.7-2.9s1.1-1.5,2-1.9c0.8-0.5,1.8-0.7,2.9-0.7 | ||||||
|  | 			C61.2,132.9,62.5,133.4,63.4,134.4z M61.8,137.5c0-0.7-0.3-1.3-0.7-1.7s-1-0.6-1.7-0.6c-0.7,0-1.2,0.2-1.7,0.6 | ||||||
|  | 			c-0.4,0.4-0.7,1-0.9,1.7H61.8z"/> | ||||||
|  | 		<path class="st1" d="M76.2,134c0.7,0.7,1.1,1.7,1.1,3v6.8h-3.1v-5.9c0-0.7-0.2-1.2-0.6-1.6s-0.9-0.6-1.5-0.6 | ||||||
|  | 			c-0.8,0-1.4,0.3-1.8,0.8c-0.4,0.5-0.7,1.2-0.7,2v5.3h-3.1V133h3.1v1.9c0.7-1.3,2-2,3.7-2C74.6,132.8,75.5,133.2,76.2,134z"/> | ||||||
|  | 		<path class="st1" d="M96,129.7h3.3l-4.7,14h-3.3l-2.9-10.1l-3,10.1h-3.2l-4.7-14h3.4l3,10.7l3-10.7H90l3.1,10.7L96,129.7z"/> | ||||||
|  | 		<path class="st1" d="M103.3,128.7c0.3,0.3,0.5,0.7,0.5,1.2s-0.2,0.9-0.5,1.2c-0.3,0.3-0.7,0.5-1.2,0.5c-0.5,0-0.9-0.2-1.2-0.5 | ||||||
|  | 			c-0.3-0.3-0.5-0.7-0.5-1.2c0-0.5,0.2-0.9,0.5-1.2c0.3-0.3,0.7-0.5,1.2-0.5C102.6,128.2,103,128.3,103.3,128.7z M100.6,133h3.1 | ||||||
|  | 			v10.8h-3.1V133z"/> | ||||||
|  | 		<path class="st1" d="M106.5,129.7h10.1l0,2.6h-6.9v3.4h6.3v2.6h-6.3v5.3h-3.2V129.7z"/> | ||||||
|  | 		<path class="st1" d="M120.9,128.7c0.3,0.3,0.5,0.7,0.5,1.2s-0.2,0.9-0.5,1.2c-0.3,0.3-0.7,0.5-1.2,0.5c-0.5,0-0.9-0.2-1.2-0.5 | ||||||
|  | 			c-0.3-0.3-0.5-0.7-0.5-1.2c0-0.5,0.2-0.9,0.5-1.2c0.3-0.3,0.7-0.5,1.2-0.5C120.1,128.2,120.5,128.3,120.9,128.7z M118.1,133h3.1 | ||||||
|  | 			v10.8h-3.1V133z"/> | ||||||
|  | 	</g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | <g> | ||||||
|  | </g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 8.0 KiB | 
| @@ -251,6 +251,17 @@ components: | |||||||
|         latestFirmwareAvailable: |         latestFirmwareAvailable: | ||||||
|           type: boolean |           type: boolean | ||||||
|  |  | ||||||
|  |     ExtraSystemConfiguration: | ||||||
|  |       type: array | ||||||
|  |       items: | ||||||
|  |         type: object | ||||||
|  |         properties: | ||||||
|  |           parameterName: | ||||||
|  |             type: string | ||||||
|  |           parameterValue: | ||||||
|  |             type: string | ||||||
|  |  | ||||||
|  |  | ||||||
|     ######################################################################################### |     ######################################################################################### | ||||||
|     ## |     ## | ||||||
|     ## These are endpoints that all services in the uCentral stack must provide |     ## These are endpoints that all services in the uCentral stack must provide | ||||||
| @@ -342,6 +353,33 @@ components: | |||||||
|                 type: integer |                 type: integer | ||||||
|                 format: int64 |                 format: int64 | ||||||
|  |  | ||||||
|  |     SystemResources: | ||||||
|  |       type: object | ||||||
|  |       properties: | ||||||
|  |         numberOfFileDescriptors: | ||||||
|  |           type: integer | ||||||
|  |           format: int64 | ||||||
|  |         currRealMem: | ||||||
|  |           type: integer | ||||||
|  |           format: int64 | ||||||
|  |         peakRealMem: | ||||||
|  |           type: integer | ||||||
|  |           format: int64 | ||||||
|  |         currVirtMem: | ||||||
|  |           type: integer | ||||||
|  |           format: int64 | ||||||
|  |         peakVirtMem: | ||||||
|  |           type: integer | ||||||
|  |           format: int64 | ||||||
|  |  | ||||||
|  |     SystemCommandResults: | ||||||
|  |       type: object | ||||||
|  |       oneOf: | ||||||
|  |         - $ref: '#/components/schemas/SystemResources' | ||||||
|  |         - $ref: '#/components/schemas/SystemInfoResults' | ||||||
|  |         - $ref: '#/components/schemas/StringList' | ||||||
|  |         - $ref: '#/components/schemas/TagValuePairList' | ||||||
|  |  | ||||||
|     SystemCommandSetLogLevel: |     SystemCommandSetLogLevel: | ||||||
|       type: object |       type: object | ||||||
|       properties: |       properties: | ||||||
| @@ -476,6 +514,11 @@ paths: | |||||||
|             type: boolean |             type: boolean | ||||||
|             default: false |             default: false | ||||||
|           required: false |           required: false | ||||||
|  |         - in: query | ||||||
|  |           name: updateTimeOnly | ||||||
|  |           schema: | ||||||
|  |             type: boolean | ||||||
|  |           required: false | ||||||
|       responses: |       responses: | ||||||
|         200: |         200: | ||||||
|           description: List firmwares |           description: List firmwares | ||||||
| @@ -483,6 +526,11 @@ paths: | |||||||
|             application/json: |             application/json: | ||||||
|               schema: |               schema: | ||||||
|                 oneOf: |                 oneOf: | ||||||
|  |                   - type: object | ||||||
|  |                     properties: | ||||||
|  |                       lastUpdateTime: | ||||||
|  |                         type: integer | ||||||
|  |                         format: int64 | ||||||
|                   - $ref: '#/components/schemas/FirmwareDetailsList' |                   - $ref: '#/components/schemas/FirmwareDetailsList' | ||||||
|                   - $ref: '#/components/schemas/FirmwareDetails' |                   - $ref: '#/components/schemas/FirmwareDetails' | ||||||
|         403: |         403: | ||||||
| @@ -490,6 +538,29 @@ paths: | |||||||
|         404: |         404: | ||||||
|           $ref: '#/components/responses/NotFound' |           $ref: '#/components/responses/NotFound' | ||||||
|  |  | ||||||
|  |     put: | ||||||
|  |       tags: | ||||||
|  |         - Firmware | ||||||
|  |       summary: Force a DB refresh. | ||||||
|  |       description: Force a DB refresh. | ||||||
|  |       operationId: updateFirmwareList | ||||||
|  |       parameters: | ||||||
|  |         - in: query | ||||||
|  |           description: Force the firmware DB update | ||||||
|  |           name: update | ||||||
|  |           schema: | ||||||
|  |             type: boolean | ||||||
|  |           required: false | ||||||
|  |       responses: | ||||||
|  |         200: | ||||||
|  |           $ref: '#/components/responses/Success' | ||||||
|  |         400: | ||||||
|  |           $ref: '#/components/responses/BadRequest' | ||||||
|  |         403: | ||||||
|  |           $ref: '#/components/responses/Unauthorized' | ||||||
|  |         404: | ||||||
|  |           $ref: '#/components/responses/NotFound' | ||||||
|  |  | ||||||
|   /firmware/{id}: |   /firmware/{id}: | ||||||
|     get: |     get: | ||||||
|       tags: |       tags: | ||||||
| @@ -699,19 +770,19 @@ paths: | |||||||
|       operationId: getFirmwareAge |       operationId: getFirmwareAge | ||||||
|       parameters: |       parameters: | ||||||
|         - in: query |         - in: query | ||||||
|           description: The exact current verion of the firmware on that device. |           description: The exact current version of the firmware on that device. | ||||||
|           name: revision |           name: revision | ||||||
|           schema: |           schema: | ||||||
|             type: string |             type: string | ||||||
|           required: true |           required: true | ||||||
|         - in: query |         - in: query | ||||||
|           description: The exact current verion of the firmware on that device. |           description: The exact current version of the firmware on that device. | ||||||
|           name: deviceType |           name: deviceType | ||||||
|           schema: |           schema: | ||||||
|             type: string |             type: string | ||||||
|           required: true |           required: true | ||||||
|         - in: query |         - in: query | ||||||
|           description: Specify lits of serial  numbers to retrive age for |           description: Specify list of serial  numbers to retrieve age for | ||||||
|           name: select |           name: select | ||||||
|           schema: |           schema: | ||||||
|             type: string |             type: string | ||||||
| @@ -881,16 +952,75 @@ paths: | |||||||
|             type: string |             type: string | ||||||
|             enum: |             enum: | ||||||
|               - info |               - info | ||||||
|  |               - extraConfiguration | ||||||
|  |               - resources | ||||||
|           required: true |           required: true | ||||||
|  |  | ||||||
|       responses: |       responses: | ||||||
|         200: |         200: | ||||||
|           description: Successfull command execution |           $ref: '#/components/schemas/SystemCommandResults' | ||||||
|           content: |         403: | ||||||
|             application/json: |           $ref: '#/components/responses/Unauthorized' | ||||||
|               schema: |         404: | ||||||
|                 oneOf: |           $ref: '#/components/responses/NotFound' | ||||||
|                   - $ref: '#/components/schemas/SystemInfoResults' |  | ||||||
|  |   /systemConfiguration: | ||||||
|  |     get: | ||||||
|  |       tags: | ||||||
|  |         - SystemConfiguration | ||||||
|  |       summary: Retrieve system configuration items | ||||||
|  |       operationId: getSystemConfiguration | ||||||
|  |       parameters: | ||||||
|  |         - in: query | ||||||
|  |           description: Which parameters you want to retrieve | ||||||
|  |           name: entries | ||||||
|  |           schema: | ||||||
|  |             type: string | ||||||
|  |             example: | ||||||
|  |               - element1 | ||||||
|  |               - element1,element2,element3 | ||||||
|  |           required: false | ||||||
|  |       responses: | ||||||
|  |         200: | ||||||
|  |           description: List of configuration elements | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 type: array | ||||||
|  |                 items: | ||||||
|  |                   $ref: '#/components/schemas/ExtraSystemConfiguration' | ||||||
|  |         403: | ||||||
|  |           $ref: '#/components/responses/Unauthorized' | ||||||
|  |         404: | ||||||
|  |           $ref: '#/components/responses/NotFound' | ||||||
|  |  | ||||||
|  |     put: | ||||||
|  |       tags: | ||||||
|  |         - SystemConfiguration | ||||||
|  |       summary: Set some or all system configuration | ||||||
|  |       operationId: setSystemConfiguration | ||||||
|  |       requestBody: | ||||||
|  |         content: | ||||||
|  |           application/json: | ||||||
|  |             schema: | ||||||
|  |               $ref: '#/components/schemas/ExtraSystemConfiguration' | ||||||
|  |  | ||||||
|  |       responses: | ||||||
|  |         200: | ||||||
|  |           $ref: '#/components/schemas/ExtraSystemConfiguration' | ||||||
|  |         403: | ||||||
|  |           $ref: '#/components/responses/Unauthorized' | ||||||
|  |         404: | ||||||
|  |           $ref: '#/components/responses/NotFound' | ||||||
|  |  | ||||||
|  |     delete: | ||||||
|  |       tags: | ||||||
|  |         - SystemConfiguration | ||||||
|  |       summary: Delete all additional system configuration | ||||||
|  |       operationId: deleteSystemConfiguration | ||||||
|  |  | ||||||
|  |       responses: | ||||||
|  |         200: | ||||||
|  |           $ref: '#/components/responses/Success' | ||||||
|         403: |         403: | ||||||
|           $ref: '#/components/responses/Unauthorized' |           $ref: '#/components/responses/Unauthorized' | ||||||
|         404: |         404: | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								overlays/curl/portfile.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | |||||||
|  | set(VCPKG_POLICY_EMPTY_PACKAGE enabled) | ||||||
							
								
								
									
										4
									
								
								overlays/curl/vcpkg.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,4 @@ | |||||||
|  | { | ||||||
|  |     "name": "curl", | ||||||
|  |     "version-string": "7.74.0-1.3+deb11u3" | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								overlays/openssl/portfile.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | |||||||
|  | set(VCPKG_POLICY_EMPTY_PACKAGE enabled) | ||||||
							
								
								
									
										4
									
								
								overlays/openssl/vcpkg.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,4 @@ | |||||||
|  | { | ||||||
|  |     "name": "openssl", | ||||||
|  |     "version-string": "1.1.1n-0+deb11u3" | ||||||
|  | } | ||||||
							
								
								
									
										1
									
								
								overlays/zlib/portfile.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1 @@ | |||||||
|  | set(VCPKG_POLICY_EMPTY_PACKAGE enabled) | ||||||
							
								
								
									
										4
									
								
								overlays/zlib/vcpkg.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,4 @@ | |||||||
|  | { | ||||||
|  |     "name": "zlib", | ||||||
|  |     "version-string": "1:1.2.11.dfsg-2+deb11u2" | ||||||
|  | } | ||||||
| @@ -43,6 +43,8 @@ firmwaredb.maxage = 90 | |||||||
| # | # | ||||||
| # Firmware Microservice Specific Section | # Firmware Microservice Specific Section | ||||||
| # | # | ||||||
|  | s3.useVirtualAdressing = true | ||||||
|  | s3.endpoint.https = true | ||||||
| s3.bucketname = ucentral-ap-firmware | s3.bucketname = ucentral-ap-firmware | ||||||
| s3.region = us-east-1 | s3.region = us-east-1 | ||||||
| s3.secret = ******************************************* | s3.secret = ******************************************* | ||||||
|   | |||||||
| @@ -38,12 +38,15 @@ openwifi.system.commandchannel = /tmp/app.ucentralfms | |||||||
| openwifi.system.uri.ui = ${SYSTEM_URI_UI} | openwifi.system.uri.ui = ${SYSTEM_URI_UI} | ||||||
| openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE} | openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE} | ||||||
|  |  | ||||||
| firmwaredb.refresh = 1800 | firmwaredb.refresh = ${FIRMWAREDB_REFRESH} | ||||||
| firmwaredb.maxage = 90 | firmwaredb.maxage = ${FIRMWAREDB_MAXAGE} | ||||||
|  |  | ||||||
| # | # | ||||||
| # Firmware Microservice Specific Section | # Firmware Microservice Specific Section | ||||||
| # | # | ||||||
|  | s3.useVirtualAdressing = ${S3_VIRTUAL_ADRESSING} | ||||||
|  | s3.endpointOverride = ${S3_ENDPOINT} | ||||||
|  | s3.endpoint.https = ${S3_HTTPS} | ||||||
| s3.bucketname = ${S3_BUCKETNAME} | s3.bucketname = ${S3_BUCKETNAME} | ||||||
| s3.region = ${S3_REGION} | s3.region = ${S3_REGION} | ||||||
| s3.secret = ${S3_SECRET} | s3.secret = ${S3_SECRET} | ||||||
|   | |||||||
| @@ -3,105 +3,127 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "AutoUpdater.h" | #include "AutoUpdater.h" | ||||||
| #include "SDK/Prov_SDK.h" |  | ||||||
| #include "SDK/GW_SDK.h" |  | ||||||
| #include "LatestFirmwareCache.h" | #include "LatestFirmwareCache.h" | ||||||
|  | #include "SDK/GW_SDK.h" | ||||||
|  | #include "SDK/Prov_SDK.h" | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
|  |  | ||||||
|  | #include "framework/MicroServiceFuncs.h" | ||||||
|  | #include "framework/utils.h" | ||||||
|  |  | ||||||
|  | #include "fmt/format.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     int AutoUpdater::Start() { | 	int AutoUpdater::Start() { | ||||||
|         poco_information(Logger(),"Starting..."); | 		poco_information(Logger(), "Starting..."); | ||||||
|         AutoUpdaterEnabled_ = MicroService::instance().ConfigGetBool("autoupdater.enabled", false); | 		AutoUpdaterEnabled_ = MicroServiceConfigGetBool("autoupdater.enabled", false); | ||||||
|         if(AutoUpdaterEnabled_) { | 		if (AutoUpdaterEnabled_) { | ||||||
|             Running_ = false; | 			Running_ = false; | ||||||
|             AutoUpdaterFrequency_ = MicroService::instance().ConfigGetInt("autoupdater.frequency",600); | 			AutoUpdaterFrequency_ = MicroServiceConfigGetInt("autoupdater.frequency", 600); | ||||||
|             AutoUpdaterCallBack_ = std::make_unique<Poco::TimerCallback<AutoUpdater>>(*this, &AutoUpdater::onTimer); | 			AutoUpdaterCallBack_ = | ||||||
|             Timer_.setStartInterval(5 * 60 * 1000);  // first run in 5 minutes | 				std::make_unique<Poco::TimerCallback<AutoUpdater>>(*this, &AutoUpdater::onTimer); | ||||||
|             Timer_.setPeriodicInterval(AutoUpdaterFrequency_ * 1000); | 			Timer_.setStartInterval(5 * 60 * 1000); // first run in 5 minutes | ||||||
|             Timer_.start(*AutoUpdaterCallBack_); | 			Timer_.setPeriodicInterval(AutoUpdaterFrequency_ * 1000); | ||||||
|         } | 			Timer_.start(*AutoUpdaterCallBack_); | ||||||
|         return 0; | 		} | ||||||
|     } | 		return 0; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     void AutoUpdater::Stop() { | 	void AutoUpdater::Stop() { | ||||||
|         poco_information(Logger(),"Stopping..."); | 		poco_information(Logger(), "Stopping..."); | ||||||
|         Running_ = false; | 		Running_ = false; | ||||||
|         if(AutoUpdaterEnabled_) { | 		if (AutoUpdaterEnabled_) { | ||||||
|             Timer_.stop(); | 			Timer_.stop(); | ||||||
|         } | 		} | ||||||
|         poco_information(Logger(),"Stopped..."); | 		poco_information(Logger(), "Stopped..."); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void AutoUpdater::ToBeUpgraded(std::string serialNumber, std::string DeviceType) { | 	void AutoUpdater::ToBeUpgraded(std::string serialNumber, std::string DeviceType) { | ||||||
|         if(!AutoUpdaterEnabled_) | 		if (!AutoUpdaterEnabled_) | ||||||
|             return; | 			return; | ||||||
|         std::lock_guard G(Mutex_); | 		std::lock_guard G(Mutex_); | ||||||
|         Queue_.emplace_back(std::make_pair(std::move(serialNumber),std::move(DeviceType))); | 		Queue_.emplace_back(std::make_pair(std::move(serialNumber), std::move(DeviceType))); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void AutoUpdater::onTimer([[maybe_unused]] Poco::Timer & timer) { | 	void AutoUpdater::onTimer([[maybe_unused]] Poco::Timer &timer) { | ||||||
|         Utils::SetThreadName("auto-updater"); | 		Utils::SetThreadName("auto-updater"); | ||||||
|         Running_ = true; | 		Running_ = true; | ||||||
|         std::unique_lock    L(Mutex_); | 		std::unique_lock L(Mutex_); | ||||||
|         while(!Queue_.empty() && Running_) { | 		while (!Queue_.empty() && Running_) { | ||||||
|             auto Entry = Queue_.front(); | 			auto Entry = Queue_.front(); | ||||||
|             Queue_.pop_front(); | 			Queue_.pop_front(); | ||||||
|             try { | 			try { | ||||||
|                 poco_debug(Logger(),fmt::format("Preparing to upgrade {}",Entry.first)); | 				poco_debug(Logger(), fmt::format("Preparing to upgrade {}", Entry.first)); | ||||||
|                 auto CacheEntry = Cache_.find(Entry.first); | 				auto CacheEntry = Cache_.find(Entry.first); | ||||||
|                 uint64_t now = OpenWifi::Now(); | 				uint64_t now = Utils::Now(); | ||||||
|                 std::string firmwareUpgrade; | 				std::string firmwareUpgrade; | ||||||
|                 if(CacheEntry == Cache_.end() || (CacheEntry->second.LastCheck-now)>300) { | 				if (CacheEntry == Cache_.end() || (CacheEntry->second.LastCheck - now) > 300) { | ||||||
|                     //  get the firmware settings for that device. | 					//  get the firmware settings for that device. | ||||||
|                     SerialCache     C; | 					SerialCache C; | ||||||
|                     C.LastCheck = now; | 					C.LastCheck = now; | ||||||
|                     bool        firmwareRCOnly; | 					bool firmwareRCOnly; | ||||||
|                     if(OpenWifi::SDK::Prov::GetFirmwareOptions(Entry.first, firmwareUpgrade, firmwareRCOnly)) { | 					if (OpenWifi::SDK::Prov::GetFirmwareOptions(Entry.first, firmwareUpgrade, | ||||||
|                         poco_debug(Logger(),fmt::format("Found firmware options for {}",Entry.first)); | 																firmwareRCOnly)) { | ||||||
|                         C.firmwareRCOnly = firmwareRCOnly; | 						poco_debug(Logger(), | ||||||
|                         C.firmwareUpgrade = firmwareUpgrade; | 								   fmt::format("Found firmware options for {}", Entry.first)); | ||||||
|                     } else { | 						C.firmwareRCOnly = firmwareRCOnly; | ||||||
|                         poco_debug(Logger(),fmt::format("Found no firmware options for {}",Entry.first)); | 						C.firmwareUpgrade = firmwareUpgrade; | ||||||
|                         C.firmwareRCOnly = firmwareRCOnly; | 					} else { | ||||||
|                         C.firmwareUpgrade = firmwareUpgrade; | 						poco_debug(Logger(), | ||||||
|                     } | 								   fmt::format("Found no firmware options for {}", Entry.first)); | ||||||
|                     Cache_[Entry.first] = C; | 						C.firmwareRCOnly = firmwareRCOnly; | ||||||
|                 } else { | 						C.firmwareUpgrade = firmwareUpgrade; | ||||||
|  | 					} | ||||||
|  | 					Cache_[Entry.first] = C; | ||||||
|  | 				} else { | ||||||
|  | 				} | ||||||
|  |  | ||||||
|                 } | 				if (firmwareUpgrade == "no") { | ||||||
|  | 					poco_information( | ||||||
|  | 						Logger(), | ||||||
|  | 						fmt::format("Device {} not upgradable. Provisioning service settings.", | ||||||
|  | 									Entry.first)); | ||||||
|  | 					continue; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|                 if(firmwareUpgrade=="no") { | 				LatestFirmwareCacheEntry fwEntry; | ||||||
|                     poco_information(Logger(),fmt::format("Device {} not upgradable. Provisioning service settings.",Entry.first)); | 				FMSObjects::Firmware fwDetails; | ||||||
|                     continue; | 				auto LF = LatestFirmwareCache()->FindLatestFirmware(Entry.second, fwEntry); | ||||||
|                 } | 				if (LF) { | ||||||
|  | 					if (StorageService()->FirmwaresDB().GetFirmware(fwEntry.Id, fwDetails)) { | ||||||
|  | 						//  send the command to upgrade this device... | ||||||
|  | 						poco_information(Logger(), fmt::format("Upgrading {} to version {}", | ||||||
|  | 															   Entry.first, fwEntry.Revision)); | ||||||
|  | 						if (OpenWifi::SDK::GW::SendFirmwareUpgradeCommand(Entry.first, | ||||||
|  | 																		  fwDetails.uri)) { | ||||||
|  | 							poco_information( | ||||||
|  | 								Logger(), fmt::format("Upgrade command sent for {}", Entry.first)); | ||||||
|  | 						} else { | ||||||
|  | 							poco_information( | ||||||
|  | 								Logger(), | ||||||
|  | 								fmt::format("Upgrade command not sent for {}", Entry.first)); | ||||||
|  | 						} | ||||||
|  | 					} else { | ||||||
|  | 						poco_information(Logger(), | ||||||
|  | 										 fmt::format("Firmware for device {} ({}) cannot be found.", | ||||||
|  | 													 Entry.first, Entry.second)); | ||||||
|  | 					} | ||||||
|  | 				} else { | ||||||
|  | 					poco_information(Logger(), | ||||||
|  | 									 fmt::format("Firmware for device {} ({}) cannot be found.", | ||||||
|  | 												 Entry.first, Entry.second)); | ||||||
|  | 				} | ||||||
|  | 			} catch (...) { | ||||||
|  | 				poco_information( | ||||||
|  | 					Logger(), | ||||||
|  | 					fmt::format("Exception during auto update for device {}.", Entry.first)); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|                 LatestFirmwareCacheEntry    fwEntry; | 	void AutoUpdater::reinitialize([[maybe_unused]] Poco::Util::Application &self) { | ||||||
|                 FMSObjects::Firmware        fwDetails; | 		poco_information(Logger(), "Reinitializing."); | ||||||
|                 auto LF = LatestFirmwareCache()->FindLatestFirmware(Entry.second, fwEntry ); | 		Reset(); | ||||||
|                 if(LF) { | 	} | ||||||
|                     if(StorageService()->FirmwaresDB().GetFirmware(fwEntry.Id,fwDetails)) { | } // namespace OpenWifi | ||||||
|                         //  send the command to upgrade this device... |  | ||||||
|                         poco_information(Logger(),fmt::format("Upgrading {} to version {}", Entry.first, fwEntry.Revision)); |  | ||||||
|                         if(OpenWifi::SDK::GW::SendFirmwareUpgradeCommand(Entry.first,fwDetails.uri)) { |  | ||||||
|                             poco_information(Logger(),fmt::format("Upgrade command sent for {}",Entry.first)); |  | ||||||
|                         } else { |  | ||||||
|                             poco_information(Logger(),fmt::format("Upgrade command not sent for {}",Entry.first)); |  | ||||||
|                         } |  | ||||||
|                     } else { |  | ||||||
|                         poco_information(Logger(),fmt::format("Firmware for device {} ({}) cannot be found.", Entry.first, Entry.second )); |  | ||||||
|                     } |  | ||||||
|                 } else { |  | ||||||
|                     poco_information(Logger(),fmt::format("Firmware for device {} ({}) cannot be found.", Entry.first, Entry.second )); |  | ||||||
|                 } |  | ||||||
|             } catch (...) { |  | ||||||
|                 poco_information(Logger(),fmt::format("Exception during auto update for device {}.", Entry.first )); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void AutoUpdater::reinitialize([[maybe_unused]] Poco::Util::Application &self) { |  | ||||||
|         poco_information(Logger(),"Reinitializing."); |  | ||||||
|         Reset(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -2,57 +2,52 @@ | |||||||
| // Created by stephane bourque on 2021-10-04. | // Created by stephane bourque on 2021-10-04. | ||||||
| // | // | ||||||
|  |  | ||||||
| #ifndef OWFMS_AUTOUPDATER_H | #pragma once | ||||||
| #define OWFMS_AUTOUPDATER_H |  | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" |  | ||||||
| #include <deque> | #include <deque> | ||||||
| #include "Poco/Util/Application.h" |  | ||||||
| #include "Poco/Timer.h" | #include "Poco/Timer.h" | ||||||
|  | #include "Poco/Util/Application.h" | ||||||
|  | #include "framework/SubSystemServer.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     class AutoUpdater : public SubSystemServer { // };, Poco::Runnable { | 	class AutoUpdater : public SubSystemServer { // };, Poco::Runnable { | ||||||
|     public: | 	  public: | ||||||
|  | 		struct SerialCache { | ||||||
|  | 			uint64_t LastCheck = 0; | ||||||
|  | 			std::string firmwareUpgrade; | ||||||
|  | 			bool firmwareRCOnly = false; | ||||||
|  | 		}; | ||||||
|  |  | ||||||
|     struct SerialCache { | 		static auto instance() { | ||||||
|             uint64_t        LastCheck=0; | 			static auto instance_ = new AutoUpdater; | ||||||
|             std::string     firmwareUpgrade; | 			return instance_; | ||||||
|             bool            firmwareRCOnly=false; | 		} | ||||||
|         }; |  | ||||||
|  |  | ||||||
|         static auto instance() { | 		int Start() override; | ||||||
|             static auto instance_ = new AutoUpdater; | 		void Stop() override; | ||||||
|             return instance_; | 		void ToBeUpgraded(std::string serialNumber, std::string DeviceType); | ||||||
|         } | 		inline void Reset() { | ||||||
|  | 			std::lock_guard G(Mutex_); | ||||||
|  | 			Cache_.clear(); | ||||||
|  | 			Queue_.clear(); | ||||||
|  | 		} | ||||||
|  | 		void reinitialize(Poco::Util::Application &self) final; | ||||||
|  | 		void onTimer(Poco::Timer &timer); | ||||||
|  |  | ||||||
|         int Start() override; | 	  private: | ||||||
|         void Stop() override; | 		std::atomic_bool Running_ = false; | ||||||
|         void ToBeUpgraded(std::string serialNumber, std::string DeviceType); | 		std::map<std::string, SerialCache> Cache_; | ||||||
|         inline void Reset() { | 		std::deque<std::pair<std::string, std::string>> Queue_; | ||||||
|             std::lock_guard   G(Mutex_); | 		uint64_t AutoUpdaterFrequency_ = 600; | ||||||
|             Cache_.clear(); | 		bool AutoUpdaterEnabled_ = true; | ||||||
|             Queue_.clear(); | 		Poco::Timer Timer_; | ||||||
|         } | 		std::unique_ptr<Poco::TimerCallback<AutoUpdater>> AutoUpdaterCallBack_; | ||||||
|         void reinitialize(Poco::Util::Application &self) final; |  | ||||||
|         void onTimer(Poco::Timer & timer); |  | ||||||
|  |  | ||||||
|     private: | 		explicit AutoUpdater() noexcept | ||||||
|         std::atomic_bool                                    Running_=false; | 			: SubSystemServer("AutoUpdater", "AUTO-UPDATER", "autoupdater") {} | ||||||
|         std::map<std::string,SerialCache>                   Cache_; | 	}; | ||||||
|         std::deque<std::pair<std::string,std::string>>      Queue_; |  | ||||||
|         uint64_t                                            AutoUpdaterFrequency_=600; |  | ||||||
|         bool                                                AutoUpdaterEnabled_=true; |  | ||||||
|         Poco::Timer                                         Timer_; |  | ||||||
|         std::unique_ptr<Poco::TimerCallback<AutoUpdater>>   AutoUpdaterCallBack_; |  | ||||||
|  |  | ||||||
|         explicit AutoUpdater() noexcept: | 	inline auto AutoUpdater() { return AutoUpdater::instance(); } | ||||||
|         SubSystemServer("AutoUpdater", "AUTO-UPDATER", "autoupdater") | } // namespace OpenWifi | ||||||
|             { |  | ||||||
|             } |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     inline auto AutoUpdater() { return AutoUpdater::instance(); } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #endif //OWFMS_AUTOUPDATER_H |  | ||||||
|   | |||||||
| @@ -3,65 +3,62 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include <aws/core/Aws.h> | #include <aws/core/Aws.h> | ||||||
| #include <aws/s3/model/CreateBucketRequest.h> |  | ||||||
| #include <aws/s3/model/PutObjectRequest.h> |  | ||||||
| #include <aws/s3/model/AccessControlPolicy.h> | #include <aws/s3/model/AccessControlPolicy.h> | ||||||
| #include <aws/s3/model/PutBucketAclRequest.h> | #include <aws/s3/model/CreateBucketRequest.h> | ||||||
| #include <aws/s3/model/GetBucketAclRequest.h> | #include <aws/s3/model/GetBucketAclRequest.h> | ||||||
|  | #include <aws/s3/model/PutBucketAclRequest.h> | ||||||
|  | #include <aws/s3/model/PutObjectRequest.h> | ||||||
|  |  | ||||||
|  | #include "AutoUpdater.h" | ||||||
| #include "Daemon.h" | #include "Daemon.h" | ||||||
| #include "StorageService.h" |  | ||||||
| #include "ManifestCreator.h" |  | ||||||
| #include "NewConnectionHandler.h" |  | ||||||
| #include "LatestFirmwareCache.h" |  | ||||||
| #include "DeviceCache.h" | #include "DeviceCache.h" | ||||||
| #include "FirmwareCache.h" | #include "FirmwareCache.h" | ||||||
| #include "AutoUpdater.h" | #include "LatestFirmwareCache.h" | ||||||
|  | #include "ManifestCreator.h" | ||||||
| #include "NewCommandHandler.h" | #include "NewCommandHandler.h" | ||||||
|  | #include "NewConnectionHandler.h" | ||||||
|  | #include "StorageService.h" | ||||||
|  |  | ||||||
|  | #include "framework/UI_WebSocketClientServer.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class Daemon *Daemon::instance_ = nullptr; | 	class Daemon *Daemon::instance_ = nullptr; | ||||||
|  |  | ||||||
|     class Daemon *Daemon::instance() { | 	class Daemon *Daemon::instance() { | ||||||
|         if (instance_ == nullptr) { | 		if (instance_ == nullptr) { | ||||||
|             instance_ = new Daemon(vDAEMON_PROPERTIES_FILENAME, | 			instance_ = new Daemon( | ||||||
|                                    vDAEMON_ROOT_ENV_VAR, | 				vDAEMON_PROPERTIES_FILENAME, vDAEMON_ROOT_ENV_VAR, vDAEMON_CONFIG_ENV_VAR, | ||||||
|                                    vDAEMON_CONFIG_ENV_VAR, | 				vDAEMON_APP_NAME, vDAEMON_BUS_TIMER, | ||||||
|                                    vDAEMON_APP_NAME, | 				SubSystemVec{StorageService(), FirmwareCache(), LatestFirmwareCache(), | ||||||
|                                    vDAEMON_BUS_TIMER, | 							 DeviceCache(), NewConnectionHandler(), ManifestCreator(), | ||||||
|                                    SubSystemVec{ | 							 AutoUpdater(), NewCommandHandler(), UI_WebSocketClientServer()}); | ||||||
|                                             StorageService(), | 		} | ||||||
|                                             FirmwareCache(), | 		return instance_; | ||||||
|                                             LatestFirmwareCache(), | 	} | ||||||
|                                             DeviceCache(), |  | ||||||
|                                             NewConnectionHandler(), |  | ||||||
|                                             ManifestCreator(), |  | ||||||
|                                             AutoUpdater(), |  | ||||||
|                                             NewCommandHandler() |  | ||||||
|                                    }); |  | ||||||
|         } |  | ||||||
|         return instance_; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) { | 	void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) {} | ||||||
|     } |  | ||||||
| } | 	void DaemonPostInitialization(Poco::Util::Application &self) { | ||||||
|  | 		Daemon()->PostInitialization(self); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | } // namespace OpenWifi | ||||||
|  |  | ||||||
| int main(int argc, char **argv) { | int main(int argc, char **argv) { | ||||||
|     SSL_library_init(); | 	SSL_library_init(); | ||||||
|     Aws::SDKOptions AwsOptions; | 	Aws::SDKOptions AwsOptions; | ||||||
|     AwsOptions.memoryManagementOptions.memoryManager = nullptr; | 	AwsOptions.memoryManagementOptions.memoryManager = nullptr; | ||||||
|     AwsOptions.cryptoOptions.initAndCleanupOpenSSL = false; | 	AwsOptions.cryptoOptions.initAndCleanupOpenSSL = false; | ||||||
|     AwsOptions.httpOptions.initAndCleanupCurl = true; | 	AwsOptions.httpOptions.initAndCleanupCurl = true; | ||||||
|  |  | ||||||
|     Aws::InitAPI(AwsOptions); | 	Aws::InitAPI(AwsOptions); | ||||||
|  |  | ||||||
|     int ExitCode=0; | 	int ExitCode = 0; | ||||||
|     { | 	{ | ||||||
|         auto App = OpenWifi::Daemon::instance(); | 		auto App = OpenWifi::Daemon::instance(); | ||||||
|         ExitCode = App->run(argc, argv); | 		ExitCode = App->run(argc, argv); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     ShutdownAPI(AwsOptions); | 	ShutdownAPI(AwsOptions); | ||||||
|     return ExitCode; | 	return ExitCode; | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										54
									
								
								src/Daemon.h
									
									
									
									
									
								
							
							
						
						| @@ -6,43 +6,37 @@ | |||||||
| #define UCENTRALFWS_DAEMON_H | #define UCENTRALFWS_DAEMON_H | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" | #include "framework/MicroService.h" | ||||||
|  | #include "framework/MicroServiceNames.h" | ||||||
| #include "framework/OpenWifiTypes.h" | #include "framework/OpenWifiTypes.h" | ||||||
| #include "RESTObjects/RESTAPI_FMSObjects.h" |  | ||||||
| #include "Dashboard.h" | #include "Dashboard.h" | ||||||
|  | #include "RESTObjects/RESTAPI_FMSObjects.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     [[maybe_unused]] static const char * vDAEMON_PROPERTIES_FILENAME = "owfms.properties"; | 	[[maybe_unused]] static const char *vDAEMON_PROPERTIES_FILENAME = "owfms.properties"; | ||||||
|     [[maybe_unused]] static const char * vDAEMON_ROOT_ENV_VAR = "OWFMS_ROOT"; | 	[[maybe_unused]] static const char *vDAEMON_ROOT_ENV_VAR = "OWFMS_ROOT"; | ||||||
|     [[maybe_unused]] static const char * vDAEMON_CONFIG_ENV_VAR = "OWFMS_CONFIG"; | 	[[maybe_unused]] static const char *vDAEMON_CONFIG_ENV_VAR = "OWFMS_CONFIG"; | ||||||
|     [[maybe_unused]] static const char * vDAEMON_APP_NAME = uSERVICE_FIRMWARE.c_str(); | 	[[maybe_unused]] static const char *vDAEMON_APP_NAME = uSERVICE_FIRMWARE.c_str(); | ||||||
|     [[maybe_unused]] static const uint64_t vDAEMON_BUS_TIMER = 10000; | 	[[maybe_unused]] static const uint64_t vDAEMON_BUS_TIMER = 10000; | ||||||
|  |  | ||||||
|     class Daemon : public MicroService { | 	class Daemon : public MicroService { | ||||||
|     public: | 	  public: | ||||||
|         explicit Daemon(const std::string & PropFile, | 		explicit Daemon(const std::string &PropFile, const std::string &RootEnv, | ||||||
|                         const std::string & RootEnv, | 						const std::string &ConfigEnv, const std::string &AppName, uint64_t BusTimer, | ||||||
|                         const std::string & ConfigEnv, | 						const SubSystemVec &SubSystems) | ||||||
|                         const std::string & AppName, | 			: MicroService(PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems){}; | ||||||
|                         uint64_t 	BusTimer, |  | ||||||
|                         const SubSystemVec & SubSystems) : |  | ||||||
|                 MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {}; |  | ||||||
|  |  | ||||||
|         void PostInitialization(Poco::Util::Application &self); | 		void PostInitialization(Poco::Util::Application &self); | ||||||
|         static Daemon *instance(); | 		static Daemon *instance(); | ||||||
|         inline void ResetDashboard() { DB_.Reset(); } | 		inline DeviceDashboard &GetDashboard() { return DB_; } | ||||||
|         inline void CreateDashboard() { DB_.Create(); } |  | ||||||
|         inline const FMSObjects::DeviceReport & GetDashboard() { return DB_.Report(); } |  | ||||||
|  |  | ||||||
|     private: | 	  private: | ||||||
|         static Daemon 				*instance_; | 		static Daemon *instance_; | ||||||
|         DeviceDashboard             DB_; | 		DeviceDashboard DB_; | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     inline Daemon * Daemon() { return Daemon::instance(); } | 	inline Daemon *Daemon() { return Daemon::instance(); } | ||||||
|     inline void DaemonPostInitialization(Poco::Util::Application &self) { | } // namespace OpenWifi | ||||||
|         Daemon()->PostInitialization(self); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #endif //UCENTRALFWS_DAEMON_H | #endif // UCENTRALFWS_DAEMON_H | ||||||
|   | |||||||
| @@ -4,15 +4,47 @@ | |||||||
|  |  | ||||||
| #include "Dashboard.h" | #include "Dashboard.h" | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
|  | #include "framework/utils.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
| 	void DeviceDashboard::Create() { |  | ||||||
| 		uint64_t Now = OpenWifi::Now(); |  | ||||||
|  |  | ||||||
| 		if(LastRun_==0 || (Now-LastRun_)>120) { | 	bool DeviceDashboard::Get(FMSObjects::DeviceReport &D, Poco::Logger &Logger) { | ||||||
| 			DB_.reset(); | 		uint64_t Now = Utils::Now(); | ||||||
| 			StorageService()->DevicesDB().GenerateDeviceReport(DB_); | 		if (!ValidDashboard_ || LastRun_ == 0 || (Now - LastRun_) > 120) { | ||||||
| 			LastRun_ = Now; | 			Generate(D, Logger); | ||||||
|  | 		} else { | ||||||
|  | 			std::lock_guard G(DataMutex_); | ||||||
|  | 			D = DB_; | ||||||
|  | 		} | ||||||
|  | 		return ValidDashboard_; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	void DeviceDashboard::Generate(FMSObjects::DeviceReport &D, Poco::Logger &Logger) { | ||||||
|  | 		if (GeneratingDashboard_.load()) { | ||||||
|  | 			// std::cout << "Trying to generate dashboard but already being generated" << std::endl; | ||||||
|  | 			while (GeneratingDashboard_.load()) { | ||||||
|  | 				Poco::Thread::trySleep(100); | ||||||
|  | 			} | ||||||
|  | 			std::lock_guard G(DataMutex_); | ||||||
|  | 			D = DB_; | ||||||
|  | 		} else { | ||||||
|  | 			GeneratingDashboard_ = true; | ||||||
|  | 			ValidDashboard_ = false; | ||||||
|  | 			try { | ||||||
|  | 				// std::cout << "Generating dashboard." << std::endl; | ||||||
|  | 				poco_information(Logger, "DASHBOARD: Generating a new dashboard."); | ||||||
|  | 				FMSObjects::DeviceReport NewData; | ||||||
|  | 				StorageService()->DevicesDB().GenerateDeviceReport(NewData); | ||||||
|  | 				LastRun_ = Utils::Now(); | ||||||
|  | 				NewData.snapshot = LastRun_; | ||||||
|  | 				D = NewData; | ||||||
|  | 				std::lock_guard G(DataMutex_); | ||||||
|  | 				DB_ = NewData; | ||||||
|  | 				ValidDashboard_ = true; | ||||||
|  | 			} catch (...) { | ||||||
|  | 			} | ||||||
|  | 			GeneratingDashboard_ = false; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| } |  | ||||||
|  | } // namespace OpenWifi | ||||||
|   | |||||||
| @@ -2,22 +2,26 @@ | |||||||
| // Created by stephane bourque on 2021-07-21. | // Created by stephane bourque on 2021-07-21. | ||||||
| // | // | ||||||
|  |  | ||||||
| #ifndef UCENTRALGW_DASHBOARD_H | #pragma once | ||||||
| #define UCENTRALGW_DASHBOARD_H |  | ||||||
|  |  | ||||||
| #include "framework/OpenWifiTypes.h" | #include <mutex> | ||||||
|  |  | ||||||
|  | #include "Poco/Logger.h" | ||||||
| #include "RESTObjects/RESTAPI_FMSObjects.h" | #include "RESTObjects/RESTAPI_FMSObjects.h" | ||||||
|  | #include "framework/OpenWifiTypes.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
| 	class DeviceDashboard { | 	class DeviceDashboard { | ||||||
| 	  public: | 	  public: | ||||||
| 			void Create(); | 		bool Get(FMSObjects::DeviceReport &D, Poco::Logger &Logger); | ||||||
| 			const FMSObjects::DeviceReport & Report() const { return DB_;} |  | ||||||
| 			inline void Reset() { LastRun_=0; DB_.reset(); } |  | ||||||
| 	  private: |  | ||||||
|             FMSObjects::DeviceReport  	DB_; |  | ||||||
| 			uint64_t 				LastRun_=0; |  | ||||||
| 	}; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #endif // UCENTRALGW_DASHBOARD_H | 	  private: | ||||||
|  | 		std::mutex DataMutex_; | ||||||
|  | 		volatile std::atomic_bool GeneratingDashboard_ = false; | ||||||
|  | 		volatile bool ValidDashboard_ = false; | ||||||
|  | 		FMSObjects::DeviceReport DB_; | ||||||
|  | 		uint64_t LastRun_ = 0; | ||||||
|  |  | ||||||
|  | 		void Generate(FMSObjects::DeviceReport &D, Poco::Logger &Logger); | ||||||
|  | 	}; | ||||||
|  | } // namespace OpenWifi | ||||||
|   | |||||||
| @@ -6,45 +6,39 @@ | |||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     int DeviceCache::Start() { | 	int DeviceCache::Start() { | ||||||
|         poco_information(Logger(),"Starting..."); | 		poco_information(Logger(), "Starting..."); | ||||||
|         return 0; | 		return 0; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void DeviceCache::Stop() { | 	void DeviceCache::Stop() { | ||||||
|         poco_information(Logger(),"Stopping..."); | 		poco_information(Logger(), "Stopping..."); | ||||||
|         poco_information(Logger(),"Stopped..."); | 		poco_information(Logger(), "Stopped..."); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void DeviceCache::AddToCache( | 	void DeviceCache::AddToCache(const std::string &SerialNumber, const std::string &DeviceType, | ||||||
|                         const std::string &SerialNumber, const std::string & DeviceType, | 								 const std::string &Host, const std::string &Revision) { | ||||||
|                         const std::string &Host, const std::string &Revision) { | 		std::lock_guard G(Mutex_); | ||||||
|         std::lock_guard G(Mutex_); | 		auto Device = DeviceCache_.find(SerialNumber); | ||||||
|         auto Device = DeviceCache_.find(SerialNumber); |  | ||||||
|  |  | ||||||
|         if(Device==DeviceCache_.end()) { | 		if (Device == DeviceCache_.end()) { | ||||||
|             DeviceCache_[SerialNumber]=DeviceCacheEntry{ | 			DeviceCache_[SerialNumber] = | ||||||
|                                                 .deviceType=DeviceType, | 				DeviceCacheEntry{.deviceType = DeviceType, .host = Host, .revision = Revision}; | ||||||
|                                                 .host=Host, | 		} else { | ||||||
|                                                 .revision=Revision}; | 			Device->second.revision = Revision; | ||||||
|         } else { | 			Device->second.host = Host; | ||||||
|             Device->second.revision=Revision; | 			Device->second.deviceType = DeviceType; | ||||||
|             Device->second.host=Host; | 		} | ||||||
|             Device->second.deviceType=DeviceType; | 	} | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool DeviceCache::GetDevice(const std::string &SerialNumber, DeviceCacheEntry & E) { | 	bool DeviceCache::GetDevice(const std::string &SerialNumber, DeviceCacheEntry &E) { | ||||||
|         std::lock_guard G(Mutex_); | 		std::lock_guard G(Mutex_); | ||||||
|         auto Device = DeviceCache_.find(SerialNumber); | 		auto Device = DeviceCache_.find(SerialNumber); | ||||||
|         if(Device==DeviceCache_.end()) | 		if (Device == DeviceCache_.end()) | ||||||
|             return false; | 			return false; | ||||||
|         E=Device->second; | 		E = Device->second; | ||||||
|         return true; | 		return true; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|  | 	void DeviceCache::DumpCache() {} | ||||||
|     void DeviceCache::DumpCache() { | } // namespace OpenWifi | ||||||
|  |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -2,47 +2,40 @@ | |||||||
| // Created by stephane bourque on 2021-07-13. | // Created by stephane bourque on 2021-07-13. | ||||||
| // | // | ||||||
|  |  | ||||||
| #ifndef UCENTRALFMS_DEVICECACHE_H | #pragma once | ||||||
| #define UCENTRALFMS_DEVICECACHE_H |  | ||||||
|  |  | ||||||
|  | #include "framework/SubSystemServer.h" | ||||||
| #include <string> | #include <string> | ||||||
| #include "framework/MicroService.h" |  | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     struct DeviceCacheEntry { | 	struct DeviceCacheEntry { | ||||||
|         std::string     deviceType; | 		std::string deviceType; | ||||||
|         std::string     host; | 		std::string host; | ||||||
|         std::string     revision; | 		std::string revision; | ||||||
|     }; | 	}; | ||||||
|     typedef std::map<std::string, DeviceCacheEntry> DeviceCacheMap; | 	typedef std::map<std::string, DeviceCacheEntry> DeviceCacheMap; | ||||||
|  |  | ||||||
|     class DeviceCache : public SubSystemServer { | 	class DeviceCache : public SubSystemServer { | ||||||
|     public: | 	  public: | ||||||
|         static auto instance() { | 		static auto instance() { | ||||||
|             static auto instance_ = new DeviceCache; | 			static auto instance_ = new DeviceCache; | ||||||
|             return instance_; | 			return instance_; | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         int Start() override; | 		int Start() override; | ||||||
|         void Stop() override; | 		void Stop() override; | ||||||
|         void AddToCache(const std::string &serialNumber, const std::string & DeviceType, | 		void AddToCache(const std::string &serialNumber, const std::string &DeviceType, | ||||||
|                         const std::string &Host, const std::string &Revision); | 						const std::string &Host, const std::string &Revision); | ||||||
|         void DumpCache(); | 		void DumpCache(); | ||||||
|         bool GetDevice(const std::string &SerialNumber, DeviceCacheEntry & E); | 		bool GetDevice(const std::string &SerialNumber, DeviceCacheEntry &E); | ||||||
|  |  | ||||||
|     private: | 	  private: | ||||||
|         std::atomic_bool    Running_=false; | 		std::atomic_bool Running_ = false; | ||||||
|         DeviceCacheMap      DeviceCache_; | 		DeviceCacheMap DeviceCache_; | ||||||
|         explicit DeviceCache() noexcept: | 		explicit DeviceCache() noexcept | ||||||
|                 SubSystemServer("DeviceCache", "DEVICE-CACHE", "devicecache") | 			: SubSystemServer("DeviceCache", "DEVICE-CACHE", "devicecache") {} | ||||||
|         { | 	}; | ||||||
|         } |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     inline auto DeviceCache() { return DeviceCache::instance(); } | 	inline auto DeviceCache() { return DeviceCache::instance(); } | ||||||
| } | } // namespace OpenWifi | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #endif //UCENTRALFMS_DEVICECACHE_H |  | ||||||
|   | |||||||
| @@ -6,22 +6,25 @@ | |||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     int FirmwareCache::Start() { | 	int FirmwareCache::Start() { | ||||||
|         poco_information(Logger(),"Starting..."); | 		poco_information(Logger(), "Starting..."); | ||||||
|         return 0; | 		return 0; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void FirmwareCache::Stop() { | 	void FirmwareCache::Stop() { | ||||||
|         poco_information(Logger(),"Stopping..."); | 		poco_information(Logger(), "Stopping..."); | ||||||
|         poco_information(Logger(),"Stopped..."); | 		poco_information(Logger(), "Stopped..."); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     std::shared_ptr<FMSObjects::Firmware> GetFirmware([[maybe_unused]] const std::string & DeviceType, [[maybe_unused]] const std::string & Revision) { | 	std::shared_ptr<FMSObjects::Firmware> | ||||||
|         return nullptr; | 	GetFirmware([[maybe_unused]] const std::string &DeviceType, | ||||||
|     } | 				[[maybe_unused]] const std::string &Revision) { | ||||||
|  | 		return nullptr; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     std::shared_ptr<FMSObjects::Firmware> AddFirmware([[maybe_unused]] const FMSObjects::Firmware &F) { | 	std::shared_ptr<FMSObjects::Firmware> | ||||||
|         return nullptr; | 	AddFirmware([[maybe_unused]] const FMSObjects::Firmware &F) { | ||||||
|     } | 		return nullptr; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| } | } // namespace OpenWifi | ||||||
|   | |||||||
| @@ -2,44 +2,39 @@ | |||||||
| // Created by stephane bourque on 2021-07-26. | // Created by stephane bourque on 2021-07-26. | ||||||
| // | // | ||||||
|  |  | ||||||
| #ifndef UCENTRALFMS_FIRMWARECACHE_H | #pragma once | ||||||
| #define UCENTRALFMS_FIRMWARECACHE_H |  | ||||||
|  |  | ||||||
| #include <map> | #include <map> | ||||||
| #include <memory> | #include <memory> | ||||||
|  |  | ||||||
| #include "RESTObjects/RESTAPI_FMSObjects.h" | #include "RESTObjects/RESTAPI_FMSObjects.h" | ||||||
| #include "framework/MicroService.h" | #include "framework/SubSystemServer.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     typedef std::map<std::string,std::shared_ptr<FMSObjects::Firmware>> FirmwareCacheMap; | 	typedef std::map<std::string, std::shared_ptr<FMSObjects::Firmware>> FirmwareCacheMap; | ||||||
|  |  | ||||||
|     class FirmwareCache: public SubSystemServer { | 	class FirmwareCache : public SubSystemServer { | ||||||
|     public: | 	  public: | ||||||
|         static auto instance() { | 		static auto instance() { | ||||||
|             static auto instance_= new FirmwareCache; | 			static auto instance_ = new FirmwareCache; | ||||||
|             return instance_; | 			return instance_; | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         int Start() override; | 		int Start() override; | ||||||
|         void Stop() override; | 		void Stop() override; | ||||||
|  |  | ||||||
|         std::shared_ptr<FMSObjects::Firmware> GetFirmware(const std::string & DeviceType, const std::string & Revision); | 		std::shared_ptr<FMSObjects::Firmware> GetFirmware(const std::string &DeviceType, | ||||||
|         std::shared_ptr<FMSObjects::Firmware> AddFirmware(const FMSObjects::Firmware &F); | 														  const std::string &Revision); | ||||||
|  | 		std::shared_ptr<FMSObjects::Firmware> AddFirmware(const FMSObjects::Firmware &F); | ||||||
|  |  | ||||||
|     private: | 	  private: | ||||||
|         std::atomic_bool        Running_=false; | 		std::atomic_bool Running_ = false; | ||||||
|         FirmwareCacheMap        Cache_; | 		FirmwareCacheMap Cache_; | ||||||
|         explicit FirmwareCache() noexcept: | 		explicit FirmwareCache() noexcept | ||||||
|                 SubSystemServer("FirmwareCache", "FIRMWARE-CACHE", "firmwarecache") | 			: SubSystemServer("FirmwareCache", "FIRMWARE-CACHE", "firmwarecache") {} | ||||||
|         { | 	}; | ||||||
|         } |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     inline auto FirmwareCache() { return FirmwareCache::instance(); } | 	inline auto FirmwareCache() { return FirmwareCache::instance(); } | ||||||
|  |  | ||||||
| } | } // namespace OpenWifi | ||||||
|  |  | ||||||
|  |  | ||||||
| #endif //UCENTRALFMS_FIRMWARECACHE_H |  | ||||||
|   | |||||||
| @@ -7,94 +7,91 @@ | |||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     int LatestFirmwareCache::Start() { | 	int LatestFirmwareCache::Start() { | ||||||
|         poco_information(Logger(),"Starting..."); | 		poco_information(Logger(), "Starting..."); | ||||||
|         StorageService()->FirmwaresDB().PopulateLatestFirmwareCache(); | 		StorageService()->FirmwaresDB().PopulateLatestFirmwareCache(); | ||||||
|         return 0; | 		return 0; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void LatestFirmwareCache::Stop() { | 	void LatestFirmwareCache::Stop() { | ||||||
|         poco_information(Logger(),"Stopping..."); | 		poco_information(Logger(), "Stopping..."); | ||||||
|         poco_information(Logger(),"Stopped..."); | 		poco_information(Logger(), "Stopped..."); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     bool LatestFirmwareCache::AddToCache(const std::string & DeviceType, const std::string &Revision, const std::string &Id, uint64_t TimeStamp) { | 	bool LatestFirmwareCache::AddToCache(const std::string &DeviceType, const std::string &Revision, | ||||||
|         std::lock_guard G(Mutex_); | 										 const std::string &Id, uint64_t TimeStamp) { | ||||||
|  | 		std::lock_guard G(Mutex_); | ||||||
|  |  | ||||||
|         RevisionSet_.insert(Revision); | 		RevisionSet_.insert(Revision); | ||||||
|         DeviceSet_.insert(DeviceType); | 		DeviceSet_.insert(DeviceType); | ||||||
|  |  | ||||||
|         auto E = Cache_.find(DeviceType); | 		auto E = Cache_.find(DeviceType); | ||||||
|         if((E==Cache_.end()) || (TimeStamp >= E->second.TimeStamp)) { | 		if ((E == Cache_.end()) || (TimeStamp >= E->second.TimeStamp)) { | ||||||
|             Cache_[DeviceType] = LatestFirmwareCacheEntry{ | 			Cache_[DeviceType] = | ||||||
|                 .Id=Id, | 				LatestFirmwareCacheEntry{.Id = Id, .TimeStamp = TimeStamp, .Revision = Revision}; | ||||||
|                 .TimeStamp=TimeStamp, | 		} | ||||||
|                 .Revision=Revision}; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if(!IsRC(Revision)) | 		if (!IsRC(Revision)) | ||||||
|             return true; | 			return true; | ||||||
|  |  | ||||||
|         auto rcE = rcCache_.find(DeviceType); | 		auto rcE = rcCache_.find(DeviceType); | ||||||
|         if((rcE==rcCache_.end()) || (TimeStamp >= rcE->second.TimeStamp)) { | 		if ((rcE == rcCache_.end()) || (TimeStamp >= rcE->second.TimeStamp)) { | ||||||
|             rcCache_[DeviceType] = LatestFirmwareCacheEntry{ | 			rcCache_[DeviceType] = | ||||||
|                 .Id=Id, | 				LatestFirmwareCacheEntry{.Id = Id, .TimeStamp = TimeStamp, .Revision = Revision}; | ||||||
|                 .TimeStamp=TimeStamp, | 		} | ||||||
|                 .Revision=Revision}; | 		return true; | ||||||
|         } | 	} | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool LatestFirmwareCache::FindLatestFirmware(const std::string &DeviceType, LatestFirmwareCacheEntry &Entry )  { | 	bool LatestFirmwareCache::FindLatestFirmware(const std::string &DeviceType, | ||||||
|         std::lock_guard G(Mutex_); | 												 LatestFirmwareCacheEntry &Entry) { | ||||||
|  | 		std::lock_guard G(Mutex_); | ||||||
|  |  | ||||||
|         auto E=Cache_.find(DeviceType); | 		auto E = Cache_.find(DeviceType); | ||||||
|         if(E!=Cache_.end()) { | 		if (E != Cache_.end()) { | ||||||
|             Entry = E->second; | 			Entry = E->second; | ||||||
|             return true; | 			return true; | ||||||
|         } | 		} | ||||||
|         return false; | 		return false; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     bool LatestFirmwareCache::FindLatestRCOnlyFirmware(const std::string &DeviceType, LatestFirmwareCacheEntry &Entry ) { | 	bool LatestFirmwareCache::FindLatestRCOnlyFirmware(const std::string &DeviceType, | ||||||
|         std::lock_guard G(Mutex_); | 													   LatestFirmwareCacheEntry &Entry) { | ||||||
|  | 		std::lock_guard G(Mutex_); | ||||||
|  |  | ||||||
|         auto E=rcCache_.find(DeviceType); | 		auto E = rcCache_.find(DeviceType); | ||||||
|         if(E!=rcCache_.end()) { | 		if (E != rcCache_.end()) { | ||||||
|             Entry = E->second; | 			Entry = E->second; | ||||||
|             return true; | 			return true; | ||||||
|         } | 		} | ||||||
|         return false; | 		return false; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|  | 	bool LatestFirmwareCache::IsLatest(const std::string &DeviceType, const std::string &Revision) { | ||||||
|  | 		std::lock_guard G(Mutex_); | ||||||
|  |  | ||||||
|     bool LatestFirmwareCache::IsLatest(const std::string &DeviceType, const std::string &Revision) { | 		auto E = Cache_.find(DeviceType); | ||||||
|         std::lock_guard G(Mutex_); | 		if (E != Cache_.end()) { | ||||||
|  | 			return E->second.Revision == Revision; | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|         auto E=Cache_.find(DeviceType); | 	bool LatestFirmwareCache::IsLatestRCOnly(const std::string &DeviceType, | ||||||
|         if(E!=Cache_.end()) { | 											 const std::string &Revision) { | ||||||
|             return E->second.Revision==Revision; | 		std::lock_guard G(Mutex_); | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool LatestFirmwareCache::IsLatestRCOnly(const std::string &DeviceType, const std::string &Revision) { | 		auto E = rcCache_.find(DeviceType); | ||||||
|         std::lock_guard G(Mutex_); | 		if (E != rcCache_.end()) { | ||||||
|  | 			return E->second.Revision == Revision; | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|         auto E=rcCache_.find(DeviceType); | 	void LatestFirmwareCache::DumpCache() { | ||||||
|         if(E!=rcCache_.end()) { | 		std::lock_guard G(Mutex_); | ||||||
|             return E->second.Revision==Revision; |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|  | 		for (auto &[Id, E] : Cache_) { | ||||||
|     void LatestFirmwareCache::DumpCache() { | 			std::cout << "Device: " << Id << "    ID:" << E.Id << std::endl; | ||||||
|         std::lock_guard G(Mutex_); | 		} | ||||||
|  | 	} | ||||||
|         for( auto &[Id,E]:Cache_) { | } // namespace OpenWifi | ||||||
|             std::cout << "Device: " << Id << "    ID:" << E.Id << std::endl; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -2,68 +2,73 @@ | |||||||
| // Created by stephane bourque on 2021-07-13. | // Created by stephane bourque on 2021-07-13. | ||||||
| // | // | ||||||
|  |  | ||||||
| #ifndef UCENTRALFMS_LATESTFIRMWARECACHE_H | #pragma once | ||||||
| #define UCENTRALFMS_LATESTFIRMWARECACHE_H |  | ||||||
|  |  | ||||||
| #include "Poco/JSON/Object.h" | #include "Poco/JSON/Object.h" | ||||||
|  | #include "Poco/JWT/Signer.h" | ||||||
| #include "Poco/Net/HTTPServerRequest.h" | #include "Poco/Net/HTTPServerRequest.h" | ||||||
| #include "Poco/Net/HTTPServerResponse.h" | #include "Poco/Net/HTTPServerResponse.h" | ||||||
| #include "Poco/JWT/Signer.h" |  | ||||||
| #include "Poco/SHA2Engine.h" | #include "Poco/SHA2Engine.h" | ||||||
|  | #include "Poco/StringTokenizer.h" | ||||||
|  |  | ||||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||||
| #include "framework/MicroService.h" | #include "framework/SubSystemServer.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     struct LatestFirmwareCacheEntry { | 	struct LatestFirmwareCacheEntry { | ||||||
|         std::string     Id; | 		std::string Id; | ||||||
|         uint64_t        TimeStamp=0; | 		uint64_t TimeStamp = 0; | ||||||
|         std::string     Revision; | 		std::string Revision; | ||||||
|     }; | 	}; | ||||||
|     typedef std::map<std::string, LatestFirmwareCacheEntry> LatestFirmwareCacheMap; | 	typedef std::map<std::string, LatestFirmwareCacheEntry> LatestFirmwareCacheMap; | ||||||
|     typedef std::map<std::string, LatestFirmwareCacheEntry> rcOnlyLatestFirmwareCacheMap; | 	typedef std::map<std::string, LatestFirmwareCacheEntry> rcOnlyLatestFirmwareCacheMap; | ||||||
|  |  | ||||||
|     class LatestFirmwareCache : public SubSystemServer { | 	class LatestFirmwareCache : public SubSystemServer { | ||||||
|     public: | 	  public: | ||||||
|         static auto instance() { | 		static auto instance() { | ||||||
|             static auto instance_ = new LatestFirmwareCache; | 			static auto instance_ = new LatestFirmwareCache; | ||||||
|             return instance_; | 			return instance_; | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         int Start() override; | 		int Start() override; | ||||||
|         void Stop() override; | 		void Stop() override; | ||||||
|         bool AddToCache(const std::string & DeviceType, const std::string & Revision, const std::string &Id, uint64_t TimeStamp); | 		bool AddToCache(const std::string &DeviceType, const std::string &Revision, | ||||||
|         // void AddRevision(const std::string &Revision); | 						const std::string &Id, uint64_t TimeStamp); | ||||||
|         bool FindLatestFirmware(const std::string &DeviceType, LatestFirmwareCacheEntry &Entry ); | 		// void AddRevision(const std::string &Revision); | ||||||
|         bool FindLatestRCOnlyFirmware(const std::string &DeviceType, LatestFirmwareCacheEntry &Entry ); | 		bool FindLatestFirmware(const std::string &DeviceType, LatestFirmwareCacheEntry &Entry); | ||||||
|  | 		bool FindLatestRCOnlyFirmware(const std::string &DeviceType, | ||||||
|  | 									  LatestFirmwareCacheEntry &Entry); | ||||||
|  |  | ||||||
|         inline static bool IsRC(const std::string & Revision) { | 		inline static bool IsRC(const std::string &Revision) { | ||||||
|             // OpenWrt 21.02-SNAPSHOT r16399+120-c67509efd7 / TIP-v2.5.0-36b5478 | 			// OpenWrt 21.02-SNAPSHOT r16399+120-c67509efd7 / TIP-v2.5.0-36b5478 | ||||||
|             auto Tokens = Poco::StringTokenizer(Revision,"/", Poco::StringTokenizer::TOK_TRIM); | 			auto Tokens = Poco::StringTokenizer(Revision, "/", Poco::StringTokenizer::TOK_TRIM); | ||||||
|             if(Tokens.count()!=2) | 			if (Tokens.count() != 2) | ||||||
|                 return false; | 				return false; | ||||||
|             return (Tokens[1].substr(0,5) == "IP-v"); | 			return (Tokens[1].substr(0, 5) == "TIP-v"); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         void DumpCache(); | 		void DumpCache(); | ||||||
|         inline Types::StringSet GetRevisions() { std::lock_guard G(Mutex_); return RevisionSet_; }; | 		inline Types::StringSet GetRevisions() { | ||||||
|         inline Types::StringSet GetDevices() { std::lock_guard G(Mutex_); return DeviceSet_; }; | 			std::lock_guard G(Mutex_); | ||||||
|         bool IsLatest(const std::string &DeviceType, const std::string &Revision); | 			return RevisionSet_; | ||||||
|         bool IsLatestRCOnly(const std::string &DeviceType, const std::string &Revision); | 		}; | ||||||
|  | 		inline Types::StringSet GetDevices() { | ||||||
|  | 			std::lock_guard G(Mutex_); | ||||||
|  | 			return DeviceSet_; | ||||||
|  | 		}; | ||||||
|  | 		bool IsLatest(const std::string &DeviceType, const std::string &Revision); | ||||||
|  | 		bool IsLatestRCOnly(const std::string &DeviceType, const std::string &Revision); | ||||||
|  |  | ||||||
|     private: | 	  private: | ||||||
|         LatestFirmwareCacheMap          Cache_; | 		LatestFirmwareCacheMap Cache_; | ||||||
|         rcOnlyLatestFirmwareCacheMap    rcCache_; | 		rcOnlyLatestFirmwareCacheMap rcCache_; | ||||||
|         Types::StringSet            RevisionSet_; | 		Types::StringSet RevisionSet_; | ||||||
|         Types::StringSet            DeviceSet_; | 		Types::StringSet DeviceSet_; | ||||||
|         explicit LatestFirmwareCache() noexcept: | 		explicit LatestFirmwareCache() noexcept | ||||||
|                 SubSystemServer("LatestFirmwareCache", "LATEST-FIRMWARE-CACHE", "LatestFirmwareCache") | 			: SubSystemServer("LatestFirmwareCache", "LATEST-FIRMWARE-CACHE", | ||||||
|         { | 							  "LatestFirmwareCache") {} | ||||||
|         } | 	}; | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     inline auto LatestFirmwareCache() { return LatestFirmwareCache::instance(); } | 	inline auto LatestFirmwareCache() { return LatestFirmwareCache::instance(); } | ||||||
| } | } // namespace OpenWifi | ||||||
|  |  | ||||||
|  |  | ||||||
| #endif //UCENTRALFMS_LATESTFIRMWARECACHE_H |  | ||||||
|   | |||||||
| @@ -6,310 +6,355 @@ | |||||||
| #include "Poco/JSON/Parser.h" | #include "Poco/JSON/Parser.h" | ||||||
| #include "Poco/JSON/Stringifier.h" | #include "Poco/JSON/Stringifier.h" | ||||||
|  |  | ||||||
|  | #include <aws/s3/model/GetObjectRequest.h> | ||||||
| #include <aws/s3/model/ListObjectsRequest.h> | #include <aws/s3/model/ListObjectsRequest.h> | ||||||
| #include <aws/s3/model/ListObjectsV2Request.h> | #include <aws/s3/model/ListObjectsV2Request.h> | ||||||
| #include <aws/s3/model/GetObjectRequest.h> |  | ||||||
|  |  | ||||||
|  | #include "LatestFirmwareCache.h" | ||||||
| #include "ManifestCreator.h" | #include "ManifestCreator.h" | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
| #include "LatestFirmwareCache.h" |  | ||||||
|  | #include "fmt/format.h" | ||||||
|  | #include "framework/utils.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     void ManifestCreator::onTimer([[maybe_unused]] Poco::Timer &timer) { | 	void ManifestCreator::onTimer([[maybe_unused]] Poco::Timer &timer) { | ||||||
|         Utils::SetThreadName("manifest"); | 		Utils::SetThreadName("manifest"); | ||||||
|         poco_information(Logger(),"Performing DB refresh"); | 		RunUpdateTask(); | ||||||
|         S3BucketContent BucketList; | 	} | ||||||
|         StorageService()->FirmwaresDB().RemoveOldFirmware(); |  | ||||||
|         ReadBucket(BucketList); |  | ||||||
|         poco_information(Logger(),fmt::format("Found {} firmware entries in S3 repository.", BucketList.size())); |  | ||||||
|         ComputeManifest(BucketList); |  | ||||||
|         AddManifestToDB(BucketList); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool ManifestCreator::ComputeManifest(S3BucketContent &BucketContent) { | 	bool ManifestCreator::RunUpdateTask() { | ||||||
|  | 		if (!UpdateRunning_.test_and_set(std::memory_order_acquire)) { | ||||||
|  | 			poco_information(Logger(), "Performing DB refresh"); | ||||||
|  | 			RunnerThread_.start(*this); | ||||||
|  | 			return true; | ||||||
|  | 		} else { | ||||||
|  | 			poco_information(Logger(), "DB refresh already in progress"); | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|         uint64_t Limit = OpenWifi::Now() - MaxAge_, Rejected=0, Accepted=0, BadFormat=0, MissingJson=0; | 	void ManifestCreator::run() { | ||||||
|         for(auto &[Name,Entry]:BucketContent) { | 		S3BucketContent BucketList; | ||||||
|             std::string C = Entry.S3ContentManifest; | 		StorageService()->FirmwaresDB().RemoveOldFirmware(); | ||||||
|  | 		ReadBucket(BucketList); | ||||||
|  | 		poco_information(Logger(), fmt::format("Found {} firmware entries in S3 repository.", | ||||||
|  | 											   BucketList.size())); | ||||||
|  | 		ComputeManifest(BucketList); | ||||||
|  | 		AddManifestToDB(BucketList); | ||||||
|  | 		LastUpdate_ = Utils::Now(); | ||||||
|  | 		UpdateRunning_.clear(std::memory_order_release); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|             try { | 	bool ManifestCreator::ComputeManifest(S3BucketContent &BucketContent) { | ||||||
|                 Poco::JSON::Parser  P; |  | ||||||
|                 auto ParsedContent = P.parse(Entry.S3ContentManifest).extract<Poco::JSON::Object::Ptr>(); |  | ||||||
|  |  | ||||||
|                 if( ParsedContent->has("image") && | 		uint64_t Limit = Utils::Now() - MaxAge_, Rejected = 0, Accepted = 0, BadFormat = 0, | ||||||
|                     ParsedContent->has("compatible") && | 				 MissingJson = 0; | ||||||
|                     ParsedContent->has("revision") && | 		for (auto &[Name, Entry] : BucketContent) { | ||||||
|                     ParsedContent->has("timestamp")) | 			std::string C = Entry.S3ContentManifest; | ||||||
|                 { |  | ||||||
|                     Entry.Timestamp = ParsedContent->get("timestamp"); |  | ||||||
|                     if(Entry.Timestamp>Limit) { |  | ||||||
|                         Entry.Compatible = ParsedContent->get("compatible").toString(); |  | ||||||
|                         Entry.Revision = ParsedContent->get("revision").toString(); |  | ||||||
|                         Entry.Image = ParsedContent->get("image").toString(); |  | ||||||
|                         auto FullNme = Name + "-upgrade.bin"; |  | ||||||
|                         if(FullNme!=Entry.Image) { |  | ||||||
|                             poco_error(Logger(),fmt::format("MANIFEST({}): Image name does not match manifest name ({}).",Name,Entry.Image)); |  | ||||||
|                             Entry.Valid = false; |  | ||||||
|                             BadFormat++; |  | ||||||
|                             continue; |  | ||||||
|                         } |  | ||||||
|                         Accepted++; |  | ||||||
|                         Entry.Valid = true; |  | ||||||
|                     } else { |  | ||||||
|                         Rejected++; |  | ||||||
|                         Entry.Valid = false; |  | ||||||
|                     } |  | ||||||
|                 } else { |  | ||||||
|                     poco_error(Logger(),fmt::format("MANIFEST({}): Entry does not have a valid JSON manifest.",Name)); |  | ||||||
|                     MissingJson++; |  | ||||||
|                     Entry.Valid = false; |  | ||||||
|                 } |  | ||||||
|             } catch (const Poco::Exception  &E ) { |  | ||||||
|                 Logger().log(E); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         poco_information(Logger(),fmt::format("Accepted {} firmwares.", Accepted)); | 			try { | ||||||
|         poco_information(Logger(),fmt::format("Rejected {} too old firmwares.", Rejected)); | 				Poco::JSON::Parser P; | ||||||
|         poco_information(Logger(),fmt::format("Rejected {} bad JSON.", BadFormat)); | 				auto ParsedContent = | ||||||
|         poco_information(Logger(),fmt::format("Rejected {} missing JSON.", MissingJson)); | 					P.parse(Entry.S3ContentManifest).extract<Poco::JSON::Object::Ptr>(); | ||||||
|  |  | ||||||
|         return true; | 				if (ParsedContent->has("image") && ParsedContent->has("compatible") && | ||||||
|     } | 					ParsedContent->has("revision") && ParsedContent->has("timestamp")) { | ||||||
|  | 					Entry.Timestamp = ParsedContent->get("timestamp"); | ||||||
|  | 					if (Entry.Timestamp > Limit) { | ||||||
|  | 						Entry.Compatible = ParsedContent->get("compatible").toString(); | ||||||
|  | 						Entry.Revision = ParsedContent->get("revision").toString(); | ||||||
|  | 						Entry.Image = ParsedContent->get("image").toString(); | ||||||
|  | 						auto FullNme = Name + "-upgrade.bin"; | ||||||
|  | 						if (FullNme != Entry.Image) { | ||||||
|  | 							poco_error( | ||||||
|  | 								Logger(), | ||||||
|  | 								fmt::format( | ||||||
|  | 									"MANIFEST({}): Image name does not match manifest name ({}).", | ||||||
|  | 									Name, Entry.Image)); | ||||||
|  | 							Entry.Valid = false; | ||||||
|  | 							BadFormat++; | ||||||
|  | 							continue; | ||||||
|  | 						} | ||||||
|  | 						Accepted++; | ||||||
|  | 						Entry.Valid = true; | ||||||
|  | 					} else { | ||||||
|  | 						Rejected++; | ||||||
|  | 						Entry.Valid = false; | ||||||
|  | 					} | ||||||
|  | 				} else { | ||||||
|  | 					poco_error( | ||||||
|  | 						Logger(), | ||||||
|  | 						fmt::format("MANIFEST({}): Entry does not have a valid JSON manifest.", | ||||||
|  | 									Name)); | ||||||
|  | 					MissingJson++; | ||||||
|  | 					Entry.Valid = false; | ||||||
|  | 				} | ||||||
|  | 			} catch (const Poco::Exception &E) { | ||||||
|  | 				Logger().log(E); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|     bool ManifestCreator::AddManifestToDB(S3BucketContent & BucketContent) { | 		poco_information(Logger(), fmt::format("Accepted {} firmwares.", Accepted)); | ||||||
|  | 		poco_information(Logger(), fmt::format("Rejected {} too old firmwares.", Rejected)); | ||||||
|  | 		poco_information(Logger(), fmt::format("Rejected {} bad JSON.", BadFormat)); | ||||||
|  | 		poco_information(Logger(), fmt::format("Rejected {} missing JSON.", MissingJson)); | ||||||
|  |  | ||||||
|         for(auto &[Release,BucketEntry]:BucketContent) { | 		return true; | ||||||
|             FMSObjects::Firmware    F; | 	} | ||||||
|             auto R = Release; |  | ||||||
|  |  | ||||||
|             // skip staging releases. | 	bool ManifestCreator::AddManifestToDB(S3BucketContent &BucketContent) { | ||||||
|             if(BucketEntry.URI.find("-staging-")!=std::string::npos) |  | ||||||
|                 continue; |  | ||||||
|  |  | ||||||
|             if(BucketEntry.Valid && !StorageService()->FirmwaresDB().GetFirmwareByName(R,BucketEntry.Compatible,F)) { | 		//  remove all staging names | ||||||
|                 F.id = MicroService::instance().CreateUUID(); | 		for (auto it = BucketContent.begin(); it != end(BucketContent);) { | ||||||
|                 F.release = Release; | 			if (it->second.URI.find("-staging-") != std::string::npos) { | ||||||
|                 F.size = BucketEntry.S3Size; | 				it = BucketContent.erase(it); | ||||||
|                 F.created = OpenWifi::Now(); | 			} else { | ||||||
|                 F.imageDate = BucketEntry.S3TimeStamp; | 				++it; | ||||||
|                 F.image = BucketEntry.Image; | 			} | ||||||
|                 F.uri = BucketEntry.URI; | 		} | ||||||
|                 F.revision = BucketEntry.Revision; |  | ||||||
|                 F.deviceType = BucketEntry.Compatible; |  | ||||||
|                 if(StorageService()->FirmwaresDB().AddFirmware(F)) { |  | ||||||
|                     poco_information(Logger(),fmt::format("Adding firmware '{}', size={}",Release,F.size)); |  | ||||||
|                 } else { |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     int ManifestCreator::Start() { | 		//  Now remove all DB entries that do not appear in the Latest manifest | ||||||
|         Running_ = true; | 		auto RemovedEntries = | ||||||
|         S3BucketName_ = MicroService::instance().ConfigGetString("s3.bucketname"); | 			StorageService()->FirmwaresDB().RemoveOldDBEntriesNotInManifest(BucketContent); | ||||||
|         S3Region_ = MicroService::instance().ConfigGetString("s3.region"); | 		poco_information(Logger(), fmt::format("Removed {} DB entries that no longer are relevant.", | ||||||
|         S3Secret_ = MicroService::instance().ConfigGetString("s3.secret"); | 											   RemovedEntries)); | ||||||
|         S3Key_ = MicroService::instance().ConfigGetString("s3.key"); |  | ||||||
|         S3Retry_ = MicroService::instance().ConfigGetInt("s3.retry",60); |  | ||||||
|  |  | ||||||
|         DBRefresh_ = MicroService::instance().ConfigGetInt("firmwaredb.refresh",30*60); | 		for (auto &[Release, BucketEntry] : BucketContent) { | ||||||
|         MaxAge_ = MicroService::instance().ConfigGetInt("firmwaredb.maxage",90) * 24 * 60 * 60; | 			FMSObjects::Firmware F; | ||||||
|  | 			auto R = Release; | ||||||
|  |  | ||||||
|         AwsConfig_.enableTcpKeepAlive = true; | 			if (BucketEntry.Valid && | ||||||
|         AwsConfig_.enableEndpointDiscovery = true; | 				!StorageService()->FirmwaresDB().GetFirmwareByName(R, BucketEntry.Compatible, F)) { | ||||||
|         AwsConfig_.useDualStack = true; | 				F.id = MicroServiceCreateUUID(); | ||||||
|         if(!S3Region_.empty()) | 				F.release = Release; | ||||||
|             AwsConfig_.region = S3Region_; | 				F.size = BucketEntry.S3Size; | ||||||
|         AwsCreds_.SetAWSAccessKeyId(S3Key_); | 				F.created = Utils::Now(); | ||||||
|         AwsCreds_.SetAWSSecretKey(S3Secret_); | 				F.imageDate = BucketEntry.S3TimeStamp; | ||||||
|  | 				F.image = BucketEntry.Image; | ||||||
|  | 				F.uri = BucketEntry.URI; | ||||||
|  | 				F.revision = BucketEntry.Revision; | ||||||
|  | 				F.deviceType = BucketEntry.Compatible; | ||||||
|  | 				if (StorageService()->FirmwaresDB().AddFirmware(F)) { | ||||||
|  | 					poco_information(Logger(), | ||||||
|  | 									 fmt::format("Adding firmware '{}', size={}", Release, F.size)); | ||||||
|  | 				} else { | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|         ManifestCreatorCallBack_ = std::make_unique<Poco::TimerCallback<ManifestCreator>>(*this, &ManifestCreator::onTimer); | 	int ManifestCreator::Start() { | ||||||
|         Timer_.setStartInterval(1 * 60 * 1000);  // first run in 1 minutes | 		Running_ = true; | ||||||
|         Timer_.setPeriodicInterval((long)(DBRefresh_ * 1000)); | 		S3EndpointOverride_ = MicroServiceConfigGetString("s3.endpointOverride", ""); | ||||||
|         Timer_.start(*ManifestCreatorCallBack_); | 		S3EndpointHttps_ = MicroServiceConfigGetBool("s3.endpoint.https", true); | ||||||
|  | 		S3UseVirtualAdressing_  = MicroServiceConfigGetBool("s3.useVirtualAdressing", true); | ||||||
|  | 		S3BucketName_ = MicroServiceConfigGetString("s3.bucketname", ""); | ||||||
|  | 		S3Region_ = MicroServiceConfigGetString("s3.region", ""); | ||||||
|  | 		S3Secret_ = MicroServiceConfigGetString("s3.secret", ""); | ||||||
|  | 		S3Key_ = MicroServiceConfigGetString("s3.key", ""); | ||||||
|  | 		S3Retry_ = MicroServiceConfigGetInt("s3.retry", 60); | ||||||
|  |  | ||||||
|         return 0; | 		DBRefresh_ = MicroServiceConfigGetInt("firmwaredb.refresh", 24 * 60 * 60); | ||||||
|     } | 		MaxAge_ = MicroServiceConfigGetInt("firmwaredb.maxage", 90) * 24 * 60 * 60; | ||||||
|  |  | ||||||
|     void ManifestCreator::Stop() { | 		AwsConfig_.enableTcpKeepAlive = true; | ||||||
|         if(Running_) { | 		AwsConfig_.enableEndpointDiscovery = true; | ||||||
|             Running_ = false; | 		AwsConfig_.useDualStack = true; | ||||||
|             Timer_.stop(); | 		if(!S3EndpointHttps_) | ||||||
|         } | 			AwsConfig_.scheme = Aws::Http::Scheme::HTTP; | ||||||
|     } | 		if(!S3EndpointOverride_.empty()) { | ||||||
|  | 			AwsConfig_.endpointOverride = Aws::String(S3EndpointOverride_); | ||||||
|  | 			AwsConfig_.useDualStack = false; | ||||||
|  | 		} | ||||||
|  | 		if (!S3Region_.empty()) | ||||||
|  | 			AwsConfig_.region = S3Region_; | ||||||
|  | 		AwsCreds_.SetAWSAccessKeyId(S3Key_); | ||||||
|  | 		AwsCreds_.SetAWSSecretKey(S3Secret_); | ||||||
|  |  | ||||||
|     void ManifestCreator::CloseBucket() { | 		ManifestCreatorCallBack_ = std::make_unique<Poco::TimerCallback<ManifestCreator>>( | ||||||
|     } | 			*this, &ManifestCreator::onTimer); | ||||||
|  | 		Timer_.setStartInterval(1 * 60 * 1000); // first run in 1 hour | ||||||
|  | 		Timer_.setPeriodicInterval((long)(DBRefresh_ * 1000)); | ||||||
|  | 		Timer_.start(*ManifestCreatorCallBack_); | ||||||
|  |  | ||||||
|     bool ManifestCreator::GetBucketObjectContent(Aws::S3::S3Client &S3Client, const std::string &ObjectName, | 		return 0; | ||||||
|                                                  std::string &ObjectContent) { | 	} | ||||||
|         Aws::S3::Model::GetObjectRequest Request; |  | ||||||
|         Request.SetBucket(S3BucketName_.c_str()); |  | ||||||
|         Request.SetKey(ObjectName.c_str()); |  | ||||||
|  |  | ||||||
|         Aws::S3::Model::GetObjectOutcome get_object_outcome = S3Client.GetObject(Request); | 	void ManifestCreator::Stop() { | ||||||
|  | 		if (Running_) { | ||||||
|  | 			Running_ = false; | ||||||
|  | 			Timer_.stop(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|         if (get_object_outcome.IsSuccess()) | 	void ManifestCreator::CloseBucket() {} | ||||||
|         { |  | ||||||
|             auto & FileData = get_object_outcome.GetResultWithOwnership().GetBody(); |  | ||||||
|             std::string O; |  | ||||||
|             std::ostringstream OS(O); |  | ||||||
|             OS << FileData.rdbuf(); |  | ||||||
|             ObjectContent = OS.str(); |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool ManifestCreator::ReadBucket(S3BucketContent & Bucket) { | 	bool ManifestCreator::GetBucketObjectContent(Aws::S3::S3Client &S3Client, | ||||||
|         static const std::string JSON(".json"); | 												 const std::string &ObjectName, | ||||||
|         static const std::string UPGRADE("-upgrade.bin"); | 												 std::string &ObjectContent) { | ||||||
|  | 		Aws::S3::Model::GetObjectRequest Request; | ||||||
|  | 		Request.SetBucket(S3BucketName_.c_str()); | ||||||
|  | 		Request.SetKey(ObjectName.c_str()); | ||||||
|  |  | ||||||
|         std::string     URIBase = "https://"; | 		Aws::S3::Model::GetObjectOutcome get_object_outcome = S3Client.GetObject(Request); | ||||||
|         URIBase += MicroService::instance().ConfigGetString("s3.bucket.uri"); |  | ||||||
|  |  | ||||||
|         Bucket.clear(); | 		if (get_object_outcome.IsSuccess()) { | ||||||
|  | 			auto &FileData = get_object_outcome.GetResultWithOwnership().GetBody(); | ||||||
|  | 			std::string O; | ||||||
|  | 			std::ostringstream OS(O); | ||||||
|  | 			OS << FileData.rdbuf(); | ||||||
|  | 			ObjectContent = OS.str(); | ||||||
|  | 			return true; | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|         Aws::S3::Model::ListObjectsV2Request Request; | 	bool ManifestCreator::ReadBucket(S3BucketContent &Bucket) { | ||||||
|         Request.WithBucket(S3BucketName_.c_str()); | 		static const std::string JSON(".json"); | ||||||
|         Aws::S3::S3Client S3Client(AwsCreds_,AwsConfig_); | 		static const std::string UPGRADE("-upgrade.bin"); | ||||||
|         Request.SetMaxKeys(100); |  | ||||||
|         Aws::S3::Model::ListObjectsV2Outcome Outcome; |  | ||||||
|  |  | ||||||
|         bool isDone=false; | 		std::string URIBase = "https://"; | ||||||
|         int Count=0, Runs=0; | 		URIBase += MicroServiceConfigGetString("s3.bucket.uri", ""); | ||||||
|  |  | ||||||
|         while(!isDone) { | 		Bucket.clear(); | ||||||
|             Outcome = S3Client.ListObjectsV2(Request); |  | ||||||
|             if(!Outcome.IsSuccess()) { |  | ||||||
|                 poco_error(Logger(),fmt::format("Error while doing ListObjectsV2: {}, {}", |  | ||||||
|                                            std::string{Outcome.GetError().GetExceptionName()}, |  | ||||||
|                                            std::string{Outcome.GetError().GetMessage()})); |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
|             Aws::Vector<Aws::S3::Model::Object> objects = Outcome.GetResult().GetContents(); |  | ||||||
|             Runs++; |  | ||||||
|             for (const auto &Object : objects) { |  | ||||||
|                 Count++; |  | ||||||
|                 // std::cout << "Run: " << Runs << "  Count: " << Count << std::endl; |  | ||||||
|                 Poco::Path FileName(Object.GetKey().c_str()); |  | ||||||
|                 if (!Running_) |  | ||||||
|                     return false; |  | ||||||
|                 if (FileName.getExtension() == "json") { |  | ||||||
|                     std::string Release = FileName.getBaseName(); |  | ||||||
|                     std::string Content; |  | ||||||
|  |  | ||||||
|                     if (GetBucketObjectContent(S3Client, FileName.getFileName(), Content)) { | 		Aws::S3::Model::ListObjectsV2Request Request; | ||||||
|                         // std::cout << "Object: " << FileName.getFileName() << std::endl; | 		Request.WithBucket(S3BucketName_.c_str()); | ||||||
|                         // std::cout << "Content: " << Content << std::endl; | 		Aws::S3::S3Client S3Client(AwsCreds_, AwsConfig_, Aws::Client::AWSAuthV4Signer::PayloadSigningPolicy::Never, S3UseVirtualAdressing_); | ||||||
|                         Poco::JSON::Parser P; | 		Request.SetMaxKeys(100); | ||||||
|                         auto ParsedContent = P.parse(Content).extract<Poco::JSON::Object::Ptr>(); | 		Aws::S3::Model::ListObjectsV2Outcome Outcome; | ||||||
|                         if (ParsedContent->has("image") && |  | ||||||
|                             ParsedContent->has("compatible") && |  | ||||||
|                             ParsedContent->has("revision") && |  | ||||||
|                             ParsedContent->has("timestamp")) { |  | ||||||
|                             auto It = Bucket.find(Release); |  | ||||||
|                             uint64_t TimeStamp = ParsedContent->get("timestamp"); |  | ||||||
|                             auto Compatible = ParsedContent->get("compatible").toString(); |  | ||||||
|                             auto Revision = ParsedContent->get("revision").toString(); |  | ||||||
|                             // std::cout << "Revision from bucket in JSON" << Revision << std::endl; |  | ||||||
|                             auto Image = ParsedContent->get("image").toString(); |  | ||||||
|                             if (It != Bucket.end()) { |  | ||||||
|                                 It->second.Timestamp = TimeStamp; |  | ||||||
|                                 It->second.Compatible = Compatible; |  | ||||||
|                                 It->second.Revision = Revision; |  | ||||||
|                                 It->second.Image = Image; |  | ||||||
|                                 It->second.S3ContentManifest = Content; |  | ||||||
|                             } else { |  | ||||||
|                                       Bucket.emplace(Release, S3BucketEntry{ |  | ||||||
|                                         .Valid = false, |  | ||||||
|                                         .S3Name = "", |  | ||||||
|                                         .S3ContentManifest = Content, |  | ||||||
|                                         .S3TimeStamp = 0 , |  | ||||||
|                                         .S3Size = 0 , |  | ||||||
|                                         .Revision = Revision, |  | ||||||
|                                         .Image = Image, |  | ||||||
|                                         .Compatible = Compatible, |  | ||||||
|                                         .Timestamp = TimeStamp, |  | ||||||
|                                         .URI = ""}); |  | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } else if (FileName.getExtension() == "bin") { |  | ||||||
|                     //  we must remove -upgrade, so |  | ||||||
|                     const auto &ReleaseName = FileName.getBaseName().substr(0, FileName.getBaseName().size() - 8); |  | ||||||
|                     auto It = Bucket.find(ReleaseName); |  | ||||||
|                     auto S3TimeStamp = (uint64_t) (Object.GetLastModified().Millis() / 1000); |  | ||||||
|                     uint64_t S3Size = Object.GetSize(); |  | ||||||
|                     std::string URI = URIBase + "/" + FileName.getFileName(); |  | ||||||
|                     if (It != Bucket.end()) { |  | ||||||
|                         It->second.S3TimeStamp = S3TimeStamp; |  | ||||||
|                         It->second.S3Size = S3Size; |  | ||||||
|                         It->second.S3Name = ReleaseName; |  | ||||||
|                         It->second.URI = URI; |  | ||||||
|                     } else { |  | ||||||
|  |  | ||||||
|                         Bucket.emplace(ReleaseName, S3BucketEntry{ | 		bool isDone = false; | ||||||
|                                 .Valid = false, | 		int Count = 0, Runs = 0; | ||||||
|                                 .S3Name = "", |  | ||||||
|                                 .S3ContentManifest = "", |  | ||||||
|                                 .S3TimeStamp = S3TimeStamp, |  | ||||||
|                                 .S3Size = S3Size , |  | ||||||
|                                 .Revision = "", |  | ||||||
|                                 .Image = "", |  | ||||||
|                                 .Compatible = "", |  | ||||||
|                                 .Timestamp = 0 , |  | ||||||
|                                 .URI = URI}); |  | ||||||
|                     } |  | ||||||
|                 } else { |  | ||||||
|                     // std::cout << "Ignoring " << FileName.getFileName() << std::endl; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             isDone = !Outcome.GetResult().GetIsTruncated(); | 		while (!isDone) { | ||||||
|             if(!isDone) { | 			Outcome = S3Client.ListObjectsV2(Request); | ||||||
|                 // std::cout << "Going for next run..." << std::endl; | 			if (!Outcome.IsSuccess()) { | ||||||
|                 // auto Token = Outcome.GetResult().GetContinuationToken(); | 				poco_error(Logger(), fmt::format("Error while doing ListObjectsV2: {}, {}", | ||||||
|                 auto Token = Outcome.GetResult().GetNextContinuationToken(); | 												 std::string{Outcome.GetError().GetExceptionName()}, | ||||||
|                 Request.SetContinuationToken(Token); | 												 std::string{Outcome.GetError().GetMessage()})); | ||||||
|                 // std::cout << "Continuation set..." << std::endl; | 				return false; | ||||||
|             } | 			} | ||||||
|         } | 			Aws::Vector<Aws::S3::Model::Object> objects = Outcome.GetResult().GetContents(); | ||||||
|  | 			Runs++; | ||||||
|  | 			for (const auto &Object : objects) { | ||||||
|  | 				Count++; | ||||||
|  | 				// std::cout << "Run: " << Runs << "  Count: " << Count << std::endl; | ||||||
|  | 				Poco::Path FileName(Object.GetKey().c_str()); | ||||||
|  | 				if (!Running_) | ||||||
|  | 					return false; | ||||||
|  | 				if (FileName.getExtension() == "json") { | ||||||
|  | 					std::string Release = FileName.getBaseName(); | ||||||
|  | 					std::string Content; | ||||||
|  |  | ||||||
|         // std::cout << "Count:" << Count << "  Runs:" << Runs << std::endl; | 					if (GetBucketObjectContent(S3Client, FileName.getFileName(), Content)) { | ||||||
|         if(!Outcome.IsSuccess()) { | 						// std::cout << "Object: " << FileName.getFileName() << std::endl; | ||||||
|             poco_error(Logger(),fmt::format("Error while doing ListObjectsV2: {}, {}", | 						// std::cout << "Content: " << Content << std::endl; | ||||||
|                                        std::string{Outcome.GetError().GetExceptionName()}, | 						Poco::JSON::Parser P; | ||||||
|                                        std::string{Outcome.GetError().GetMessage()})); | 						auto ParsedContent = P.parse(Content).extract<Poco::JSON::Object::Ptr>(); | ||||||
|             return false; | 						if (ParsedContent->has("image") && ParsedContent->has("compatible") && | ||||||
|         } | 							ParsedContent->has("revision") && ParsedContent->has("timestamp")) { | ||||||
|         return true; | 							auto It = Bucket.find(Release); | ||||||
|     } | 							uint64_t TimeStamp = ParsedContent->get("timestamp"); | ||||||
|  | 							auto Compatible = ParsedContent->get("compatible").toString(); | ||||||
|  | 							auto Revision = ParsedContent->get("revision").toString(); | ||||||
|  | 							// std::cout << "Revision from bucket in JSON" << Revision << std::endl; | ||||||
|  | 							auto Image = ParsedContent->get("image").toString(); | ||||||
|  | 							if (It != Bucket.end()) { | ||||||
|  | 								It->second.Timestamp = TimeStamp; | ||||||
|  | 								It->second.Compatible = Compatible; | ||||||
|  | 								It->second.Revision = Revision; | ||||||
|  | 								It->second.Image = Image; | ||||||
|  | 								It->second.S3ContentManifest = Content; | ||||||
|  | 							} else { | ||||||
|  | 								Bucket.emplace(Release, S3BucketEntry{.Valid = false, | ||||||
|  | 																	  .S3Name = "", | ||||||
|  | 																	  .S3ContentManifest = Content, | ||||||
|  | 																	  .S3TimeStamp = 0, | ||||||
|  | 																	  .S3Size = 0, | ||||||
|  | 																	  .Revision = Revision, | ||||||
|  | 																	  .Image = Image, | ||||||
|  | 																	  .Compatible = Compatible, | ||||||
|  | 																	  .Timestamp = TimeStamp, | ||||||
|  | 																	  .URI = ""}); | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} else if (FileName.getExtension() == "bin") { | ||||||
|  | 					//  we must remove -upgrade, so | ||||||
|  | 					const auto &ReleaseName = | ||||||
|  | 						FileName.getBaseName().substr(0, FileName.getBaseName().size() - 8); | ||||||
|  | 					auto It = Bucket.find(ReleaseName); | ||||||
|  | 					auto S3TimeStamp = (uint64_t)(Object.GetLastModified().Millis() / 1000); | ||||||
|  | 					uint64_t S3Size = Object.GetSize(); | ||||||
|  | 					std::string URI = URIBase + "/" + FileName.getFileName(); | ||||||
|  | 					if (It != Bucket.end()) { | ||||||
|  | 						It->second.S3TimeStamp = S3TimeStamp; | ||||||
|  | 						It->second.S3Size = S3Size; | ||||||
|  | 						It->second.S3Name = ReleaseName; | ||||||
|  | 						It->second.URI = URI; | ||||||
|  | 					} else { | ||||||
|  |  | ||||||
|     void S3BucketEntry::Print() const { | 						Bucket.emplace(ReleaseName, S3BucketEntry{.Valid = false, | ||||||
|         if(Valid) { | 																  .S3Name = "", | ||||||
|             std::cout << "  Name: " << S3Name << std::endl; | 																  .S3ContentManifest = "", | ||||||
|             std::cout << "  Size: " << S3Size << std::endl; | 																  .S3TimeStamp = S3TimeStamp, | ||||||
|             std::cout << "  Date: " << S3TimeStamp << std::endl; | 																  .S3Size = S3Size, | ||||||
|             std::cout << "  Latest: " << S3ContentManifest << std::endl; | 																  .Revision = "", | ||||||
|             std::cout << "  Image: " << Image << std::endl; | 																  .Image = "", | ||||||
|             std::cout << "  Revision: " << Revision << std::endl; | 																  .Compatible = "", | ||||||
|             std::cout << "  Compatible: " << Compatible << std::endl; | 																  .Timestamp = 0, | ||||||
|             std::cout << "  Timestamp: " << Timestamp << std::endl; | 																  .URI = URI}); | ||||||
|             std::cout << "  URI: " << URI << std::endl; | 					} | ||||||
|         } else { | 				} else { | ||||||
|  | 					// std::cout << "Ignoring " << FileName.getFileName() << std::endl; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  |  | ||||||
|         } | 			isDone = !Outcome.GetResult().GetIsTruncated(); | ||||||
|     } | 			if (!isDone) { | ||||||
|  | 				// std::cout << "Going for next run..." << std::endl; | ||||||
|  | 				// auto Token = Outcome.GetResult().GetContinuationToken(); | ||||||
|  | 				auto Token = Outcome.GetResult().GetNextContinuationToken(); | ||||||
|  | 				Request.SetContinuationToken(Token); | ||||||
|  | 				// std::cout << "Continuation set..." << std::endl; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|     void Print(const S3BucketContent &B) { | 		// std::cout << "Count:" << Count << "  Runs:" << Runs << std::endl; | ||||||
|         for(const auto &[Name,Entry]:B) { | 		if (!Outcome.IsSuccess()) { | ||||||
|             std::cout << "Release:" << Name << std::endl; | 			poco_error(Logger(), fmt::format("Run({},{}) Error while doing ListObjectsV2: {}, {}", | ||||||
|             Entry.Print(); |                                              Runs, Count, | ||||||
|         } | 											 std::string{Outcome.GetError().GetExceptionName()}, | ||||||
|     } | 											 std::string{Outcome.GetError().GetMessage()})); | ||||||
|  | 			return false; | ||||||
|  | 		} | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| } | 	void S3BucketEntry::Print() const { | ||||||
|  | 		if (Valid) { | ||||||
|  | 			std::cout << "  Name: " << S3Name << std::endl; | ||||||
|  | 			std::cout << "  Size: " << S3Size << std::endl; | ||||||
|  | 			std::cout << "  Date: " << S3TimeStamp << std::endl; | ||||||
|  | 			std::cout << "  Latest: " << S3ContentManifest << std::endl; | ||||||
|  | 			std::cout << "  Image: " << Image << std::endl; | ||||||
|  | 			std::cout << "  Revision: " << Revision << std::endl; | ||||||
|  | 			std::cout << "  Compatible: " << Compatible << std::endl; | ||||||
|  | 			std::cout << "  Timestamp: " << Timestamp << std::endl; | ||||||
|  | 			std::cout << "  URI: " << URI << std::endl; | ||||||
|  | 		} else { | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void Print(const S3BucketContent &B) { | ||||||
|  | 		for (const auto &[Name, Entry] : B) { | ||||||
|  | 			std::cout << "Release:" << Name << std::endl; | ||||||
|  | 			Entry.Print(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | } // namespace OpenWifi | ||||||
|   | |||||||
| @@ -2,74 +2,80 @@ | |||||||
| // Created by stephane bourque on 2021-06-02. | // Created by stephane bourque on 2021-06-02. | ||||||
| // | // | ||||||
|  |  | ||||||
| #ifndef UCENTRALFWS_MANIFESTCREATOR_H | #pragma once | ||||||
| #define UCENTRALFWS_MANIFESTCREATOR_H |  | ||||||
|  |  | ||||||
| #include <aws/core/Aws.h> | #include <aws/core/Aws.h> | ||||||
| #include <aws/s3/S3Client.h> |  | ||||||
| #include <aws/core/auth/AWSCredentials.h> | #include <aws/core/auth/AWSCredentials.h> | ||||||
|  | #include <aws/s3/S3Client.h> | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" |  | ||||||
| #include "Poco/Timer.h" | #include "Poco/Timer.h" | ||||||
|  | #include "framework/SubSystemServer.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     struct S3BucketEntry { | 	struct S3BucketEntry { | ||||||
|         bool            Valid = false; | 		bool Valid = false; | ||||||
|         std::string     S3Name; | 		std::string S3Name; | ||||||
|         std::string     S3ContentManifest; | 		std::string S3ContentManifest; | ||||||
|         uint64_t        S3TimeStamp = 0; | 		uint64_t S3TimeStamp = 0; | ||||||
|         uint64_t        S3Size = 0; | 		uint64_t S3Size = 0; | ||||||
|         std::string     Revision; | 		std::string Revision; | ||||||
|         std::string     Image; | 		std::string Image; | ||||||
|         std::string     Compatible; | 		std::string Compatible; | ||||||
|         uint64_t        Timestamp = 0; | 		uint64_t Timestamp = 0; | ||||||
|         std::string     URI; | 		std::string URI; | ||||||
|         void            Print() const; | 		void Print() const; | ||||||
|     }; | 	}; | ||||||
|     typedef std::map<const std::string, S3BucketEntry>    S3BucketContent; | 	typedef std::map<const std::string, S3BucketEntry> S3BucketContent; | ||||||
|  |  | ||||||
|     class ManifestCreator : public SubSystemServer { | 	class ManifestCreator : public SubSystemServer, Poco::Runnable { | ||||||
|     public: | 	  public: | ||||||
|         static auto instance() { | 		static auto instance() { | ||||||
|             static auto instance_ = new ManifestCreator; | 			static auto instance_ = new ManifestCreator; | ||||||
|             return instance_; | 			return instance_; | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         int Start() override; | 		int Start() override; | ||||||
|         void Stop() override; | 		void Stop() override; | ||||||
|  |  | ||||||
|         bool ComputeManifest(S3BucketContent & BucketContent); | 		bool ComputeManifest(S3BucketContent &BucketContent); | ||||||
|         bool AddManifestToDB(S3BucketContent & BucketContent); | 		bool AddManifestToDB(S3BucketContent &BucketContent); | ||||||
|         bool InitBucket(); | 		bool InitBucket(); | ||||||
|         bool ReadBucket(S3BucketContent & Bucket); | 		bool ReadBucket(S3BucketContent &Bucket); | ||||||
|         bool GetBucketObjectContent(Aws::S3::S3Client &S3Client, const std::string &ObjectName, std::string & ObjectContent); | 		bool GetBucketObjectContent(Aws::S3::S3Client &S3Client, const std::string &ObjectName, | ||||||
|         void CloseBucket(); | 									std::string &ObjectContent); | ||||||
|         void Print(const S3BucketContent &B); | 		void CloseBucket(); | ||||||
|         uint64_t MaxAge() const { return MaxAge_; } | 		void Print(const S3BucketContent &B); | ||||||
|         void onTimer(Poco::Timer & timer); | 		uint64_t MaxAge() const { return MaxAge_; } | ||||||
|  | 		void onTimer(Poco::Timer &timer); | ||||||
|  | 		bool RunUpdateTask(); | ||||||
|  | 		void run() override; | ||||||
|  | 		std::uint64_t LastUpdate() const { return LastUpdate_; } | ||||||
|  |  | ||||||
|     private: | 	  private: | ||||||
|         std::atomic_bool            Running_ = false; | 		std::atomic_bool Running_ = false; | ||||||
|         Aws::String                 S3BucketName_; | 		Aws::String S3EndpointOverride_; | ||||||
|         Aws::String                 S3Region_; | 		bool S3EndpointHttps_; | ||||||
|         Aws::String                 S3Key_; | 		bool S3UseVirtualAdressing_; | ||||||
|         Aws::String                 S3Secret_; | 		Aws::String S3BucketName_; | ||||||
|         uint64_t                    S3Retry_; | 		Aws::String S3Region_; | ||||||
|         Aws::Client::ClientConfiguration    AwsConfig_{"ARILIA"}; | 		Aws::String S3Key_; | ||||||
|         Aws::Auth::AWSCredentials           AwsCreds_; | 		Aws::String S3Secret_; | ||||||
|         uint64_t                     DBRefresh_ = 30 * 60; | 		uint64_t S3Retry_; | ||||||
|         uint64_t                    MaxAge_ = 0 ; | 		Aws::Client::ClientConfiguration AwsConfig_{"ARILIA"}; | ||||||
|         Poco::Timer                                             Timer_; | 		Aws::Auth::AWSCredentials AwsCreds_; | ||||||
|         std::unique_ptr<Poco::TimerCallback<ManifestCreator>>   ManifestCreatorCallBack_; | 		uint64_t DBRefresh_ = 30 * 60; | ||||||
|  | 		uint64_t MaxAge_ = 0; | ||||||
|  | 		Poco::Timer Timer_; | ||||||
|  | 		std::unique_ptr<Poco::TimerCallback<ManifestCreator>> ManifestCreatorCallBack_; | ||||||
|  | 		std::atomic_flag UpdateRunning_ = ATOMIC_FLAG_INIT; | ||||||
|  | 		Poco::Thread RunnerThread_; | ||||||
|  | 		std::uint64_t LastUpdate_ = 0; | ||||||
|  |  | ||||||
|         ManifestCreator() noexcept: | 		ManifestCreator() noexcept | ||||||
|                 SubSystemServer("ManifestCreator", "MANIFEST-MGR", "manifestcreator") { | 			: SubSystemServer("ManifestCreator", "MANIFEST-MGR", "manifestcreator") {} | ||||||
|         } | 	}; | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     inline auto ManifestCreator() { return ManifestCreator::instance(); }; | 	inline auto ManifestCreator() { return ManifestCreator::instance(); }; | ||||||
|  |  | ||||||
| } | } // namespace OpenWifi | ||||||
|  |  | ||||||
| #endif //UCENTRALFWS_MANIFESTCREATOR_H |  | ||||||
|   | |||||||
| @@ -5,83 +5,95 @@ | |||||||
| #include "NewCommandHandler.h" | #include "NewCommandHandler.h" | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
|  |  | ||||||
|  | #include "fmt/format.h" | ||||||
|  | #include "framework/KafkaManager.h" | ||||||
|  | #include "nlohmann/json.hpp" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     void NewCommandHandler::run() { | 	void NewCommandHandler::run() { | ||||||
|         Running_ = true ; | 		Running_ = true; | ||||||
|         Utils::SetThreadName("cmd-handler"); | 		Utils::SetThreadName("cmd-handler"); | ||||||
|         while(Running_) { | 		while (Running_) { | ||||||
|             Poco::Thread::trySleep(2000); | 			Poco::Thread::trySleep(2000); | ||||||
|  |  | ||||||
|             if(!Running_) | 			if (!Running_) | ||||||
|                 break; | 				break; | ||||||
|  |  | ||||||
|             while(!NewCommands_.empty()) { | 			while (!NewCommands_.empty()) { | ||||||
|                 if(!Running_) | 				if (!Running_) | ||||||
|                     break; | 					break; | ||||||
|  |  | ||||||
|                 Types::StringPair  S; | 				Types::StringPair S; | ||||||
|                 { | 				{ | ||||||
|                     std::lock_guard G(Mutex_); | 					std::lock_guard G(Mutex_); | ||||||
|                     S = NewCommands_.front(); | 					S = NewCommands_.front(); | ||||||
|                     NewCommands_.pop(); | 					NewCommands_.pop(); | ||||||
|                 } | 				} | ||||||
|  |  | ||||||
|                 try { | 				try { | ||||||
|                     auto SerialNumber = S.first; | 					auto SerialNumber = S.first; | ||||||
|                     auto M = nlohmann::json::parse(S.second); | 					auto M = nlohmann::json::parse(S.second); | ||||||
|  |  | ||||||
|                     std::string EndPoint; | 					std::string EndPoint; | ||||||
|  |  | ||||||
|                     if(M.contains(uCentralProtocol::SYSTEM)) { | 					if (M.contains(uCentralProtocol::SYSTEM)) { | ||||||
|                         auto SystemObj = M[uCentralProtocol::SYSTEM]; | 						auto SystemObj = M[uCentralProtocol::SYSTEM]; | ||||||
|                         if(SystemObj.contains(uCentralProtocol::HOST)) | 						if (SystemObj.contains(uCentralProtocol::HOST)) | ||||||
|                             EndPoint = SystemObj[uCentralProtocol::HOST]; | 							EndPoint = SystemObj[uCentralProtocol::HOST]; | ||||||
|                     } | 					} | ||||||
|  |  | ||||||
|                     if(M.contains(uCentralProtocol::PAYLOAD)) { | 					if (M.contains(uCentralProtocol::PAYLOAD)) { | ||||||
|                         auto PayloadSection = M[uCentralProtocol::PAYLOAD]; | 						auto PayloadSection = M[uCentralProtocol::PAYLOAD]; | ||||||
|                         if(PayloadSection.contains("command")) { | 						if (PayloadSection.contains("command")) { | ||||||
|                             auto Command = PayloadSection["command"]; | 							auto Command = PayloadSection["command"]; | ||||||
|                             if(Command=="delete_device") { | 							if (Command == "delete_device") { | ||||||
|                                 auto pSerialNumber = PayloadSection["payload"]["serialNumber"]; | 								auto pSerialNumber = PayloadSection["payload"]["serialNumber"]; | ||||||
|                                 if(pSerialNumber==SerialNumber) { | 								if (pSerialNumber == SerialNumber) { | ||||||
|                                     poco_debug(Logger(),fmt::format("Removing device '{}' from upgrade history.",SerialNumber)); | 									poco_debug( | ||||||
|                                     StorageService()->HistoryDB().DeleteHistory(SerialNumber); | 										Logger(), | ||||||
|                                     poco_debug(Logger(),fmt::format("Removing device '{}' from device table.",SerialNumber)); | 										fmt::format("Removing device '{}' from upgrade history.", | ||||||
|                                     StorageService()->DevicesDB().DeleteDevice(SerialNumber); | 													SerialNumber)); | ||||||
|                                 } | 									StorageService()->HistoryDB().DeleteHistory(SerialNumber); | ||||||
|                             } | 									poco_debug( | ||||||
|                         } | 										Logger(), | ||||||
|                     } | 										fmt::format("Removing device '{}' from device table.", | ||||||
|                 } catch (const Poco::Exception &E) { | 													SerialNumber)); | ||||||
|                     Logger().log(E); | 									StorageService()->DevicesDB().DeleteDevice(SerialNumber); | ||||||
|                 } | 								} | ||||||
|             } | 							} | ||||||
|         } | 						} | ||||||
|     }; | 					} | ||||||
|  | 				} catch (const Poco::Exception &E) { | ||||||
|  | 					Logger().log(E); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|     int NewCommandHandler::Start() { | 	int NewCommandHandler::Start() { | ||||||
|         Types::TopicNotifyFunction F = [this](std::string s1,std::string s2) { this->CommandReceived(s1,s2); }; | 		Types::TopicNotifyFunction F = [this](std::string s1, std::string s2) { | ||||||
|         WatcherId_ = KafkaManager()->RegisterTopicWatcher(KafkaTopics::COMMAND, F); | 			this->CommandReceived(s1, s2); | ||||||
|         Worker_.start(*this); | 		}; | ||||||
|         return 0; | 		WatcherId_ = KafkaManager()->RegisterTopicWatcher(KafkaTopics::COMMAND, F); | ||||||
|     }; | 		Worker_.start(*this); | ||||||
|  | 		return 0; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|     void NewCommandHandler::Stop() { | 	void NewCommandHandler::Stop() { | ||||||
|         KafkaManager()->UnregisterTopicWatcher(KafkaTopics::COMMAND, WatcherId_); | 		KafkaManager()->UnregisterTopicWatcher(KafkaTopics::COMMAND, WatcherId_); | ||||||
|         Running_ = false; | 		Running_ = false; | ||||||
|         Worker_.wakeUp(); | 		Worker_.wakeUp(); | ||||||
|         Worker_.join(); | 		Worker_.join(); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     bool NewCommandHandler::Update() { | 	bool NewCommandHandler::Update() { | ||||||
|         Worker_.wakeUp(); | 		Worker_.wakeUp(); | ||||||
|         return true; | 		return true; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void NewCommandHandler::CommandReceived( const std::string & Key, const std::string & Message) { | 	void NewCommandHandler::CommandReceived(const std::string &Key, const std::string &Message) { | ||||||
|         std::lock_guard G(Mutex_); | 		std::lock_guard G(Mutex_); | ||||||
|         NewCommands_.push(std::make_pair(Key,Message)); | 		NewCommands_.push(std::make_pair(Key, Message)); | ||||||
|     } | 	} | ||||||
| } | } // namespace OpenWifi | ||||||
| @@ -2,40 +2,35 @@ | |||||||
| // Created by stephane bourque on 2021-11-21. | // Created by stephane bourque on 2021-11-21. | ||||||
| // | // | ||||||
|  |  | ||||||
| #ifndef OWFMS_NEWCOMMANDHANDLER_H | #pragma once | ||||||
| #define OWFMS_NEWCOMMANDHANDLER_H |  | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" |  | ||||||
| #include "framework/OpenWifiTypes.h" | #include "framework/OpenWifiTypes.h" | ||||||
|  | #include "framework/SubSystemServer.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     class NewCommandHandler : public SubSystemServer, Poco::Runnable { | 	class NewCommandHandler : public SubSystemServer, Poco::Runnable { | ||||||
|     public: | 	  public: | ||||||
|         static auto instance() { | 		static auto instance() { | ||||||
|             static auto instance_ = new NewCommandHandler; | 			static auto instance_ = new NewCommandHandler; | ||||||
|             return instance_; | 			return instance_; | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         void run() override; | 		void run() override; | ||||||
|         int Start() override; | 		int Start() override; | ||||||
|         void Stop() override; | 		void Stop() override; | ||||||
|         bool Update(); | 		bool Update(); | ||||||
|         void CommandReceived( const std::string & Key, const std::string & Message); | 		void CommandReceived(const std::string &Key, const std::string &Message); | ||||||
|  |  | ||||||
|     private: | 	  private: | ||||||
|         Poco::Thread                Worker_; | 		Poco::Thread Worker_; | ||||||
|         std::atomic_bool            Running_ = false; | 		std::atomic_bool Running_ = false; | ||||||
|         int                         WatcherId_=0; | 		int WatcherId_ = 0; | ||||||
|         Types::StringPairQueue      NewCommands_; | 		Types::StringPairQueue NewCommands_; | ||||||
|  |  | ||||||
|         NewCommandHandler() noexcept: | 		NewCommandHandler() noexcept | ||||||
|             SubSystemServer("NewCommandHandler", "NEWCOM-MGR", "commanmdhandler") { | 			: SubSystemServer("NewCommandHandler", "NEWCOM-MGR", "commanmdhandler") {} | ||||||
|         } | 	}; | ||||||
|  | 	inline auto NewCommandHandler() { return NewCommandHandler::instance(); }; | ||||||
|  |  | ||||||
|     }; | } // namespace OpenWifi | ||||||
|     inline auto NewCommandHandler() { return NewCommandHandler::instance(); }; |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #endif //OWFMS_NEWCOMMANDHANDLER_H |  | ||||||
|   | |||||||
| @@ -3,142 +3,178 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "NewConnectionHandler.h" | #include "NewConnectionHandler.h" | ||||||
| #include "framework/KafkaTopics.h" | #include "AutoUpdater.h" | ||||||
| #include "framework/OpenWifiTypes.h" | #include "DeviceCache.h" | ||||||
| #include "framework/ow_constants.h" | #include "LatestFirmwareCache.h" | ||||||
| #include "Poco/JSON/Object.h" | #include "Poco/JSON/Object.h" | ||||||
| #include "Poco/JSON/Parser.h" | #include "Poco/JSON/Parser.h" | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
| #include "LatestFirmwareCache.h" | #include "framework/KafkaTopics.h" | ||||||
| #include "DeviceCache.h" | #include "framework/OpenWifiTypes.h" | ||||||
| #include "AutoUpdater.h" | #include "framework/ow_constants.h" | ||||||
|  |  | ||||||
|  | #include "fmt/format.h" | ||||||
|  | #include "framework/KafkaManager.h" | ||||||
|  |  | ||||||
| /* | /* | ||||||
| { "system" : { "id" : 6715803232063 , "host" : "https://localhost:17002" } , | { "system" : { "id" : 6715803232063 , "host" : "https://localhost:17002" } , | ||||||
|  "payload" : "{"capabilities":{"compatible":"linksys_ea8300","model":"Linksys EA8300 (Dallas)","network":{"lan":["eth0"],"wan":["eth1"]},"platform":"ap","switch":{"switch0":{"enable":true,"ports":[{"device":"eth0","need_tag":false,"num":0,"want_untag":true},{"num":1,"role":"lan"},{"num":2,"role":"lan"},{"num":3,"role":"lan"},{"num":4,"role":"lan"}],"reset":true,"roles":[{"device":"eth0","ports":"1 2 3 4 0","role":"lan"}]}},"wifi":{"platform/soc/a000000.wifi":{"band":["2G"],"channels":[1,2,3,4,5,6,7,8,9,10,11],"frequencies":[2412,2417,2422,2427,2432,2437,2442,2447,2452,2457,2462],"ht_capa":6639,"htmode":["HT20","HT40","VHT20","VHT40","VHT80"],"rx_ant":3,"tx_ant":3,"vht_capa":865687986},"platform/soc/a800000.wifi":{"band":["5G"],"channels":[36,40,44,48,52,56,60,64],"frequencies":[5180,5200,5220,5240,5260,5280,5300,5320],"ht_capa":6639,"htmode":["HT20","HT40","VHT20","VHT40","VHT80"],"rx_ant":3,"tx_ant":3,"vht_capa":865687986},"soc/40000000.pci/pci0000:00/0000:00:00.0/0000:01:00.0":{"band":["5G"],"channels":[100,104,108,112,116,120,124,128,132,136,140,144,149,153,157,161,165],"frequencies":[5500,5520,5540,5560,5580,5600,5620,5640,5660,5680,5700,5720,5745,5765,5785,5805,5825],"ht_capa":6639,"htmode":["HT20","HT40","VHT20","VHT40","VHT80"],"rx_ant":3,"tx_ant":3,"vht_capa":865696178}}},"firmware":"OpenWrt 21.02-SNAPSHOT r16011+53-6fd65c6573 / TIP-devel-0825cb93","serial":"24f5a207a130","uuid":1623866223}} |  "payload" : "{"capabilities":{"compatible":"linksys_ea8300","model":"Linksys EA8300 | ||||||
|  | (Dallas)","network":{"lan":["eth0"],"wan":["eth1"]},"platform":"ap","switch":{"switch0":{"enable":true,"ports":[{"device":"eth0","need_tag":false,"num":0,"want_untag":true},{"num":1,"role":"lan"},{"num":2,"role":"lan"},{"num":3,"role":"lan"},{"num":4,"role":"lan"}],"reset":true,"roles":[{"device":"eth0","ports":"1 | ||||||
|  | 2 3 4 | ||||||
|  | 0","role":"lan"}]}},"wifi":{"platform/soc/a000000.wifi":{"band":["2G"],"channels":[1,2,3,4,5,6,7,8,9,10,11],"frequencies":[2412,2417,2422,2427,2432,2437,2442,2447,2452,2457,2462],"ht_capa":6639,"htmode":["HT20","HT40","VHT20","VHT40","VHT80"],"rx_ant":3,"tx_ant":3,"vht_capa":865687986},"platform/soc/a800000.wifi":{"band":["5G"],"channels":[36,40,44,48,52,56,60,64],"frequencies":[5180,5200,5220,5240,5260,5280,5300,5320],"ht_capa":6639,"htmode":["HT20","HT40","VHT20","VHT40","VHT80"],"rx_ant":3,"tx_ant":3,"vht_capa":865687986},"soc/40000000.pci/pci0000:00/0000:00:00.0/0000:01:00.0":{"band":["5G"],"channels":[100,104,108,112,116,120,124,128,132,136,140,144,149,153,157,161,165],"frequencies":[5500,5520,5540,5560,5580,5600,5620,5640,5660,5680,5700,5720,5745,5765,5785,5805,5825],"ht_capa":6639,"htmode":["HT20","HT40","VHT20","VHT40","VHT80"],"rx_ant":3,"tx_ant":3,"vht_capa":865696178}}},"firmware":"OpenWrt | ||||||
|  | 21.02-SNAPSHOT r16011+53-6fd65c6573 / | ||||||
|  | TIP-devel-0825cb93","serial":"24f5a207a130","uuid":1623866223}} | ||||||
|  */ |  */ | ||||||
|  |  | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     void NewConnectionHandler::run() { | 	void NewConnectionHandler::run() { | ||||||
|         Utils::SetThreadName("conn-handler"); | 		Utils::SetThreadName("conn-handler"); | ||||||
|         Running_ = true ; | 		Running_ = true; | ||||||
|         while(Running_) { | 		while (Running_) { | ||||||
|             Poco::Thread::trySleep(2000); | 			Poco::Thread::trySleep(2000); | ||||||
|  |  | ||||||
|             if(!Running_) | 			if (!Running_) | ||||||
|                 break; | 				break; | ||||||
|  |  | ||||||
|             while(!NewConnections_.empty()) { | 			while (!NewConnections_.empty()) { | ||||||
|                 if(!Running_) | 				if (!Running_) | ||||||
|                     break; | 					break; | ||||||
|  |  | ||||||
|                 Types::StringPair  S; | 				Types::StringPair S; | ||||||
|                 { | 				{ | ||||||
|                     std::lock_guard G(Mutex_); | 					std::lock_guard G(Mutex_); | ||||||
|                     S = NewConnections_.front(); | 					S = NewConnections_.front(); | ||||||
|                     NewConnections_.pop(); | 					NewConnections_.pop(); | ||||||
|                 } | 				} | ||||||
|  |  | ||||||
|                 try { | 				try { | ||||||
|                     auto SerialNumber = S.first; | 					auto SerialNumber = S.first; | ||||||
|                     Poco::JSON::Parser  Parser; | 					Poco::JSON::Parser Parser; | ||||||
|                     auto Object = Parser.parse(S.second).extract<Poco::JSON::Object::Ptr>(); | 					auto Object = Parser.parse(S.second).extract<Poco::JSON::Object::Ptr>(); | ||||||
|  |  | ||||||
|                     std::string EndPoint; | 					std::string EndPoint; | ||||||
|  |  | ||||||
|                     if(Object->has(uCentralProtocol::SYSTEM)) { | 					if (Object->has(uCentralProtocol::SYSTEM)) { | ||||||
|                         auto SystemObj = Object->getObject(uCentralProtocol::SYSTEM); | 						auto SystemObj = Object->getObject(uCentralProtocol::SYSTEM); | ||||||
|                         if(SystemObj->has(uCentralProtocol::HOST)) | 						if (SystemObj->has(uCentralProtocol::HOST)) | ||||||
|                             EndPoint = SystemObj->get(uCentralProtocol::HOST).toString(); | 							EndPoint = SystemObj->get(uCentralProtocol::HOST).toString(); | ||||||
|                     } | 					} | ||||||
|  |  | ||||||
|                     if(Object->has(uCentralProtocol::PAYLOAD)) { | 					if (Object->has(uCentralProtocol::PAYLOAD)) { | ||||||
|                         auto PayloadObj = Object->getObject(uCentralProtocol::PAYLOAD); | 						auto PayloadObj = Object->getObject(uCentralProtocol::PAYLOAD); | ||||||
|                         if(PayloadObj->has(uCentralProtocol::CAPABILITIES)) { | 						if (PayloadObj->has(uCentralProtocol::CAPABILITIES)) { | ||||||
|                             // std::cout << "CAPABILITIES:" << SerialNumber << std::endl; | 							// std::cout << "CAPABILITIES:" << SerialNumber << std::endl; | ||||||
|                             auto CapObj = PayloadObj->getObject(uCentralProtocol::CAPABILITIES); | 							auto CapObj = PayloadObj->getObject(uCentralProtocol::CAPABILITIES); | ||||||
|                             if(CapObj->has(uCentralProtocol::COMPATIBLE)) { | 							if (CapObj->has(uCentralProtocol::COMPATIBLE)) { | ||||||
|                                 auto DeviceType = CapObj->get(uCentralProtocol::COMPATIBLE).toString(); | 								auto DeviceType = | ||||||
|                                 auto Serial = PayloadObj->get(uCentralProtocol::SERIAL).toString(); | 									CapObj->get(uCentralProtocol::COMPATIBLE).toString(); | ||||||
|                                 auto Revision = Storage::TrimRevision(PayloadObj->get(uCentralProtocol::FIRMWARE).toString()); | 								auto Serial = PayloadObj->get(uCentralProtocol::SERIAL).toString(); | ||||||
|                                 // std::cout << "ConnectionEvent: SerialNumber: " << SerialNumber << " DeviceType: " << DeviceType << " Revision:" << Revision << std::endl; | 								auto Revision = Storage::TrimRevision( | ||||||
|                                 FMSObjects::FirmwareAgeDetails  FA; | 									PayloadObj->get(uCentralProtocol::FIRMWARE).toString()); | ||||||
|                                 if(StorageService()->FirmwaresDB().ComputeFirmwareAge(DeviceType, Revision, FA)) { | 								// std::cout << "ConnectionEvent: SerialNumber: " << SerialNumber << | ||||||
|                                     StorageService()->DevicesDB().SetDeviceRevision(SerialNumber, Revision, DeviceType, EndPoint); | 								// " DeviceType: " << DeviceType << " Revision:" << Revision << | ||||||
|                                     if(FA.age) | 								// std::endl; | ||||||
|                                         poco_information(Logger(),fmt::format("Device {} connection. Firmware is {} older than latest.",SerialNumber, Utils::SecondsToNiceText(FA.age))); | 								FMSObjects::FirmwareAgeDetails FA; | ||||||
|                                     else | 								if (StorageService()->FirmwaresDB().ComputeFirmwareAge( | ||||||
|                                     poco_information(Logger(),fmt::format("Device {} connection. Device firmware is up to date.",SerialNumber)); | 										DeviceType, Revision, FA)) { | ||||||
|                                 } | 									StorageService()->DevicesDB().SetDeviceRevision( | ||||||
|                                 else { | 										SerialNumber, Revision, DeviceType, EndPoint); | ||||||
|                                     poco_information(Logger(),fmt::format("Device {} connection. Firmware age cannot be determined.",SerialNumber)); | 									if (FA.age) | ||||||
|                                 } | 										poco_information( | ||||||
|  | 											Logger(), | ||||||
|  | 											fmt::format("Device {} connection. Firmware is {} " | ||||||
|  | 														"older than latest.", | ||||||
|  | 														SerialNumber, | ||||||
|  | 														Utils::SecondsToNiceText(FA.age))); | ||||||
|  | 									else | ||||||
|  | 										poco_information(Logger(), | ||||||
|  | 														 fmt::format("Device {} connection. Device " | ||||||
|  | 																	 "firmware is up to date.", | ||||||
|  | 																	 SerialNumber)); | ||||||
|  | 								} else { | ||||||
|  | 									poco_information(Logger(), | ||||||
|  | 													 fmt::format("Device {} connection. Firmware " | ||||||
|  | 																 "age cannot be determined.", | ||||||
|  | 																 SerialNumber)); | ||||||
|  | 								} | ||||||
|  |  | ||||||
|                                 if(!LatestFirmwareCache()->IsLatest(DeviceType, Revision)) { | 								if (!LatestFirmwareCache()->IsLatest(DeviceType, Revision)) { | ||||||
|                                     // std::cout << "Device (connection): " << SerialNumber << " to be upgraded ... " << std::endl; | 									// std::cout << "Device (connection): " << SerialNumber << " to | ||||||
|                                     AutoUpdater()->ToBeUpgraded(SerialNumber, DeviceType); | 									// be upgraded ... " << std::endl; | ||||||
|                                 } | 									AutoUpdater()->ToBeUpgraded(SerialNumber, DeviceType); | ||||||
|                                 DeviceCache()->AddToCache(Serial, DeviceType, EndPoint, Revision); | 								} | ||||||
|                             } | 								DeviceCache()->AddToCache(Serial, DeviceType, EndPoint, Revision); | ||||||
|                         } else if(PayloadObj->has(uCentralProtocol::DISCONNECTION)) { | 							} | ||||||
|                             auto DisconnectMessage = PayloadObj->getObject(uCentralProtocol::DISCONNECTION); | 						} else if (PayloadObj->has(uCentralProtocol::DISCONNECTION)) { | ||||||
|                             if(DisconnectMessage->has(uCentralProtocol::SERIALNUMBER) && DisconnectMessage->has(uCentralProtocol::TIMESTAMP)) { | 							auto DisconnectMessage = | ||||||
|                                 auto SNum = DisconnectMessage->get(uCentralProtocol::SERIALNUMBER).toString(); | 								PayloadObj->getObject(uCentralProtocol::DISCONNECTION); | ||||||
|                                 auto Timestamp = DisconnectMessage->get(uCentralProtocol::TIMESTAMP); | 							if (DisconnectMessage->has(uCentralProtocol::SERIALNUMBER) && | ||||||
|                                 StorageService()->DevicesDB().SetDeviceDisconnected(SNum,EndPoint); | 								DisconnectMessage->has(uCentralProtocol::TIMESTAMP)) { | ||||||
|                                 // std::cout << "DISCONNECTION:" << SerialNumber << std::endl; | 								auto SNum = DisconnectMessage->get(uCentralProtocol::SERIALNUMBER) | ||||||
|                             } | 												.toString(); | ||||||
|                         } else if(PayloadObj->has(uCentralProtocol::PING)) { | 								auto Timestamp = | ||||||
|                             // std::cout << "PING:" << SerialNumber << std::endl; | 									DisconnectMessage->get(uCentralProtocol::TIMESTAMP); | ||||||
|                             auto PingMessage = PayloadObj->getObject(uCentralProtocol::PING); | 								StorageService()->DevicesDB().SetDeviceDisconnected(SNum, EndPoint); | ||||||
|                             if( PingMessage->has(uCentralProtocol::FIRMWARE) && | 								// std::cout << "DISCONNECTION:" << SerialNumber << std::endl; | ||||||
|                             PingMessage->has(uCentralProtocol::SERIALNUMBER) && | 							} | ||||||
|                             PingMessage->has(uCentralProtocol::COMPATIBLE)) { | 						} else if (PayloadObj->has(uCentralProtocol::PING)) { | ||||||
|                                 auto Revision = Storage::TrimRevision(PingMessage->get(uCentralProtocol::FIRMWARE).toString()); | 							// std::cout << "PING:" << SerialNumber << std::endl; | ||||||
|                                 auto Serial = PingMessage->get( uCentralProtocol::SERIALNUMBER).toString(); | 							auto PingMessage = PayloadObj->getObject(uCentralProtocol::PING); | ||||||
|                                 auto DeviceType = PingMessage->get( uCentralProtocol::COMPATIBLE).toString(); | 							if (PingMessage->has(uCentralProtocol::FIRMWARE) && | ||||||
|                                 StorageService()->DevicesDB().SetDeviceRevision(Serial, Revision, DeviceType, EndPoint); | 								PingMessage->has(uCentralProtocol::SERIALNUMBER) && | ||||||
|                                 DeviceCache()->AddToCache(Serial, DeviceType, EndPoint, Revision); | 								PingMessage->has(uCentralProtocol::COMPATIBLE)) { | ||||||
|                                 if(!LatestFirmwareCache()->IsLatest(DeviceType, Revision)) { | 								auto Revision = Storage::TrimRevision( | ||||||
|                                     // std::cout << "Device(ping): " << SerialNumber << " to be upgraded ... " << std::endl; | 									PingMessage->get(uCentralProtocol::FIRMWARE).toString()); | ||||||
|                                     AutoUpdater()->ToBeUpgraded(SerialNumber, DeviceType); | 								auto Serial = | ||||||
|                                 } | 									PingMessage->get(uCentralProtocol::SERIALNUMBER).toString(); | ||||||
|                             } | 								auto DeviceType = | ||||||
|                         } | 									PingMessage->get(uCentralProtocol::COMPATIBLE).toString(); | ||||||
|                     } | 								StorageService()->DevicesDB().SetDeviceRevision( | ||||||
|                 } catch (const Poco::Exception &E) { | 									Serial, Revision, DeviceType, EndPoint); | ||||||
|                     Logger().log(E); | 								DeviceCache()->AddToCache(Serial, DeviceType, EndPoint, Revision); | ||||||
|                 } | 								if (!LatestFirmwareCache()->IsLatest(DeviceType, Revision)) { | ||||||
|             } | 									// std::cout << "Device(ping): " << SerialNumber << " to be | ||||||
|         } | 									// upgraded ... " << std::endl; | ||||||
|     }; | 									AutoUpdater()->ToBeUpgraded(SerialNumber, DeviceType); | ||||||
|  | 								} | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} catch (const Poco::Exception &E) { | ||||||
|  | 					Logger().log(E); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|     int NewConnectionHandler::Start() { | 	int NewConnectionHandler::Start() { | ||||||
|         poco_information(Logger(),"Starting..."); | 		poco_information(Logger(), "Starting..."); | ||||||
|         Types::TopicNotifyFunction F = [this](std::string s1,std::string s2) { this->ConnectionReceived(s1,s2); }; | 		Types::TopicNotifyFunction F = [this](std::string s1, std::string s2) { | ||||||
|         ConnectionWatcherId_ = KafkaManager()->RegisterTopicWatcher(KafkaTopics::CONNECTION, F); | 			this->ConnectionReceived(s1, s2); | ||||||
|         Worker_.start(*this); | 		}; | ||||||
|         return 0; | 		ConnectionWatcherId_ = KafkaManager()->RegisterTopicWatcher(KafkaTopics::CONNECTION, F); | ||||||
|     }; | 		Worker_.start(*this); | ||||||
|  | 		return 0; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|     void NewConnectionHandler::Stop() { | 	void NewConnectionHandler::Stop() { | ||||||
|         poco_information(Logger(),"Stopping..."); | 		poco_information(Logger(), "Stopping..."); | ||||||
|         KafkaManager()->UnregisterTopicWatcher(KafkaTopics::CONNECTION, ConnectionWatcherId_); | 		KafkaManager()->UnregisterTopicWatcher(KafkaTopics::CONNECTION, ConnectionWatcherId_); | ||||||
|         Running_ = false; | 		Running_ = false; | ||||||
|         Worker_.wakeUp(); | 		Worker_.wakeUp(); | ||||||
|         Worker_.join(); | 		Worker_.join(); | ||||||
|         poco_information(Logger(),"Stopped..."); | 		poco_information(Logger(), "Stopped..."); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     bool NewConnectionHandler::Update() { | 	bool NewConnectionHandler::Update() { | ||||||
|         Worker_.wakeUp(); | 		Worker_.wakeUp(); | ||||||
|         return true; | 		return true; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void NewConnectionHandler::ConnectionReceived( const std::string & Key, const std::string & Message) { | 	void NewConnectionHandler::ConnectionReceived(const std::string &Key, | ||||||
|         std::lock_guard G(Mutex_); | 												  const std::string &Message) { | ||||||
|         NewConnections_.push(std::make_pair(Key,Message)); | 		std::lock_guard G(Mutex_); | ||||||
|     } | 		NewConnections_.push(std::make_pair(Key, Message)); | ||||||
| } | 	} | ||||||
|  | } // namespace OpenWifi | ||||||
| @@ -2,42 +2,35 @@ | |||||||
| // Created by stephane bourque on 2021-07-13. | // Created by stephane bourque on 2021-07-13. | ||||||
| // | // | ||||||
|  |  | ||||||
| #ifndef UCENTRALFMS_NEWCONNECTIONHANDLER_H | #pragma once | ||||||
| #define UCENTRALFMS_NEWCONNECTIONHANDLER_H |  | ||||||
|  |  | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" |  | ||||||
| #include "framework/OpenWifiTypes.h" | #include "framework/OpenWifiTypes.h" | ||||||
|  | #include "framework/SubSystemServer.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     class NewConnectionHandler : public SubSystemServer, Poco::Runnable { | 	class NewConnectionHandler : public SubSystemServer, Poco::Runnable { | ||||||
|     public: | 	  public: | ||||||
|  | 		static auto instance() { | ||||||
|  | 			static auto instance_ = new NewConnectionHandler; | ||||||
|  | 			return instance_; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|         static auto instance() { | 		void run() override; | ||||||
|             static auto instance_ = new NewConnectionHandler; | 		int Start() override; | ||||||
|             return instance_; | 		void Stop() override; | ||||||
|         } | 		bool Update(); | ||||||
|  |  | ||||||
|         void run() override; | 		void ConnectionReceived(const std::string &Key, const std::string &Message); | ||||||
|         int Start() override; |  | ||||||
|         void Stop() override; |  | ||||||
|         bool Update(); |  | ||||||
|  |  | ||||||
|         void ConnectionReceived( const std::string & Key, const std::string & Message); | 	  private: | ||||||
|  | 		Poco::Thread Worker_; | ||||||
|  | 		std::atomic_bool Running_ = false; | ||||||
|  | 		uint64_t ConnectionWatcherId_ = 0; | ||||||
|  | 		Types::StringPairQueue NewConnections_; | ||||||
|  |  | ||||||
|     private: | 		NewConnectionHandler() noexcept | ||||||
|         Poco::Thread                Worker_; | 			: SubSystemServer("ConnectionHandler", "NEWCONN-MGR", "connectionhandler") {} | ||||||
|         std::atomic_bool            Running_ = false; | 	}; | ||||||
|         uint64_t                    ConnectionWatcherId_=0; | 	inline auto NewConnectionHandler() { return NewConnectionHandler::instance(); }; | ||||||
|         Types::StringPairQueue      NewConnections_; | } // namespace OpenWifi | ||||||
|  |  | ||||||
|         NewConnectionHandler() noexcept: |  | ||||||
|                 SubSystemServer("ConnectionHandler", "NEWCONN-MGR", "connectionhandler") { |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     }; |  | ||||||
|     inline auto NewConnectionHandler() { return NewConnectionHandler::instance(); }; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #endif //UCENTRALFMS_NEWCONNECTIONHANDLER_H |  | ||||||
|   | |||||||
| @@ -2,46 +2,40 @@ | |||||||
| // Created by stephane bourque on 2021-10-23. | // Created by stephane bourque on 2021-10-23. | ||||||
| // | // | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" |  | ||||||
|  |  | ||||||
| #include "RESTAPI/RESTAPI_firmwareHandler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_firmwaresHandler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_firmwareAgeHandler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_connectedDeviceHandler.h" | #include "RESTAPI/RESTAPI_connectedDeviceHandler.h" | ||||||
| #include "RESTAPI/RESTAPI_connectedDevicesHandler.h" | #include "RESTAPI/RESTAPI_connectedDevicesHandler.h" | ||||||
| #include "RESTAPI/RESTAPI_historyHandler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_deviceReportHandler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_deviceInformation_handler.h" | #include "RESTAPI/RESTAPI_deviceInformation_handler.h" | ||||||
|  | #include "RESTAPI/RESTAPI_deviceReportHandler.h" | ||||||
|  | #include "RESTAPI/RESTAPI_firmwareAgeHandler.h" | ||||||
|  | #include "RESTAPI/RESTAPI_firmwareHandler.h" | ||||||
|  | #include "RESTAPI/RESTAPI_firmwaresHandler.h" | ||||||
|  | #include "RESTAPI/RESTAPI_historyHandler.h" | ||||||
|  | #include "framework/RESTAPI_Handler.h" | ||||||
|  | #include "framework/RESTAPI_SystemCommand.h" | ||||||
|  | #include "framework/RESTAPI_SystemConfiguration.h" | ||||||
|  | #include "framework/RESTAPI_WebSocketServer.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, | 	Poco::Net::HTTPRequestHandler * | ||||||
|                                                             Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) { | 	RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, | ||||||
|         return  RESTAPI_Router< | 					  Poco::Logger &L, RESTAPI_GenericServerAccounting &S, uint64_t TransactionId) { | ||||||
|                 RESTAPI_firmwaresHandler, | 		return RESTAPI_Router<RESTAPI_firmwaresHandler, RESTAPI_system_configuration, RESTAPI_firmwareHandler, | ||||||
|                 RESTAPI_firmwareHandler, | 							  RESTAPI_system_command, RESTAPI_firmwareAgeHandler, | ||||||
|                 RESTAPI_system_command, | 							  RESTAPI_connectedDevicesHandler, RESTAPI_connectedDeviceHandler, | ||||||
|                 RESTAPI_firmwareAgeHandler, | 							  RESTAPI_historyHandler, RESTAPI_deviceReportHandler, | ||||||
|                 RESTAPI_connectedDevicesHandler, | 							  RESTAPI_deviceInformation_handler, RESTAPI_webSocketServer>( | ||||||
|                 RESTAPI_connectedDeviceHandler, | 			Path, Bindings, L, S, TransactionId); | ||||||
|                 RESTAPI_historyHandler, | 	} | ||||||
|                 RESTAPI_deviceReportHandler, |  | ||||||
|                 RESTAPI_deviceInformation_handler |  | ||||||
|             >(Path,Bindings,L, S, TransactionId); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, | 	Poco::Net::HTTPRequestHandler * | ||||||
|                                                             Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) { | 	RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, | ||||||
|         return RESTAPI_Router_I< | 					  Poco::Logger &L, RESTAPI_GenericServerAccounting &S, uint64_t TransactionId) { | ||||||
|                 RESTAPI_firmwaresHandler, | 		return RESTAPI_Router_I<RESTAPI_firmwaresHandler, RESTAPI_system_configuration, RESTAPI_firmwareHandler, | ||||||
|                 RESTAPI_firmwareHandler, | 								RESTAPI_system_command, RESTAPI_firmwareAgeHandler, | ||||||
|                 RESTAPI_system_command, | 								RESTAPI_connectedDevicesHandler, RESTAPI_connectedDeviceHandler, | ||||||
|                 RESTAPI_firmwareAgeHandler, | 								RESTAPI_historyHandler, RESTAPI_deviceReportHandler, | ||||||
|                 RESTAPI_connectedDevicesHandler, | 								RESTAPI_deviceInformation_handler>(Path, Bindings, L, S, | ||||||
|                 RESTAPI_connectedDeviceHandler, | 																   TransactionId); | ||||||
|                 RESTAPI_historyHandler, | 	} | ||||||
|                 RESTAPI_deviceReportHandler, | } // namespace OpenWifi | ||||||
|                 RESTAPI_deviceInformation_handler |  | ||||||
|             >(Path, Bindings, L, S, TransactionId); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -9,19 +9,19 @@ | |||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     void RESTAPI_connectedDeviceHandler::DoGet() { | 	void RESTAPI_connectedDeviceHandler::DoGet() { | ||||||
|         auto SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER,""); | 		auto SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, ""); | ||||||
|  |  | ||||||
|         if(SerialNumber.empty()) { | 		if (SerialNumber.empty()) { | ||||||
|             return BadRequest(RESTAPI::Errors::MissingSerialNumber); | 			return BadRequest(RESTAPI::Errors::MissingSerialNumber); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         FMSObjects::DeviceConnectionInformation DevInfo; | 		FMSObjects::DeviceConnectionInformation DevInfo; | ||||||
|         if(StorageService()->DevicesDB().GetDevice(SerialNumber, DevInfo)) { | 		if (StorageService()->DevicesDB().GetDevice(SerialNumber, DevInfo)) { | ||||||
|             Poco::JSON::Object  Answer; | 			Poco::JSON::Object Answer; | ||||||
|             DevInfo.to_json(Answer); | 			DevInfo.to_json(Answer); | ||||||
|             return ReturnObject(Answer); | 			return ReturnObject(Answer); | ||||||
|         } | 		} | ||||||
|         NotFound(); | 		NotFound(); | ||||||
|     } | 	} | ||||||
| } | } // namespace OpenWifi | ||||||
| @@ -5,26 +5,27 @@ | |||||||
| #ifndef UCENTRALFMS_RESTAPI_CONNECTEDDEVICEHANDLER_H | #ifndef UCENTRALFMS_RESTAPI_CONNECTEDDEVICEHANDLER_H | ||||||
| #define UCENTRALFMS_RESTAPI_CONNECTEDDEVICEHANDLER_H | #define UCENTRALFMS_RESTAPI_CONNECTEDDEVICEHANDLER_H | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" | #include "framework/RESTAPI_Handler.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_connectedDeviceHandler : public RESTAPIHandler { | 	class RESTAPI_connectedDeviceHandler : public RESTAPIHandler { | ||||||
|     public: | 	  public: | ||||||
|         RESTAPI_connectedDeviceHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | 		RESTAPI_connectedDeviceHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, | ||||||
|                 : RESTAPIHandler(bindings, L, | 									   RESTAPI_GenericServerAccounting &Server, | ||||||
|                                  std::vector<std::string> | 									   uint64_t TransactionId, bool Internal) | ||||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | 			: RESTAPIHandler(bindings, L, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_OPTIONS}, | 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                                           Server, | 													  Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
|                                           TransactionId, | 							 Server, TransactionId, Internal) {} | ||||||
|                                           Internal) {} | 		static auto PathName() { | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/connectedDevice/{serialNumber}"};} | 			return std::list<std::string>{"/api/v1/connectedDevice/{serialNumber}"}; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|         void DoGet() final; | 		void DoGet() final; | ||||||
|         void DoDelete() final {}; | 		void DoDelete() final{}; | ||||||
|         void DoPost() final {}; | 		void DoPost() final{}; | ||||||
|         void DoPut() final {}; | 		void DoPut() final{}; | ||||||
|     }; | 	}; | ||||||
| } | } // namespace OpenWifi | ||||||
|  |  | ||||||
| #endif //UCENTRALFMS_RESTAPI_CONNECTEDDEVICEHANDLER_H | #endif // UCENTRALFMS_RESTAPI_CONNECTEDDEVICEHANDLER_H | ||||||
|   | |||||||
| @@ -2,8 +2,8 @@ | |||||||
| // Created by stephane bourque on 2021-07-18. | // Created by stephane bourque on 2021-07-18. | ||||||
| // | // | ||||||
|  |  | ||||||
| #include "Poco/JSON/Object.h" |  | ||||||
| #include "Poco/JSON/Array.h" | #include "Poco/JSON/Array.h" | ||||||
|  | #include "Poco/JSON/Object.h" | ||||||
|  |  | ||||||
| #include "RESTAPI_connectedDevicesHandler.h" | #include "RESTAPI_connectedDevicesHandler.h" | ||||||
| #include "RESTObjects/RESTAPI_FMSObjects.h" | #include "RESTObjects/RESTAPI_FMSObjects.h" | ||||||
| @@ -11,20 +11,20 @@ | |||||||
| #include "framework/ow_constants.h" | #include "framework/ow_constants.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     void RESTAPI_connectedDevicesHandler::DoGet() { | 	void RESTAPI_connectedDevicesHandler::DoGet() { | ||||||
|         std::vector<FMSObjects::DeviceConnectionInformation> Devices; | 		std::vector<FMSObjects::DeviceConnectionInformation> Devices; | ||||||
|         Poco::JSON::Object AnswerObj; | 		Poco::JSON::Object AnswerObj; | ||||||
|         Poco::JSON::Array AnswerArr; | 		Poco::JSON::Array AnswerArr; | ||||||
|         if (StorageService()->DevicesDB().GetDevices(QB_.Offset, QB_.Limit, Devices)) { | 		if (StorageService()->DevicesDB().GetDevices(QB_.Offset, QB_.Limit, Devices)) { | ||||||
|             for (const auto &i:Devices) { | 			for (const auto &i : Devices) { | ||||||
|                 Poco::JSON::Object Obj; | 				Poco::JSON::Object Obj; | ||||||
|                 i.to_json(Obj); | 				i.to_json(Obj); | ||||||
|                 AnswerArr.add(Obj); | 				AnswerArr.add(Obj); | ||||||
|             } | 			} | ||||||
|             AnswerObj.set(RESTAPI::Protocol::DEVICES, AnswerArr); | 			AnswerObj.set(RESTAPI::Protocol::DEVICES, AnswerArr); | ||||||
|             return ReturnObject(AnswerObj); | 			return ReturnObject(AnswerObj); | ||||||
|         } | 		} | ||||||
|         AnswerObj.set(RESTAPI::Protocol::DEVICES, AnswerArr); | 		AnswerObj.set(RESTAPI::Protocol::DEVICES, AnswerArr); | ||||||
|         ReturnObject(AnswerObj); | 		ReturnObject(AnswerObj); | ||||||
|     } | 	} | ||||||
| } | } // namespace OpenWifi | ||||||
| @@ -5,27 +5,24 @@ | |||||||
| #ifndef UCENTRALFMS_RESTAPI_CONNECTEDDEVICESHANDLER_H | #ifndef UCENTRALFMS_RESTAPI_CONNECTEDDEVICESHANDLER_H | ||||||
| #define UCENTRALFMS_RESTAPI_CONNECTEDDEVICESHANDLER_H | #define UCENTRALFMS_RESTAPI_CONNECTEDDEVICESHANDLER_H | ||||||
|  |  | ||||||
|  | #include "framework/RESTAPI_Handler.h" | ||||||
| #include "framework/MicroService.h" |  | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_connectedDevicesHandler : public RESTAPIHandler { | 	class RESTAPI_connectedDevicesHandler : public RESTAPIHandler { | ||||||
|     public: | 	  public: | ||||||
|         RESTAPI_connectedDevicesHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | 		RESTAPI_connectedDevicesHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, | ||||||
|                 : RESTAPIHandler(bindings, L, | 										RESTAPI_GenericServerAccounting &Server, | ||||||
|                                  std::vector<std::string> | 										uint64_t TransactionId, bool Internal) | ||||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | 			: RESTAPIHandler(bindings, L, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_OPTIONS}, | 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                                           Server, | 													  Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
|                                           TransactionId, | 							 Server, TransactionId, Internal) {} | ||||||
|                                           Internal) {} | 		static auto PathName() { return std::list<std::string>{"/api/v1/connectedDevices"}; } | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/connectedDevices"};} | 		void DoGet() final; | ||||||
|         void DoGet()  final; | 		void DoDelete() final{}; | ||||||
|         void DoDelete() final {}; | 		void DoPost() final{}; | ||||||
|         void DoPost() final {}; | 		void DoPut() final{}; | ||||||
|         void DoPut() final {}; | 	}; | ||||||
|  | } // namespace OpenWifi | ||||||
|  |  | ||||||
|     }; | #endif // UCENTRALFMS_RESTAPI_CONNECTEDDEVICESHANDLER_H | ||||||
| } |  | ||||||
|  |  | ||||||
| #endif //UCENTRALFMS_RESTAPI_CONNECTEDDEVICESHANDLER_H |  | ||||||
|   | |||||||
| @@ -3,45 +3,45 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "RESTAPI_deviceInformation_handler.h" | #include "RESTAPI_deviceInformation_handler.h" | ||||||
| #include "StorageService.h" |  | ||||||
| #include "LatestFirmwareCache.h" | #include "LatestFirmwareCache.h" | ||||||
|  | #include "StorageService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     void RESTAPI_deviceInformation_handler::DoGet() { | 	void RESTAPI_deviceInformation_handler::DoGet() { | ||||||
|         auto SerialNumber = GetBinding("serialNumber",""); | 		auto SerialNumber = GetBinding("serialNumber", ""); | ||||||
|  |  | ||||||
|         if(SerialNumber.empty() || !Utils::ValidSerialNumber(SerialNumber)) { | 		if (SerialNumber.empty() || !Utils::ValidSerialNumber(SerialNumber)) { | ||||||
|             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | 			return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         FMSObjects::DeviceInformation   DI; | 		FMSObjects::DeviceInformation DI; | ||||||
|  |  | ||||||
|         //  Let's get the history | 		//  Let's get the history | ||||||
|         StorageService()->HistoryDB().GetHistory(SerialNumber,0,100,DI.history.history); | 		StorageService()->HistoryDB().GetHistory(SerialNumber, 0, 100, DI.history.history); | ||||||
|  |  | ||||||
|         // Let's get the DeviceConnectionInformation | 		// Let's get the DeviceConnectionInformation | ||||||
|         FMSObjects::DeviceConnectionInformation DCI; | 		FMSObjects::DeviceConnectionInformation DCI; | ||||||
|         StorageService()->DevicesDB().GetDevice(SerialNumber,DCI); | 		StorageService()->DevicesDB().GetDevice(SerialNumber, DCI); | ||||||
|  |  | ||||||
|         LatestFirmwareCacheEntry    LFE; | 		LatestFirmwareCacheEntry LFE; | ||||||
|         LatestFirmwareCache()->FindLatestFirmware(DCI.deviceType,LFE); | 		LatestFirmwareCache()->FindLatestFirmware(DCI.deviceType, LFE); | ||||||
|  |  | ||||||
|         FMSObjects::Firmware        Latest; | 		FMSObjects::Firmware Latest; | ||||||
|         StorageService()->FirmwaresDB().GetFirmware(LFE.Id,Latest); | 		StorageService()->FirmwaresDB().GetFirmware(LFE.Id, Latest); | ||||||
|  |  | ||||||
|         DI.serialNumber = SerialNumber; | 		DI.serialNumber = SerialNumber; | ||||||
|         DI.currentFirmware = DCI.revision; | 		DI.currentFirmware = DCI.revision; | ||||||
|         DI.latestFirmware = LFE.Revision; | 		DI.latestFirmware = LFE.Revision; | ||||||
|         DI.latestFirmwareDate = LFE.TimeStamp; | 		DI.latestFirmwareDate = LFE.TimeStamp; | ||||||
|         DI.latestFirmwareURI = Latest.uri; | 		DI.latestFirmwareURI = Latest.uri; | ||||||
|         FirmwaresDB::RecordName FI; | 		FirmwaresDB::RecordName FI; | ||||||
|         StorageService()->FirmwaresDB().GetFirmwareByRevision(DCI.revision,DCI.deviceType,FI); | 		StorageService()->FirmwaresDB().GetFirmwareByRevision(DCI.revision, DCI.deviceType, FI); | ||||||
|         DI.currentFirmwareDate = FI.imageDate; | 		DI.currentFirmwareDate = FI.imageDate; | ||||||
|  |  | ||||||
|         DI.latestFirmwareAvailable = (LFE.Revision != DCI.revision); | 		DI.latestFirmwareAvailable = (LFE.Revision != DCI.revision); | ||||||
|  |  | ||||||
|         Poco::JSON::Object  Answer; | 		Poco::JSON::Object Answer; | ||||||
|         DI.to_json(Answer); | 		DI.to_json(Answer); | ||||||
|         return ReturnObject(Answer); | 		return ReturnObject(Answer); | ||||||
|     } | 	} | ||||||
| } | } // namespace OpenWifi | ||||||
| @@ -4,23 +4,24 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" | #include "framework/RESTAPI_Handler.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_deviceInformation_handler : public RESTAPIHandler { | 	class RESTAPI_deviceInformation_handler : public RESTAPIHandler { | ||||||
|     public: | 	  public: | ||||||
|         RESTAPI_deviceInformation_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | 		RESTAPI_deviceInformation_handler(const RESTAPIHandler::BindingMap &bindings, | ||||||
|                 : RESTAPIHandler(bindings, L, | 										  Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, | ||||||
|                                  std::vector<std::string> | 										  uint64_t TransactionId, bool Internal) | ||||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | 			: RESTAPIHandler(bindings, L, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_OPTIONS}, | 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                                  Server, | 													  Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
|                                  TransactionId, | 							 Server, TransactionId, Internal) {} | ||||||
|                                  Internal) {} | 		static auto PathName() { | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/deviceInformation/{serialNumber}"};} | 			return std::list<std::string>{"/api/v1/deviceInformation/{serialNumber}"}; | ||||||
|         void DoGet()  final; | 		} | ||||||
|         void DoDelete() final {}; | 		void DoGet() final; | ||||||
|         void DoPost() final {}; | 		void DoDelete() final{}; | ||||||
|         void DoPut() final {}; | 		void DoPost() final{}; | ||||||
|     }; | 		void DoPut() final{}; | ||||||
| } | 	}; | ||||||
|  | } // namespace OpenWifi | ||||||
|   | |||||||
| @@ -3,15 +3,19 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "RESTAPI_deviceReportHandler.h" | #include "RESTAPI_deviceReportHandler.h" | ||||||
| #include "RESTObjects/RESTAPI_FMSObjects.h" |  | ||||||
| #include "Poco/JSON/Object.h" |  | ||||||
| #include "Daemon.h" | #include "Daemon.h" | ||||||
|  | #include "Poco/JSON/Object.h" | ||||||
|  | #include "RESTObjects/RESTAPI_FMSObjects.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     void RESTAPI_deviceReportHandler::DoGet() { | 	void RESTAPI_deviceReportHandler::DoGet() { | ||||||
|         Daemon()->CreateDashboard(); | 		poco_information(Logger(), fmt::format("GET-DASHBOARD: {}", Requester())); | ||||||
|         Poco::JSON::Object  O; | 		FMSObjects::DeviceReport Data; | ||||||
|         Daemon()->GetDashboard().to_json(O); | 		if (Daemon()->GetDashboard().Get(Data, Logger())) { | ||||||
|         ReturnObject(O); | 			Poco::JSON::Object Answer; | ||||||
|     } | 			Data.to_json(Answer); | ||||||
| } | 			return ReturnObject(Answer); | ||||||
|  | 		} | ||||||
|  | 		return BadRequest(RESTAPI::Errors::InternalError); | ||||||
|  | 	} | ||||||
|  | } // namespace OpenWifi | ||||||
| @@ -4,23 +4,22 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" | #include "framework/RESTAPI_Handler.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_deviceReportHandler : public RESTAPIHandler { | 	class RESTAPI_deviceReportHandler : public RESTAPIHandler { | ||||||
|     public: | 	  public: | ||||||
|         RESTAPI_deviceReportHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | 		RESTAPI_deviceReportHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, | ||||||
|                 : RESTAPIHandler(bindings, L, | 									RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, | ||||||
|                                  std::vector<std::string> | 									bool Internal) | ||||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | 			: RESTAPIHandler(bindings, L, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_OPTIONS}, | 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                                           Server, | 													  Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
|                                           TransactionId, | 							 Server, TransactionId, Internal) {} | ||||||
|                                  Internal) {} | 		static auto PathName() { return std::list<std::string>{"/api/v1/deviceReport"}; } | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/deviceReport"};} | 		void DoGet() final; | ||||||
|         void DoGet()  final; | 		void DoDelete() final{}; | ||||||
|         void DoDelete() final {}; | 		void DoPost() final{}; | ||||||
|         void DoPost() final {}; | 		void DoPut() final{}; | ||||||
|         void DoPut() final {}; | 	}; | ||||||
|     }; | } // namespace OpenWifi | ||||||
| } |  | ||||||
|   | |||||||
| @@ -4,56 +4,57 @@ | |||||||
|  |  | ||||||
| #include "RESTAPI_firmwareAgeHandler.h" | #include "RESTAPI_firmwareAgeHandler.h" | ||||||
|  |  | ||||||
| #include "StorageService.h" |  | ||||||
| #include "Poco/JSON/Parser.h" |  | ||||||
| #include "DeviceCache.h" | #include "DeviceCache.h" | ||||||
|  | #include "Poco/JSON/Parser.h" | ||||||
|  | #include "StorageService.h" | ||||||
| #include "framework/ow_constants.h" | #include "framework/ow_constants.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     void RESTAPI_firmwareAgeHandler::DoGet() { | 	void RESTAPI_firmwareAgeHandler::DoGet() { | ||||||
|         if (!QB_.Select.empty()) { | 		if (!QB_.Select.empty()) { | ||||||
|             Poco::JSON::Array Objects; | 			Poco::JSON::Array Objects; | ||||||
|             for (auto &i : SelectedRecords()) { | 			for (auto &i : SelectedRecords()) { | ||||||
|                 DeviceCacheEntry E; | 				DeviceCacheEntry E; | ||||||
|                 if (DeviceCache()->GetDevice(i, E)) { | 				if (DeviceCache()->GetDevice(i, E)) { | ||||||
|                     FMSObjects::FirmwareAgeDetails FA; | 					FMSObjects::FirmwareAgeDetails FA; | ||||||
|                     if(StorageService()->FirmwaresDB().ComputeFirmwareAge(E.deviceType,E.revision,FA)) { | 					if (StorageService()->FirmwaresDB().ComputeFirmwareAge(E.deviceType, E.revision, | ||||||
|                         Poco::JSON::Object  O; | 																		   FA)) { | ||||||
|                         FA.to_json(O); | 						Poco::JSON::Object O; | ||||||
|                         O.set(uCentralProtocol::SERIALNUMBER,i); | 						FA.to_json(O); | ||||||
|                         Objects.add(O); | 						O.set(uCentralProtocol::SERIALNUMBER, i); | ||||||
|                     } else { | 						Objects.add(O); | ||||||
|                         Poco::JSON::Object  O; | 					} else { | ||||||
|                         O.set(uCentralProtocol::SERIALNUMBER,i); | 						Poco::JSON::Object O; | ||||||
|                         Objects.add(O); | 						O.set(uCentralProtocol::SERIALNUMBER, i); | ||||||
|                     } | 						Objects.add(O); | ||||||
|                 } else { | 					} | ||||||
|                     Poco::JSON::Object  O; | 				} else { | ||||||
|                     O.set(uCentralProtocol::SERIALNUMBER,i); | 					Poco::JSON::Object O; | ||||||
|                     Objects.add(O); | 					O.set(uCentralProtocol::SERIALNUMBER, i); | ||||||
|                 } | 					Objects.add(O); | ||||||
|             } | 				} | ||||||
|             Poco::JSON::Object Answer; | 			} | ||||||
|             Answer.set(RESTAPI::Protocol::AGES, Objects); | 			Poco::JSON::Object Answer; | ||||||
|             return ReturnObject(Answer); | 			Answer.set(RESTAPI::Protocol::AGES, Objects); | ||||||
|         } else { | 			return ReturnObject(Answer); | ||||||
|             auto DeviceType = GetParameter(RESTAPI::Protocol::DEVICETYPE, ""); | 		} else { | ||||||
|             auto Revision = GetParameter(RESTAPI::Protocol::REVISION, ""); | 			auto DeviceType = ORM::Escape(GetParameter(RESTAPI::Protocol::DEVICETYPE, "")); | ||||||
|  | 			auto Revision = ORM::Escape(GetParameter(RESTAPI::Protocol::REVISION, "")); | ||||||
|  |  | ||||||
|             if (DeviceType.empty() || Revision.empty()) { | 			if (DeviceType.empty() || Revision.empty()) { | ||||||
|                 return BadRequest(RESTAPI::Errors::BothDeviceTypeRevision); | 				return BadRequest(RESTAPI::Errors::BothDeviceTypeRevision); | ||||||
|             } | 			} | ||||||
|  |  | ||||||
|             Revision = Storage::TrimRevision(Revision); | 			Revision = Storage::TrimRevision(Revision); | ||||||
|  |  | ||||||
|             FMSObjects::FirmwareAgeDetails FA; | 			FMSObjects::FirmwareAgeDetails FA; | ||||||
|             if (StorageService()->FirmwaresDB().ComputeFirmwareAge(DeviceType, Revision, FA)) { | 			if (StorageService()->FirmwaresDB().ComputeFirmwareAge(DeviceType, Revision, FA)) { | ||||||
|                 Poco::JSON::Object Answer; | 				Poco::JSON::Object Answer; | ||||||
|  |  | ||||||
|                 FA.to_json(Answer); | 				FA.to_json(Answer); | ||||||
|                 return ReturnObject(Answer); | 				return ReturnObject(Answer); | ||||||
|             } | 			} | ||||||
|             NotFound(); | 			NotFound(); | ||||||
|         } | 		} | ||||||
|     } | 	} | ||||||
| } | } // namespace OpenWifi | ||||||
| @@ -5,25 +5,24 @@ | |||||||
| #ifndef UCENTRALFMS_RESTAPI_FIRMWAREAGEHANDLER_H | #ifndef UCENTRALFMS_RESTAPI_FIRMWAREAGEHANDLER_H | ||||||
| #define UCENTRALFMS_RESTAPI_FIRMWAREAGEHANDLER_H | #define UCENTRALFMS_RESTAPI_FIRMWAREAGEHANDLER_H | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" | #include "framework/RESTAPI_Handler.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_firmwareAgeHandler : public RESTAPIHandler { | 	class RESTAPI_firmwareAgeHandler : public RESTAPIHandler { | ||||||
|     public: | 	  public: | ||||||
|         RESTAPI_firmwareAgeHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | 		RESTAPI_firmwareAgeHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, | ||||||
|                 : RESTAPIHandler(bindings, L, | 								   RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, | ||||||
|                                  std::vector<std::string> | 								   bool Internal) | ||||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | 			: RESTAPIHandler(bindings, L, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_OPTIONS}, | 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                                           Server, | 													  Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
|                                           TransactionId, | 							 Server, TransactionId, Internal) {} | ||||||
|                                           Internal) {} | 		static auto PathName() { return std::list<std::string>{"/api/v1/firmwareAge"}; } | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/firmwareAge"};} | 		void DoGet() final; | ||||||
|         void DoGet()  final; | 		void DoDelete() final{}; | ||||||
|         void DoDelete() final {}; | 		void DoPost() final{}; | ||||||
|         void DoPost() final {}; | 		void DoPut() final{}; | ||||||
|         void DoPut() final {}; | 	}; | ||||||
|     }; | } // namespace OpenWifi | ||||||
| } |  | ||||||
|  |  | ||||||
| #endif //UCENTRALFMS_RESTAPI_FIRMWAREAGEHANDLER_H | #endif // UCENTRALFMS_RESTAPI_FIRMWAREAGEHANDLER_H | ||||||
|   | |||||||
| @@ -4,90 +4,92 @@ | |||||||
|  |  | ||||||
| #include "Poco/JSON/Parser.h" | #include "Poco/JSON/Parser.h" | ||||||
|  |  | ||||||
| #include "RESTAPI_firmwareHandler.h" | #include "RESTAPI/RESTAPI_firmwareHandler.h" | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
|  | #include "framework/MicroServiceFuncs.h" | ||||||
| #include "framework/ow_constants.h" | #include "framework/ow_constants.h" | ||||||
|  | #include "framework/utils.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     void | 	void RESTAPI_firmwareHandler::DoPost() { | ||||||
|     RESTAPI_firmwareHandler::DoPost() { | 		const auto &Obj = ParsedBody_; | ||||||
|         const auto &Obj = ParsedBody_; | 		FMSObjects::Firmware F; | ||||||
|         FMSObjects::Firmware F; | 		if (!F.from_json(Obj)) { | ||||||
|         if (!F.from_json(Obj)) { | 			return BadRequest(RESTAPI::Errors::InvalidJSONDocument); | ||||||
|             return BadRequest(RESTAPI::Errors::InvalidJSONDocument); | 		} | ||||||
|         } | 		F.id = MicroServiceCreateUUID(); | ||||||
|         F.id = MicroService::instance().CreateUUID(); | 		if (StorageService()->FirmwaresDB().AddFirmware(F)) { | ||||||
|         if(StorageService()->FirmwaresDB().AddFirmware(F)) { | 			Poco::JSON::Object Answer; | ||||||
|             Poco::JSON::Object  Answer; | 			F.to_json(Answer); | ||||||
|             F.to_json(Answer); | 			return ReturnObject(Answer); | ||||||
|             return ReturnObject(Answer); | 		} | ||||||
|         } | 		BadRequest(RESTAPI::Errors::RecordNotCreated); | ||||||
|         BadRequest(RESTAPI::Errors::RecordNotCreated); | 	} | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void | 	void RESTAPI_firmwareHandler::DoGet() { | ||||||
|     RESTAPI_firmwareHandler::DoGet() { | 		auto UUID = GetBinding(uCentralProtocol::ID, ""); | ||||||
|         auto UUID = GetBinding(uCentralProtocol::ID, ""); |  | ||||||
|  |  | ||||||
|         if(UUID.empty()) { | 		if (UUID.empty()) { | ||||||
|             return BadRequest(RESTAPI::Errors::MissingUUID); | 			return BadRequest(RESTAPI::Errors::MissingUUID); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         FMSObjects::Firmware F; | 		FMSObjects::Firmware F; | ||||||
|         if (StorageService()->FirmwaresDB().GetFirmware(UUID, F)) { | 		if (StorageService()->FirmwaresDB().GetFirmware(UUID, F)) { | ||||||
|             Poco::JSON::Object Object; | 			Poco::JSON::Object Object; | ||||||
|             F.to_json(Object); | 			F.to_json(Object); | ||||||
|             return ReturnObject(Object); | 			return ReturnObject(Object); | ||||||
|         } | 		} | ||||||
|         NotFound(); | 		NotFound(); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void | 	void RESTAPI_firmwareHandler::DoDelete() { | ||||||
|     RESTAPI_firmwareHandler::DoDelete() { | 		auto UUID = GetBinding(uCentralProtocol::ID, ""); | ||||||
|         auto UUID = GetBinding(uCentralProtocol::ID, ""); | 		if (UUID.empty()) { | ||||||
|         if(UUID.empty()) { | 			return BadRequest(RESTAPI::Errors::MissingUUID); | ||||||
|             return BadRequest(RESTAPI::Errors::MissingUUID); | 		} | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if (StorageService()->FirmwaresDB().DeleteFirmware(UUID)) { | 		if (StorageService()->FirmwaresDB().DeleteFirmware(UUID)) { | ||||||
|             return OK(); | 			return OK(); | ||||||
|         } | 		} | ||||||
|         BadRequest(RESTAPI::Errors::CouldNotBeDeleted); | 		BadRequest(RESTAPI::Errors::CouldNotBeDeleted); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void RESTAPI_firmwareHandler::DoPut() { | 	void RESTAPI_firmwareHandler::DoPut() { | ||||||
|         auto UUID = GetBinding(uCentralProtocol::ID, ""); | 		auto UUID = GetBinding(uCentralProtocol::ID, ""); | ||||||
|         if(UUID.empty()) { | 		if (UUID.empty()) { | ||||||
|             return BadRequest(RESTAPI::Errors::MissingUUID); | 			return BadRequest(RESTAPI::Errors::MissingUUID); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         FMSObjects::Firmware    F; | 		FMSObjects::Firmware F; | ||||||
|         if(!StorageService()->FirmwaresDB().GetFirmware(UUID, F)) { | 		if (!StorageService()->FirmwaresDB().GetFirmware(UUID, F)) { | ||||||
|             return NotFound(); | 			return NotFound(); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         const auto & Obj = ParsedBody_; | 		const auto &Obj = ParsedBody_; | ||||||
|         FMSObjects::Firmware    NewFirmware; | 		FMSObjects::Firmware NewFirmware; | ||||||
|         if(!NewFirmware.from_json(Obj)) { | 		if (!NewFirmware.from_json(Obj)) { | ||||||
|             return BadRequest(RESTAPI::Errors::InvalidJSONDocument); | 			return BadRequest(RESTAPI::Errors::InvalidJSONDocument); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         if(Obj->has(RESTAPI::Protocol::DESCRIPTION)) | 		if (Obj->has(RESTAPI::Protocol::DESCRIPTION)) | ||||||
|             F.description = Obj->get(RESTAPI::Protocol::DESCRIPTION).toString(); | 			F.description = Obj->get(RESTAPI::Protocol::DESCRIPTION).toString(); | ||||||
|         if(Obj->has(RESTAPI::Protocol::NOTES)) { | 		if (Obj->has(RESTAPI::Protocol::NOTES)) { | ||||||
|             SecurityObjects::NoteInfoVec NIV; | 			SecurityObjects::NoteInfoVec NIV; | ||||||
|             NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(Obj->get(RESTAPI::Protocol::NOTES).toString()); | 			NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>( | ||||||
|             for(auto const &i:NIV) { | 				Obj->get(RESTAPI::Protocol::NOTES).toString()); | ||||||
|                 SecurityObjects::NoteInfo   ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UserInfo_.userinfo.email, .note=i.note}; | 			for (auto const &i : NIV) { | ||||||
|                 F.notes.push_back(ii); | 				SecurityObjects::NoteInfo ii{.created = (uint64_t)Utils::Now(), | ||||||
|             } | 											 .createdBy = UserInfo_.userinfo.email, | ||||||
|         } | 											 .note = i.note}; | ||||||
|  | 				F.notes.push_back(ii); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|         if(StorageService()->FirmwaresDB().UpdateFirmware(UUID, F)) { | 		if (StorageService()->FirmwaresDB().UpdateFirmware(UUID, F)) { | ||||||
|             Poco::JSON::Object  Answer; | 			Poco::JSON::Object Answer; | ||||||
|             F.to_json(Answer); | 			F.to_json(Answer); | ||||||
|             return ReturnObject(Answer); | 			return ReturnObject(Answer); | ||||||
|         } | 		} | ||||||
|         BadRequest(RESTAPI::Errors::RecordNotUpdated); | 		BadRequest(RESTAPI::Errors::RecordNotUpdated); | ||||||
|     } | 	} | ||||||
| } | } // namespace OpenWifi | ||||||
| @@ -5,28 +5,27 @@ | |||||||
| #ifndef UCENTRALFWS_RESTAPI_FIRMWAREHANDLER_H | #ifndef UCENTRALFWS_RESTAPI_FIRMWAREHANDLER_H | ||||||
| #define UCENTRALFWS_RESTAPI_FIRMWAREHANDLER_H | #define UCENTRALFWS_RESTAPI_FIRMWAREHANDLER_H | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" | #include "framework/RESTAPI_Handler.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_firmwareHandler : public RESTAPIHandler { | 	class RESTAPI_firmwareHandler : public RESTAPIHandler { | ||||||
|     public: | 	  public: | ||||||
|         RESTAPI_firmwareHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | 		RESTAPI_firmwareHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, | ||||||
|                 : RESTAPIHandler(bindings, L, | 								RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, | ||||||
|                                  std::vector<std::string> | 								bool Internal) | ||||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | 			: RESTAPIHandler(bindings, L, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_POST, | 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_PUT, | 													  Poco::Net::HTTPRequest::HTTP_POST, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_DELETE, | 													  Poco::Net::HTTPRequest::HTTP_PUT, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_OPTIONS}, | 													  Poco::Net::HTTPRequest::HTTP_DELETE, | ||||||
|                                           Server, | 													  Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
|                                           TransactionId, | 							 Server, TransactionId, Internal) {} | ||||||
|                                           Internal) {} | 		static auto PathName() { return std::list<std::string>{"/api/v1/firmware/{id}"}; } | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/firmware/{id}"};} | 		void DoGet() final; | ||||||
|         void DoGet()  final; | 		void DoDelete() final; | ||||||
|         void DoDelete() final; | 		void DoPost() final; | ||||||
|         void DoPost() final; | 		void DoPut() final; | ||||||
|         void DoPut() final; | 	}; | ||||||
|     }; | } // namespace OpenWifi | ||||||
| } |  | ||||||
|  |  | ||||||
| #endif //UCENTRALFWS_RESTAPI_FIRMWAREHANDLER_H | #endif // UCENTRALFWS_RESTAPI_FIRMWAREHANDLER_H | ||||||
|   | |||||||
| @@ -3,102 +3,124 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "RESTAPI_firmwaresHandler.h" | #include "RESTAPI_firmwaresHandler.h" | ||||||
| #include "StorageService.h" |  | ||||||
| #include "LatestFirmwareCache.h" | #include "LatestFirmwareCache.h" | ||||||
|  | #include "StorageService.h" | ||||||
| #include "framework/ow_constants.h" | #include "framework/ow_constants.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     void | 	void RESTAPI_firmwaresHandler::DoGet() { | ||||||
|     RESTAPI_firmwaresHandler::DoGet() { | 		std::string DeviceType = ORM::Escape(GetParameter(RESTAPI::Protocol::DEVICETYPE, "")); | ||||||
|         std::string DeviceType = GetParameter(RESTAPI::Protocol::DEVICETYPE, ""); | 		bool IdOnly = GetBoolParameter(RESTAPI::Protocol::IDONLY); | ||||||
|         bool IdOnly = GetBoolParameter(RESTAPI::Protocol::IDONLY); | 		bool LatestOnly = GetBoolParameter(RESTAPI::Protocol::LATESTONLY); | ||||||
|         bool LatestOnly = GetBoolParameter(RESTAPI::Protocol::LATESTONLY); | 		bool rcOnly = GetBoolParameter("rcOnly"); | ||||||
|         bool rcOnly = GetBoolParameter("rcOnly"); |  | ||||||
|  |  | ||||||
|         if(GetBoolParameter(RESTAPI::Protocol::DEVICESET)) { | 		if (GetBoolParameter("updateTimeOnly")) { | ||||||
|             auto Revisions = LatestFirmwareCache()->GetDevices(); | 			Poco::JSON::Object Answer; | ||||||
|             Poco::JSON::Array ObjectArray; | 			Answer.set("lastUpdateTime", ManifestCreator()->LastUpdate()); | ||||||
|             for (const auto &i:Revisions) { | 			return ReturnObject(Answer); | ||||||
|                 ObjectArray.add(i); | 		} | ||||||
|             } |  | ||||||
|             Poco::JSON::Object RetObj; |  | ||||||
|             RetObj.set(RESTAPI::Protocol::DEVICETYPES, ObjectArray); |  | ||||||
|             return ReturnObject(RetObj); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if(GetBoolParameter(RESTAPI::Protocol::REVISIONSET)) { | 		if (GetBoolParameter(RESTAPI::Protocol::DEVICESET)) { | ||||||
|             auto Revisions = LatestFirmwareCache()->GetRevisions(); | 			auto Revisions = LatestFirmwareCache()->GetDevices(); | ||||||
|             Poco::JSON::Array ObjectArray; | 			Poco::JSON::Array ObjectArray; | ||||||
|             for (const auto &i:Revisions) { | 			for (const auto &i : Revisions) { | ||||||
|                 ObjectArray.add(i); | 				ObjectArray.add(i); | ||||||
|             } | 			} | ||||||
|             Poco::JSON::Object RetObj; | 			Poco::JSON::Object RetObj; | ||||||
|             RetObj.set(RESTAPI::Protocol::REVISIONS, ObjectArray); | 			RetObj.set(RESTAPI::Protocol::DEVICETYPES, ObjectArray); | ||||||
|             return ReturnObject(RetObj); | 			return ReturnObject(RetObj); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         // special cases: if latestOnly and deviceType | 		if (GetBoolParameter(RESTAPI::Protocol::REVISIONSET)) { | ||||||
|         if(!DeviceType.empty()) { | 			auto Revisions = LatestFirmwareCache()->GetRevisions(); | ||||||
|             if(LatestOnly) { | 			Poco::JSON::Array ObjectArray; | ||||||
|                 LatestFirmwareCacheEntry    Entry; | 			for (const auto &i : Revisions) { | ||||||
|                 if(rcOnly) { | 				ObjectArray.add(i); | ||||||
|                     if (!LatestFirmwareCache()->FindLatestRCOnlyFirmware(DeviceType, Entry)) { | 			} | ||||||
|                         return NotFound(); | 			Poco::JSON::Object RetObj; | ||||||
|                     } | 			RetObj.set(RESTAPI::Protocol::REVISIONS, ObjectArray); | ||||||
|                 } else { | 			return ReturnObject(RetObj); | ||||||
|                     if (!LatestFirmwareCache()->FindLatestFirmware(DeviceType, Entry)) { | 		} | ||||||
|                         return NotFound(); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 FMSObjects::Firmware    F; | 		// special cases: if latestOnly and deviceType | ||||||
|                 if(StorageService()->FirmwaresDB().GetFirmware(Entry.Id,F)) { | 		if (!DeviceType.empty()) { | ||||||
|                     Poco::JSON::Object  Answer; | 			if (LatestOnly) { | ||||||
|                     F.to_json(Answer); | 				LatestFirmwareCacheEntry Entry; | ||||||
|                     return ReturnObject(Answer); | 				if (rcOnly) { | ||||||
|                 } | 					if (!LatestFirmwareCache()->FindLatestRCOnlyFirmware(DeviceType, Entry)) { | ||||||
|                 return NotFound(); | 						return NotFound(); | ||||||
|             } else { | 					} | ||||||
|                 std::vector<FMSObjects::Firmware> List; | 				} else { | ||||||
|                 if (StorageService()->FirmwaresDB().GetFirmwares(QB_.Offset, QB_.Limit, DeviceType, List)) { | 					if (!LatestFirmwareCache()->FindLatestFirmware(DeviceType, Entry)) { | ||||||
|                     Poco::JSON::Array ObjectArray; | 						return NotFound(); | ||||||
|                     for (const auto &i:List) { | 					} | ||||||
|                         if(rcOnly && !LatestFirmwareCache::IsRC(i.revision)) | 				} | ||||||
|                             continue; |  | ||||||
|                         if(IdOnly) { |  | ||||||
|                             ObjectArray.add(i.id); |  | ||||||
|                         } else { |  | ||||||
|                             Poco::JSON::Object Obj; |  | ||||||
|                             i.to_json(Obj); |  | ||||||
|                             ObjectArray.add(Obj); |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                     Poco::JSON::Object RetObj; |  | ||||||
|                     RetObj.set(RESTAPI::Protocol::FIRMWARES, ObjectArray); |  | ||||||
|                     return ReturnObject(RetObj); |  | ||||||
|                 } else { |  | ||||||
|                     return NotFound(); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         std::vector<FMSObjects::Firmware> List; | 				FMSObjects::Firmware F; | ||||||
|         Poco::JSON::Array ObjectArray; | 				if (StorageService()->FirmwaresDB().GetFirmware(Entry.Id, F)) { | ||||||
|         Poco::JSON::Object Answer; | 					Poco::JSON::Object Answer; | ||||||
|         if (StorageService()->FirmwaresDB().GetFirmwares(QB_.Offset, QB_.Limit, DeviceType, List)) { | 					F.to_json(Answer); | ||||||
|             for (const auto &i:List) { | 					return ReturnObject(Answer); | ||||||
|                 if(rcOnly && !LatestFirmwareCache::IsRC(i.revision)) | 				} | ||||||
|                     continue; | 				return NotFound(); | ||||||
|                 if(IdOnly) { | 			} else { | ||||||
|                     ObjectArray.add(i.id); | 				std::vector<FMSObjects::Firmware> List; | ||||||
|                 } else { | 				if (StorageService()->FirmwaresDB().GetFirmwares(QB_.Offset, QB_.Limit, DeviceType, | ||||||
|                     Poco::JSON::Object Obj; | 																 List)) { | ||||||
|                     i.to_json(Obj); | 					Poco::JSON::Array ObjectArray; | ||||||
|                     ObjectArray.add(Obj); | 					for (const auto &i : List) { | ||||||
|                 } | 						if (rcOnly && !LatestFirmwareCache::IsRC(i.revision)) | ||||||
|             } | 							continue; | ||||||
|         } | 						if (IdOnly) { | ||||||
|         Answer.set(RESTAPI::Protocol::FIRMWARES, ObjectArray); | 							ObjectArray.add(i.id); | ||||||
|         ReturnObject(Answer); | 						} else { | ||||||
|     } | 							Poco::JSON::Object Obj; | ||||||
| } | 							i.to_json(Obj); | ||||||
|  | 							ObjectArray.add(Obj); | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 					Poco::JSON::Object RetObj; | ||||||
|  | 					RetObj.set(RESTAPI::Protocol::FIRMWARES, ObjectArray); | ||||||
|  | 					return ReturnObject(RetObj); | ||||||
|  | 				} else { | ||||||
|  | 					return NotFound(); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		std::vector<FMSObjects::Firmware> List; | ||||||
|  | 		Poco::JSON::Array ObjectArray; | ||||||
|  | 		Poco::JSON::Object Answer; | ||||||
|  | 		if (StorageService()->FirmwaresDB().GetFirmwares(QB_.Offset, QB_.Limit, DeviceType, List)) { | ||||||
|  | 			for (const auto &i : List) { | ||||||
|  | 				if (rcOnly && !LatestFirmwareCache::IsRC(i.revision)) | ||||||
|  | 					continue; | ||||||
|  | 				if (IdOnly) { | ||||||
|  | 					ObjectArray.add(i.id); | ||||||
|  | 				} else { | ||||||
|  | 					Poco::JSON::Object Obj; | ||||||
|  | 					i.to_json(Obj); | ||||||
|  | 					ObjectArray.add(Obj); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 		Answer.set(RESTAPI::Protocol::FIRMWARES, ObjectArray); | ||||||
|  | 		ReturnObject(Answer); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void RESTAPI_firmwaresHandler::DoPut() { | ||||||
|  | 		if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT && | ||||||
|  | 			UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) { | ||||||
|  | 			return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if (GetBoolParameter("update")) { | ||||||
|  | 			if (ManifestCreator()->RunUpdateTask()) { | ||||||
|  | 				return OK(); | ||||||
|  | 			} | ||||||
|  | 			return BadRequest(RESTAPI::Errors::FirmwareBDInProgress); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||||
|  | 	} | ||||||
|  | } // namespace OpenWifi | ||||||
|   | |||||||
| @@ -5,26 +5,26 @@ | |||||||
| #ifndef UCENTRALFWS_RESTAPI_FIRMWARESHANDLER_H | #ifndef UCENTRALFWS_RESTAPI_FIRMWARESHANDLER_H | ||||||
| #define UCENTRALFWS_RESTAPI_FIRMWARESHANDLER_H | #define UCENTRALFWS_RESTAPI_FIRMWARESHANDLER_H | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" | #include "framework/RESTAPI_Handler.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_firmwaresHandler : public RESTAPIHandler { | 	class RESTAPI_firmwaresHandler : public RESTAPIHandler { | ||||||
|     public: | 	  public: | ||||||
|         RESTAPI_firmwaresHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | 		RESTAPI_firmwaresHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, | ||||||
|                 : RESTAPIHandler(bindings, L, | 								 RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, | ||||||
|                                  std::vector<std::string> | 								 bool Internal) | ||||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | 			: RESTAPIHandler(bindings, L, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_OPTIONS}, | 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                                           Server, | 													  Poco::Net::HTTPRequest::HTTP_PUT, | ||||||
|                                           TransactionId, | 													  Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
|                                           Internal) {} | 							 Server, TransactionId, Internal) {} | ||||||
|  |  | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/firmwares"};} | 		static auto PathName() { return std::list<std::string>{"/api/v1/firmwares"}; } | ||||||
|         void DoGet()  final; | 		void DoGet() final; | ||||||
|         void DoDelete() final {}; | 		void DoDelete() final{}; | ||||||
|         void DoPost() final {}; | 		void DoPost() final{}; | ||||||
|         void DoPut() final {}; | 		void DoPut() final; | ||||||
|     }; | 	}; | ||||||
| } | } // namespace OpenWifi | ||||||
|  |  | ||||||
| #endif //UCENTRALFWS_RESTAPI_FIRMWARESHANDLER_H | #endif // UCENTRALFWS_RESTAPI_FIRMWARESHANDLER_H | ||||||
|   | |||||||
| @@ -7,59 +7,59 @@ | |||||||
| #include "framework/ow_constants.h" | #include "framework/ow_constants.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     void | 	void RESTAPI_historyHandler::DoGet() { | ||||||
|     RESTAPI_historyHandler::DoGet() { | 		auto SerialNumber = ORM::Escape(GetBinding(RESTAPI::Protocol::SERIALNUMBER, "")); | ||||||
|         auto SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, ""); |  | ||||||
|  |  | ||||||
|         if(SerialNumber.empty()) { | 		if (SerialNumber.empty()) { | ||||||
|             return BadRequest(RESTAPI::Errors::MissingSerialNumber); | 			return BadRequest(RESTAPI::Errors::MissingSerialNumber); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         auto unknownList = GetBoolParameter("unknownList"); | 		auto unknownList = GetBoolParameter("unknownList"); | ||||||
|         if(SerialNumber=="000000000000" && unknownList) { | 		if (SerialNumber == "000000000000" && unknownList) { | ||||||
|             // so let's get all the devices, filter the latest record | 			// so let's get all the devices, filter the latest record | ||||||
|             FMSObjects::DeviceCurrentInfoList   L; | 			FMSObjects::DeviceCurrentInfoList L; | ||||||
|             StorageService()->HistoryDB().GetUnknownDeviceFirmwares(QB_.Offset,QB_.Limit,L.devices); | 			StorageService()->HistoryDB().GetUnknownDeviceFirmwares(QB_.Offset, QB_.Limit, | ||||||
|             Poco::JSON::Object  Answer; | 																	L.devices); | ||||||
|             L.to_json(Answer); | 			Poco::JSON::Object Answer; | ||||||
|             return ReturnObject(Answer); | 			L.to_json(Answer); | ||||||
|         } | 			return ReturnObject(Answer); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|         auto currentList = GetBoolParameter("currentList"); | 		auto currentList = GetBoolParameter("currentList"); | ||||||
|         if(SerialNumber=="000000000000" && currentList) { | 		if (SerialNumber == "000000000000" && currentList) { | ||||||
|             // so let's get all the devices, filter the latest record | 			// so let's get all the devices, filter the latest record | ||||||
|             FMSObjects::DeviceCurrentInfoList   L; | 			FMSObjects::DeviceCurrentInfoList L; | ||||||
|             StorageService()->HistoryDB().GetDeviceFirmwares(QB_.Offset,QB_.Limit,L.devices); | 			StorageService()->HistoryDB().GetDeviceFirmwares(QB_.Offset, QB_.Limit, L.devices); | ||||||
|             Poco::JSON::Object  Answer; | 			Poco::JSON::Object Answer; | ||||||
|             L.to_json(Answer); | 			L.to_json(Answer); | ||||||
|             return ReturnObject(Answer); | 			return ReturnObject(Answer); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         FMSObjects::RevisionHistoryEntryVec H; | 		FMSObjects::RevisionHistoryEntryVec H; | ||||||
|         if (StorageService()->HistoryDB().GetHistory(SerialNumber, QB_.Offset, QB_.Limit, H)) { | 		if (StorageService()->HistoryDB().GetHistory(SerialNumber, QB_.Offset, QB_.Limit, H)) { | ||||||
|             Poco::JSON::Array A; | 			Poco::JSON::Array A; | ||||||
|             for (auto const &i:H) { | 			for (auto const &i : H) { | ||||||
|                 Poco::JSON::Object O; | 				Poco::JSON::Object O; | ||||||
|                 i.to_json(O); | 				i.to_json(O); | ||||||
|                 A.add(O); | 				A.add(O); | ||||||
|             } | 			} | ||||||
|             Poco::JSON::Object Answer; | 			Poco::JSON::Object Answer; | ||||||
|             Answer.set(RESTAPI::Protocol::HISTORY, A); | 			Answer.set(RESTAPI::Protocol::HISTORY, A); | ||||||
|             return ReturnObject(Answer); | 			return ReturnObject(Answer); | ||||||
|         } | 		} | ||||||
|         NotFound(); | 		NotFound(); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void RESTAPI_historyHandler::DoDelete() { | 	void RESTAPI_historyHandler::DoDelete() { | ||||||
|         auto SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, ""); | 		auto SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, ""); | ||||||
|         auto Id = GetParameter(RESTAPI::Protocol::ID, ""); | 		auto Id = GetParameter(RESTAPI::Protocol::ID, ""); | ||||||
|         if (SerialNumber.empty() || Id.empty()) { | 		if (SerialNumber.empty() || Id.empty()) { | ||||||
|             return BadRequest(RESTAPI::Errors::IdOrSerialEmpty); | 			return BadRequest(RESTAPI::Errors::IdOrSerialEmpty); | ||||||
|         } | 		} | ||||||
|  |  | ||||||
|         if (!StorageService()->HistoryDB().DeleteHistory(SerialNumber, Id)) { | 		if (!StorageService()->HistoryDB().DeleteHistory(SerialNumber, Id)) { | ||||||
|             return OK(); | 			return OK(); | ||||||
|         } | 		} | ||||||
|         NotFound(); | 		NotFound(); | ||||||
|     } | 	} | ||||||
| } | } // namespace OpenWifi | ||||||
| @@ -4,24 +4,25 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" | #include "framework/RESTAPI_Handler.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_historyHandler : public RESTAPIHandler { | 	class RESTAPI_historyHandler : public RESTAPIHandler { | ||||||
|     public: | 	  public: | ||||||
|         RESTAPI_historyHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | 		RESTAPI_historyHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, | ||||||
|                 : RESTAPIHandler(bindings, L, | 							   RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, | ||||||
|                                  std::vector<std::string> | 							   bool Internal) | ||||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | 			: RESTAPIHandler(bindings, L, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_DELETE, | 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_OPTIONS}, | 													  Poco::Net::HTTPRequest::HTTP_DELETE, | ||||||
|                                           Server, | 													  Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
|                                           TransactionId, | 							 Server, TransactionId, Internal) {} | ||||||
|                                           Internal) {} | 		static auto PathName() { | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/revisionHistory/{serialNumber}"};} | 			return std::list<std::string>{"/api/v1/revisionHistory/{serialNumber}"}; | ||||||
|         void DoGet()  final; | 		} | ||||||
|         void DoDelete() final; | 		void DoGet() final; | ||||||
|         void DoPost() final {}; | 		void DoDelete() final; | ||||||
|         void DoPut() final {}; | 		void DoPost() final{}; | ||||||
|     }; | 		void DoPut() final{}; | ||||||
| } | 	}; | ||||||
|  | } // namespace OpenWifi | ||||||
|   | |||||||
| @@ -5,418 +5,339 @@ | |||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "RESTAPI_ProvObjects.h" | #include "RESTAPI_ProvObjects.h" | ||||||
|  | #include "framework/utils.h" | ||||||
| #include <vector> | #include <vector> | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     namespace AnalyticsObjects { | 	namespace AnalyticsObjects { | ||||||
|  |  | ||||||
|         struct Report { | 		struct Report { | ||||||
|             uint64_t snapShot = 0; | 			uint64_t snapShot = 0; | ||||||
|  |  | ||||||
|             void reset(); | 			void reset(); | ||||||
|  |  | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         }; | 		}; | ||||||
|  |  | ||||||
|         struct VenueInfo { | 		struct VenueInfo { | ||||||
|             OpenWifi::Types::UUID_t id; | 			OpenWifi::Types::UUID_t id; | ||||||
|             std::string name; | 			std::string name; | ||||||
|             std::string description; | 			std::string description; | ||||||
|             uint64_t retention = 0; | 			uint64_t retention = 0; | ||||||
|             uint64_t interval = 0; | 			uint64_t interval = 0; | ||||||
|             bool monitorSubVenues = false; | 			bool monitorSubVenues = false; | ||||||
|  |  | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|         }; | 		}; | ||||||
|  |  | ||||||
|         struct BoardInfo { | 		struct BoardInfo { | ||||||
|             ProvObjects::ObjectInfo info; | 			ProvObjects::ObjectInfo info; | ||||||
|             std::vector<VenueInfo> venueList; | 			std::vector<VenueInfo> venueList; | ||||||
|  |  | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  |  | ||||||
|             inline bool operator<(const BoardInfo &bb) const { | 			inline bool operator<(const BoardInfo &bb) const { return info.id < bb.info.id; } | ||||||
|                 return info.id < bb.info.id; |  | ||||||
|             } | 			inline bool operator==(const BoardInfo &bb) const { return info.id == bb.info.id; } | ||||||
|  | 		}; | ||||||
|             inline bool operator==(const BoardInfo &bb) const { |  | ||||||
|                 return info.id == bb.info.id; | 		struct DeviceInfo { | ||||||
|             } | 			std::string boardId; | ||||||
|         }; | 			std::string type; | ||||||
|  | 			std::string serialNumber; | ||||||
|         struct DeviceInfo { | 			std::string deviceType; | ||||||
|             std::string boardId; | 			uint64_t lastContact = 0; | ||||||
|             std::string type; | 			uint64_t lastPing = 0; | ||||||
|             std::string serialNumber; | 			uint64_t lastState = 0; | ||||||
|             std::string deviceType; | 			std::string lastFirmware; | ||||||
|             uint64_t lastContact = 0 ; | 			uint64_t lastFirmwareUpdate = 0; | ||||||
|             uint64_t lastPing = 0; | 			uint64_t lastConnection = 0; | ||||||
|             uint64_t lastState = 0; | 			uint64_t lastDisconnection = 0; | ||||||
|             std::string lastFirmware; | 			uint64_t pings = 0; | ||||||
|             uint64_t lastFirmwareUpdate = 0; | 			uint64_t states = 0; | ||||||
|             uint64_t lastConnection = 0; | 			bool connected = false; | ||||||
|             uint64_t lastDisconnection = 0; | 			std::string connectionIp; | ||||||
|             uint64_t pings = 0; | 			uint64_t associations_2g = 0; | ||||||
|             uint64_t states = 0; | 			uint64_t associations_5g = 0; | ||||||
|             bool connected = false; | 			uint64_t associations_6g = 0; | ||||||
|             std::string connectionIp; | 			uint64_t health = 0; | ||||||
|             uint64_t associations_2g = 0; | 			uint64_t lastHealth = 0; | ||||||
|             uint64_t associations_5g = 0; | 			std::string locale; | ||||||
|             uint64_t associations_6g = 0; | 			uint64_t uptime = 0; | ||||||
|             uint64_t health = 0; | 			double memory = 0.0; | ||||||
|             uint64_t lastHealth = 0; |  | ||||||
|             std::string locale; | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|             uint64_t uptime = 0; | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|             double memory = 0.0; | 		}; | ||||||
|  |  | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; | 		struct DeviceInfoList { | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | 			std::vector<DeviceInfo> devices; | ||||||
|         }; |  | ||||||
|  | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         struct DeviceInfoList { | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|             std::vector<DeviceInfo> devices; | 		}; | ||||||
|  |  | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; | 		enum wifi_band { band_2g = 0, band_5g = 1, band_6g = 2 }; | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
|         }; | 		struct TIDstat_entry { | ||||||
|  | 			uint64_t rx_msdu = 0, tx_msdu = 0, tx_msdu_failed = 0, tx_msdu_retries = 0; | ||||||
|         enum wifi_band { |  | ||||||
|             band_2g = 0, band_5g = 1, band_6g = 2 | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         }; | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 		}; | ||||||
|         struct TIDstat_entry { |  | ||||||
|             uint64_t rx_msdu = 0, | 		struct UE_rate { | ||||||
|                     tx_msdu = 0, | 			uint64_t bitrate = 0; | ||||||
|                     tx_msdu_failed = 0, | 			uint64_t mcs = 0; | ||||||
|                     tx_msdu_retries = 0; | 			uint64_t nss = 0; | ||||||
|  | 			bool ht = false; | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; | 			bool sgi = false; | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | 			uint64_t chwidth = 0; | ||||||
|         }; |  | ||||||
|  | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         struct UE_rate { | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|             uint64_t    bitrate=0; | 		}; | ||||||
|             uint64_t    mcs=0; |  | ||||||
|             uint64_t    nss=0; | 		struct AveragePoint { | ||||||
|             bool        ht=false; | 			double min = 0.0, max = 0.0, avg = 0.0; | ||||||
|             bool        sgi=false; | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|             uint64_t    chwidth=0; | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 		}; | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		struct UETimePoint { | ||||||
|         }; | 			std::string station; | ||||||
|  | 			int64_t rssi = 0; | ||||||
|         struct AveragePoint { | 			uint64_t tx_bytes = 0, rx_bytes = 0, tx_duration = 0, rx_packets = 0, tx_packets = 0, | ||||||
|             double      min = 0.0, | 					 tx_retries = 0, tx_failed = 0, connected = 0, inactive = 0; | ||||||
|                         max = 0.0, |  | ||||||
|                         avg = 0.0; | 			double tx_bytes_bw = 0.0, rx_bytes_bw = 0.0, tx_packets_bw = 0.0, rx_packets_bw = 0.0, | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; | 				   tx_failed_pct = 0.0, tx_retries_pct = 0.0, tx_duration_pct = 0.0; | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
|         }; | 			uint64_t tx_bytes_delta = 0, rx_bytes_delta = 0, tx_duration_delta = 0, | ||||||
|  | 					 rx_packets_delta = 0, tx_packets_delta = 0, tx_retries_delta = 0, | ||||||
|         struct UETimePoint { | 					 tx_failed_delta = 0; | ||||||
|             std::string station; |  | ||||||
|             int64_t rssi = 0; | 			UE_rate tx_rate, rx_rate; | ||||||
|             uint64_t tx_bytes = 0, | 			std::vector<TIDstat_entry> tidstats; | ||||||
|                     rx_bytes = 0, |  | ||||||
|                     tx_duration = 0, | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|                     rx_packets = 0, | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|                     tx_packets = 0, | 		}; | ||||||
|                     tx_retries = 0, |  | ||||||
|                     tx_failed = 0, | 		enum SSID_MODES { unknown = 0, ap, mesh, sta, wds_ap, wds_sta, wds_repeater }; | ||||||
|                     connected = 0, |  | ||||||
|                     inactive = 0; | 		inline SSID_MODES SSID_Mode(const std::string &m) { | ||||||
|  | 			if (m == "ap") | ||||||
|             double  tx_bytes_bw = 0.0 , | 				return ap; | ||||||
|                     rx_bytes_bw = 0.0 , | 			if (m == "sta") | ||||||
|                     tx_packets_bw = 0.0 , | 				return sta; | ||||||
|                     rx_packets_bw = 0.0 , | 			if (m == "mesh") | ||||||
|                     tx_failed_pct = 0.0 , | 				return mesh; | ||||||
|                     tx_retries_pct = 0.0 , | 			if (m == "wds-ap") | ||||||
|                     tx_duration_pct = 0.0; | 				return wds_ap; | ||||||
|  | 			if (m == "wds-sta") | ||||||
|             uint64_t    tx_bytes_delta = 0, | 				return wds_sta; | ||||||
|                         rx_bytes_delta = 0, | 			if (m == "wds-repeater") | ||||||
|                         tx_duration_delta = 0, | 				return wds_repeater; | ||||||
|                         rx_packets_delta = 0, | 			return unknown; | ||||||
|                         tx_packets_delta = 0, | 		} | ||||||
|                         tx_retries_delta = 0, |  | ||||||
|                         tx_failed_delta = 0; | 		struct SSIDTimePoint { | ||||||
|  | 			std::string bssid, mode, ssid; | ||||||
|             UE_rate tx_rate, | 			uint64_t band = 0, channel = 0; | ||||||
|                     rx_rate; | 			std::vector<UETimePoint> associations; | ||||||
|             std::vector<TIDstat_entry> tidstats; |  | ||||||
|  | 			AveragePoint tx_bytes_bw, rx_bytes_bw, tx_packets_bw, rx_packets_bw, tx_failed_pct, | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; | 				tx_retries_pct, tx_duration_pct; | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
|         }; | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|         enum SSID_MODES { | 		}; | ||||||
|             unknown = 0, |  | ||||||
|             ap, | 		struct APTimePoint { | ||||||
|             mesh, | 			uint64_t collisions = 0, multicast = 0, rx_bytes = 0, rx_dropped = 0, rx_errors = 0, | ||||||
|             sta, | 					 rx_packets = 0, tx_bytes = 0, tx_dropped = 0, tx_errors = 0, tx_packets = 0; | ||||||
|             wds_ap, |  | ||||||
|             wds_sta, | 			double tx_bytes_bw = 0.0, rx_bytes_bw = 0.0, rx_dropped_pct = 0.0, tx_dropped_pct = 0.0, | ||||||
|             wds_repeater | 				   rx_packets_bw = 0.0, tx_packets_bw = 0.0, rx_errors_pct = 0.0, | ||||||
|         }; | 				   tx_errors_pct = 0.0; | ||||||
|  |  | ||||||
|         inline SSID_MODES SSID_Mode(const std::string &m) { | 			uint64_t tx_bytes_delta = 0, rx_bytes_delta = 0, rx_dropped_delta = 0, | ||||||
|             if (m == "ap") | 					 tx_dropped_delta = 0, rx_packets_delta = 0, tx_packets_delta = 0, | ||||||
|                 return ap; | 					 rx_errors_delta = 0, tx_errors_delta = 0; | ||||||
|             if (m == "sta") |  | ||||||
|                 return sta; | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|             if (m == "mesh") | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|                 return mesh; | 		}; | ||||||
|             if (m == "wds-ap") |  | ||||||
|                 return wds_ap; | 		struct RadioTimePoint { | ||||||
|             if (m == "wds-sta") | 			uint64_t band = 0, channel_width = 0; | ||||||
|                 return wds_sta; | 			uint64_t active_ms = 0, busy_ms = 0, receive_ms = 0, transmit_ms = 0, tx_power = 0, | ||||||
|             if (m == "wds-repeater") | 					 channel = 0; | ||||||
|                 return wds_repeater; | 			int64_t temperature = 0, noise = 0; | ||||||
|             return unknown; |  | ||||||
|         } | 			double active_pct = 0.0, busy_pct = 0.0, receive_pct = 0.0, transmit_pct = 0.0; | ||||||
|  |  | ||||||
|         struct SSIDTimePoint { | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|             std::string bssid, | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|                         mode, | 		}; | ||||||
|                         ssid; |  | ||||||
|             uint64_t    band=0, | 		struct DeviceTimePoint { | ||||||
|                         channel=0; | 			std::string id; | ||||||
|             std::vector<UETimePoint> associations; | 			std::string boardId; | ||||||
|  | 			uint64_t timestamp = 0; | ||||||
|             AveragePoint    tx_bytes_bw, | 			APTimePoint ap_data; | ||||||
|                             rx_bytes_bw, | 			std::vector<SSIDTimePoint> ssid_data; | ||||||
|                             tx_packets_bw, | 			std::vector<RadioTimePoint> radio_data; | ||||||
|                             rx_packets_bw, | 			AnalyticsObjects::DeviceInfo device_info; | ||||||
|                             tx_failed_pct, | 			std::string serialNumber; | ||||||
|                             tx_retries_pct, |  | ||||||
|                             tx_duration_pct; | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | 			inline bool operator<(const DeviceTimePoint &rhs) const { | ||||||
|         }; | 				if (timestamp < rhs.timestamp) | ||||||
|  | 					return true; | ||||||
|  | 				if (timestamp > rhs.timestamp) | ||||||
|         struct APTimePoint { | 					return false; | ||||||
|             uint64_t    collisions = 0, | 				if (device_info.serialNumber < rhs.device_info.serialNumber) | ||||||
|                         multicast = 0, | 					return true; | ||||||
|                         rx_bytes = 0, | 				return false; | ||||||
|                         rx_dropped = 0, | 			} | ||||||
|                         rx_errors = 0, |  | ||||||
|                         rx_packets = 0, | 			inline bool operator==(const DeviceTimePoint &rhs) const { | ||||||
|                         tx_bytes = 0, | 				return timestamp == rhs.timestamp && | ||||||
|                         tx_dropped = 0, | 					   device_info.serialNumber == rhs.device_info.serialNumber; | ||||||
|                         tx_errors = 0, | 			} | ||||||
|                         tx_packets = 0; |  | ||||||
|  | 			inline bool operator>(const DeviceTimePoint &rhs) const { | ||||||
|             double      tx_bytes_bw = 0.0 , | 				if (timestamp > rhs.timestamp) | ||||||
|                         rx_bytes_bw = 0.0 , | 					return true; | ||||||
|                         rx_dropped_pct = 0.0, | 				if (timestamp < rhs.timestamp) | ||||||
|                         tx_dropped_pct = 0.0, | 					return false; | ||||||
|                         rx_packets_bw = 0.0, | 				if (device_info.serialNumber > rhs.device_info.serialNumber) | ||||||
|                         tx_packets_bw = 0.0, | 					return true; | ||||||
|                         rx_errors_pct = 0.0 , | 				return false; | ||||||
|                         tx_errors_pct = 0.0; | 			} | ||||||
|  | 		}; | ||||||
|             uint64_t    tx_bytes_delta = 0, |  | ||||||
|                         rx_bytes_delta = 0 , | 		struct DeviceTimePointAnalysis { | ||||||
|                         rx_dropped_delta = 0, | 			uint64_t timestamp; | ||||||
|                         tx_dropped_delta = 0, |  | ||||||
|                         rx_packets_delta = 0, | 			AveragePoint noise; | ||||||
|                         tx_packets_delta = 0, | 			AveragePoint temperature; | ||||||
|                         rx_errors_delta = 0, | 			AveragePoint active_pct; | ||||||
|                         tx_errors_delta = 0; | 			AveragePoint busy_pct; | ||||||
|  | 			AveragePoint receive_pct; | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; | 			AveragePoint transmit_pct; | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | 			AveragePoint tx_power; | ||||||
|         }; |  | ||||||
|  | 			AveragePoint tx_bytes_bw; | ||||||
|         struct RadioTimePoint { | 			AveragePoint rx_bytes_bw; | ||||||
|             uint64_t    band = 0, | 			AveragePoint rx_dropped_pct; | ||||||
|                         channel_width = 0; | 			AveragePoint tx_dropped_pct; | ||||||
|             uint64_t    active_ms = 0, | 			AveragePoint rx_packets_bw; | ||||||
|                         busy_ms = 0, | 			AveragePoint tx_packets_bw; | ||||||
|                         receive_ms = 0, | 			AveragePoint rx_errors_pct; | ||||||
|                         transmit_ms = 0, | 			AveragePoint tx_errors_pct; | ||||||
|                         tx_power = 0, |  | ||||||
|                         channel = 0; | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|             int64_t     temperature = 0, | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|                         noise = 0; | 		}; | ||||||
|  |  | ||||||
|             double      active_pct = 0.0 , | 		struct DeviceTimePointList { | ||||||
|                         busy_pct = 0.0, | 			std::vector<DeviceTimePoint> points; | ||||||
|                         receive_pct = 0.0, | 			std::vector<DeviceTimePointAnalysis> stats; | ||||||
|                         transmit_pct = 0.0; | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; | 		}; | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
|         }; | 		struct BandwidthAnalysisEntry { | ||||||
|  | 			uint64_t timestamp = 0; | ||||||
|  | 		}; | ||||||
|         struct DeviceTimePoint { |  | ||||||
|             std::string                     id; | 		struct BandwidthAnalysis {}; | ||||||
|             std::string                     boardId; |  | ||||||
|             uint64_t                        timestamp = 0; | 		struct AverageValueSigned { | ||||||
|             APTimePoint                     ap_data; | 			int64_t peak = 0, avg = 0, low = 0; | ||||||
|             std::vector<SSIDTimePoint>      ssid_data; | 		}; | ||||||
|             std::vector<RadioTimePoint>     radio_data; |  | ||||||
|             AnalyticsObjects::DeviceInfo    device_info; | 		struct AverageValueUnsigned { | ||||||
|             std::string                     serialNumber; | 			uint64_t peak = 0, avg = 0, low = 0; | ||||||
|  | 		}; | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		struct RadioAnalysis { | ||||||
|  | 			uint64_t timestamp = 0; | ||||||
|             inline bool operator<(const DeviceTimePoint &rhs) const { | 			AverageValueSigned noise, temperature; | ||||||
|                 if(timestamp < rhs.timestamp) | 			AverageValueUnsigned active_ms, busy_ms, transmit_ms, receive_ms; | ||||||
|                     return true; | 		}; | ||||||
|                 if(timestamp > rhs.timestamp) |  | ||||||
|                     return false; | 		struct DeviceTimePointStats { | ||||||
|                 if(device_info.serialNumber < rhs.device_info.serialNumber) | 			uint64_t firstPoint = 0; | ||||||
|                     return true; | 			uint64_t lastPoint = 0; | ||||||
|                 return false; | 			uint64_t count = 0; | ||||||
|             } |  | ||||||
|  | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|             inline bool operator==(const DeviceTimePoint &rhs) const { | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|                 return timestamp==rhs.timestamp && device_info.serialNumber==rhs.device_info.serialNumber; | 		}; | ||||||
|             } |  | ||||||
|  | 		struct WifiClientRate { | ||||||
|             inline bool operator>(const DeviceTimePoint &rhs) const { | 			uint32_t bitrate = 0; | ||||||
|                 if(timestamp > rhs.timestamp) | 			uint32_t chwidth = 0; | ||||||
|                     return true; | 			uint16_t mcs = 0; | ||||||
|                 if(timestamp < rhs.timestamp) | 			uint16_t nss = 0; | ||||||
|                     return false; | 			bool vht = false; | ||||||
|                 if(device_info.serialNumber > rhs.device_info.serialNumber) |  | ||||||
|                     return true; | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|                 return false; | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|             } | 		}; | ||||||
|  |  | ||||||
|         }; | 		struct WifiClientHistory { | ||||||
|  | 			uint64_t timestamp = Utils::Now(); | ||||||
|         struct DeviceTimePointAnalysis { | 			std::string station_id; | ||||||
|             uint64_t        timestamp; | 			std::string bssid; | ||||||
|  | 			std::string ssid; | ||||||
|             AveragePoint    noise; | 			int64_t rssi = 0; | ||||||
|             AveragePoint    temperature; | 			uint32_t rx_bitrate = 0; | ||||||
|             AveragePoint    active_pct; | 			uint32_t rx_chwidth = 0; | ||||||
|             AveragePoint    busy_pct; | 			uint16_t rx_mcs = 0; | ||||||
|             AveragePoint    receive_pct; | 			uint16_t rx_nss = 0; | ||||||
|             AveragePoint    transmit_pct; | 			bool rx_vht = false; | ||||||
|             AveragePoint    tx_power; | 			uint32_t tx_bitrate = 0; | ||||||
|  | 			uint32_t tx_chwidth = 0; | ||||||
|             AveragePoint    tx_bytes_bw; | 			uint16_t tx_mcs = 0; | ||||||
|             AveragePoint    rx_bytes_bw; | 			uint16_t tx_nss = 0; | ||||||
|             AveragePoint    rx_dropped_pct; | 			bool tx_vht = false; | ||||||
|             AveragePoint    tx_dropped_pct; | 			uint64_t rx_bytes = 0; | ||||||
|             AveragePoint    rx_packets_bw; | 			uint64_t tx_bytes = 0; | ||||||
|             AveragePoint    tx_packets_bw; | 			uint64_t rx_duration = 0; | ||||||
|             AveragePoint    rx_errors_pct; | 			uint64_t tx_duration = 0; | ||||||
|             AveragePoint    tx_errors_pct; | 			uint64_t rx_packets = 0; | ||||||
|  | 			uint64_t tx_packets = 0; | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; | 			std::string ipv4; | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | 			std::string ipv6; | ||||||
|  | 			uint64_t channel_width = 0; | ||||||
|         }; | 			int64_t noise = 0; | ||||||
|  | 			uint64_t tx_power = 0; | ||||||
|         struct DeviceTimePointList { | 			uint64_t channel = 0; | ||||||
|             std::vector<DeviceTimePoint>            points; | 			uint64_t active_ms = 0; | ||||||
|             std::vector<DeviceTimePointAnalysis>    stats; | 			uint64_t busy_ms = 0; | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; | 			uint64_t receive_ms = 0; | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | 			std::string mode; | ||||||
|         }; | 			int64_t ack_signal = 0; | ||||||
|  | 			int64_t ack_signal_avg = 0; | ||||||
|         struct BandwidthAnalysisEntry { | 			uint64_t connected = 0; | ||||||
|             uint64_t    timestamp = 0; | 			uint64_t inactive = 0; | ||||||
|  | 			uint64_t tx_retries = 0; | ||||||
|         }; | 			std::string venue_id; | ||||||
|  |  | ||||||
|         struct BandwidthAnalysis { | 			void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 			bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|         }; | 		}; | ||||||
|  |  | ||||||
|         struct AverageValueSigned { | 	} // namespace AnalyticsObjects | ||||||
|             int64_t     peak=0, avg=0, low=0; |  | ||||||
|         }; | } // namespace OpenWifi | ||||||
|  |  | ||||||
|         struct AverageValueUnsigned { |  | ||||||
|             uint64_t     peak=0, avg=0, low=0; |  | ||||||
|         }; |  | ||||||
|  |  | ||||||
|         struct RadioAnalysis { |  | ||||||
|             uint64_t                timestamp=0; |  | ||||||
|             AverageValueSigned      noise, temperature; |  | ||||||
|             AverageValueUnsigned    active_ms, |  | ||||||
|                                     busy_ms, |  | ||||||
|                                     transmit_ms, |  | ||||||
|                                     receive_ms; |  | ||||||
|         }; |  | ||||||
|  |  | ||||||
|         struct DeviceTimePointStats { |  | ||||||
|             uint64_t                firstPoint=0; |  | ||||||
|             uint64_t                lastPoint=0; |  | ||||||
|             uint64_t                count=0; |  | ||||||
|  |  | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
|         }; |  | ||||||
|  |  | ||||||
|         struct WifiClientRate { |  | ||||||
|             uint32_t    bitrate=0; |  | ||||||
|             uint32_t    chwidth=0; |  | ||||||
|             uint16_t    mcs=0; |  | ||||||
|             uint16_t    nss=0; |  | ||||||
|             bool        vht=false; |  | ||||||
|  |  | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
|         }; |  | ||||||
|  |  | ||||||
|         struct WifiClientHistory { |  | ||||||
|             uint64_t        timestamp=OpenWifi::Now(); |  | ||||||
|             std::string     station_id; |  | ||||||
|             std::string     bssid; |  | ||||||
|             std::string     ssid; |  | ||||||
|             int64_t         rssi=0; |  | ||||||
|             uint32_t        rx_bitrate=0; |  | ||||||
|             uint32_t        rx_chwidth=0; |  | ||||||
|             uint16_t        rx_mcs=0; |  | ||||||
|             uint16_t        rx_nss=0; |  | ||||||
|             bool            rx_vht=false; |  | ||||||
|             uint32_t        tx_bitrate=0; |  | ||||||
|             uint32_t        tx_chwidth=0; |  | ||||||
|             uint16_t        tx_mcs=0; |  | ||||||
|             uint16_t        tx_nss=0; |  | ||||||
|             bool            tx_vht=false; |  | ||||||
|             uint64_t        rx_bytes=0; |  | ||||||
|             uint64_t        tx_bytes=0; |  | ||||||
|             uint64_t        rx_duration=0; |  | ||||||
|             uint64_t        tx_duration=0; |  | ||||||
|             uint64_t        rx_packets=0; |  | ||||||
|             uint64_t        tx_packets=0; |  | ||||||
|             std::string     ipv4; |  | ||||||
|             std::string     ipv6; |  | ||||||
|             uint64_t        channel_width=0; |  | ||||||
|             int64_t         noise=0; |  | ||||||
|             uint64_t        tx_power=0; |  | ||||||
|             uint64_t        channel=0; |  | ||||||
|             uint64_t        active_ms=0; |  | ||||||
|             uint64_t        busy_ms=0; |  | ||||||
|             uint64_t        receive_ms=0; |  | ||||||
|             std::string     mode; |  | ||||||
|             int64_t         ack_signal=0; |  | ||||||
|             int64_t         ack_signal_avg=0; |  | ||||||
|             uint64_t        connected=0; |  | ||||||
|             uint64_t        inactive=0; |  | ||||||
|             uint64_t        tx_retries=0; |  | ||||||
|             std::string     venue_id; |  | ||||||
|  |  | ||||||
|             void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
|         }; |  | ||||||
|  |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -3,206 +3,210 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "RESTAPI_CertObjects.h" | #include "RESTAPI_CertObjects.h" | ||||||
| #include "framework/MicroService.h" | #include "framework/RESTAPI_utils.h" | ||||||
|  |  | ||||||
| using OpenWifi::RESTAPI_utils::field_to_json; |  | ||||||
| using OpenWifi::RESTAPI_utils::field_from_json; | using OpenWifi::RESTAPI_utils::field_from_json; | ||||||
|  | using OpenWifi::RESTAPI_utils::field_to_json; | ||||||
|  |  | ||||||
| namespace OpenWifi::CertObjects { | namespace OpenWifi::CertObjects { | ||||||
|     void CertificateEntry::to_json(Poco::JSON::Object &Obj) const { | 	void CertificateEntry::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         field_to_json(Obj,"id", id); | 		field_to_json(Obj, "id", id); | ||||||
|         field_to_json(Obj,"entity", entity); | 		field_to_json(Obj, "entity", entity); | ||||||
|         field_to_json(Obj,"creator", creator); | 		field_to_json(Obj, "creator", creator); | ||||||
|         field_to_json(Obj,"type", type); | 		field_to_json(Obj, "type", type); | ||||||
|         field_to_json(Obj,"status", status); | 		field_to_json(Obj, "status", status); | ||||||
|         field_to_json(Obj,"certificate", certificate); | 		field_to_json(Obj, "certificate", certificate); | ||||||
|         field_to_json(Obj,"key", key); | 		field_to_json(Obj, "key", key); | ||||||
|         field_to_json(Obj,"devid", devid); | 		field_to_json(Obj, "devid", devid); | ||||||
|         field_to_json(Obj,"cas", cas); | 		field_to_json(Obj, "cas", cas); | ||||||
|         field_to_json(Obj,"manufacturer", manufacturer); | 		field_to_json(Obj, "manufacturer", manufacturer); | ||||||
|         field_to_json(Obj,"model", model); | 		field_to_json(Obj, "model", model); | ||||||
|         field_to_json(Obj,"redirector", redirector); | 		field_to_json(Obj, "redirector", redirector); | ||||||
|         field_to_json(Obj,"commonName", commonName); | 		field_to_json(Obj, "commonName", commonName); | ||||||
|         field_to_json(Obj,"certificateId", certificateId); | 		field_to_json(Obj, "certificateId", certificateId); | ||||||
|         field_to_json(Obj,"batch", batch); | 		field_to_json(Obj, "batch", batch); | ||||||
|         field_to_json(Obj,"created", created); | 		field_to_json(Obj, "created", created); | ||||||
|         field_to_json(Obj,"modified", modified); | 		field_to_json(Obj, "modified", modified); | ||||||
|         field_to_json(Obj,"revoked", revoked); | 		field_to_json(Obj, "revoked", revoked); | ||||||
|         field_to_json(Obj,"revokeCount", revokeCount); | 		field_to_json(Obj, "revokeCount", revokeCount); | ||||||
|         field_to_json(Obj,"synched", synched); | 		field_to_json(Obj, "synched", synched); | ||||||
|     } | 		field_to_json(Obj, "expiryDate", expiryDate); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         try { | 		try { | ||||||
|             field_from_json(Obj,"id", id); | 			field_from_json(Obj, "id", id); | ||||||
|             field_from_json(Obj,"entity", entity); | 			field_from_json(Obj, "entity", entity); | ||||||
|             field_from_json(Obj,"creator", creator); | 			field_from_json(Obj, "creator", creator); | ||||||
|             field_from_json(Obj,"type", type); | 			field_from_json(Obj, "type", type); | ||||||
|             field_from_json(Obj,"status", status); | 			field_from_json(Obj, "status", status); | ||||||
|             field_from_json(Obj,"certificate", certificate); | 			field_from_json(Obj, "certificate", certificate); | ||||||
|             field_from_json(Obj,"key", key); | 			field_from_json(Obj, "key", key); | ||||||
|             field_from_json(Obj,"devid", devid); | 			field_from_json(Obj, "devid", devid); | ||||||
|             field_from_json(Obj,"cas", cas); | 			field_from_json(Obj, "cas", cas); | ||||||
|             field_from_json(Obj,"manufacturer", manufacturer); | 			field_from_json(Obj, "manufacturer", manufacturer); | ||||||
|             field_from_json(Obj,"model", model); | 			field_from_json(Obj, "model", model); | ||||||
|             field_from_json(Obj,"redirector", redirector); | 			field_from_json(Obj, "redirector", redirector); | ||||||
|             field_from_json(Obj,"commonName", commonName); | 			field_from_json(Obj, "commonName", commonName); | ||||||
|             field_from_json(Obj,"certificateId", certificateId); | 			field_from_json(Obj, "certificateId", certificateId); | ||||||
|             field_from_json(Obj,"batch", batch); | 			field_from_json(Obj, "batch", batch); | ||||||
|             field_from_json(Obj,"created", created); | 			field_from_json(Obj, "created", created); | ||||||
|             field_from_json(Obj,"modified", modified); | 			field_from_json(Obj, "modified", modified); | ||||||
|             field_from_json(Obj,"revoked", revoked); | 			field_from_json(Obj, "revoked", revoked); | ||||||
|             field_from_json(Obj,"revokeCount", revokeCount); | 			field_from_json(Obj, "revokeCount", revokeCount); | ||||||
|             field_from_json(Obj,"synched", synched); | 			field_from_json(Obj, "synched", synched); | ||||||
|             return true; | 			field_from_json(Obj, "expiryDate", expiryDate); | ||||||
|         } catch (...) { | 			return true; | ||||||
|         } | 		} catch (...) { | ||||||
|         return false; | 		} | ||||||
|     } | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     void EntityEntry::to_json(Poco::JSON::Object &Obj) const { | 	void EntityEntry::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         field_to_json(Obj,"id", id); | 		field_to_json(Obj, "id", id); | ||||||
|         field_to_json(Obj,"creator", creator); | 		field_to_json(Obj, "creator", creator); | ||||||
|         field_to_json(Obj,"name", name); | 		field_to_json(Obj, "name", name); | ||||||
|         field_to_json(Obj,"description", description); | 		field_to_json(Obj, "description", description); | ||||||
|         field_to_json(Obj,"defaultRedirector", defaultRedirector); | 		field_to_json(Obj, "defaultRedirector", defaultRedirector); | ||||||
|         field_to_json(Obj,"apiKey", apiKey); | 		field_to_json(Obj, "apiKey", apiKey); | ||||||
|         field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile); | 		field_to_json(Obj, "serverEnrollmentProfile", serverEnrollmentProfile); | ||||||
|         field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile); | 		field_to_json(Obj, "clientEnrollmentProfile", clientEnrollmentProfile); | ||||||
|         field_to_json(Obj,"organization", organization); | 		field_to_json(Obj, "organization", organization); | ||||||
|         field_to_json(Obj,"created", created); | 		field_to_json(Obj, "created", created); | ||||||
|         field_to_json(Obj,"modified", modified); | 		field_to_json(Obj, "modified", modified); | ||||||
|         field_to_json(Obj,"suspended", suspended); | 		field_to_json(Obj, "suspended", suspended); | ||||||
|         field_to_json(Obj,"deleted", deleted); | 		field_to_json(Obj, "deleted", deleted); | ||||||
|         field_to_json(Obj,"notes", notes); | 		field_to_json(Obj, "notes", notes); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         try { | 		try { | ||||||
|             field_from_json(Obj,"id", id); | 			field_from_json(Obj, "id", id); | ||||||
|             field_from_json(Obj,"creator", creator); | 			field_from_json(Obj, "creator", creator); | ||||||
|             field_from_json(Obj,"name", name); | 			field_from_json(Obj, "name", name); | ||||||
|             field_from_json(Obj,"description", description); | 			field_from_json(Obj, "description", description); | ||||||
|             field_from_json(Obj,"defaultRedirector", defaultRedirector); | 			field_from_json(Obj, "defaultRedirector", defaultRedirector); | ||||||
|             field_from_json(Obj,"apiKey", apiKey); | 			field_from_json(Obj, "apiKey", apiKey); | ||||||
|             field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile); | 			field_from_json(Obj, "serverEnrollmentProfile", serverEnrollmentProfile); | ||||||
|             field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile); | 			field_from_json(Obj, "clientEnrollmentProfile", clientEnrollmentProfile); | ||||||
|             field_from_json(Obj,"organization", organization); | 			field_from_json(Obj, "organization", organization); | ||||||
|             field_from_json(Obj,"created", created); | 			field_from_json(Obj, "created", created); | ||||||
|             field_from_json(Obj,"modified", modified); | 			field_from_json(Obj, "modified", modified); | ||||||
|             field_from_json(Obj,"suspended", suspended); | 			field_from_json(Obj, "suspended", suspended); | ||||||
|             field_from_json(Obj,"deleted", deleted); | 			field_from_json(Obj, "deleted", deleted); | ||||||
|             field_from_json(Obj,"notes", notes); | 			field_from_json(Obj, "notes", notes); | ||||||
|             return true; | 			return true; | ||||||
|         } catch (...) { | 		} catch (...) { | ||||||
|         } | 		} | ||||||
|         return false; | 		return false; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void BatchEntry::to_json(Poco::JSON::Object &Obj) const { | 	void BatchEntry::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         field_to_json(Obj,"id", id); | 		field_to_json(Obj, "id", id); | ||||||
|         field_to_json(Obj,"entity", entity); | 		field_to_json(Obj, "entity", entity); | ||||||
|         field_to_json(Obj,"creator", creator); | 		field_to_json(Obj, "creator", creator); | ||||||
|         field_to_json(Obj,"name", name); | 		field_to_json(Obj, "name", name); | ||||||
|         field_to_json(Obj,"description", description); | 		field_to_json(Obj, "description", description); | ||||||
|         field_to_json(Obj,"manufacturer", manufacturer); | 		field_to_json(Obj, "manufacturer", manufacturer); | ||||||
|         field_to_json(Obj,"model", model); | 		field_to_json(Obj, "model", model); | ||||||
|         field_to_json(Obj,"redirector", redirector); | 		field_to_json(Obj, "redirector", redirector); | ||||||
|         field_to_json(Obj,"commonNames", commonNames); | 		field_to_json(Obj, "commonNames", commonNames); | ||||||
|         field_to_json(Obj,"jobHistory", jobHistory); | 		field_to_json(Obj, "jobHistory", jobHistory); | ||||||
|         field_to_json(Obj,"notes", notes); | 		field_to_json(Obj, "notes", notes); | ||||||
|         field_to_json(Obj,"submitted", submitted); | 		field_to_json(Obj, "submitted", submitted); | ||||||
|         field_to_json(Obj,"started", started); | 		field_to_json(Obj, "started", started); | ||||||
|         field_to_json(Obj,"completed", completed); | 		field_to_json(Obj, "completed", completed); | ||||||
|         field_to_json(Obj,"modified", modified); | 		field_to_json(Obj, "modified", modified); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         try { | 		try { | ||||||
|             field_from_json(Obj,"id", id); | 			field_from_json(Obj, "id", id); | ||||||
|             field_from_json(Obj,"entity", entity); | 			field_from_json(Obj, "entity", entity); | ||||||
|             field_from_json(Obj,"creator", creator); | 			field_from_json(Obj, "creator", creator); | ||||||
|             field_from_json(Obj,"name", name); | 			field_from_json(Obj, "name", name); | ||||||
|             field_from_json(Obj,"description", description); | 			field_from_json(Obj, "description", description); | ||||||
|             field_from_json(Obj,"manufacturer", manufacturer); | 			field_from_json(Obj, "manufacturer", manufacturer); | ||||||
|             field_from_json(Obj,"model", model); | 			field_from_json(Obj, "model", model); | ||||||
|             field_from_json(Obj,"redirector", redirector); | 			field_from_json(Obj, "redirector", redirector); | ||||||
|             field_from_json(Obj,"commonNames", commonNames); | 			field_from_json(Obj, "commonNames", commonNames); | ||||||
|             field_from_json(Obj,"jobHistory", jobHistory); | 			field_from_json(Obj, "jobHistory", jobHistory); | ||||||
|             field_from_json(Obj,"notes", notes); | 			field_from_json(Obj, "notes", notes); | ||||||
|             field_from_json(Obj,"submitted", submitted); | 			field_from_json(Obj, "submitted", submitted); | ||||||
|             field_from_json(Obj,"started", started); | 			field_from_json(Obj, "started", started); | ||||||
|             field_from_json(Obj,"completed", completed); | 			field_from_json(Obj, "completed", completed); | ||||||
|             field_from_json(Obj,"modified", modified); | 			field_from_json(Obj, "modified", modified); | ||||||
|             return true; | 			return true; | ||||||
|         } catch (...) { | 		} catch (...) { | ||||||
|         } | 		} | ||||||
|         return false; | 		return false; | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void JobEntry::to_json(Poco::JSON::Object &Obj) const { | 	void JobEntry::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         field_to_json(Obj,"id", id); | 		field_to_json(Obj, "id", id); | ||||||
|         field_to_json(Obj,"entity", entity); | 		field_to_json(Obj, "entity", entity); | ||||||
|         field_to_json(Obj,"creator", creator); | 		field_to_json(Obj, "creator", creator); | ||||||
|         field_to_json(Obj,"batch", batch); | 		field_to_json(Obj, "batch", batch); | ||||||
|         field_to_json(Obj,"commonNames", commonNames); | 		field_to_json(Obj, "commonNames", commonNames); | ||||||
|         field_to_json(Obj,"completedNames", completedNames); | 		field_to_json(Obj, "completedNames", completedNames); | ||||||
|         field_to_json(Obj,"errorNames", errorNames); | 		field_to_json(Obj, "errorNames", errorNames); | ||||||
|         field_to_json(Obj,"status", status); | 		field_to_json(Obj, "status", status); | ||||||
|         field_to_json(Obj,"command", command); | 		field_to_json(Obj, "command", command); | ||||||
|         field_to_json(Obj,"parameters", parameters); | 		field_to_json(Obj, "parameters", parameters); | ||||||
|         field_to_json(Obj,"submitted", submitted); | 		field_to_json(Obj, "submitted", submitted); | ||||||
|         field_to_json(Obj,"started", started); | 		field_to_json(Obj, "started", started); | ||||||
|         field_to_json(Obj,"completed", completed); | 		field_to_json(Obj, "completed", completed); | ||||||
|     } | 		field_to_json(Obj, "requesterUsername", requesterUsername); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         try { | 		try { | ||||||
|             field_from_json(Obj,"id", id); | 			field_from_json(Obj, "id", id); | ||||||
|             field_from_json(Obj,"entity", entity); | 			field_from_json(Obj, "entity", entity); | ||||||
|             field_from_json(Obj,"creator", creator); | 			field_from_json(Obj, "creator", creator); | ||||||
|             field_from_json(Obj,"batch", batch); | 			field_from_json(Obj, "batch", batch); | ||||||
|             field_from_json(Obj,"commonNames", commonNames); | 			field_from_json(Obj, "commonNames", commonNames); | ||||||
|             field_from_json(Obj,"completedNames", completedNames); | 			field_from_json(Obj, "completedNames", completedNames); | ||||||
|             field_from_json(Obj,"errorNames", errorNames); | 			field_from_json(Obj, "errorNames", errorNames); | ||||||
|             field_from_json(Obj,"status", status); | 			field_from_json(Obj, "status", status); | ||||||
|             field_from_json(Obj,"command", command); | 			field_from_json(Obj, "command", command); | ||||||
|             field_from_json(Obj,"parameters", parameters); | 			field_from_json(Obj, "parameters", parameters); | ||||||
|             field_from_json(Obj,"submitted", submitted); | 			field_from_json(Obj, "submitted", submitted); | ||||||
|             field_from_json(Obj,"started", started); | 			field_from_json(Obj, "started", started); | ||||||
|             field_from_json(Obj,"completed", completed); | 			field_from_json(Obj, "completed", completed); | ||||||
|             return true; | 			field_from_json(Obj, "requesterUsername", requesterUsername); | ||||||
|         } catch (...) { | 			return true; | ||||||
|         } | 		} catch (...) { | ||||||
|         return false; | 		} | ||||||
|     } | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     void DashBoardYearlyStats::to_json(Poco::JSON::Object &Obj) const { | 	void DashBoardYearlyStats::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         field_to_json(Obj, "year", year); | 		field_to_json(Obj, "year", year); | ||||||
|         field_to_json(Obj, "activeCerts", activeCerts); | 		field_to_json(Obj, "activeCerts", activeCerts); | ||||||
|         field_to_json(Obj, "revokedCerts", revokedCerts); | 		field_to_json(Obj, "revokedCerts", revokedCerts); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void Dashboard::to_json(Poco::JSON::Object &Obj) const { | 	void Dashboard::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         field_to_json(Obj,"snapshot", snapshot); | 		field_to_json(Obj, "snapshot", snapshot); | ||||||
|         field_to_json(Obj,"numberOfIssuedCerts", numberOfIssuedCerts); | 		field_to_json(Obj, "numberOfIssuedCerts", numberOfIssuedCerts); | ||||||
|         field_to_json(Obj,"numberOfRevokedCerts", numberOfRevokedCerts); | 		field_to_json(Obj, "numberOfRevokedCerts", numberOfRevokedCerts); | ||||||
|         field_to_json(Obj,"activeCertsPerOrganization", activeCertsPerOrganization); | 		field_to_json(Obj, "activeCertsPerOrganization", activeCertsPerOrganization); | ||||||
|         field_to_json(Obj,"revokedCertsPerOrganization", revokedCertsPerOrganization); | 		field_to_json(Obj, "revokedCertsPerOrganization", revokedCertsPerOrganization); | ||||||
|         field_to_json(Obj,"numberOfRedirectors", numberOfRedirectors); | 		field_to_json(Obj, "numberOfRedirectors", numberOfRedirectors); | ||||||
|         field_to_json(Obj,"deviceTypes", deviceTypes); | 		field_to_json(Obj, "deviceTypes", deviceTypes); | ||||||
|         field_to_json(Obj,"monthlyNumberOfCerts", monthlyNumberOfCerts); | 		field_to_json(Obj, "monthlyNumberOfCerts", monthlyNumberOfCerts); | ||||||
|         field_to_json(Obj,"monthlyNumberOfCertsPerOrgPerYear", monthlyNumberOfCertsPerOrgPerYear); | 		field_to_json(Obj, "monthlyNumberOfCertsPerOrgPerYear", monthlyNumberOfCertsPerOrgPerYear); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void Dashboard::reset() { | 	void Dashboard::reset() { | ||||||
|         snapshot=0; | 		snapshot = 0; | ||||||
|         numberOfRevokedCerts = numberOfIssuedCerts = 0; | 		numberOfRevokedCerts = numberOfIssuedCerts = 0; | ||||||
|         activeCertsPerOrganization.clear(); | 		activeCertsPerOrganization.clear(); | ||||||
|         revokedCertsPerOrganization.clear(); | 		revokedCertsPerOrganization.clear(); | ||||||
|         numberOfRedirectors.clear(); | 		numberOfRedirectors.clear(); | ||||||
|         deviceTypes.clear(); | 		deviceTypes.clear(); | ||||||
|         monthlyNumberOfCerts.clear(); | 		monthlyNumberOfCerts.clear(); | ||||||
|         monthlyNumberOfCertsPerOrgPerYear.clear(); | 		monthlyNumberOfCertsPerOrgPerYear.clear(); | ||||||
|     } | 	} | ||||||
| } | } // namespace OpenWifi::CertObjects | ||||||
| @@ -4,119 +4,121 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include <string> |  | ||||||
| #include "framework/OpenWifiTypes.h" |  | ||||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||||
|  | #include "framework/OpenWifiTypes.h" | ||||||
|  | #include <string> | ||||||
|  |  | ||||||
| namespace OpenWifi::CertObjects { | namespace OpenWifi::CertObjects { | ||||||
|  |  | ||||||
|     struct CertificateEntry { | 	struct CertificateEntry { | ||||||
|         OpenWifi::Types::UUID_t         id; | 		OpenWifi::Types::UUID_t id; | ||||||
|         OpenWifi::Types::UUID_t         entity; | 		OpenWifi::Types::UUID_t entity; | ||||||
|         OpenWifi::Types::UUID_t         creator; | 		OpenWifi::Types::UUID_t creator; | ||||||
|         std::string                     type; | 		std::string type; | ||||||
|         std::string                     status; | 		std::string status; | ||||||
|         std::string                     certificate; | 		std::string certificate; | ||||||
|         std::string                     key; | 		std::string key; | ||||||
|         std::string                     devid; | 		std::string devid; | ||||||
|         std::string                     cas; | 		std::string cas; | ||||||
|         std::string                     manufacturer; | 		std::string manufacturer; | ||||||
|         std::string                     model; | 		std::string model; | ||||||
|         std::string                     redirector; | 		std::string redirector; | ||||||
|         std::string                     commonName; | 		std::string commonName; | ||||||
|         std::string                     certificateId; | 		std::string certificateId; | ||||||
|         OpenWifi::Types::UUID_t         batch; | 		OpenWifi::Types::UUID_t batch; | ||||||
|         uint64_t                        created = 0; | 		uint64_t created = 0; | ||||||
|         uint64_t                        modified = 0; | 		uint64_t modified = 0; | ||||||
|         uint64_t                        revoked = 0; | 		uint64_t revoked = 0; | ||||||
|         uint64_t                        revokeCount = 0; | 		uint64_t revokeCount = 0; | ||||||
|         uint64_t                        synched = 0; | 		uint64_t synched = 0; | ||||||
|  | 		uint64_t expiryDate = 0; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     struct EntityEntry { | 	struct EntityEntry { | ||||||
|         OpenWifi::Types::UUID_t         id; | 		OpenWifi::Types::UUID_t id; | ||||||
|         OpenWifi::Types::UUID_t         creator; | 		OpenWifi::Types::UUID_t creator; | ||||||
|         std::string                     name; | 		std::string name; | ||||||
|         std::string                     description; | 		std::string description; | ||||||
|         std::string                     defaultRedirector; | 		std::string defaultRedirector; | ||||||
|         std::string                     apiKey; | 		std::string apiKey; | ||||||
|         std::string                     serverEnrollmentProfile; | 		std::string serverEnrollmentProfile; | ||||||
|         std::string                     clientEnrollmentProfile; | 		std::string clientEnrollmentProfile; | ||||||
|         std::string                     organization; | 		std::string organization; | ||||||
|         SecurityObjects::NoteInfoVec    notes; | 		SecurityObjects::NoteInfoVec notes; | ||||||
|         bool                            suspended=false; | 		bool suspended = false; | ||||||
|         bool                            deleted=false; | 		bool deleted = false; | ||||||
|         uint64_t                        created = 0 ; | 		uint64_t created = 0; | ||||||
|         uint64_t                        modified = 0 ; | 		uint64_t modified = 0; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     struct BatchEntry { | 	struct BatchEntry { | ||||||
|         OpenWifi::Types::UUID_t         id; | 		OpenWifi::Types::UUID_t id; | ||||||
|         OpenWifi::Types::UUID_t         entity; | 		OpenWifi::Types::UUID_t entity; | ||||||
|         OpenWifi::Types::UUID_t         creator; | 		OpenWifi::Types::UUID_t creator; | ||||||
|         std::string                     name; | 		std::string name; | ||||||
|         std::string                     description; | 		std::string description; | ||||||
|         std::string                     manufacturer; | 		std::string manufacturer; | ||||||
|         std::string                     model; | 		std::string model; | ||||||
|         std::string                     redirector; | 		std::string redirector; | ||||||
|         std::vector<std::string>        commonNames; | 		std::vector<std::string> commonNames; | ||||||
|         std::vector<std::string>        jobHistory; | 		std::vector<std::string> jobHistory; | ||||||
|         SecurityObjects::NoteInfoVec    notes; | 		SecurityObjects::NoteInfoVec notes; | ||||||
|         uint64_t                        submitted = 0 ; | 		uint64_t submitted = 0; | ||||||
|         uint64_t                        started = 0 ; | 		uint64_t started = 0; | ||||||
|         uint64_t                        completed = 0 ; | 		uint64_t completed = 0; | ||||||
|         uint64_t                        modified = 0 ; | 		uint64_t modified = 0; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     struct JobEntry { | 	struct JobEntry { | ||||||
|         OpenWifi::Types::UUID_t         id; | 		OpenWifi::Types::UUID_t id; | ||||||
|         OpenWifi::Types::UUID_t         entity; | 		OpenWifi::Types::UUID_t entity; | ||||||
|         OpenWifi::Types::UUID_t         creator; | 		OpenWifi::Types::UUID_t creator; | ||||||
|         OpenWifi::Types::UUID_t         batch; | 		OpenWifi::Types::UUID_t batch; | ||||||
|         std::string                     command; | 		std::string command; | ||||||
|         OpenWifi::Types::StringVec      commonNames; | 		OpenWifi::Types::StringVec commonNames; | ||||||
|         OpenWifi::Types::StringVec      completedNames; | 		OpenWifi::Types::StringVec completedNames; | ||||||
|         OpenWifi::Types::StringVec      errorNames; | 		OpenWifi::Types::StringVec errorNames; | ||||||
|         Types::StringPairVec            parameters; | 		Types::StringPairVec parameters; | ||||||
|         std::string                     status; | 		std::string status; | ||||||
|         uint64_t                        submitted=0; | 		uint64_t submitted = 0; | ||||||
|         uint64_t                        started=0; | 		uint64_t started = 0; | ||||||
|         uint64_t                        completed=0; | 		uint64_t completed = 0; | ||||||
|  | 		std::string requesterUsername; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     struct DashBoardYearlyStats { | 	struct DashBoardYearlyStats { | ||||||
|         uint64_t                            year=0; | 		uint64_t year = 0; | ||||||
|         OpenWifi::Types::Counted3DMapSII    activeCerts; | 		OpenWifi::Types::Counted3DMapSII activeCerts; | ||||||
|         OpenWifi::Types::Counted3DMapSII    revokedCerts; | 		OpenWifi::Types::Counted3DMapSII revokedCerts; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     struct Dashboard { | 	struct Dashboard { | ||||||
|         uint64_t                            snapshot=0; | 		uint64_t snapshot = 0; | ||||||
|         uint64_t                            numberOfIssuedCerts=0; | 		uint64_t numberOfIssuedCerts = 0; | ||||||
|         uint64_t                            numberOfRevokedCerts=0; | 		uint64_t numberOfRevokedCerts = 0; | ||||||
|         OpenWifi::Types::CountedMap         activeCertsPerOrganization; | 		OpenWifi::Types::CountedMap activeCertsPerOrganization; | ||||||
|         OpenWifi::Types::CountedMap         revokedCertsPerOrganization; | 		OpenWifi::Types::CountedMap revokedCertsPerOrganization; | ||||||
|         OpenWifi::Types::CountedMap         numberOfRedirectors; | 		OpenWifi::Types::CountedMap numberOfRedirectors; | ||||||
|         OpenWifi::Types::CountedMap         deviceTypes; | 		OpenWifi::Types::CountedMap deviceTypes; | ||||||
|         OpenWifi::Types::CountedMap         monthlyNumberOfCerts; | 		OpenWifi::Types::CountedMap monthlyNumberOfCerts; | ||||||
|         std::vector<DashBoardYearlyStats>   monthlyNumberOfCertsPerOrgPerYear; | 		std::vector<DashBoardYearlyStats> monthlyNumberOfCertsPerOrgPerYear; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         void reset(); | 		void reset(); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
| } | } // namespace OpenWifi::CertObjects | ||||||
| @@ -3,307 +3,296 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "RESTAPI_FMSObjects.h" | #include "RESTAPI_FMSObjects.h" | ||||||
| #include "framework/MicroService.h" | #include "framework/RESTAPI_utils.h" | ||||||
|  | #include "framework/utils.h" | ||||||
|  |  | ||||||
| using OpenWifi::RESTAPI_utils::field_to_json; |  | ||||||
| using OpenWifi::RESTAPI_utils::field_from_json; | using OpenWifi::RESTAPI_utils::field_from_json; | ||||||
|  | using OpenWifi::RESTAPI_utils::field_to_json; | ||||||
|  |  | ||||||
| namespace OpenWifi::FMSObjects { | namespace OpenWifi::FMSObjects { | ||||||
|  |  | ||||||
|     void Firmware::to_json(Poco::JSON::Object &Obj) const { | 	void Firmware::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         field_to_json(Obj, "id", id); | 		field_to_json(Obj, "id", id); | ||||||
|         field_to_json(Obj, "release", release); | 		field_to_json(Obj, "release", release); | ||||||
|         field_to_json(Obj, "deviceType", deviceType); | 		field_to_json(Obj, "deviceType", deviceType); | ||||||
|         field_to_json(Obj, "description", description); | 		field_to_json(Obj, "description", description); | ||||||
|         field_to_json(Obj, "revision", revision); | 		field_to_json(Obj, "revision", revision); | ||||||
|         field_to_json(Obj, "uri", uri); | 		field_to_json(Obj, "uri", uri); | ||||||
|         field_to_json(Obj, "image", image); | 		field_to_json(Obj, "image", image); | ||||||
|         field_to_json(Obj, "imageDate", imageDate); | 		field_to_json(Obj, "imageDate", imageDate); | ||||||
|         field_to_json(Obj, "size", size); | 		field_to_json(Obj, "size", size); | ||||||
|         field_to_json(Obj, "downloadCount", downloadCount); | 		field_to_json(Obj, "downloadCount", downloadCount); | ||||||
|         field_to_json(Obj, "firmwareHash", firmwareHash); | 		field_to_json(Obj, "firmwareHash", firmwareHash); | ||||||
|         field_to_json(Obj, "owner", owner); | 		field_to_json(Obj, "owner", owner); | ||||||
|         field_to_json(Obj, "location", location); | 		field_to_json(Obj, "location", location); | ||||||
|         field_to_json(Obj, "uploader", uploader); | 		field_to_json(Obj, "uploader", uploader); | ||||||
|         field_to_json(Obj, "digest", digest); | 		field_to_json(Obj, "digest", digest); | ||||||
|         field_to_json(Obj, "latest", latest); | 		field_to_json(Obj, "latest", latest); | ||||||
|         field_to_json(Obj, "notes", notes); | 		field_to_json(Obj, "notes", notes); | ||||||
|         field_to_json(Obj, "created", created); | 		field_to_json(Obj, "created", created); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     bool Firmware::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool Firmware::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         try { | 		try { | ||||||
|             field_from_json(Obj, "id", id); | 			field_from_json(Obj, "id", id); | ||||||
|             field_from_json(Obj, "release", release); | 			field_from_json(Obj, "release", release); | ||||||
|             field_from_json(Obj, "deviceType", deviceType); | 			field_from_json(Obj, "deviceType", deviceType); | ||||||
|             field_from_json(Obj, "description", description); | 			field_from_json(Obj, "description", description); | ||||||
|             field_from_json(Obj, "revision", revision); | 			field_from_json(Obj, "revision", revision); | ||||||
|             field_from_json(Obj, "uri", uri); | 			field_from_json(Obj, "uri", uri); | ||||||
|             field_from_json(Obj, "image", image); | 			field_from_json(Obj, "image", image); | ||||||
|             field_from_json(Obj, "imageDate", imageDate); | 			field_from_json(Obj, "imageDate", imageDate); | ||||||
|             field_from_json(Obj, "size", size); | 			field_from_json(Obj, "size", size); | ||||||
|             field_from_json(Obj, "downloadCount", downloadCount); | 			field_from_json(Obj, "downloadCount", downloadCount); | ||||||
|             field_from_json(Obj, "firmwareHash", firmwareHash); | 			field_from_json(Obj, "firmwareHash", firmwareHash); | ||||||
|             field_from_json(Obj, "owner", owner); | 			field_from_json(Obj, "owner", owner); | ||||||
|             field_from_json(Obj, "location", location); | 			field_from_json(Obj, "location", location); | ||||||
|             field_from_json(Obj, "uploader", uploader); | 			field_from_json(Obj, "uploader", uploader); | ||||||
|             field_from_json(Obj, "digest", digest); | 			field_from_json(Obj, "digest", digest); | ||||||
|             field_from_json(Obj, "latest", latest); | 			field_from_json(Obj, "latest", latest); | ||||||
|             field_from_json(Obj, "notes", notes); | 			field_from_json(Obj, "notes", notes); | ||||||
|             field_from_json(Obj, "created", created); | 			field_from_json(Obj, "created", created); | ||||||
|             return true; | 			return true; | ||||||
|         } catch (...) { | 		} catch (...) { | ||||||
|  | 		} | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|         } | 	void FirmwareList::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         return true; | 		field_to_json(Obj, "firmwares", firmwares); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     void FirmwareList::to_json(Poco::JSON::Object &Obj) const { | 	bool FirmwareList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         field_to_json(Obj,"firmwares",firmwares); | 		try { | ||||||
|     } | 			field_from_json(Obj, "firmwares", firmwares); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (...) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     bool FirmwareList::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	void DeviceType::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         try { | 		field_to_json(Obj, "id", id); | ||||||
|             field_from_json(Obj, "firmwares", firmwares); | 		field_to_json(Obj, "deviceType", deviceType); | ||||||
|             return true; | 		field_to_json(Obj, "manufacturer", manufacturer); | ||||||
|         } catch (...) { | 		field_to_json(Obj, "model", model); | ||||||
|  | 		field_to_json(Obj, "policy", policy); | ||||||
|  | 		field_to_json(Obj, "notes", notes); | ||||||
|  | 		field_to_json(Obj, "lastUpdate", lastUpdate); | ||||||
|  | 		field_to_json(Obj, "created", created); | ||||||
|  | 		field_to_json(Obj, "id", id); | ||||||
|  | 		field_to_json(Obj, "id", id); | ||||||
|  | 		field_to_json(Obj, "id", id); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|         } | 	bool DeviceType::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         return false; | 		try { | ||||||
|     } | 			field_from_json(Obj, "id", id); | ||||||
|  | 			field_from_json(Obj, "deviceType", deviceType); | ||||||
|  | 			field_from_json(Obj, "manufacturer", manufacturer); | ||||||
|  | 			field_from_json(Obj, "model", model); | ||||||
|  | 			field_from_json(Obj, "policy", policy); | ||||||
|  | 			field_from_json(Obj, "notes", notes); | ||||||
|  | 			field_from_json(Obj, "lastUpdate", lastUpdate); | ||||||
|  | 			field_from_json(Obj, "created", created); | ||||||
|  | 			field_from_json(Obj, "id", id); | ||||||
|  | 			field_from_json(Obj, "id", id); | ||||||
|  | 			field_from_json(Obj, "id", id); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (...) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     void DeviceType::to_json(Poco::JSON::Object &Obj) const { | 	void DeviceTypeList::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         field_to_json(Obj, "id", id); | 		field_to_json(Obj, "deviceTypes", deviceTypes); | ||||||
|         field_to_json(Obj, "deviceType", deviceType); | 	} | ||||||
|         field_to_json(Obj, "manufacturer", manufacturer); |  | ||||||
|         field_to_json(Obj, "model", model); |  | ||||||
|         field_to_json(Obj, "policy", policy); |  | ||||||
|         field_to_json(Obj, "notes", notes); |  | ||||||
|         field_to_json(Obj, "lastUpdate", lastUpdate); |  | ||||||
|         field_to_json(Obj, "created", created); |  | ||||||
|         field_to_json(Obj, "id", id); |  | ||||||
|         field_to_json(Obj, "id", id); |  | ||||||
|         field_to_json(Obj, "id", id); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool DeviceType::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool DeviceTypeList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         try { | 		try { | ||||||
|             field_from_json(Obj, "id", id); | 			field_from_json(Obj, "deviceTypes", deviceTypes); | ||||||
|             field_from_json(Obj, "deviceType", deviceType); | 			return true; | ||||||
|             field_from_json(Obj, "manufacturer", manufacturer); | 		} catch (...) { | ||||||
|             field_from_json(Obj, "model", model); | 		} | ||||||
|             field_from_json(Obj, "policy", policy); | 		return false; | ||||||
|             field_from_json(Obj, "notes", notes); | 	} | ||||||
|             field_from_json(Obj, "lastUpdate", lastUpdate); |  | ||||||
|             field_from_json(Obj, "created", created); |  | ||||||
|             field_from_json(Obj, "id", id); |  | ||||||
|             field_from_json(Obj, "id", id); |  | ||||||
|             field_from_json(Obj, "id", id); |  | ||||||
|             return true; |  | ||||||
|         } catch (...) { |  | ||||||
|  |  | ||||||
|         } | 	void RevisionHistoryEntry::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         return false; | 		field_to_json(Obj, "id", id); | ||||||
|     } | 		field_to_json(Obj, "serialNumber", serialNumber); | ||||||
|  | 		field_to_json(Obj, "fromRelease", fromRelease); | ||||||
|  | 		field_to_json(Obj, "toRelease", toRelease); | ||||||
|  | 		field_to_json(Obj, "commandUUID", commandUUID); | ||||||
|  | 		field_to_json(Obj, "revisionId", revisionId); | ||||||
|  | 		field_to_json(Obj, "upgraded", upgraded); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     void DeviceTypeList::to_json(Poco::JSON::Object &Obj) const { | 	bool RevisionHistoryEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         field_to_json(Obj,"deviceTypes", deviceTypes); | 		try { | ||||||
|     } | 			field_from_json(Obj, "id", id); | ||||||
|  | 			field_from_json(Obj, "serialNumber", serialNumber); | ||||||
|  | 			field_from_json(Obj, "fromRelease", fromRelease); | ||||||
|  | 			field_from_json(Obj, "toRelease", toRelease); | ||||||
|  | 			field_from_json(Obj, "commandUUID", commandUUID); | ||||||
|  | 			field_from_json(Obj, "revisionId", revisionId); | ||||||
|  | 			field_from_json(Obj, "upgraded", upgraded); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (...) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     bool DeviceTypeList::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	void RevisionHistoryEntryList::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         try { | 		field_to_json(Obj, "deviceTypes", history); | ||||||
|             field_from_json(Obj,"deviceTypes", deviceTypes); | 	} | ||||||
|             return true; |  | ||||||
|         } catch(...) { |  | ||||||
|  |  | ||||||
|         } | 	bool RevisionHistoryEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         return false; | 		try { | ||||||
|     } | 			field_from_json(Obj, "deviceTypes", history); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (...) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     void RevisionHistoryEntry::to_json(Poco::JSON::Object &Obj) const { | 	void FirmwareAgeDetails::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         field_to_json(Obj, "id", id); | 		field_to_json(Obj, "latestId", latestId); | ||||||
|         field_to_json(Obj, "serialNumber", serialNumber); | 		field_to_json(Obj, "image", image); | ||||||
|         field_to_json(Obj, "fromRelease", fromRelease); | 		field_to_json(Obj, "imageDate", imageDate); | ||||||
|         field_to_json(Obj, "toRelease", toRelease); | 		field_to_json(Obj, "revision", revision); | ||||||
|         field_to_json(Obj, "commandUUID", commandUUID); | 		field_to_json(Obj, "uri", uri); | ||||||
|         field_to_json(Obj, "revisionId", revisionId); | 		field_to_json(Obj, "age", age); | ||||||
|         field_to_json(Obj, "upgraded", upgraded); | 		field_to_json(Obj, "latest", latest); | ||||||
|     } | 	} | ||||||
|  |  | ||||||
|     bool RevisionHistoryEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool FirmwareAgeDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         try { | 		try { | ||||||
|             field_from_json(Obj, "id", id); | 			field_from_json(Obj, "latestId", latestId); | ||||||
|             field_from_json(Obj, "serialNumber", serialNumber); | 			field_from_json(Obj, "image", image); | ||||||
|             field_from_json(Obj, "fromRelease", fromRelease); | 			field_from_json(Obj, "imageDate", imageDate); | ||||||
|             field_from_json(Obj, "toRelease", toRelease); | 			field_from_json(Obj, "revision", revision); | ||||||
|             field_from_json(Obj, "commandUUID", commandUUID); | 			field_from_json(Obj, "uri", uri); | ||||||
|             field_from_json(Obj, "revisionId", revisionId); | 			field_from_json(Obj, "age", age); | ||||||
|             field_from_json(Obj, "upgraded", upgraded); | 			field_from_json(Obj, "latest", latest); | ||||||
|             return true; | 			return true; | ||||||
|         } catch(...) { | 		} catch (...) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|         } | 	void DeviceConnectionInformation::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         return false; | 		field_to_json(Obj, "serialNumber", serialNumber); | ||||||
|     } | 		field_to_json(Obj, "revision", revision); | ||||||
|  | 		field_to_json(Obj, "deviceType", deviceType); | ||||||
|  | 		field_to_json(Obj, "endPoint", endPoint); | ||||||
|  | 		field_to_json(Obj, "lastUpdate", lastUpdate); | ||||||
|  | 		field_to_json(Obj, "status", status); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     void RevisionHistoryEntryList::to_json(Poco::JSON::Object &Obj) const { | 	bool DeviceConnectionInformation::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         field_to_json(Obj,"deviceTypes", history); | 		try { | ||||||
|     } | 			field_from_json(Obj, "serialNumber", serialNumber); | ||||||
|  | 			field_from_json(Obj, "revision", revision); | ||||||
|  | 			field_from_json(Obj, "deviceType", deviceType); | ||||||
|  | 			field_from_json(Obj, "endPoint", endPoint); | ||||||
|  | 			field_from_json(Obj, "lastUpdate", lastUpdate); | ||||||
|  | 			field_from_json(Obj, "status", status); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (...) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     bool RevisionHistoryEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	void DeviceReport::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         try { | 		field_to_json(Obj, "ouis", OUI_); | ||||||
|             field_from_json(Obj,"deviceTypes", history); | 		field_to_json(Obj, "revisions", Revisions_); | ||||||
|             return true; | 		field_to_json(Obj, "deviceTypes", DeviceTypes_); | ||||||
|         } catch(...) { | 		field_to_json(Obj, "status", Status_); | ||||||
|  | 		field_to_json(Obj, "endPoints", EndPoints_); | ||||||
|  | 		field_to_json(Obj, "usingLatest", UsingLatest_); | ||||||
|  | 		field_to_json(Obj, "unknownFirmwares", UnknownFirmwares_); | ||||||
|  | 		field_to_json(Obj, "snapshot", snapshot); | ||||||
|  | 		field_to_json(Obj, "numberOfDevices", numberOfDevices); | ||||||
|  | 		field_to_json(Obj, "totalSecondsOld", totalSecondsOld_); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|         } | 	void DeviceReport::reset() { | ||||||
|         return false; | 		OUI_.clear(); | ||||||
|     } | 		Revisions_.clear(); | ||||||
|  | 		DeviceTypes_.clear(); | ||||||
|  | 		Status_.clear(); | ||||||
|  | 		EndPoints_.clear(); | ||||||
|  | 		UsingLatest_.clear(); | ||||||
|  | 		UnknownFirmwares_.clear(); | ||||||
|  | 		totalSecondsOld_.clear(); | ||||||
|  | 		numberOfDevices = 0; | ||||||
|  | 		snapshot = Utils::Now(); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     void FirmwareAgeDetails::to_json(Poco::JSON::Object &Obj) const { | 	bool DeviceReport::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         field_to_json(Obj,"latestId", latestId); | 		try { | ||||||
|         field_to_json(Obj,"image", image); |  | ||||||
|         field_to_json(Obj,"imageDate", imageDate); |  | ||||||
|         field_to_json(Obj,"revision", revision); |  | ||||||
|         field_to_json(Obj,"uri", uri); |  | ||||||
|         field_to_json(Obj,"age", age); |  | ||||||
|         field_to_json(Obj,"latest",latest); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool FirmwareAgeDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { | 			return true; | ||||||
|         try { | 		} catch (...) { | ||||||
|             field_from_json(Obj,"latestId", latestId); | 		} | ||||||
|             field_from_json(Obj,"image", image); | 		return false; | ||||||
|             field_from_json(Obj,"imageDate", imageDate); | 	} | ||||||
|             field_from_json(Obj,"revision", revision); |  | ||||||
|             field_from_json(Obj,"uri", uri); |  | ||||||
|             field_from_json(Obj,"age", age); |  | ||||||
|             field_from_json(Obj,"latest", latest); |  | ||||||
|             return true; |  | ||||||
|         } catch(...) { |  | ||||||
|  |  | ||||||
|         } | 	void DeviceInformation::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         return false; | 		field_to_json(Obj, "serialNumber", serialNumber); | ||||||
|     } | 		field_to_json(Obj, "history", history); | ||||||
|  | 		field_to_json(Obj, "currentFirmware", currentFirmware); | ||||||
|  | 		field_to_json(Obj, "currentFirmwareDate", currentFirmwareDate); | ||||||
|  | 		field_to_json(Obj, "latestFirmware", latestFirmware); | ||||||
|  | 		field_to_json(Obj, "latestFirmwareDate", latestFirmwareDate); | ||||||
|  | 		field_to_json(Obj, "latestFirmwareAvailable", latestFirmwareAvailable); | ||||||
|  | 		field_to_json(Obj, "latestFirmwareURI", latestFirmwareURI); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     void DeviceConnectionInformation::to_json(Poco::JSON::Object &Obj) const { | 	bool DeviceInformation::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         field_to_json(Obj, "serialNumber", serialNumber); | 		try { | ||||||
|         field_to_json(Obj, "revision", revision); | 			field_from_json(Obj, "serialNumber", serialNumber); | ||||||
|         field_to_json(Obj, "deviceType", deviceType); | 			field_from_json(Obj, "history", history); | ||||||
|         field_to_json(Obj, "endPoint", endPoint); | 			field_from_json(Obj, "currentFirmware", currentFirmware); | ||||||
|         field_to_json(Obj, "lastUpdate", lastUpdate); | 			field_from_json(Obj, "currentFirmwareDate", currentFirmwareDate); | ||||||
|         field_to_json(Obj, "status", status); | 			field_from_json(Obj, "latestFirmware", latestFirmware); | ||||||
|     } | 			field_from_json(Obj, "latestFirmwareDate", latestFirmwareDate); | ||||||
|  | 			field_from_json(Obj, "latestFirmwareAvailable", latestFirmwareAvailable); | ||||||
|  | 			field_from_json(Obj, "latestFirmwareURI", latestFirmwareURI); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (...) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     bool DeviceConnectionInformation::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	void DeviceCurrentInfo::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         try { | 		field_to_json(Obj, "serialNumber", serialNumber); | ||||||
|             field_from_json(Obj, "serialNumber", serialNumber); | 		field_to_json(Obj, "revision", revision); | ||||||
|             field_from_json(Obj, "revision", revision); | 		field_to_json(Obj, "upgraded", upgraded); | ||||||
|             field_from_json(Obj, "deviceType", deviceType); | 	} | ||||||
|             field_from_json(Obj, "endPoint", endPoint); |  | ||||||
|             field_from_json(Obj, "lastUpdate", lastUpdate); |  | ||||||
|             field_from_json(Obj, "status", status); |  | ||||||
|             return true; |  | ||||||
|         } catch(...) { |  | ||||||
|  |  | ||||||
|         } | 	bool DeviceCurrentInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         return false; | 		try { | ||||||
|     } | 			field_from_json(Obj, "serialNumber", serialNumber); | ||||||
|  | 			field_from_json(Obj, "revision", revision); | ||||||
|  | 			field_from_json(Obj, "upgraded", upgraded); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (...) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|     void DeviceReport::to_json(Poco::JSON::Object &Obj) const { | 	void DeviceCurrentInfoList::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         field_to_json(Obj, "ouis",OUI_); | 		field_to_json(Obj, "devices", devices); | ||||||
|         field_to_json(Obj, "revisions", Revisions_); | 	} | ||||||
|         field_to_json(Obj, "deviceTypes", DeviceTypes_); |  | ||||||
|         field_to_json(Obj, "status", Status_); |  | ||||||
|         field_to_json(Obj, "endPoints", EndPoints_); |  | ||||||
|         field_to_json(Obj, "usingLatest", UsingLatest_); |  | ||||||
|         field_to_json(Obj, "unknownFirmwares", UnknownFirmwares_); |  | ||||||
|         field_to_json(Obj,"snapshot",snapshot); |  | ||||||
|         field_to_json(Obj,"numberOfDevices",numberOfDevices); |  | ||||||
|         field_to_json(Obj, "totalSecondsOld", totalSecondsOld_); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void DeviceReport::reset() { | 	bool DeviceCurrentInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         OUI_.clear(); | 		try { | ||||||
|         Revisions_.clear(); | 			field_from_json(Obj, "devices", devices); | ||||||
|         DeviceTypes_.clear(); | 			return true; | ||||||
|         Status_.clear(); | 		} catch (...) { | ||||||
|         EndPoints_.clear(); | 		} | ||||||
|         UsingLatest_.clear(); | 		return false; | ||||||
|         UnknownFirmwares_.clear(); | 	} | ||||||
|         totalSecondsOld_.clear(); |  | ||||||
|         numberOfDevices = 0 ; |  | ||||||
|         snapshot = OpenWifi::Now(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool DeviceReport::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) { | } // namespace OpenWifi::FMSObjects | ||||||
|         try { |  | ||||||
|  |  | ||||||
|             return true; |  | ||||||
|         } catch (...) { |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void DeviceInformation::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
|         field_to_json(Obj, "serialNumber",serialNumber); |  | ||||||
|         field_to_json(Obj, "history", history); |  | ||||||
|         field_to_json(Obj, "currentFirmware", currentFirmware); |  | ||||||
|         field_to_json(Obj, "currentFirmwareDate", currentFirmwareDate); |  | ||||||
|         field_to_json(Obj, "latestFirmware", latestFirmware); |  | ||||||
|         field_to_json(Obj, "latestFirmwareDate", latestFirmwareDate); |  | ||||||
|         field_to_json(Obj, "latestFirmwareAvailable",latestFirmwareAvailable); |  | ||||||
|         field_to_json(Obj, "latestFirmwareURI",latestFirmwareURI); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool DeviceInformation::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
|         try { |  | ||||||
|             field_from_json(Obj, "serialNumber",serialNumber); |  | ||||||
|             field_from_json(Obj, "history", history); |  | ||||||
|             field_from_json(Obj, "currentFirmware", currentFirmware); |  | ||||||
|             field_from_json(Obj, "currentFirmwareDate", currentFirmwareDate); |  | ||||||
|             field_from_json(Obj, "latestFirmware", latestFirmware); |  | ||||||
|             field_from_json(Obj, "latestFirmwareDate", latestFirmwareDate); |  | ||||||
|             field_from_json(Obj, "latestFirmwareAvailable",latestFirmwareAvailable); |  | ||||||
|             field_from_json(Obj, "latestFirmwareURI",latestFirmwareURI); |  | ||||||
|             return true; |  | ||||||
|         } catch(...) { |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void DeviceCurrentInfo::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
|         field_to_json(Obj, "serialNumber",serialNumber); |  | ||||||
|         field_to_json(Obj, "revision", revision); |  | ||||||
|         field_to_json(Obj, "upgraded", upgraded); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool DeviceCurrentInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
|         try { |  | ||||||
|             field_from_json(Obj, "serialNumber",serialNumber); |  | ||||||
|             field_from_json(Obj, "revision", revision); |  | ||||||
|             field_from_json(Obj, "upgraded", upgraded); |  | ||||||
|             return true; |  | ||||||
|         } catch(...) { |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void DeviceCurrentInfoList::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
|         field_to_json(Obj, "devices",devices); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool DeviceCurrentInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
|         try { |  | ||||||
|             field_from_json(Obj, "devices",devices); |  | ||||||
|             return true; |  | ||||||
|         } catch(...) { |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -11,149 +11,149 @@ | |||||||
|  |  | ||||||
| namespace OpenWifi::FMSObjects { | namespace OpenWifi::FMSObjects { | ||||||
|  |  | ||||||
|     struct Firmware { | 	struct Firmware { | ||||||
|         std::string     id; | 		std::string id; | ||||||
|         std::string     release; | 		std::string release; | ||||||
|         std::string     deviceType; | 		std::string deviceType; | ||||||
|         std::string     description; | 		std::string description; | ||||||
|         std::string     revision; | 		std::string revision; | ||||||
|         std::string     uri; | 		std::string uri; | ||||||
|         std::string     image; | 		std::string image; | ||||||
|         uint64_t        imageDate=0; | 		uint64_t imageDate = 0; | ||||||
|         uint64_t        size=0; | 		uint64_t size = 0; | ||||||
|         uint64_t        downloadCount=0; | 		uint64_t downloadCount = 0; | ||||||
|         std::string     firmwareHash; | 		std::string firmwareHash; | ||||||
|         std::string     owner; | 		std::string owner; | ||||||
|         std::string     location; | 		std::string location; | ||||||
|         std::string     uploader; | 		std::string uploader; | ||||||
|         std::string     digest; | 		std::string digest; | ||||||
|         bool            latest=false; | 		bool latest = false; | ||||||
|         SecurityObjects::NoteInfoVec    notes; | 		SecurityObjects::NoteInfoVec notes; | ||||||
|         uint64_t        created=0; | 		uint64_t created = 0; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|     typedef std::vector<Firmware>    FirmwareVec; | 	typedef std::vector<Firmware> FirmwareVec; | ||||||
|  |  | ||||||
|     struct FirmwareList { | 	struct FirmwareList { | ||||||
|         FirmwareVec  firmwares; | 		FirmwareVec firmwares; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     struct DeviceType { | 	struct DeviceType { | ||||||
|         std::string id; | 		std::string id; | ||||||
|         std::string deviceType; | 		std::string deviceType; | ||||||
|         std::string manufacturer; | 		std::string manufacturer; | ||||||
|         std::string model; | 		std::string model; | ||||||
|         std::string policy; | 		std::string policy; | ||||||
|         SecurityObjects::NoteInfoVec notes; | 		SecurityObjects::NoteInfoVec notes; | ||||||
|         uint64_t lastUpdate=0; | 		uint64_t lastUpdate = 0; | ||||||
|         uint64_t created=0; | 		uint64_t created = 0; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|     typedef std::vector<DeviceType> DeviceTypeVec; | 	typedef std::vector<DeviceType> DeviceTypeVec; | ||||||
|  |  | ||||||
|     struct DeviceTypeList { | 	struct DeviceTypeList { | ||||||
|         DeviceTypeVec   deviceTypes; | 		DeviceTypeVec deviceTypes; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     struct RevisionHistoryEntry { | 	struct RevisionHistoryEntry { | ||||||
|         std::string id; | 		std::string id; | ||||||
|         std::string serialNumber; | 		std::string serialNumber; | ||||||
|         std::string fromRelease; | 		std::string fromRelease; | ||||||
|         std::string toRelease; | 		std::string toRelease; | ||||||
|         std::string commandUUID; | 		std::string commandUUID; | ||||||
|         std::string revisionId; | 		std::string revisionId; | ||||||
|         uint64_t    upgraded; | 		uint64_t upgraded; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|     typedef std::vector<RevisionHistoryEntry>   RevisionHistoryEntryVec; | 	typedef std::vector<RevisionHistoryEntry> RevisionHistoryEntryVec; | ||||||
|  |  | ||||||
|     struct RevisionHistoryEntryList { | 	struct RevisionHistoryEntryList { | ||||||
|         RevisionHistoryEntryVec history; | 		RevisionHistoryEntryVec history; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     struct FirmwareAgeDetails { | 	struct FirmwareAgeDetails { | ||||||
|         std::string latestId; | 		std::string latestId; | ||||||
|         std::string image; | 		std::string image; | ||||||
|         uint64_t imageDate; | 		uint64_t imageDate; | ||||||
|         std::string revision; | 		std::string revision; | ||||||
|         std::string uri; | 		std::string uri; | ||||||
|         uint64_t age=0; | 		uint64_t age = 0; | ||||||
|         bool latest=true; | 		bool latest = true; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     struct DeviceConnectionInformation { | 	struct DeviceConnectionInformation { | ||||||
|         std::string serialNumber; | 		std::string serialNumber; | ||||||
|         std::string revision; | 		std::string revision; | ||||||
|         std::string deviceType; | 		std::string deviceType; | ||||||
|         std::string endPoint; | 		std::string endPoint; | ||||||
|         uint64_t    lastUpdate; | 		uint64_t lastUpdate; | ||||||
|         std::string status; | 		std::string status; | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     struct DeviceReport { | 	struct DeviceReport { | ||||||
|         uint64_t               snapshot=0; | 		uint64_t snapshot = 0; | ||||||
|         uint64_t               numberOfDevices=0; | 		uint64_t numberOfDevices = 0; | ||||||
|         Types::CountedMap      OUI_; | 		Types::CountedMap OUI_; | ||||||
|         Types::CountedMap      Revisions_; | 		Types::CountedMap Revisions_; | ||||||
|         Types::CountedMap      DeviceTypes_; | 		Types::CountedMap DeviceTypes_; | ||||||
|         Types::CountedMap      Status_; | 		Types::CountedMap Status_; | ||||||
|         Types::CountedMap      EndPoints_; | 		Types::CountedMap EndPoints_; | ||||||
|         Types::CountedMap      UsingLatest_; | 		Types::CountedMap UsingLatest_; | ||||||
|         Types::CountedMap      UnknownFirmwares_; | 		Types::CountedMap UnknownFirmwares_; | ||||||
|         Types::CountedMap      totalSecondsOld_; | 		Types::CountedMap totalSecondsOld_; | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         void reset(); | 		void reset(); | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     struct DeviceInformation { | 	struct DeviceInformation { | ||||||
|         std::string                 serialNumber; | 		std::string serialNumber; | ||||||
|         RevisionHistoryEntryList    history; | 		RevisionHistoryEntryList history; | ||||||
|         std::string                 currentFirmware; | 		std::string currentFirmware; | ||||||
|         uint64_t                    currentFirmwareDate=0; | 		uint64_t currentFirmwareDate = 0; | ||||||
|         std::string                 latestFirmware; | 		std::string latestFirmware; | ||||||
|         uint64_t                    latestFirmwareDate=0; | 		uint64_t latestFirmwareDate = 0; | ||||||
|         bool                        latestFirmwareAvailable; | 		bool latestFirmwareAvailable; | ||||||
|         std::string                 latestFirmwareURI; | 		std::string latestFirmwareURI; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     struct DeviceCurrentInfo { | 	struct DeviceCurrentInfo { | ||||||
|         std::string                 serialNumber; | 		std::string serialNumber; | ||||||
|         std::string                 revision; | 		std::string revision; | ||||||
|         uint64_t                    upgraded=0; | 		uint64_t upgraded = 0; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
|     struct DeviceCurrentInfoList { | 	struct DeviceCurrentInfoList { | ||||||
|         std::vector<DeviceCurrentInfo>  devices; | 		std::vector<DeviceCurrentInfo> devices; | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|     }; | 	}; | ||||||
|  |  | ||||||
| } | } // namespace OpenWifi::FMSObjects | ||||||
|   | |||||||
| @@ -10,45 +10,55 @@ | |||||||
| #include "Poco/JSON/Stringifier.h" | #include "Poco/JSON/Stringifier.h" | ||||||
|  |  | ||||||
| #include "Daemon.h" | #include "Daemon.h" | ||||||
| #ifdef	TIP_GATEWAY_SERVICE | #ifdef TIP_GATEWAY_SERVICE | ||||||
| #include "DeviceRegistry.h" | #include "AP_WS_Server.h" | ||||||
| #include "CapabilitiesCache.h" | #include "CapabilitiesCache.h" | ||||||
|  | #include "RADIUSSessionTracker.h" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #include "RESTAPI_GWobjects.h" | #include "RESTAPI_GWobjects.h" | ||||||
| #include "framework/MicroService.h" | #include "framework/RESTAPI_utils.h" | ||||||
|  | #include "framework/utils.h" | ||||||
|  |  | ||||||
| using OpenWifi::RESTAPI_utils::field_to_json; |  | ||||||
| using OpenWifi::RESTAPI_utils::field_from_json; |  | ||||||
| using OpenWifi::RESTAPI_utils::EmbedDocument; | using OpenWifi::RESTAPI_utils::EmbedDocument; | ||||||
|  | using OpenWifi::RESTAPI_utils::field_from_json; | ||||||
|  | using OpenWifi::RESTAPI_utils::field_to_json; | ||||||
|  |  | ||||||
| namespace OpenWifi::GWObjects { | namespace OpenWifi::GWObjects { | ||||||
|  |  | ||||||
| 	void Device::to_json(Poco::JSON::Object &Obj) const { | 	void Device::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		field_to_json(Obj,"serialNumber", SerialNumber); | 		field_to_json(Obj, "serialNumber", SerialNumber); | ||||||
| #ifdef TIP_GATEWAY_SERVICE | #ifdef TIP_GATEWAY_SERVICE | ||||||
| 		field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible)); | 		field_to_json(Obj, "deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible)); | ||||||
|  | 		field_to_json(Obj, "hasRADIUSSessions", RADIUSSessionTracker()->HasSessions(SerialNumber)); | ||||||
| #endif | #endif | ||||||
| 		field_to_json(Obj,"macAddress", MACAddress); | 		field_to_json(Obj, "macAddress", MACAddress); | ||||||
| 		field_to_json(Obj,"manufacturer", Manufacturer); | 		field_to_json(Obj, "manufacturer", Manufacturer); | ||||||
| 		field_to_json(Obj,"UUID", UUID); | 		field_to_json(Obj, "UUID", UUID); | ||||||
| 		EmbedDocument("configuration", Obj, Configuration); | 		EmbedDocument("configuration", Obj, Configuration); | ||||||
| 		field_to_json(Obj,"notes", Notes); | 		field_to_json(Obj, "notes", Notes); | ||||||
| 		field_to_json(Obj,"createdTimestamp", CreationTimestamp); | 		field_to_json(Obj, "createdTimestamp", CreationTimestamp); | ||||||
| 		field_to_json(Obj,"lastConfigurationChange", LastConfigurationChange); | 		field_to_json(Obj, "lastConfigurationChange", LastConfigurationChange); | ||||||
| 		field_to_json(Obj,"lastConfigurationDownload", LastConfigurationDownload); | 		field_to_json(Obj, "lastConfigurationDownload", LastConfigurationDownload); | ||||||
| 		field_to_json(Obj,"lastFWUpdate", LastFWUpdate); | 		field_to_json(Obj, "lastFWUpdate", LastFWUpdate); | ||||||
| 		field_to_json(Obj,"owner", Owner); | 		field_to_json(Obj, "owner", Owner); | ||||||
| 		field_to_json(Obj,"location", Location); | 		field_to_json(Obj, "location", Location); | ||||||
| 		field_to_json(Obj,"venue", Venue); | 		field_to_json(Obj, "venue", Venue); | ||||||
| 		field_to_json(Obj,"firmware", Firmware); | 		field_to_json(Obj, "firmware", Firmware); | ||||||
| 		field_to_json(Obj,"compatible", Compatible); | 		field_to_json(Obj, "compatible", Compatible); | ||||||
| 		field_to_json(Obj,"fwUpdatePolicy", FWUpdatePolicy); | 		field_to_json(Obj, "fwUpdatePolicy", FWUpdatePolicy); | ||||||
| 		field_to_json(Obj,"devicePassword", DevicePassword); | 		field_to_json(Obj, "devicePassword", DevicePassword); | ||||||
| 		field_to_json(Obj,"subscriber", subscriber); | 		field_to_json(Obj, "subscriber", subscriber); | ||||||
| 		field_to_json(Obj,"entity", entity); | 		field_to_json(Obj, "entity", entity); | ||||||
| 		field_to_json(Obj,"modified", modified); | 		field_to_json(Obj, "modified", modified); | ||||||
| 		field_to_json(Obj,"locale", locale); | 		field_to_json(Obj, "locale", locale); | ||||||
|  | 		field_to_json(Obj, "restrictedDevice", restrictedDevice); | ||||||
|  | 		field_to_json(Obj, "pendingConfiguration", pendingConfiguration); | ||||||
|  | 		field_to_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd); | ||||||
|  | 		field_to_json(Obj, "restrictionDetails", restrictionDetails); | ||||||
|  | 		field_to_json(Obj, "pendingUUID", pendingUUID); | ||||||
|  | 		field_to_json(Obj, "simulated", simulated); | ||||||
|  | 		field_to_json(Obj, "lastRecordedContact", lastRecordedContact); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void Device::to_json_with_status(Poco::JSON::Object &Obj) const { | 	void Device::to_json_with_status(Poco::JSON::Object &Obj) const { | ||||||
| @@ -57,37 +67,61 @@ namespace OpenWifi::GWObjects { | |||||||
| #ifdef TIP_GATEWAY_SERVICE | #ifdef TIP_GATEWAY_SERVICE | ||||||
| 		ConnectionState ConState; | 		ConnectionState ConState; | ||||||
|  |  | ||||||
| 		if (DeviceRegistry()->GetState(SerialNumber, ConState)) { | 		if (AP_WS_Server()->GetState(SerialNumber, ConState)) { | ||||||
| 			ConState.to_json(Obj); | 			ConState.to_json(SerialNumber,Obj); | ||||||
| 		} else { | 		} else { | ||||||
| 			field_to_json(Obj,"ipAddress", ""); | 			field_to_json(Obj, "ipAddress", ""); | ||||||
| 			field_to_json(Obj,"txBytes", (uint64_t) 0); | 			field_to_json(Obj, "txBytes", (uint64_t)0); | ||||||
| 			field_to_json(Obj,"rxBytes", (uint64_t )0); | 			field_to_json(Obj, "rxBytes", (uint64_t)0); | ||||||
| 			field_to_json(Obj,"messageCount", (uint64_t )0); | 			field_to_json(Obj, "messageCount", (uint64_t)0); | ||||||
| 			field_to_json(Obj,"connected", false); | 			field_to_json(Obj, "connected", false); | ||||||
| 			field_to_json(Obj,"lastContact", ""); | 			field_to_json(Obj, "lastContact", ""); | ||||||
| 			field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); | 			field_to_json(Obj, "verifiedCertificate", "NO_CERTIFICATE"); | ||||||
| 			field_to_json(Obj,"associations_2G", (uint64_t) 0); | 			field_to_json(Obj, "associations_2G", (uint64_t)0); | ||||||
| 			field_to_json(Obj,"associations_5G", (uint64_t) 0); | 			field_to_json(Obj, "associations_5G", (uint64_t)0); | ||||||
|  | 			field_to_json(Obj, "associations_6G", (uint64_t)0); | ||||||
|  | 			field_to_json(Obj, "hasRADIUSSessions", false); | ||||||
|  | 			field_to_json(Obj, "hasGPS", ConState.hasGPS); | ||||||
|  | 			field_to_json(Obj, "sanity", ConState.sanity); | ||||||
|  | 			field_to_json(Obj, "memoryUsed", ConState.memoryUsed); | ||||||
|  | 			field_to_json(Obj, "sanity", ConState.sanity); | ||||||
|  | 			field_to_json(Obj, "load", ConState.load); | ||||||
|  | 			field_to_json(Obj, "temperature", ConState.temperature); | ||||||
| 		} | 		} | ||||||
| #endif | #endif | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool Device::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool Device::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
| 		try { | 		try { | ||||||
| 			field_from_json(Obj,"serialNumber",SerialNumber); | 			field_from_json(Obj, "serialNumber", SerialNumber); | ||||||
| 			field_from_json(Obj,"deviceType",DeviceType); | 			field_from_json(Obj, "deviceType", DeviceType); | ||||||
| 			field_from_json(Obj,"macAddress",MACAddress); | 			field_from_json(Obj, "macAddress", MACAddress); | ||||||
| 			field_from_json(Obj,"configuration",Configuration); | 			field_from_json(Obj, "manufacturer", Manufacturer); | ||||||
| 			field_from_json(Obj,"notes",Notes); | 			field_from_json(Obj, "UUID", UUID); | ||||||
| 			field_from_json(Obj,"manufacturer",Manufacturer); | 			field_from_json(Obj, "configuration", Configuration); | ||||||
| 			field_from_json(Obj,"owner",Owner); | 			field_from_json(Obj, "notes", Notes); | ||||||
| 			field_from_json(Obj,"location",Location); | 			field_from_json(Obj, "createdTimestamp", CreationTimestamp); | ||||||
| 			field_from_json(Obj,"venue",Venue); | 			field_from_json(Obj, "lastConfigurationChange", LastConfigurationChange); | ||||||
| 			field_from_json(Obj,"compatible",Compatible); | 			field_from_json(Obj, "lastConfigurationDownload", LastConfigurationDownload); | ||||||
| 			field_from_json(Obj,"subscriber", subscriber); | 			field_from_json(Obj, "lastFWUpdate", LastFWUpdate); | ||||||
| 			field_from_json(Obj,"entity", entity); | 			field_from_json(Obj, "owner", Owner); | ||||||
| 			field_from_json(Obj,"locale", locale); | 			field_from_json(Obj, "location", Location); | ||||||
|  | 			field_from_json(Obj, "venue", Venue); | ||||||
|  | 			field_from_json(Obj, "firmware", Firmware); | ||||||
|  | 			field_from_json(Obj, "compatible", Compatible); | ||||||
|  | 			field_from_json(Obj, "fwUpdatePolicy", FWUpdatePolicy); | ||||||
|  | 			field_from_json(Obj, "devicePassword", DevicePassword); | ||||||
|  | 			field_from_json(Obj, "subscriber", subscriber); | ||||||
|  | 			field_from_json(Obj, "entity", entity); | ||||||
|  | 			field_from_json(Obj, "modified", modified); | ||||||
|  | 			field_from_json(Obj, "locale", locale); | ||||||
|  | 			field_from_json(Obj, "restrictedDevice", restrictedDevice); | ||||||
|  | 			field_from_json(Obj, "pendingConfiguration", pendingConfiguration); | ||||||
|  | 			field_from_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd); | ||||||
|  | 			field_from_json(Obj, "restrictionDetails", restrictionDetails); | ||||||
|  | 			field_from_json(Obj, "pendingUUID", pendingUUID); | ||||||
|  | 			field_from_json(Obj, "simulated", simulated); | ||||||
|  | 			field_from_json(Obj, "lastRecordedContact", lastRecordedContact); | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
| @@ -95,73 +129,101 @@ namespace OpenWifi::GWObjects { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void Device::Print() const { | 	void Device::Print() const { | ||||||
| 		std::cout << "Device: " << SerialNumber << " DeviceType:" << DeviceType << " MACAddress:" << MACAddress << " Manufacturer:" | 		std::cout << "Device: " << SerialNumber << " DeviceType:" << DeviceType | ||||||
| 				  << Manufacturer << " " << Configuration << std::endl; | 				  << " MACAddress:" << MACAddress << " Manufacturer:" << Manufacturer << " " | ||||||
|  | 				  << Configuration << std::endl; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void Statistics::to_json(Poco::JSON::Object &Obj) const { | 	void Statistics::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		EmbedDocument("data", Obj, Data); | 		EmbedDocument("data", Obj, Data); | ||||||
| 		field_to_json(Obj,"UUID", UUID); | 		field_to_json(Obj, "UUID", UUID); | ||||||
| 		field_to_json(Obj,"recorded", Recorded); | 		field_to_json(Obj, "recorded", Recorded); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void Capabilities::to_json(Poco::JSON::Object &Obj) const { | 	void Capabilities::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		EmbedDocument("capabilities", Obj, Capabilities); | 		EmbedDocument("capabilities", Obj, Capabilities); | ||||||
| 		field_to_json(Obj,"firstUpdate", FirstUpdate); | 		field_to_json(Obj, "firstUpdate", FirstUpdate); | ||||||
| 		field_to_json(Obj,"lastUpdate", LastUpdate); | 		field_to_json(Obj, "lastUpdate", LastUpdate); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void DeviceLog::to_json(Poco::JSON::Object &Obj) const { | 	void DeviceLog::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		EmbedDocument("data", Obj, Data); | 		EmbedDocument("data", Obj, Data); | ||||||
| 		field_to_json(Obj,"log", Log); | 		field_to_json(Obj, "log", Log); | ||||||
| 		field_to_json(Obj,"severity", Severity); | 		field_to_json(Obj, "severity", Severity); | ||||||
| 		field_to_json(Obj,"recorded", Recorded); | 		field_to_json(Obj, "recorded", Recorded); | ||||||
| 		field_to_json(Obj,"logType", LogType); | 		field_to_json(Obj, "logType", LogType); | ||||||
| 		field_to_json(Obj,"UUID", UUID); | 		field_to_json(Obj, "UUID", UUID); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void HealthCheck::to_json(Poco::JSON::Object &Obj) const { | 	void HealthCheck::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		EmbedDocument("values", Obj, Data); | 		EmbedDocument("values", Obj, Data); | ||||||
| 		field_to_json(Obj,"UUID", UUID); | 		field_to_json(Obj, "UUID", UUID); | ||||||
| 		field_to_json(Obj,"sanity", Sanity); | 		field_to_json(Obj, "sanity", Sanity); | ||||||
| 		field_to_json(Obj,"recorded", Recorded); | 		field_to_json(Obj, "recorded", Recorded); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void DefaultConfiguration::to_json(Poco::JSON::Object &Obj) const { | 	void DefaultConfiguration::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		EmbedDocument("configuration", Obj, Configuration); | 		EmbedDocument("configuration", Obj, Configuration); | ||||||
| 		field_to_json(Obj,"name", Name); | 		field_to_json(Obj, "name", Name); | ||||||
| 		field_to_json(Obj,"modelIds", Models); | 		field_to_json(Obj, "modelIds", Models); | ||||||
| 		field_to_json(Obj,"description", Description); | 		field_to_json(Obj, "description", Description); | ||||||
| 		field_to_json(Obj,"created", Created); | 		field_to_json(Obj, "created", Created); | ||||||
| 		field_to_json(Obj,"lastModified", LastModified); | 		field_to_json(Obj, "lastModified", LastModified); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void DefaultFirmware::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj, "deviceType", deviceType); | ||||||
|  | 		field_to_json(Obj, "description", Description); | ||||||
|  | 		field_to_json(Obj, "uri", uri); | ||||||
|  | 		field_to_json(Obj, "revision", revision); | ||||||
|  | 		field_to_json(Obj, "imageCreationDate", imageCreationDate); | ||||||
|  | 		field_to_json(Obj, "created", Created); | ||||||
|  | 		field_to_json(Obj, "lastModified", LastModified); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool DefaultFirmware::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj, "deviceType", deviceType); | ||||||
|  | 			field_from_json(Obj, "description", Description); | ||||||
|  | 			field_from_json(Obj, "uri", uri); | ||||||
|  | 			field_from_json(Obj, "revision", revision); | ||||||
|  | 			field_from_json(Obj, "imageCreationDate", imageCreationDate); | ||||||
|  | 			field_from_json(Obj, "created", Created); | ||||||
|  | 			field_from_json(Obj, "lastModified", LastModified); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void CommandDetails::to_json(Poco::JSON::Object &Obj) const { | 	void CommandDetails::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		EmbedDocument("details", Obj, Details); | 		EmbedDocument("details", Obj, Details); | ||||||
| 		EmbedDocument("results", Obj, Results); | 		EmbedDocument("results", Obj, Results); | ||||||
| 		field_to_json(Obj,"UUID", UUID); | 		field_to_json(Obj, "UUID", UUID); | ||||||
| 		field_to_json(Obj,"serialNumber", SerialNumber); | 		field_to_json(Obj, "serialNumber", SerialNumber); | ||||||
| 		field_to_json(Obj,"command", Command); | 		field_to_json(Obj, "command", Command); | ||||||
| 		field_to_json(Obj,"errorText", ErrorText); | 		field_to_json(Obj, "errorText", ErrorText); | ||||||
| 		field_to_json(Obj,"submittedBy", SubmittedBy); | 		field_to_json(Obj, "submittedBy", SubmittedBy); | ||||||
| 		field_to_json(Obj,"status", Status); | 		field_to_json(Obj, "status", Status); | ||||||
| 		field_to_json(Obj,"submitted", Submitted); | 		field_to_json(Obj, "submitted", Submitted); | ||||||
| 		field_to_json(Obj,"executed", Executed); | 		field_to_json(Obj, "executed", Executed); | ||||||
| 		field_to_json(Obj,"completed", Completed); | 		field_to_json(Obj, "completed", Completed); | ||||||
| 		field_to_json(Obj,"when", RunAt); | 		field_to_json(Obj, "when", RunAt); | ||||||
| 		field_to_json(Obj,"errorCode", ErrorCode); | 		field_to_json(Obj, "errorCode", ErrorCode); | ||||||
| 		field_to_json(Obj,"custom", Custom); | 		field_to_json(Obj, "custom", Custom); | ||||||
| 		field_to_json(Obj,"waitingForFile", WaitingForFile); | 		field_to_json(Obj, "waitingForFile", WaitingForFile); | ||||||
| 		field_to_json(Obj,"attachFile", AttachDate); | 		field_to_json(Obj, "attachFile", AttachDate); | ||||||
| 		field_to_json(Obj,"executionTime", executionTime); | 		field_to_json(Obj, "executionTime", executionTime); | ||||||
|  | 		field_to_json(Obj, "lastTry", lastTry); | ||||||
|  | 		field_to_json(Obj, "deferred", deferred); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
| 		try { | 		try { | ||||||
| 			field_from_json(Obj,"name",Name); | 			field_from_json(Obj, "name", Name); | ||||||
| 			field_from_json(Obj,"configuration",Configuration); | 			field_from_json(Obj, "configuration", Configuration); | ||||||
| 			field_from_json(Obj,"modelIds",Models); | 			field_from_json(Obj, "modelIds", Models); | ||||||
| 			field_from_json(Obj,"description",Description); | 			field_from_json(Obj, "description", Description); | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
| @@ -169,68 +231,96 @@ namespace OpenWifi::GWObjects { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void BlackListedDevice::to_json(Poco::JSON::Object &Obj) const { | 	void BlackListedDevice::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		field_to_json(Obj,"serialNumber", serialNumber); | 		field_to_json(Obj, "serialNumber", serialNumber); | ||||||
| 		field_to_json(Obj,"author", author); | 		field_to_json(Obj, "author", author); | ||||||
| 		field_to_json(Obj,"reason", reason); | 		field_to_json(Obj, "reason", reason); | ||||||
| 		field_to_json(Obj,"created", created); | 		field_to_json(Obj, "created", created); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool BlackListedDevice::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool BlackListedDevice::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
| 		try { | 		try { | ||||||
| 			field_from_json(Obj,"serialNumber",serialNumber); | 			field_from_json(Obj, "serialNumber", serialNumber); | ||||||
| 			field_from_json(Obj,"author",author); | 			field_from_json(Obj, "author", author); | ||||||
| 			field_from_json(Obj,"reason",reason); | 			field_from_json(Obj, "reason", reason); | ||||||
| 			field_from_json(Obj,"created",created); | 			field_from_json(Obj, "created", created); | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void ConnectionState::to_json(Poco::JSON::Object &Obj) const { | 	void ConnectionState::to_json([[maybe_unused]] const std::string &SerialNumber, Poco::JSON::Object &Obj)  { | ||||||
| 		field_to_json(Obj,"ipAddress", Address); | 		field_to_json(Obj, "ipAddress", Address); | ||||||
| 		field_to_json(Obj,"txBytes", TX); | 		field_to_json(Obj, "txBytes", TX); | ||||||
| 		field_to_json(Obj,"rxBytes", RX); | 		field_to_json(Obj, "rxBytes", RX); | ||||||
| 		field_to_json(Obj,"messageCount", MessageCount); | 		field_to_json(Obj, "messageCount", MessageCount); | ||||||
| 		field_to_json(Obj,"UUID", UUID); | 		field_to_json(Obj, "UUID", UUID); | ||||||
| 		field_to_json(Obj,"connected", Connected); | 		field_to_json(Obj, "connected", Connected); | ||||||
| 		field_to_json(Obj,"firmware", Firmware); | 		field_to_json(Obj, "firmware", Firmware); | ||||||
| 		field_to_json(Obj,"lastContact", LastContact); | 		field_to_json(Obj, "lastContact", LastContact); | ||||||
| 		field_to_json(Obj,"associations_2G", Associations_2G); | 		field_to_json(Obj, "associations_2G", Associations_2G); | ||||||
| 		field_to_json(Obj,"associations_5G", Associations_5G); | 		field_to_json(Obj, "associations_5G", Associations_5G); | ||||||
| 		field_to_json(Obj,"webSocketClients", webSocketClients); | 		field_to_json(Obj, "associations_6G", Associations_6G); | ||||||
| 		field_to_json(Obj,"websocketPackets", websocketPackets); | 		field_to_json(Obj, "webSocketClients", webSocketClients); | ||||||
| 		field_to_json(Obj,"kafkaClients", kafkaClients); | 		field_to_json(Obj, "websocketPackets", websocketPackets); | ||||||
| 		field_to_json(Obj,"kafkaPackets", kafkaPackets); | 		field_to_json(Obj, "kafkaClients", kafkaClients); | ||||||
| 		field_to_json(Obj,"locale", locale); | 		field_to_json(Obj, "kafkaPackets", kafkaPackets); | ||||||
| 		field_to_json(Obj,"started", started); | 		field_to_json(Obj, "locale", locale); | ||||||
| 		field_to_json(Obj,"sessionId", sessionId); | 		field_to_json(Obj, "started", started); | ||||||
| 		field_to_json(Obj,"connectionCompletionTime", connectionCompletionTime); | 		field_to_json(Obj, "sessionId", sessionId); | ||||||
| 		field_to_json(Obj,"totalConnectionTime", OpenWifi::Now() - started); | 		field_to_json(Obj, "connectionCompletionTime", connectionCompletionTime); | ||||||
|  | 		field_to_json(Obj, "totalConnectionTime", Utils::Now() - started); | ||||||
|  | 		field_to_json(Obj, "certificateExpiryDate", certificateExpiryDate); | ||||||
|  | 		field_to_json(Obj, "connectReason", connectReason); | ||||||
|  |  | ||||||
| 		switch(VerifiedCertificate) { | #ifdef TIP_GATEWAY_SERVICE | ||||||
| 			case NO_CERTIFICATE: | 		hasRADIUSSessions = RADIUSSessionTracker()->HasSessions(SerialNumber); | ||||||
| 				field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); break; | 		AP_WS_Server()->ExtendedAttributes(SerialNumber, hasGPS, sanity, | ||||||
| 			case VALID_CERTIFICATE: | 										   memoryUsed, | ||||||
| 				field_to_json(Obj,"verifiedCertificate", "VALID_CERTIFICATE"); break; | 										   load, | ||||||
| 			case MISMATCH_SERIAL: | 										   temperature); | ||||||
| 				field_to_json(Obj,"verifiedCertificate", "MISMATCH_SERIAL"); break; | #endif | ||||||
| 			case VERIFIED: | 		field_to_json(Obj, "hasRADIUSSessions", hasRADIUSSessions ); | ||||||
| 				field_to_json(Obj,"verifiedCertificate", "VERIFIED"); break; | 		field_to_json(Obj, "hasGPS", hasGPS); | ||||||
| 			default: | 		field_to_json(Obj, "sanity", sanity); | ||||||
| 				field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); break; | 		field_to_json(Obj, "memoryUsed", memoryUsed); | ||||||
|  | 		field_to_json(Obj, "sanity", sanity); | ||||||
|  | 		field_to_json(Obj, "load", load); | ||||||
|  | 		field_to_json(Obj, "temperature", temperature); | ||||||
|  |  | ||||||
|  | 		switch (VerifiedCertificate) { | ||||||
|  | 		case NO_CERTIFICATE: | ||||||
|  | 			field_to_json(Obj, "verifiedCertificate", "NO_CERTIFICATE"); | ||||||
|  | 			break; | ||||||
|  | 		case VALID_CERTIFICATE: | ||||||
|  | 			field_to_json(Obj, "verifiedCertificate", "VALID_CERTIFICATE"); | ||||||
|  | 			break; | ||||||
|  | 		case MISMATCH_SERIAL: | ||||||
|  | 			field_to_json(Obj, "verifiedCertificate", "MISMATCH_SERIAL"); | ||||||
|  | 			break; | ||||||
|  | 		case VERIFIED: | ||||||
|  | 			field_to_json(Obj, "verifiedCertificate", "VERIFIED"); | ||||||
|  | 			break; | ||||||
|  | 		case SIMULATED: | ||||||
|  | 			field_to_json(Obj, "verifiedCertificate", "SIMULATED"); | ||||||
|  | 			break; | ||||||
|  | 		default: | ||||||
|  | 			field_to_json(Obj, "verifiedCertificate", "NO_CERTIFICATE"); | ||||||
|  | 			break; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void DeviceConnectionStatistics::to_json(Poco::JSON::Object &Obj) const { | 	void DeviceConnectionStatistics::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		field_to_json(Obj,"averageConnectionTime", averageConnectionTime); | 		field_to_json(Obj, "averageConnectionTime", averageConnectionTime); | ||||||
| 		field_to_json(Obj,"connectedDevices", connectedDevices ); | 		field_to_json(Obj, "connectedDevices", connectedDevices); | ||||||
|  | 		field_to_json(Obj, "connectingDevices", connectingDevices); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool DeviceConnectionStatistics::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool DeviceConnectionStatistics::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
| 		try { | 		try { | ||||||
| 			field_from_json(Obj,"averageConnectionTime", averageConnectionTime); | 			field_from_json(Obj, "averageConnectionTime", averageConnectionTime); | ||||||
| 			field_from_json(Obj,"connectedDevices", connectedDevices ); | 			field_from_json(Obj, "connectedDevices", connectedDevices); | ||||||
|  | 			field_from_json(Obj, "connectingDevices", connectingDevices); | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
| @@ -238,37 +328,37 @@ namespace OpenWifi::GWObjects { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const { | 	void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		field_to_json(Obj,"serialNumber", SerialNumber); | 		field_to_json(Obj, "serialNumber", SerialNumber); | ||||||
| 		field_to_json(Obj,"server", Server); | 		field_to_json(Obj, "server", Server); | ||||||
| 		field_to_json(Obj,"port", Port); | 		field_to_json(Obj, "port", Port); | ||||||
| 		field_to_json(Obj,"token",Token); | 		field_to_json(Obj, "token", Token); | ||||||
| 		field_to_json(Obj,"timeout", TimeOut); | 		field_to_json(Obj, "timeout", TimeOut); | ||||||
| 		field_to_json(Obj,"connectionId",ConnectionId); | 		field_to_json(Obj, "connectionId", ConnectionId); | ||||||
| 		field_to_json(Obj,"commandUUID",CommandUUID); | 		field_to_json(Obj, "commandUUID", CommandUUID); | ||||||
| 		field_to_json(Obj,"started", Started); | 		field_to_json(Obj, "started", Started); | ||||||
| 		field_to_json(Obj,"viewport",ViewPort); | 		field_to_json(Obj, "viewport", ViewPort); | ||||||
| 		field_to_json(Obj,"password",DevicePassword); | 		field_to_json(Obj, "password", DevicePassword); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void Dashboard::to_json(Poco::JSON::Object &Obj) const { | 	void Dashboard::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		field_to_json(Obj,"commands",commands); | 		field_to_json(Obj, "commands", commands); | ||||||
| 		field_to_json(Obj,"upTimes",upTimes); | 		field_to_json(Obj, "upTimes", upTimes); | ||||||
| 		field_to_json(Obj,"memoryUsed",memoryUsed); | 		field_to_json(Obj, "memoryUsed", memoryUsed); | ||||||
| 		field_to_json(Obj,"load1",load1); | 		field_to_json(Obj, "load1", load1); | ||||||
| 		field_to_json(Obj,"load5",load5); | 		field_to_json(Obj, "load5", load5); | ||||||
| 		field_to_json(Obj,"load15",load15); | 		field_to_json(Obj, "load15", load15); | ||||||
| 		field_to_json(Obj,"vendors",vendors); | 		field_to_json(Obj, "vendors", vendors); | ||||||
| 		field_to_json(Obj,"status",status); | 		field_to_json(Obj, "status", status); | ||||||
| 		field_to_json(Obj,"deviceType",deviceType); | 		field_to_json(Obj, "deviceType", deviceType); | ||||||
| 		field_to_json(Obj,"healths",healths); | 		field_to_json(Obj, "healths", healths); | ||||||
| 		field_to_json(Obj,"certificates",certificates); | 		field_to_json(Obj, "certificates", certificates); | ||||||
| 		field_to_json(Obj,"lastContact",lastContact); | 		field_to_json(Obj, "lastContact", lastContact); | ||||||
| 		field_to_json(Obj,"associations",associations); | 		field_to_json(Obj, "associations", associations); | ||||||
| 		field_to_json(Obj,"snapshot",snapshot); | 		field_to_json(Obj, "snapshot", snapshot); | ||||||
| 		field_to_json(Obj,"numberOfDevices",numberOfDevices); | 		field_to_json(Obj, "numberOfDevices", numberOfDevices); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void Dashboard::reset()  { | 	void Dashboard::reset() { | ||||||
| 		commands.clear(); | 		commands.clear(); | ||||||
| 		upTimes.clear(); | 		upTimes.clear(); | ||||||
| 		memoryUsed.clear(); | 		memoryUsed.clear(); | ||||||
| @@ -282,32 +372,38 @@ namespace OpenWifi::GWObjects { | |||||||
| 		certificates.clear(); | 		certificates.clear(); | ||||||
| 		lastContact.clear(); | 		lastContact.clear(); | ||||||
| 		associations.clear(); | 		associations.clear(); | ||||||
| 		numberOfDevices = 0 ; | 		numberOfDevices = 0; | ||||||
| 		snapshot = OpenWifi::Now(); | 		snapshot = Utils::Now(); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const{ | 	void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		field_to_json(Obj,"deviceType", deviceType); | 		field_to_json(Obj, "deviceType", deviceType); | ||||||
| 		field_to_json(Obj,"capabilities", capabilities); | 		field_to_json(Obj, "capabilities", capabilities); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	void ScriptRequest::to_json(Poco::JSON::Object &Obj) const { | 	void ScriptRequest::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		field_to_json(Obj,"serialNumber",serialNumber); | 		field_to_json(Obj, "serialNumber", serialNumber); | ||||||
| 		field_to_json(Obj,"timeout",timeout); | 		field_to_json(Obj, "timeout", timeout); | ||||||
| 		field_to_json(Obj,"type",type); | 		field_to_json(Obj, "type", type); | ||||||
| 		field_to_json(Obj,"script",script); | 		field_to_json(Obj, "scriptId", scriptId); | ||||||
| 		field_to_json(Obj,"scriptId",scriptId); | 		field_to_json(Obj, "script", script); | ||||||
| 		field_to_json(Obj,"when",when); | 		field_to_json(Obj, "when", when); | ||||||
|  | 		field_to_json(Obj, "signature", signature); | ||||||
|  | 		field_to_json(Obj, "deferred", deferred); | ||||||
|  | 		field_to_json(Obj, "uri", uri); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool ScriptRequest::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool ScriptRequest::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
| 		try { | 		try { | ||||||
| 			field_from_json(Obj,"serialNumber",serialNumber); | 			field_from_json(Obj, "serialNumber", serialNumber); | ||||||
| 			field_from_json(Obj,"timeout",timeout); | 			field_from_json(Obj, "timeout", timeout); | ||||||
| 			field_from_json(Obj,"type",type); | 			field_from_json(Obj, "type", type); | ||||||
| 			field_from_json(Obj,"script",script); | 			field_from_json(Obj, "script", script); | ||||||
| 			field_from_json(Obj,"scriptId",scriptId); | 			field_from_json(Obj, "scriptId", scriptId); | ||||||
| 			field_from_json(Obj,"when",when); | 			field_from_json(Obj, "when", when); | ||||||
|  | 			field_from_json(Obj, "signature", signature); | ||||||
|  | 			field_from_json(Obj, "deferred", deferred); | ||||||
|  | 			field_from_json(Obj, "uri", uri); | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
| @@ -315,12 +411,12 @@ namespace OpenWifi::GWObjects { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void RadiusProxyPoolList::to_json(Poco::JSON::Object &Obj) const { | 	void RadiusProxyPoolList::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		field_to_json(Obj,"pools",pools); | 		field_to_json(Obj, "pools", pools); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool RadiusProxyPoolList::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool RadiusProxyPoolList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
| 		try { | 		try { | ||||||
| 			field_from_json(Obj,"pools",pools); | 			field_from_json(Obj, "pools", pools); | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
| @@ -328,22 +424,30 @@ namespace OpenWifi::GWObjects { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void RadiusProxyPool::to_json(Poco::JSON::Object &Obj) const { | 	void RadiusProxyPool::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		field_to_json(Obj,"name",name); | 		field_to_json(Obj, "name", name); | ||||||
| 		field_to_json(Obj,"description",description); | 		field_to_json(Obj, "description", description); | ||||||
| 		field_to_json(Obj,"authConfig",authConfig); | 		field_to_json(Obj, "authConfig", authConfig); | ||||||
| 		field_to_json(Obj,"acctConfig",acctConfig); | 		field_to_json(Obj, "acctConfig", acctConfig); | ||||||
| 		field_to_json(Obj,"coaConfig",coaConfig); | 		field_to_json(Obj, "coaConfig", coaConfig); | ||||||
| 		field_to_json(Obj,"useByDefault",useByDefault); | 		field_to_json(Obj, "useByDefault", useByDefault); | ||||||
|  | 		field_to_json(Obj, "radsecKeepAlive", radsecKeepAlive); | ||||||
|  | 		field_to_json(Obj, "poolProxyIp", poolProxyIp); | ||||||
|  | 		field_to_json(Obj, "radsecPoolType", radsecPoolType); | ||||||
|  | 		field_to_json(Obj, "enabled", enabled); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
| 		try { | 		try { | ||||||
| 			field_from_json(Obj,"name",name); | 			field_from_json(Obj, "name", name); | ||||||
| 			field_from_json(Obj,"description",description); | 			field_from_json(Obj, "description", description); | ||||||
| 			field_from_json(Obj,"authConfig",authConfig); | 			field_from_json(Obj, "authConfig", authConfig); | ||||||
| 			field_from_json(Obj,"acctConfig",acctConfig); | 			field_from_json(Obj, "acctConfig", acctConfig); | ||||||
| 			field_from_json(Obj,"coaConfig",coaConfig); | 			field_from_json(Obj, "coaConfig", coaConfig); | ||||||
| 			field_from_json(Obj,"useByDefault",useByDefault); | 			field_from_json(Obj, "useByDefault", useByDefault); | ||||||
|  | 			field_from_json(Obj, "radsecKeepAlive", radsecKeepAlive); | ||||||
|  | 			field_from_json(Obj, "poolProxyIp", poolProxyIp); | ||||||
|  | 			field_from_json(Obj, "radsecPoolType", radsecPoolType); | ||||||
|  | 			field_from_json(Obj, "enabled", enabled); | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
| @@ -351,20 +455,20 @@ namespace OpenWifi::GWObjects { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void RadiusProxyServerConfig::to_json(Poco::JSON::Object &Obj) const { | 	void RadiusProxyServerConfig::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		field_to_json(Obj,"strategy",strategy); | 		field_to_json(Obj, "strategy", strategy); | ||||||
| 		field_to_json(Obj,"monitor",monitor); | 		field_to_json(Obj, "monitor", monitor); | ||||||
| 		field_to_json(Obj,"monitorMethod",monitorMethod); | 		field_to_json(Obj, "monitorMethod", monitorMethod); | ||||||
| 		field_to_json(Obj,"methodParameters",methodParameters); | 		field_to_json(Obj, "methodParameters", methodParameters); | ||||||
| 		field_to_json(Obj,"servers",servers); | 		field_to_json(Obj, "servers", servers); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
| 		try { | 		try { | ||||||
| 			field_from_json(Obj,"strategy",strategy); | 			field_from_json(Obj, "strategy", strategy); | ||||||
| 			field_from_json(Obj,"monitor",monitor); | 			field_from_json(Obj, "monitor", monitor); | ||||||
| 			field_from_json(Obj,"monitorMethod",monitorMethod); | 			field_from_json(Obj, "monitorMethod", monitorMethod); | ||||||
| 			field_from_json(Obj,"methodParameters",methodParameters); | 			field_from_json(Obj, "methodParameters", methodParameters); | ||||||
| 			field_from_json(Obj,"servers",servers); | 			field_from_json(Obj, "servers", servers); | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
| @@ -372,42 +476,243 @@ namespace OpenWifi::GWObjects { | |||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void RadiusProxyServerEntry::to_json(Poco::JSON::Object &Obj) const { | 	void RadiusProxyServerEntry::to_json(Poco::JSON::Object &Obj) const { | ||||||
| 		field_to_json(Obj,"name",name); | 		field_to_json(Obj, "name", name); | ||||||
| 		field_to_json(Obj,"ip",ip); | 		field_to_json(Obj, "ip", ip); | ||||||
| 		field_to_json(Obj,"port",port); | 		field_to_json(Obj, "port", port); | ||||||
| 		field_to_json(Obj,"weight",weight); | 		field_to_json(Obj, "weight", weight); | ||||||
| 		field_to_json(Obj,"secret",secret); | 		field_to_json(Obj, "secret", secret); | ||||||
| 		field_to_json(Obj,"certificate",certificate); | 		field_to_json(Obj, "certificate", certificate); | ||||||
| 		field_to_json(Obj,"radsec",radsec); | 		field_to_json(Obj, "radsec", radsec); | ||||||
| 		field_to_json(Obj,"radsecPort",radsecPort); | 		field_to_json(Obj, "allowSelfSigned", allowSelfSigned); | ||||||
| 		field_to_json(Obj,"radsecSecret",radsecSecret); | 		field_to_json(Obj, "radsecPort", radsecPort); | ||||||
| 		field_to_json(Obj,"radsecCacerts",radsecCacerts); | 		field_to_json(Obj, "radsecSecret", radsecSecret); | ||||||
| 		field_to_json(Obj,"radsecCert",radsecCert); | 		field_to_json(Obj, "radsecCacerts", radsecCacerts); | ||||||
| 		field_to_json(Obj,"radsecKey",radsecKey); | 		field_to_json(Obj, "radsecCert", radsecCert); | ||||||
| 		field_to_json(Obj,"radsecRealms",radsecRealms); | 		field_to_json(Obj, "radsecKey", radsecKey); | ||||||
| 		field_to_json(Obj,"ignore",ignore); | 		field_to_json(Obj, "radsecRealms", radsecRealms); | ||||||
|  | 		field_to_json(Obj, "ignore", ignore); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool RadiusProxyServerEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool RadiusProxyServerEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
| 		try { | 		try { | ||||||
| 			field_from_json(Obj,"name",name); | 			field_from_json(Obj, "name", name); | ||||||
| 			field_from_json(Obj,"ip",ip); | 			field_from_json(Obj, "ip", ip); | ||||||
| 			field_from_json(Obj,"port",port); | 			field_from_json(Obj, "port", port); | ||||||
| 			field_from_json(Obj,"weight",weight); | 			field_from_json(Obj, "weight", weight); | ||||||
| 			field_from_json(Obj,"secret",secret); | 			field_from_json(Obj, "secret", secret); | ||||||
| 			field_from_json(Obj,"certificate",certificate); | 			field_from_json(Obj, "certificate", certificate); | ||||||
| 			field_from_json(Obj,"radsec",radsec); | 			field_from_json(Obj, "radsec", radsec); | ||||||
| 			field_from_json(Obj,"radsecSecret",radsecSecret); | 			field_from_json(Obj, "allowSelfSigned", allowSelfSigned); | ||||||
| 			field_from_json(Obj,"radsecPort",radsecPort); | 			field_from_json(Obj, "radsecSecret", radsecSecret); | ||||||
| 			field_from_json(Obj,"radsecCacerts",radsecCacerts); | 			field_from_json(Obj, "radsecPort", radsecPort); | ||||||
| 			field_from_json(Obj,"radsecCert",radsecCert); | 			field_from_json(Obj, "radsecCacerts", radsecCacerts); | ||||||
| 			field_from_json(Obj,"radsecKey",radsecKey); | 			field_from_json(Obj, "radsecCert", radsecCert); | ||||||
| 			field_from_json(Obj,"radsecRealms",radsecRealms); | 			field_from_json(Obj, "radsecKey", radsecKey); | ||||||
| 			field_from_json(Obj,"ignore",ignore); | 			field_from_json(Obj, "radsecRealms", radsecRealms); | ||||||
|  | 			field_from_json(Obj, "ignore", ignore); | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| 		} | 		} | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
| } |  | ||||||
|  |  | ||||||
|  | 	void ScriptEntry::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj, "id", id); | ||||||
|  | 		field_to_json(Obj, "name", name); | ||||||
|  | 		field_to_json(Obj, "description", description); | ||||||
|  | 		field_to_json(Obj, "uri", uri); | ||||||
|  | 		field_to_json(Obj, "content", content); | ||||||
|  | 		field_to_json(Obj, "version", version); | ||||||
|  | 		field_to_json(Obj, "type", type); | ||||||
|  | 		field_to_json(Obj, "created", created); | ||||||
|  | 		field_to_json(Obj, "modified", modified); | ||||||
|  | 		field_to_json(Obj, "author", author); | ||||||
|  | 		field_to_json(Obj, "restricted", restricted); | ||||||
|  | 		field_to_json(Obj, "deferred", deferred); | ||||||
|  | 		field_to_json(Obj, "timeout", timeout); | ||||||
|  | 		field_to_json(Obj, "defaultUploadURI", defaultUploadURI); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool ScriptEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj, "id", id); | ||||||
|  | 			field_from_json(Obj, "name", name); | ||||||
|  | 			field_from_json(Obj, "description", description); | ||||||
|  | 			field_from_json(Obj, "uri", uri); | ||||||
|  | 			field_from_json(Obj, "content", content); | ||||||
|  | 			field_from_json(Obj, "version", version); | ||||||
|  | 			field_from_json(Obj, "type", type); | ||||||
|  | 			field_from_json(Obj, "created", created); | ||||||
|  | 			field_from_json(Obj, "modified", modified); | ||||||
|  | 			field_from_json(Obj, "author", author); | ||||||
|  | 			field_from_json(Obj, "restricted", restricted); | ||||||
|  | 			field_from_json(Obj, "deferred", deferred); | ||||||
|  | 			field_from_json(Obj, "timeout", timeout); | ||||||
|  | 			field_from_json(Obj, "defaultUploadURI", defaultUploadURI); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void ScriptEntryList::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj, "scripts", scripts); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool ScriptEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj, "scripts", scripts); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void RangeOptions::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj, "NO_IR", NO_IR); | ||||||
|  | 		field_to_json(Obj, "AUTO_BW", AUTO_BW); | ||||||
|  | 		field_to_json(Obj, "DFS", DFS); | ||||||
|  | 		field_to_json(Obj, "NO_OUTDOOR", NO_OUTDOOR); | ||||||
|  | 		field_to_json(Obj, "wmmrule_ETSI", wmmrule_ETSI); | ||||||
|  | 		field_to_json(Obj, "NO_OFDM", NO_OFDM); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void FrequencyRange::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj, "from", from); | ||||||
|  | 		field_to_json(Obj, "to", to); | ||||||
|  | 		field_to_json(Obj, "channelWidth", channelWidth); | ||||||
|  | 		field_to_json(Obj, "powerDb", powerDb); | ||||||
|  | 		field_to_json(Obj, "options", options); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void RegulatoryCountryInfo::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj, "country", country); | ||||||
|  | 		field_to_json(Obj, "domain", domain); | ||||||
|  | 		field_to_json(Obj, "ranges", ranges); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void DeviceRestrictionsKeyInfo::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj, "vendor", vendor); | ||||||
|  | 		field_to_json(Obj, "algo", algo); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool DeviceRestrictionsKeyInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj, "vendor", vendor); | ||||||
|  | 			field_from_json(Obj, "algo", algo); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void DeviceRestrictions::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj, "dfs", dfs); | ||||||
|  | 		field_to_json(Obj, "ssh", ssh); | ||||||
|  | 		field_to_json(Obj, "rtty", rtty); | ||||||
|  | 		field_to_json(Obj, "tty", tty); | ||||||
|  | 		field_to_json(Obj, "developer", developer); | ||||||
|  | 		field_to_json(Obj, "upgrade", upgrade); | ||||||
|  | 		field_to_json(Obj, "commands", commands); | ||||||
|  | 		field_to_json(Obj, "country", country); | ||||||
|  | 		field_to_json(Obj, "key_info", key_info); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool DeviceRestrictions::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj, "dfs", dfs); | ||||||
|  | 			field_from_json(Obj, "ssh", ssh); | ||||||
|  | 			field_from_json(Obj, "rtty", rtty); | ||||||
|  | 			field_from_json(Obj, "tty", tty); | ||||||
|  | 			field_from_json(Obj, "developer", developer); | ||||||
|  | 			field_from_json(Obj, "upgrade", upgrade); | ||||||
|  | 			field_from_json(Obj, "commands", commands); | ||||||
|  | 			field_from_json(Obj, "country", country); | ||||||
|  | 			field_from_json(Obj, "key_info", key_info); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool DeviceRestrictionsKeyInfo::operator!=( | ||||||
|  | 		const OpenWifi::GWObjects::DeviceRestrictionsKeyInfo &T) const { | ||||||
|  | 		return (T.algo != algo) || (T.vendor != vendor); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool DeviceRestrictions::operator!=(const OpenWifi::GWObjects::DeviceRestrictions &T) const { | ||||||
|  | 		return ((T.dfs != dfs) || (T.rtty != rtty) || (T.upgrade != upgrade) || | ||||||
|  | 				(T.commands != commands) || (T.developer != developer) || (T.ssh != ssh) || | ||||||
|  | 				(T.key_info != key_info) || (T.country != country)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void RADIUSSession::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj, "started", started); | ||||||
|  | 		field_to_json(Obj, "lastTransaction", lastTransaction); | ||||||
|  | 		field_to_json(Obj, "destination", destination); | ||||||
|  | 		field_to_json(Obj, "serialNumber", serialNumber); | ||||||
|  | 		field_to_json(Obj, "userName", userName); | ||||||
|  | 		field_to_json(Obj, "accountingSessionId", accountingSessionId); | ||||||
|  | 		field_to_json(Obj, "accountingMultiSessionId", accountingMultiSessionId); | ||||||
|  | 		field_to_json(Obj, "inputPackets", inputPackets); | ||||||
|  | 		field_to_json(Obj, "outputPackets", outputPackets); | ||||||
|  | 		field_to_json(Obj, "inputOctets", inputOctets); | ||||||
|  | 		field_to_json(Obj, "outputOctets", outputOctets); | ||||||
|  | 		field_to_json(Obj, "inputGigaWords", inputGigaWords); | ||||||
|  | 		field_to_json(Obj, "outputGigaWords", outputGigaWords); | ||||||
|  | 		field_to_json(Obj, "sessionTime", sessionTime); | ||||||
|  | 		field_to_json(Obj, "callingStationId", callingStationId); | ||||||
|  | 		field_to_json(Obj, "chargeableUserIdentity", chargeableUserIdentity); | ||||||
|  | 		field_to_json(Obj, "interface", interface); | ||||||
|  | 		field_to_json(Obj, "secret", secret); | ||||||
|  | 		field_to_json(Obj, "nasId", nasId); | ||||||
|  | 		field_to_json(Obj, "calledStationId", calledStationId); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void RADIUSSessionList::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj, "sessions", sessions); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void RadiusCoADMParameters::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj, "accountingSessionId", accountingSessionId); | ||||||
|  | 		field_to_json(Obj, "accountingMultiSessionId", accountingMultiSessionId); | ||||||
|  | 		field_to_json(Obj, "callingStationId", callingStationId); | ||||||
|  | 		field_to_json(Obj, "chargeableUserIdentity", chargeableUserIdentity); | ||||||
|  | 		field_to_json(Obj, "userName", userName); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool RadiusCoADMParameters::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj, "accountingSessionId", accountingSessionId); | ||||||
|  | 			field_from_json(Obj, "accountingMultiSessionId", accountingMultiSessionId); | ||||||
|  | 			field_from_json(Obj, "callingStationId", callingStationId); | ||||||
|  | 			field_from_json(Obj, "chargeableUserIdentity", chargeableUserIdentity); | ||||||
|  | 			field_from_json(Obj, "userName", userName); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool DeviceTransferRequest::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj, "serialNumber", serialNumber); | ||||||
|  | 			field_from_json(Obj, "server", server); | ||||||
|  | 			field_from_json(Obj, "port", port); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool DeviceCertificateUpdateRequest::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj, "serialNumber", serialNumber); | ||||||
|  | 			field_from_json(Obj, "encodedCertificate", encodedCertificate); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | } // namespace OpenWifi::GWObjects | ||||||
|   | |||||||
| @@ -11,38 +11,73 @@ | |||||||
| #include "Poco/JSON/Object.h" | #include "Poco/JSON/Object.h" | ||||||
| #include "RESTAPI_SecurityObjects.h" | #include "RESTAPI_SecurityObjects.h" | ||||||
|  |  | ||||||
|  | #ifdef TIP_GATEWAY_SERVICE | ||||||
|  | #include <RADIUS_helpers.h> | ||||||
|  | #endif | ||||||
|  |  | ||||||
| namespace OpenWifi::GWObjects { | namespace OpenWifi::GWObjects { | ||||||
|  |  | ||||||
| 	enum CertificateValidation { | 	enum CertificateValidation { NO_CERTIFICATE, VALID_CERTIFICATE, MISMATCH_SERIAL, VERIFIED, SIMULATED }; | ||||||
| 		NO_CERTIFICATE, |  | ||||||
| 		VALID_CERTIFICATE, |  | ||||||
| 		MISMATCH_SERIAL, |  | ||||||
| 		VERIFIED |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct ConnectionState { | 	struct ConnectionState { | ||||||
| 		uint64_t MessageCount = 0 ; | 		uint64_t MessageCount = 0; | ||||||
| 		std::string Address; | 		std::string Address; | ||||||
| 		uint64_t UUID = 0 ; | 		uint64_t UUID = 0; | ||||||
| 		uint64_t PendingUUID = 0 ; | 		uint64_t PendingUUID = 0; | ||||||
| 		uint64_t TX = 0, RX = 0; | 		uint64_t TX = 0, RX = 0; | ||||||
| 		uint64_t Associations_2G=0; | 		uint64_t Associations_2G = 0; | ||||||
| 		uint64_t Associations_5G=0; | 		uint64_t Associations_5G = 0; | ||||||
|  | 		uint64_t Associations_6G = 0; | ||||||
| 		bool Connected = false; | 		bool Connected = false; | ||||||
| 		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; | 		std::string Compatible; | ||||||
| 		uint64_t 	kafkaClients=0; | 		uint64_t kafkaClients = 0; | ||||||
| 		uint64_t 	webSocketClients=0; | 		uint64_t webSocketClients = 0; | ||||||
| 		uint64_t 	kafkaPackets=0; | 		uint64_t kafkaPackets = 0; | ||||||
| 		uint64_t 	websocketPackets=0; | 		uint64_t websocketPackets = 0; | ||||||
| 		std::string locale; | 		std::string locale; | ||||||
| 		uint64_t 	started=0; | 		uint64_t started = 0; | ||||||
| 		uint64_t 	sessionId=0; | 		uint64_t sessionId = 0; | ||||||
| 		double      connectionCompletionTime=0.0; | 		double connectionCompletionTime = 0.0; | ||||||
|  | 		std::uint64_t certificateExpiryDate = 0; | ||||||
|  | 		std::uint64_t hasRADIUSSessions = 0; | ||||||
|  | 		bool hasGPS = false; | ||||||
|  | 		std::uint64_t sanity=0; | ||||||
|  | 		std::double_t memoryUsed=0.0; | ||||||
|  | 		std::double_t load=0.0; | ||||||
|  | 		std::double_t temperature=0.0; | ||||||
|  | 		std::string 	connectReason; | ||||||
|  |  | ||||||
|  | 		void to_json(const std::string &SerialNumber, Poco::JSON::Object &Obj) ; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct DeviceRestrictionsKeyInfo { | ||||||
|  | 		std::string vendor; | ||||||
|  | 		std::string algo; | ||||||
|  |  | ||||||
|  | 		bool operator!=(const DeviceRestrictionsKeyInfo &b) const; | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct DeviceRestrictions { | ||||||
|  | 		bool dfs = false; | ||||||
|  | 		bool ssh = false; | ||||||
|  | 		bool rtty = false; | ||||||
|  | 		bool tty = false; | ||||||
|  | 		bool developer = false; | ||||||
|  | 		bool upgrade = false; | ||||||
|  | 		bool commands = false; | ||||||
|  | 		std::vector<std::string> country; | ||||||
|  | 		DeviceRestrictionsKeyInfo key_info; | ||||||
|  |  | ||||||
|  | 		bool operator!=(const DeviceRestrictions &D) const; | ||||||
|  |  | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct Device { | 	struct Device { | ||||||
| @@ -51,23 +86,30 @@ namespace OpenWifi::GWObjects { | |||||||
| 		std::string MACAddress; | 		std::string MACAddress; | ||||||
| 		std::string Manufacturer; | 		std::string Manufacturer; | ||||||
| 		std::string Configuration; | 		std::string Configuration; | ||||||
| 		SecurityObjects::NoteInfoVec 	Notes; | 		SecurityObjects::NoteInfoVec Notes; | ||||||
| 		std::string Owner; | 		std::string Owner; | ||||||
| 		std::string Location; | 		std::string Location; | ||||||
| 		std::string Firmware; | 		std::string Firmware; | ||||||
| 		std::string Compatible; | 		std::string Compatible; | ||||||
| 		std::string FWUpdatePolicy; | 		std::string FWUpdatePolicy; | ||||||
| 		uint64_t UUID = 0 ; | 		uint64_t UUID = 0; | ||||||
| 		uint64_t CreationTimestamp = 0 ; | 		uint64_t CreationTimestamp = 0; | ||||||
| 		uint64_t LastConfigurationChange = 0 ; | 		uint64_t LastConfigurationChange = 0; | ||||||
| 		uint64_t LastConfigurationDownload = 0 ; | 		uint64_t LastConfigurationDownload = 0; | ||||||
| 		uint64_t LastFWUpdate = 0 ; | 		uint64_t LastFWUpdate = 0; | ||||||
| 		std::string Venue; | 		std::string Venue; | ||||||
| 		std::string DevicePassword; | 		std::string DevicePassword; | ||||||
| 		std::string subscriber; | 		std::string subscriber; | ||||||
| 		std::string entity; | 		std::string entity; | ||||||
| 		uint64_t 	modified=0; | 		uint64_t modified = 0; | ||||||
| 		std::string locale; | 		std::string locale; | ||||||
|  | 		bool restrictedDevice = false; | ||||||
|  | 		std::string pendingConfiguration; | ||||||
|  | 		std::string pendingConfigurationCmd; | ||||||
|  | 		DeviceRestrictions restrictionDetails; | ||||||
|  | 		std::uint64_t pendingUUID = 0; | ||||||
|  | 		bool simulated=false; | ||||||
|  | 		std::uint64_t lastRecordedContact=0; | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 		void to_json_with_status(Poco::JSON::Object &Obj) const; | 		void to_json_with_status(Poco::JSON::Object &Obj) const; | ||||||
| @@ -78,32 +120,34 @@ namespace OpenWifi::GWObjects { | |||||||
| 	struct DeviceConnectionStatistics { | 	struct DeviceConnectionStatistics { | ||||||
| 		std::uint64_t connectedDevices = 0; | 		std::uint64_t connectedDevices = 0; | ||||||
| 		std::uint64_t averageConnectionTime = 0; | 		std::uint64_t averageConnectionTime = 0; | ||||||
|  | 		std::uint64_t connectingDevices = 0; | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct Statistics { | 	struct Statistics { | ||||||
| 		std::string SerialNumber; | 		std::string SerialNumber; | ||||||
| 		uint64_t 	UUID = 0 ; | 		uint64_t UUID = 0; | ||||||
| 		std::string Data; | 		std::string Data; | ||||||
| 		uint64_t 	Recorded = 0; | 		uint64_t Recorded = 0; | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct HealthCheck { | 	struct HealthCheck { | ||||||
| 		std::string SerialNumber; | 		std::string SerialNumber; | ||||||
| 		uint64_t 	UUID = 0 ; | 		uint64_t UUID = 0; | ||||||
| 		std::string Data; | 		std::string Data; | ||||||
| 		uint64_t 	Recorded = 0 ; | 		uint64_t Recorded = 0; | ||||||
| 		uint64_t 	Sanity = 0 ; | 		uint64_t Sanity = 0; | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct Capabilities { | 	struct Capabilities { | ||||||
| 		std::string Capabilities; | 		std::string Capabilities; | ||||||
| 		uint64_t 	FirstUpdate = 0 ; | 		uint64_t FirstUpdate = 0; | ||||||
| 		uint64_t 	LastUpdate = 0 ; | 		uint64_t LastUpdate = 0; | ||||||
| 		void 		to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct DeviceLog { | 	struct DeviceLog { | ||||||
| @@ -120,11 +164,11 @@ namespace OpenWifi::GWObjects { | |||||||
| 		std::string SerialNumber; | 		std::string SerialNumber; | ||||||
| 		std::string Log; | 		std::string Log; | ||||||
| 		std::string Data; | 		std::string Data; | ||||||
| 		uint64_t 	Severity = 0 ; | 		uint64_t Severity = 0; | ||||||
| 		uint64_t 	Recorded = 0 ; | 		uint64_t Recorded = 0; | ||||||
| 		uint64_t 	LogType = 0 ; | 		uint64_t LogType = 0; | ||||||
| 		uint64_t 	UUID = 0 ; | 		uint64_t UUID = 0; | ||||||
| 		void 		to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct DefaultConfiguration { | 	struct DefaultConfiguration { | ||||||
| @@ -132,10 +176,30 @@ namespace OpenWifi::GWObjects { | |||||||
| 		std::string Configuration; | 		std::string Configuration; | ||||||
| 		Types::StringVec Models; | 		Types::StringVec Models; | ||||||
| 		std::string Description; | 		std::string Description; | ||||||
| 		uint64_t 	Created; | 		uint64_t Created; | ||||||
| 		uint64_t 	LastModified; | 		uint64_t LastModified; | ||||||
| 		void 		to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 		bool 		from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct DefaultFirmware { | ||||||
|  | 		std::string deviceType; | ||||||
|  | 		std::string Description; | ||||||
|  | 		std::string uri; | ||||||
|  | 		std::string revision; | ||||||
|  | 		uint64_t imageCreationDate; | ||||||
|  | 		uint64_t Created; | ||||||
|  | 		uint64_t LastModified; | ||||||
|  |  | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct DefaultFirmwareList { | ||||||
|  | 		std::vector<DefaultFirmware>	firmwares; | ||||||
|  |  | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct CommandDetails { | 	struct CommandDetails { | ||||||
| @@ -149,16 +213,20 @@ namespace OpenWifi::GWObjects { | |||||||
| 		std::string ErrorText; | 		std::string ErrorText; | ||||||
| 		uint64_t Submitted = time(nullptr); | 		uint64_t Submitted = time(nullptr); | ||||||
| 		uint64_t Executed = 0; | 		uint64_t Executed = 0; | ||||||
| 		uint64_t Completed = 0 ; | 		uint64_t Completed = 0; | ||||||
| 		uint64_t RunAt = 0 ; | 		uint64_t RunAt = 0; | ||||||
| 		uint64_t ErrorCode = 0 ; | 		uint64_t ErrorCode = 0; | ||||||
| 		uint64_t Custom = 0 ; | 		uint64_t Custom = 0; | ||||||
| 		uint64_t WaitingForFile = 0 ; | 		uint64_t WaitingForFile = 0; | ||||||
| 		uint64_t AttachDate = 0 ; | 		uint64_t AttachDate = 0; | ||||||
| 		uint64_t AttachSize = 0 ; | 		uint64_t AttachSize = 0; | ||||||
| 		std::string AttachType; | 		std::string AttachType; | ||||||
| 		double 		executionTime = 0.0; | 		double executionTime = 0.0; | ||||||
|  | 		std::uint64_t lastTry = 0; | ||||||
|  | 		bool deferred = false; | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct BlackListedDevice { | 	struct BlackListedDevice { | ||||||
| @@ -173,20 +241,20 @@ namespace OpenWifi::GWObjects { | |||||||
| 	struct RttySessionDetails { | 	struct RttySessionDetails { | ||||||
| 		std::string SerialNumber; | 		std::string SerialNumber; | ||||||
| 		std::string Server; | 		std::string Server; | ||||||
| 		uint64_t 	Port = 0 ; | 		uint64_t Port = 0; | ||||||
| 		std::string Token; | 		std::string Token; | ||||||
| 		uint64_t 	TimeOut = 0 ; | 		uint64_t TimeOut = 0; | ||||||
| 		std::string ConnectionId; | 		std::string ConnectionId; | ||||||
| 		uint64_t 	Started = 0 ; | 		uint64_t Started = 0; | ||||||
| 		std::string CommandUUID; | 		std::string CommandUUID; | ||||||
| 		uint64_t 	ViewPort = 0 ; | 		uint64_t ViewPort = 0; | ||||||
| 		std::string DevicePassword; | 		std::string DevicePassword; | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct Dashboard { | 	struct Dashboard { | ||||||
| 		uint64_t 		  snapshot = 0 ; | 		uint64_t snapshot = 0; | ||||||
| 		uint64_t 		  numberOfDevices = 0 ; | 		uint64_t numberOfDevices = 0; | ||||||
| 		Types::CountedMap commands; | 		Types::CountedMap commands; | ||||||
| 		Types::CountedMap upTimes; | 		Types::CountedMap upTimes; | ||||||
| 		Types::CountedMap memoryUsed; | 		Types::CountedMap memoryUsed; | ||||||
| @@ -211,13 +279,44 @@ namespace OpenWifi::GWObjects { | |||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	struct ScriptEntry { | ||||||
|  | 		std::string id; | ||||||
|  | 		std::string name; | ||||||
|  | 		std::string description; | ||||||
|  | 		std::string uri; | ||||||
|  | 		std::string content; | ||||||
|  | 		std::string version; | ||||||
|  | 		std::string type; | ||||||
|  | 		std::uint64_t created; | ||||||
|  | 		std::uint64_t modified; | ||||||
|  | 		std::string author; | ||||||
|  | 		Types::StringVec restricted; | ||||||
|  | 		bool deferred = false; | ||||||
|  | 		std::uint64_t timeout = 30; | ||||||
|  | 		std::string defaultUploadURI; | ||||||
|  |  | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct ScriptEntryList { | ||||||
|  | 		std::vector<ScriptEntry> scripts; | ||||||
|  |  | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
| 	struct ScriptRequest { | 	struct ScriptRequest { | ||||||
| 		uint64_t 	timeout=30; |  | ||||||
| 		std::string serialNumber; | 		std::string serialNumber; | ||||||
|  | 		uint64_t timeout = 30; | ||||||
| 		std::string type; | 		std::string type; | ||||||
| 		std::string script; | 		std::string script; | ||||||
| 		std::string scriptId; | 		std::string scriptId; | ||||||
| 		uint64_t 	when=0; | 		std::uint64_t when; | ||||||
|  | 		std::string signature; | ||||||
|  | 		bool deferred; | ||||||
|  | 		std::string uri; | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
| 	}; | 	}; | ||||||
| @@ -225,50 +324,191 @@ namespace OpenWifi::GWObjects { | |||||||
| 	struct RadiusProxyServerEntry { | 	struct RadiusProxyServerEntry { | ||||||
| 		std::string name; | 		std::string name; | ||||||
| 		std::string ip; | 		std::string ip; | ||||||
| 		uint16_t 	port=0; | 		uint16_t port = 0; | ||||||
| 		uint64_t 	weight=0; | 		uint64_t weight = 0; | ||||||
| 		std::string secret; | 		std::string secret; | ||||||
| 		std::string certificate; | 		std::string certificate; | ||||||
| 		bool 		radsec=false; | 		bool radsec = false; | ||||||
| 		uint16_t 	radsecPort=2083; | 		bool allowSelfSigned = false; | ||||||
|  | 		uint16_t radsecPort = 2083; | ||||||
| 		std::string radsecSecret; | 		std::string radsecSecret; | ||||||
| 		std::string radsecKey; | 		std::string radsecKey; | ||||||
| 		std::string radsecCert; | 		std::string radsecCert; | ||||||
| 		std::vector<std::string> 	radsecCacerts; | 		std::vector<std::string> radsecCacerts; | ||||||
| 		std::vector<std::string>	radsecRealms; | 		std::vector<std::string> radsecRealms; | ||||||
| 		bool 		ignore=false; | 		bool ignore = false; | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct RadiusProxyServerConfig { | 	struct RadiusProxyServerConfig { | ||||||
| 		std::string 	strategy; | 		std::string strategy; | ||||||
| 		bool 			monitor=false; | 		bool monitor = false; | ||||||
| 		std::string 	monitorMethod; | 		std::string monitorMethod; | ||||||
| 		std::vector<std::string>	methodParameters; | 		std::vector<std::string> methodParameters; | ||||||
| 		std::vector<RadiusProxyServerEntry>	servers; | 		std::vector<RadiusProxyServerEntry> servers; | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct 	RadiusProxyPool { | 	struct RadiusProxyPool { | ||||||
| 		std::string name; | 		std::string name; | ||||||
| 		std::string description; | 		std::string description; | ||||||
| 		RadiusProxyServerConfig	authConfig; | 		RadiusProxyServerConfig authConfig; | ||||||
| 		RadiusProxyServerConfig	acctConfig; | 		RadiusProxyServerConfig acctConfig; | ||||||
| 		RadiusProxyServerConfig	coaConfig; | 		RadiusProxyServerConfig coaConfig; | ||||||
| 		bool 		useByDefault=false; | 		bool useByDefault = false; | ||||||
|  | 		std::string 	radsecPoolType; | ||||||
|  | 		std::string 	poolProxyIp; | ||||||
|  | 		std::uint64_t 	radsecKeepAlive=25; | ||||||
|  | 		bool			enabled=true; | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct RadiusProxyPoolList { | 	struct RadiusProxyPoolList { | ||||||
| 		std::vector<RadiusProxyPool>	pools; | 		std::vector<RadiusProxyPool> pools; | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
| 	}; | 	}; | ||||||
| } |  | ||||||
|  | 	struct RangeOptions { | ||||||
|  | 		bool NO_IR=false; | ||||||
|  | 		bool AUTO_BW=false; | ||||||
|  | 		bool DFS=false; | ||||||
|  | 		bool NO_OUTDOOR=false; | ||||||
|  | 		bool wmmrule_ETSI=false; | ||||||
|  | 		bool NO_OFDM=false; | ||||||
|  |  | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct FrequencyRange { | ||||||
|  | 		float from = 0.0; | ||||||
|  | 		float to = 0.0; | ||||||
|  | 		int channelWidth = 0; | ||||||
|  | 		int powerDb = 0; | ||||||
|  | 		RangeOptions    options; | ||||||
|  |  | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct RegulatoryCountryInfo { | ||||||
|  | 		std::string country; | ||||||
|  | 		std::string domain; | ||||||
|  | 		std::vector<FrequencyRange>   ranges; | ||||||
|  |  | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	using RegulatoryInfoCountryMap = std::map<std::string,RegulatoryCountryInfo>; | ||||||
|  |  | ||||||
|  | 	struct RADIUSSession { | ||||||
|  | 		std::uint64_t 			started=0, | ||||||
|  | 								lastTransaction=0; | ||||||
|  | 		std::string 			serialNumber, | ||||||
|  | 								destination, | ||||||
|  | 								userName, | ||||||
|  | 					 			accountingSessionId, | ||||||
|  | 								accountingMultiSessionId, | ||||||
|  | 					 			callingStationId, | ||||||
|  | 								chargeableUserIdentity, | ||||||
|  | 								secret, | ||||||
|  | 								interface, | ||||||
|  | 								nasId; | ||||||
|  | 		std::uint64_t 			inputPackets = 0, | ||||||
|  | 								outputPackets = 0, | ||||||
|  | 								inputOctets = 0, | ||||||
|  | 								outputOctets = 0, | ||||||
|  | 								inputGigaWords = 0, | ||||||
|  | 								outputGigaWords = 0; | ||||||
|  | 		std::uint32_t 			sessionTime = 0; | ||||||
|  | 		std::string 			calledStationId; | ||||||
|  |  | ||||||
|  | #ifdef TIP_GATEWAY_SERVICE | ||||||
|  | 		RADIUS::RadiusPacket	accountingPacket; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct RADIUSSessionList { | ||||||
|  | 		std::vector<RADIUSSession>	sessions; | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct RadiusCoADMParameters { | ||||||
|  | 		std::string 			accountingSessionId, | ||||||
|  | 								accountingMultiSessionId, | ||||||
|  | 								callingStationId, | ||||||
|  | 								chargeableUserIdentity, | ||||||
|  | 								userName; | ||||||
|  |  | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	enum class RadiusPoolStrategy { | ||||||
|  | 		round_robin, random, weighted, unknown | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	enum class RadiusEndpointType { | ||||||
|  | 		generic, radsec, globalreach, orion, unknown | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	static inline RadiusEndpointType RadiusEndpointType(const std::string &T) { | ||||||
|  | 		if(T=="generic") return RadiusEndpointType::generic; | ||||||
|  | 		if(T=="radsec") return RadiusEndpointType::radsec; | ||||||
|  | 		if(T=="globalreach") return RadiusEndpointType::globalreach; | ||||||
|  | 		if(T=="orion") return RadiusEndpointType::orion; | ||||||
|  | 		return RadiusEndpointType::unknown; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	static inline RadiusPoolStrategy RadiusPoolStrategy(const std::string &T) { | ||||||
|  | 		if(T=="round_robin") return RadiusPoolStrategy::round_robin; | ||||||
|  | 		if(T=="random") return RadiusPoolStrategy::random; | ||||||
|  | 		if(T=="weighted") return RadiusPoolStrategy::weighted; | ||||||
|  | 		return RadiusPoolStrategy::unknown; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	static inline std::string to_string(enum RadiusEndpointType T) { | ||||||
|  | 		switch(T) { | ||||||
|  | 		case RadiusEndpointType::generic: return "generic"; | ||||||
|  | 		case RadiusEndpointType::radsec: return "radsec"; | ||||||
|  | 		case RadiusEndpointType::globalreach: return "globalreach"; | ||||||
|  | 		case RadiusEndpointType::orion: return "orion"; | ||||||
|  | 		default: | ||||||
|  | 			return "unknown"; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	static inline std::string to_string(enum RadiusPoolStrategy T) { | ||||||
|  | 		switch(T) { | ||||||
|  | 		case RadiusPoolStrategy::round_robin: return "round_robin"; | ||||||
|  | 		case RadiusPoolStrategy::random: return "random"; | ||||||
|  | 		case RadiusPoolStrategy::weighted: return "weighted"; | ||||||
|  | 		default: | ||||||
|  | 			return "unknown"; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	struct DeviceTransferRequest { | ||||||
|  | 		std::string 	serialNumber; | ||||||
|  | 		std::string 	server; | ||||||
|  | 		std::uint64_t 	port; | ||||||
|  |  | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct DeviceCertificateUpdateRequest { | ||||||
|  | 		std::string 	serialNumber; | ||||||
|  | 		std::string 	encodedCertificate; | ||||||
|  |  | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | } // namespace OpenWifi::GWObjects | ||||||
|   | |||||||
							
								
								
									
										103
									
								
								src/RESTObjects/RESTAPI_OWLSobjects.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,103 @@ | |||||||
|  | // | ||||||
|  | // Created by stephane bourque on 2021-08-31. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include "framework/RESTAPI_utils.h" | ||||||
|  |  | ||||||
|  | using OpenWifi::RESTAPI_utils::EmbedDocument; | ||||||
|  | using OpenWifi::RESTAPI_utils::field_from_json; | ||||||
|  | using OpenWifi::RESTAPI_utils::field_to_json; | ||||||
|  |  | ||||||
|  | #include "RESTAPI_OWLSobjects.h" | ||||||
|  |  | ||||||
|  | // SIM -> 0x53/0x073, 0x49/0x69, 0x4d/0x6d | ||||||
|  |  | ||||||
|  | namespace OpenWifi::OWLSObjects { | ||||||
|  |  | ||||||
|  | 	void SimulationDetails::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj, "id", id); | ||||||
|  | 		field_to_json(Obj, "name", name); | ||||||
|  | 		field_to_json(Obj, "gateway", gateway); | ||||||
|  | 		field_to_json(Obj, "certificate", certificate); | ||||||
|  | 		field_to_json(Obj, "key", key); | ||||||
|  | 		field_to_json(Obj, "macPrefix", macPrefix); | ||||||
|  | 		field_to_json(Obj, "deviceType", deviceType); | ||||||
|  | 		field_to_json(Obj, "devices", devices); | ||||||
|  | 		field_to_json(Obj, "healthCheckInterval", healthCheckInterval); | ||||||
|  | 		field_to_json(Obj, "stateInterval", stateInterval); | ||||||
|  | 		field_to_json(Obj, "minAssociations", minAssociations); | ||||||
|  | 		field_to_json(Obj, "maxAssociations", maxAssociations); | ||||||
|  | 		field_to_json(Obj, "minClients", minClients); | ||||||
|  | 		field_to_json(Obj, "maxClients", maxClients); | ||||||
|  | 		field_to_json(Obj, "simulationLength", simulationLength); | ||||||
|  | 		field_to_json(Obj, "threads", threads); | ||||||
|  | 		field_to_json(Obj, "clientInterval", clientInterval); | ||||||
|  | 		field_to_json(Obj, "keepAlive", keepAlive); | ||||||
|  | 		field_to_json(Obj, "reconnectInterval", reconnectInterval); | ||||||
|  | 		field_to_json(Obj, "concurrentDevices", concurrentDevices); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool SimulationDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj, "id", id); | ||||||
|  | 			field_from_json(Obj, "name", name); | ||||||
|  | 			field_from_json(Obj, "gateway", gateway); | ||||||
|  | 			field_from_json(Obj, "certificate", certificate); | ||||||
|  | 			field_from_json(Obj, "key", key); | ||||||
|  | 			field_from_json(Obj, "macPrefix", macPrefix); | ||||||
|  | 			field_from_json(Obj, "deviceType", deviceType); | ||||||
|  | 			field_from_json(Obj, "devices", devices); | ||||||
|  | 			field_from_json(Obj, "healthCheckInterval", healthCheckInterval); | ||||||
|  | 			field_from_json(Obj, "stateInterval", stateInterval); | ||||||
|  | 			field_from_json(Obj, "minAssociations", minAssociations); | ||||||
|  | 			field_from_json(Obj, "maxAssociations", maxAssociations); | ||||||
|  | 			field_from_json(Obj, "minClients", minClients); | ||||||
|  | 			field_from_json(Obj, "maxClients", maxClients); | ||||||
|  | 			field_from_json(Obj, "simulationLength", simulationLength); | ||||||
|  | 			field_from_json(Obj, "threads", threads); | ||||||
|  | 			field_from_json(Obj, "clientInterval", clientInterval); | ||||||
|  | 			field_from_json(Obj, "keepAlive", keepAlive); | ||||||
|  | 			field_from_json(Obj, "reconnectInterval", reconnectInterval); | ||||||
|  | 			field_from_json(Obj, "concurrentDevices", concurrentDevices); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (...) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void SimulationDetailsList::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj, "list", list); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool SimulationDetailsList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj, "list", list); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (...) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  |     void SimulationStatus::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  |         field_to_json(Obj, "id", id); | ||||||
|  |         field_to_json(Obj, "simulationId", simulationId); | ||||||
|  |         field_to_json(Obj, "state", state); | ||||||
|  |         field_to_json(Obj, "tx", tx); | ||||||
|  |         field_to_json(Obj, "rx", rx); | ||||||
|  |         field_to_json(Obj, "msgsTx", msgsTx); | ||||||
|  |         field_to_json(Obj, "msgsRx", msgsRx); | ||||||
|  |         field_to_json(Obj, "liveDevices", liveDevices); | ||||||
|  |         field_to_json(Obj, "timeToFullDevices", timeToFullDevices); | ||||||
|  |         field_to_json(Obj, "startTime", startTime); | ||||||
|  |         field_to_json(Obj, "endTime", endTime); | ||||||
|  |         field_to_json(Obj, "errorDevices", errorDevices); | ||||||
|  |         field_to_json(Obj, "owner", owner); | ||||||
|  |         field_to_json(Obj, "expectedDevices", expectedDevices); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | 	void Dashboard::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const {} | ||||||
|  |  | ||||||
|  | 	bool Dashboard::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) { return true; } | ||||||
|  |  | ||||||
|  | 	void Dashboard::reset() {} | ||||||
|  | } // namespace OpenWifi::OWLSObjects | ||||||
							
								
								
									
										75
									
								
								src/RESTObjects/RESTAPI_OWLSobjects.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,75 @@ | |||||||
|  | // | ||||||
|  | // Created by stephane bourque on 2021-08-31. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #ifndef UCENTRALSIM_RESTAPI_OWLSOBJECTS_H | ||||||
|  | #define UCENTRALSIM_RESTAPI_OWLSOBJECTS_H | ||||||
|  |  | ||||||
|  | #include "Poco/JSON/Object.h" | ||||||
|  | #include <vector> | ||||||
|  |  | ||||||
|  | namespace OpenWifi::OWLSObjects { | ||||||
|  |  | ||||||
|  | 	struct SimulationDetails { | ||||||
|  | 		std::string id; | ||||||
|  | 		std::string name; | ||||||
|  | 		std::string gateway; | ||||||
|  | 		std::string certificate; | ||||||
|  | 		std::string key; | ||||||
|  | 		std::string macPrefix; | ||||||
|  | 		std::string deviceType; | ||||||
|  | 		uint64_t devices = 5; | ||||||
|  | 		uint64_t healthCheckInterval = 60; | ||||||
|  | 		uint64_t stateInterval = 60; | ||||||
|  | 		uint64_t minAssociations = 1; | ||||||
|  | 		uint64_t maxAssociations = 3; | ||||||
|  | 		uint64_t minClients = 1; | ||||||
|  | 		uint64_t maxClients = 3; | ||||||
|  | 		uint64_t simulationLength = 60 * 60; | ||||||
|  | 		uint64_t threads = 16; | ||||||
|  | 		uint64_t clientInterval = 1; | ||||||
|  | 		uint64_t keepAlive = 300; | ||||||
|  | 		uint64_t reconnectInterval = 30; | ||||||
|  | 		uint64_t concurrentDevices = 5; | ||||||
|  |  | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | 	struct SimulationDetailsList { | ||||||
|  | 		std::vector<SimulationDetails> list; | ||||||
|  |  | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  |     struct SimulationStatus { | ||||||
|  |         std::string id; | ||||||
|  |         std::string simulationId; | ||||||
|  |         std::string state; | ||||||
|  |         uint64_t tx; | ||||||
|  |         uint64_t rx; | ||||||
|  |         uint64_t msgsTx; | ||||||
|  |         uint64_t msgsRx; | ||||||
|  |         uint64_t liveDevices; | ||||||
|  |         uint64_t timeToFullDevices; | ||||||
|  |         uint64_t startTime; | ||||||
|  |         uint64_t endTime; | ||||||
|  |         uint64_t errorDevices; | ||||||
|  |         std::string owner; | ||||||
|  |         uint64_t expectedDevices; | ||||||
|  |  | ||||||
|  |         void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  | 	struct Dashboard { | ||||||
|  | 		int O; | ||||||
|  |  | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 		void reset(); | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | } // namespace OpenWifi::OWLSObjects | ||||||
|  |  | ||||||
|  | #endif // UCENTRALSIM_RESTAPI_OWLSOBJECTS_H | ||||||