mirror of
				https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
				synced 2025-10-31 02:38:03 +00:00 
			
		
		
		
	Merge remote-tracking branch 'origin/master' into WIFI-14903-ssl-upgrade-via-debian-bookworm
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -29,4 +29,4 @@ helm/charts/* | |||||||
| !helm/charts/.gitkeep | !helm/charts/.gitkeep | ||||||
| /portal-test/ | /portal-test/ | ||||||
| /src/ow_version.h | /src/ow_version.h | ||||||
|  | .vscode/* | ||||||
|   | |||||||
| @@ -1609,6 +1609,74 @@ components: | |||||||
|                 maximum: 60000 |                 maximum: 60000 | ||||||
|                 description: off time in milliseconds |                 description: off time in milliseconds | ||||||
|  |  | ||||||
|  |     PackageGetResponse: | ||||||
|  |       type: object | ||||||
|  |       properties: | ||||||
|  |         serial: | ||||||
|  |           type: string | ||||||
|  |         status: | ||||||
|  |           type: object | ||||||
|  |           properties: | ||||||
|  |             package: | ||||||
|  |               type: string | ||||||
|  |             text: | ||||||
|  |               type: string | ||||||
|  |         uuid: | ||||||
|  |           type: number | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     PackageInstallRequest: | ||||||
|  |       type: object | ||||||
|  |       properties: | ||||||
|  |         serialNumber: | ||||||
|  |           type: string | ||||||
|  |         packages: | ||||||
|  |           type: array | ||||||
|  |           items: | ||||||
|  |             type: object | ||||||
|  |             properties: | ||||||
|  |               name: | ||||||
|  |                 type: string | ||||||
|  |               url: | ||||||
|  |                 type: string | ||||||
|  |      | ||||||
|  |     PackageInstallResponse: | ||||||
|  |       type: object | ||||||
|  |       properties: | ||||||
|  |         serial: | ||||||
|  |           type: string | ||||||
|  |         status: | ||||||
|  |           type: object | ||||||
|  |           properties: | ||||||
|  |             error: | ||||||
|  |               type: number | ||||||
|  |             packages: | ||||||
|  |               type: array | ||||||
|  |               items: | ||||||
|  |                 type: object | ||||||
|  |                 properties: | ||||||
|  |                   name: | ||||||
|  |                     type: string | ||||||
|  |                   result: | ||||||
|  |                     type: string | ||||||
|  |             text: | ||||||
|  |               type: string | ||||||
|  |         uuid: | ||||||
|  |           type: number | ||||||
|  |  | ||||||
|  |     PackageRemoveRequest: | ||||||
|  |       type: object | ||||||
|  |       properties: | ||||||
|  |         serialNumber: | ||||||
|  |           type: string | ||||||
|  |         packages:  | ||||||
|  |           type: array | ||||||
|  |           items: | ||||||
|  |             type: object | ||||||
|  |             properties: | ||||||
|  |               name: | ||||||
|  |                 type: string | ||||||
|  |  | ||||||
| paths: | paths: | ||||||
|   /devices: |   /devices: | ||||||
|     get: |     get: | ||||||
| @@ -3119,6 +3187,98 @@ paths: | |||||||
|         404: |         404: | ||||||
|           $ref: '#/components/responses/NotFound' |           $ref: '#/components/responses/NotFound' | ||||||
|  |  | ||||||
|  |   /device/{serialNumber}/package: | ||||||
|  |     get: | ||||||
|  |       tags: | ||||||
|  |         - Commands | ||||||
|  |       summary: Get package installed on the remote device. | ||||||
|  |       operationId: getDevicePackages | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: serialNumber | ||||||
|  |           schema: | ||||||
|  |             type: string | ||||||
|  |           required: true | ||||||
|  |         - in: query | ||||||
|  |           name: pkgName | ||||||
|  |           schema: | ||||||
|  |             type: string | ||||||
|  |           required: true | ||||||
|  |           description: The name or identifier of the package to retrieve. | ||||||
|  |       responses: | ||||||
|  |         200: | ||||||
|  |           description: Successful command execution | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 $ref: '#/components/schemas/PackageGetResponse' | ||||||
|  |         403: | ||||||
|  |           $ref: '#/components/responses/Unauthorized' | ||||||
|  |         404: | ||||||
|  |           $ref: '#/components/responses/NotFound' | ||||||
|  |  | ||||||
|  |     post: | ||||||
|  |       tags: | ||||||
|  |         - Commands | ||||||
|  |       summary: Install IPK files to remote device. | ||||||
|  |       operationId: postDevicePackages | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: serialNumber | ||||||
|  |           schema: | ||||||
|  |             type: string | ||||||
|  |           required: true | ||||||
|  |       requestBody: | ||||||
|  |         description: Packages to be installed | ||||||
|  |         content: | ||||||
|  |           application/json: | ||||||
|  |             schema: | ||||||
|  |               $ref: '#/components/schemas/PackageInstallRequest' | ||||||
|  |       responses: | ||||||
|  |         200: | ||||||
|  |           description: Successful command execution | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 $ref: '#/components/schemas/PackageInstallResponse' | ||||||
|  |  | ||||||
|  |         400: | ||||||
|  |           $ref: '#/components/responses/BadRequest' | ||||||
|  |         403: | ||||||
|  |           $ref: '#/components/responses/Unauthorized' | ||||||
|  |         404: | ||||||
|  |           $ref: '#/components/responses/NotFound' | ||||||
|  |  | ||||||
|  |     delete: | ||||||
|  |       tags: | ||||||
|  |         - Commands | ||||||
|  |       summary: Remove install packages from remote device. | ||||||
|  |       operationId: deleteDevicePackages | ||||||
|  |       parameters: | ||||||
|  |         - in: path | ||||||
|  |           name: serialNumber | ||||||
|  |           schema: | ||||||
|  |             type: string | ||||||
|  |           required: true | ||||||
|  |       requestBody: | ||||||
|  |         description: Packages to be removed | ||||||
|  |         content: | ||||||
|  |           application/json: | ||||||
|  |             schema: | ||||||
|  |               $ref: '#/components/schemas/PackageRemoveRequest' | ||||||
|  |       responses: | ||||||
|  |         200: | ||||||
|  |           content: | ||||||
|  |             application/json: | ||||||
|  |               schema: | ||||||
|  |                 $ref: '#/components/schemas/PackageInstallResponse' | ||||||
|  |         400: | ||||||
|  |           $ref: '#/components/responses/BadRequest' | ||||||
|  |         403: | ||||||
|  |           $ref: '#/components/responses/Unauthorized' | ||||||
|  |         404: | ||||||
|  |           $ref: '#/components/responses/NotFound' | ||||||
|  |  | ||||||
|   /ouis: |   /ouis: | ||||||
|     get: |     get: | ||||||
|       tags: |       tags: | ||||||
|   | |||||||
| @@ -22,7 +22,7 @@ | |||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| 	class AP_WS_Connection { | 	class AP_WS_Connection { | ||||||
| 		static constexpr int BufSize = 256000; | 		static constexpr int BufSize = 512000; | ||||||
|  |  | ||||||
| 	  public: | 	  public: | ||||||
| 		explicit AP_WS_Connection(Poco::Net::HTTPServerRequest &request, | 		explicit AP_WS_Connection(Poco::Net::HTTPServerRequest &request, | ||||||
|   | |||||||
| @@ -91,6 +91,31 @@ namespace OpenWifi { | |||||||
| 					TransactionId_, UUID, RPC, Poco::Thread::current()->id())); | 					TransactionId_, UUID, RPC, Poco::Thread::current()->id())); | ||||||
| 			return Rtty(UUID, RPC, 60000ms, Restrictions); | 			return Rtty(UUID, RPC, 60000ms, Restrictions); | ||||||
| 		}; | 		}; | ||||||
|  | 		case APCommands::Commands::package:{ | ||||||
|  | 			GWObjects::DeviceRestrictions Restrictions; | ||||||
|  | 			std::string pkg_name = ""; | ||||||
|  | 			if (!AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) { | ||||||
|  | 				CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected); | ||||||
|  | 				return BadRequest(RESTAPI::Errors::DeviceNotConnected); | ||||||
|  | 			} | ||||||
|  | 			Poco::URI uri(Request->getURI()); | ||||||
|  | 			for (const auto ¶m : uri.getQueryParameters()) { | ||||||
|  | 				if (param.first == "pkgName") { | ||||||
|  | 					pkg_name = param.second; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			if (pkg_name.empty()) { | ||||||
|  | 				return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||||
|  | 			} | ||||||
|  | 			auto UUID = MicroServiceCreateUUID(); | ||||||
|  | 			auto RPC = CommandManager()->Next_RPC_ID(); | ||||||
|  | 			poco_debug( | ||||||
|  | 				Logger_, | ||||||
|  | 				fmt::format( | ||||||
|  | 					"Command RTTY TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}", | ||||||
|  | 					TransactionId_, UUID, RPC, Poco::Thread::current()->id())); | ||||||
|  | 			return GetPackages(UUID, RPC, 300000ms, Restrictions, pkg_name); | ||||||
|  | 		} | ||||||
| 		default: | 		default: | ||||||
| 			return BadRequest(RESTAPI::Errors::InvalidCommand); | 			return BadRequest(RESTAPI::Errors::InvalidCommand); | ||||||
| 		} | 		} | ||||||
| @@ -128,6 +153,21 @@ namespace OpenWifi { | |||||||
| 			return DeleteChecks(); | 			return DeleteChecks(); | ||||||
| 		case APCommands::Commands::statistics: | 		case APCommands::Commands::statistics: | ||||||
| 			return DeleteStatistics(); | 			return DeleteStatistics(); | ||||||
|  | 		case APCommands::Commands::package: { | ||||||
|  | 			GWObjects::DeviceRestrictions Restrictions; | ||||||
|  | 			if (!AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) { | ||||||
|  | 				CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected); | ||||||
|  | 				return BadRequest(RESTAPI::Errors::DeviceNotConnected); | ||||||
|  | 			} | ||||||
|  | 			auto UUID = MicroServiceCreateUUID(); | ||||||
|  | 			auto RPC = CommandManager()->Next_RPC_ID(); | ||||||
|  | 			poco_debug( | ||||||
|  | 				Logger_, | ||||||
|  | 				fmt::format( | ||||||
|  | 					"Command RTTY TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}", | ||||||
|  | 					TransactionId_, UUID, RPC, Poco::Thread::current()->id())); | ||||||
|  | 			return DeletePackages(UUID, RPC, 300000ms, Restrictions); | ||||||
|  | 		} | ||||||
| 		default: | 		default: | ||||||
| 			return BadRequest(RESTAPI::Errors::InvalidCommand); | 			return BadRequest(RESTAPI::Errors::InvalidCommand); | ||||||
| 		} | 		} | ||||||
| @@ -171,7 +211,7 @@ namespace OpenWifi { | |||||||
| 		{APCommands::Commands::fixedconfig, false, true, &RESTAPI_device_commandHandler::FixedConfig, 120000ms}, | 		{APCommands::Commands::fixedconfig, false, true, &RESTAPI_device_commandHandler::FixedConfig, 120000ms}, | ||||||
| 		{APCommands::Commands::cablediagnostics, false, true, &RESTAPI_device_commandHandler::CableDiagnostics, 120000ms}, | 		{APCommands::Commands::cablediagnostics, false, true, &RESTAPI_device_commandHandler::CableDiagnostics, 120000ms}, | ||||||
| 		{APCommands::Commands::reenroll, false, true, &RESTAPI_device_commandHandler::ReEnroll, 120000ms}, | 		{APCommands::Commands::reenroll, false, true, &RESTAPI_device_commandHandler::ReEnroll, 120000ms}, | ||||||
|  | 		{APCommands::Commands::package, false, true, &RESTAPI_device_commandHandler::PackageInstall, 120000ms}, | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	void RESTAPI_device_commandHandler::DoPost() { | 	void RESTAPI_device_commandHandler::DoPost() { | ||||||
| @@ -409,6 +449,210 @@ namespace OpenWifi { | |||||||
| 		BadRequest(RESTAPI::Errors::NoRecordsDeleted); | 		BadRequest(RESTAPI::Errors::NoRecordsDeleted); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	void RESTAPI_device_commandHandler::GetPackages(const std::string &CMD_UUID, uint64_t CMD_RPC, | ||||||
|  | 		[[maybe_unused]] std::chrono::milliseconds timeout, | ||||||
|  | 		[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions, | ||||||
|  | 		const std::string pkg_name) { | ||||||
|  | 		poco_debug(Logger_, fmt::format("GET-PACKAGES({},{}): TID={} user={} serial={}. thr_id={}", | ||||||
|  | 										TransactionId_, Requester(), SerialNumber_, | ||||||
|  | 										Poco::Thread::current()->id())); | ||||||
|  |  | ||||||
|  | 		if (IsDeviceSimulated(SerialNumber_)) { | ||||||
|  | 			return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Poco::JSON::Object Params; | ||||||
|  | 		Params.set(uCentralProtocol::OPERATION, "list"); | ||||||
|  | 		Params.set(uCentralProtocol::SERIAL, SerialNumber_); | ||||||
|  | 		Params.set(uCentralProtocol::PACKAGE, pkg_name); | ||||||
|  |  | ||||||
|  | 		std::stringstream ParamStream; | ||||||
|  | 		Params.stringify(ParamStream); | ||||||
|  |  | ||||||
|  | 		GWObjects::CommandDetails Cmd; | ||||||
|  | 		Cmd.SerialNumber = SerialNumber_; | ||||||
|  | 		Cmd.UUID = CMD_UUID; | ||||||
|  | 		Cmd.SubmittedBy = Requester(); | ||||||
|  | 		Cmd.Command = uCentralProtocol::PACKAGE; | ||||||
|  | 		Cmd.RunAt = 0; | ||||||
|  | 		Cmd.Details = ParamStream.str(); | ||||||
|  |  | ||||||
|  | 		RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::package, false, Cmd, Params, | ||||||
|  | 										*Request, *Response, timeout, nullptr, nullptr, Logger_); | ||||||
|  |  | ||||||
|  | 		Poco::JSON::Object O, P; | ||||||
|  | 		Cmd.to_json(O); | ||||||
|  |  | ||||||
|  | 		Poco::Dynamic::Var resultsVar = O.get("results"); | ||||||
|  | 		Poco::JSON::Object::Ptr resultsObj = resultsVar.extract<Poco::JSON::Object::Ptr>(); | ||||||
|  |  | ||||||
|  | 		return ReturnObject(*resultsObj); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void RESTAPI_device_commandHandler::PackageInstall( | ||||||
|  | 		const std::string &CMD_UUID, uint64_t CMD_RPC, | ||||||
|  | 		[[maybe_unused]] std::chrono::milliseconds timeout, | ||||||
|  | 		[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) { | ||||||
|  | 	 | ||||||
|  | 		if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT && | ||||||
|  | 			UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) { | ||||||
|  | 			CallCanceled("INSTALLPACKAGE", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED); | ||||||
|  | 			return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		poco_debug(Logger_, fmt::format("INSTALL-PACKAGES({},{}): TID={} user={} serial={}", CMD_UUID, | ||||||
|  | 										CMD_RPC, TransactionId_, Requester(), SerialNumber_)); | ||||||
|  |  | ||||||
|  | 		if (IsDeviceSimulated(SerialNumber_)) { | ||||||
|  | 			CallCanceled("INSTALL-PACKAGES", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported); | ||||||
|  | 			return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		const auto &Obj = ParsedBody_; | ||||||
|  | 		if (!Obj->has(RESTAPI::Protocol::SERIALNUMBER)) { | ||||||
|  | 			return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString(); | ||||||
|  | 		if (SerialNumber_ != SNum) { | ||||||
|  | 			CallCanceled("INSTALL-PACKAGES", CMD_UUID, CMD_RPC, RESTAPI::Errors::SerialNumberMismatch); | ||||||
|  | 			return BadRequest(RESTAPI::Errors::SerialNumberMismatch); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		std::ostringstream os; | ||||||
|  | 		ParsedBody_->stringify(os); | ||||||
|  |  | ||||||
|  | 		poco_information(Logger_, fmt::format("INSTALL_OBJECT: {} for device {}", os.str(), SerialNumber_)); | ||||||
|  |  | ||||||
|  | 		GWObjects::PackageInstall	PI; | ||||||
|  | 		if (!PI.from_json(ParsedBody_)) { | ||||||
|  | 			return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Poco::JSON::Array::Ptr ArrayObj = Poco::SharedPtr<Poco::JSON::Array>(new Poco::JSON::Array); | ||||||
|  | 		for (const auto &i : PI.pkgs) { | ||||||
|  | 			Poco::JSON::Object::Ptr Obj = | ||||||
|  | 				Poco::SharedPtr<Poco::JSON::Object>(new Poco::JSON::Object); | ||||||
|  | 			i.to_json(*Obj); | ||||||
|  | 			ArrayObj->add(Obj); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Poco::JSON::Object Params; | ||||||
|  | 		Params.set(uCentralProtocol::OPERATION, "install"); | ||||||
|  | 		Params.set(uCentralProtocol::SERIAL, SerialNumber_); | ||||||
|  | 		Params.set(uCentralProtocol::PACKAGES, ArrayObj); | ||||||
|  |  | ||||||
|  | 		std::ostringstream os2; | ||||||
|  | 		Params.stringify(os2); | ||||||
|  |  | ||||||
|  | 		poco_information(Logger_, fmt::format("INSTALL_OBJECT2: {} for device {}", os2.str(), SerialNumber_)); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 		std::stringstream ParamStream; | ||||||
|  | 		Params.stringify(ParamStream); | ||||||
|  |  | ||||||
|  | 		GWObjects::CommandDetails Cmd; | ||||||
|  | 		Cmd.SerialNumber = SerialNumber_; | ||||||
|  | 		Cmd.UUID = CMD_UUID; | ||||||
|  | 		Cmd.SubmittedBy = Requester(); | ||||||
|  | 		Cmd.Command = uCentralProtocol::PACKAGE; | ||||||
|  | 		Cmd.RunAt = 0; | ||||||
|  | 		Cmd.Details = ParamStream.str(); | ||||||
|  |  | ||||||
|  | 		RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::package, false, Cmd, Params, | ||||||
|  | 										*Request, *Response, timeout, nullptr, nullptr, Logger_); | ||||||
|  |  | ||||||
|  | 		Poco::JSON::Object O, P; | ||||||
|  | 		Cmd.to_json(O); | ||||||
|  |  | ||||||
|  | 		Poco::Dynamic::Var resultsVar = O.get("results"); | ||||||
|  | 		Poco::JSON::Object::Ptr resultsObj = resultsVar.extract<Poco::JSON::Object::Ptr>(); | ||||||
|  |  | ||||||
|  | 		return ReturnObject(*resultsObj); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void RESTAPI_device_commandHandler::DeletePackages( | ||||||
|  | 		const std::string &CMD_UUID, uint64_t CMD_RPC, | ||||||
|  | 		[[maybe_unused]] std::chrono::milliseconds timeout, | ||||||
|  | 		[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) { | ||||||
|  |  | ||||||
|  | 		if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT && | ||||||
|  | 			UserInfo_.userinfo.userRole != SecurityObjects::ADMIN) { | ||||||
|  | 			CallCanceled("DELETE-PACKAGES", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED); | ||||||
|  | 			return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		poco_debug(Logger_, fmt::format("DELETE-PACKAGES({},{}): TID={} user={} serial={}", CMD_UUID, | ||||||
|  | 										CMD_RPC, TransactionId_, Requester(), SerialNumber_)); | ||||||
|  |  | ||||||
|  | 		if (IsDeviceSimulated(SerialNumber_)) { | ||||||
|  | 			CallCanceled("DELETE-PACKAGES", CMD_UUID, CMD_RPC, RESTAPI::Errors::SimulatedDeviceNotSupported); | ||||||
|  | 			return BadRequest(RESTAPI::Errors::SimulatedDeviceNotSupported); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		const auto &Obj = ParsedBody_; | ||||||
|  | 		if (!Obj->has(RESTAPI::Protocol::SERIALNUMBER)) { | ||||||
|  | 			return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		auto SNum = Obj->get(RESTAPI::Protocol::SERIALNUMBER).toString(); | ||||||
|  | 		if (SerialNumber_ != SNum) { | ||||||
|  | 			CallCanceled("DELETE-PACKAGES", CMD_UUID, CMD_RPC, RESTAPI::Errors::SerialNumberMismatch); | ||||||
|  | 			return BadRequest(RESTAPI::Errors::SerialNumberMismatch); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		std::ostringstream os; | ||||||
|  | 		ParsedBody_->stringify(os); | ||||||
|  |  | ||||||
|  | 		poco_information(Logger_, fmt::format("DELETE_OBJECT: {} for device {}", os.str(), SerialNumber_)); | ||||||
|  |  | ||||||
|  | 		GWObjects::PackageRemove	PR; | ||||||
|  | 		if (!PR.from_json(ParsedBody_)) { | ||||||
|  | 			return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Poco::JSON::Array::Ptr ArrayObj = Poco::SharedPtr<Poco::JSON::Array>(new Poco::JSON::Array); | ||||||
|  | 		for (const auto &i : PR.pkgs) { | ||||||
|  | 			Poco::JSON::Object::Ptr Obj = | ||||||
|  | 				Poco::SharedPtr<Poco::JSON::Object>(new Poco::JSON::Object); | ||||||
|  | 			i.to_json(*Obj); | ||||||
|  | 			ArrayObj->add(Obj); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		Poco::JSON::Object Params; | ||||||
|  | 		Params.set(uCentralProtocol::OPERATION, "delete"); | ||||||
|  | 		Params.set(uCentralProtocol::SERIAL, SerialNumber_); | ||||||
|  | 		Params.set(uCentralProtocol::PACKAGES, ArrayObj); | ||||||
|  |  | ||||||
|  | 		std::ostringstream os2; | ||||||
|  | 		Params.stringify(os2); | ||||||
|  |  | ||||||
|  | 		poco_information(Logger_, fmt::format("DELETE_OBJECT2: {} for device {}", os2.str(), SerialNumber_)); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 		std::stringstream ParamStream; | ||||||
|  | 		Params.stringify(ParamStream); | ||||||
|  |  | ||||||
|  | 		GWObjects::CommandDetails Cmd; | ||||||
|  | 		Cmd.SerialNumber = SerialNumber_; | ||||||
|  | 		Cmd.UUID = CMD_UUID; | ||||||
|  | 		Cmd.SubmittedBy = Requester(); | ||||||
|  | 		Cmd.Command = uCentralProtocol::PACKAGE; | ||||||
|  | 		Cmd.RunAt = 0; | ||||||
|  | 		Cmd.Details = ParamStream.str(); | ||||||
|  |  | ||||||
|  | 		RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::package, false, Cmd, Params, | ||||||
|  | 										*Request, *Response, timeout, nullptr, nullptr, Logger_); | ||||||
|  |  | ||||||
|  | 		Poco::JSON::Object O, P; | ||||||
|  | 		Cmd.to_json(O); | ||||||
|  |  | ||||||
|  | 		Poco::Dynamic::Var resultsVar = O.get("results"); | ||||||
|  | 		Poco::JSON::Object::Ptr resultsObj = resultsVar.extract<Poco::JSON::Object::Ptr>(); | ||||||
|  |  | ||||||
|  | 		return ReturnObject(*resultsObj); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	void RESTAPI_device_commandHandler::Ping( | 	void RESTAPI_device_commandHandler::Ping( | ||||||
| 		const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, | 		const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, | ||||||
| 		[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) { | 		[[maybe_unused]] const GWObjects::DeviceRestrictions &Restrictions) { | ||||||
|   | |||||||
| @@ -33,6 +33,10 @@ namespace OpenWifi { | |||||||
| 		void GetStatus(); | 		void GetStatus(); | ||||||
| 		void GetChecks(); | 		void GetChecks(); | ||||||
| 		void DeleteChecks(); | 		void DeleteChecks(); | ||||||
|  | 		void GetPackages(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, | ||||||
|  | 					   const GWObjects::DeviceRestrictions &R, std::string pkg_name); | ||||||
|  | 		void DeletePackages(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, | ||||||
|  | 					   const GWObjects::DeviceRestrictions &R); | ||||||
|  |  | ||||||
| 		bool IsDeviceSimulated(std::string &Serial); | 		bool IsDeviceSimulated(std::string &Serial); | ||||||
|  |  | ||||||
| @@ -76,6 +80,8 @@ namespace OpenWifi { | |||||||
| 					  const GWObjects::DeviceRestrictions &R); | 					  const GWObjects::DeviceRestrictions &R); | ||||||
| 		void ReEnroll(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, | 		void ReEnroll(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, | ||||||
| 					  const GWObjects::DeviceRestrictions &R); | 					  const GWObjects::DeviceRestrictions &R); | ||||||
|  | 		void PackageInstall(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, | ||||||
|  | 					  const GWObjects::DeviceRestrictions &R); | ||||||
|  |  | ||||||
| 		static auto PathName() { | 		static auto PathName() { | ||||||
| 			return std::list<std::string>{"/api/v1/device/{serialNumber}/{command}"}; | 			return std::list<std::string>{"/api/v1/device/{serialNumber}/{command}"}; | ||||||
|   | |||||||
| @@ -12,9 +12,9 @@ | |||||||
| #include "Daemon.h" | #include "Daemon.h" | ||||||
| #ifdef TIP_GATEWAY_SERVICE | #ifdef TIP_GATEWAY_SERVICE | ||||||
| #include "AP_WS_Server.h" | #include "AP_WS_Server.h" | ||||||
| #include "StorageService.h" |  | ||||||
| #include "CapabilitiesCache.h" | #include "CapabilitiesCache.h" | ||||||
| #include "RADIUSSessionTracker.h" | #include "RADIUSSessionTracker.h" | ||||||
|  | #include "StorageService.h" | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| #include "RESTAPI_GWobjects.h" | #include "RESTAPI_GWobjects.h" | ||||||
| @@ -31,7 +31,8 @@ namespace OpenWifi::GWObjects { | |||||||
| 		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", StorageService()->GetPlatform(SerialNumber)); | 		field_to_json(Obj, "deviceType", StorageService()->GetPlatform(SerialNumber)); | ||||||
| 		field_to_json(Obj, "blackListed", StorageService()->IsBlackListed(Utils::MACToInt(SerialNumber))); | 		field_to_json(Obj, "blackListed", | ||||||
|  | 					  StorageService()->IsBlackListed(Utils::MACToInt(SerialNumber))); | ||||||
| #endif | #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); | ||||||
| @@ -179,7 +180,6 @@ namespace OpenWifi::GWObjects { | |||||||
| 			field_from_json(Obj, "recorded", Recorded); | 			field_from_json(Obj, "recorded", Recorded); | ||||||
| 			return true; | 			return true; | ||||||
| 		} catch (...) { | 		} catch (...) { | ||||||
|  |  | ||||||
| 		} | 		} | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
| @@ -275,7 +275,8 @@ namespace OpenWifi::GWObjects { | |||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void ConnectionState::to_json([[maybe_unused]] const std::string &SerialNumber, Poco::JSON::Object &Obj)  { | 	void ConnectionState::to_json([[maybe_unused]] const std::string &SerialNumber, | ||||||
|  | 								  Poco::JSON::Object &Obj) { | ||||||
| 		field_to_json(Obj, "ipAddress", Address); | 		field_to_json(Obj, "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); | ||||||
| @@ -831,4 +832,102 @@ namespace OpenWifi::GWObjects { | |||||||
| 		} | 		} | ||||||
| 		return false; | 		return false; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	bool PackageInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj, "name", name); | ||||||
|  | 			field_from_json(Obj, "version", version); | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void PackageInfo::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		field_to_json(Obj, "name", name); | ||||||
|  | 		field_to_json(Obj, "version", version); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool PackageList::from_json(const Poco::JSON::Array::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  |  | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void PackageList::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		Obj.set("serialNumber", serialNumber); | ||||||
|  |  | ||||||
|  | 		Poco::JSON::Array packageJsonArray; | ||||||
|  | 		for (const auto &pkg : packageArray) { | ||||||
|  | 			Poco::JSON::Object pkgObj; | ||||||
|  | 			pkg.to_json(pkgObj); | ||||||
|  | 			packageJsonArray.add(pkgObj); | ||||||
|  | 		} | ||||||
|  | 		Obj.set("packageArray", packageJsonArray); | ||||||
|  |  | ||||||
|  | 		Obj.set("FirstUpdate", Poco::UInt64(FirstUpdate)); | ||||||
|  | 		Obj.set("LastUpdate", Poco::UInt64(LastUpdate)); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool ToBeInstalled::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj, "name", name); | ||||||
|  | 			field_from_json(Obj, "url", url); | ||||||
|  |  | ||||||
|  | 			Poco::URI uri(url); | ||||||
|  | 			std::string scheme = uri.getScheme(); | ||||||
|  | 			if (scheme != "http" && scheme != "https") { | ||||||
|  | 				return false; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void ToBeInstalled::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		Obj.set("name", name); | ||||||
|  | 		Obj.set("url", url); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool PackageInstall::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj, "serialNumber", serialNumber); | ||||||
|  | 			field_from_json(Obj, "when", when); | ||||||
|  | 			field_from_json(Obj, "packages", pkgs); | ||||||
|  |  | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool ToBeRemoved::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj, "name", name); | ||||||
|  |  | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	void ToBeRemoved::to_json(Poco::JSON::Object &Obj) const { | ||||||
|  | 		Obj.set("name", name); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	bool PackageRemove::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|  | 		try { | ||||||
|  | 			field_from_json(Obj, "serialNumber", serialNumber); | ||||||
|  | 			field_from_json(Obj, "packages", pkgs); | ||||||
|  |  | ||||||
|  | 			return true; | ||||||
|  | 		} catch (const Poco::Exception &E) { | ||||||
|  | 		} | ||||||
|  | 		return false; | ||||||
|  | 	} | ||||||
| } // namespace OpenWifi::GWObjects | } // namespace OpenWifi::GWObjects | ||||||
|   | |||||||
| @@ -552,6 +552,51 @@ namespace OpenWifi::GWObjects { | |||||||
| 		std::string 	serialNumber; | 		std::string 	serialNumber; | ||||||
| 		std::uint64_t 	when; | 		std::uint64_t 	when; | ||||||
|  |  | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 	}; | ||||||
|  | 	struct PackageInfo { | ||||||
|  | 		std::string	 name; | ||||||
|  | 		std::string	 version; | ||||||
|  |  | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 	}; | ||||||
|  | 	struct PackageList { | ||||||
|  | 		std::string	serialNumber; | ||||||
|  | 		std::vector<PackageInfo>	packageArray; | ||||||
|  | 		uint64_t 	FirstUpdate = 0; | ||||||
|  | 		uint64_t 	LastUpdate = 0; | ||||||
|  | 		std::string packageStringArray; | ||||||
|  |  | ||||||
|  | 		bool from_json(const Poco::JSON::Array::Ptr &Obj); | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 	}; | ||||||
|  | 	struct ToBeInstalled { | ||||||
|  | 		std::string name; | ||||||
|  | 		std::string url; | ||||||
|  |  | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 	}; | ||||||
|  | 	struct PackageInstall { | ||||||
|  | 		std::string 	serialNumber; | ||||||
|  | 		std::uint64_t   when; | ||||||
|  | 		std::vector<ToBeInstalled> pkgs; | ||||||
|  |  | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 	}; | ||||||
|  | 	struct ToBeRemoved { | ||||||
|  | 		std::string		name; | ||||||
|  |  | ||||||
|  | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
|  | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
|  | 	}; | ||||||
|  | 	struct PackageRemove { | ||||||
|  | 		std::string 	serialNumber; | ||||||
|  | 		std::uint64_t   when; | ||||||
|  | 		std::vector<ToBeRemoved> pkgs; | ||||||
|  |  | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||||
| 	}; | 	}; | ||||||
| } // namespace OpenWifi::GWObjects | } // namespace OpenWifi::GWObjects | ||||||
|   | |||||||
| @@ -433,6 +433,10 @@ namespace OpenWifi::RESTAPI::Errors { | |||||||
|  |  | ||||||
| 	static const struct msg InvalidRRMAction { 1192, "Invalid RRM Action." }; | 	static const struct msg InvalidRRMAction { 1192, "Invalid RRM Action." }; | ||||||
|  |  | ||||||
|  | 	static const struct msg InvalidPackageURL { 1193, "Invalid URL, must start with http:// or https://." }; | ||||||
|  | 	static const struct msg FailedToDownload { 1194, "Failed to download package." }; | ||||||
|  | 	static const struct msg FailedToDecompress { 1195, "Failed to decompress package data."}; | ||||||
|  |  | ||||||
|     static const struct msg SimulationDoesNotExist { |     static const struct msg SimulationDoesNotExist { | ||||||
|         7000, "Simulation Instance ID does not exist." |         7000, "Simulation Instance ID does not exist." | ||||||
|     }; |     }; | ||||||
| @@ -550,6 +554,10 @@ namespace OpenWifi::RESTAPI::Protocol { | |||||||
| 	static const char *DEBUG = "debug"; | 	static const char *DEBUG = "debug"; | ||||||
| 	static const char *SCRIPT = "script"; | 	static const char *SCRIPT = "script"; | ||||||
| 	static const char *TIMEOUT = "timeout"; | 	static const char *TIMEOUT = "timeout"; | ||||||
|  | 	static const char *PACKAGE = "package"; | ||||||
|  | 	static const char *PACKAGES = "packages"; | ||||||
|  | 	static const char *PACKAGEINST = "packageInstall"; | ||||||
|  | 	static const char *PACKAGEDEL = "packageDelete"; | ||||||
|  |  | ||||||
| 	static const char *NEWPASSWORD = "newPassword"; | 	static const char *NEWPASSWORD = "newPassword"; | ||||||
| 	static const char *USERS = "users"; | 	static const char *USERS = "users"; | ||||||
| @@ -669,6 +677,9 @@ namespace OpenWifi::uCentralProtocol { | |||||||
| 	static const char *SIGNATURE = "signature"; | 	static const char *SIGNATURE = "signature"; | ||||||
| 	static const char *INFO = "info"; | 	static const char *INFO = "info"; | ||||||
| 	static const char *DATE = "date"; | 	static const char *DATE = "date"; | ||||||
|  | 	static const char *PACKAGE = "package"; | ||||||
|  | 	static const char *PACKAGES = "packages"; | ||||||
|  | 	static const char *CATEGORY = "category"; | ||||||
|  |  | ||||||
| 	static const char *SERIALNUMBER = "serialNumber"; | 	static const char *SERIALNUMBER = "serialNumber"; | ||||||
| 	static const char *COMPATIBLE = "compatible"; | 	static const char *COMPATIBLE = "compatible"; | ||||||
| @@ -701,7 +712,7 @@ namespace OpenWifi::uCentralProtocol { | |||||||
| 	static const char *CABLEDIAGNOSTICS = "cable-diagnostics"; | 	static const char *CABLEDIAGNOSTICS = "cable-diagnostics"; | ||||||
| 	static const char *REENROLL = "reenroll"; | 	static const char *REENROLL = "reenroll"; | ||||||
|  |  | ||||||
|  | 	static const char *OPERATION = "op"; | ||||||
| } // namespace OpenWifi::uCentralProtocol | } // namespace OpenWifi::uCentralProtocol | ||||||
|  |  | ||||||
| namespace OpenWifi::uCentralProtocol::Events { | namespace OpenWifi::uCentralProtocol::Events { | ||||||
| @@ -736,7 +747,8 @@ namespace OpenWifi::uCentralProtocol::Events { | |||||||
| 		ET_EVENT, | 		ET_EVENT, | ||||||
| 		ET_WIFISCAN, | 		ET_WIFISCAN, | ||||||
| 		ET_ALARM, | 		ET_ALARM, | ||||||
| 		ET_REBOOTLOG | 		ET_REBOOTLOG, | ||||||
|  | 		ET_PACKAGE | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	inline EVENT_MSG EventFromString(const std::string &Method) { | 	inline EVENT_MSG EventFromString(const std::string &Method) { | ||||||
| @@ -770,6 +782,8 @@ namespace OpenWifi::uCentralProtocol::Events { | |||||||
| 			return ET_ALARM; | 			return ET_ALARM; | ||||||
| 		else if (strcmp(REBOOTLOG, Method.c_str()) == 0) | 		else if (strcmp(REBOOTLOG, Method.c_str()) == 0) | ||||||
| 			return ET_REBOOTLOG; | 			return ET_REBOOTLOG; | ||||||
|  | 		else if (strcmp(PACKAGE, Method.c_str()) == 0) | ||||||
|  | 			return ET_PACKAGE; | ||||||
| 		return ET_UNKNOWN; | 		return ET_UNKNOWN; | ||||||
| 	}; | 	}; | ||||||
| } // namespace OpenWifi::uCentralProtocol::Events | } // namespace OpenWifi::uCentralProtocol::Events | ||||||
| @@ -801,6 +815,7 @@ namespace OpenWifi::APCommands { | |||||||
| 		fixedconfig, | 		fixedconfig, | ||||||
| 		cablediagnostics, | 		cablediagnostics, | ||||||
| 		reenroll, | 		reenroll, | ||||||
|  | 		package, | ||||||
| 		unknown | 		unknown | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| @@ -817,7 +832,7 @@ namespace OpenWifi::APCommands { | |||||||
| 		RESTAPI::Protocol::RRM,		 	 RESTAPI::Protocol::CERTUPDATE, | 		RESTAPI::Protocol::RRM,		 	 RESTAPI::Protocol::CERTUPDATE, | ||||||
| 		RESTAPI::Protocol::TRANSFER,	 RESTAPI::Protocol::POWERCYCLE, | 		RESTAPI::Protocol::TRANSFER,	 RESTAPI::Protocol::POWERCYCLE, | ||||||
| 		RESTAPI::Protocol::FIXEDCONFIG,  RESTAPI::Protocol::CABLEDIAGNOSTICS, | 		RESTAPI::Protocol::FIXEDCONFIG,  RESTAPI::Protocol::CABLEDIAGNOSTICS, | ||||||
| 		RESTAPI::Protocol::REENROLL | 		RESTAPI::Protocol::REENROLL,	 RESTAPI::Protocol::PACKAGE | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	inline const char *to_string(Commands Cmd) { return uCentralAPCommands[(uint8_t)Cmd]; } | 	inline const char *to_string(Commands Cmd) { return uCentralAPCommands[(uint8_t)Cmd]; } | ||||||
|   | |||||||
| @@ -49,8 +49,7 @@ namespace OpenWifi { | |||||||
| 						"Data TEXT, " | 						"Data TEXT, " | ||||||
| 						"Recorded BIGINT, " | 						"Recorded BIGINT, " | ||||||
| 						"INDEX StatSerial0 (SerialNumber)), ", | 						"INDEX StatSerial0 (SerialNumber)), ", | ||||||
| 						"INDEX StatSerial (SerialNumber ASC, Recorded ASC))", | 					"INDEX StatSerial (SerialNumber ASC, Recorded ASC))", Poco::Data::Keywords::now; | ||||||
| 					Poco::Data::Keywords::now; |  | ||||||
| 			} | 			} | ||||||
| 			return 0; | 			return 0; | ||||||
| 		} catch (const Poco::Exception &E) { | 		} catch (const Poco::Exception &E) { | ||||||
| @@ -154,8 +153,7 @@ namespace OpenWifi { | |||||||
| 				"alter table devices add column lastRecordedContact bigint", | 				"alter table devices add column lastRecordedContact bigint", | ||||||
| 				"alter table devices add column simulated boolean", | 				"alter table devices add column simulated boolean", | ||||||
| 				"alter table devices add column certificateExpiryDate bigint", | 				"alter table devices add column certificateExpiryDate bigint", | ||||||
| 				"alter table devices add column connectReason TEXT" | 				"alter table devices add column connectReason TEXT"}; | ||||||
| 			}; |  | ||||||
|  |  | ||||||
| 			for (const auto &i : Script) { | 			for (const auto &i : Script) { | ||||||
| 				try { | 				try { | ||||||
| @@ -279,9 +277,7 @@ namespace OpenWifi { | |||||||
| 					Poco::Data::Keywords::now; | 					Poco::Data::Keywords::now; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			std::vector<std::string> Script{ | 			std::vector<std::string> Script{"alter table DefaultConfigs add column Platform text"}; | ||||||
| 				"alter table DefaultConfigs add column Platform text" |  | ||||||
| 			}; |  | ||||||
|  |  | ||||||
| 			for (const auto &i : Script) { | 			for (const auto &i : Script) { | ||||||
| 				try { | 				try { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Carsten Schafer
					Carsten Schafer