/* * Copyright (c) 2023 Fancy Code. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "AppManager.h" #include "AppClient.h" #include "AppManagerMakePtr.h" #include "IAppManager.h" #include "IAppProtocolHandle.h" #include "IHalCpp.h" #include "ILog.h" #include "StatusCode.h" #include "TcpModule.h" #include "WebServer.h" #include #include AppManager::AppManager() : mTcpServer(nullptr), mInitRuning(false) { } const StatusCode AppManager::Init(const AppParam ¶m) { std::shared_ptr protocolHandle; AppManagerMakePtr::GetInstance()->CreateProtocolHandle(protocolHandle); IAppProtocolHandle::GetInstance(&protocolHandle); auto initThread = [](std::shared_ptr appManager, const AppParam param) { LogInfo("WifiApModeInit started.\n"); appManager->WifiApModeInit(param); }; mInitThread = std::thread(initThread, shared_from_this(), param); return CreateStatusCode(STATUS_CODE_OK); } const StatusCode AppManager::UnInit(void) { if (true == mInitRuning) { std::shared_ptr wifi; IHalCpp::GetInstance()->GetWifiHal(wifi); if (!wifi) { LogWarning("Get wifi hal failed.\n"); goto GOAHEAD; } wifi->CloseApMode(); } GOAHEAD: mInitRuning = false; if (mInitThread.joinable()) { mInitThread.join(); } HttpServerStop(); TcpServerStop(); std::shared_ptr protocolHandle = std::make_shared(); IAppProtocolHandle::GetInstance(&protocolHandle); mAppMonitor.reset(); return CreateStatusCode(STATUS_CODE_OK); } const StatusCode AppManager::SetAppMonitor(std::shared_ptr &monitor) { IAppProtocolHandle::GetInstance()->SetAppMonitor(monitor); mAppMonitor = monitor; return CreateStatusCode(STATUS_CODE_OK); } StatusCode AppManager::SetSdCardStatus(const SdCardStatus &status) { for (const auto &pair : mAppClients) { pair.second->SetSdCardStatus(status); } return CreateStatusCode(STATUS_CODE_OK); } void AppManager::AppRequestHandle(const char *url, const unsigned int urlLength, ResponseHandle responseHandle, void *context) { IAppProtocolHandle::GetInstance()->RequestHandle(url, urlLength, responseHandle, context); } void AppManager::AppRequestHandleTcp(const char *data, const unsigned int dataLength, ResponseHandle responseHandle, void *context) { } void AppManager::AppClientConnected(const void *client, const char *ip) { void *object = (void *)client; mAppClients[object] = std::make_shared(client); mAppMonitor->AppClientConnected(mAppClients[object]); } void AppManager::AppClientClosed(const void *client) { void *object = (void *)client; auto it = mAppClients.find(object); if (it != mAppClients.end()) { mAppClients.erase(it); } else { LogError("App client not exit.\n"); } } void AppManager::HttpServerStart(const AppParam ¶m) { auto httpServerThread = [=](std::shared_ptr app) { LogInfo("AppManager httpServer started.\n"); app->HttpServerThread(param); }; mHttpSever = std::thread(httpServerThread, shared_from_this()); } void AppManager::HttpServerStop(void) { WebServerExit(); if (mHttpSever.joinable()) { mHttpSever.join(); } } void AppManager::HttpServerThread(const AppParam ¶m) { std::shared_ptr app = shared_from_this(); auto httpHandle = [](const char *url, const unsigned int urlLength, ResponseHandle responseHandle, void *context) -> void { // LogInfo("url = %s\n", url); std::shared_ptr app = IAppManager::GetInstance(); std::shared_ptr appImpl = std::dynamic_pointer_cast(app); if (appImpl) { appImpl->AppRequestHandle(url, urlLength, responseHandle, context); } }; WebServerParam web = {.mIp = param.mIP, .mPort = param.mHttpPort, .mHttpRequestHandle = httpHandle}; WebServerInit(web); WebServerUnInit(); } void AppManager::TcpServerStart(const AppParam ¶m) { auto acceptClientFunc = [](void *object, const char *ip) -> bool { LogInfo("accept client, peer ip: %s\n", ip); if (nullptr != object) { std::shared_ptr app = IAppManager::GetInstance(); std::shared_ptr appImpl = std::dynamic_pointer_cast(app); if (appImpl) { appImpl->AppClientConnected(object, ip); } return true; } return false; }; auto readFunc = [](const void *data, const ssize_t len, const void *object) -> void { LogInfo("read data: %s\n", (char *)data); }; auto closedFunc = [](const void *object) -> void { LogInfo("closed.\n"); std::shared_ptr app = IAppManager::GetInstance(); std::shared_ptr appImpl = std::dynamic_pointer_cast(app); if (appImpl) { appImpl->AppClientClosed(object); } }; TcpServerParam tcpServerparam = { .mIp = param.mIP, .mPort = param.mTcpPort, .mAcceptClientFunc = acceptClientFunc, .mClientAcceptParam = { .mReadFunc = readFunc, .mClosedFunc = closedFunc, }, }; mTcpServer = CreateTcpServer(tcpServerparam); if (nullptr == mTcpServer) { LogError("Create tcp server failed.\n"); } LogInfo("Create tcp server success.\n"); } void AppManager::TcpServerStop(void) { if (nullptr != mTcpServer) { FreeTcpServer(mTcpServer); } } void AppManager::WifiApModeInit(const AppParam ¶m) { mInitRuning = true; std::shared_ptr wifi; IHalCpp::GetInstance()->GetWifiHal(wifi); if (!wifi) { LogError("Get wifi hal failed.\n"); return; } StatusCode codePower = wifi->PowerOn(); if (!IsCodeOK(codePower)) { LogError("Wifi power on failed.\n"); return; } /** * @brief This interface depends on hardware and may block. It is necessary to ensure that hardware interface * blocking does not cause the main thread to block. */ StatusCode code = wifi->OpenApMode(); if (!IsCodeOK(code)) { LogError("OpenApMode failed.\n"); return; } if (false == mInitRuning) { LogWarning("AppManager init stop.\n"); return; } HttpServerStart(param); TcpServerStart(param); }